mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-13 20:24:17 +01:00
Compare commits
143 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b6517aae8 | ||
|
|
aadcf771e7 | ||
|
|
bf4673a1d9 | ||
|
|
76b214c643 | ||
|
|
434a5a809e | ||
|
|
88fe25f69e | ||
|
|
bef1e39ac3 | ||
|
|
c604d5dbe5 | ||
|
|
a0d912a395 | ||
|
|
a56852f918 | ||
|
|
4228fc1b89 | ||
|
|
e644b8da28 | ||
|
|
ace3a8f755 | ||
|
|
76ed347cbf | ||
|
|
c3469a1687 | ||
|
|
0a9693daea | ||
|
|
414bd8bee7 | ||
|
|
8e1745d67a | ||
|
|
889f01a724 | ||
|
|
6e62905fa7 | ||
|
|
654787fa0d | ||
|
|
835ba23935 | ||
|
|
389a8781d6 | ||
|
|
3eabe591df | ||
|
|
487d3b9399 | ||
|
|
4d4e4669dd | ||
|
|
fb065549e9 | ||
|
|
2c34154915 | ||
|
|
3704051b0f | ||
|
|
b2b8f2b6eb | ||
|
|
22e6c0655b | ||
|
|
bb2ba0cf11 | ||
|
|
e854386b23 | ||
|
|
49d24df2e7 | ||
|
|
c9b291c2f3 | ||
|
|
65f789880d | ||
|
|
abf998a727 | ||
|
|
4cc191cb25 | ||
|
|
dc431c10a5 | ||
|
|
26862ba78f | ||
|
|
e4374337f2 | ||
|
|
240c889fff | ||
|
|
612cd31c3e | ||
|
|
304b362002 | ||
|
|
8f34f197d0 | ||
|
|
1c97266a93 | ||
|
|
a9caddafd5 | ||
|
|
34bf95dddb | ||
|
|
4761b8f584 | ||
|
|
0d94aae732 | ||
|
|
e83f328cdc | ||
|
|
52fd29c478 | ||
|
|
a8b79993df | ||
|
|
98574558e5 | ||
|
|
557cbf23ce | ||
|
|
56753ae7ba | ||
|
|
b66df624f7 | ||
|
|
be78f1447b | ||
|
|
97e32a3cb7 | ||
|
|
4472920536 | ||
|
|
ac6a726f57 | ||
|
|
00d550f4fe | ||
|
|
0f98fac157 | ||
|
|
c25f0f72db | ||
|
|
72e05e23bc | ||
|
|
2c3bed6ba5 | ||
|
|
d6df9885dc | ||
|
|
e7936500e0 | ||
|
|
4ef4e65d46 | ||
|
|
40b4a8fd7a | ||
|
|
8a1f03c272 | ||
|
|
8ed479eddf | ||
|
|
c0a278ca2c | ||
|
|
2e9a7004c6 | ||
|
|
75c76a92b9 | ||
|
|
282935c6d6 | ||
|
|
d7b189b714 | ||
|
|
e3da3f356c | ||
|
|
66bed4217f | ||
|
|
56bbf6593a | ||
|
|
b8e1e7c384 | ||
|
|
a0d2c39f45 | ||
|
|
07df3186c2 | ||
|
|
5b59e74417 | ||
|
|
b4485f028d | ||
|
|
74674cfa0c | ||
|
|
f192c17c9b | ||
|
|
aa1ac29182 | ||
|
|
081ac6bf8b | ||
|
|
e4b32343ae | ||
|
|
c93370ec92 | ||
|
|
9abd7f2767 | ||
|
|
8a9877bb01 | ||
|
|
c1e1476fa6 | ||
|
|
b1abbb8e77 | ||
|
|
fcb0660def | ||
|
|
a6073e2a42 | ||
|
|
2c87077918 | ||
|
|
4e0a9f62b9 | ||
|
|
39636f5293 | ||
|
|
b53124e708 | ||
|
|
9a684c9ff5 | ||
|
|
c7d1620c1e | ||
|
|
325b54031c | ||
|
|
155a9d6266 | ||
|
|
4f6fb44f79 | ||
|
|
bfce99859f | ||
|
|
6c556d6a61 | ||
|
|
7ed42005dd | ||
|
|
aad978f5f6 | ||
|
|
c0ad4aab51 | ||
|
|
8fe0ac8195 | ||
|
|
46f8818cee | ||
|
|
118f51cc64 | ||
|
|
096d82741d | ||
|
|
b98cb31fd2 | ||
|
|
90813ce030 | ||
|
|
95bc52b2bc | ||
|
|
d79e4b5853 | ||
|
|
a40a6905be | ||
|
|
6b3a64ce14 | ||
|
|
4fca1600ca | ||
|
|
b1e65e6f9d | ||
|
|
381b23fe0c | ||
|
|
782c4446b2 | ||
|
|
76eaa75d04 | ||
|
|
361ed536a3 | ||
|
|
b1d00e9812 | ||
|
|
b0abf865cb | ||
|
|
d398381b52 | ||
|
|
d75d70bee5 | ||
|
|
296f1e90b5 | ||
|
|
9d3dfbbece | ||
|
|
d6d592f099 | ||
|
|
00cb1b6643 | ||
|
|
22babad789 | ||
|
|
18ff905746 | ||
|
|
fd0d761b92 | ||
|
|
750d4f9eca | ||
|
|
5ca151b675 | ||
|
|
67fd65d366 | ||
|
|
45981f2fee | ||
|
|
cf308fc118 |
165 changed files with 2388 additions and 1210 deletions
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
|
@ -15,12 +15,12 @@ jobs:
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: '8.x.x'
|
dotnet-version: '9.x.x'
|
||||||
- name: Restore dependencies
|
- name: Restore dependencies
|
||||||
run: dotnet restore
|
run: dotnet restore
|
||||||
- name: Download Dalamud
|
- name: Download Dalamud
|
||||||
run: |
|
run: |
|
||||||
Invoke-WebRequest -Uri https://goatcorp.github.io/dalamud-distrib/latest.zip -OutFile latest.zip
|
Invoke-WebRequest -Uri https://goatcorp.github.io/dalamud-distrib/stg/latest.zip -OutFile latest.zip
|
||||||
Expand-Archive -Force latest.zip "$env:AppData\XIVLauncher\addon\Hooks\dev"
|
Expand-Archive -Force latest.zip "$env:AppData\XIVLauncher\addon\Hooks\dev"
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
2
.github/workflows/test_release.yml
vendored
2
.github/workflows/test_release.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: '8.x.x'
|
dotnet-version: '9.x.x'
|
||||||
- name: Restore dependencies
|
- name: Restore dependencies
|
||||||
run: dotnet restore
|
run: dotnet restore
|
||||||
- name: Download Dalamud
|
- name: Download Dalamud
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9f9bdf0873899d2e45fabaca446bb1624303b418
|
Subproject commit 59a7ab5fa9941eb754757b62e4cb189e455e9514
|
||||||
|
|
@ -7,6 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
.github\workflows\release.yml = .github\workflows\release.yml
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
|
Glamourer\Glamourer.json = Glamourer\Glamourer.json
|
||||||
repo.json = repo.json
|
repo.json = repo.json
|
||||||
.github\workflows\test_release.yml = .github\workflows\test_release.yml
|
.github\workflows\test_release.yml = .github\workflows\test_release.yml
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
|
|
@ -29,30 +30,30 @@ Global
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{01EB903D-871F-4285-A8CF-6486561D5B5B}.Release|Any CPU.Build.0 = Release|x64
|
||||||
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}.Release|Any CPU.Build.0 = Release|x64
|
||||||
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C0A2FAF8-C3AE-4B7B-ADDB-4AAC1A855428}.Release|Any CPU.Build.0 = Release|x64
|
||||||
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{AAFE22E7-0F9B-462A-AAA3-6EE3B268F3F8}.Release|Any CPU.Build.0 = Release|x64
|
||||||
{EF233CE2-F243-449E-BE05-72B9D110E419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{EF233CE2-F243-449E-BE05-72B9D110E419}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{EF233CE2-F243-449E-BE05-72B9D110E419}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EF233CE2-F243-449E-BE05-72B9D110E419}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{EF233CE2-F243-449E-BE05-72B9D110E419}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EF233CE2-F243-449E-BE05-72B9D110E419}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{EF233CE2-F243-449E-BE05-72B9D110E419}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EF233CE2-F243-449E-BE05-72B9D110E419}.Release|Any CPU.Build.0 = Release|x64
|
||||||
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Release|Any CPU.Build.0 = Release|Any CPU
|
{9B46691B-FAB2-4CC3-9B89-C8B91A590F47}.Release|Any CPU.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,43 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using OtterGui;
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
using ObjectManager = Glamourer.Interop.ObjectManager;
|
|
||||||
|
|
||||||
namespace Glamourer.Api;
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorManager actors) : IApiService
|
public class ApiHelpers(ActorObjectManager objects, StateManager stateManager, ActorManager actors) : IApiService
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
internal IEnumerable<ActorState> FindExistingStates(string actorName)
|
internal IEnumerable<ActorState> FindExistingStates(string actorName, ushort worldId = ushort.MaxValue)
|
||||||
{
|
{
|
||||||
if (actorName.Length == 0 || !ByteString.FromString(actorName, out var byteString))
|
if (actorName.Length == 0 || !ByteString.FromString(actorName, out var byteString))
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
foreach (var state in stateManager.Values.Where(state
|
if (worldId == WorldId.AnyWorld.Id)
|
||||||
=> state.Identifier.Type is IdentifierType.Player && state.Identifier.PlayerName == byteString))
|
{
|
||||||
yield return state;
|
foreach (var state in stateManager.Values.Where(state
|
||||||
|
=> state.Identifier.Type is IdentifierType.Player && state.Identifier.PlayerName == byteString))
|
||||||
|
yield return state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var identifier = actors.CreatePlayer(byteString, worldId);
|
||||||
|
if (stateManager.TryGetValue(identifier, out var state))
|
||||||
|
yield return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
internal GlamourerApiEc FindExistingState(int objectIndex, out ActorState? state)
|
internal GlamourerApiEc FindExistingState(int objectIndex, out ActorState? state)
|
||||||
{
|
{
|
||||||
var actor = objects[objectIndex];
|
var actor = objects.Objects[objectIndex];
|
||||||
var identifier = actor.GetIdentifier(actors);
|
var identifier = actor.GetIdentifier(actors);
|
||||||
if (!identifier.IsValid)
|
if (!identifier.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -42,7 +52,7 @@ public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorM
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
internal ActorState? FindState(int objectIndex)
|
internal ActorState? FindState(int objectIndex)
|
||||||
{
|
{
|
||||||
var actor = objects[objectIndex];
|
var actor = objects.Objects[objectIndex];
|
||||||
var identifier = actor.GetIdentifier(actors);
|
var identifier = actor.GetIdentifier(actors);
|
||||||
if (identifier.IsValid && stateManager.GetOrCreate(identifier, actor, out var state))
|
if (identifier.IsValid && stateManager.GetOrCreate(identifier, actor, out var state))
|
||||||
return state;
|
return state;
|
||||||
|
|
@ -73,10 +83,8 @@ public class ApiHelpers(ObjectManager objects, StateManager stateManager, ActorM
|
||||||
if (objectName.Length == 0 || !ByteString.FromString(objectName, out var byteString))
|
if (objectName.Length == 0 || !ByteString.FromString(objectName, out var byteString))
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
objects.Update();
|
|
||||||
|
|
||||||
return stateManager.Values.Where(state => state.Identifier.Type is IdentifierType.Player && state.Identifier.PlayerName == byteString)
|
return stateManager.Values.Where(state => state.Identifier.Type is IdentifierType.Player && state.Identifier.PlayerName == byteString)
|
||||||
.Concat(objects.Identifiers
|
.Concat(objects
|
||||||
.Where(kvp => kvp.Key is { IsValid: true, Type: IdentifierType.Player } && kvp.Key.PlayerName == byteString)
|
.Where(kvp => kvp.Key is { IsValid: true, Type: IdentifierType.Player } && kvp.Key.PlayerName == byteString)
|
||||||
.SelectWhere(kvp =>
|
.SelectWhere(kvp =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,32 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
||||||
namespace Glamourer.Api;
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager stateManager) : IGlamourerApiDesigns, IApiService
|
public class DesignsApi(
|
||||||
|
ApiHelpers helpers,
|
||||||
|
DesignManager designs,
|
||||||
|
StateManager stateManager,
|
||||||
|
DesignFileSystem fileSystem,
|
||||||
|
DesignColors color,
|
||||||
|
DesignConverter converter)
|
||||||
|
: IGlamourerApiDesigns, IApiService
|
||||||
{
|
{
|
||||||
public Dictionary<Guid, string> GetDesignList()
|
public Dictionary<Guid, string> GetDesignList()
|
||||||
=> designs.Designs.ToDictionary(d => d.Identifier, d => d.Name.Text);
|
=> designs.Designs.ToDictionary(d => d.Identifier, d => d.Name.Text);
|
||||||
|
|
||||||
|
public Dictionary<Guid, (string DisplayName, string FullPath, uint DisplayColor, bool ShownInQdb)> GetDesignListExtended()
|
||||||
|
=> fileSystem.ToDictionary(kvp => kvp.Key.Identifier,
|
||||||
|
kvp => (kvp.Key.Name.Text, kvp.Value.FullName(), color.GetColor(kvp.Key), kvp.Key.QuickDesign));
|
||||||
|
|
||||||
|
public (string DisplayName, string FullPath, uint DisplayColor, bool ShowInQdb) GetExtendedDesignData(Guid designId)
|
||||||
|
=> designs.Designs.ByIdentifier(designId) is { } d
|
||||||
|
? (d.Name.Text, fileSystem.TryGetValue(d, out var leaf) ? leaf.FullName() : d.Name.Text, color.GetColor(d), d.QuickDesign)
|
||||||
|
: (string.Empty, string.Empty, 0, false);
|
||||||
|
|
||||||
public GlamourerApiEc ApplyDesign(Guid designId, int objectIndex, uint key, ApplyFlag flags)
|
public GlamourerApiEc ApplyDesign(Guid designId, int objectIndex, uint key, ApplyFlag flags)
|
||||||
{
|
{
|
||||||
var args = ApiHelpers.Args("Design", designId, "Index", objectIndex, "Key", key, "Flags", flags);
|
var args = ApiHelpers.Args("Design", designId, "Index", objectIndex, "Key", key, "Flags", flags);
|
||||||
|
|
@ -66,4 +83,56 @@ public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager
|
||||||
|
|
||||||
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public (GlamourerApiEc, Guid) AddDesign(string designInput, string name)
|
||||||
|
{
|
||||||
|
var args = ApiHelpers.Args("DesignData", designInput, "Name", name);
|
||||||
|
|
||||||
|
if (converter.FromBase64(designInput, true, true, out _) is not { } designBase)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var jObj = JObject.Parse(designInput);
|
||||||
|
designBase = converter.FromJObject(jObj, true, true);
|
||||||
|
if (designBase is null)
|
||||||
|
return (ApiHelpers.Return(GlamourerApiEc.CouldNotParse, args), Guid.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Glamourer.Log.Error($"Failure parsing data for AddDesign due to\n{ex}");
|
||||||
|
return (ApiHelpers.Return(GlamourerApiEc.CouldNotParse, args), Guid.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var design = designBase is Design d
|
||||||
|
? designs.CreateClone(d, name, true)
|
||||||
|
: designs.CreateClone(designBase, name, true);
|
||||||
|
return (ApiHelpers.Return(GlamourerApiEc.Success, args), design.Identifier);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Glamourer.Log.Error($"Unknown error creating design via IPC:\n{ex}");
|
||||||
|
return (ApiHelpers.Return(GlamourerApiEc.UnknownError, args), Guid.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlamourerApiEc DeleteDesign(Guid designId)
|
||||||
|
{
|
||||||
|
var args = ApiHelpers.Args("DesignId", designId);
|
||||||
|
if (designs.Designs.ByIdentifier(designId) is not { } design)
|
||||||
|
return ApiHelpers.Return(GlamourerApiEc.NothingDone, args);
|
||||||
|
|
||||||
|
designs.Delete(design);
|
||||||
|
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? GetDesignBase64(Guid designId)
|
||||||
|
=> designs.Designs.ByIdentifier(designId) is { } design
|
||||||
|
? converter.ShareBase64(design)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
public JObject? GetDesignJObject(Guid designId)
|
||||||
|
=> designs.Designs.ByIdentifier(designId) is { } design
|
||||||
|
? converter.ShareJObject(design)
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Glamourer.Api;
|
||||||
public class GlamourerApi(DesignsApi designs, StateApi state, ItemsApi items) : IGlamourerApi, IApiService
|
public class GlamourerApi(DesignsApi designs, StateApi state, ItemsApi items) : IGlamourerApi, IApiService
|
||||||
{
|
{
|
||||||
public const int CurrentApiVersionMajor = 1;
|
public const int CurrentApiVersionMajor = 1;
|
||||||
public const int CurrentApiVersionMinor = 4;
|
public const int CurrentApiVersionMinor = 7;
|
||||||
|
|
||||||
public (int Major, int Minor) ApiVersion
|
public (int Major, int Minor) ApiVersion
|
||||||
=> (CurrentApiVersionMajor, CurrentApiVersionMinor);
|
=> (CurrentApiVersionMajor, CurrentApiVersionMinor);
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,14 @@ public sealed class IpcProviders : IDisposable, IApiService
|
||||||
IpcSubscribers.ApiVersion.Provider(pi, api),
|
IpcSubscribers.ApiVersion.Provider(pi, api),
|
||||||
|
|
||||||
IpcSubscribers.GetDesignList.Provider(pi, api.Designs),
|
IpcSubscribers.GetDesignList.Provider(pi, api.Designs),
|
||||||
|
IpcSubscribers.GetDesignListExtended.Provider(pi, api.Designs),
|
||||||
|
IpcSubscribers.GetExtendedDesignData.Provider(pi, api.Designs),
|
||||||
IpcSubscribers.ApplyDesign.Provider(pi, api.Designs),
|
IpcSubscribers.ApplyDesign.Provider(pi, api.Designs),
|
||||||
IpcSubscribers.ApplyDesignName.Provider(pi, api.Designs),
|
IpcSubscribers.ApplyDesignName.Provider(pi, api.Designs),
|
||||||
|
IpcSubscribers.AddDesign.Provider(pi, api.Designs),
|
||||||
|
IpcSubscribers.DeleteDesign.Provider(pi, api.Designs),
|
||||||
|
IpcSubscribers.GetDesignBase64.Provider(pi, api.Designs),
|
||||||
|
IpcSubscribers.GetDesignJObject.Provider(pi, api.Designs),
|
||||||
|
|
||||||
IpcSubscribers.SetItem.Provider(pi, api.Items),
|
IpcSubscribers.SetItem.Provider(pi, api.Items),
|
||||||
IpcSubscribers.SetItemName.Provider(pi, api.Items),
|
IpcSubscribers.SetItemName.Provider(pi, api.Items),
|
||||||
|
|
@ -36,6 +42,8 @@ public sealed class IpcProviders : IDisposable, IApiService
|
||||||
(a, b, c, d, e, f) => (int)api.Items.SetItemName(a, (ApiEquipSlot)b, c, [d], e, (ApplyFlag)f)),
|
(a, b, c, d, e, f) => (int)api.Items.SetItemName(a, (ApiEquipSlot)b, c, [d], e, (ApplyFlag)f)),
|
||||||
IpcSubscribers.SetBonusItem.Provider(pi, api.Items),
|
IpcSubscribers.SetBonusItem.Provider(pi, api.Items),
|
||||||
IpcSubscribers.SetBonusItemName.Provider(pi, api.Items),
|
IpcSubscribers.SetBonusItemName.Provider(pi, api.Items),
|
||||||
|
IpcSubscribers.SetMetaState.Provider(pi, api.Items),
|
||||||
|
IpcSubscribers.SetMetaStateName.Provider(pi, api.Items),
|
||||||
IpcSubscribers.GetState.Provider(pi, api.State),
|
IpcSubscribers.GetState.Provider(pi, api.State),
|
||||||
IpcSubscribers.GetStateName.Provider(pi, api.State),
|
IpcSubscribers.GetStateName.Provider(pi, api.State),
|
||||||
IpcSubscribers.GetStateBase64.Provider(pi, api.State),
|
IpcSubscribers.GetStateBase64.Provider(pi, api.State),
|
||||||
|
|
@ -46,6 +54,7 @@ public sealed class IpcProviders : IDisposable, IApiService
|
||||||
IpcSubscribers.RevertStateName.Provider(pi, api.State),
|
IpcSubscribers.RevertStateName.Provider(pi, api.State),
|
||||||
IpcSubscribers.UnlockState.Provider(pi, api.State),
|
IpcSubscribers.UnlockState.Provider(pi, api.State),
|
||||||
IpcSubscribers.UnlockStateName.Provider(pi, api.State),
|
IpcSubscribers.UnlockStateName.Provider(pi, api.State),
|
||||||
|
IpcSubscribers.DeletePlayerState.Provider(pi, api.State),
|
||||||
IpcSubscribers.UnlockAll.Provider(pi, api.State),
|
IpcSubscribers.UnlockAll.Provider(pi, api.State),
|
||||||
IpcSubscribers.RevertToAutomation.Provider(pi, api.State),
|
IpcSubscribers.RevertToAutomation.Provider(pi, api.State),
|
||||||
IpcSubscribers.RevertToAutomationName.Provider(pi, api.State),
|
IpcSubscribers.RevertToAutomationName.Provider(pi, api.State),
|
||||||
|
|
|
||||||
|
|
@ -4,34 +4,31 @@ using Glamourer.Automation;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Designs.History;
|
using Glamourer.Designs.History;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Interop.Structs;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
using ObjectManager = Glamourer.Interop.ObjectManager;
|
using Penumbra.GameData.Structs;
|
||||||
using StateChanged = Glamourer.Events.StateChanged;
|
using StateChanged = Glamourer.Events.StateChanged;
|
||||||
|
|
||||||
namespace Glamourer.Api;
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly ApiHelpers _helpers;
|
private readonly ApiHelpers _helpers;
|
||||||
private readonly StateManager _stateManager;
|
private readonly StateManager _stateManager;
|
||||||
private readonly DesignConverter _converter;
|
private readonly DesignConverter _converter;
|
||||||
private readonly Configuration _config;
|
private readonly AutoDesignApplier _autoDesigns;
|
||||||
private readonly AutoDesignApplier _autoDesigns;
|
private readonly ActorObjectManager _objects;
|
||||||
private readonly ObjectManager _objects;
|
private readonly StateChanged _stateChanged;
|
||||||
private readonly StateChanged _stateChanged;
|
private readonly StateFinalized _stateFinalized;
|
||||||
private readonly StateFinalized _stateFinalized;
|
private readonly GPoseService _gPose;
|
||||||
private readonly GPoseService _gPose;
|
|
||||||
|
|
||||||
public StateApi(ApiHelpers helpers,
|
public StateApi(ApiHelpers helpers,
|
||||||
StateManager stateManager,
|
StateManager stateManager,
|
||||||
DesignConverter converter,
|
DesignConverter converter,
|
||||||
Configuration config,
|
|
||||||
AutoDesignApplier autoDesigns,
|
AutoDesignApplier autoDesigns,
|
||||||
ObjectManager objects,
|
ActorObjectManager objects,
|
||||||
StateChanged stateChanged,
|
StateChanged stateChanged,
|
||||||
StateFinalized stateFinalized,
|
StateFinalized stateFinalized,
|
||||||
GPoseService gPose)
|
GPoseService gPose)
|
||||||
|
|
@ -39,7 +36,6 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||||
_helpers = helpers;
|
_helpers = helpers;
|
||||||
_stateManager = stateManager;
|
_stateManager = stateManager;
|
||||||
_converter = converter;
|
_converter = converter;
|
||||||
_config = config;
|
|
||||||
_autoDesigns = autoDesigns;
|
_autoDesigns = autoDesigns;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_stateChanged = stateChanged;
|
_stateChanged = stateChanged;
|
||||||
|
|
@ -204,6 +200,27 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||||
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GlamourerApiEc DeletePlayerState(string playerName, ushort worldId, uint key)
|
||||||
|
{
|
||||||
|
var args = ApiHelpers.Args("Name", playerName, "World", worldId, "Key", key);
|
||||||
|
var states = _helpers.FindExistingStates(playerName).ToList();
|
||||||
|
if (states.Count is 0)
|
||||||
|
return ApiHelpers.Return(GlamourerApiEc.NothingDone, args);
|
||||||
|
|
||||||
|
var anyLocked = false;
|
||||||
|
foreach (var state in states)
|
||||||
|
{
|
||||||
|
if (state.CanUnlock(key))
|
||||||
|
_stateManager.DeleteState(state.Identifier);
|
||||||
|
else
|
||||||
|
anyLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiHelpers.Return(anyLocked
|
||||||
|
? GlamourerApiEc.InvalidKey
|
||||||
|
: GlamourerApiEc.Success, args);
|
||||||
|
}
|
||||||
|
|
||||||
public int UnlockAll(uint key)
|
public int UnlockAll(uint key)
|
||||||
=> _stateManager.Values.Count(state => state.Unlock(key));
|
=> _stateManager.Values.Count(state => state.Unlock(key));
|
||||||
|
|
||||||
|
|
@ -219,7 +236,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||||
if (!state.CanUnlock(key))
|
if (!state.CanUnlock(key))
|
||||||
return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args);
|
return ApiHelpers.Return(GlamourerApiEc.InvalidKey, args);
|
||||||
|
|
||||||
RevertToAutomation(_objects[objectIndex], state, key, flags);
|
RevertToAutomation(_objects.Objects[objectIndex], state, key, flags);
|
||||||
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
return ApiHelpers.Return(GlamourerApiEc.Success, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,15 +289,9 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||||
var source = (flags & ApplyFlag.Once) != 0 ? StateSource.IpcManual : StateSource.IpcFixed;
|
var source = (flags & ApplyFlag.Once) != 0 ? StateSource.IpcManual : StateSource.IpcFixed;
|
||||||
switch (flags & (ApplyFlag.Equipment | ApplyFlag.Customization))
|
switch (flags & (ApplyFlag.Equipment | ApplyFlag.Customization))
|
||||||
{
|
{
|
||||||
case ApplyFlag.Equipment:
|
case ApplyFlag.Equipment: _stateManager.ResetEquip(state, source, key); break;
|
||||||
_stateManager.ResetEquip(state, source, key);
|
case ApplyFlag.Customization: _stateManager.ResetCustomize(state, source, key); break;
|
||||||
break;
|
case ApplyFlag.Equipment | ApplyFlag.Customization: _stateManager.ResetState(state, source, key, true); break;
|
||||||
case ApplyFlag.Customization:
|
|
||||||
_stateManager.ResetCustomize(state, source, key);
|
|
||||||
break;
|
|
||||||
case ApplyFlag.Equipment | ApplyFlag.Customization:
|
|
||||||
_stateManager.ResetState(state, source, key);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiHelpers.Lock(state, key, flags);
|
ApiHelpers.Lock(state, key, flags);
|
||||||
|
|
@ -288,7 +299,6 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
|
||||||
|
|
||||||
private GlamourerApiEc RevertToAutomation(ActorState state, uint key, ApplyFlag flags)
|
private GlamourerApiEc RevertToAutomation(ActorState state, uint key, ApplyFlag flags)
|
||||||
{
|
{
|
||||||
_objects.Update();
|
|
||||||
if (!_objects.TryGetValue(state.Identifier, out var actors) || !actors.Valid)
|
if (!_objects.TryGetValue(state.Identifier, out var actors) || !actors.Valid)
|
||||||
return GlamourerApiEc.ActorNotFound;
|
return GlamourerApiEc.ActorNotFound;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public static class ApplicationTypeExtensions
|
||||||
var customizeFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeFlagExtensions.All : 0;
|
var customizeFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeFlagExtensions.All : 0;
|
||||||
var parameterFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeParameterExtensions.All : 0;
|
var parameterFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeParameterExtensions.All : 0;
|
||||||
var crestFlags = type.HasFlag(ApplicationType.GearCustomization) ? CrestExtensions.AllRelevant : 0;
|
var crestFlags = type.HasFlag(ApplicationType.GearCustomization) ? CrestExtensions.AllRelevant : 0;
|
||||||
var metaFlags = (type.HasFlag(ApplicationType.Armor) ? MetaFlag.HatState | MetaFlag.VisorState : 0)
|
var metaFlags = (type.HasFlag(ApplicationType.Armor) ? MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.EarState : 0)
|
||||||
| (type.HasFlag(ApplicationType.Weapons) ? MetaFlag.WeaponState : 0)
|
| (type.HasFlag(ApplicationType.Weapons) ? MetaFlag.WeaponState : 0)
|
||||||
| (type.HasFlag(ApplicationType.Customizations) ? MetaFlag.Wetness : 0);
|
| (type.HasFlag(ApplicationType.Customizations) ? MetaFlag.Wetness : 0);
|
||||||
var bonusFlags = type.HasFlag(ApplicationType.Armor) ? BonusExtensions.All : 0;
|
var bonusFlags = type.HasFlag(ApplicationType.Armor) ? BonusExtensions.All : 0;
|
||||||
|
|
@ -47,7 +47,13 @@ public static class ApplicationTypeExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ApplicationCollection ApplyWhat(this ApplicationType type, IDesignStandIn designStandIn)
|
public static ApplicationCollection ApplyWhat(this ApplicationType type, IDesignStandIn designStandIn)
|
||||||
=> designStandIn is not DesignBase design ? type.Collection() : type.Collection().Restrict(design.Application);
|
{
|
||||||
|
if(designStandIn is not DesignBase design)
|
||||||
|
return type.Collection();
|
||||||
|
var ret = type.Collection().Restrict(design.Application);
|
||||||
|
ret.CustomizeRaw = ret.CustomizeRaw.FixApplication(design.CustomizeSet);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public const EquipFlag WeaponFlags = EquipFlag.Mainhand | EquipFlag.Offhand;
|
public const EquipFlag WeaponFlags = EquipFlag.Mainhand | EquipFlag.Offhand;
|
||||||
public const EquipFlag ArmorFlags = EquipFlag.Head | EquipFlag.Body | EquipFlag.Hands | EquipFlag.Legs | EquipFlag.Feet;
|
public const EquipFlag ArmorFlags = EquipFlag.Head | EquipFlag.Body | EquipFlag.Hands | EquipFlag.Legs | EquipFlag.Feet;
|
||||||
|
|
|
||||||
|
|
@ -11,29 +11,28 @@ using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using ObjectManager = Glamourer.Interop.ObjectManager;
|
|
||||||
|
|
||||||
namespace Glamourer.Automation;
|
namespace Glamourer.Automation;
|
||||||
|
|
||||||
public sealed class AutoDesignApplier : IDisposable
|
public sealed class AutoDesignApplier : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly AutoDesignManager _manager;
|
private readonly AutoDesignManager _manager;
|
||||||
private readonly StateManager _state;
|
private readonly StateManager _state;
|
||||||
private readonly JobService _jobs;
|
private readonly JobService _jobs;
|
||||||
private readonly EquippedGearset _equippedGearset;
|
private readonly EquippedGearset _equippedGearset;
|
||||||
private readonly ActorManager _actors;
|
private readonly ActorManager _actors;
|
||||||
private readonly AutomationChanged _event;
|
private readonly AutomationChanged _event;
|
||||||
private readonly ObjectManager _objects;
|
private readonly ActorObjectManager _objects;
|
||||||
private readonly WeaponLoading _weapons;
|
private readonly WeaponLoading _weapons;
|
||||||
private readonly HumanModelList _humans;
|
private readonly HumanModelList _humans;
|
||||||
private readonly DesignMerger _designMerger;
|
private readonly DesignMerger _designMerger;
|
||||||
private readonly IClientState _clientState;
|
private readonly IClientState _clientState;
|
||||||
|
|
||||||
private readonly JobChangeState _jobChangeState;
|
private readonly JobChangeState _jobChangeState;
|
||||||
|
|
||||||
public AutoDesignApplier(Configuration config, AutoDesignManager manager, StateManager state, JobService jobs, ActorManager actors,
|
public AutoDesignApplier(Configuration config, AutoDesignManager manager, StateManager state, JobService jobs, ActorManager actors,
|
||||||
AutomationChanged @event, ObjectManager objects, WeaponLoading weapons, HumanModelList humans, IClientState clientState,
|
AutomationChanged @event, ActorObjectManager objects, WeaponLoading weapons, HumanModelList humans, IClientState clientState,
|
||||||
EquippedGearset equippedGearset, DesignMerger designMerger, JobChangeState jobChangeState)
|
EquippedGearset equippedGearset, DesignMerger designMerger, JobChangeState jobChangeState)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
@ -154,7 +153,6 @@ public sealed class AutoDesignApplier : IDisposable
|
||||||
if (newSet is not { Enabled: true })
|
if (newSet is not { Enabled: true })
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_objects.Update();
|
|
||||||
foreach (var id in newSet.Identifiers)
|
foreach (var id in newSet.Identifiers)
|
||||||
{
|
{
|
||||||
if (_objects.TryGetValue(id, out var data))
|
if (_objects.TryGetValue(id, out var data))
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using Glamourer.Services;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||||
|
|
@ -31,6 +32,7 @@ public class DefaultDesignSettings
|
||||||
public bool ResetAdvancedDyes = false;
|
public bool ResetAdvancedDyes = false;
|
||||||
public bool ShowQuickDesignBar = true;
|
public bool ShowQuickDesignBar = true;
|
||||||
public bool ResetTemporarySettings = false;
|
public bool ResetTemporarySettings = false;
|
||||||
|
public bool Locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Configuration : IPluginConfiguration, ISavable
|
public class Configuration : IPluginConfiguration, ISavable
|
||||||
|
|
@ -38,33 +40,37 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly EphemeralConfig Ephemeral;
|
public readonly EphemeralConfig Ephemeral;
|
||||||
|
|
||||||
public bool UseRestrictedGearProtection { get; set; } = false;
|
public bool AttachToPcp { get; set; } = true;
|
||||||
public bool OpenFoldersByDefault { get; set; } = false;
|
public bool UseRestrictedGearProtection { get; set; } = false;
|
||||||
public bool AutoRedrawEquipOnChanges { get; set; } = false;
|
public bool OpenFoldersByDefault { get; set; } = false;
|
||||||
public bool EnableAutoDesigns { get; set; } = true;
|
public bool AutoRedrawEquipOnChanges { get; set; } = false;
|
||||||
public bool HideApplyCheckmarks { get; set; } = false;
|
public bool EnableAutoDesigns { get; set; } = true;
|
||||||
public bool SmallEquip { get; set; } = false;
|
public bool HideApplyCheckmarks { get; set; } = false;
|
||||||
public bool UnlockedItemMode { get; set; } = false;
|
public bool SmallEquip { get; set; } = false;
|
||||||
public byte DisableFestivals { get; set; } = 1;
|
public bool UnlockedItemMode { get; set; } = false;
|
||||||
public bool EnableGameContextMenu { get; set; } = true;
|
public byte DisableFestivals { get; set; } = 1;
|
||||||
public bool HideWindowInCutscene { get; set; } = false;
|
public bool EnableGameContextMenu { get; set; } = true;
|
||||||
public bool ShowAutomationSetEditing { get; set; } = true;
|
public bool HideWindowInCutscene { get; set; } = false;
|
||||||
public bool ShowAllAutomatedApplicationRules { get; set; } = true;
|
public bool ShowAutomationSetEditing { get; set; } = true;
|
||||||
public bool ShowUnlockedItemWarnings { get; set; } = true;
|
public bool ShowAllAutomatedApplicationRules { get; set; } = true;
|
||||||
public bool RevertManualChangesOnZoneChange { get; set; } = false;
|
public bool ShowUnlockedItemWarnings { get; set; } = true;
|
||||||
public bool ShowQuickBarInTabs { get; set; } = true;
|
public bool RevertManualChangesOnZoneChange { get; set; } = false;
|
||||||
public bool OpenWindowAtStart { get; set; } = false;
|
public bool ShowQuickBarInTabs { get; set; } = true;
|
||||||
public bool ShowWindowWhenUiHidden { get; set; } = false;
|
public bool OpenWindowAtStart { get; set; } = false;
|
||||||
public bool KeepAdvancedDyesAttached { get; set; } = true;
|
public bool ShowWindowWhenUiHidden { get; set; } = false;
|
||||||
public bool ShowPalettePlusImport { get; set; } = true;
|
public bool KeepAdvancedDyesAttached { get; set; } = true;
|
||||||
public bool UseFloatForColors { get; set; } = true;
|
public bool ShowPalettePlusImport { get; set; } = true;
|
||||||
public bool UseRgbForColors { get; set; } = true;
|
public bool UseFloatForColors { get; set; } = true;
|
||||||
public bool ShowColorConfig { get; set; } = true;
|
public bool UseRgbForColors { get; set; } = true;
|
||||||
public bool ChangeEntireItem { get; set; } = false;
|
public bool ShowColorConfig { get; set; } = true;
|
||||||
public bool AlwaysApplyAssociatedMods { get; set; } = false;
|
public bool ChangeEntireItem { get; set; } = false;
|
||||||
public bool UseTemporarySettings { get; set; } = true;
|
public bool AlwaysApplyAssociatedMods { get; set; } = true;
|
||||||
public bool AllowDoubleClickToApply { get; set; } = false;
|
public bool UseTemporarySettings { get; set; } = true;
|
||||||
public bool RespectManualOnAutomationUpdate { get; set; } = false;
|
public bool AllowDoubleClickToApply { get; set; } = false;
|
||||||
|
public bool RespectManualOnAutomationUpdate { get; set; } = false;
|
||||||
|
public bool PreventRandomRepeats { get; set; } = false;
|
||||||
|
public string PcpFolder { get; set; } = "PCP";
|
||||||
|
public string PcpColor { get; set; } = "";
|
||||||
|
|
||||||
public DesignPanelFlag HideDesignPanel { get; set; } = 0;
|
public DesignPanelFlag HideDesignPanel { get; set; } = 0;
|
||||||
public DesignPanelFlag AutoExpandDesignPanel { get; set; } = 0;
|
public DesignPanelFlag AutoExpandDesignPanel { get; set; } = 0;
|
||||||
|
|
@ -75,10 +81,11 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
|
public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
|
||||||
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
||||||
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
||||||
|
public DoubleModifier IncognitoModifier { get; set; } = new(ModifierHotkey.Control);
|
||||||
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
||||||
|
|
||||||
public QdbButtons QdbButtons { get; set; } =
|
public QdbButtons QdbButtons { get; set; } =
|
||||||
QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvanced;
|
QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvancedDyes;
|
||||||
|
|
||||||
[JsonConverter(typeof(SortModeConverter))]
|
[JsonConverter(typeof(SortModeConverter))]
|
||||||
[JsonProperty(Order = int.MaxValue)]
|
[JsonProperty(Order = int.MaxValue)]
|
||||||
|
|
@ -155,7 +162,7 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
|
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public const int CurrentVersion = 7;
|
public const int CurrentVersion = 8;
|
||||||
|
|
||||||
public static readonly ISortMode<Design>[] ValidSortModes =
|
public static readonly ISortMode<Design>[] ValidSortModes =
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using OtterGui.Text.EndObjects;
|
using OtterGui.Text.EndObjects;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
namespace Glamourer.Designs;
|
namespace Glamourer.Designs;
|
||||||
|
|
@ -19,13 +19,13 @@ public record struct ApplicationCollection(
|
||||||
public static readonly ApplicationCollection None = new(0, 0, CustomizeFlag.BodyType, 0, 0, 0);
|
public static readonly ApplicationCollection None = new(0, 0, CustomizeFlag.BodyType, 0, 0, 0);
|
||||||
|
|
||||||
public static readonly ApplicationCollection Equipment = new(EquipFlagExtensions.All, BonusExtensions.All,
|
public static readonly ApplicationCollection Equipment = new(EquipFlagExtensions.All, BonusExtensions.All,
|
||||||
CustomizeFlag.BodyType, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.WeaponState | MetaFlag.VisorState);
|
CustomizeFlag.BodyType, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.WeaponState | MetaFlag.VisorState | MetaFlag.EarState);
|
||||||
|
|
||||||
public static readonly ApplicationCollection Customizations = new(0, 0, CustomizeFlagExtensions.AllRelevant, 0,
|
public static readonly ApplicationCollection Customizations = new(0, 0, CustomizeFlagExtensions.AllRelevant, 0,
|
||||||
CustomizeParameterExtensions.All, MetaFlag.Wetness);
|
CustomizeParameterExtensions.All, MetaFlag.Wetness);
|
||||||
|
|
||||||
public static readonly ApplicationCollection Default = new(EquipFlagExtensions.All, BonusExtensions.All,
|
public static readonly ApplicationCollection Default = new(EquipFlagExtensions.All, BonusExtensions.All,
|
||||||
CustomizeFlagExtensions.AllRelevant, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState);
|
CustomizeFlagExtensions.AllRelevant, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState | MetaFlag.EarState);
|
||||||
|
|
||||||
public static ApplicationCollection FromKeys()
|
public static ApplicationCollection FromKeys()
|
||||||
=> (ImGui.GetIO().KeyCtrl, ImGui.GetIO().KeyShift) switch
|
=> (ImGui.GetIO().KeyCtrl, ImGui.GetIO().KeyShift) switch
|
||||||
|
|
@ -47,7 +47,7 @@ public record struct ApplicationCollection(
|
||||||
Equip = 0;
|
Equip = 0;
|
||||||
BonusItem = 0;
|
BonusItem = 0;
|
||||||
Crest = 0;
|
Crest = 0;
|
||||||
Meta &= ~(MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState);
|
Meta &= ~(MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState | MetaFlag.EarState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveCustomize()
|
public void RemoveCustomize()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
namespace Glamourer.Designs;
|
namespace Glamourer.Designs;
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn
|
||||||
|
|
||||||
public new JObject JsonSerialize()
|
public new JObject JsonSerialize()
|
||||||
{
|
{
|
||||||
var ret = new JObject()
|
var ret = new JObject
|
||||||
{
|
{
|
||||||
["FileVersion"] = FileVersion,
|
["FileVersion"] = FileVersion,
|
||||||
["Identifier"] = Identifier,
|
["Identifier"] = Identifier,
|
||||||
|
|
@ -131,12 +131,17 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn
|
||||||
var ret = new JArray();
|
var ret = new JArray();
|
||||||
foreach (var (mod, settings) in AssociatedMods)
|
foreach (var (mod, settings) in AssociatedMods)
|
||||||
{
|
{
|
||||||
var obj = new JObject()
|
var obj = new JObject
|
||||||
{
|
{
|
||||||
["Name"] = mod.Name,
|
["Name"] = mod.Name,
|
||||||
["Directory"] = mod.DirectoryName,
|
["Directory"] = mod.DirectoryName,
|
||||||
["Enabled"] = settings.Enabled,
|
|
||||||
};
|
};
|
||||||
|
if (settings.Remove)
|
||||||
|
obj["Remove"] = true;
|
||||||
|
else if (settings.ForceInherit)
|
||||||
|
obj["Inherit"] = true;
|
||||||
|
else
|
||||||
|
obj["Enabled"] = settings.Enabled;
|
||||||
if (settings.Enabled)
|
if (settings.Enabled)
|
||||||
{
|
{
|
||||||
obj["Priority"] = settings.Priority;
|
obj["Priority"] = settings.Priority;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ public class DesignBase
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Used when importing .cma or .chara files. </summary>
|
/// <summary> Used when importing .cma or .chara files. </summary>
|
||||||
internal DesignBase(CustomizeService customize, in DesignData designData, EquipFlag equipFlags, CustomizeFlag customizeFlags, BonusItemFlag bonusFlags)
|
internal DesignBase(CustomizeService customize, in DesignData designData, EquipFlag equipFlags, CustomizeFlag customizeFlags,
|
||||||
|
BonusItemFlag bonusFlags)
|
||||||
{
|
{
|
||||||
_designData = designData;
|
_designData = designData;
|
||||||
ApplyCustomize = customizeFlags & CustomizeFlagExtensions.AllRelevant;
|
ApplyCustomize = customizeFlags & CustomizeFlagExtensions.AllRelevant;
|
||||||
|
|
@ -254,9 +255,10 @@ public class DesignBase
|
||||||
ret[slot.ToString()] = Serialize(item.Id, stains, crest, DoApplyEquip(slot), DoApplyStain(slot), DoApplyCrest(crestSlot));
|
ret[slot.ToString()] = Serialize(item.Id, stains, crest, DoApplyEquip(slot), DoApplyStain(slot), DoApplyCrest(crestSlot));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret["Hat"] = new QuadBool(_designData.IsHatVisible(), DoApplyMeta(MetaIndex.HatState)).ToJObject("Show", "Apply");
|
ret["Hat"] = new QuadBool(_designData.IsHatVisible(), DoApplyMeta(MetaIndex.HatState)).ToJObject("Show", "Apply");
|
||||||
ret["Visor"] = new QuadBool(_designData.IsVisorToggled(), DoApplyMeta(MetaIndex.VisorState)).ToJObject("IsToggled", "Apply");
|
ret["VieraEars"] = new QuadBool(_designData.AreEarsVisible(), DoApplyMeta(MetaIndex.EarState)).ToJObject("Show", "Apply");
|
||||||
ret["Weapon"] = new QuadBool(_designData.IsWeaponVisible(), DoApplyMeta(MetaIndex.WeaponState)).ToJObject("Show", "Apply");
|
ret["Visor"] = new QuadBool(_designData.IsVisorToggled(), DoApplyMeta(MetaIndex.VisorState)).ToJObject("IsToggled", "Apply");
|
||||||
|
ret["Weapon"] = new QuadBool(_designData.IsWeaponVisible(), DoApplyMeta(MetaIndex.WeaponState)).ToJObject("Show", "Apply");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -603,6 +605,10 @@ public class DesignBase
|
||||||
metaValue = QuadBool.FromJObject(equip["Visor"], "IsToggled", "Apply", QuadBool.NullFalse);
|
metaValue = QuadBool.FromJObject(equip["Visor"], "IsToggled", "Apply", QuadBool.NullFalse);
|
||||||
design.SetApplyMeta(MetaIndex.VisorState, metaValue.Enabled);
|
design.SetApplyMeta(MetaIndex.VisorState, metaValue.Enabled);
|
||||||
design._designData.SetVisor(metaValue.ForcedValue);
|
design._designData.SetVisor(metaValue.ForcedValue);
|
||||||
|
|
||||||
|
metaValue = QuadBool.FromJObject(equip["VieraEars"], "Show", "Apply", QuadBool.NullTrue);
|
||||||
|
design.SetApplyMeta(MetaIndex.EarState, metaValue.Enabled);
|
||||||
|
design._designData.SetEarsVisible(metaValue.ForcedValue);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void PrintWarning(string msg)
|
void PrintWarning(string msg)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,12 @@ using Dalamud.Interface.ImGuiNotification;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using Glamourer.Gui;
|
using Glamourer.Gui;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
|
|
||||||
namespace Glamourer.Designs;
|
namespace Glamourer.Designs;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,7 @@ public unsafe struct DesignData
|
||||||
MetaIndex.HatState => IsHatVisible(),
|
MetaIndex.HatState => IsHatVisible(),
|
||||||
MetaIndex.VisorState => IsVisorToggled(),
|
MetaIndex.VisorState => IsVisorToggled(),
|
||||||
MetaIndex.WeaponState => IsWeaponVisible(),
|
MetaIndex.WeaponState => IsWeaponVisible(),
|
||||||
|
MetaIndex.EarState => AreEarsVisible(),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -297,6 +298,7 @@ public unsafe struct DesignData
|
||||||
MetaIndex.HatState => SetHatVisible(value),
|
MetaIndex.HatState => SetHatVisible(value),
|
||||||
MetaIndex.VisorState => SetVisor(value),
|
MetaIndex.VisorState => SetVisor(value),
|
||||||
MetaIndex.WeaponState => SetWeaponVisible(value),
|
MetaIndex.WeaponState => SetWeaponVisible(value),
|
||||||
|
MetaIndex.EarState => SetEarsVisible(value),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -340,6 +342,9 @@ public unsafe struct DesignData
|
||||||
public readonly bool IsWeaponVisible()
|
public readonly bool IsWeaponVisible()
|
||||||
=> (_states & 0x08) == 0x08;
|
=> (_states & 0x08) == 0x08;
|
||||||
|
|
||||||
|
public readonly bool AreEarsVisible()
|
||||||
|
=> (_states & 0x10) == 0x00;
|
||||||
|
|
||||||
public bool SetWeaponVisible(bool value)
|
public bool SetWeaponVisible(bool value)
|
||||||
{
|
{
|
||||||
if (value == IsWeaponVisible())
|
if (value == IsWeaponVisible())
|
||||||
|
|
@ -349,6 +354,15 @@ public unsafe struct DesignData
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetEarsVisible(bool value)
|
||||||
|
{
|
||||||
|
if (value == AreEarsVisible())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_states = (byte)(value ? _states & ~0x10 : _states | 0x10);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetDefaultEquipment(ItemManager items)
|
public void SetDefaultEquipment(ItemManager items)
|
||||||
{
|
{
|
||||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
|
|
@ -386,6 +400,7 @@ public unsafe struct DesignData
|
||||||
|
|
||||||
SetHatVisible(true);
|
SetHatVisible(true);
|
||||||
SetWeaponVisible(true);
|
SetWeaponVisible(true);
|
||||||
|
SetEarsVisible(true);
|
||||||
SetVisor(false);
|
SetVisor(false);
|
||||||
fixed (uint* ptr = _itemIds)
|
fixed (uint* ptr = _itemIds)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,11 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||||
|
|
||||||
public struct CreationDate : ISortMode<Design>
|
public struct CreationDate : ISortMode<Design>
|
||||||
{
|
{
|
||||||
public string Name
|
public ReadOnlySpan<byte> Name
|
||||||
=> "Creation Date (Older First)";
|
=> "Creation Date (Older First)"u8;
|
||||||
|
|
||||||
public string Description
|
public ReadOnlySpan<byte> Description
|
||||||
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their creation date.";
|
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their creation date."u8;
|
||||||
|
|
||||||
public IEnumerable<IPath> GetChildren(Folder f)
|
public IEnumerable<IPath> GetChildren(Folder f)
|
||||||
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderBy(l => l.Value.CreationDate));
|
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderBy(l => l.Value.CreationDate));
|
||||||
|
|
@ -53,11 +53,11 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||||
|
|
||||||
public struct UpdateDate : ISortMode<Design>
|
public struct UpdateDate : ISortMode<Design>
|
||||||
{
|
{
|
||||||
public string Name
|
public ReadOnlySpan<byte> Name
|
||||||
=> "Update Date (Older First)";
|
=> "Update Date (Older First)"u8;
|
||||||
|
|
||||||
public string Description
|
public ReadOnlySpan<byte> Description
|
||||||
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their last update date.";
|
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their last update date."u8;
|
||||||
|
|
||||||
public IEnumerable<IPath> GetChildren(Folder f)
|
public IEnumerable<IPath> GetChildren(Folder f)
|
||||||
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderBy(l => l.Value.LastEdit));
|
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderBy(l => l.Value.LastEdit));
|
||||||
|
|
@ -65,11 +65,11 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||||
|
|
||||||
public struct InverseCreationDate : ISortMode<Design>
|
public struct InverseCreationDate : ISortMode<Design>
|
||||||
{
|
{
|
||||||
public string Name
|
public ReadOnlySpan<byte> Name
|
||||||
=> "Creation Date (Newer First)";
|
=> "Creation Date (Newer First)"u8;
|
||||||
|
|
||||||
public string Description
|
public ReadOnlySpan<byte> Description
|
||||||
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse creation date.";
|
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse creation date."u8;
|
||||||
|
|
||||||
public IEnumerable<IPath> GetChildren(Folder f)
|
public IEnumerable<IPath> GetChildren(Folder f)
|
||||||
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderByDescending(l => l.Value.CreationDate));
|
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderByDescending(l => l.Value.CreationDate));
|
||||||
|
|
@ -77,11 +77,11 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||||
|
|
||||||
public struct InverseUpdateDate : ISortMode<Design>
|
public struct InverseUpdateDate : ISortMode<Design>
|
||||||
{
|
{
|
||||||
public string Name
|
public ReadOnlySpan<byte> Name
|
||||||
=> "Update Date (Newer First)";
|
=> "Update Date (Newer First)"u8;
|
||||||
|
|
||||||
public string Description
|
public ReadOnlySpan<byte> Description
|
||||||
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse last update date.";
|
=> "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse last update date."u8;
|
||||||
|
|
||||||
public IEnumerable<IPath> GetChildren(Folder f)
|
public IEnumerable<IPath> GetChildren(Folder f)
|
||||||
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderByDescending(l => l.Value.LastEdit));
|
=> f.GetSubFolders().Cast<IPath>().Concat(f.GetLeaves().OrderByDescending(l => l.Value.LastEdit));
|
||||||
|
|
@ -114,14 +114,14 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case DesignChanged.Type.Deleted:
|
case DesignChanged.Type.Deleted:
|
||||||
if (FindLeaf(design, out var leaf1))
|
if (TryGetValue(design, out var leaf1))
|
||||||
Delete(leaf1);
|
Delete(leaf1);
|
||||||
return;
|
return;
|
||||||
case DesignChanged.Type.ReloadedAll:
|
case DesignChanged.Type.ReloadedAll:
|
||||||
Reload();
|
Reload();
|
||||||
return;
|
return;
|
||||||
case DesignChanged.Type.Renamed when (data as RenameTransaction?)?.Old is { } oldName:
|
case DesignChanged.Type.Renamed when (data as RenameTransaction?)?.Old is { } oldName:
|
||||||
if (!FindLeaf(design, out var leaf2))
|
if (!TryGetValue(design, out var leaf2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var old = oldName.FixName();
|
var old = oldName.FixName();
|
||||||
|
|
@ -150,15 +150,6 @@ public sealed class DesignFileSystem : FileSystem<Design>, IDisposable, ISavable
|
||||||
? (string.Empty, false)
|
? (string.Empty, false)
|
||||||
: (DesignToIdentifier(design), true);
|
: (DesignToIdentifier(design), true);
|
||||||
|
|
||||||
// Search the entire filesystem for the leaf corresponding to a design.
|
|
||||||
public bool FindLeaf(Design design, [NotNullWhen(true)] out Leaf? leaf)
|
|
||||||
{
|
|
||||||
leaf = Root.GetAllDescendants(ISortMode<Design>.Lexicographical)
|
|
||||||
.OfType<Leaf>()
|
|
||||||
.FirstOrDefault(l => l.Value == design);
|
|
||||||
return leaf != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void MigrateOldPaths(SaveService saveService, Dictionary<string, string> oldPaths)
|
internal static void MigrateOldPaths(SaveService saveService, Dictionary<string, string> oldPaths)
|
||||||
{
|
{
|
||||||
if (oldPaths.Count == 0)
|
if (oldPaths.Count == 0)
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,13 @@ using Glamourer.GameData;
|
||||||
using Glamourer.Interop.Material;
|
using Glamourer.Interop.Material;
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Interop.Penumbra;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
|
|
||||||
namespace Glamourer.Designs;
|
namespace Glamourer.Designs;
|
||||||
|
|
||||||
public sealed class DesignManager : DesignEditor
|
public sealed class DesignManager : DesignEditor
|
||||||
|
|
@ -110,6 +111,7 @@ public sealed class DesignManager : DesignEditor
|
||||||
QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar,
|
QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar,
|
||||||
ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings,
|
ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings,
|
||||||
};
|
};
|
||||||
|
design.SetWriteProtected(Config.DefaultDesignSettings.Locked);
|
||||||
Designs.Add(design);
|
Designs.Add(design);
|
||||||
Glamourer.Log.Debug($"Added new design {design.Identifier}.");
|
Glamourer.Log.Debug($"Added new design {design.Identifier}.");
|
||||||
SaveService.ImmediateSave(design);
|
SaveService.ImmediateSave(design);
|
||||||
|
|
@ -134,6 +136,7 @@ public sealed class DesignManager : DesignEditor
|
||||||
ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings,
|
ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
design.SetWriteProtected(Config.DefaultDesignSettings.Locked);
|
||||||
Designs.Add(design);
|
Designs.Add(design);
|
||||||
Glamourer.Log.Debug($"Added new design {design.Identifier} by cloning Temporary Design.");
|
Glamourer.Log.Debug($"Added new design {design.Identifier} by cloning Temporary Design.");
|
||||||
SaveService.ImmediateSave(design);
|
SaveService.ImmediateSave(design);
|
||||||
|
|
@ -153,6 +156,7 @@ public sealed class DesignManager : DesignEditor
|
||||||
Name = actualName,
|
Name = actualName,
|
||||||
Index = Designs.Count,
|
Index = Designs.Count,
|
||||||
};
|
};
|
||||||
|
design.SetWriteProtected(Config.DefaultDesignSettings.Locked);
|
||||||
Designs.Add(design);
|
Designs.Add(design);
|
||||||
Glamourer.Log.Debug(
|
Glamourer.Log.Debug(
|
||||||
$"Added new design {design.Identifier} by cloning {clone.Identifier.ToString()}.");
|
$"Added new design {design.Identifier} by cloning {clone.Identifier.ToString()}.");
|
||||||
|
|
@ -225,7 +229,7 @@ public sealed class DesignManager : DesignEditor
|
||||||
|
|
||||||
design.Tags = design.Tags.Append(tag).OrderBy(t => t).ToArray();
|
design.Tags = design.Tags.Append(tag).OrderBy(t => t).ToArray();
|
||||||
design.LastEdit = DateTimeOffset.UtcNow;
|
design.LastEdit = DateTimeOffset.UtcNow;
|
||||||
var idx = design.Tags.IndexOf(tag);
|
var idx = design.Tags.AsEnumerable().IndexOf(tag);
|
||||||
SaveService.QueueSave(design);
|
SaveService.QueueSave(design);
|
||||||
Glamourer.Log.Debug($"Added tag {tag} at {idx} to design {design.Identifier}.");
|
Glamourer.Log.Debug($"Added tag {tag} at {idx} to design {design.Identifier}.");
|
||||||
DesignChanged.Invoke(DesignChanged.Type.AddedTag, design, new TagAddedTransaction(tag, idx));
|
DesignChanged.Invoke(DesignChanged.Type.AddedTag, design, new TagAddedTransaction(tag, idx));
|
||||||
|
|
@ -258,7 +262,7 @@ public sealed class DesignManager : DesignEditor
|
||||||
SaveService.QueueSave(design);
|
SaveService.QueueSave(design);
|
||||||
Glamourer.Log.Debug($"Renamed tag {oldTag} at {tagIdx} to {newTag} in design {design.Identifier} and reordered tags.");
|
Glamourer.Log.Debug($"Renamed tag {oldTag} at {tagIdx} to {newTag} in design {design.Identifier} and reordered tags.");
|
||||||
DesignChanged.Invoke(DesignChanged.Type.ChangedTag, design,
|
DesignChanged.Invoke(DesignChanged.Type.ChangedTag, design,
|
||||||
new TagChangedTransaction(oldTag, newTag, tagIdx, design.Tags.IndexOf(newTag)));
|
new TagChangedTransaction(oldTag, newTag, tagIdx, design.Tags.AsEnumerable().IndexOf(newTag)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Add an associated mod to a design. </summary>
|
/// <summary> Add an associated mod to a design. </summary>
|
||||||
|
|
@ -553,7 +557,7 @@ public sealed class DesignManager : DesignEditor
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Move(SaveService.FileNames.MigrationDesignFile,
|
File.Move(SaveService.FileNames.MigrationDesignFile,
|
||||||
Path.ChangeExtension(SaveService.FileNames.MigrationDesignFile, ".json.bak"));
|
Path.ChangeExtension(SaveService.FileNames.MigrationDesignFile, ".json.bak"), true);
|
||||||
Glamourer.Log.Information($"Moved migrated design file {SaveService.FileNames.MigrationDesignFile} to backup file.");
|
Glamourer.Log.Information($"Moved migrated design file {SaveService.FileNames.MigrationDesignFile} to backup file.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Interop.Structs;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Designs.History;
|
namespace Glamourer.Designs.History;
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ public class EditorHistory : IDisposable, IService
|
||||||
{
|
{
|
||||||
if (!_stateEntries.TryGetValue(state, out var list))
|
if (!_stateEntries.TryGetValue(state, out var list))
|
||||||
{
|
{
|
||||||
list = new Queue();
|
list = [];
|
||||||
_stateEntries.Add(state, list);
|
_stateEntries.Add(state, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@ public class EditorHistory : IDisposable, IService
|
||||||
{
|
{
|
||||||
if (!_designEntries.TryGetValue(design, out var list))
|
if (!_designEntries.TryGetValue(design, out var list))
|
||||||
{
|
{
|
||||||
list = new Queue();
|
list = [];
|
||||||
_designEntries.Add(design, list);
|
_designEntries.Add(design, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Dalamud.Interface.ImGuiNotification;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Notification = OtterGui.Classes.Notification;
|
using Notification = OtterGui.Classes.Notification;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,15 @@ public enum MetaIndex
|
||||||
VisorState = StateIndex.MetaVisorState,
|
VisorState = StateIndex.MetaVisorState,
|
||||||
WeaponState = StateIndex.MetaWeaponState,
|
WeaponState = StateIndex.MetaWeaponState,
|
||||||
ModelId = StateIndex.MetaModelId,
|
ModelId = StateIndex.MetaModelId,
|
||||||
|
EarState = StateIndex.MetaEarState,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MetaExtensions
|
public static class MetaExtensions
|
||||||
{
|
{
|
||||||
public static readonly IReadOnlyList<MetaIndex> AllRelevant =
|
public static readonly IReadOnlyList<MetaIndex> AllRelevant =
|
||||||
[MetaIndex.Wetness, MetaIndex.HatState, MetaIndex.VisorState, MetaIndex.WeaponState];
|
[MetaIndex.Wetness, MetaIndex.HatState, MetaIndex.VisorState, MetaIndex.WeaponState, MetaIndex.EarState];
|
||||||
|
|
||||||
public const MetaFlag All = MetaFlag.Wetness | MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState;
|
public const MetaFlag All = MetaFlag.Wetness | MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState | MetaFlag.EarState;
|
||||||
|
|
||||||
public static MetaFlag ToFlag(this MetaIndex index)
|
public static MetaFlag ToFlag(this MetaIndex index)
|
||||||
=> index switch
|
=> index switch
|
||||||
|
|
@ -26,6 +27,7 @@ public static class MetaExtensions
|
||||||
MetaIndex.HatState => MetaFlag.HatState,
|
MetaIndex.HatState => MetaFlag.HatState,
|
||||||
MetaIndex.VisorState => MetaFlag.VisorState,
|
MetaIndex.VisorState => MetaFlag.VisorState,
|
||||||
MetaIndex.WeaponState => MetaFlag.WeaponState,
|
MetaIndex.WeaponState => MetaFlag.WeaponState,
|
||||||
|
MetaIndex.EarState => MetaFlag.EarState,
|
||||||
_ => (MetaFlag)byte.MaxValue,
|
_ => (MetaFlag)byte.MaxValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -36,7 +38,8 @@ public static class MetaExtensions
|
||||||
MetaFlag.HatState => MetaIndex.HatState,
|
MetaFlag.HatState => MetaIndex.HatState,
|
||||||
MetaFlag.VisorState => MetaIndex.VisorState,
|
MetaFlag.VisorState => MetaIndex.VisorState,
|
||||||
MetaFlag.WeaponState => MetaIndex.WeaponState,
|
MetaFlag.WeaponState => MetaIndex.WeaponState,
|
||||||
_ => (MetaIndex)byte.MaxValue,
|
MetaFlag.EarState => MetaIndex.EarState,
|
||||||
|
_ => (MetaIndex)byte.MaxValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static IEnumerable<MetaIndex> ToIndices(this MetaFlag index)
|
public static IEnumerable<MetaIndex> ToIndices(this MetaFlag index)
|
||||||
|
|
@ -49,6 +52,8 @@ public static class MetaExtensions
|
||||||
yield return MetaIndex.VisorState;
|
yield return MetaIndex.VisorState;
|
||||||
if (index.HasFlag(MetaFlag.WeaponState))
|
if (index.HasFlag(MetaFlag.WeaponState))
|
||||||
yield return MetaIndex.WeaponState;
|
yield return MetaIndex.WeaponState;
|
||||||
|
if (index.HasFlag(MetaFlag.EarState))
|
||||||
|
yield return MetaIndex.EarState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToName(this MetaIndex index)
|
public static string ToName(this MetaIndex index)
|
||||||
|
|
@ -58,6 +63,7 @@ public static class MetaExtensions
|
||||||
MetaIndex.VisorState => "Visor Toggled",
|
MetaIndex.VisorState => "Visor Toggled",
|
||||||
MetaIndex.WeaponState => "Weapon Visible",
|
MetaIndex.WeaponState => "Weapon Visible",
|
||||||
MetaIndex.Wetness => "Force Wetness",
|
MetaIndex.Wetness => "Force Wetness",
|
||||||
|
MetaIndex.EarState => "Ears Visible",
|
||||||
_ => "Unknown Meta",
|
_ => "Unknown Meta",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -68,6 +74,7 @@ public static class MetaExtensions
|
||||||
MetaIndex.VisorState => "Toggle the visor state of the characters head gear.",
|
MetaIndex.VisorState => "Toggle the visor state of the characters head gear.",
|
||||||
MetaIndex.WeaponState => "Hide or show the characters weapons when not drawn.",
|
MetaIndex.WeaponState => "Hide or show the characters weapons when not drawn.",
|
||||||
MetaIndex.Wetness => "Force the character to be wet or not.",
|
MetaIndex.Wetness => "Force the character to be wet or not.",
|
||||||
|
MetaIndex.EarState => "Hide or show the characters ears through the head gear. (Viera only)",
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,33 @@
|
||||||
using OtterGui.Services;
|
using OtterGui;
|
||||||
|
using OtterGui.Services;
|
||||||
|
|
||||||
namespace Glamourer.Designs.Special;
|
namespace Glamourer.Designs.Special;
|
||||||
|
|
||||||
public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem) : IService
|
public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem, Configuration config) : IService
|
||||||
{
|
{
|
||||||
private readonly Random _rng = new();
|
private readonly Random _rng = new();
|
||||||
|
private readonly WeakReference<Design> _lastDesign = new(null!, false);
|
||||||
|
|
||||||
public Design? Design(IReadOnlyList<Design> localDesigns)
|
public Design? Design(IReadOnlyList<Design> localDesigns)
|
||||||
{
|
{
|
||||||
if (localDesigns.Count == 0)
|
if (localDesigns.Count is 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var idx = _rng.Next(0, localDesigns.Count);
|
var idx = _rng.Next(0, localDesigns.Count);
|
||||||
Glamourer.Log.Verbose($"[Random Design] Chose design {idx + 1} out of {localDesigns.Count}: {localDesigns[idx].Incognito}.");
|
if (localDesigns.Count is 1)
|
||||||
return localDesigns[idx];
|
{
|
||||||
|
_lastDesign.SetTarget(localDesigns[idx]);
|
||||||
|
return localDesigns[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.PreventRandomRepeats && _lastDesign.TryGetTarget(out var lastDesign))
|
||||||
|
while (lastDesign == localDesigns[idx])
|
||||||
|
idx = _rng.Next(0, localDesigns.Count);
|
||||||
|
|
||||||
|
var design = localDesigns[idx];
|
||||||
|
Glamourer.Log.Verbose($"[Random Design] Chose design {idx + 1} out of {localDesigns.Count}: {design.Incognito}.");
|
||||||
|
_lastDesign.SetTarget(design);
|
||||||
|
return design;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Design? Design()
|
public Design? Design()
|
||||||
|
|
@ -24,12 +38,12 @@ public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileS
|
||||||
|
|
||||||
public Design? Design(IReadOnlyList<IDesignPredicate> predicates)
|
public Design? Design(IReadOnlyList<IDesignPredicate> predicates)
|
||||||
{
|
{
|
||||||
if (predicates.Count == 0)
|
return predicates.Count switch
|
||||||
return Design();
|
{
|
||||||
if (predicates.Count == 1)
|
0 => Design(),
|
||||||
return Design(predicates[0]);
|
1 => Design(predicates[0]),
|
||||||
|
_ => Design(IDesignPredicate.Get(predicates, designs, fileSystem).ToList()),
|
||||||
return Design(IDesignPredicate.Get(predicates, designs, fileSystem).ToList());
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Design? Design(string restrictions)
|
public Design? Design(string restrictions)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public interface IDesignPredicate
|
||||||
: designs;
|
: designs;
|
||||||
|
|
||||||
private static (Design Design, string LowerName, string Identifier, string LowerPath) Transform(Design d, DesignFileSystem fs)
|
private static (Design Design, string LowerName, string Identifier, string LowerPath) Transform(Design d, DesignFileSystem fs)
|
||||||
=> (d, d.Name.Lower, d.Identifier.ToString(), fs.FindLeaf(d, out var l) ? l.FullName().ToLowerInvariant() : string.Empty);
|
=> (d, d.Name.Lower, d.Identifier.ToString(), fs.TryGetValue(d, out var l) ? l.FullName().ToLowerInvariant() : string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RandomPredicate
|
public static class RandomPredicate
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ public class EphemeralConfig : ISavable
|
||||||
public Guid SelectedQuickDesign { get; set; } = Guid.Empty;
|
public Guid SelectedQuickDesign { get; set; } = Guid.Empty;
|
||||||
public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion;
|
public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion;
|
||||||
|
|
||||||
|
public float CurrentDesignSelectorWidth { get; set; } = 200f;
|
||||||
|
public float DesignSelectorMinimumScale { get; set; } = 0.1f;
|
||||||
|
public float DesignSelectorMaximumScale { get; set; } = 0.5f;
|
||||||
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
private readonly SaveService _saveService;
|
private readonly SaveService _saveService;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Glamourer.Events;
|
||||||
/// </list>
|
/// </list>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class GearsetDataLoaded()
|
public sealed class GearsetDataLoaded()
|
||||||
: EventWrapper<Model, GearsetDataLoaded.Priority>(nameof(GearsetDataLoaded))
|
: EventWrapper<Actor, Model, GearsetDataLoaded.Priority>(nameof(GearsetDataLoaded))
|
||||||
{
|
{
|
||||||
public enum Priority
|
public enum Priority
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,8 @@ public sealed class PenumbraReloaded()
|
||||||
|
|
||||||
/// <seealso cref="Interop.VisorService.Restore"/>
|
/// <seealso cref="Interop.VisorService.Restore"/>
|
||||||
VisorService = 0,
|
VisorService = 0,
|
||||||
|
|
||||||
|
/// <seealso cref="Interop.VieraEarService.Restore"/>
|
||||||
|
VieraEarService = 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Glamourer.Designs.History;
|
||||||
using Glamourer.Interop.Structs;
|
using Glamourer.Interop.Structs;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Events;
|
namespace Glamourer.Events;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using Glamourer.Api;
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Interop.Structs;
|
using Glamourer.Interop.Structs;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Events;
|
namespace Glamourer.Events;
|
||||||
|
|
||||||
|
|
|
||||||
22
Glamourer/Events/VieraEarStateChanged.cs
Normal file
22
Glamourer/Events/VieraEarStateChanged.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
using OtterGui.Classes;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
|
namespace Glamourer.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered when the state of viera ear visibility for any draw object is changed.
|
||||||
|
/// <list type="number">
|
||||||
|
/// <item>Parameter is the model with a changed viera ear visibility state. </item>
|
||||||
|
/// <item>Parameter is the new state. </item>
|
||||||
|
/// <item>Parameter is whether to call the original function. </item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
public sealed class VieraEarStateChanged()
|
||||||
|
: EventWrapperRef2<Actor, bool, VieraEarStateChanged.Priority>(nameof(VieraEarStateChanged))
|
||||||
|
{
|
||||||
|
public enum Priority
|
||||||
|
{
|
||||||
|
/// <seealso cref="State.StateListener.OnVieraEarChange"/>
|
||||||
|
StateListener = 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using Race = Penumbra.GameData.Enums.Race;
|
using Race = Penumbra.GameData.Enums.Race;
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,10 @@ using Glamourer.Gui;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.GameData.Files;
|
|
||||||
|
|
||||||
namespace Glamourer;
|
namespace Glamourer;
|
||||||
|
|
||||||
|
|
@ -28,6 +26,7 @@ public class Glamourer : IDalamudPlugin
|
||||||
|
|
||||||
public static readonly Logger Log = new();
|
public static readonly Logger Log = new();
|
||||||
public static MessageService Messager { get; private set; } = null!;
|
public static MessageService Messager { get; private set; } = null!;
|
||||||
|
public static DynamisIpc Dynamis { get; private set; } = null!;
|
||||||
|
|
||||||
private readonly ServiceManager _services;
|
private readonly ServiceManager _services;
|
||||||
|
|
||||||
|
|
@ -37,6 +36,7 @@ public class Glamourer : IDalamudPlugin
|
||||||
{
|
{
|
||||||
_services = StaticServiceManager.CreateProvider(pluginInterface, Log, this);
|
_services = StaticServiceManager.CreateProvider(pluginInterface, Log, this);
|
||||||
Messager = _services.GetService<MessageService>();
|
Messager = _services.GetService<MessageService>();
|
||||||
|
Dynamis = _services.GetService<DynamisIpc>();
|
||||||
_services.EnsureRequiredServices();
|
_services.EnsureRequiredServices();
|
||||||
|
|
||||||
_services.GetService<VisorService>();
|
_services.GetService<VisorService>();
|
||||||
|
|
@ -71,6 +71,7 @@ public class Glamourer : IDalamudPlugin
|
||||||
sb.Append($"> **`Festival Easter-Eggs: `** {config.DisableFestivals}\n");
|
sb.Append($"> **`Festival Easter-Eggs: `** {config.DisableFestivals}\n");
|
||||||
sb.Append($"> **`Apply Entire Weapon: `** {config.ChangeEntireItem}\n");
|
sb.Append($"> **`Apply Entire Weapon: `** {config.ChangeEntireItem}\n");
|
||||||
sb.Append($"> **`Apply Associated Mods:`** {config.AlwaysApplyAssociatedMods}\n");
|
sb.Append($"> **`Apply Associated Mods:`** {config.AlwaysApplyAssociatedMods}\n");
|
||||||
|
sb.Append($"> **`Attach to PCP: `** {config.AttachToPcp}\n");
|
||||||
sb.Append($"> **`Hidden Panels: `** {config.HideDesignPanel}\n");
|
sb.Append($"> **`Hidden Panels: `** {config.HideDesignPanel}\n");
|
||||||
sb.Append($"> **`Show QDB: `** {config.Ephemeral.ShowDesignQuickBar}\n");
|
sb.Append($"> **`Show QDB: `** {config.Ephemeral.ShowDesignQuickBar}\n");
|
||||||
sb.Append($"> **`QDB Hotkey: `** {config.ToggleQuickDesignBar}\n");
|
sb.Append($"> **`QDB Hotkey: `** {config.ToggleQuickDesignBar}\n");
|
||||||
|
|
@ -82,7 +83,7 @@ public class Glamourer : IDalamudPlugin
|
||||||
var designManager = _services.GetService<DesignManager>();
|
var designManager = _services.GetService<DesignManager>();
|
||||||
var autoManager = _services.GetService<AutoDesignManager>();
|
var autoManager = _services.GetService<AutoDesignManager>();
|
||||||
var stateManager = _services.GetService<StateManager>();
|
var stateManager = _services.GetService<StateManager>();
|
||||||
var objectManager = _services.GetService<ObjectManager>();
|
var objectManager = _services.GetService<ActorObjectManager>();
|
||||||
var currentPlayer = objectManager.PlayerData.Identifier;
|
var currentPlayer = objectManager.PlayerData.Identifier;
|
||||||
var states = stateManager.Where(kvp => objectManager.ContainsKey(kvp.Key)).ToList();
|
var states = stateManager.Where(kvp => objectManager.ContainsKey(kvp.Key)).ToList();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,32 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Dalamud.NET.Sdk/13.1.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
|
||||||
<LangVersion>preview</LangVersion>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<RootNamespace>Glamourer</RootNamespace>
|
<RootNamespace>Glamourer</RootNamespace>
|
||||||
<AssemblyName>Glamourer</AssemblyName>
|
<AssemblyName>Glamourer</AssemblyName>
|
||||||
<FileVersion>9.0.0.1</FileVersion>
|
<FileVersion>9.0.0.1</FileVersion>
|
||||||
<AssemblyVersion>9.0.0.1</AssemblyVersion>
|
<AssemblyVersion>9.0.0.1</AssemblyVersion>
|
||||||
<Company>SoftOtter</Company>
|
|
||||||
<Product>Glamourer</Product>
|
<Product>Glamourer</Product>
|
||||||
<Copyright>Copyright © 2023</Copyright>
|
<Copyright>Copyright © 2025</Copyright>
|
||||||
<Deterministic>true</Deterministic>
|
|
||||||
<OutputType>Library</OutputType>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
|
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
|
||||||
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
|
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="LegacyTattoo.raw" />
|
<None Remove="LegacyTattoo.raw" />
|
||||||
|
|
||||||
|
<None Include="Glamourer.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="LegacyTattoo.raw" />
|
<EmbeddedResource Include="LegacyTattoo.raw" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Dalamud">
|
|
||||||
<HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="FFXIVClientStructs">
|
|
||||||
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="ImGui.NET">
|
|
||||||
<HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="ImGuiScene">
|
|
||||||
<HintPath>$(DalamudLibPath)ImGuiScene.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Lumina">
|
|
||||||
<HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Lumina.Excel">
|
|
||||||
<HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json">
|
|
||||||
<HintPath>$(DalamudLibPath)Newtonsoft.Json.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Glamourer.Api\Glamourer.Api.csproj" />
|
<ProjectReference Include="..\Glamourer.Api\Glamourer.Api.csproj" />
|
||||||
<ProjectReference Include="..\OtterGui\OtterGui.csproj" />
|
<ProjectReference Include="..\OtterGui\OtterGui.csproj" />
|
||||||
<ProjectReference Include="..\Penumbra.Api\Penumbra.Api.csproj" />
|
<ProjectReference Include="..\Penumbra.Api\Penumbra.Api.csproj" />
|
||||||
<ProjectReference Include="..\Penumbra.String\Penumbra.string.csproj" />
|
<ProjectReference Include="..\Penumbra.String\Penumbra.String.csproj" />
|
||||||
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||||
<PackageReference Include="Vortice.Direct3D11" Version="3.4.2-beta" />
|
<PackageReference Include="Vortice.Direct3D11" Version="3.4.2-beta" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
@ -116,14 +56,4 @@
|
||||||
<InformationalVersion>$(GitCommitHash)</InformationalVersion>
|
<InformationalVersion>$(GitCommitHash)</InformationalVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="Glamourer.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
|
||||||
<Exec Command="if $(Configuration) == Release powershell Copy-Item -Force $(TargetDir)$(SolutionName).json -Destination $(SolutionDir)" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"AssemblyVersion": "9.0.0.1",
|
"AssemblyVersion": "9.0.0.1",
|
||||||
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
|
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
|
||||||
"ApplicableVersion": "any",
|
"ApplicableVersion": "any",
|
||||||
"DalamudApiLevel": 11,
|
"DalamudApiLevel": 13,
|
||||||
"ImageUrls": null,
|
"ImageUrls": null,
|
||||||
"IconUrl": "https://raw.githubusercontent.com/Ottermandias/Glamourer/master/images/icon.png"
|
"IconUrl": "https://raw.githubusercontent.com/Ottermandias/Glamourer/master/images/icon.png"
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
|
|
||||||
namespace Glamourer.Gui;
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,83 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using OtterGui.Text;
|
||||||
|
using OtterGui.Text.EndObjects;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Customization;
|
namespace Glamourer.Gui.Customization;
|
||||||
|
|
||||||
public partial class CustomizationDrawer
|
public partial class CustomizationDrawer
|
||||||
{
|
{
|
||||||
private const string ColorPickerPopupName = "ColorPicker";
|
private const string ColorPickerPopupName = "ColorPicker";
|
||||||
|
private CustomizeValue _draggedColorValue;
|
||||||
|
private CustomizeIndex _draggedColorType;
|
||||||
|
|
||||||
|
|
||||||
|
private void DrawDragDropSource(CustomizeIndex index, CustomizeData custom)
|
||||||
|
{
|
||||||
|
using var dragDropSource = ImUtf8.DragDropSource();
|
||||||
|
if (!dragDropSource)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!DragDropSource.SetPayload("##colorDragDrop"u8))
|
||||||
|
_draggedColorValue = _customize[index];
|
||||||
|
ImUtf8.Text(
|
||||||
|
$"Dragging {(custom.Color == 0 ? $"{_currentOption} (NPC)" : _currentOption)} #{_draggedColorValue.Value}...");
|
||||||
|
_draggedColorType = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawDragDropTarget(CustomizeIndex index)
|
||||||
|
{
|
||||||
|
using var dragDropTarget = ImUtf8.DragDropTarget();
|
||||||
|
if (!dragDropTarget.Success || !dragDropTarget.IsDropping("##colorDragDrop"u8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var idx = _set.DataByValue(_draggedColorType, _draggedColorValue, out var draggedData, _customize.Face);
|
||||||
|
var bestMatch = _draggedColorValue;
|
||||||
|
if (draggedData.HasValue)
|
||||||
|
{
|
||||||
|
var draggedColor = draggedData.Value.Color;
|
||||||
|
var targetData = _set.Data(index, idx);
|
||||||
|
if (targetData.Color != draggedColor)
|
||||||
|
{
|
||||||
|
var bestDiff = Diff(targetData.Color, draggedColor);
|
||||||
|
var count = _set.Count(index);
|
||||||
|
for (var i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
targetData = _set.Data(index, i);
|
||||||
|
if (targetData.Color == draggedColor)
|
||||||
|
{
|
||||||
|
UpdateValue(_draggedColorValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var diff = Diff(targetData.Color, draggedColor);
|
||||||
|
if (diff >= bestDiff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bestDiff = diff;
|
||||||
|
bestMatch = (CustomizeValue)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateValue(bestMatch);
|
||||||
|
return;
|
||||||
|
|
||||||
|
static uint Diff(uint color1, uint color2)
|
||||||
|
{
|
||||||
|
var r = (color1 & 0xFF) - (color2 & 0xFF);
|
||||||
|
var g = ((color1 >> 8) & 0xFF) - ((color2 >> 8) & 0xFF);
|
||||||
|
var b = ((color1 >> 16) & 0xFF) - ((color2 >> 16) & 0xFF);
|
||||||
|
return 30 * r * r + 59 * g * g + 11 * b * b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawColorPicker(CustomizeIndex index)
|
private void DrawColorPicker(CustomizeIndex index)
|
||||||
{
|
{
|
||||||
|
|
@ -21,7 +88,7 @@ public partial class CustomizationDrawer
|
||||||
|
|
||||||
using (_ = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, current < 0))
|
using (_ = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, current < 0))
|
||||||
{
|
{
|
||||||
if (ImGui.ColorButton($"{_customize[index].Value}##color", color, ImGuiColorEditFlags.None, _framedIconSize))
|
if (ImGui.ColorButton($"{_customize[index].Value}##color", color, ImGuiColorEditFlags.NoDragDrop, _framedIconSize))
|
||||||
{
|
{
|
||||||
ImGui.OpenPopup(ColorPickerPopupName);
|
ImGui.OpenPopup(ColorPickerPopupName);
|
||||||
}
|
}
|
||||||
|
|
@ -30,6 +97,9 @@ public partial class CustomizationDrawer
|
||||||
var data = _set.Data(_currentIndex, current, _customize.Face);
|
var data = _set.Data(_currentIndex, current, _customize.Face);
|
||||||
UpdateValue(data.Value);
|
UpdateValue(data.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawDragDropSource(index, custom);
|
||||||
|
DrawDragDropTarget(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
var npc = false;
|
var npc = false;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
using Dalamud.Interface.Textures.TextureWraps;
|
using Dalamud.Interface.Textures.TextureWraps;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
@ -34,7 +35,7 @@ public partial class CustomizationDrawer
|
||||||
var hasIcon = icon.TryGetWrap(out var wrap, out _);
|
var hasIcon = icon.TryGetWrap(out var wrap, out _);
|
||||||
using (_ = ImRaii.Disabled(_locked || _currentIndex is CustomizeIndex.Face && _lockedRedraw))
|
using (_ = ImRaii.Disabled(_locked || _currentIndex is CustomizeIndex.Face && _lockedRedraw))
|
||||||
{
|
{
|
||||||
if (ImGui.ImageButton(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, _iconSize))
|
if (ImGui.ImageButton(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, _iconSize))
|
||||||
{
|
{
|
||||||
ImGui.OpenPopup(IconSelectorPopup);
|
ImGui.OpenPopup(IconSelectorPopup);
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +89,7 @@ public partial class CustomizationDrawer
|
||||||
: ImRaii.PushColor(ImGuiCol.Button, ColorId.FavoriteStarOn.Value(), isFavorite);
|
: ImRaii.PushColor(ImGuiCol.Button, ColorId.FavoriteStarOn.Value(), isFavorite);
|
||||||
var hasIcon = icon.TryGetWrap(out var wrap, out var _);
|
var hasIcon = icon.TryGetWrap(out var wrap, out var _);
|
||||||
|
|
||||||
if (ImGui.ImageButton(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, _iconSize))
|
if (ImGui.ImageButton(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, _iconSize))
|
||||||
{
|
{
|
||||||
UpdateValue(custom.Value);
|
UpdateValue(custom.Value);
|
||||||
ImGui.CloseCurrentPopup();
|
ImGui.CloseCurrentPopup();
|
||||||
|
|
@ -214,7 +215,7 @@ public partial class CustomizationDrawer
|
||||||
hasIcon = icon.TryGetWrap(out wrap, out _);
|
hasIcon = icon.TryGetWrap(out wrap, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.ImageButton(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, _iconSize, Vector2.Zero, Vector2.One,
|
if (ImGui.ImageButton(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, _iconSize, Vector2.Zero, Vector2.One,
|
||||||
(int)ImGui.GetStyle().FramePadding.X, Vector4.Zero, enabled ? Vector4.One : _redTint))
|
(int)ImGui.GetStyle().FramePadding.X, Vector4.Zero, enabled ? Vector4.One : _redTint))
|
||||||
{
|
{
|
||||||
_customize.Set(featureIdx, enabled ? CustomizeValue.Zero : CustomizeValue.Max);
|
_customize.Set(featureIdx, enabled ? CustomizeValue.Zero : CustomizeValue.Max);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGuiInternal;
|
using OtterGuiInternal;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ using Dalamud.Plugin.Services;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using Glamourer.Designs;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Interop.PalettePlus;
|
using Glamourer.Interop.PalettePlus;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
@ -287,13 +287,13 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImGuiColorEditFlags GetFlags()
|
private ImGuiColorEditFlags GetFlags()
|
||||||
=> Format | Display | ImGuiColorEditFlags.HDR | ImGuiColorEditFlags.NoOptions;
|
=> Format | Display | ImGuiColorEditFlags.Hdr | ImGuiColorEditFlags.NoOptions;
|
||||||
|
|
||||||
private ImGuiColorEditFlags Format
|
private ImGuiColorEditFlags Format
|
||||||
=> config.UseFloatForColors ? ImGuiColorEditFlags.Float : ImGuiColorEditFlags.Uint8;
|
=> config.UseFloatForColors ? ImGuiColorEditFlags.Float : ImGuiColorEditFlags.Uint8;
|
||||||
|
|
||||||
private ImGuiColorEditFlags Display
|
private ImGuiColorEditFlags Display
|
||||||
=> config.UseRgbForColors ? ImGuiColorEditFlags.DisplayRGB : ImGuiColorEditFlags.DisplayHSV;
|
=> config.UseRgbForColors ? ImGuiColorEditFlags.DisplayRgb : ImGuiColorEditFlags.DisplayHsv;
|
||||||
|
|
||||||
private ImRaii.IEndObject EnsureSize()
|
private ImRaii.IEndObject EnsureSize()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ using Glamourer.Designs;
|
||||||
using Glamourer.Designs.History;
|
using Glamourer.Designs.History;
|
||||||
using Glamourer.Designs.Special;
|
using Glamourer.Designs.Special;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
||||||
|
|
@ -21,6 +22,7 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
|
||||||
protected readonly TabSelected TabSelected;
|
protected readonly TabSelected TabSelected;
|
||||||
protected float InnerWidth;
|
protected float InnerWidth;
|
||||||
private IDesignStandIn? _currentDesign;
|
private IDesignStandIn? _currentDesign;
|
||||||
|
private bool _isCurrentSelectionDirty;
|
||||||
|
|
||||||
protected DesignComboBase(Func<IReadOnlyList<Tuple<IDesignStandIn, string>>> generator, Logger log, DesignChanged designChanged,
|
protected DesignComboBase(Func<IReadOnlyList<Tuple<IDesignStandIn, string>>> generator, Logger log, DesignChanged designChanged,
|
||||||
TabSelected tabSelected, EphemeralConfig config, DesignColors designColors)
|
TabSelected tabSelected, EphemeralConfig config, DesignColors designColors)
|
||||||
|
|
@ -83,17 +85,11 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
|
||||||
DrawRightAligned(quickDesign.ResolveName(false), "[Nothing]", DesignColors.MissingColor);
|
DrawRightAligned(quickDesign.ResolveName(false), "[Nothing]", DesignColors.MissingColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override int UpdateCurrentSelected(int currentSelected)
|
|
||||||
{
|
|
||||||
CurrentSelectionIdx = Items.IndexOf(p => _currentDesign == p.Item1);
|
|
||||||
UpdateSelection(CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : null);
|
|
||||||
return CurrentSelectionIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool Draw(IDesignStandIn? currentDesign, string? label, float width)
|
protected bool Draw(IDesignStandIn? currentDesign, string? label, float width)
|
||||||
{
|
{
|
||||||
_currentDesign = currentDesign;
|
_currentDesign = currentDesign;
|
||||||
InnerWidth = 400 * ImGuiHelpers.GlobalScale;
|
UpdateCurrentSelection();
|
||||||
|
InnerWidth = 400 * ImGuiHelpers.GlobalScale;
|
||||||
var name = label ?? "Select Design Here...";
|
var name = label ?? "Select Design Here...";
|
||||||
bool ret;
|
bool ret;
|
||||||
using (_ = currentDesign != null ? ImRaii.PushColor(ImGuiCol.Text, DesignColors.GetColor(currentDesign as Design)) : null)
|
using (_ = currentDesign != null ? ImRaii.PushColor(ImGuiCol.Text, DesignColors.GetColor(currentDesign as Design)) : null)
|
||||||
|
|
@ -127,37 +123,60 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
|
||||||
return filter.IsContained(path) || filter.IsContained(design.ResolveName(false));
|
return filter.IsContained(path) || filter.IsContained(design.ResolveName(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDesignChanged(DesignChanged.Type type, Design design, ITransaction? _ = null)
|
protected override void OnMouseWheel(string preview, ref int _2, int steps)
|
||||||
{
|
{
|
||||||
switch (type)
|
if (!ReferenceEquals(_currentDesign, CurrentSelection?.Item1))
|
||||||
{
|
CurrentSelectionIdx = -1;
|
||||||
case DesignChanged.Type.Created:
|
|
||||||
case DesignChanged.Type.Renamed:
|
|
||||||
case DesignChanged.Type.ChangedColor:
|
|
||||||
case DesignChanged.Type.Deleted:
|
|
||||||
case DesignChanged.Type.QuickDesignBar:
|
|
||||||
var priorState = IsInitialized;
|
|
||||||
if (priorState)
|
|
||||||
Cleanup();
|
|
||||||
CurrentSelectionIdx = Items.IndexOf(s => ReferenceEquals(s.Item1, CurrentSelection?.Item1));
|
|
||||||
if (CurrentSelectionIdx >= 0)
|
|
||||||
{
|
|
||||||
UpdateSelection(Items[CurrentSelectionIdx]);
|
|
||||||
}
|
|
||||||
else if (Items.Count > 0)
|
|
||||||
{
|
|
||||||
CurrentSelectionIdx = 0;
|
|
||||||
UpdateSelection(Items[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateSelection(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!priorState)
|
base.OnMouseWheel(preview, ref _2, steps);
|
||||||
Cleanup();
|
}
|
||||||
break;
|
|
||||||
|
private void UpdateCurrentSelection()
|
||||||
|
{
|
||||||
|
if (!_isCurrentSelectionDirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var priorState = IsInitialized;
|
||||||
|
if (priorState)
|
||||||
|
Cleanup();
|
||||||
|
CurrentSelectionIdx = Items.IndexOf(s => ReferenceEquals(s.Item1, CurrentSelection?.Item1));
|
||||||
|
if (CurrentSelectionIdx >= 0)
|
||||||
|
{
|
||||||
|
UpdateSelection(Items[CurrentSelectionIdx]);
|
||||||
}
|
}
|
||||||
|
else if (Items.Count > 0)
|
||||||
|
{
|
||||||
|
CurrentSelectionIdx = 0;
|
||||||
|
UpdateSelection(Items[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateSelection(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priorState)
|
||||||
|
Cleanup();
|
||||||
|
_isCurrentSelectionDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int UpdateCurrentSelected(int currentSelected)
|
||||||
|
{
|
||||||
|
CurrentSelectionIdx = Items.IndexOf(p => _currentDesign == p.Item1);
|
||||||
|
UpdateSelection(CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : null);
|
||||||
|
return CurrentSelectionIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDesignChanged(DesignChanged.Type type, Design? _1, ITransaction? _2 = null)
|
||||||
|
{
|
||||||
|
_isCurrentSelectionDirty = type switch
|
||||||
|
{
|
||||||
|
DesignChanged.Type.Created => true,
|
||||||
|
DesignChanged.Type.Renamed => true,
|
||||||
|
DesignChanged.Type.ChangedColor => true,
|
||||||
|
DesignChanged.Type.Deleted => true,
|
||||||
|
DesignChanged.Type.QuickDesignBar => true,
|
||||||
|
_ => _isCurrentSelectionDirty,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void QuickSelectedDesignTooltip(IDesignStandIn? design)
|
private void QuickSelectedDesignTooltip(IDesignStandIn? design)
|
||||||
|
|
@ -175,7 +194,7 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
|
||||||
ImGui.TextUnformatted("Currently resolving to ");
|
ImGui.TextUnformatted("Currently resolving to ");
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, DesignColors.GetColor(linkedDesign));
|
using var color = ImRaii.PushColor(ImGuiCol.Text, DesignColors.GetColor(linkedDesign));
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
ImGui.TextUnformatted(linkedDesign.Name);
|
ImGui.TextUnformatted(linkedDesign.Name.Text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -225,8 +244,7 @@ public abstract class DesignCombo : DesignComboBase
|
||||||
|
|
||||||
public sealed class QuickDesignCombo : DesignCombo
|
public sealed class QuickDesignCombo : DesignCombo
|
||||||
{
|
{
|
||||||
public QuickDesignCombo(DesignManager designs,
|
public QuickDesignCombo(DesignFileSystem fileSystem,
|
||||||
DesignFileSystem fileSystem,
|
|
||||||
Logger log,
|
Logger log,
|
||||||
DesignChanged designChanged,
|
DesignChanged designChanged,
|
||||||
TabSelected tabSelected,
|
TabSelected tabSelected,
|
||||||
|
|
@ -234,9 +252,9 @@ public sealed class QuickDesignCombo : DesignCombo
|
||||||
DesignColors designColors)
|
DesignColors designColors)
|
||||||
: base(log, designChanged, tabSelected, config, designColors, () =>
|
: base(log, designChanged, tabSelected, config, designColors, () =>
|
||||||
[
|
[
|
||||||
.. designs.Designs
|
.. fileSystem
|
||||||
.Where(d => d.QuickDesign)
|
.Where(kvp => kvp.Key.QuickDesign)
|
||||||
.Select(d => new Tuple<IDesignStandIn, string>(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty))
|
.Select(kvp => new Tuple<IDesignStandIn, string>(kvp.Key, kvp.Value.FullName()))
|
||||||
.OrderBy(d => d.Item2),
|
.OrderBy(d => d.Item2),
|
||||||
])
|
])
|
||||||
{
|
{
|
||||||
|
|
@ -277,7 +295,6 @@ public sealed class QuickDesignCombo : DesignCombo
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class LinkDesignCombo(
|
public sealed class LinkDesignCombo(
|
||||||
DesignManager designs,
|
|
||||||
DesignFileSystem fileSystem,
|
DesignFileSystem fileSystem,
|
||||||
Logger log,
|
Logger log,
|
||||||
DesignChanged designChanged,
|
DesignChanged designChanged,
|
||||||
|
|
@ -286,8 +303,8 @@ public sealed class LinkDesignCombo(
|
||||||
DesignColors designColors)
|
DesignColors designColors)
|
||||||
: DesignCombo(log, designChanged, tabSelected, config, designColors, () =>
|
: DesignCombo(log, designChanged, tabSelected, config, designColors, () =>
|
||||||
[
|
[
|
||||||
.. designs.Designs
|
.. fileSystem
|
||||||
.Select(d => new Tuple<IDesignStandIn, string>(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty))
|
.Select(kvp => new Tuple<IDesignStandIn, string>(kvp.Key, kvp.Value.FullName()))
|
||||||
.OrderBy(d => d.Item2),
|
.OrderBy(d => d.Item2),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -301,8 +318,8 @@ public sealed class RandomDesignCombo(
|
||||||
DesignColors designColors)
|
DesignColors designColors)
|
||||||
: DesignCombo(log, designChanged, tabSelected, config, designColors, () =>
|
: DesignCombo(log, designChanged, tabSelected, config, designColors, () =>
|
||||||
[
|
[
|
||||||
.. designs.Designs
|
.. fileSystem
|
||||||
.Select(d => new Tuple<IDesignStandIn, string>(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty))
|
.Select(kvp => new Tuple<IDesignStandIn, string>(kvp.Key, kvp.Value.FullName()))
|
||||||
.OrderBy(d => d.Item2),
|
.OrderBy(d => d.Item2),
|
||||||
])
|
])
|
||||||
{
|
{
|
||||||
|
|
@ -328,7 +345,6 @@ public sealed class RandomDesignCombo(
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class SpecialDesignCombo(
|
public sealed class SpecialDesignCombo(
|
||||||
DesignManager designs,
|
|
||||||
DesignFileSystem fileSystem,
|
DesignFileSystem fileSystem,
|
||||||
TabSelected tabSelected,
|
TabSelected tabSelected,
|
||||||
DesignColors designColors,
|
DesignColors designColors,
|
||||||
|
|
@ -338,8 +354,8 @@ public sealed class SpecialDesignCombo(
|
||||||
EphemeralConfig config,
|
EphemeralConfig config,
|
||||||
RandomDesignGenerator rng,
|
RandomDesignGenerator rng,
|
||||||
QuickSelectedDesign quickSelectedDesign)
|
QuickSelectedDesign quickSelectedDesign)
|
||||||
: DesignComboBase(() => designs.Designs
|
: DesignComboBase(() => fileSystem
|
||||||
.Select(d => new Tuple<IDesignStandIn, string>(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty))
|
.Select(kvp => new Tuple<IDesignStandIn, string>(kvp.Key, kvp.Value.FullName()))
|
||||||
.OrderBy(d => d.Item2)
|
.OrderBy(d => d.Item2)
|
||||||
.Prepend(new Tuple<IDesignStandIn, string>(new RandomDesign(rng), string.Empty))
|
.Prepend(new Tuple<IDesignStandIn, string>(new RandomDesign(rng), string.Empty))
|
||||||
.Prepend(new Tuple<IDesignStandIn, string>(quickSelectedDesign, string.Empty))
|
.Prepend(new Tuple<IDesignStandIn, string>(quickSelectedDesign, string.Empty))
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,28 @@ using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Automation;
|
using Glamourer.Automation;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Interop.Penumbra;
|
||||||
using Glamourer.Interop.Structs;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Gui;
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum QdbButtons
|
public enum QdbButtons
|
||||||
{
|
{
|
||||||
ApplyDesign = 0x01,
|
ApplyDesign = 0x01,
|
||||||
RevertAll = 0x02,
|
RevertAll = 0x02,
|
||||||
RevertAutomation = 0x04,
|
RevertAutomation = 0x04,
|
||||||
RevertAdvanced = 0x08,
|
RevertAdvancedDyes = 0x08,
|
||||||
RevertEquip = 0x10,
|
RevertEquip = 0x10,
|
||||||
RevertCustomize = 0x20,
|
RevertCustomize = 0x20,
|
||||||
ReapplyAutomation = 0x40,
|
ReapplyAutomation = 0x40,
|
||||||
ResetSettings = 0x80,
|
ResetSettings = 0x80,
|
||||||
|
RevertAdvancedCustomization = 0x100,
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class DesignQuickBar : Window, IDisposable
|
public sealed class DesignQuickBar : Window, IDisposable
|
||||||
|
|
@ -37,21 +37,21 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
? ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoMove
|
? ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoMove
|
||||||
: ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing;
|
: ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing;
|
||||||
|
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly QuickDesignCombo _designCombo;
|
private readonly QuickDesignCombo _designCombo;
|
||||||
private readonly StateManager _stateManager;
|
private readonly StateManager _stateManager;
|
||||||
private readonly AutoDesignApplier _autoDesignApplier;
|
private readonly AutoDesignApplier _autoDesignApplier;
|
||||||
private readonly ObjectManager _objects;
|
private readonly ActorObjectManager _objects;
|
||||||
private readonly PenumbraService _penumbra;
|
private readonly PenumbraService _penumbra;
|
||||||
private readonly IKeyState _keyState;
|
private readonly IKeyState _keyState;
|
||||||
private readonly ImRaii.Style _windowPadding = new();
|
private readonly ImRaii.Style _windowPadding = new();
|
||||||
private readonly ImRaii.Color _windowColor = new();
|
private readonly ImRaii.Color _windowColor = new();
|
||||||
private DateTime _keyboardToggle = DateTime.UnixEpoch;
|
private DateTime _keyboardToggle = DateTime.UnixEpoch;
|
||||||
private int _numButtons;
|
private int _numButtons;
|
||||||
private readonly StringBuilder _tooltipBuilder = new(512);
|
private readonly StringBuilder _tooltipBuilder = new(512);
|
||||||
|
|
||||||
public DesignQuickBar(Configuration config, QuickDesignCombo designCombo, StateManager stateManager, IKeyState keyState,
|
public DesignQuickBar(Configuration config, QuickDesignCombo designCombo, StateManager stateManager, IKeyState keyState,
|
||||||
ObjectManager objects, AutoDesignApplier autoDesignApplier, PenumbraService penumbra)
|
ActorObjectManager objects, AutoDesignApplier autoDesignApplier, PenumbraService penumbra)
|
||||||
: base("Glamourer Quick Bar", ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking)
|
: base("Glamourer Quick Bar", ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
@ -64,6 +64,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
IsOpen = _config.Ephemeral.ShowDesignQuickBar;
|
IsOpen = _config.Ephemeral.ShowDesignQuickBar;
|
||||||
DisableWindowSounds = true;
|
DisableWindowSounds = true;
|
||||||
Size = Vector2.Zero;
|
Size = Vector2.Zero;
|
||||||
|
RespectCloseHotkey = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -125,6 +126,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
DrawRevertEquipButton(buttonSize);
|
DrawRevertEquipButton(buttonSize);
|
||||||
DrawRevertCustomizeButton(buttonSize);
|
DrawRevertCustomizeButton(buttonSize);
|
||||||
DrawRevertAdvancedCustomization(buttonSize);
|
DrawRevertAdvancedCustomization(buttonSize);
|
||||||
|
DrawRevertAdvancedDyes(buttonSize);
|
||||||
DrawRevertAutomationButton(buttonSize);
|
DrawRevertAutomationButton(buttonSize);
|
||||||
DrawReapplyAutomationButton(buttonSize);
|
DrawReapplyAutomationButton(buttonSize);
|
||||||
DrawResetSettingsButton(buttonSize);
|
DrawResetSettingsButton(buttonSize);
|
||||||
|
|
@ -173,7 +175,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
available |= 2;
|
available |= 2;
|
||||||
_tooltipBuilder.Append("Right-Click: Apply ")
|
_tooltipBuilder.Append("Right-Click: Apply ")
|
||||||
.Append(design.ResolveName(_config.Ephemeral.IncognitoMode))
|
.Append(design.ResolveName(_config.Ephemeral.IncognitoMode))
|
||||||
.Append(" to {_targetIdentifier}.");
|
.Append(" to ").Append(_config.Ephemeral.IncognitoMode ? _targetIdentifier.Incognito(null) : _targetIdentifier.ToName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (available == 0)
|
if (available == 0)
|
||||||
|
|
@ -222,7 +224,8 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (available == 0)
|
if (available == 0)
|
||||||
_tooltipBuilder.Append("Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
|
_tooltipBuilder.Append(
|
||||||
|
"Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
|
||||||
|
|
||||||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, available);
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, available);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
@ -258,9 +261,10 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (available == 0)
|
if (available == 0)
|
||||||
_tooltipBuilder.Append("Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
|
_tooltipBuilder.Append(
|
||||||
|
"Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
|
||||||
|
|
||||||
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, available);
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, available);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (!clicked)
|
if (!clicked)
|
||||||
return;
|
return;
|
||||||
|
|
@ -300,7 +304,8 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (available == 0)
|
if (available == 0)
|
||||||
_tooltipBuilder.Append("Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
|
_tooltipBuilder.Append(
|
||||||
|
"Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
|
||||||
|
|
||||||
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.Repeat, buttonSize, available);
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.Repeat, buttonSize, available);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
@ -316,7 +321,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
|
|
||||||
private void DrawRevertAdvancedCustomization(Vector2 buttonSize)
|
private void DrawRevertAdvancedCustomization(Vector2 buttonSize)
|
||||||
{
|
{
|
||||||
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedCustomization))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var available = 0;
|
var available = 0;
|
||||||
|
|
@ -325,7 +330,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
||||||
{
|
{
|
||||||
available |= 1;
|
available |= 1;
|
||||||
_tooltipBuilder.Append("Left-Click: Revert the advanced customizations and dyes of the player character to their game state.");
|
_tooltipBuilder.Append("Left-Click: Revert the advanced customizations of the player character to their game state.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
||||||
|
|
@ -333,7 +338,40 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
if (available != 0)
|
if (available != 0)
|
||||||
_tooltipBuilder.Append('\n');
|
_tooltipBuilder.Append('\n');
|
||||||
available |= 2;
|
available |= 2;
|
||||||
_tooltipBuilder.Append("Right-Click: Revert the advanced customizations and dyes of ")
|
_tooltipBuilder.Append("Right-Click: Revert the advanced customizations of ")
|
||||||
|
.Append(_targetIdentifier)
|
||||||
|
.Append(" to their game state.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == 0)
|
||||||
|
_tooltipBuilder.Append("Neither player character nor target are available or their state is locked.");
|
||||||
|
|
||||||
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.PaintBrush, buttonSize, available);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (clicked)
|
||||||
|
_stateManager.ResetAdvancedCustomizations(state!, StateSource.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawRevertAdvancedDyes(Vector2 buttonSize)
|
||||||
|
{
|
||||||
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedDyes))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var available = 0;
|
||||||
|
_tooltipBuilder.Clear();
|
||||||
|
|
||||||
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
||||||
|
{
|
||||||
|
available |= 1;
|
||||||
|
_tooltipBuilder.Append("Left-Click: Revert the advanced dyes of the player character to their game state.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
||||||
|
{
|
||||||
|
if (available != 0)
|
||||||
|
_tooltipBuilder.Append('\n');
|
||||||
|
available |= 2;
|
||||||
|
_tooltipBuilder.Append("Right-Click: Revert the advanced dyes of ")
|
||||||
.Append(_targetIdentifier)
|
.Append(_targetIdentifier)
|
||||||
.Append(" to their game state.");
|
.Append(" to their game state.");
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +382,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, available);
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, available);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (clicked)
|
if (clicked)
|
||||||
_stateManager.ResetAdvancedState(state!, StateSource.Manual);
|
_stateManager.ResetAdvancedDyes(state!, StateSource.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawRevertCustomizeButton(Vector2 buttonSize)
|
private void DrawRevertCustomizeButton(Vector2 buttonSize)
|
||||||
|
|
@ -424,7 +462,9 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
if (_playerIdentifier.IsValid && _playerData.Valid)
|
if (_playerIdentifier.IsValid && _playerData.Valid)
|
||||||
{
|
{
|
||||||
available |= 1;
|
available |= 1;
|
||||||
_tooltipBuilder.Append("Left-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ")
|
_tooltipBuilder
|
||||||
|
.Append(
|
||||||
|
"Left-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ")
|
||||||
.Append(_playerIdentifier)
|
.Append(_playerIdentifier)
|
||||||
.Append('.');
|
.Append('.');
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +474,9 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
if (available != 0)
|
if (available != 0)
|
||||||
_tooltipBuilder.Append('\n');
|
_tooltipBuilder.Append('\n');
|
||||||
available |= 2;
|
available |= 2;
|
||||||
_tooltipBuilder.Append("Right-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ")
|
_tooltipBuilder
|
||||||
|
.Append(
|
||||||
|
"Right-Click: Reset all temporary settings applied by Glamourer (manually or through automation) to the collection affecting ")
|
||||||
.Append(_targetIdentifier)
|
.Append(_targetIdentifier)
|
||||||
.Append('.');
|
.Append('.');
|
||||||
}
|
}
|
||||||
|
|
@ -495,7 +537,9 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
++_numButtons;
|
++_numButtons;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
|
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedCustomization))
|
||||||
|
++_numButtons;
|
||||||
|
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedDyes))
|
||||||
++_numButtons;
|
++_numButtons;
|
||||||
if (_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
|
if (_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
|
||||||
++_numButtons;
|
++_numButtons;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Lumina.Excel.Sheets;
|
using Lumina.Excel.Sheets;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
|
||||||
public readonly void SetStains(StainIds stains)
|
public readonly void SetStains(StainIds stains)
|
||||||
=> _editor.ChangeStains(_object, Slot, stains, ApplySettings.Manual);
|
=> _editor.ChangeStains(_object, Slot, stains, ApplySettings.Manual);
|
||||||
|
|
||||||
|
public readonly void SetStain(int which, StainId stain)
|
||||||
|
=> _editor.ChangeStains(_object, Slot, CurrentStains.With(which, stain), ApplySettings.Manual);
|
||||||
|
|
||||||
public readonly void SetApplyItem(bool value)
|
public readonly void SetApplyItem(bool value)
|
||||||
{
|
{
|
||||||
var manager = (DesignManager)_editor;
|
var manager = (DesignManager)_editor;
|
||||||
|
|
|
||||||
83
Glamourer/Gui/Equipment/EquipItemSlotCache.cs
Normal file
83
Glamourer/Gui/Equipment/EquipItemSlotCache.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
using Glamourer.Services;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Glamourer.Gui.Equipment;
|
||||||
|
|
||||||
|
[InlineArray(13)]
|
||||||
|
public struct EquipItemSlotCache
|
||||||
|
{
|
||||||
|
private EquipItem _element;
|
||||||
|
|
||||||
|
public EquipItem Dragged
|
||||||
|
{
|
||||||
|
get => this[^1];
|
||||||
|
set => this[^1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
=> ((Span<EquipItem>)this).Clear();
|
||||||
|
|
||||||
|
public EquipItem this[EquipSlot slot]
|
||||||
|
{
|
||||||
|
get => this[(int)slot.ToIndex()];
|
||||||
|
set => this[(int)slot.ToIndex()] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(ItemManager items, in EquipItem item, EquipSlot startSlot)
|
||||||
|
{
|
||||||
|
if (item.Id == Dragged.Id && item.Type == Dragged.Type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (startSlot)
|
||||||
|
{
|
||||||
|
case EquipSlot.MainHand:
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
this[EquipSlot.MainHand] = item;
|
||||||
|
if (item.Type is FullEquipType.Sword)
|
||||||
|
this[EquipSlot.OffHand] = items.FindClosestShield(item.ItemId, out var shield) ? shield : default;
|
||||||
|
else
|
||||||
|
this[EquipSlot.OffHand] = items.ItemData.Secondary.GetValueOrDefault(item.ItemId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EquipSlot.OffHand:
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
if (item.Type is FullEquipType.Shield)
|
||||||
|
this[EquipSlot.MainHand] = items.FindClosestSword(item.ItemId, out var sword) ? sword : default;
|
||||||
|
else
|
||||||
|
this[EquipSlot.MainHand] = items.ItemData.Primary.GetValueOrDefault(item.ItemId);
|
||||||
|
this[EquipSlot.OffHand] = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
this[EquipSlot.MainHand] = default;
|
||||||
|
this[EquipSlot.OffHand] = default;
|
||||||
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
|
{
|
||||||
|
if (startSlot == slot)
|
||||||
|
{
|
||||||
|
this[slot] = item;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slotItem = items.Identify(slot, item.PrimaryId, item.Variant);
|
||||||
|
if (!slotItem.Valid || slotItem.ItemId.Id is not 0 != item.ItemId.Id is not 0)
|
||||||
|
{
|
||||||
|
slotItem = items.Identify(EquipSlot.OffHand, item.PrimaryId, item.SecondaryId, 1, item.Type);
|
||||||
|
if (slotItem.ItemId.Id is not 0 != item.ItemId.Id is not 0)
|
||||||
|
slotItem = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
this[slot] = slotItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dragged = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,15 +3,15 @@ using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Gui.Materials;
|
using Glamourer.Gui.Materials;
|
||||||
using Glamourer.Interop.Material;
|
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using OtterGui.Text.EndObjects;
|
using OtterGui.Text.EndObjects;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
@ -32,20 +32,24 @@ public class EquipmentDrawer
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly GPoseService _gPose;
|
private readonly GPoseService _gPose;
|
||||||
private readonly AdvancedDyePopup _advancedDyes;
|
private readonly AdvancedDyePopup _advancedDyes;
|
||||||
|
private readonly ItemCopyService _itemCopy;
|
||||||
|
|
||||||
private float _requiredComboWidthUnscaled;
|
private float _requiredComboWidthUnscaled;
|
||||||
private float _requiredComboWidth;
|
private float _requiredComboWidth;
|
||||||
|
|
||||||
private Stain? _draggedStain;
|
private Stain? _draggedStain;
|
||||||
|
private EquipItemSlotCache _draggedItem;
|
||||||
|
private EquipSlot _dragTarget;
|
||||||
|
|
||||||
public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, TextureService textures,
|
public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, TextureService textures,
|
||||||
Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes)
|
Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes, ItemCopyService itemCopy)
|
||||||
{
|
{
|
||||||
_items = items;
|
_items = items;
|
||||||
_textures = textures;
|
_textures = textures;
|
||||||
_config = config;
|
_config = config;
|
||||||
_gPose = gPose;
|
_gPose = gPose;
|
||||||
_advancedDyes = advancedDyes;
|
_advancedDyes = advancedDyes;
|
||||||
|
_itemCopy = itemCopy;
|
||||||
_stainData = items.Stains;
|
_stainData = items.Stains;
|
||||||
_stainCombo = new GlamourerColorCombo(DefaultWidth - 20, _stainData, favorites);
|
_stainCombo = new GlamourerColorCombo(DefaultWidth - 20, _stainData, favorites);
|
||||||
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, Glamourer.Log, favorites)).ToArray();
|
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, Glamourer.Log, favorites)).ToArray();
|
||||||
|
|
@ -78,6 +82,7 @@ public class EquipmentDrawer
|
||||||
|
|
||||||
_requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale;
|
_requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale;
|
||||||
_advancedMaterialColor = ColorId.AdvancedDyeActive.Value();
|
_advancedMaterialColor = ColorId.AdvancedDyeActive.Value();
|
||||||
|
_dragTarget = EquipSlot.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool VerifyRestrictedGear(EquipDrawData data)
|
private bool VerifyRestrictedGear(EquipDrawData data)
|
||||||
|
|
@ -183,6 +188,7 @@ public class EquipmentDrawer
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Small
|
#region Small
|
||||||
|
|
||||||
private void DrawEquipSmall(in EquipDrawData equipDrawData)
|
private void DrawEquipSmall(in EquipDrawData equipDrawData)
|
||||||
|
|
@ -401,6 +407,7 @@ public class EquipmentDrawer
|
||||||
? _stainCombo.Draw($"##stain{data.Slot}", stain.RgbaColor, stain.Name, found, stain.Gloss)
|
? _stainCombo.Draw($"##stain{data.Slot}", stain.RgbaColor, stain.Name, found, stain.Gloss)
|
||||||
: _stainCombo.Draw($"##stain{data.Slot}", stain.RgbaColor, stain.Name, found, stain.Gloss, width);
|
: _stainCombo.Draw($"##stain{data.Slot}", stain.RgbaColor, stain.Name, found, stain.Gloss, width);
|
||||||
|
|
||||||
|
_itemCopy.HandleCopyPaste(data, index);
|
||||||
if (!change)
|
if (!change)
|
||||||
DrawStainDragDrop(data, index, stain, found);
|
DrawStainDragDrop(data, index, stain, found);
|
||||||
|
|
||||||
|
|
@ -425,8 +432,8 @@ public class EquipmentDrawer
|
||||||
using var dragSource = ImUtf8.DragDropSource();
|
using var dragSource = ImUtf8.DragDropSource();
|
||||||
if (dragSource.Success)
|
if (dragSource.Success)
|
||||||
{
|
{
|
||||||
if (DragDropSource.SetPayload("stainDragDrop"u8))
|
DragDropSource.SetPayload("stainDragDrop"u8);
|
||||||
_draggedStain = stain;
|
_draggedStain = stain;
|
||||||
ImUtf8.Text($"Dragging {stain.Name}...");
|
ImUtf8.Text($"Dragging {stain.Name}...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -451,10 +458,12 @@ public class EquipmentDrawer
|
||||||
using var disabled = ImRaii.Disabled(data.Locked);
|
using var disabled = ImRaii.Disabled(data.Locked);
|
||||||
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
||||||
_requiredComboWidth);
|
_requiredComboWidth);
|
||||||
|
DrawGearDragDrop(data);
|
||||||
if (change)
|
if (change)
|
||||||
data.SetItem(combo.CurrentSelection);
|
data.SetItem(combo.CurrentSelection);
|
||||||
else if (combo.CustomVariant.Id > 0)
|
else if (combo.CustomVariant.Id > 0)
|
||||||
data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant));
|
data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant));
|
||||||
|
_itemCopy.HandleCopyPaste(data);
|
||||||
|
|
||||||
if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, ItemManager.NothingItem(data.Slot),
|
if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, ItemManager.NothingItem(data.Slot),
|
||||||
out var item))
|
out var item))
|
||||||
|
|
@ -472,6 +481,14 @@ public class EquipmentDrawer
|
||||||
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem,
|
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem,
|
||||||
small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
||||||
_requiredComboWidth);
|
_requiredComboWidth);
|
||||||
|
if (ImGui.IsItemHovered() && ImGui.GetIO().KeyCtrl)
|
||||||
|
{
|
||||||
|
if (ImGui.IsKeyPressed(ImGuiKey.C))
|
||||||
|
_itemCopy.Copy(combo.CurrentSelection);
|
||||||
|
else if (ImGui.IsKeyPressed(ImGuiKey.V))
|
||||||
|
_itemCopy.Paste(data.Slot.ToEquipType(), data.SetItem);
|
||||||
|
}
|
||||||
|
|
||||||
if (change)
|
if (change)
|
||||||
data.SetItem(combo.CurrentSelection);
|
data.SetItem(combo.CurrentSelection);
|
||||||
else if (combo.CustomVariant.Id > 0)
|
else if (combo.CustomVariant.Id > 0)
|
||||||
|
|
@ -482,6 +499,50 @@ public class EquipmentDrawer
|
||||||
data.SetItem(item);
|
data.SetItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawGearDragDrop(in EquipDrawData data)
|
||||||
|
{
|
||||||
|
if (data.CurrentItem.Valid)
|
||||||
|
{
|
||||||
|
using var dragSource = ImUtf8.DragDropSource();
|
||||||
|
if (dragSource.Success)
|
||||||
|
{
|
||||||
|
DragDropSource.SetPayload("equipDragDrop"u8);
|
||||||
|
_draggedItem.Update(_items, data.CurrentItem, data.Slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using var dragTarget = ImUtf8.DragDropTarget();
|
||||||
|
if (!dragTarget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var item = _draggedItem[data.Slot];
|
||||||
|
if (!item.Valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragTarget = data.Slot;
|
||||||
|
if (!dragTarget.IsDropping("equipDragDrop"u8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
data.SetItem(item);
|
||||||
|
_draggedItem.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void DrawDragDropTooltip()
|
||||||
|
{
|
||||||
|
var payload = ImGui.GetDragDropPayload().Handle;
|
||||||
|
if (payload is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)Unsafe.AsPointer(ref payload->DataType_0)).SequenceEqual("equipDragDrop"u8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
using var tt = ImUtf8.Tooltip();
|
||||||
|
if (_dragTarget is EquipSlot.Unknown)
|
||||||
|
ImUtf8.Text($"Dragging {_draggedItem.Dragged.Name}...");
|
||||||
|
else
|
||||||
|
ImUtf8.Text($"Converting to {_draggedItem[_dragTarget].Name}...");
|
||||||
|
}
|
||||||
|
|
||||||
private static bool ResetOrClear<T>(bool locked, bool clicked, bool allowRevert, bool allowClear,
|
private static bool ResetOrClear<T>(bool locked, bool clicked, bool allowRevert, bool allowClear,
|
||||||
in T currentItem, in T revertItem, in T clearItem, out T? item) where T : IEquatable<T>
|
in T currentItem, in T revertItem, in T clearItem, out T? item) where T : IEquatable<T>
|
||||||
{
|
{
|
||||||
|
|
@ -530,8 +591,13 @@ public class EquipmentDrawer
|
||||||
if (combo.Draw(mainhand.CurrentItem.Name, mainhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
if (combo.Draw(mainhand.CurrentItem.Name, mainhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
||||||
_requiredComboWidth))
|
_requiredComboWidth))
|
||||||
changedItem = combo.CurrentSelection;
|
changedItem = combo.CurrentSelection;
|
||||||
else if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem,
|
else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type))
|
||||||
default, out var c))
|
changedItem = _items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant);
|
||||||
|
_itemCopy.HandleCopyPaste(mainhand);
|
||||||
|
DrawGearDragDrop(mainhand);
|
||||||
|
|
||||||
|
if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem,
|
||||||
|
default, out var c))
|
||||||
changedItem = c;
|
changedItem = c;
|
||||||
|
|
||||||
if (changedItem != null)
|
if (changedItem != null)
|
||||||
|
|
@ -548,7 +614,8 @@ public class EquipmentDrawer
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unknown)
|
if (unknown)
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, "The weapon type could not be identified, thus changing it to other weapons of that type is not possible."u8);
|
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled,
|
||||||
|
"The weapon type could not be identified, thus changing it to other weapons of that type is not possible."u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawOffhand(in EquipDrawData mainhand, in EquipDrawData offhand, out string label, bool small, bool clear, bool open)
|
private void DrawOffhand(in EquipDrawData mainhand, in EquipDrawData offhand, out string label, bool small, bool clear, bool open)
|
||||||
|
|
@ -568,6 +635,10 @@ public class EquipmentDrawer
|
||||||
if (combo.Draw(offhand.CurrentItem.Name, offhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
if (combo.Draw(offhand.CurrentItem.Name, offhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
|
||||||
_requiredComboWidth))
|
_requiredComboWidth))
|
||||||
offhand.SetItem(combo.CurrentSelection);
|
offhand.SetItem(combo.CurrentSelection);
|
||||||
|
else if (combo.CustomVariant.Id > 0 && ItemData.ConvertWeaponId(combo.CustomSetId) == offhand.CurrentItem.Type)
|
||||||
|
offhand.SetItem(_items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant));
|
||||||
|
_itemCopy.HandleCopyPaste(offhand);
|
||||||
|
DrawGearDragDrop(offhand);
|
||||||
|
|
||||||
var defaultOffhand = _items.GetDefaultOffhand(mainhand.CurrentItem);
|
var defaultOffhand = _items.GetDefaultOffhand(mainhand.CurrentItem);
|
||||||
if (ResetOrClear(locked, clear, offhand.AllowRevert, true, offhand.CurrentItem, offhand.GameItem, defaultOffhand, out var item))
|
if (ResetOrClear(locked, clear, offhand.AllowRevert, true, offhand.CurrentItem, offhand.GameItem, defaultOffhand, out var item))
|
||||||
|
|
@ -622,6 +693,7 @@ public class EquipmentDrawer
|
||||||
{
|
{
|
||||||
ImUtf8.Text(label);
|
ImUtf8.Text(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasAdvancedDyes)
|
if (hasAdvancedDyes)
|
||||||
ImUtf8.HoverTooltip("This design has advanced dyes setup for this slot."u8);
|
ImUtf8.HoverTooltip("This design has advanced dyes setup for this slot."u8);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Lumina.Excel.Sheets;
|
using Lumina.Excel.Sheets;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
|
||||||
73
Glamourer/Gui/Equipment/ItemCopyService.cs
Normal file
73
Glamourer/Gui/Equipment/ItemCopyService.cs
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
using Glamourer.Services;
|
||||||
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using OtterGui.Services;
|
||||||
|
using Penumbra.GameData.DataContainers;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Glamourer.Gui.Equipment;
|
||||||
|
|
||||||
|
public class ItemCopyService(ItemManager items, DictStain stainData) : IUiService
|
||||||
|
{
|
||||||
|
public EquipItem? Item { get; private set; }
|
||||||
|
public Stain? Stain { get; private set; }
|
||||||
|
|
||||||
|
public void Copy(in EquipItem item)
|
||||||
|
=> Item = item;
|
||||||
|
|
||||||
|
public void Copy(in Stain stain)
|
||||||
|
=> Stain = stain;
|
||||||
|
|
||||||
|
public void Paste(int which, Action<int, StainId> setter)
|
||||||
|
{
|
||||||
|
if (Stain is { } stain)
|
||||||
|
setter(which, stain.RowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Paste(FullEquipType type, Action<EquipItem> setter)
|
||||||
|
{
|
||||||
|
if (Item is not { } item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (type != item.Type)
|
||||||
|
{
|
||||||
|
if (type.IsBonus())
|
||||||
|
item = items.Identify(type.ToBonus(), item.PrimaryId, item.Variant);
|
||||||
|
else if (type.IsEquipment() || type.IsAccessory())
|
||||||
|
item = items.Identify(type.ToSlot(), item.PrimaryId, item.Variant);
|
||||||
|
else
|
||||||
|
item = items.Identify(type.ToSlot(), item.PrimaryId, item.SecondaryId, item.Variant);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Valid && item.Type == type)
|
||||||
|
setter(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleCopyPaste(in EquipDrawData data)
|
||||||
|
{
|
||||||
|
if (ImGui.GetIO().KeyCtrl)
|
||||||
|
{
|
||||||
|
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
|
||||||
|
Paste(data.CurrentItem.Type, data.SetItem);
|
||||||
|
}
|
||||||
|
else if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
|
||||||
|
{
|
||||||
|
Copy(data.CurrentItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleCopyPaste(in EquipDrawData data, int which)
|
||||||
|
{
|
||||||
|
if (ImGui.GetIO().KeyCtrl)
|
||||||
|
{
|
||||||
|
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
|
||||||
|
Paste(which, data.SetStain);
|
||||||
|
}
|
||||||
|
else if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)
|
||||||
|
&& ImGui.IsMouseClicked(ImGuiMouseButton.Middle)
|
||||||
|
&& stainData.TryGetValue(data.CurrentStains[which].Id, out var stain))
|
||||||
|
{
|
||||||
|
Copy(stain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -19,6 +19,10 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
|
||||||
private ItemId _currentItem;
|
private ItemId _currentItem;
|
||||||
private float _innerWidth;
|
private float _innerWidth;
|
||||||
|
|
||||||
|
public PrimaryId CustomSetId { get; private set; }
|
||||||
|
public SecondaryId CustomWeaponId { get; private set; }
|
||||||
|
public Variant CustomVariant { get; private set; }
|
||||||
|
|
||||||
public WeaponCombo(ItemManager items, FullEquipType type, Logger log, FavoriteManager favorites)
|
public WeaponCombo(ItemManager items, FullEquipType type, Logger log, FavoriteManager favorites)
|
||||||
: base(() => GetWeapons(favorites, items, type), MouseWheelType.Control, log)
|
: base(() => GetWeapons(favorites, items, type), MouseWheelType.Control, log)
|
||||||
{
|
{
|
||||||
|
|
@ -46,8 +50,9 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
|
||||||
|
|
||||||
public bool Draw(string previewName, ItemId previewIdx, float width, float innerWidth)
|
public bool Draw(string previewName, ItemId previewIdx, float width, float innerWidth)
|
||||||
{
|
{
|
||||||
_innerWidth = innerWidth;
|
_innerWidth = innerWidth;
|
||||||
_currentItem = previewIdx;
|
_currentItem = previewIdx;
|
||||||
|
CustomVariant = 0;
|
||||||
return Draw($"##{Label}", previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
return Draw($"##{Label}", previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,6 +79,24 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnClosePopup()
|
||||||
|
{
|
||||||
|
// If holding control while the popup closes, try to parse the input as a full tuple of set id, weapon id and variant, and set a custom item for that.
|
||||||
|
if (!ImGui.GetIO().KeyCtrl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var split = Filter.Text.Split('-', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||||
|
if (split.Length != 3
|
||||||
|
|| !ushort.TryParse(split[0], out var setId)
|
||||||
|
|| !ushort.TryParse(split[1], out var weaponId)
|
||||||
|
|| !byte.TryParse(split[2], out var variant))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CustomSetId = setId;
|
||||||
|
CustomWeaponId = weaponId;
|
||||||
|
CustomVariant = variant;
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool IsVisible(int globalIndex, LowerString filter)
|
protected override bool IsVisible(int globalIndex, LowerString filter)
|
||||||
=> base.IsVisible(globalIndex, filter) || Items[globalIndex].ModelString.StartsWith(filter.Lower);
|
=> base.IsVisible(globalIndex, filter) || Items[globalIndex].ModelString.StartsWith(filter.Lower);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Gui.Materials;
|
using Glamourer.Gui.Materials;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ public class GlamourerChangelog
|
||||||
Add1_3_5_0(Changelog);
|
Add1_3_5_0(Changelog);
|
||||||
Add1_3_6_0(Changelog);
|
Add1_3_6_0(Changelog);
|
||||||
Add1_3_7_0(Changelog);
|
Add1_3_7_0(Changelog);
|
||||||
|
Add1_3_8_0(Changelog);
|
||||||
|
Add1_4_0_0(Changelog);
|
||||||
|
Add1_5_0_0(Changelog);
|
||||||
|
Add1_5_1_0(Changelog);
|
||||||
}
|
}
|
||||||
|
|
||||||
private (int, ChangeLogDisplayType) ConfigData()
|
private (int, ChangeLogDisplayType) ConfigData()
|
||||||
|
|
@ -61,6 +65,66 @@ public class GlamourerChangelog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Add1_5_1_0(Changelog log)
|
||||||
|
=> log.NextVersion("Version 1.5.1.0")
|
||||||
|
.RegisterHighlight("Added support for Penumbras PCP functionality to add the current state of the character as a design.")
|
||||||
|
.RegisterEntry("On import, a design for the PCP is created and, if possible, applied to the character.", 1)
|
||||||
|
.RegisterEntry("No automation is assigned.", 1)
|
||||||
|
.RegisterEntry("Finer control about this can be found in the settings.", 1)
|
||||||
|
.RegisterEntry("Fixed an issue with static visors not toggling through Glamourer (1.5.0.7).")
|
||||||
|
.RegisterEntry("The advanced dye slot combo now contains glasses (1.5.0.7).")
|
||||||
|
.RegisterEntry("Several fixes for patch-related issues (1.5.0.1 - 1.5.0.6");
|
||||||
|
|
||||||
|
private static void Add1_5_0_0(Changelog log)
|
||||||
|
=> log.NextVersion("Version 1.5.0.0")
|
||||||
|
.RegisterImportant("Updated for game version 7.30 and Dalamud API13, which uses a new GUI backend. Some things may not work as expected. Please let me know any issues you encounter.")
|
||||||
|
.RegisterHighlight("Added the new Viera Ears state to designs. Old designs will not apply the state.")
|
||||||
|
.RegisterHighlight("Added the option to make newly created designs write-protected by default to the design defaults.")
|
||||||
|
.RegisterEntry("Fixed issues with reverting state and IPC.")
|
||||||
|
.RegisterEntry("Fixed an issue when using the mousewheel to scroll through designs (1.4.0.3).")
|
||||||
|
.RegisterEntry("Fixed an issue with invalid bonus items (1.4.0.3).")
|
||||||
|
.RegisterHighlight("Added drag & drop of equipment pieces which will try to match the corresponding model IDs in other slots if possible (1.4.0.2).")
|
||||||
|
.RegisterEntry("Heavily optimized some issues when having many designs and creating new ones or updating them (1.4.0.2)")
|
||||||
|
.RegisterEntry("Fixed an issue with staining templates (1.4.0.1).")
|
||||||
|
.RegisterEntry("Fixed an issue with the QDB buttons not counting correctly (1.4.0.1).");
|
||||||
|
|
||||||
|
private static void Add1_4_0_0(Changelog log)
|
||||||
|
=> log.NextVersion("Version 1.4.0.0")
|
||||||
|
.RegisterHighlight("The design selector width is now draggable within certain restrictions that depend on the total window width.")
|
||||||
|
.RegisterEntry("The current behavior may not be final, let me know if you have any comments.", 1)
|
||||||
|
.RegisterEntry("Regular customization colors can now be dragged & dropped onto other customizations.")
|
||||||
|
.RegisterEntry(
|
||||||
|
"If no identical color is available in the target slot, the most similar color available (for certain values of similar) will be chosen instead.",
|
||||||
|
1)
|
||||||
|
.RegisterEntry("Resetting advanced dyes and customizations has been split into two buttons for the quick design bar.")
|
||||||
|
.RegisterEntry("Weapons now also support custom ID input in the combo search box.")
|
||||||
|
.RegisterEntry("Added new IPC methods GetExtendedDesignData, AddDesign, DeleteDesign, GetDesignBase64, GetDesignJObject.")
|
||||||
|
.RegisterEntry("Added the option to prevent immediate repeats for random design selection (Thanks Diorik!).")
|
||||||
|
.RegisterEntry("Optimized some multi-design changes when selecting many designs and changing them at once.")
|
||||||
|
.RegisterEntry("Fixed item combos not starting from the currently selected item when scrolling them via mouse wheel.")
|
||||||
|
.RegisterEntry("Fixed some issue with Glamourer not searching mods by name for mod associations in some cases.")
|
||||||
|
.RegisterEntry("Fixed the IPC methods SetMetaState and SetMetaStateName not working (Thanks Caraxi!).")
|
||||||
|
.RegisterEntry("Added new IPC method GetDesignListExtended. (1.3.8.6)")
|
||||||
|
.RegisterEntry(
|
||||||
|
"Improved the naming of NPCs for identifiers by using Haselnussbombers new naming functionality (Thanks Hasel!). (1.3.8.6)")
|
||||||
|
.RegisterEntry(
|
||||||
|
"Added a modifier key separate from the delete modifier key that is used for less important key-checks, specifically toggling incognito mode. (1.3.8.5)")
|
||||||
|
.RegisterEntry("Used better Penumbra IPC for some things. (1.3.8.5)")
|
||||||
|
.RegisterEntry("Fixed an issue with advanced dyes for weapons. (1.3.8.5)")
|
||||||
|
.RegisterEntry("Fixed an issue with NPC automation due to missing job detection. (1.3.8.1)");
|
||||||
|
|
||||||
|
private static void Add1_3_8_0(Changelog log)
|
||||||
|
=> log.NextVersion("Version 1.3.8.0")
|
||||||
|
.RegisterImportant("Updated Glamourer for update 7.20 and Dalamud API 12.")
|
||||||
|
.RegisterEntry(
|
||||||
|
"This is not thoroughly tested, but I decided to push to stable instead of testing because otherwise a lot of people would just go to testing just for early access again despite having no business doing so.",
|
||||||
|
1)
|
||||||
|
.RegisterEntry(
|
||||||
|
"I also do not use most of the functionality of Glamourer myself, so I am unable to even encounter most issues myself.", 1)
|
||||||
|
.RegisterEntry("If you encounter any issues, please report them quickly on the discord.", 1)
|
||||||
|
.RegisterEntry("Added a chat command to clear temporary settings applied by Glamourer to Penumbra.")
|
||||||
|
.RegisterEntry("Fixed small issues with customizations not applicable to your race still applying.");
|
||||||
|
|
||||||
private static void Add1_3_7_0(Changelog log)
|
private static void Add1_3_7_0(Changelog log)
|
||||||
=> log.NextVersion("Version 1.3.7.0")
|
=> log.NextVersion("Version 1.3.7.0")
|
||||||
.RegisterImportant(
|
.RegisterImportant(
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ using Glamourer.Gui.Tabs.NpcTab;
|
||||||
using Glamourer.Gui.Tabs.SettingsTab;
|
using Glamourer.Gui.Tabs.SettingsTab;
|
||||||
using Glamourer.Gui.Tabs.UnlocksTab;
|
using Glamourer.Gui.Tabs.UnlocksTab;
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Interop.Penumbra;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Custom;
|
using OtterGui.Custom;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using FFXIVClientStructs.Interop;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Interop.Material;
|
using Glamourer.Interop.Material;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -91,10 +91,10 @@ public sealed unsafe class AdvancedDyePopup(
|
||||||
var modelHandle = model == null ? null : model->ModelResourceHandle;
|
var modelHandle = model == null ? null : model->ModelResourceHandle;
|
||||||
var path = materialHandle == null
|
var path = materialHandle == null
|
||||||
? string.Empty
|
? string.Empty
|
||||||
: ByteString.FromSpanUnsafe(materialHandle->ResourceHandle.FileName.AsSpan(), true).ToString();
|
: ByteString.FromSpanUnsafe(materialHandle->FileName.AsSpan(), true).ToString();
|
||||||
var gamePath = modelHandle == null
|
var gamePath = modelHandle == null
|
||||||
? string.Empty
|
? string.Empty
|
||||||
: modelHandle->GetMaterialFileNameBySlotAsString(index.MaterialIndex);
|
: modelHandle->GetMaterialFileNameBySlot(index.MaterialIndex).ToString();
|
||||||
return (path, gamePath);
|
return (path, gamePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Interop.Material;
|
using Glamourer.Interop.Material;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -18,7 +18,6 @@ public class MaterialDrawer(DesignManager _designManager, Configuration _config)
|
||||||
public const float GlossWidth = 100;
|
public const float GlossWidth = 100;
|
||||||
public const float SpecularStrengthWidth = 125;
|
public const float SpecularStrengthWidth = 125;
|
||||||
|
|
||||||
private EquipSlot _newSlot = EquipSlot.Head;
|
|
||||||
private int _newMaterialIdx;
|
private int _newMaterialIdx;
|
||||||
private int _newRowIdx;
|
private int _newRowIdx;
|
||||||
private MaterialValueIndex _newKey = MaterialValueIndex.FromSlot(EquipSlot.Head);
|
private MaterialValueIndex _newKey = MaterialValueIndex.FromSlot(EquipSlot.Head);
|
||||||
|
|
@ -178,14 +177,42 @@ public class MaterialDrawer(DesignManager _designManager, Configuration _config)
|
||||||
|
|
||||||
public sealed class MaterialSlotCombo;
|
public sealed class MaterialSlotCombo;
|
||||||
|
|
||||||
|
private void DrawSlotCombo()
|
||||||
|
{
|
||||||
|
var width = ImUtf8.CalcTextSize(EquipSlot.OffHand.ToName()).X + ImGui.GetFrameHeightWithSpacing();
|
||||||
|
ImGui.SetNextItemWidth(width);
|
||||||
|
using var combo = ImUtf8.Combo("##slot"u8, _newKey.SlotName());
|
||||||
|
if (combo)
|
||||||
|
{
|
||||||
|
var currentSlot = _newKey.ToEquipSlot();
|
||||||
|
foreach (var tmpSlot in EquipSlotExtensions.FullSlots)
|
||||||
|
{
|
||||||
|
if (ImUtf8.Selectable(tmpSlot.ToName(), tmpSlot == currentSlot) && currentSlot != tmpSlot)
|
||||||
|
_newKey = MaterialValueIndex.FromSlot(tmpSlot) with
|
||||||
|
{
|
||||||
|
MaterialIndex = (byte)_newMaterialIdx,
|
||||||
|
RowIndex = (byte)_newRowIdx,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentBonus = _newKey.ToBonusSlot();
|
||||||
|
foreach (var bonusSlot in BonusExtensions.AllFlags)
|
||||||
|
{
|
||||||
|
if (ImUtf8.Selectable(bonusSlot.ToName(), bonusSlot == currentBonus) && bonusSlot != currentBonus)
|
||||||
|
_newKey = MaterialValueIndex.FromSlot(bonusSlot) with
|
||||||
|
{
|
||||||
|
MaterialIndex = (byte)_newMaterialIdx,
|
||||||
|
RowIndex = (byte)_newRowIdx,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImUtf8.HoverTooltip("Choose a slot for an advanced dye row."u8);
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawNew(Design design)
|
public void DrawNew(Design design)
|
||||||
{
|
{
|
||||||
if (EquipSlotCombo.Draw("##slot", "Choose a slot for an advanced dye row.", ref _newSlot))
|
DrawSlotCombo();
|
||||||
_newKey = MaterialValueIndex.FromSlot(_newSlot) with
|
|
||||||
{
|
|
||||||
MaterialIndex = (byte)_newMaterialIdx,
|
|
||||||
RowIndex = (byte)_newRowIdx,
|
|
||||||
};
|
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
DrawMaterialIdxDrag();
|
DrawMaterialIdxDrag();
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,40 @@
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Interop.Penumbra;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.GameData.Data;
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Gui;
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
public sealed class PenumbraChangedItemTooltip : IDisposable
|
public sealed class PenumbraChangedItemTooltip : IDisposable
|
||||||
{
|
{
|
||||||
private readonly PenumbraService _penumbra;
|
private readonly PenumbraService _penumbra;
|
||||||
private readonly StateManager _stateManager;
|
private readonly StateManager _stateManager;
|
||||||
private readonly ItemManager _items;
|
private readonly ItemManager _items;
|
||||||
private readonly ObjectManager _objects;
|
private readonly ActorObjectManager _objects;
|
||||||
private readonly CustomizeService _customize;
|
private readonly CustomizeService _customize;
|
||||||
private readonly GPoseService _gpose;
|
private readonly GPoseService _gpose;
|
||||||
|
|
||||||
private readonly EquipItem[] _lastItems = new EquipItem[EquipFlagExtensions.NumEquipFlags / 2];
|
private readonly EquipItem[] _lastItems = new EquipItem[EquipFlagExtensions.NumEquipFlags / 2 + BonusExtensions.AllFlags.Count];
|
||||||
|
|
||||||
public IEnumerable<KeyValuePair<EquipSlot, EquipItem>> LastItems
|
public IEnumerable<KeyValuePair<object, EquipItem>> LastItems
|
||||||
=> EquipSlotExtensions.EqdpSlots.Append(EquipSlot.MainHand).Append(EquipSlot.OffHand).Zip(_lastItems)
|
=> EquipSlotExtensions.EqdpSlots.Cast<object>().Append(EquipSlot.MainHand).Append(EquipSlot.OffHand)
|
||||||
.Select(p => new KeyValuePair<EquipSlot, EquipItem>(p.First, p.Second));
|
.Concat(BonusExtensions.AllFlags.Cast<object>()).Zip(_lastItems)
|
||||||
|
.Select(p => new KeyValuePair<object, EquipItem>(p.First, p.Second));
|
||||||
|
|
||||||
public ChangedItemType LastType { get; private set; } = ChangedItemType.None;
|
public ChangedItemType LastType { get; private set; } = ChangedItemType.None;
|
||||||
public uint LastId { get; private set; } = 0;
|
public uint LastId { get; private set; }
|
||||||
public DateTime LastTooltip { get; private set; } = DateTime.MinValue;
|
public DateTime LastTooltip { get; private set; } = DateTime.MinValue;
|
||||||
public DateTime LastClick { get; private set; } = DateTime.MinValue;
|
public DateTime LastClick { get; private set; } = DateTime.MinValue;
|
||||||
|
|
||||||
public PenumbraChangedItemTooltip(PenumbraService penumbra, StateManager stateManager, ItemManager items, ObjectManager objects,
|
public PenumbraChangedItemTooltip(PenumbraService penumbra, StateManager stateManager, ItemManager items, ActorObjectManager objects,
|
||||||
CustomizeService customize, GPoseService gpose)
|
CustomizeService customize, GPoseService gpose)
|
||||||
{
|
{
|
||||||
_penumbra = penumbra;
|
_penumbra = penumbra;
|
||||||
|
|
@ -72,6 +73,21 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
|
||||||
if (!Player())
|
if (!Player())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var bonusSlot = item.Type.ToBonus();
|
||||||
|
if (bonusSlot is not BonusItemFlag.Unknown)
|
||||||
|
{
|
||||||
|
// + 2 due to weapons.
|
||||||
|
var glasses = _lastItems[bonusSlot.ToSlot() + 2];
|
||||||
|
using (_ = !openTooltip ? null : ImRaii.Tooltip())
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted($"{prefix}Right-Click to apply to current actor.");
|
||||||
|
if (glasses.Valid)
|
||||||
|
ImGui.TextUnformatted($"{prefix}Control + Right-Click to re-apply {glasses.Name} to current actor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var slot = item.Type.ToSlot();
|
var slot = item.Type.ToSlot();
|
||||||
var last = _lastItems[slot.ToIndex()];
|
var last = _lastItems[slot.ToIndex()];
|
||||||
switch (slot)
|
switch (slot)
|
||||||
|
|
@ -109,6 +125,27 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
|
||||||
|
|
||||||
public void ApplyItem(ActorState state, EquipItem item)
|
public void ApplyItem(ActorState state, EquipItem item)
|
||||||
{
|
{
|
||||||
|
var bonusSlot = item.Type.ToBonus();
|
||||||
|
if (bonusSlot is not BonusItemFlag.Unknown)
|
||||||
|
{
|
||||||
|
// + 2 due to weapons.
|
||||||
|
var glasses = _lastItems[bonusSlot.ToSlot() + 2];
|
||||||
|
if (ImGui.GetIO().KeyCtrl && glasses.Valid)
|
||||||
|
{
|
||||||
|
Glamourer.Log.Debug($"Re-Applying {glasses.Name} to {bonusSlot.ToName()}.");
|
||||||
|
SetLastItem(bonusSlot, default, state);
|
||||||
|
_stateManager.ChangeBonusItem(state, bonusSlot, glasses, ApplySettings.Manual);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Glamourer.Log.Debug($"Applying {item.Name} to {bonusSlot.ToName()}.");
|
||||||
|
SetLastItem(bonusSlot, item, state);
|
||||||
|
_stateManager.ChangeBonusItem(state, bonusSlot, item, ApplySettings.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var slot = item.Type.ToSlot();
|
var slot = item.Type.ToSlot();
|
||||||
var last = _lastItems[slot.ToIndex()];
|
var last = _lastItems[slot.ToIndex()];
|
||||||
switch (slot)
|
switch (slot)
|
||||||
|
|
@ -265,7 +302,22 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
|
||||||
{
|
{
|
||||||
var oldItem = state.ModelData.Item(slot);
|
var oldItem = state.ModelData.Item(slot);
|
||||||
if (oldItem.Id != item.Id)
|
if (oldItem.Id != item.Id)
|
||||||
_lastItems[slot.ToIndex()] = oldItem;
|
last = oldItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetLastItem(BonusItemFlag slot, EquipItem item, ActorState state)
|
||||||
|
{
|
||||||
|
ref var last = ref _lastItems[slot.ToSlot() + 2];
|
||||||
|
if (!item.Valid)
|
||||||
|
{
|
||||||
|
last = default;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var oldItem = state.ModelData.BonusItem(slot);
|
||||||
|
if (oldItem.Id != item.Id)
|
||||||
|
last = oldItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,8 @@ using Glamourer.Gui.Customization;
|
||||||
using Glamourer.Gui.Equipment;
|
using Glamourer.Gui.Equipment;
|
||||||
using Glamourer.Gui.Materials;
|
using Glamourer.Gui.Materials;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Interop.Structs;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
@ -22,7 +21,6 @@ using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
using ObjectManager = Glamourer.Interop.ObjectManager;
|
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.ActorTab;
|
namespace Glamourer.Gui.Tabs.ActorTab;
|
||||||
|
|
||||||
|
|
@ -35,7 +33,7 @@ public class ActorPanel
|
||||||
private readonly AutoDesignApplier _autoDesignApplier;
|
private readonly AutoDesignApplier _autoDesignApplier;
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly DesignConverter _converter;
|
private readonly DesignConverter _converter;
|
||||||
private readonly ObjectManager _objects;
|
private readonly ActorObjectManager _objects;
|
||||||
private readonly DesignManager _designManager;
|
private readonly DesignManager _designManager;
|
||||||
private readonly ImportService _importService;
|
private readonly ImportService _importService;
|
||||||
private readonly ICondition _conditions;
|
private readonly ICondition _conditions;
|
||||||
|
|
@ -53,7 +51,7 @@ public class ActorPanel
|
||||||
AutoDesignApplier autoDesignApplier,
|
AutoDesignApplier autoDesignApplier,
|
||||||
Configuration config,
|
Configuration config,
|
||||||
DesignConverter converter,
|
DesignConverter converter,
|
||||||
ObjectManager objects,
|
ActorObjectManager objects,
|
||||||
DesignManager designManager,
|
DesignManager designManager,
|
||||||
ImportService importService,
|
ImportService importService,
|
||||||
ICondition conditions,
|
ICondition conditions,
|
||||||
|
|
@ -87,7 +85,7 @@ public class ActorPanel
|
||||||
_rightButtons =
|
_rightButtons =
|
||||||
[
|
[
|
||||||
new LockedButton(this),
|
new LockedButton(this),
|
||||||
new HeaderDrawer.IncognitoButton(_config.Ephemeral),
|
new HeaderDrawer.IncognitoButton(_config),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +104,7 @@ public class ActorPanel
|
||||||
{
|
{
|
||||||
using var group = ImRaii.Group();
|
using var group = ImRaii.Group();
|
||||||
(_identifier, _data) = _selector.Selection;
|
(_identifier, _data) = _selector.Selection;
|
||||||
_lockedRedraw = _identifier.Type is IdentifierType.Special
|
_lockedRedraw = _identifier.Type is IdentifierType.Special || _objects.IsInLobby
|
||||||
|| _conditions[ConditionFlag.OccupiedInCutSceneEvent];
|
|| _conditions[ConditionFlag.OccupiedInCutSceneEvent];
|
||||||
(_actorName, _actor) = GetHeaderName();
|
(_actorName, _actor) = GetHeaderName();
|
||||||
DrawHeader();
|
DrawHeader();
|
||||||
|
|
@ -240,6 +238,7 @@ public class ActorPanel
|
||||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||||
DrawEquipmentMetaToggles();
|
DrawEquipmentMetaToggles();
|
||||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||||
|
_equipmentDrawer.DrawDragDropTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawParameterHeader()
|
private void DrawParameterHeader()
|
||||||
|
|
@ -306,6 +305,12 @@ public class ActorPanel
|
||||||
EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(MetaIndex.WeaponState, _stateManager, _state!));
|
EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(MetaIndex.WeaponState, _stateManager, _state!));
|
||||||
EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromState(CrestFlag.OffHand, _stateManager, _state!));
|
EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromState(CrestFlag.OffHand, _stateManager, _state!));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
using (_ = ImRaii.Group())
|
||||||
|
{
|
||||||
|
EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(MetaIndex.EarState, _stateManager, _state!));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawMonsterPanel()
|
private void DrawMonsterPanel()
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,17 @@
|
||||||
using System.Security.AccessControl;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.Interop.Structs;
|
|
||||||
using ImGuiNET;
|
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.ActorTab;
|
namespace Glamourer.Gui.Tabs.ActorTab;
|
||||||
|
|
||||||
public class ActorSelector(ObjectManager objects, ActorManager actors, EphemeralConfig config)
|
public class ActorSelector(ActorObjectManager objects, ActorManager actors, EphemeralConfig config)
|
||||||
{
|
{
|
||||||
private ActorIdentifier _identifier = ActorIdentifier.Invalid;
|
private ActorIdentifier _identifier = ActorIdentifier.Invalid;
|
||||||
|
|
||||||
|
|
@ -89,11 +87,10 @@ public class ActorSelector(ObjectManager objects, ActorManager actors, Ephemeral
|
||||||
if (!child)
|
if (!child)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
objects.Update();
|
|
||||||
_world = new WorldId(objects.Player.Valid ? objects.Player.HomeWorld : (ushort)0);
|
_world = new WorldId(objects.Player.Valid ? objects.Player.HomeWorld : (ushort)0);
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing);
|
||||||
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeight());
|
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeight());
|
||||||
var remainder = ImGuiClip.FilteredClippedDraw(objects.Identifiers.Where(p => p.Value.Objects.Any(a => a.Model)), skips, CheckFilter,
|
var remainder = ImGuiClip.FilteredClippedDraw(objects.Where(p => p.Value.Objects.Any(a => a.Model)), skips, CheckFilter,
|
||||||
DrawSelectable);
|
DrawSelectable);
|
||||||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight());
|
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.ActorTab;
|
namespace Glamourer.Gui.Tabs.ActorTab;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
namespace Glamourer.Gui.Tabs.AutomationTab;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Custom;
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
|
using OtterGui.Custom;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
namespace Glamourer.Gui.Tabs.AutomationTab;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Gui;
|
using Penumbra.GameData.Gui;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ using Glamourer.Automation;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Designs.Special;
|
using Glamourer.Designs.Special;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
@ -278,7 +278,7 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
|
||||||
private void LookupTooltip(IEnumerable<Design> designs)
|
private void LookupTooltip(IEnumerable<Design> designs)
|
||||||
{
|
{
|
||||||
using var _ = ImRaii.Tooltip();
|
using var _ = ImRaii.Tooltip();
|
||||||
var tt = string.Join('\n', designs.Select(d => _designFileSystem.FindLeaf(d, out var l) ? l.FullName() : d.Name.Text).OrderBy(t => t));
|
var tt = string.Join('\n', designs.Select(d => _designFileSystem.TryGetValue(d, out var l) ? l.FullName() : d.Name.Text).OrderBy(t => t));
|
||||||
ImGui.TextUnformatted(tt.Length == 0
|
ImGui.TextUnformatted(tt.Length == 0
|
||||||
? "Matches no currently existing designs."
|
? "Matches no currently existing designs."
|
||||||
: "Matches the following designs:");
|
: "Matches the following designs:");
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ using Glamourer.Designs.Special;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -31,7 +32,7 @@ public class SetPanel(
|
||||||
RandomRestrictionDrawer _randomDrawer)
|
RandomRestrictionDrawer _randomDrawer)
|
||||||
{
|
{
|
||||||
private readonly JobGroupCombo _jobGroupCombo = new(_manager, _jobs, Glamourer.Log);
|
private readonly JobGroupCombo _jobGroupCombo = new(_manager, _jobs, Glamourer.Log);
|
||||||
private readonly HeaderDrawer.Button[] _rightButtons = [new HeaderDrawer.IncognitoButton(_config.Ephemeral)];
|
private readonly HeaderDrawer.Button[] _rightButtons = [new HeaderDrawer.IncognitoButton(_config)];
|
||||||
private string? _tempName;
|
private string? _tempName;
|
||||||
private int _dragIndex = -1;
|
private int _dragIndex = -1;
|
||||||
|
|
||||||
|
|
@ -431,10 +432,10 @@ public class SetPanel(
|
||||||
if (source)
|
if (source)
|
||||||
{
|
{
|
||||||
ImUtf8.Text($"Moving design #{index + 1:D2}...");
|
ImUtf8.Text($"Moving design #{index + 1:D2}...");
|
||||||
if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0))
|
if (ImGui.SetDragDropPayload(dragDropLabel, null, 0))
|
||||||
{
|
{
|
||||||
_dragIndex = index;
|
_dragIndex = index;
|
||||||
_selector._dragDesignIndex = index;
|
_selector.DragDesignIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Glamourer.Automation;
|
using Glamourer.Automation;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Interop;
|
using Dalamud.Bindings.ImGui;
|
||||||
using ImGuiNET;
|
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
using ImGuiClip = OtterGui.ImGuiClip;
|
using ImGuiClip = OtterGui.ImGuiClip;
|
||||||
|
|
||||||
|
|
@ -18,8 +18,7 @@ public class SetSelector : IDisposable
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly AutoDesignManager _manager;
|
private readonly AutoDesignManager _manager;
|
||||||
private readonly AutomationChanged _event;
|
private readonly AutomationChanged _event;
|
||||||
private readonly ActorManager _actors;
|
private readonly ActorObjectManager _objects;
|
||||||
private readonly ObjectManager _objects;
|
|
||||||
private readonly List<(AutoDesignSet, int)> _list = [];
|
private readonly List<(AutoDesignSet, int)> _list = [];
|
||||||
|
|
||||||
public AutoDesignSet? Selection { get; private set; }
|
public AutoDesignSet? Selection { get; private set; }
|
||||||
|
|
@ -38,14 +37,13 @@ public class SetSelector : IDisposable
|
||||||
private int _dragIndex = -1;
|
private int _dragIndex = -1;
|
||||||
private Action? _endAction;
|
private Action? _endAction;
|
||||||
|
|
||||||
internal int _dragDesignIndex = -1;
|
internal int DragDesignIndex = -1;
|
||||||
|
|
||||||
public SetSelector(AutoDesignManager manager, AutomationChanged @event, Configuration config, ActorManager actors, ObjectManager objects)
|
public SetSelector(AutoDesignManager manager, AutomationChanged @event, Configuration config, ActorObjectManager objects)
|
||||||
{
|
{
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
_event = @event;
|
_event = @event;
|
||||||
_config = config;
|
_config = config;
|
||||||
_actors = actors;
|
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_event.Subscribe(OnAutomationChange, AutomationChanged.Priority.SetSelector);
|
_event.Subscribe(OnAutomationChange, AutomationChanged.Priority.SetSelector);
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +92,7 @@ public class SetSelector : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
private LowerString _filter = LowerString.Empty;
|
private LowerString _filter = LowerString.Empty;
|
||||||
private uint _enabledFilter = 0;
|
private uint _enabledFilter;
|
||||||
private float _width;
|
private float _width;
|
||||||
private Vector2 _defaultItemSpacing;
|
private Vector2 _defaultItemSpacing;
|
||||||
private Vector2 _selectableSize;
|
private Vector2 _selectableSize;
|
||||||
|
|
@ -146,7 +144,7 @@ public class SetSelector : IDisposable
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var f = _enabledFilter;
|
var f = _enabledFilter;
|
||||||
|
|
||||||
if (ImGui.CheckboxFlags("##enabledFilter", ref f, 3))
|
if (ImGui.CheckboxFlags("##enabledFilter", ref f, 3u))
|
||||||
{
|
{
|
||||||
_enabledFilter = _enabledFilter switch
|
_enabledFilter = _enabledFilter switch
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +175,6 @@ public class SetSelector : IDisposable
|
||||||
UpdateList();
|
UpdateList();
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing);
|
||||||
_selectableSize = new Vector2(0, 2 * ImGui.GetTextLineHeight() + ImGui.GetStyle().ItemSpacing.Y);
|
_selectableSize = new Vector2(0, 2 * ImGui.GetTextLineHeight() + ImGui.GetStyle().ItemSpacing.Y);
|
||||||
_objects.Update();
|
|
||||||
ImGuiClip.ClippedDraw(_list, DrawSetSelectable, _selectableSize.Y + 2 * ImGui.GetStyle().ItemSpacing.Y);
|
ImGuiClip.ClippedDraw(_list, DrawSetSelectable, _selectableSize.Y + 2 * ImGui.GetStyle().ItemSpacing.Y);
|
||||||
_endAction?.Invoke();
|
_endAction?.Invoke();
|
||||||
_endAction = null;
|
_endAction = null;
|
||||||
|
|
@ -186,7 +183,7 @@ public class SetSelector : IDisposable
|
||||||
private void DrawSetSelectable((AutoDesignSet Set, int Index) pair)
|
private void DrawSetSelectable((AutoDesignSet Set, int Index) pair)
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId(pair.Index);
|
using var id = ImRaii.PushId(pair.Index);
|
||||||
using (var color = ImRaii.PushColor(ImGuiCol.Text, pair.Set.Enabled ? ColorId.EnabledAutoSet.Value() : ColorId.DisabledAutoSet.Value()))
|
using (ImRaii.PushColor(ImGuiCol.Text, pair.Set.Enabled ? ColorId.EnabledAutoSet.Value() : ColorId.DisabledAutoSet.Value()))
|
||||||
{
|
{
|
||||||
if (ImGui.Selectable(GetSetName(pair.Set, pair.Index), pair.Set == Selection, ImGuiSelectableFlags.None, _selectableSize))
|
if (ImGui.Selectable(GetSetName(pair.Set, pair.Index), pair.Set == Selection, ImGuiSelectableFlags.None, _selectableSize))
|
||||||
{
|
{
|
||||||
|
|
@ -285,9 +282,9 @@ public class SetSelector : IDisposable
|
||||||
|
|
||||||
private void NewSetButton(Vector2 size)
|
private void NewSetButton(Vector2 size)
|
||||||
{
|
{
|
||||||
var id = _actors.GetCurrentPlayer();
|
var id = _objects.Actors.GetCurrentPlayer();
|
||||||
if (!id.IsValid)
|
if (!id.IsValid)
|
||||||
id = _actors.CreatePlayer(ByteString.FromSpanUnsafe("New Design"u8, true, false, true), ushort.MaxValue);
|
id = _objects.Actors.CreatePlayer(ByteString.FromSpanUnsafe("New Design"u8, true, false, true), ushort.MaxValue);
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), size,
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), size,
|
||||||
$"Create a new Automatic Design Set for {id}. The associated player can be changed later.", !id.IsValid, true))
|
$"Create a new Automatic Design Set for {id}. The associated player can be changed later.", !id.IsValid, true))
|
||||||
_manager.AddDesignSet("New Automation Set", id);
|
_manager.AddDesignSet("New Automation Set", id);
|
||||||
|
|
@ -332,15 +329,15 @@ public class SetSelector : IDisposable
|
||||||
}
|
}
|
||||||
else if (ImGuiUtil.IsDropping("DesignDragDrop"))
|
else if (ImGuiUtil.IsDropping("DesignDragDrop"))
|
||||||
{
|
{
|
||||||
if (_dragDesignIndex >= 0)
|
if (DragDesignIndex >= 0)
|
||||||
{
|
{
|
||||||
var idx = _dragDesignIndex;
|
var idx = DragDesignIndex;
|
||||||
var setTo = set;
|
var setTo = set;
|
||||||
var setFrom = Selection!;
|
var setFrom = Selection!;
|
||||||
_endAction = () => _manager.MoveDesignToSet(setFrom, idx, setTo);
|
_endAction = () => _manager.MoveDesignToSet(setFrom, idx, setTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
_dragDesignIndex = -1;
|
DragDesignIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +347,7 @@ public class SetSelector : IDisposable
|
||||||
if (source)
|
if (source)
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted($"Moving design set {GetSetName(set, index)} from position {index + 1}...");
|
ImGui.TextUnformatted($"Moving design set {GetSetName(set, index)} from position {index + 1}...");
|
||||||
if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0))
|
if (ImGui.SetDragDropPayload(dragDropLabel, null, 0))
|
||||||
_dragIndex = index;
|
_dragIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.Interop.Structs;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IGameDataDrawer
|
public class ActiveStatePanel(StateManager _stateManager, ActorObjectManager _objectManager) : IGameDataDrawer
|
||||||
{
|
{
|
||||||
public string Label
|
public string Label
|
||||||
=> $"Active Actors ({_stateManager.Count})###Active Actors";
|
=> $"Active Actors ({_stateManager.Count})###Active Actors";
|
||||||
|
|
@ -22,8 +21,7 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
_objectManager.Update();
|
foreach (var (identifier, actors) in _objectManager)
|
||||||
foreach (var (identifier, actors) in _objectManager.Identifiers)
|
|
||||||
{
|
{
|
||||||
if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Trash.ToIconString()}##{actors.Label}", new Vector2(ImGui.GetFrameHeight()),
|
if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Trash.ToIconString()}##{actors.Label}", new Vector2(ImGui.GetFrameHeight()),
|
||||||
string.Empty, !_stateManager.ContainsKey(identifier), true))
|
string.Empty, !_stateManager.ContainsKey(identifier), true))
|
||||||
|
|
@ -66,13 +64,15 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM
|
||||||
static string ItemString(in DesignData data, EquipSlot slot)
|
static string ItemString(in DesignData data, EquipSlot slot)
|
||||||
{
|
{
|
||||||
var item = data.Item(slot);
|
var item = data.Item(slot);
|
||||||
return $"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})";
|
return
|
||||||
|
$"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})";
|
||||||
}
|
}
|
||||||
|
|
||||||
static string BonusItemString(in DesignData data, BonusItemFlag slot)
|
static string BonusItemString(in DesignData data, BonusItemFlag slot)
|
||||||
{
|
{
|
||||||
var item = data.BonusItem(slot);
|
var item = data.BonusItem(slot);
|
||||||
return $"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})";
|
return
|
||||||
|
$"{item.Name} ({item.Id.ToDiscriminatingString()} {item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})";
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintRow("Model ID", state.BaseData.ModelId, state.ModelData.ModelId, state.Sources[MetaIndex.ModelId]);
|
PrintRow("Model ID", state.BaseData.ModelId, state.ModelData.ModelId, state.Sources[MetaIndex.ModelId]);
|
||||||
|
|
@ -87,6 +87,9 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM
|
||||||
PrintRow("Visor Toggled", state.BaseData.IsVisorToggled(), state.ModelData.IsVisorToggled(),
|
PrintRow("Visor Toggled", state.BaseData.IsVisorToggled(), state.ModelData.IsVisorToggled(),
|
||||||
state.Sources[MetaIndex.VisorState]);
|
state.Sources[MetaIndex.VisorState]);
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
|
PrintRow("Viera Ears Visible", state.BaseData.AreEarsVisible(), state.ModelData.AreEarsVisible(),
|
||||||
|
state.Sources[MetaIndex.EarState]);
|
||||||
|
ImGui.TableNextRow();
|
||||||
PrintRow("Weapon Visible", state.BaseData.IsWeaponVisible(), state.ModelData.IsWeaponVisible(),
|
PrintRow("Weapon Visible", state.BaseData.IsWeaponVisible(), state.ModelData.IsWeaponVisible(),
|
||||||
state.Sources[MetaIndex.WeaponState]);
|
state.Sources[MetaIndex.WeaponState]);
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
||||||
using Glamourer.Interop;
|
using Dalamud.Bindings.ImGui;
|
||||||
using ImGuiNET;
|
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public unsafe class AdvancedCustomizationDrawer(ObjectManager objects) : IGameDataDrawer
|
public unsafe class AdvancedCustomizationDrawer(ActorObjectManager objects) : IGameDataDrawer
|
||||||
{
|
{
|
||||||
public string Label
|
public string Label
|
||||||
=> "Advanced Customizations";
|
=> "Advanced Customizations";
|
||||||
|
|
@ -31,8 +31,8 @@ public unsafe class AdvancedCustomizationDrawer(ObjectManager objects) : IGameDa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawCBuffer("Customize"u8, model.AsHuman->CustomizeParameterCBuffer, 0);
|
DrawCBuffer("Customize"u8, model.AsHuman->CustomizeParameterCBuffer, 0);
|
||||||
DrawCBuffer("Decal"u8, model.AsHuman->DecalColorCBuffer, 1);
|
DrawCBuffer("Decal"u8, model.AsHuman->DecalColorCBuffer, 1);
|
||||||
DrawCBuffer("Unk1"u8, *(ConstantBuffer**)((byte*)model.AsHuman + 0xBA0), 2);
|
DrawCBuffer("Unk1"u8, *(ConstantBuffer**)((byte*)model.AsHuman + 0xBA0), 2);
|
||||||
DrawCBuffer("Unk2"u8, *(ConstantBuffer**)((byte*)model.AsHuman + 0xBA8), 3);
|
DrawCBuffer("Unk2"u8, *(ConstantBuffer**)((byte*)model.AsHuman + 0xBA8), 3);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Glamourer.Automation;
|
using Glamourer.Automation;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using Penumbra.GameData.Files;
|
using Penumbra.GameData.Files;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using Glamourer.Gui.Tabs.DebugTab.IpcTester;
|
using Glamourer.Gui.Tabs.DebugTab.IpcTester;
|
||||||
using ImGuiNET;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
@ -36,6 +35,7 @@ public class DebugTabHeader(string label, params IGameDataDrawer[] subTrees)
|
||||||
provider.GetRequiredService<ModelEvaluationPanel>(),
|
provider.GetRequiredService<ModelEvaluationPanel>(),
|
||||||
provider.GetRequiredService<ObjectManagerPanel>(),
|
provider.GetRequiredService<ObjectManagerPanel>(),
|
||||||
provider.GetRequiredService<PenumbraPanel>(),
|
provider.GetRequiredService<PenumbraPanel>(),
|
||||||
|
provider.GetRequiredService<DynamisPanel>(),
|
||||||
provider.GetRequiredService<IpcTesterPanel>(),
|
provider.GetRequiredService<IpcTesterPanel>(),
|
||||||
provider.GetRequiredService<DatFilePanel>(),
|
provider.GetRequiredService<DatFilePanel>(),
|
||||||
provider.GetRequiredService<GlamourPlatePanel>(),
|
provider.GetRequiredService<GlamourPlatePanel>(),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Utility;
|
using Glamourer.Utility;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
|
using OtterGui.Filesystem;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
|
|
@ -18,6 +21,7 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
|
DrawButtons();
|
||||||
foreach (var (design, idx) in _designManager.Designs.WithIndex())
|
foreach (var (design, idx) in _designManager.Designs.WithIndex())
|
||||||
{
|
{
|
||||||
using var t = ImRaii.TreeNode($"{design.Name}##{idx}");
|
using var t = ImRaii.TreeNode($"{design.Name}##{idx}");
|
||||||
|
|
@ -25,7 +29,8 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DrawDesign(design, _designFileSystem);
|
DrawDesign(design, _designFileSystem);
|
||||||
var base64 = DesignBase64Migration.CreateOldBase64(design.DesignData, design.Application.Equip, design.Application.Customize, design.Application.Meta,
|
var base64 = DesignBase64Migration.CreateOldBase64(design.DesignData, design.Application.Equip, design.Application.Customize,
|
||||||
|
design.Application.Meta,
|
||||||
design.WriteProtected());
|
design.WriteProtected());
|
||||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
|
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
|
||||||
ImGuiUtil.TextWrapped(base64);
|
ImGuiUtil.TextWrapped(base64);
|
||||||
|
|
@ -34,6 +39,26 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawButtons()
|
||||||
|
{
|
||||||
|
if (ImUtf8.Button("Generate 500 Test Designs"u8))
|
||||||
|
for (var i = 0; i < 500; ++i)
|
||||||
|
{
|
||||||
|
var design = _designManager.CreateEmpty($"Test Designs/Test Design {i}", true);
|
||||||
|
_designManager.AddTag(design, "_DebugTest");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImUtf8.SameLineInner();
|
||||||
|
if (ImUtf8.Button("Remove All Test Designs"u8))
|
||||||
|
{
|
||||||
|
var designs = _designManager.Designs.Where(d => d.Tags.Contains("_DebugTest")).ToArray();
|
||||||
|
foreach (var design in designs)
|
||||||
|
_designManager.Delete(design);
|
||||||
|
if (_designFileSystem.Find("Test Designs", out var path) && path is DesignFileSystem.Folder { TotalChildren: 0 })
|
||||||
|
_designFileSystem.Delete(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void DrawDesign(DesignBase design, DesignFileSystem? fileSystem)
|
public static void DrawDesign(DesignBase design, DesignFileSystem? fileSystem)
|
||||||
{
|
{
|
||||||
using var table = ImRaii.Table("##equip", 8, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit);
|
using var table = ImRaii.Table("##equip", 8, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit);
|
||||||
|
|
@ -52,7 +77,7 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGuiUtil.DrawTableColumn("Design File System Path");
|
ImGuiUtil.DrawTableColumn("Design File System Path");
|
||||||
if (fileSystem != null)
|
if (fileSystem != null)
|
||||||
ImGuiUtil.DrawTableColumn(fileSystem.FindLeaf(d, out var leaf) ? leaf.FullName() : "No Path Known");
|
ImGuiUtil.DrawTableColumn(fileSystem.TryGetValue(d, out var leaf) ? leaf.FullName() : "No Path Known");
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Creation");
|
ImGuiUtil.DrawTableColumn("Creation");
|
||||||
|
|
@ -89,6 +114,7 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
||||||
ImGuiUtil.DrawTableColumn(index.ToName());
|
ImGuiUtil.DrawTableColumn(index.ToName());
|
||||||
ImGuiUtil.DrawTableColumn(design.DesignData.GetMeta(index).ToString());
|
ImGuiUtil.DrawTableColumn(design.DesignData.GetMeta(index).ToString());
|
||||||
ImGuiUtil.DrawTableColumn(design.DoApplyMeta(index) ? "Apply" : "Keep");
|
ImGuiUtil.DrawTableColumn(design.DoApplyMeta(index) ? "Apply" : "Keep");
|
||||||
|
ImGui.TableNextRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Model ID");
|
ImGuiUtil.DrawTableColumn("Model ID");
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.DataContainers;
|
using Penumbra.GameData.DataContainers;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
16
Glamourer/Gui/Tabs/DebugTab/DynamisPanel.cs
Normal file
16
Glamourer/Gui/Tabs/DebugTab/DynamisPanel.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
using OtterGui.Services;
|
||||||
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
|
public class DynamisPanel(DynamisIpc dynamis) : IGameDataDrawer
|
||||||
|
{
|
||||||
|
public string Label
|
||||||
|
=> "Dynamis Interop";
|
||||||
|
|
||||||
|
public void Draw()
|
||||||
|
=> dynamis.DrawDebugInfo();
|
||||||
|
|
||||||
|
public bool Disabled
|
||||||
|
=> false;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,26 @@ using Dalamud.Plugin.Services;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Extensions;
|
||||||
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData;
|
using Penumbra.GameData;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public unsafe class GlamourPlatePanel : IGameDataDrawer
|
public unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
{
|
{
|
||||||
private readonly DesignManager _design;
|
private readonly DesignManager _design;
|
||||||
private readonly ItemManager _items;
|
private readonly ItemManager _items;
|
||||||
private readonly StateManager _state;
|
private readonly StateManager _state;
|
||||||
private readonly ObjectManager _objects;
|
private readonly ActorObjectManager _objects;
|
||||||
|
|
||||||
public string Label
|
public string Label
|
||||||
=> "Glamour Plates";
|
=> "Glamour Plates";
|
||||||
|
|
@ -28,7 +30,8 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
public bool Disabled
|
public bool Disabled
|
||||||
=> false;
|
=> false;
|
||||||
|
|
||||||
public GlamourPlatePanel(IGameInteropProvider interop, ItemManager items, DesignManager design, StateManager state, ObjectManager objects)
|
public GlamourPlatePanel(IGameInteropProvider interop, ItemManager items, DesignManager design, StateManager state,
|
||||||
|
ActorObjectManager objects)
|
||||||
{
|
{
|
||||||
_items = items;
|
_items = items;
|
||||||
_design = design;
|
_design = design;
|
||||||
|
|
@ -42,24 +45,24 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
var manager = MirageManager.Instance();
|
var manager = MirageManager.Instance();
|
||||||
using (ImRaii.Group())
|
using (ImRaii.Group())
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted("Address:");
|
ImUtf8.Text("Address:"u8);
|
||||||
ImGui.TextUnformatted("Number of Glamour Plates:");
|
ImUtf8.Text("Number of Glamour Plates:"u8);
|
||||||
ImGui.TextUnformatted("Glamour Plates Requested:");
|
ImUtf8.Text("Glamour Plates Requested:"u8);
|
||||||
ImGui.TextUnformatted("Glamour Plates Loaded:");
|
ImUtf8.Text("Glamour Plates Loaded:"u8);
|
||||||
ImGui.TextUnformatted("Is Applying Glamour Plates:");
|
ImUtf8.Text("Is Applying Glamour Plates:"u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
using (ImRaii.Group())
|
using (ImRaii.Group())
|
||||||
{
|
{
|
||||||
ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)manager:X}");
|
ImUtf8.CopyOnClickSelectable($"0x{(ulong)manager:X}");
|
||||||
ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlates.Length.ToString());
|
ImUtf8.Text(manager == null ? "-" : manager->GlamourPlates.Length.ToString());
|
||||||
ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlatesRequested.ToString());
|
ImUtf8.Text(manager == null ? "-" : manager->GlamourPlatesRequested.ToString());
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGui.SmallButton("Request Update"))
|
if (ImUtf8.SmallButton("Request Update"u8))
|
||||||
RequestGlamour();
|
RequestGlamour();
|
||||||
ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlatesLoaded.ToString());
|
ImUtf8.Text(manager == null ? "-" : manager->GlamourPlatesLoaded.ToString());
|
||||||
ImGui.TextUnformatted(manager == null ? "-" : manager->IsApplyingGlamourPlate.ToString());
|
ImUtf8.Text(manager == null ? "-" : manager->IsApplyingGlamourPlate.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manager == null)
|
if (manager == null)
|
||||||
|
|
@ -71,12 +74,12 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
|
|
||||||
for (var i = 0; i < manager->GlamourPlates.Length; ++i)
|
for (var i = 0; i < manager->GlamourPlates.Length; ++i)
|
||||||
{
|
{
|
||||||
using var tree = ImRaii.TreeNode($"Plate #{i + 1:D2}");
|
using var tree = ImUtf8.TreeNode($"Plate #{i + 1:D2}");
|
||||||
if (!tree)
|
if (!tree)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ref var plate = ref manager->GlamourPlates[i];
|
ref var plate = ref manager->GlamourPlates[i];
|
||||||
if (ImGuiUtil.DrawDisabledButton("Apply to Player", Vector2.Zero, string.Empty, !enabled))
|
if (ImUtf8.ButtonEx("Apply to Player"u8, ""u8, Vector2.Zero, !enabled))
|
||||||
{
|
{
|
||||||
var design = CreateDesign(plate);
|
var design = CreateDesign(plate);
|
||||||
_state.ApplyDesign(state!, design, ApplySettings.Manual with { IsFinal = true });
|
_state.ApplyDesign(state!, design, ApplySettings.Manual with { IsFinal = true });
|
||||||
|
|
@ -85,14 +88,14 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
||||||
using (ImRaii.Group())
|
using (ImRaii.Group())
|
||||||
{
|
{
|
||||||
foreach (var slot in EquipSlotExtensions.FullSlots)
|
foreach (var slot in EquipSlotExtensions.FullSlots)
|
||||||
ImGui.TextUnformatted(slot.ToName());
|
ImUtf8.Text(slot.ToName());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
using (ImRaii.Group())
|
using (ImRaii.Group())
|
||||||
{
|
{
|
||||||
foreach (var (_, index) in EquipSlotExtensions.FullSlots.WithIndex())
|
foreach (var (_, index) in EquipSlotExtensions.FullSlots.WithIndex())
|
||||||
ImGui.TextUnformatted($"{plate.ItemIds[index]:D6}, {StainIds.FromGlamourPlate(plate, index)}");
|
ImUtf8.Text($"{plate.ItemIds[index]:D6}, {StainIds.FromGlamourPlate(plate, index)}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Api.IpcSubscribers;
|
using Glamourer.Api.IpcSubscribers;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
using OtterGui.Text;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab.IpcTester;
|
namespace Glamourer.Gui.Tabs.DebugTab.IpcTester;
|
||||||
|
|
||||||
|
|
@ -15,6 +16,7 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi
|
||||||
private Dictionary<Guid, string> _designs = [];
|
private Dictionary<Guid, string> _designs = [];
|
||||||
private int _gameObjectIndex;
|
private int _gameObjectIndex;
|
||||||
private string _gameObjectName = string.Empty;
|
private string _gameObjectName = string.Empty;
|
||||||
|
private string _designName = string.Empty;
|
||||||
private uint _key;
|
private uint _key;
|
||||||
private ApplyFlag _flags = ApplyFlagEx.DesignDefault;
|
private ApplyFlag _flags = ApplyFlagEx.DesignDefault;
|
||||||
private Guid? _design;
|
private Guid? _design;
|
||||||
|
|
@ -30,6 +32,7 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi
|
||||||
IpcTesterHelpers.IndexInput(ref _gameObjectIndex);
|
IpcTesterHelpers.IndexInput(ref _gameObjectIndex);
|
||||||
IpcTesterHelpers.KeyInput(ref _key);
|
IpcTesterHelpers.KeyInput(ref _key);
|
||||||
IpcTesterHelpers.NameInput(ref _gameObjectName);
|
IpcTesterHelpers.NameInput(ref _gameObjectName);
|
||||||
|
ImUtf8.InputText("##designName"u8, ref _designName, "Design Name..."u8);
|
||||||
ImGuiUtil.GuidInput("##identifier", "Design Identifier...", string.Empty, ref _design, ref _designText,
|
ImGuiUtil.GuidInput("##identifier", "Design Identifier...", string.Empty, ref _design, ref _designText,
|
||||||
ImGui.GetContentRegionAvail().X);
|
ImGui.GetContentRegionAvail().X);
|
||||||
IpcTesterHelpers.DrawFlagInput(ref _flags);
|
IpcTesterHelpers.DrawFlagInput(ref _flags);
|
||||||
|
|
@ -54,6 +57,48 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi
|
||||||
IpcTesterHelpers.DrawIntro(ApplyDesignName.Label);
|
IpcTesterHelpers.DrawIntro(ApplyDesignName.Label);
|
||||||
if (ImGuiUtil.DrawDisabledButton("Apply##Name", Vector2.Zero, string.Empty, !_design.HasValue))
|
if (ImGuiUtil.DrawDisabledButton("Apply##Name", Vector2.Zero, string.Empty, !_design.HasValue))
|
||||||
_lastError = new ApplyDesignName(pluginInterface).Invoke(_design!.Value, _gameObjectName, _key, _flags);
|
_lastError = new ApplyDesignName(pluginInterface).Invoke(_design!.Value, _gameObjectName, _key, _flags);
|
||||||
|
|
||||||
|
IpcTesterHelpers.DrawIntro(GetExtendedDesignData.Label);
|
||||||
|
if (_design.HasValue)
|
||||||
|
{
|
||||||
|
var (display, path, color, draw) = new GetExtendedDesignData(pluginInterface).Invoke(_design.Value);
|
||||||
|
if (path.Length > 0)
|
||||||
|
ImUtf8.Text($"{display} ({path}){(draw ? " in QDB"u8 : ""u8)}", color);
|
||||||
|
else
|
||||||
|
ImUtf8.Text("No Data"u8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImUtf8.Text("No Data"u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcTesterHelpers.DrawIntro(GetDesignBase64.Label);
|
||||||
|
if (ImUtf8.Button("To Clipboard##Base64"u8) && _design.HasValue)
|
||||||
|
{
|
||||||
|
var data = new GetDesignBase64(pluginInterface).Invoke(_design.Value);
|
||||||
|
ImUtf8.SetClipboardText(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcTesterHelpers.DrawIntro(AddDesign.Label);
|
||||||
|
if (ImUtf8.Button("Add from Clipboard"u8))
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = ImUtf8.GetClipboardText();
|
||||||
|
_lastError = new AddDesign(pluginInterface).Invoke(data, _designName, out var newDesign);
|
||||||
|
if (_lastError is GlamourerApiEc.Success)
|
||||||
|
{
|
||||||
|
_design = newDesign;
|
||||||
|
_designText = newDesign.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_lastError = GlamourerApiEc.UnknownError;
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcTesterHelpers.DrawIntro(DeleteDesign.Label);
|
||||||
|
if (ImUtf8.Button("Delete##Design"u8) && _design.HasValue)
|
||||||
|
_lastError = new DeleteDesign(pluginInterface).Invoke(_design.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawDesignsPopup()
|
private void DrawDesignsPopup()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using static Penumbra.GameData.Files.ShpkFile;
|
using static Penumbra.GameData.Files.ShpkFile;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Api.IpcSubscribers;
|
using Glamourer.Api.IpcSubscribers;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab.IpcTester;
|
namespace Glamourer.Gui.Tabs.DebugTab.IpcTester;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Glamourer.Api.Enums;
|
using Glamourer.Api.Enums;
|
||||||
using Glamourer.Api.IpcSubscribers;
|
using Glamourer.Api.IpcSubscribers;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using Glamourer.Api.Enums;
|
||||||
using Glamourer.Api.Helpers;
|
using Glamourer.Api.Helpers;
|
||||||
using Glamourer.Api.IpcSubscribers;
|
using Glamourer.Api.IpcSubscribers;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Interop.Structs;
|
using Glamourer.Interop.Structs;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -11,13 +11,13 @@ using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using ObjectManager = Glamourer.Interop.ObjectManager;
|
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public unsafe class ModelEvaluationPanel(
|
public unsafe class ModelEvaluationPanel(
|
||||||
ObjectManager _objectManager,
|
ActorObjectManager _objectManager,
|
||||||
VisorService _visorService,
|
VisorService _visorService,
|
||||||
|
VieraEarService _vieraEarService,
|
||||||
UpdateSlotService _updateSlotService,
|
UpdateSlotService _updateSlotService,
|
||||||
ChangeCustomizeService _changeCustomizeService,
|
ChangeCustomizeService _changeCustomizeService,
|
||||||
CrestService _crestService,
|
CrestService _crestService,
|
||||||
|
|
@ -34,7 +34,7 @@ public unsafe class ModelEvaluationPanel(
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0);
|
ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0);
|
||||||
var actor = _objectManager[_gameObjectIndex];
|
var actor = _objectManager.Objects[_gameObjectIndex];
|
||||||
var model = actor.Model;
|
var model = actor.Model;
|
||||||
using var table = ImRaii.Table("##evaluationTable", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
|
using var table = ImRaii.Table("##evaluationTable", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -46,9 +46,10 @@ public unsafe class ModelEvaluationPanel(
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Address");
|
ImGuiUtil.DrawTableColumn("Address");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGuiUtil.CopyOnClickSelectable(actor.ToString());
|
|
||||||
|
Glamourer.Dynamis.DrawPointer(actor);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGuiUtil.CopyOnClickSelectable(model.ToString());
|
Glamourer.Dynamis.DrawPointer(model);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (actor.IsCharacter)
|
if (actor.IsCharacter)
|
||||||
{
|
{
|
||||||
|
|
@ -84,6 +85,7 @@ public unsafe class ModelEvaluationPanel(
|
||||||
ImGuiUtil.CopyOnClickSelectable(offhand.ToString());
|
ImGuiUtil.CopyOnClickSelectable(offhand.ToString());
|
||||||
|
|
||||||
DrawVisor(actor, model);
|
DrawVisor(actor, model);
|
||||||
|
DrawVieraEars(actor, model);
|
||||||
DrawHatState(actor, model);
|
DrawHatState(actor, model);
|
||||||
DrawWeaponState(actor, model);
|
DrawWeaponState(actor, model);
|
||||||
DrawWetness(actor, model);
|
DrawWetness(actor, model);
|
||||||
|
|
@ -135,6 +137,26 @@ public unsafe class ModelEvaluationPanel(
|
||||||
_visorService.SetVisorState(model, !VisorService.GetVisorState(model));
|
_visorService.SetVisorState(model, !VisorService.GetVisorState(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawVieraEars(Actor actor, Model model)
|
||||||
|
{
|
||||||
|
using var id = ImRaii.PushId("Viera Ears");
|
||||||
|
ImGuiUtil.DrawTableColumn("Viera Ears");
|
||||||
|
ImGuiUtil.DrawTableColumn(actor.IsCharacter ? actor.ShowVieraEars.ToString() : "No Character");
|
||||||
|
ImGuiUtil.DrawTableColumn(model.IsHuman ? model.VieraEarsVisible.ToString() : "No Human");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (!model.IsHuman)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ImGui.SmallButton("Set True"))
|
||||||
|
_vieraEarService.SetVieraEarState(model, true);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.SmallButton("Set False"))
|
||||||
|
_vieraEarService.SetVieraEarState(model, false);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.SmallButton("Toggle"))
|
||||||
|
_vieraEarService.SetVieraEarState(model, !model.VieraEarsVisible);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawHatState(Actor actor, Model model)
|
private void DrawHatState(Actor actor, Model model)
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId("HatState");
|
using var id = ImRaii.PushId("HatState");
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,18 @@ using Dalamud.Interface.Utility;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
using ImGuiClip = OtterGui.ImGuiClip;
|
using ImGuiClip = OtterGui.ImGuiClip;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectManager _objectManager, DesignConverter _designConverter)
|
public class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateManager, ActorObjectManager objectManager, DesignConverter designConverter)
|
||||||
: IGameDataDrawer
|
: IGameDataDrawer
|
||||||
{
|
{
|
||||||
public string Label
|
public string Label
|
||||||
|
|
@ -28,9 +28,9 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
ImGui.Checkbox("Compare Customize (or Gear)", ref _customizeOrGear);
|
ImUtf8.Checkbox("Compare Customize (or Gear)"u8, ref _customizeOrGear);
|
||||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
||||||
var resetScroll = ImGui.InputTextWithHint("##npcFilter", "Filter...", ref _npcFilter, 64);
|
var resetScroll = ImUtf8.InputText("##npcFilter"u8, ref _npcFilter, "Filter..."u8);
|
||||||
|
|
||||||
using var table = ImRaii.Table("npcs", 7, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
|
using var table = ImRaii.Table("npcs", 7, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
|
||||||
new Vector2(-1, 400 * ImGuiHelpers.GlobalScale));
|
new Vector2(-1, 400 * ImGuiHelpers.GlobalScale));
|
||||||
|
|
@ -40,19 +40,19 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM
|
||||||
if (resetScroll)
|
if (resetScroll)
|
||||||
ImGui.SetScrollY(0);
|
ImGui.SetScrollY(0);
|
||||||
|
|
||||||
ImGui.TableSetupColumn("Button", ImGuiTableColumnFlags.WidthFixed);
|
ImUtf8.TableSetupColumn("Button"u8, ImGuiTableColumnFlags.WidthFixed);
|
||||||
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, ImGuiHelpers.GlobalScale * 300);
|
ImUtf8.TableSetupColumn("Name"u8, ImGuiTableColumnFlags.WidthFixed, ImGuiHelpers.GlobalScale * 300);
|
||||||
ImGui.TableSetupColumn("Kind", ImGuiTableColumnFlags.WidthFixed);
|
ImUtf8.TableSetupColumn("Kind"u8, ImGuiTableColumnFlags.WidthFixed);
|
||||||
ImGui.TableSetupColumn("Id", ImGuiTableColumnFlags.WidthFixed);
|
ImUtf8.TableSetupColumn("Id"u8, ImGuiTableColumnFlags.WidthFixed);
|
||||||
ImGui.TableSetupColumn("Model", ImGuiTableColumnFlags.WidthFixed);
|
ImUtf8.TableSetupColumn("Model"u8, ImGuiTableColumnFlags.WidthFixed);
|
||||||
ImGui.TableSetupColumn("Visor", ImGuiTableColumnFlags.WidthFixed);
|
ImUtf8.TableSetupColumn("Visor"u8, ImGuiTableColumnFlags.WidthFixed);
|
||||||
ImGui.TableSetupColumn("Compare", ImGuiTableColumnFlags.WidthStretch);
|
ImUtf8.TableSetupColumn("Compare"u8, ImGuiTableColumnFlags.WidthStretch);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetFrameHeightWithSpacing());
|
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetFrameHeightWithSpacing());
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
var remainder = ImGuiClip.FilteredClippedDraw(_npcCombo.Items, skips,
|
var remainder = ImGuiClip.FilteredClippedDraw(npcCombo.Items, skips,
|
||||||
d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData);
|
d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetFrameHeightWithSpacing());
|
ImGuiClip.DrawEndDummy(remainder, ImGui.GetFrameHeightWithSpacing());
|
||||||
|
|
@ -61,43 +61,31 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM
|
||||||
void DrawData(NpcData data)
|
void DrawData(NpcData data)
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId(idx++);
|
using var id = ImRaii.PushId(idx++);
|
||||||
var disabled = !_state.GetOrCreate(_objectManager.Player, out var state);
|
var disabled = !stateManager.GetOrCreate(objectManager.Player, out var state);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGuiUtil.DrawDisabledButton("Apply", Vector2.Zero, string.Empty, disabled))
|
if (ImUtf8.ButtonEx("Apply"u8, ""u8, Vector2.Zero, disabled))
|
||||||
{
|
{
|
||||||
foreach (var (slot, item, stain) in _designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand, true))
|
foreach (var (slot, item, stain) in designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand, true))
|
||||||
_state.ChangeEquip(state!, slot, item, stain, ApplySettings.Manual);
|
stateManager.ChangeEquip(state!, slot, item, stain, ApplySettings.Manual);
|
||||||
_state.ChangeMetaState(state!, MetaIndex.VisorState, data.VisorToggled, ApplySettings.Manual);
|
stateManager.ChangeMetaState(state!, MetaIndex.VisorState, data.VisorToggled, ApplySettings.Manual);
|
||||||
_state.ChangeEntireCustomize(state!, data.Customize, CustomizeFlagExtensions.All, ApplySettings.Manual);
|
stateManager.ChangeEntireCustomize(state!, data.Customize, CustomizeFlagExtensions.All, ApplySettings.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawFrameColumn(data.Name);
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted(data.Name);
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawFrameColumn(data.Kind is ObjectKind.BattleNpc ? "B" : "E");
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted(data.Kind is ObjectKind.BattleNpc ? "B" : "E");
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawFrameColumn(data.Id.Id.ToString());
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted(data.Id.Id.ToString());
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawFrameColumn(data.ModelId.ToString());
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted(data.ModelId.ToString());
|
|
||||||
|
|
||||||
using (_ = ImRaii.PushFont(UiBuilder.IconFont))
|
using (_ = ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawFrameColumn(data.VisorToggled ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString());
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted(data.VisorToggled ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using var mono = ImRaii.PushFont(UiBuilder.MonoFont);
|
using var mono = ImRaii.PushFont(UiBuilder.MonoFont);
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawFrameColumn(_customizeOrGear ? data.Customize.ToString() : data.WriteGear());
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted(_customizeOrGear ? data.Customize.ToString() : data.WriteGear());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
using Glamourer.Interop;
|
using Dalamud.Bindings.ImGui;
|
||||||
using ImGuiNET;
|
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _actors) : IGameDataDrawer
|
public class ObjectManagerPanel(ActorObjectManager _objectManager, ActorManager _actors) : IGameDataDrawer
|
||||||
{
|
{
|
||||||
public string Label
|
public string Label
|
||||||
=> "Object Manager";
|
=> "Object Manager";
|
||||||
|
|
@ -19,44 +19,45 @@ public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _acto
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
_objectManager.Update();
|
_objectManager.Objects.DrawDebug();
|
||||||
using (var table = ImRaii.Table("##data", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit))
|
|
||||||
|
using (var table = ImUtf8.Table("##data"u8, 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit))
|
||||||
{
|
{
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Last Update");
|
ImUtf8.DrawTableColumn("World"u8);
|
||||||
ImGuiUtil.DrawTableColumn(_objectManager.LastUpdate.ToString(CultureInfo.InvariantCulture));
|
ImUtf8.DrawTableColumn(_actors.Finished ? _actors.Data.ToWorldName(_objectManager.World) : "Service Missing");
|
||||||
|
ImUtf8.DrawTableColumn(_objectManager.World.ToString());
|
||||||
|
|
||||||
|
ImUtf8.DrawTableColumn("Player Character"u8);
|
||||||
|
ImUtf8.DrawTableColumn($"{_objectManager.Player.Utf8Name} ({_objectManager.Player.Index})");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImUtf8.CopyOnClickSelectable(_objectManager.Player.ToString());
|
||||||
|
|
||||||
|
ImUtf8.DrawTableColumn("In GPose"u8);
|
||||||
|
ImUtf8.DrawTableColumn(_objectManager.IsInGPose.ToString());
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("World");
|
ImUtf8.DrawTableColumn("In Lobby"u8);
|
||||||
ImGuiUtil.DrawTableColumn(_actors.Finished ? _actors.Data.ToWorldName(_objectManager.World) : "Service Missing");
|
ImUtf8.DrawTableColumn(_objectManager.IsInLobby.ToString());
|
||||||
ImGuiUtil.DrawTableColumn(_objectManager.World.ToString());
|
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Player Character");
|
|
||||||
ImGuiUtil.DrawTableColumn($"{_objectManager.Player.Utf8Name} ({_objectManager.Player.Index})");
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGuiUtil.CopyOnClickSelectable(_objectManager.Player.ToString());
|
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("In GPose");
|
|
||||||
ImGuiUtil.DrawTableColumn(_objectManager.IsInGPose.ToString());
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
if (_objectManager.IsInGPose)
|
if (_objectManager.IsInGPose)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn("GPose Player");
|
ImUtf8.DrawTableColumn("GPose Player"u8);
|
||||||
ImGuiUtil.DrawTableColumn($"{_objectManager.GPosePlayer.Utf8Name} ({_objectManager.GPosePlayer.Index})");
|
ImUtf8.DrawTableColumn($"{_objectManager.GPosePlayer.Utf8Name} ({_objectManager.GPosePlayer.Index})");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGuiUtil.CopyOnClickSelectable(_objectManager.GPosePlayer.ToString());
|
ImUtf8.CopyOnClickSelectable(_objectManager.GPosePlayer.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Number of Players");
|
ImUtf8.DrawTableColumn("Number of Players"u8);
|
||||||
ImGuiUtil.DrawTableColumn(_objectManager.Count.ToString());
|
ImUtf8.DrawTableColumn(_objectManager.Count.ToString());
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
var filterChanged = ImGui.InputTextWithHint("##Filter", "Filter...", ref _objectFilter, 64);
|
var filterChanged = ImUtf8.InputText("##Filter"u8, ref _objectFilter, "Filter..."u8);
|
||||||
using var table2 = ImRaii.Table("##data2", 3,
|
using var table2 = ImUtf8.Table("##data2"u8, 3,
|
||||||
ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.ScrollY,
|
ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.ScrollY,
|
||||||
new Vector2(-1, 20 * ImGui.GetTextLineHeightWithSpacing()));
|
new Vector2(-1, 20 * ImGui.GetTextLineHeightWithSpacing()));
|
||||||
if (!table2)
|
if (!table2)
|
||||||
|
|
@ -69,13 +70,13 @@ public class ObjectManagerPanel(ObjectManager _objectManager, ActorManager _acto
|
||||||
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeightWithSpacing());
|
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeightWithSpacing());
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
var remainder = ImGuiClip.FilteredClippedDraw(_objectManager.Identifiers, skips,
|
var remainder = ImGuiClip.FilteredClippedDraw(_objectManager, skips,
|
||||||
p => p.Value.Label.Contains(_objectFilter, StringComparison.OrdinalIgnoreCase), p
|
p => p.Value.Label.Contains(_objectFilter, StringComparison.OrdinalIgnoreCase), p
|
||||||
=>
|
=>
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn(p.Key.ToString());
|
ImUtf8.DrawTableColumn(p.Key.ToString());
|
||||||
ImGuiUtil.DrawTableColumn(p.Value.Label);
|
ImUtf8.DrawTableColumn(p.Value.Label);
|
||||||
ImGuiUtil.DrawTableColumn(string.Join(", ", p.Value.Objects.OrderBy(a => a.Index).Select(a => a.Index.ToString())));
|
ImUtf8.DrawTableColumn(string.Join(", ", p.Value.Objects.OrderBy(a => a.Index).Select(a => a.Index.ToString())));
|
||||||
});
|
});
|
||||||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeightWithSpacing());
|
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeightWithSpacing());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Interop.Penumbra;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
@ -49,7 +49,7 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var address = _drawObject.Address;
|
var address = _drawObject.Address;
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||||
if (ImGui.InputScalar("##drawObjectPtr", ImGuiDataType.U64, (nint)(&address), nint.Zero, nint.Zero, "%llx",
|
if (ImGui.InputScalar("##drawObjectPtr", ImGuiDataType.U64, ref address, nint.Zero, nint.Zero, "%llx",
|
||||||
ImGuiInputTextFlags.CharsHexadecimal))
|
ImGuiInputTextFlags.CharsHexadecimal))
|
||||||
_drawObject = address;
|
_drawObject = address;
|
||||||
ImGuiUtil.DrawTableColumn(_penumbra.Available
|
ImGuiUtil.DrawTableColumn(_penumbra.Available
|
||||||
|
|
@ -61,7 +61,7 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||||
ImGui.InputInt("##CutsceneIndex", ref _gameObjectIndex, 0, 0);
|
ImGui.InputInt("##CutsceneIndex", ref _gameObjectIndex, 0, 0);
|
||||||
ImGuiUtil.DrawTableColumn(_penumbra.Available
|
ImGuiUtil.DrawTableColumn(_penumbra.Available
|
||||||
? _penumbra.CutsceneParent((ushort) _gameObjectIndex).ToString()
|
? _penumbra.CutsceneParent((ushort)_gameObjectIndex).ToString()
|
||||||
: "Penumbra Unavailable");
|
: "Penumbra Unavailable");
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Redraw Object");
|
ImGuiUtil.DrawTableColumn("Redraw Object");
|
||||||
|
|
@ -76,7 +76,9 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Last Tooltip Date");
|
ImGuiUtil.DrawTableColumn("Last Tooltip Date");
|
||||||
ImGuiUtil.DrawTableColumn(_penumbraTooltip.LastTooltip > DateTime.MinValue ? $"{_penumbraTooltip.LastTooltip.ToLongTimeString()} ({_penumbraTooltip.LastType} {_penumbraTooltip.LastId})" : "Never");
|
ImGuiUtil.DrawTableColumn(_penumbraTooltip.LastTooltip > DateTime.MinValue
|
||||||
|
? $"{_penumbraTooltip.LastTooltip.ToLongTimeString()} ({_penumbraTooltip.LastType} {_penumbraTooltip.LastId})"
|
||||||
|
: "Never");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn("Last Click Date");
|
ImGuiUtil.DrawTableColumn("Last Click Date");
|
||||||
|
|
@ -87,7 +89,13 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
foreach (var (slot, item) in _penumbraTooltip.LastItems)
|
foreach (var (slot, item) in _penumbraTooltip.LastItems)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn($"{slot.ToName()} Revert-Item");
|
switch (slot)
|
||||||
|
{
|
||||||
|
case EquipSlot e: ImGuiUtil.DrawTableColumn($"{e.ToName()} Revert-Item"); break;
|
||||||
|
case BonusItemFlag f: ImGuiUtil.DrawTableColumn($"{f.ToName()} Revert-Item"); break;
|
||||||
|
default: ImGuiUtil.DrawTableColumn("Unk Revert-Item"); break;
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(item.Valid ? item.Name : "None");
|
ImGuiUtil.DrawTableColumn(item.Valid ? item.Name : "None");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ using Glamourer.Interop.Structs;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Gui.Debug;
|
using Penumbra.GameData.Gui.Debug;
|
||||||
|
using Penumbra.GameData.Interop;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DebugTab;
|
namespace Glamourer.Gui.Tabs.DebugTab;
|
||||||
|
|
||||||
public class RetainedStatePanel(StateManager _stateManager, ObjectManager _objectManager) : IGameDataDrawer
|
public class RetainedStatePanel(StateManager _stateManager, ActorObjectManager _objectManager) : IGameDataDrawer
|
||||||
{
|
{
|
||||||
public string Label
|
public string Label
|
||||||
=> "Retained States (Inactive Actors)";
|
=> "Retained States (Inactive Actors)";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.Unlocks;
|
using Glamourer.Unlocks;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
@ -12,13 +12,6 @@ public sealed class DesignColorCombo(DesignColors _designColors, bool _skipAutom
|
||||||
: _designColors.Keys.OrderBy(k => k).Prepend(DesignColors.AutomaticName),
|
: _designColors.Keys.OrderBy(k => k).Prepend(DesignColors.AutomaticName),
|
||||||
MouseWheelType.Control, Glamourer.Log)
|
MouseWheelType.Control, Glamourer.Log)
|
||||||
{
|
{
|
||||||
protected override void OnMouseWheel(string preview, ref int current, int steps)
|
|
||||||
{
|
|
||||||
if (CurrentSelectionIdx < 0)
|
|
||||||
CurrentSelectionIdx = Items.IndexOf(preview);
|
|
||||||
base.OnMouseWheel(preview, ref current, steps);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool DrawSelectable(int globalIdx, bool selected)
|
protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||||
{
|
{
|
||||||
var isAutomatic = !_skipAutomatic && globalIdx == 0;
|
var isAutomatic = !_skipAutomatic && globalIdx == 0;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using Dalamud.Interface.ImGuiNotification;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
@ -189,10 +189,7 @@ public class DesignDetailTab
|
||||||
else if (_selector.Selected!.Color.Length != 0)
|
else if (_selector.Selected!.Color.Length != 0)
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var size = new Vector2(ImGui.GetFrameHeight());
|
ImUtf8.Icon(FontAwesomeIcon.ExclamationCircle, "The color associated with this design does not exist."u8, _colors.MissingColor);
|
||||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
|
||||||
ImGuiUtil.DrawTextButton(FontAwesomeIcon.ExclamationCircle.ToIconString(), size, 0, _colors.MissingColor);
|
|
||||||
ImUtf8.HoverTooltip("The color associated with this design does not exist."u8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImUtf8.DrawFrameColumn("Creation Date"u8);
|
ImUtf8.DrawFrameColumn("Creation Date"u8);
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,14 @@ using Glamourer.Designs;
|
||||||
using Glamourer.Designs.History;
|
using Glamourer.Designs.History;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using ImGuiNET;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using OtterGui.FileSystem.Selector;
|
using OtterGui.FileSystem.Selector;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using OtterGui.Text;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DesignTab;
|
namespace Glamourer.Gui.Tabs.DesignTab;
|
||||||
|
|
||||||
|
|
@ -45,6 +46,29 @@ public sealed class DesignFileSystemSelector : FileSystemSelector<Design, Design
|
||||||
public record struct DesignState(uint Color)
|
public record struct DesignState(uint Color)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
protected override float CurrentWidth
|
||||||
|
=> _config.Ephemeral.CurrentDesignSelectorWidth * ImUtf8.GlobalScale;
|
||||||
|
|
||||||
|
protected override float MinimumAbsoluteRemainder
|
||||||
|
=> 470 * ImUtf8.GlobalScale;
|
||||||
|
|
||||||
|
protected override float MinimumScaling
|
||||||
|
=> _config.Ephemeral.DesignSelectorMinimumScale;
|
||||||
|
|
||||||
|
protected override float MaximumScaling
|
||||||
|
=> _config.Ephemeral.DesignSelectorMaximumScale;
|
||||||
|
|
||||||
|
protected override void SetSize(Vector2 size)
|
||||||
|
{
|
||||||
|
base.SetSize(size);
|
||||||
|
var adaptedSize = MathF.Round(size.X / ImUtf8.GlobalScale);
|
||||||
|
if (adaptedSize == _config.Ephemeral.CurrentDesignSelectorWidth)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_config.Ephemeral.CurrentDesignSelectorWidth = adaptedSize;
|
||||||
|
_config.Ephemeral.Save();
|
||||||
|
}
|
||||||
|
|
||||||
public DesignFileSystemSelector(DesignManager designManager, DesignFileSystem fileSystem, IKeyState keyState, DesignChanged @event,
|
public DesignFileSystemSelector(DesignManager designManager, DesignFileSystem fileSystem, IKeyState keyState, DesignChanged @event,
|
||||||
Configuration config, DesignConverter converter, TabSelected selectionEvent, Logger log, DesignColors designColors,
|
Configuration config, DesignConverter converter, TabSelected selectionEvent, Logger log, DesignColors designColors,
|
||||||
DesignApplier designApplier)
|
DesignApplier designApplier)
|
||||||
|
|
@ -151,7 +175,7 @@ public sealed class DesignFileSystemSelector : FileSystemSelector<Design, Design
|
||||||
var flag = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
|
var flag = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
|
||||||
var name = IncognitoMode ? leaf.Value.Incognito : leaf.Value.Name.Text;
|
var name = IncognitoMode ? leaf.Value.Incognito : leaf.Value.Name.Text;
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, state.Color);
|
using var color = ImRaii.PushColor(ImGuiCol.Text, state.Color);
|
||||||
using var _ = ImRaii.TreeNode(name, flag);
|
using var _ = ImUtf8.TreeNode(name, flag);
|
||||||
if (_config.AllowDoubleClickToApply && ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left))
|
if (_config.AllowDoubleClickToApply && ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left))
|
||||||
_designApplier.ApplyToPlayer(leaf.Value);
|
_designApplier.ApplyToPlayer(leaf.Value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue