diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 327b75b..18435ae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: run: dotnet restore - name: Download Dalamud run: | - Invoke-WebRequest -Uri https://goatcorp.github.io/dalamud-distrib/stg/latest.zip -OutFile latest.zip + Invoke-WebRequest -Uri https://goatcorp.github.io/dalamud-distrib/latest.zip -OutFile latest.zip Expand-Archive -Force latest.zip "$env:AppData\XIVLauncher\addon\Hooks\dev" - name: Build run: | diff --git a/Glamourer.Api b/Glamourer.Api index 3bfd1db..2158bd4 160000 --- a/Glamourer.Api +++ b/Glamourer.Api @@ -1 +1 @@ -Subproject commit 3bfd1db3a471f6e808c4d981485a08f58a4bf6cd +Subproject commit 2158bd4bbcb6cefe3ce48e6d8b32e134cbee9a91 diff --git a/Glamourer/Api/ApiHelpers.cs b/Glamourer/Api/ApiHelpers.cs index 14cff3b..45d84b9 100644 --- a/Glamourer/Api/ApiHelpers.cs +++ b/Glamourer/Api/ApiHelpers.cs @@ -1,13 +1,13 @@ using Glamourer.Api.Enums; using Glamourer.Designs; using Glamourer.State; +using OtterGui; using OtterGui.Extensions; using OtterGui.Log; using OtterGui.Services; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; -using Penumbra.GameData.Structs; using Penumbra.String; namespace Glamourer.Api; @@ -15,23 +15,14 @@ namespace Glamourer.Api; public class ApiHelpers(ActorObjectManager objects, StateManager stateManager, ActorManager actors) : IApiService { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - internal IEnumerable FindExistingStates(string actorName, ushort worldId = ushort.MaxValue) + internal IEnumerable FindExistingStates(string actorName) { if (actorName.Length == 0 || !ByteString.FromString(actorName, out var byteString)) yield break; - if (worldId == WorldId.AnyWorld.Id) - { - 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; - } + foreach (var state in stateManager.Values.Where(state + => state.Identifier.Type is IdentifierType.Player && state.Identifier.PlayerName == byteString)) + yield return state; } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] diff --git a/Glamourer/Api/DesignsApi.cs b/Glamourer/Api/DesignsApi.cs index 9b48ade..0ee0b64 100644 --- a/Glamourer/Api/DesignsApi.cs +++ b/Glamourer/Api/DesignsApi.cs @@ -2,31 +2,19 @@ using Glamourer.Api.Enums; using Glamourer.Designs; using Glamourer.State; -using Newtonsoft.Json.Linq; using OtterGui.Services; namespace Glamourer.Api; -public class DesignsApi( - ApiHelpers helpers, - DesignManager designs, - StateManager stateManager, - DesignFileSystem fileSystem, - DesignColors color, - DesignConverter converter) +public class DesignsApi(ApiHelpers helpers, DesignManager designs, StateManager stateManager, DesignFileSystem fileSystem, DesignColors color) : IGlamourerApiDesigns, IApiService { public Dictionary GetDesignList() => designs.Designs.ToDictionary(d => d.Identifier, d => d.Name.Text); public Dictionary 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); + => designs.Designs.ToDictionary(d => d.Identifier, + d => (d.Name.Text, fileSystem.FindLeaf(d, out var leaf) ? leaf.FullName() : d.Name.Text, color.GetColor(d), d.QuickDesign)); public GlamourerApiEc ApplyDesign(Guid designId, int objectIndex, uint key, ApplyFlag flags) { @@ -83,56 +71,4 @@ public class DesignsApi( 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; } diff --git a/Glamourer/Api/GlamourerApi.cs b/Glamourer/Api/GlamourerApi.cs index 4bad983..9aaf72f 100644 --- a/Glamourer/Api/GlamourerApi.cs +++ b/Glamourer/Api/GlamourerApi.cs @@ -6,7 +6,7 @@ namespace Glamourer.Api; public class GlamourerApi(DesignsApi designs, StateApi state, ItemsApi items) : IGlamourerApi, IApiService { public const int CurrentApiVersionMajor = 1; - public const int CurrentApiVersionMinor = 7; + public const int CurrentApiVersionMinor = 5; public (int Major, int Minor) ApiVersion => (CurrentApiVersionMajor, CurrentApiVersionMinor); diff --git a/Glamourer/Api/IpcProviders.cs b/Glamourer/Api/IpcProviders.cs index 6019e68..70ba47f 100644 --- a/Glamourer/Api/IpcProviders.cs +++ b/Glamourer/Api/IpcProviders.cs @@ -25,13 +25,8 @@ public sealed class IpcProviders : IDisposable, IApiService 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.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.SetItemName.Provider(pi, api.Items), @@ -42,8 +37,6 @@ public sealed class IpcProviders : IDisposable, IApiService (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.SetBonusItemName.Provider(pi, api.Items), - IpcSubscribers.SetMetaState.Provider(pi, api.Items), - IpcSubscribers.SetMetaStateName.Provider(pi, api.Items), IpcSubscribers.GetState.Provider(pi, api.State), IpcSubscribers.GetStateName.Provider(pi, api.State), IpcSubscribers.GetStateBase64.Provider(pi, api.State), @@ -54,7 +47,6 @@ public sealed class IpcProviders : IDisposable, IApiService IpcSubscribers.RevertStateName.Provider(pi, api.State), IpcSubscribers.UnlockState.Provider(pi, api.State), IpcSubscribers.UnlockStateName.Provider(pi, api.State), - IpcSubscribers.DeletePlayerState.Provider(pi, api.State), IpcSubscribers.UnlockAll.Provider(pi, api.State), IpcSubscribers.RevertToAutomation.Provider(pi, api.State), IpcSubscribers.RevertToAutomationName.Provider(pi, api.State), diff --git a/Glamourer/Api/StateApi.cs b/Glamourer/Api/StateApi.cs index 3b0c2c5..43dc453 100644 --- a/Glamourer/Api/StateApi.cs +++ b/Glamourer/Api/StateApi.cs @@ -8,7 +8,6 @@ using Glamourer.State; using Newtonsoft.Json.Linq; using OtterGui.Services; using Penumbra.GameData.Interop; -using Penumbra.GameData.Structs; using StateChanged = Glamourer.Events.StateChanged; namespace Glamourer.Api; @@ -18,6 +17,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable private readonly ApiHelpers _helpers; private readonly StateManager _stateManager; private readonly DesignConverter _converter; + private readonly Configuration _config; private readonly AutoDesignApplier _autoDesigns; private readonly ActorObjectManager _objects; private readonly StateChanged _stateChanged; @@ -27,6 +27,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable public StateApi(ApiHelpers helpers, StateManager stateManager, DesignConverter converter, + Configuration config, AutoDesignApplier autoDesigns, ActorObjectManager objects, StateChanged stateChanged, @@ -36,6 +37,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable _helpers = helpers; _stateManager = stateManager; _converter = converter; + _config = config; _autoDesigns = autoDesigns; _objects = objects; _stateChanged = stateChanged; @@ -200,27 +202,6 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable 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) => _stateManager.Values.Count(state => state.Unlock(key)); @@ -291,7 +272,7 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable { case ApplyFlag.Equipment: _stateManager.ResetEquip(state, source, key); break; case ApplyFlag.Customization: _stateManager.ResetCustomize(state, source, key); break; - case ApplyFlag.Equipment | ApplyFlag.Customization: _stateManager.ResetState(state, source, key, true); break; + case ApplyFlag.Equipment | ApplyFlag.Customization: _stateManager.ResetState(state, source, key); break; } ApiHelpers.Lock(state, key, flags); diff --git a/Glamourer/Automation/ApplicationType.cs b/Glamourer/Automation/ApplicationType.cs index f72c93f..58f296e 100644 --- a/Glamourer/Automation/ApplicationType.cs +++ b/Glamourer/Automation/ApplicationType.cs @@ -38,7 +38,7 @@ public static class ApplicationTypeExtensions var customizeFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeFlagExtensions.All : 0; var parameterFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeParameterExtensions.All : 0; var crestFlags = type.HasFlag(ApplicationType.GearCustomization) ? CrestExtensions.AllRelevant : 0; - var metaFlags = (type.HasFlag(ApplicationType.Armor) ? MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.EarState : 0) + var metaFlags = (type.HasFlag(ApplicationType.Armor) ? MetaFlag.HatState | MetaFlag.VisorState : 0) | (type.HasFlag(ApplicationType.Weapons) ? MetaFlag.WeaponState : 0) | (type.HasFlag(ApplicationType.Customizations) ? MetaFlag.Wetness : 0); var bonusFlags = type.HasFlag(ApplicationType.Armor) ? BonusExtensions.All : 0; diff --git a/Glamourer/Configuration.cs b/Glamourer/Configuration.cs index d266a55..4339186 100644 --- a/Glamourer/Configuration.cs +++ b/Glamourer/Configuration.cs @@ -32,7 +32,6 @@ public class DefaultDesignSettings public bool ResetAdvancedDyes = false; public bool ShowQuickDesignBar = true; public bool ResetTemporarySettings = false; - public bool Locked = false; } public class Configuration : IPluginConfiguration, ISavable @@ -40,37 +39,33 @@ public class Configuration : IPluginConfiguration, ISavable [JsonIgnore] public readonly EphemeralConfig Ephemeral; - public bool AttachToPcp { get; set; } = true; - public bool UseRestrictedGearProtection { get; set; } = false; - public bool OpenFoldersByDefault { get; set; } = false; - public bool AutoRedrawEquipOnChanges { get; set; } = false; - public bool EnableAutoDesigns { get; set; } = true; - public bool HideApplyCheckmarks { get; set; } = false; - public bool SmallEquip { get; set; } = false; - public bool UnlockedItemMode { get; set; } = false; - public byte DisableFestivals { get; set; } = 1; - public bool EnableGameContextMenu { get; set; } = true; - public bool HideWindowInCutscene { get; set; } = false; - public bool ShowAutomationSetEditing { get; set; } = true; - public bool ShowAllAutomatedApplicationRules { get; set; } = true; - public bool ShowUnlockedItemWarnings { get; set; } = true; - public bool RevertManualChangesOnZoneChange { get; set; } = false; - public bool ShowQuickBarInTabs { get; set; } = true; - public bool OpenWindowAtStart { get; set; } = false; - public bool ShowWindowWhenUiHidden { get; set; } = false; - public bool KeepAdvancedDyesAttached { get; set; } = true; - public bool ShowPalettePlusImport { get; set; } = true; - public bool UseFloatForColors { get; set; } = true; - public bool UseRgbForColors { get; set; } = true; - public bool ShowColorConfig { get; set; } = true; - public bool ChangeEntireItem { get; set; } = false; - public bool AlwaysApplyAssociatedMods { get; set; } = true; - public bool UseTemporarySettings { get; set; } = true; - 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 bool UseRestrictedGearProtection { get; set; } = false; + public bool OpenFoldersByDefault { get; set; } = false; + public bool AutoRedrawEquipOnChanges { get; set; } = false; + public bool EnableAutoDesigns { get; set; } = true; + public bool HideApplyCheckmarks { get; set; } = false; + public bool SmallEquip { get; set; } = false; + public bool UnlockedItemMode { get; set; } = false; + public byte DisableFestivals { get; set; } = 1; + public bool EnableGameContextMenu { get; set; } = true; + public bool HideWindowInCutscene { get; set; } = false; + public bool ShowAutomationSetEditing { get; set; } = true; + public bool ShowAllAutomatedApplicationRules { get; set; } = true; + public bool ShowUnlockedItemWarnings { get; set; } = true; + public bool RevertManualChangesOnZoneChange { get; set; } = false; + public bool ShowQuickBarInTabs { get; set; } = true; + public bool OpenWindowAtStart { get; set; } = false; + public bool ShowWindowWhenUiHidden { get; set; } = false; + public bool KeepAdvancedDyesAttached { get; set; } = true; + public bool ShowPalettePlusImport { get; set; } = true; + public bool UseFloatForColors { get; set; } = true; + public bool UseRgbForColors { get; set; } = true; + public bool ShowColorConfig { get; set; } = true; + public bool ChangeEntireItem { get; set; } = false; + public bool AlwaysApplyAssociatedMods { get; set; } = false; + public bool UseTemporarySettings { get; set; } = true; + public bool AllowDoubleClickToApply { get; set; } = false; + public bool RespectManualOnAutomationUpdate { get; set; } = false; public DesignPanelFlag HideDesignPanel { get; set; } = 0; public DesignPanelFlag AutoExpandDesignPanel { get; set; } = 0; @@ -85,7 +80,7 @@ public class Configuration : IPluginConfiguration, ISavable public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New; public QdbButtons QdbButtons { get; set; } = - QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvancedDyes; + QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvanced; [JsonConverter(typeof(SortModeConverter))] [JsonProperty(Order = int.MaxValue)] @@ -162,7 +157,7 @@ public class Configuration : IPluginConfiguration, ISavable public static class Constants { - public const int CurrentVersion = 8; + public const int CurrentVersion = 7; public static readonly ISortMode[] ValidSortModes = [ diff --git a/Glamourer/DesignPanelFlag.cs b/Glamourer/DesignPanelFlag.cs index f9465d9..db84173 100644 --- a/Glamourer/DesignPanelFlag.cs +++ b/Glamourer/DesignPanelFlag.cs @@ -1,5 +1,5 @@ using Glamourer.Designs; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Text; using OtterGui.Text.EndObjects; diff --git a/Glamourer/Designs/ApplicationCollection.cs b/Glamourer/Designs/ApplicationCollection.cs index c03d4b4..13813a3 100644 --- a/Glamourer/Designs/ApplicationCollection.cs +++ b/Glamourer/Designs/ApplicationCollection.cs @@ -1,6 +1,6 @@ using Glamourer.Api.Enums; using Glamourer.GameData; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Penumbra.GameData.Enums; 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 Equipment = new(EquipFlagExtensions.All, BonusExtensions.All, - CustomizeFlag.BodyType, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.WeaponState | MetaFlag.VisorState | MetaFlag.EarState); + CustomizeFlag.BodyType, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.WeaponState | MetaFlag.VisorState); public static readonly ApplicationCollection Customizations = new(0, 0, CustomizeFlagExtensions.AllRelevant, 0, CustomizeParameterExtensions.All, MetaFlag.Wetness); public static readonly ApplicationCollection Default = new(EquipFlagExtensions.All, BonusExtensions.All, - CustomizeFlagExtensions.AllRelevant, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState | MetaFlag.EarState); + CustomizeFlagExtensions.AllRelevant, CrestExtensions.AllRelevant, 0, MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState); public static ApplicationCollection FromKeys() => (ImGui.GetIO().KeyCtrl, ImGui.GetIO().KeyShift) switch @@ -47,7 +47,7 @@ public record struct ApplicationCollection( Equip = 0; BonusItem = 0; Crest = 0; - Meta &= ~(MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState | MetaFlag.EarState); + Meta &= ~(MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState); } public void RemoveCustomize() diff --git a/Glamourer/Designs/ApplicationRules.cs b/Glamourer/Designs/ApplicationRules.cs index 281a940..0df4feb 100644 --- a/Glamourer/Designs/ApplicationRules.cs +++ b/Glamourer/Designs/ApplicationRules.cs @@ -1,7 +1,7 @@ using Glamourer.Api.Enums; using Glamourer.GameData; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Penumbra.GameData.Enums; namespace Glamourer.Designs; diff --git a/Glamourer/Designs/Design.cs b/Glamourer/Designs/Design.cs index 848e7d6..35ee3aa 100644 --- a/Glamourer/Designs/Design.cs +++ b/Glamourer/Designs/Design.cs @@ -100,7 +100,7 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn public new JObject JsonSerialize() { - var ret = new JObject + var ret = new JObject() { ["FileVersion"] = FileVersion, ["Identifier"] = Identifier, @@ -131,17 +131,12 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn var ret = new JArray(); foreach (var (mod, settings) in AssociatedMods) { - var obj = new JObject + var obj = new JObject() { ["Name"] = mod.Name, ["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) { obj["Priority"] = settings.Priority; diff --git a/Glamourer/Designs/DesignBase.cs b/Glamourer/Designs/DesignBase.cs index f87d75a..b21c433 100644 --- a/Glamourer/Designs/DesignBase.cs +++ b/Glamourer/Designs/DesignBase.cs @@ -40,8 +40,7 @@ public class DesignBase } /// Used when importing .cma or .chara files. - 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; ApplyCustomize = customizeFlags & CustomizeFlagExtensions.AllRelevant; @@ -255,10 +254,9 @@ public class DesignBase 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["VieraEars"] = new QuadBool(_designData.AreEarsVisible(), DoApplyMeta(MetaIndex.EarState)).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"); + 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["Weapon"] = new QuadBool(_designData.IsWeaponVisible(), DoApplyMeta(MetaIndex.WeaponState)).ToJObject("Show", "Apply"); } else { @@ -605,10 +603,6 @@ public class DesignBase metaValue = QuadBool.FromJObject(equip["Visor"], "IsToggled", "Apply", QuadBool.NullFalse); design.SetApplyMeta(MetaIndex.VisorState, metaValue.Enabled); 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; void PrintWarning(string msg) diff --git a/Glamourer/Designs/DesignColors.cs b/Glamourer/Designs/DesignColors.cs index a8f3178..172e10f 100644 --- a/Glamourer/Designs/DesignColors.cs +++ b/Glamourer/Designs/DesignColors.cs @@ -3,7 +3,7 @@ using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.Utility.Raii; using Glamourer.Gui; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; diff --git a/Glamourer/Designs/DesignData.cs b/Glamourer/Designs/DesignData.cs index c7ca8e5..bba0ccb 100644 --- a/Glamourer/Designs/DesignData.cs +++ b/Glamourer/Designs/DesignData.cs @@ -287,7 +287,6 @@ public unsafe struct DesignData MetaIndex.HatState => IsHatVisible(), MetaIndex.VisorState => IsVisorToggled(), MetaIndex.WeaponState => IsWeaponVisible(), - MetaIndex.EarState => AreEarsVisible(), _ => false, }; @@ -298,7 +297,6 @@ public unsafe struct DesignData MetaIndex.HatState => SetHatVisible(value), MetaIndex.VisorState => SetVisor(value), MetaIndex.WeaponState => SetWeaponVisible(value), - MetaIndex.EarState => SetEarsVisible(value), _ => false, }; @@ -342,9 +340,6 @@ public unsafe struct DesignData public readonly bool IsWeaponVisible() => (_states & 0x08) == 0x08; - public readonly bool AreEarsVisible() - => (_states & 0x10) == 0x00; - public bool SetWeaponVisible(bool value) { if (value == IsWeaponVisible()) @@ -354,15 +349,6 @@ public unsafe struct DesignData 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) { foreach (var slot in EquipSlotExtensions.EqdpSlots) @@ -400,7 +386,6 @@ public unsafe struct DesignData SetHatVisible(true); SetWeaponVisible(true); - SetEarsVisible(true); SetVisor(false); fixed (uint* ptr = _itemIds) { diff --git a/Glamourer/Designs/DesignFileSystem.cs b/Glamourer/Designs/DesignFileSystem.cs index fd47793..e985e32 100644 --- a/Glamourer/Designs/DesignFileSystem.cs +++ b/Glamourer/Designs/DesignFileSystem.cs @@ -41,11 +41,11 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable public struct CreationDate : ISortMode { - public ReadOnlySpan Name - => "Creation Date (Older First)"u8; + public string Name + => "Creation Date (Older First)"; - public ReadOnlySpan Description - => "In each folder, sort all subfolders lexicographically, then sort all leaves using their creation date."u8; + public string Description + => "In each folder, sort all subfolders lexicographically, then sort all leaves using their creation date."; public IEnumerable GetChildren(Folder f) => f.GetSubFolders().Cast().Concat(f.GetLeaves().OrderBy(l => l.Value.CreationDate)); @@ -53,11 +53,11 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable public struct UpdateDate : ISortMode { - public ReadOnlySpan Name - => "Update Date (Older First)"u8; + public string Name + => "Update Date (Older First)"; - public ReadOnlySpan Description - => "In each folder, sort all subfolders lexicographically, then sort all leaves using their last update date."u8; + public string Description + => "In each folder, sort all subfolders lexicographically, then sort all leaves using their last update date."; public IEnumerable GetChildren(Folder f) => f.GetSubFolders().Cast().Concat(f.GetLeaves().OrderBy(l => l.Value.LastEdit)); @@ -65,11 +65,11 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable public struct InverseCreationDate : ISortMode { - public ReadOnlySpan Name - => "Creation Date (Newer First)"u8; + public string Name + => "Creation Date (Newer First)"; - public ReadOnlySpan Description - => "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse creation date."u8; + public string Description + => "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse creation date."; public IEnumerable GetChildren(Folder f) => f.GetSubFolders().Cast().Concat(f.GetLeaves().OrderByDescending(l => l.Value.CreationDate)); @@ -77,11 +77,11 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable public struct InverseUpdateDate : ISortMode { - public ReadOnlySpan Name - => "Update Date (Newer First)"u8; + public string Name + => "Update Date (Newer First)"; - public ReadOnlySpan Description - => "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse last update date."u8; + public string Description + => "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse last update date."; public IEnumerable GetChildren(Folder f) => f.GetSubFolders().Cast().Concat(f.GetLeaves().OrderByDescending(l => l.Value.LastEdit)); @@ -114,14 +114,14 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable return; case DesignChanged.Type.Deleted: - if (TryGetValue(design, out var leaf1)) + if (FindLeaf(design, out var leaf1)) Delete(leaf1); return; case DesignChanged.Type.ReloadedAll: Reload(); return; case DesignChanged.Type.Renamed when (data as RenameTransaction?)?.Old is { } oldName: - if (!TryGetValue(design, out var leaf2)) + if (!FindLeaf(design, out var leaf2)) return; var old = oldName.FixName(); @@ -150,6 +150,15 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable ? (string.Empty, false) : (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.Lexicographical) + .OfType() + .FirstOrDefault(l => l.Value == design); + return leaf != null; + } + internal static void MigrateOldPaths(SaveService saveService, Dictionary oldPaths) { if (oldPaths.Count == 0) diff --git a/Glamourer/Designs/DesignManager.cs b/Glamourer/Designs/DesignManager.cs index 92f8398..fff9565 100644 --- a/Glamourer/Designs/DesignManager.cs +++ b/Glamourer/Designs/DesignManager.cs @@ -6,13 +6,12 @@ using Glamourer.GameData; using Glamourer.Interop.Material; using Glamourer.Interop.Penumbra; using Glamourer.Services; -using OtterGui.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using OtterGui.Extensions; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; - namespace Glamourer.Designs; public sealed class DesignManager : DesignEditor @@ -111,7 +110,6 @@ public sealed class DesignManager : DesignEditor QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar, ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings, }; - design.SetWriteProtected(Config.DefaultDesignSettings.Locked); Designs.Add(design); Glamourer.Log.Debug($"Added new design {design.Identifier}."); SaveService.ImmediateSave(design); @@ -136,7 +134,6 @@ public sealed class DesignManager : DesignEditor ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings, }; - design.SetWriteProtected(Config.DefaultDesignSettings.Locked); Designs.Add(design); Glamourer.Log.Debug($"Added new design {design.Identifier} by cloning Temporary Design."); SaveService.ImmediateSave(design); @@ -156,7 +153,6 @@ public sealed class DesignManager : DesignEditor Name = actualName, Index = Designs.Count, }; - design.SetWriteProtected(Config.DefaultDesignSettings.Locked); Designs.Add(design); Glamourer.Log.Debug( $"Added new design {design.Identifier} by cloning {clone.Identifier.ToString()}."); @@ -229,7 +225,7 @@ public sealed class DesignManager : DesignEditor design.Tags = design.Tags.Append(tag).OrderBy(t => t).ToArray(); design.LastEdit = DateTimeOffset.UtcNow; - var idx = design.Tags.AsEnumerable().IndexOf(tag); + var idx = design.Tags.IndexOf(tag); SaveService.QueueSave(design); Glamourer.Log.Debug($"Added tag {tag} at {idx} to design {design.Identifier}."); DesignChanged.Invoke(DesignChanged.Type.AddedTag, design, new TagAddedTransaction(tag, idx)); @@ -262,7 +258,7 @@ public sealed class DesignManager : DesignEditor SaveService.QueueSave(design); Glamourer.Log.Debug($"Renamed tag {oldTag} at {tagIdx} to {newTag} in design {design.Identifier} and reordered tags."); DesignChanged.Invoke(DesignChanged.Type.ChangedTag, design, - new TagChangedTransaction(oldTag, newTag, tagIdx, design.Tags.AsEnumerable().IndexOf(newTag))); + new TagChangedTransaction(oldTag, newTag, tagIdx, design.Tags.IndexOf(newTag))); } /// Add an associated mod to a design. @@ -557,7 +553,7 @@ public sealed class DesignManager : DesignEditor try { File.Move(SaveService.FileNames.MigrationDesignFile, - Path.ChangeExtension(SaveService.FileNames.MigrationDesignFile, ".json.bak"), true); + Path.ChangeExtension(SaveService.FileNames.MigrationDesignFile, ".json.bak")); Glamourer.Log.Information($"Moved migrated design file {SaveService.FileNames.MigrationDesignFile} to backup file."); } catch (Exception ex) diff --git a/Glamourer/Designs/History/EditorHistory.cs b/Glamourer/Designs/History/EditorHistory.cs index caec151..58bce3d 100644 --- a/Glamourer/Designs/History/EditorHistory.cs +++ b/Glamourer/Designs/History/EditorHistory.cs @@ -152,7 +152,7 @@ public class EditorHistory : IDisposable, IService { if (!_stateEntries.TryGetValue(state, out var list)) { - list = []; + list = new Queue(); _stateEntries.Add(state, list); } @@ -163,7 +163,7 @@ public class EditorHistory : IDisposable, IService { if (!_designEntries.TryGetValue(design, out var list)) { - list = []; + list = new Queue(); _designEntries.Add(design, list); } diff --git a/Glamourer/Designs/MetaIndex.cs b/Glamourer/Designs/MetaIndex.cs index 1842ae3..3fc4655 100644 --- a/Glamourer/Designs/MetaIndex.cs +++ b/Glamourer/Designs/MetaIndex.cs @@ -10,15 +10,14 @@ public enum MetaIndex VisorState = StateIndex.MetaVisorState, WeaponState = StateIndex.MetaWeaponState, ModelId = StateIndex.MetaModelId, - EarState = StateIndex.MetaEarState, } public static class MetaExtensions { public static readonly IReadOnlyList AllRelevant = - [MetaIndex.Wetness, MetaIndex.HatState, MetaIndex.VisorState, MetaIndex.WeaponState, MetaIndex.EarState]; + [MetaIndex.Wetness, MetaIndex.HatState, MetaIndex.VisorState, MetaIndex.WeaponState]; - public const MetaFlag All = MetaFlag.Wetness | MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState | MetaFlag.EarState; + public const MetaFlag All = MetaFlag.Wetness | MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState; public static MetaFlag ToFlag(this MetaIndex index) => index switch @@ -27,7 +26,6 @@ public static class MetaExtensions MetaIndex.HatState => MetaFlag.HatState, MetaIndex.VisorState => MetaFlag.VisorState, MetaIndex.WeaponState => MetaFlag.WeaponState, - MetaIndex.EarState => MetaFlag.EarState, _ => (MetaFlag)byte.MaxValue, }; @@ -38,8 +36,7 @@ public static class MetaExtensions MetaFlag.HatState => MetaIndex.HatState, MetaFlag.VisorState => MetaIndex.VisorState, MetaFlag.WeaponState => MetaIndex.WeaponState, - MetaFlag.EarState => MetaIndex.EarState, - _ => (MetaIndex)byte.MaxValue, + _ => (MetaIndex)byte.MaxValue, }; public static IEnumerable ToIndices(this MetaFlag index) @@ -52,8 +49,6 @@ public static class MetaExtensions yield return MetaIndex.VisorState; if (index.HasFlag(MetaFlag.WeaponState)) yield return MetaIndex.WeaponState; - if (index.HasFlag(MetaFlag.EarState)) - yield return MetaIndex.EarState; } public static string ToName(this MetaIndex index) @@ -63,7 +58,6 @@ public static class MetaExtensions MetaIndex.VisorState => "Visor Toggled", MetaIndex.WeaponState => "Weapon Visible", MetaIndex.Wetness => "Force Wetness", - MetaIndex.EarState => "Ears Visible", _ => "Unknown Meta", }; @@ -74,7 +68,6 @@ public static class MetaExtensions MetaIndex.VisorState => "Toggle the visor state of the characters head gear.", MetaIndex.WeaponState => "Hide or show the characters weapons when not drawn.", 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, }; } diff --git a/Glamourer/Designs/Special/RandomDesignGenerator.cs b/Glamourer/Designs/Special/RandomDesignGenerator.cs index b1e1e7c..7ed4452 100644 --- a/Glamourer/Designs/Special/RandomDesignGenerator.cs +++ b/Glamourer/Designs/Special/RandomDesignGenerator.cs @@ -1,33 +1,19 @@ -using OtterGui; -using OtterGui.Services; +using OtterGui.Services; namespace Glamourer.Designs.Special; -public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem, Configuration config) : IService +public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileSystem) : IService { - private readonly Random _rng = new(); - private readonly WeakReference _lastDesign = new(null!, false); + private readonly Random _rng = new(); public Design? Design(IReadOnlyList localDesigns) { - if (localDesigns.Count is 0) + if (localDesigns.Count == 0) return null; var idx = _rng.Next(0, localDesigns.Count); - if (localDesigns.Count is 1) - { - _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; + Glamourer.Log.Verbose($"[Random Design] Chose design {idx + 1} out of {localDesigns.Count}: {localDesigns[idx].Incognito}."); + return localDesigns[idx]; } public Design? Design() @@ -38,12 +24,12 @@ public class RandomDesignGenerator(DesignStorage designs, DesignFileSystem fileS public Design? Design(IReadOnlyList predicates) { - return predicates.Count switch - { - 0 => Design(), - 1 => Design(predicates[0]), - _ => Design(IDesignPredicate.Get(predicates, designs, fileSystem).ToList()), - }; + if (predicates.Count == 0) + return Design(); + if (predicates.Count == 1) + return Design(predicates[0]); + + return Design(IDesignPredicate.Get(predicates, designs, fileSystem).ToList()); } public Design? Design(string restrictions) diff --git a/Glamourer/Designs/Special/RandomPredicate.cs b/Glamourer/Designs/Special/RandomPredicate.cs index ae05f8f..efb3233 100644 --- a/Glamourer/Designs/Special/RandomPredicate.cs +++ b/Glamourer/Designs/Special/RandomPredicate.cs @@ -22,7 +22,7 @@ public interface IDesignPredicate : designs; private static (Design Design, string LowerName, string Identifier, string LowerPath) Transform(Design d, DesignFileSystem fs) - => (d, d.Name.Lower, d.Identifier.ToString(), fs.TryGetValue(d, out var l) ? l.FullName().ToLowerInvariant() : string.Empty); + => (d, d.Name.Lower, d.Identifier.ToString(), fs.FindLeaf(d, out var l) ? l.FullName().ToLowerInvariant() : string.Empty); } public static class RandomPredicate diff --git a/Glamourer/EphemeralConfig.cs b/Glamourer/EphemeralConfig.cs index 98dabec..3e13dc4 100644 --- a/Glamourer/EphemeralConfig.cs +++ b/Glamourer/EphemeralConfig.cs @@ -20,10 +20,6 @@ public class EphemeralConfig : ISavable public Guid SelectedQuickDesign { get; set; } = Guid.Empty; 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] private readonly SaveService _saveService; diff --git a/Glamourer/Events/PenumbraReloaded.cs b/Glamourer/Events/PenumbraReloaded.cs index 0975670..20b58f9 100644 --- a/Glamourer/Events/PenumbraReloaded.cs +++ b/Glamourer/Events/PenumbraReloaded.cs @@ -15,8 +15,5 @@ public sealed class PenumbraReloaded() /// VisorService = 0, - - /// - VieraEarService = 0, } } diff --git a/Glamourer/Events/VieraEarStateChanged.cs b/Glamourer/Events/VieraEarStateChanged.cs deleted file mode 100644 index 65730b8..0000000 --- a/Glamourer/Events/VieraEarStateChanged.cs +++ /dev/null @@ -1,22 +0,0 @@ -using OtterGui.Classes; -using Penumbra.GameData.Interop; - -namespace Glamourer.Events; - -/// -/// Triggered when the state of viera ear visibility for any draw object is changed. -/// -/// Parameter is the model with a changed viera ear visibility state. -/// Parameter is the new state. -/// Parameter is whether to call the original function. -/// -/// -public sealed class VieraEarStateChanged() - : EventWrapperRef2(nameof(VieraEarStateChanged)) -{ - public enum Priority - { - /// - StateListener = 0, - } -} diff --git a/Glamourer/Events/VisorStateChanged.cs b/Glamourer/Events/VisorStateChanged.cs index 03b7336..d2d3a6c 100644 --- a/Glamourer/Events/VisorStateChanged.cs +++ b/Glamourer/Events/VisorStateChanged.cs @@ -19,4 +19,4 @@ public sealed class VisorStateChanged() /// StateListener = 0, } -} \ No newline at end of file +} diff --git a/Glamourer/Glamourer.cs b/Glamourer/Glamourer.cs index 33c67d5..1e2a62d 100644 --- a/Glamourer/Glamourer.cs +++ b/Glamourer/Glamourer.cs @@ -26,7 +26,6 @@ public class Glamourer : IDalamudPlugin public static readonly Logger Log = new(); public static MessageService Messager { get; private set; } = null!; - public static DynamisIpc Dynamis { get; private set; } = null!; private readonly ServiceManager _services; @@ -36,7 +35,6 @@ public class Glamourer : IDalamudPlugin { _services = StaticServiceManager.CreateProvider(pluginInterface, Log, this); Messager = _services.GetService(); - Dynamis = _services.GetService(); _services.EnsureRequiredServices(); _services.GetService(); @@ -71,7 +69,6 @@ public class Glamourer : IDalamudPlugin sb.Append($"> **`Festival Easter-Eggs: `** {config.DisableFestivals}\n"); sb.Append($"> **`Apply Entire Weapon: `** {config.ChangeEntireItem}\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($"> **`Show QDB: `** {config.Ephemeral.ShowDesignQuickBar}\n"); sb.Append($"> **`QDB Hotkey: `** {config.ToggleQuickDesignBar}\n"); diff --git a/Glamourer/Glamourer.csproj b/Glamourer/Glamourer.csproj index 061e920..9dabbb2 100644 --- a/Glamourer/Glamourer.csproj +++ b/Glamourer/Glamourer.csproj @@ -1,4 +1,4 @@ - + Glamourer Glamourer diff --git a/Glamourer/Glamourer.json b/Glamourer/Glamourer.json index 2daff91..3127d7d 100644 --- a/Glamourer/Glamourer.json +++ b/Glamourer/Glamourer.json @@ -8,7 +8,7 @@ "AssemblyVersion": "9.0.0.1", "RepoUrl": "https://github.com/Ottermandias/Glamourer", "ApplicableVersion": "any", - "DalamudApiLevel": 13, + "DalamudApiLevel": 12, "ImageUrls": null, "IconUrl": "https://raw.githubusercontent.com/Ottermandias/Glamourer/master/images/icon.png" } \ No newline at end of file diff --git a/Glamourer/Gui/Colors.cs b/Glamourer/Gui/Colors.cs index b2713eb..98deace 100644 --- a/Glamourer/Gui/Colors.cs +++ b/Glamourer/Gui/Colors.cs @@ -1,4 +1,4 @@ -using Dalamud.Bindings.ImGui; +using ImGuiNET; namespace Glamourer.Gui; diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs b/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs index 4f463d6..4d34a05 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs @@ -1,83 +1,16 @@ using Dalamud.Interface; using Dalamud.Interface.Utility; using Glamourer.GameData; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; -using OtterGui.Text; -using OtterGui.Text.EndObjects; using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; -using System; namespace Glamourer.Gui.Customization; public partial class CustomizationDrawer { - 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 const string ColorPickerPopupName = "ColorPicker"; private void DrawColorPicker(CustomizeIndex index) { @@ -88,7 +21,7 @@ public partial class CustomizationDrawer using (_ = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, current < 0)) { - if (ImGui.ColorButton($"{_customize[index].Value}##color", color, ImGuiColorEditFlags.NoDragDrop, _framedIconSize)) + if (ImGui.ColorButton($"{_customize[index].Value}##color", color, ImGuiColorEditFlags.None, _framedIconSize)) { ImGui.OpenPopup(ColorPickerPopupName); } @@ -97,9 +30,6 @@ public partial class CustomizationDrawer var data = _set.Data(_currentIndex, current, _customize.Face); UpdateValue(data.Value); } - - DrawDragDropSource(index, custom); - DrawDragDropTarget(index); } var npc = false; diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs index 26e9002..2f67012 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs @@ -1,5 +1,5 @@ using Dalamud.Interface; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs b/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs index 8599f8c..eabb6f0 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs @@ -1,7 +1,7 @@ using Dalamud.Interface.Textures.TextureWraps; using Glamourer.GameData; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; using OtterGui.Raii; @@ -35,7 +35,7 @@ public partial class CustomizationDrawer var hasIcon = icon.TryGetWrap(out var wrap, out _); using (_ = ImRaii.Disabled(_locked || _currentIndex is CustomizeIndex.Face && _lockedRedraw)) { - if (ImGui.ImageButton(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, _iconSize)) + if (ImGui.ImageButton(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, _iconSize)) { ImGui.OpenPopup(IconSelectorPopup); } @@ -89,7 +89,7 @@ public partial class CustomizationDrawer : ImRaii.PushColor(ImGuiCol.Button, ColorId.FavoriteStarOn.Value(), isFavorite); var hasIcon = icon.TryGetWrap(out var wrap, out var _); - if (ImGui.ImageButton(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, _iconSize)) + if (ImGui.ImageButton(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, _iconSize)) { UpdateValue(custom.Value); ImGui.CloseCurrentPopup(); @@ -215,7 +215,7 @@ public partial class CustomizationDrawer hasIcon = icon.TryGetWrap(out wrap, out _); } - if (ImGui.ImageButton(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, _iconSize, Vector2.Zero, Vector2.One, + if (ImGui.ImageButton(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, _iconSize, Vector2.Zero, Vector2.One, (int)ImGui.GetStyle().FramePadding.X, Vector4.Zero, enabled ? Vector4.One : _redTint)) { _customize.Set(featureIdx, enabled ? CustomizeValue.Zero : CustomizeValue.Max); diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs b/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs index ec5523f..2c797b8 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs @@ -1,4 +1,4 @@ -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGuiInternal; diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.cs b/Glamourer/Gui/Customization/CustomizationDrawer.cs index 349891c..4ec6146 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.cs @@ -4,7 +4,7 @@ using Dalamud.Plugin.Services; using Glamourer.GameData; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; diff --git a/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs b/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs index 4db6b14..9bfb2f8 100644 --- a/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs +++ b/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs @@ -3,7 +3,7 @@ using Glamourer.Designs; using Glamourer.GameData; using Glamourer.Interop.PalettePlus; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Services; @@ -287,13 +287,13 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import } private ImGuiColorEditFlags GetFlags() - => Format | Display | ImGuiColorEditFlags.Hdr | ImGuiColorEditFlags.NoOptions; + => Format | Display | ImGuiColorEditFlags.HDR | ImGuiColorEditFlags.NoOptions; private ImGuiColorEditFlags Format => config.UseFloatForColors ? ImGuiColorEditFlags.Float : ImGuiColorEditFlags.Uint8; private ImGuiColorEditFlags Display - => config.UseRgbForColors ? ImGuiColorEditFlags.DisplayRgb : ImGuiColorEditFlags.DisplayHsv; + => config.UseRgbForColors ? ImGuiColorEditFlags.DisplayRGB : ImGuiColorEditFlags.DisplayHSV; private ImRaii.IEndObject EnsureSize() { diff --git a/Glamourer/Gui/DesignCombo.cs b/Glamourer/Gui/DesignCombo.cs index 2d8880e..a871cf1 100644 --- a/Glamourer/Gui/DesignCombo.cs +++ b/Glamourer/Gui/DesignCombo.cs @@ -5,7 +5,7 @@ using Glamourer.Designs; using Glamourer.Designs.History; using Glamourer.Designs.Special; using Glamourer.Events; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Extensions; @@ -22,7 +22,6 @@ public abstract class DesignComboBase : FilterComboCache>> generator, Logger log, DesignChanged designChanged, TabSelected tabSelected, EphemeralConfig config, DesignColors designColors) @@ -85,11 +84,17 @@ public abstract class DesignComboBase : FilterComboCache _currentDesign == p.Item1); + UpdateSelection(CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : null); + return CurrentSelectionIdx; + } + protected bool Draw(IDesignStandIn? currentDesign, string? label, float width) { _currentDesign = currentDesign; - UpdateCurrentSelection(); - InnerWidth = 400 * ImGuiHelpers.GlobalScale; + InnerWidth = 400 * ImGuiHelpers.GlobalScale; var name = label ?? "Select Design Here..."; bool ret; using (_ = currentDesign != null ? ImRaii.PushColor(ImGuiCol.Text, DesignColors.GetColor(currentDesign as Design)) : null) @@ -123,60 +128,37 @@ public abstract class DesignComboBase : FilterComboCache ReferenceEquals(s.Item1, CurrentSelection?.Item1)); - if (CurrentSelectionIdx >= 0) + switch (type) { - UpdateSelection(Items[CurrentSelectionIdx]); + 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) + Cleanup(); + break; } - 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) @@ -194,7 +176,7 @@ public abstract class DesignComboBase : FilterComboCache [ - .. fileSystem - .Where(kvp => kvp.Key.QuickDesign) - .Select(kvp => new Tuple(kvp.Key, kvp.Value.FullName())) + .. designs.Designs + .Where(d => d.QuickDesign) + .Select(d => new Tuple(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)) .OrderBy(d => d.Item2), ]) { @@ -295,6 +278,7 @@ public sealed class QuickDesignCombo : DesignCombo } public sealed class LinkDesignCombo( + DesignManager designs, DesignFileSystem fileSystem, Logger log, DesignChanged designChanged, @@ -303,8 +287,8 @@ public sealed class LinkDesignCombo( DesignColors designColors) : DesignCombo(log, designChanged, tabSelected, config, designColors, () => [ - .. fileSystem - .Select(kvp => new Tuple(kvp.Key, kvp.Value.FullName())) + .. designs.Designs + .Select(d => new Tuple(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)) .OrderBy(d => d.Item2), ]); @@ -318,8 +302,8 @@ public sealed class RandomDesignCombo( DesignColors designColors) : DesignCombo(log, designChanged, tabSelected, config, designColors, () => [ - .. fileSystem - .Select(kvp => new Tuple(kvp.Key, kvp.Value.FullName())) + .. designs.Designs + .Select(d => new Tuple(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)) .OrderBy(d => d.Item2), ]) { @@ -345,6 +329,7 @@ public sealed class RandomDesignCombo( } public sealed class SpecialDesignCombo( + DesignManager designs, DesignFileSystem fileSystem, TabSelected tabSelected, DesignColors designColors, @@ -354,8 +339,8 @@ public sealed class SpecialDesignCombo( EphemeralConfig config, RandomDesignGenerator rng, QuickSelectedDesign quickSelectedDesign) - : DesignComboBase(() => fileSystem - .Select(kvp => new Tuple(kvp.Key, kvp.Value.FullName())) + : DesignComboBase(() => designs.Designs + .Select(d => new Tuple(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)) .OrderBy(d => d.Item2) .Prepend(new Tuple(new RandomDesign(rng), string.Empty)) .Prepend(new Tuple(quickSelectedDesign, string.Empty)) diff --git a/Glamourer/Gui/DesignQuickBar.cs b/Glamourer/Gui/DesignQuickBar.cs index e8c0ce3..5112d97 100644 --- a/Glamourer/Gui/DesignQuickBar.cs +++ b/Glamourer/Gui/DesignQuickBar.cs @@ -8,7 +8,7 @@ using Glamourer.Automation; using Glamourer.Designs; using Glamourer.Interop.Penumbra; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Classes; using OtterGui.Text; using Penumbra.GameData.Actors; @@ -19,15 +19,14 @@ namespace Glamourer.Gui; [Flags] public enum QdbButtons { - ApplyDesign = 0x01, - RevertAll = 0x02, - RevertAutomation = 0x04, - RevertAdvancedDyes = 0x08, - RevertEquip = 0x10, - RevertCustomize = 0x20, - ReapplyAutomation = 0x40, - ResetSettings = 0x80, - RevertAdvancedCustomization = 0x100, + ApplyDesign = 0x01, + RevertAll = 0x02, + RevertAutomation = 0x04, + RevertAdvanced = 0x08, + RevertEquip = 0x10, + RevertCustomize = 0x20, + ReapplyAutomation = 0x40, + ResetSettings = 0x80, } public sealed class DesignQuickBar : Window, IDisposable @@ -64,7 +63,6 @@ public sealed class DesignQuickBar : Window, IDisposable IsOpen = _config.Ephemeral.ShowDesignQuickBar; DisableWindowSounds = true; Size = Vector2.Zero; - RespectCloseHotkey = false; } public void Dispose() @@ -126,7 +124,6 @@ public sealed class DesignQuickBar : Window, IDisposable DrawRevertEquipButton(buttonSize); DrawRevertCustomizeButton(buttonSize); DrawRevertAdvancedCustomization(buttonSize); - DrawRevertAdvancedDyes(buttonSize); DrawRevertAutomationButton(buttonSize); DrawReapplyAutomationButton(buttonSize); DrawResetSettingsButton(buttonSize); @@ -321,7 +318,7 @@ public sealed class DesignQuickBar : Window, IDisposable private void DrawRevertAdvancedCustomization(Vector2 buttonSize) { - if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedCustomization)) + if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced)) return; var available = 0; @@ -330,7 +327,7 @@ public sealed class DesignQuickBar : Window, IDisposable if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid) { available |= 1; - _tooltipBuilder.Append("Left-Click: Revert the advanced customizations of the player character to their game state."); + _tooltipBuilder.Append("Left-Click: Revert the advanced customizations and dyes of the player character to their game state."); } if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) @@ -338,40 +335,7 @@ public sealed class DesignQuickBar : Window, IDisposable if (available != 0) _tooltipBuilder.Append('\n'); available |= 2; - _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 ") + _tooltipBuilder.Append("Right-Click: Revert the advanced customizations and dyes of ") .Append(_targetIdentifier) .Append(" to their game state."); } @@ -382,7 +346,7 @@ public sealed class DesignQuickBar : Window, IDisposable var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, available); ImGui.SameLine(); if (clicked) - _stateManager.ResetAdvancedDyes(state!, StateSource.Manual); + _stateManager.ResetAdvancedState(state!, StateSource.Manual); } private void DrawRevertCustomizeButton(Vector2 buttonSize) @@ -537,9 +501,7 @@ public sealed class DesignQuickBar : Window, IDisposable ++_numButtons; } - if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedCustomization)) - ++_numButtons; - if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedDyes)) + if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced)) ++_numButtons; if (_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize)) ++_numButtons; diff --git a/Glamourer/Gui/Equipment/BonusItemCombo.cs b/Glamourer/Gui/Equipment/BonusItemCombo.cs index aa43da7..892d9f1 100644 --- a/Glamourer/Gui/Equipment/BonusItemCombo.cs +++ b/Glamourer/Gui/Equipment/BonusItemCombo.cs @@ -1,7 +1,7 @@ using Dalamud.Plugin.Services; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Lumina.Excel.Sheets; using OtterGui; using OtterGui.Classes; diff --git a/Glamourer/Gui/Equipment/EquipDrawData.cs b/Glamourer/Gui/Equipment/EquipDrawData.cs index f32e22b..77f4533 100644 --- a/Glamourer/Gui/Equipment/EquipDrawData.cs +++ b/Glamourer/Gui/Equipment/EquipDrawData.cs @@ -27,9 +27,6 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData) public readonly void SetStains(StainIds stains) => _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) { var manager = (DesignManager)_editor; diff --git a/Glamourer/Gui/Equipment/EquipItemSlotCache.cs b/Glamourer/Gui/Equipment/EquipItemSlotCache.cs deleted file mode 100644 index 20aaf11..0000000 --- a/Glamourer/Gui/Equipment/EquipItemSlotCache.cs +++ /dev/null @@ -1,83 +0,0 @@ -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)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; - } -} diff --git a/Glamourer/Gui/Equipment/EquipmentDrawer.cs b/Glamourer/Gui/Equipment/EquipmentDrawer.cs index 01ec938..0d2e8dc 100644 --- a/Glamourer/Gui/Equipment/EquipmentDrawer.cs +++ b/Glamourer/Gui/Equipment/EquipmentDrawer.cs @@ -3,15 +3,16 @@ using Dalamud.Interface.Utility; using Dalamud.Plugin.Services; using Glamourer.Events; using Glamourer.Gui.Materials; +using Glamourer.Interop.Material; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; +using OtterGui; using OtterGui.Extensions; using OtterGui.Raii; using OtterGui.Text; using OtterGui.Text.EndObjects; using OtterGui.Widgets; -using Penumbra.GameData.Data; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -32,24 +33,20 @@ public class EquipmentDrawer private readonly Configuration _config; private readonly GPoseService _gPose; private readonly AdvancedDyePopup _advancedDyes; - private readonly ItemCopyService _itemCopy; private float _requiredComboWidthUnscaled; private float _requiredComboWidth; - private Stain? _draggedStain; - private EquipItemSlotCache _draggedItem; - private EquipSlot _dragTarget; + private Stain? _draggedStain; public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, TextureService textures, - Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes, ItemCopyService itemCopy) + Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes) { _items = items; _textures = textures; _config = config; _gPose = gPose; _advancedDyes = advancedDyes; - _itemCopy = itemCopy; _stainData = items.Stains; _stainCombo = new GlamourerColorCombo(DefaultWidth - 20, _stainData, favorites); _itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, Glamourer.Log, favorites)).ToArray(); @@ -82,7 +79,6 @@ public class EquipmentDrawer _requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale; _advancedMaterialColor = ColorId.AdvancedDyeActive.Value(); - _dragTarget = EquipSlot.Unknown; } private bool VerifyRestrictedGear(EquipDrawData data) @@ -188,7 +184,6 @@ public class EquipmentDrawer return change; } - #region Small private void DrawEquipSmall(in EquipDrawData equipDrawData) @@ -407,7 +402,6 @@ 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, width); - _itemCopy.HandleCopyPaste(data, index); if (!change) DrawStainDragDrop(data, index, stain, found); @@ -432,8 +426,8 @@ public class EquipmentDrawer using var dragSource = ImUtf8.DragDropSource(); if (dragSource.Success) { - DragDropSource.SetPayload("stainDragDrop"u8); - _draggedStain = stain; + if (DragDropSource.SetPayload("stainDragDrop"u8)) + _draggedStain = stain; ImUtf8.Text($"Dragging {stain.Name}..."); } } @@ -458,12 +452,10 @@ public class EquipmentDrawer using var disabled = ImRaii.Disabled(data.Locked); var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, _requiredComboWidth); - DrawGearDragDrop(data); if (change) data.SetItem(combo.CurrentSelection); else if (combo.CustomVariant.Id > 0) 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), out var item)) @@ -481,14 +473,6 @@ public class EquipmentDrawer var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, _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) data.SetItem(combo.CurrentSelection); else if (combo.CustomVariant.Id > 0) @@ -499,50 +483,6 @@ public class EquipmentDrawer 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(bool locked, bool clicked, bool allowRevert, bool allowClear, in T currentItem, in T revertItem, in T clearItem, out T? item) where T : IEquatable { @@ -591,13 +531,8 @@ public class EquipmentDrawer if (combo.Draw(mainhand.CurrentItem.Name, mainhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, _requiredComboWidth)) changedItem = combo.CurrentSelection; - else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type)) - 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)) + else if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem, + default, out var c)) changedItem = c; if (changedItem != null) @@ -614,8 +549,7 @@ public class EquipmentDrawer } 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) @@ -635,10 +569,6 @@ public class EquipmentDrawer if (combo.Draw(offhand.CurrentItem.Name, offhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, _requiredComboWidth)) 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); if (ResetOrClear(locked, clear, offhand.AllowRevert, true, offhand.CurrentItem, offhand.GameItem, defaultOffhand, out var item)) @@ -693,7 +623,6 @@ public class EquipmentDrawer { ImUtf8.Text(label); } - if (hasAdvancedDyes) ImUtf8.HoverTooltip("This design has advanced dyes setup for this slot."u8); } diff --git a/Glamourer/Gui/Equipment/GlamourerColorCombo.cs b/Glamourer/Gui/Equipment/GlamourerColorCombo.cs index 3149e67..527dbb5 100644 --- a/Glamourer/Gui/Equipment/GlamourerColorCombo.cs +++ b/Glamourer/Gui/Equipment/GlamourerColorCombo.cs @@ -2,7 +2,7 @@ using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Widgets; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Structs; diff --git a/Glamourer/Gui/Equipment/ItemCombo.cs b/Glamourer/Gui/Equipment/ItemCombo.cs index 7c0c3bc..14f2e8a 100644 --- a/Glamourer/Gui/Equipment/ItemCombo.cs +++ b/Glamourer/Gui/Equipment/ItemCombo.cs @@ -1,7 +1,7 @@ using Dalamud.Plugin.Services; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Lumina.Excel.Sheets; using OtterGui.Classes; using OtterGui.Extensions; diff --git a/Glamourer/Gui/Equipment/ItemCopyService.cs b/Glamourer/Gui/Equipment/ItemCopyService.cs deleted file mode 100644 index 6912f1f..0000000 --- a/Glamourer/Gui/Equipment/ItemCopyService.cs +++ /dev/null @@ -1,73 +0,0 @@ -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 setter) - { - if (Stain is { } stain) - setter(which, stain.RowIndex); - } - - public void Paste(FullEquipType type, Action 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); - } - } -} diff --git a/Glamourer/Gui/Equipment/WeaponCombo.cs b/Glamourer/Gui/Equipment/WeaponCombo.cs index 3029db7..e96f721 100644 --- a/Glamourer/Gui/Equipment/WeaponCombo.cs +++ b/Glamourer/Gui/Equipment/WeaponCombo.cs @@ -1,6 +1,7 @@ using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; +using OtterGui; using OtterGui.Classes; using OtterGui.Extensions; using OtterGui.Log; @@ -19,10 +20,6 @@ public sealed class WeaponCombo : FilterComboCache private ItemId _currentItem; 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) : base(() => GetWeapons(favorites, items, type), MouseWheelType.Control, log) { @@ -50,9 +47,8 @@ public sealed class WeaponCombo : FilterComboCache public bool Draw(string previewName, ItemId previewIdx, float width, float innerWidth) { - _innerWidth = innerWidth; - _currentItem = previewIdx; - CustomVariant = 0; + _innerWidth = innerWidth; + _currentItem = previewIdx; return Draw($"##{Label}", previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing()); } @@ -79,24 +75,6 @@ public sealed class WeaponCombo : FilterComboCache 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) => base.IsVisible(globalIndex, filter) || Items[globalIndex].ModelString.StartsWith(filter.Lower); diff --git a/Glamourer/Gui/GenericPopupWindow.cs b/Glamourer/Gui/GenericPopupWindow.cs index 5061862..502af14 100644 --- a/Glamourer/Gui/GenericPopupWindow.cs +++ b/Glamourer/Gui/GenericPopupWindow.cs @@ -3,7 +3,7 @@ using Dalamud.Interface.Utility; using Dalamud.Interface.Windowing; using Dalamud.Plugin.Services; using Glamourer.Gui.Materials; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; diff --git a/Glamourer/Gui/GlamourerChangelog.cs b/Glamourer/Gui/GlamourerChangelog.cs index 686d4a1..e12b32e 100644 --- a/Glamourer/Gui/GlamourerChangelog.cs +++ b/Glamourer/Gui/GlamourerChangelog.cs @@ -42,9 +42,6 @@ public class GlamourerChangelog Add1_3_6_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() @@ -65,54 +62,6 @@ 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.") diff --git a/Glamourer/Gui/MainWindow.cs b/Glamourer/Gui/MainWindow.cs index a39db2e..f21a2b7 100644 --- a/Glamourer/Gui/MainWindow.cs +++ b/Glamourer/Gui/MainWindow.cs @@ -12,7 +12,7 @@ using Glamourer.Gui.Tabs.NpcTab; using Glamourer.Gui.Tabs.SettingsTab; using Glamourer.Gui.Tabs.UnlocksTab; using Glamourer.Interop.Penumbra; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Custom; diff --git a/Glamourer/Gui/Materials/AdvancedDyePopup.cs b/Glamourer/Gui/Materials/AdvancedDyePopup.cs index 4499107..ec25378 100644 --- a/Glamourer/Gui/Materials/AdvancedDyePopup.cs +++ b/Glamourer/Gui/Materials/AdvancedDyePopup.cs @@ -8,7 +8,7 @@ using FFXIVClientStructs.Interop; using Glamourer.Designs; using Glamourer.Interop.Material; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui.Services; using OtterGui.Text; @@ -91,7 +91,7 @@ public sealed unsafe class AdvancedDyePopup( var modelHandle = model == null ? null : model->ModelResourceHandle; var path = materialHandle == null ? string.Empty - : ByteString.FromSpanUnsafe(materialHandle->FileName.AsSpan(), true).ToString(); + : ByteString.FromSpanUnsafe(materialHandle->ResourceHandle.FileName.AsSpan(), true).ToString(); var gamePath = modelHandle == null ? string.Empty : modelHandle->GetMaterialFileNameBySlot(index.MaterialIndex).ToString(); diff --git a/Glamourer/Gui/Materials/MaterialDrawer.cs b/Glamourer/Gui/Materials/MaterialDrawer.cs index 7c16372..0c4433d 100644 --- a/Glamourer/Gui/Materials/MaterialDrawer.cs +++ b/Glamourer/Gui/Materials/MaterialDrawer.cs @@ -3,7 +3,7 @@ using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Glamourer.Designs; using Glamourer.Interop.Material; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Services; using OtterGui.Text; @@ -18,6 +18,7 @@ public class MaterialDrawer(DesignManager _designManager, Configuration _config) public const float GlossWidth = 100; public const float SpecularStrengthWidth = 125; + private EquipSlot _newSlot = EquipSlot.Head; private int _newMaterialIdx; private int _newRowIdx; private MaterialValueIndex _newKey = MaterialValueIndex.FromSlot(EquipSlot.Head); @@ -177,42 +178,14 @@ public class MaterialDrawer(DesignManager _designManager, Configuration _config) 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) { - DrawSlotCombo(); + if (EquipSlotCombo.Draw("##slot", "Choose a slot for an advanced dye row.", ref _newSlot)) + _newKey = MaterialValueIndex.FromSlot(_newSlot) with + { + MaterialIndex = (byte)_newMaterialIdx, + RowIndex = (byte)_newRowIdx, + }; ImUtf8.SameLineInner(); DrawMaterialIdxDrag(); ImUtf8.SameLineInner(); diff --git a/Glamourer/Gui/PenumbraChangedItemTooltip.cs b/Glamourer/Gui/PenumbraChangedItemTooltip.cs index dff9a6e..1723333 100644 --- a/Glamourer/Gui/PenumbraChangedItemTooltip.cs +++ b/Glamourer/Gui/PenumbraChangedItemTooltip.cs @@ -3,7 +3,7 @@ using Glamourer.Events; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using Penumbra.Api.Enums; using Penumbra.GameData.Data; @@ -22,12 +22,11 @@ public sealed class PenumbraChangedItemTooltip : IDisposable private readonly CustomizeService _customize; private readonly GPoseService _gpose; - private readonly EquipItem[] _lastItems = new EquipItem[EquipFlagExtensions.NumEquipFlags / 2 + BonusExtensions.AllFlags.Count]; + private readonly EquipItem[] _lastItems = new EquipItem[EquipFlagExtensions.NumEquipFlags / 2]; - public IEnumerable> LastItems - => EquipSlotExtensions.EqdpSlots.Cast().Append(EquipSlot.MainHand).Append(EquipSlot.OffHand) - .Concat(BonusExtensions.AllFlags.Cast()).Zip(_lastItems) - .Select(p => new KeyValuePair(p.First, p.Second)); + public IEnumerable> LastItems + => EquipSlotExtensions.EqdpSlots.Append(EquipSlot.MainHand).Append(EquipSlot.OffHand).Zip(_lastItems) + .Select(p => new KeyValuePair(p.First, p.Second)); public ChangedItemType LastType { get; private set; } = ChangedItemType.None; public uint LastId { get; private set; } @@ -73,21 +72,6 @@ public sealed class PenumbraChangedItemTooltip : IDisposable if (!Player()) 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 last = _lastItems[slot.ToIndex()]; switch (slot) @@ -125,27 +109,6 @@ public sealed class PenumbraChangedItemTooltip : IDisposable 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 last = _lastItems[slot.ToIndex()]; switch (slot) @@ -302,22 +265,7 @@ public sealed class PenumbraChangedItemTooltip : IDisposable { var oldItem = state.ModelData.Item(slot); if (oldItem.Id != item.Id) - 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; + _lastItems[slot.ToIndex()] = oldItem; } } diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs index 224154b..5419f23 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs @@ -11,7 +11,7 @@ using Glamourer.Gui.Equipment; using Glamourer.Gui.Materials; using Glamourer.Interop; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Raii; @@ -238,7 +238,6 @@ public class ActorPanel ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2)); DrawEquipmentMetaToggles(); ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2)); - _equipmentDrawer.DrawDragDropTooltip(); } private void DrawParameterHeader() @@ -305,12 +304,6 @@ public class ActorPanel EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(MetaIndex.WeaponState, _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() diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs b/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs index 7d132a1..e46d651 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorSelector.cs @@ -1,5 +1,5 @@ using Dalamud.Interface; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorTab.cs b/Glamourer/Gui/Tabs/ActorTab/ActorTab.cs index 9751a71..4e5e15c 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorTab.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorTab.cs @@ -1,5 +1,5 @@ using Dalamud.Interface.Utility; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Widgets; namespace Glamourer.Gui.Tabs.ActorTab; diff --git a/Glamourer/Gui/Tabs/AutomationTab/AutomationTab.cs b/Glamourer/Gui/Tabs/AutomationTab/AutomationTab.cs index da3b636..831ee7c 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/AutomationTab.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/AutomationTab.cs @@ -1,5 +1,5 @@ using Dalamud.Interface.Utility; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Widgets; namespace Glamourer.Gui.Tabs.AutomationTab; diff --git a/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs b/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs index 1d3e711..8a08437 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs @@ -1,12 +1,12 @@ using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Utility; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; +using OtterGui.Custom; using OtterGui.Extensions; using OtterGui.Log; using OtterGui.Widgets; using Penumbra.GameData.DataContainers; -using OtterGui.Custom; namespace Glamourer.Gui.Tabs.AutomationTab; diff --git a/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs b/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs index ba2e424..b197a1a 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs @@ -1,5 +1,5 @@ using Dalamud.Game.ClientState.Objects.Enums; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Penumbra.GameData.Actors; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Gui; diff --git a/Glamourer/Gui/Tabs/AutomationTab/RandomRestrictionDrawer.cs b/Glamourer/Gui/Tabs/AutomationTab/RandomRestrictionDrawer.cs index 8eba59b..e7efc09 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/RandomRestrictionDrawer.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/RandomRestrictionDrawer.cs @@ -4,7 +4,7 @@ using Glamourer.Automation; using Glamourer.Designs; using Glamourer.Designs.Special; using Glamourer.Events; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Services; @@ -278,7 +278,7 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable private void LookupTooltip(IEnumerable designs) { using var _ = ImRaii.Tooltip(); - var tt = string.Join('\n', designs.Select(d => _designFileSystem.TryGetValue(d, out var l) ? l.FullName() : d.Name.Text).OrderBy(t => t)); + var tt = string.Join('\n', designs.Select(d => _designFileSystem.FindLeaf(d, out var l) ? l.FullName() : d.Name.Text).OrderBy(t => t)); ImGui.TextUnformatted(tt.Length == 0 ? "Matches no currently existing designs." : "Matches the following designs:"); diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs index 8a85a45..1600837 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs @@ -6,7 +6,7 @@ using Glamourer.Designs.Special; using Glamourer.Interop; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; using OtterGui.Log; @@ -432,7 +432,7 @@ public class SetPanel( if (source) { ImUtf8.Text($"Moving design #{index + 1:D2}..."); - if (ImGui.SetDragDropPayload(dragDropLabel, null, 0)) + if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) { _dragIndex = index; _selector.DragDesignIndex = index; diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs b/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs index 8a235ae..96730e8 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs @@ -2,7 +2,7 @@ using Dalamud.Interface.Utility; using Glamourer.Automation; using Glamourer.Events; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Extensions; @@ -144,7 +144,7 @@ public class SetSelector : IDisposable ImGui.SameLine(); var f = _enabledFilter; - if (ImGui.CheckboxFlags("##enabledFilter", ref f, 3u)) + if (ImGui.CheckboxFlags("##enabledFilter", ref f, 3)) { _enabledFilter = _enabledFilter switch { @@ -347,7 +347,7 @@ public class SetSelector : IDisposable if (source) { ImGui.TextUnformatted($"Moving design set {GetSetName(set, index)} from position {index + 1}..."); - if (ImGui.SetDragDropPayload(dragDropLabel, null, 0)) + if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) _dragIndex = index; } } diff --git a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs index 35642a7..b4bdc2a 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs @@ -2,7 +2,7 @@ using Glamourer.GameData; using Glamourer.Designs; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; @@ -87,9 +87,6 @@ public class ActiveStatePanel(StateManager _stateManager, ActorObjectManager _ob PrintRow("Visor Toggled", state.BaseData.IsVisorToggled(), state.ModelData.IsVisorToggled(), state.Sources[MetaIndex.VisorState]); 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(), state.Sources[MetaIndex.WeaponState]); ImGui.TableNextRow(); diff --git a/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs b/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs index 2202ceb..5a02621 100644 --- a/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs +++ b/Glamourer/Gui/Tabs/DebugTab/AdvancedCustomizationDrawer.cs @@ -1,5 +1,5 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Gui.Debug; diff --git a/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs b/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs index aee59b6..df39f45 100644 --- a/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/AutoDesignPanel.cs @@ -1,5 +1,5 @@ using Glamourer.Automation; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs index 6c0995c..565b6ba 100644 --- a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs @@ -1,7 +1,7 @@ using Dalamud.Interface; using Glamourer.GameData; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Text; diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs index 4bf7d7b..a53a677 100644 --- a/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs @@ -1,5 +1,5 @@ using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; diff --git a/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs b/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs index 7c61392..11f27fd 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs @@ -1,5 +1,5 @@ using Glamourer.Interop; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using Penumbra.GameData.Files; using Penumbra.GameData.Gui.Debug; diff --git a/Glamourer/Gui/Tabs/DebugTab/DebugTab.cs b/Glamourer/Gui/Tabs/DebugTab/DebugTab.cs index b760221..cd89aec 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DebugTab.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DebugTab.cs @@ -1,4 +1,4 @@ -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui.Services; using OtterGui.Widgets; diff --git a/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs b/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs index 3df425f..90282e8 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DebugTabHeader.cs @@ -1,4 +1,5 @@ using Glamourer.Gui.Tabs.DebugTab.IpcTester; +using ImGuiNET; using Microsoft.Extensions.DependencyInjection; using OtterGui.Raii; using Penumbra.GameData.Gui.Debug; @@ -35,7 +36,6 @@ public class DebugTabHeader(string label, params IGameDataDrawer[] subTrees) provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), - provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs index 287d373..2345abc 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DesignConverterPanel.cs @@ -1,7 +1,7 @@ using Dalamud.Interface; using Glamourer.Designs; using Glamourer.Utility; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Newtonsoft.Json.Linq; using OtterGui; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs index 7c60dda..ede3e9e 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs @@ -1,11 +1,9 @@ using Dalamud.Interface; using Glamourer.Designs; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; -using OtterGui.Filesystem; using OtterGui.Raii; -using OtterGui.Text; using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; @@ -21,7 +19,6 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _ public void Draw() { - DrawButtons(); foreach (var (design, idx) in _designManager.Designs.WithIndex()) { using var t = ImRaii.TreeNode($"{design.Name}##{idx}"); @@ -29,8 +26,7 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _ continue; 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()); using var font = ImRaii.PushFont(UiBuilder.MonoFont); ImGuiUtil.TextWrapped(base64); @@ -39,26 +35,6 @@ 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) { using var table = ImRaii.Table("##equip", 8, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit); @@ -77,7 +53,7 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _ ImGui.TableNextRow(); ImGuiUtil.DrawTableColumn("Design File System Path"); if (fileSystem != null) - ImGuiUtil.DrawTableColumn(fileSystem.TryGetValue(d, out var leaf) ? leaf.FullName() : "No Path Known"); + ImGuiUtil.DrawTableColumn(fileSystem.FindLeaf(d, out var leaf) ? leaf.FullName() : "No Path Known"); ImGui.TableNextRow(); ImGuiUtil.DrawTableColumn("Creation"); @@ -114,7 +90,6 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _ ImGuiUtil.DrawTableColumn(index.ToName()); ImGuiUtil.DrawTableColumn(design.DesignData.GetMeta(index).ToString()); ImGuiUtil.DrawTableColumn(design.DoApplyMeta(index) ? "Apply" : "Keep"); - ImGui.TableNextRow(); } ImGuiUtil.DrawTableColumn("Model ID"); diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs index cf45077..26be8ce 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs @@ -1,7 +1,7 @@ using Dalamud.Interface; using Glamourer.Designs; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/DebugTab/DynamisPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DynamisPanel.cs deleted file mode 100644 index 92cd777..0000000 --- a/Glamourer/Gui/Tabs/DebugTab/DynamisPanel.cs +++ /dev/null @@ -1,16 +0,0 @@ -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; -} diff --git a/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs b/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs index 370c4e5..c517070 100644 --- a/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/FunPanel.cs @@ -1,5 +1,5 @@ using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Penumbra.GameData.Gui.Debug; namespace Glamourer.Gui.Tabs.DebugTab; diff --git a/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs index f480f6d..aafc21a 100644 --- a/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/GlamourPlatePanel.cs @@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.Game; using Glamourer.Designs; using Glamourer.Services; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; using OtterGui.Text; diff --git a/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs b/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs index ca9ff7b..f57a57e 100644 --- a/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/InventoryPanel.cs @@ -1,5 +1,5 @@ using FFXIVClientStructs.FFXIV.Client.Game; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Gui.Debug; diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs index 8cbf57a..918c7ad 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/DesignIpcTester.cs @@ -3,11 +3,10 @@ using Dalamud.Interface.Utility; using Dalamud.Plugin; using Glamourer.Api.Enums; using Glamourer.Api.IpcSubscribers; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Services; -using OtterGui.Text; namespace Glamourer.Gui.Tabs.DebugTab.IpcTester; @@ -16,7 +15,6 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi private Dictionary _designs = []; private int _gameObjectIndex; private string _gameObjectName = string.Empty; - private string _designName = string.Empty; private uint _key; private ApplyFlag _flags = ApplyFlagEx.DesignDefault; private Guid? _design; @@ -32,7 +30,6 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi IpcTesterHelpers.IndexInput(ref _gameObjectIndex); IpcTesterHelpers.KeyInput(ref _key); IpcTesterHelpers.NameInput(ref _gameObjectName); - ImUtf8.InputText("##designName"u8, ref _designName, "Design Name..."u8); ImGuiUtil.GuidInput("##identifier", "Design Identifier...", string.Empty, ref _design, ref _designText, ImGui.GetContentRegionAvail().X); IpcTesterHelpers.DrawFlagInput(ref _flags); @@ -57,48 +54,6 @@ public class DesignIpcTester(IDalamudPluginInterface pluginInterface) : IUiServi IpcTesterHelpers.DrawIntro(ApplyDesignName.Label); if (ImGuiUtil.DrawDisabledButton("Apply##Name", Vector2.Zero, string.Empty, !_design.HasValue)) _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() diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterHelpers.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterHelpers.cs index dbcb30c..500fddd 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterHelpers.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterHelpers.cs @@ -1,6 +1,6 @@ using Glamourer.Api.Enums; using Glamourer.Designs; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using static Penumbra.GameData.Files.ShpkFile; diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterPanel.cs index f4e6925..1a78b24 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/IpcTesterPanel.cs @@ -1,7 +1,7 @@ using Dalamud.Plugin; using Dalamud.Plugin.Services; using Glamourer.Api.IpcSubscribers; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Penumbra.GameData.Gui.Debug; namespace Glamourer.Gui.Tabs.DebugTab.IpcTester; diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/ItemsIpcTester.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/ItemsIpcTester.cs index ea95a9d..1499fcb 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/ItemsIpcTester.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/ItemsIpcTester.cs @@ -1,7 +1,7 @@ using Dalamud.Plugin; using Glamourer.Api.Enums; using Glamourer.Api.IpcSubscribers; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Services; diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs index e97d337..638bffc 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs @@ -5,7 +5,7 @@ using Glamourer.Api.Enums; using Glamourer.Api.Helpers; using Glamourer.Api.IpcSubscribers; using Glamourer.Designs; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; diff --git a/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs index f82bfb3..afbb86b 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ItemUnlockPanel.cs @@ -1,7 +1,7 @@ using Dalamud.Interface.Utility; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; diff --git a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs index 185e19b..fc4799f 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs @@ -2,7 +2,7 @@ using Glamourer.GameData; using Glamourer.Interop; using Glamourer.Interop.Structs; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Text; @@ -17,7 +17,6 @@ namespace Glamourer.Gui.Tabs.DebugTab; public unsafe class ModelEvaluationPanel( ActorObjectManager _objectManager, VisorService _visorService, - VieraEarService _vieraEarService, UpdateSlotService _updateSlotService, ChangeCustomizeService _changeCustomizeService, CrestService _crestService, @@ -46,10 +45,9 @@ public unsafe class ModelEvaluationPanel( ImGuiUtil.DrawTableColumn("Address"); ImGui.TableNextColumn(); - - Glamourer.Dynamis.DrawPointer(actor); + ImGuiUtil.CopyOnClickSelectable(actor.ToString()); ImGui.TableNextColumn(); - Glamourer.Dynamis.DrawPointer(model); + ImGuiUtil.CopyOnClickSelectable(model.ToString()); ImGui.TableNextColumn(); if (actor.IsCharacter) { @@ -85,7 +83,6 @@ public unsafe class ModelEvaluationPanel( ImGuiUtil.CopyOnClickSelectable(offhand.ToString()); DrawVisor(actor, model); - DrawVieraEars(actor, model); DrawHatState(actor, model); DrawWeaponState(actor, model); DrawWetness(actor, model); @@ -137,26 +134,6 @@ public unsafe class ModelEvaluationPanel( _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) { using var id = ImRaii.PushId("HatState"); diff --git a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs index 0d93bb8..966bc6f 100644 --- a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs @@ -4,7 +4,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Object; using Glamourer.Designs; using Glamourer.GameData; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Enums; diff --git a/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs index 97847ae..a4d1224 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ObjectManagerPanel.cs @@ -1,4 +1,4 @@ -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Text; using Penumbra.GameData.Actors; diff --git a/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs b/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs index 833ebe4..3714c82 100644 --- a/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs @@ -1,6 +1,6 @@ using Dalamud.Interface.Utility; using Glamourer.Interop.Penumbra; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.Api.Enums; @@ -49,7 +49,7 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem ImGui.TableNextColumn(); var address = _drawObject.Address; ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale); - if (ImGui.InputScalar("##drawObjectPtr", ImGuiDataType.U64, ref address, nint.Zero, nint.Zero, "%llx", + if (ImGui.InputScalar("##drawObjectPtr", ImGuiDataType.U64, (nint)(&address), nint.Zero, nint.Zero, "%llx", ImGuiInputTextFlags.CharsHexadecimal)) _drawObject = address; ImGuiUtil.DrawTableColumn(_penumbra.Available @@ -61,7 +61,7 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale); ImGui.InputInt("##CutsceneIndex", ref _gameObjectIndex, 0, 0); ImGuiUtil.DrawTableColumn(_penumbra.Available - ? _penumbra.CutsceneParent((ushort)_gameObjectIndex).ToString() + ? _penumbra.CutsceneParent((ushort) _gameObjectIndex).ToString() : "Penumbra Unavailable"); ImGuiUtil.DrawTableColumn("Redraw Object"); @@ -76,9 +76,7 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem } 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(); ImGuiUtil.DrawTableColumn("Last Click Date"); @@ -89,13 +87,7 @@ public unsafe class PenumbraPanel(PenumbraService _penumbra, PenumbraChangedItem ImGui.Separator(); foreach (var (slot, item) in _penumbraTooltip.LastItems) { - 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($"{slot.ToName()} Revert-Item"); ImGuiUtil.DrawTableColumn(item.Valid ? item.Name : "None"); ImGui.TableNextColumn(); } diff --git a/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs b/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs index b22008d..99c79ed 100644 --- a/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/UnlockableItemsPanel.cs @@ -1,7 +1,7 @@ using Dalamud.Interface.Utility; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignColorCombo.cs b/Glamourer/Gui/Tabs/DesignTab/DesignColorCombo.cs index e9fe775..9444ff7 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignColorCombo.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignColorCombo.cs @@ -1,6 +1,7 @@ using Glamourer.Designs; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; +using OtterGui.Extensions; using OtterGui.Raii; using OtterGui.Widgets; @@ -12,6 +13,13 @@ public sealed class DesignColorCombo(DesignColors _designColors, bool _skipAutom : _designColors.Keys.OrderBy(k => k).Prepend(DesignColors.AutomaticName), 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) { var isAutomatic = !_skipAutomatic && globalIdx == 0; diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignDetailTab.cs b/Glamourer/Gui/Tabs/DesignTab/DesignDetailTab.cs index 8a3dd06..cbf7acd 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignDetailTab.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignDetailTab.cs @@ -2,7 +2,7 @@ using Dalamud.Interface.ImGuiNotification; using Glamourer.Designs; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Raii; @@ -189,7 +189,10 @@ public class DesignDetailTab else if (_selector.Selected!.Color.Length != 0) { ImGui.SameLine(); - ImUtf8.Icon(FontAwesomeIcon.ExclamationCircle, "The color associated with this design does not exist."u8, _colors.MissingColor); + var size = new Vector2(ImGui.GetFrameHeight()); + 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); diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs b/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs index e0e4543..ea117c5 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs @@ -5,14 +5,13 @@ using Glamourer.Designs; using Glamourer.Designs.History; using Glamourer.Events; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Filesystem; using OtterGui.FileSystem.Selector; using OtterGui.Log; using OtterGui.Raii; -using OtterGui.Text; namespace Glamourer.Gui.Tabs.DesignTab; @@ -46,29 +45,6 @@ public sealed class DesignFileSystemSelector : FileSystemSelector _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, Configuration config, DesignConverter converter, TabSelected selectionEvent, Logger log, DesignColors designColors, DesignApplier designApplier) @@ -175,7 +151,7 @@ public sealed class DesignFileSystemSelector : FileSystemSelector slots) @@ -315,9 +310,6 @@ public class DesignPanel ImUtf8.IconDummy(); DrawParameterApplication(); - - ImUtf8.IconDummy(); - DrawBonusSlotApplication(); } } @@ -326,7 +318,7 @@ public class DesignPanel var enabled = _config.DeleteDesignModifier.IsActive(); bool? equip = null; bool? customize = null; - var size = new Vector2(210 * ImUtf8.GlobalScale, 0); + var size = new Vector2(200 * ImUtf8.GlobalScale, 0); if (ImUtf8.ButtonEx("Disable Everything"u8, "Disable application of everything, including any existing advanced dyes, advanced customizations, crests and wetness."u8, size, !enabled)) @@ -404,7 +396,6 @@ public class DesignPanel _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.HatState, equip.Value); _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.VisorState, equip.Value); _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.WeaponState, equip.Value); - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.EarState, equip.Value); } if (customize.HasValue) @@ -417,7 +408,6 @@ public class DesignPanel "Apply Hat Visibility", "Apply Visor State", "Apply Weapon Visibility", - "Apply Viera Ear Visibility", ]; private void DrawMetaApplication() diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignTab.cs b/Glamourer/Gui/Tabs/DesignTab/DesignTab.cs index 1b92291..9832451 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignTab.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignTab.cs @@ -2,7 +2,7 @@ using Dalamud.Interface.Utility; using Glamourer.Designs; using Glamourer.Interop; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Classes; using OtterGui.Widgets; @@ -16,7 +16,7 @@ public class DesignTab(DesignFileSystemSelector _selector, DesignPanel _panel, I public void DrawContent() { - _selector.Draw(); + _selector.Draw(GetDesignSelectorSize()); if (_importService.CreateCharaTarget(out var designBase, out var name)) { var newDesign = _manager.CreateClone(designBase, name, true); @@ -27,4 +27,7 @@ public class DesignTab(DesignFileSystemSelector _selector, DesignPanel _panel, I _panel.Draw(); _importService.CreateCharaSource(); } + + public float GetDesignSelectorSize() + => 200f * ImGuiHelpers.GlobalScale; } diff --git a/Glamourer/Gui/Tabs/DesignTab/ModAssociationsTab.cs b/Glamourer/Gui/Tabs/DesignTab/ModAssociationsTab.cs index 587fe65..bab25f0 100644 --- a/Glamourer/Gui/Tabs/DesignTab/ModAssociationsTab.cs +++ b/Glamourer/Gui/Tabs/DesignTab/ModAssociationsTab.cs @@ -5,7 +5,7 @@ using Dalamud.Utility; using Glamourer.Designs; using Glamourer.Interop.Penumbra; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Extensions; @@ -71,8 +71,6 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect private void DrawApplyAllButton() { var (id, name) = penumbra.CurrentCollection; - if (config.Ephemeral.IncognitoMode) - name = id.ShortGuid(); if (ImGuiUtil.DrawDisabledButton($"Try Applying All Associated Mods to {name}##applyAll", new Vector2(ImGui.GetContentRegionAvail().X, 0), string.Empty, id == Guid.Empty)) ApplyAll(); diff --git a/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs b/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs index 76579c2..6ec9a1c 100644 --- a/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs +++ b/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs @@ -1,6 +1,6 @@ using Dalamud.Interface.Utility; using Glamourer.Interop.Penumbra; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Classes; using OtterGui.Log; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs b/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs index a68c191..3567fb6 100644 --- a/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs +++ b/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs @@ -2,7 +2,8 @@ using Dalamud.Interface.Utility; using Glamourer.Designs; using Glamourer.Interop.Material; -using Dalamud.Bindings.ImGui; +using ImGuiNET; +using OtterGui; using OtterGui.Extensions; using OtterGui.Raii; using OtterGui.Text; @@ -10,11 +11,7 @@ using static Glamourer.Gui.Tabs.HeaderDrawer; namespace Glamourer.Gui.Tabs.DesignTab; -public class MultiDesignPanel( - DesignFileSystemSelector selector, - DesignManager editor, - DesignColors colors, - Configuration config) +public class MultiDesignPanel(DesignFileSystemSelector selector, DesignManager editor, DesignColors colors, Configuration config) { private readonly Button[] _leftButtons = []; private readonly Button[] _rightButtons = [new IncognitoButton(config)]; @@ -204,21 +201,16 @@ public class MultiDesignPanel( ? $"All {_numDesigns} selected designs are already displayed in the quick design bar." : $"Display all {_numDesigns} selected designs in the quick design bar. Changes {diff} designs."; if (ImUtf8.ButtonEx("Display Selected Designs in QDB"u8, tt, buttonWidth, diff == 0)) - { foreach (var design in selector.SelectedPaths.OfType()) editor.SetQuickDesign(design.Value, true); - } ImGui.SameLine(); tt = _numQuickDesignEnabled == 0 ? $"All {_numDesigns} selected designs are already hidden in the quick design bar." : $"Hide all {_numDesigns} selected designs in the quick design bar. Changes {_numQuickDesignEnabled} designs."; if (ImUtf8.ButtonEx("Hide Selected Designs in QDB"u8, tt, buttonWidth, _numQuickDesignEnabled == 0)) - { foreach (var design in selector.SelectedPaths.OfType()) editor.SetQuickDesign(design.Value, false); - } - ImGui.Separator(); } @@ -335,10 +327,8 @@ public class MultiDesignPanel( : $"Set the color of {_addDesigns.Count} designs to \"{_colorCombo.CurrentSelection}\"\n\n\t{string.Join("\n\t", _addDesigns.Select(m => m.Name.Text))}"; ImGui.SameLine(); if (ImUtf8.ButtonEx(label, tooltip, width, _addDesigns.Count == 0)) - { foreach (var design in _addDesigns) editor.ChangeColor(design, _colorCombo.CurrentSelection!); - } label = _removeDesigns.Count > 0 ? $"Unset {_removeDesigns.Count} Designs" @@ -348,10 +338,8 @@ public class MultiDesignPanel( : $"Set {_removeDesigns.Count} designs to use automatic color again:\n\n\t{string.Join("\n\t", _removeDesigns.Select(m => m.Item1.Name.Text))}"; ImGui.SameLine(); if (ImUtf8.ButtonEx(label, tooltip, width, _removeDesigns.Count == 0)) - { foreach (var (design, _) in _removeDesigns) editor.ChangeColor(design, string.Empty); - } ImGui.Separator(); } @@ -467,8 +455,7 @@ public class MultiDesignPanel( foreach (var design in selector.SelectedPaths.OfType().Select(l => l.Value)) { - editor.ChangeApplyMulti(design, equip, customize, equip, customize.HasValue && !customize.Value ? false : null, null, equip, equip, - equip); + editor.ChangeApplyMulti(design, equip, customize, equip, customize.HasValue && !customize.Value ? false : null, null, equip, equip, equip); if (equip.HasValue) { editor.ChangeApplyMeta(design, MetaIndex.HatState, equip.Value); @@ -490,7 +477,7 @@ public class MultiDesignPanel( foreach (var leaf in selector.SelectedPaths.OfType()) { - var index = leaf.Value.Tags.AsEnumerable().IndexOf(_tag); + var index = leaf.Value.Tags.IndexOf(_tag); if (index >= 0) _removeDesigns.Add((leaf.Value, index)); else diff --git a/Glamourer/Gui/Tabs/HeaderDrawer.cs b/Glamourer/Gui/Tabs/HeaderDrawer.cs index cb169ba..d6baeb9 100644 --- a/Glamourer/Gui/Tabs/HeaderDrawer.cs +++ b/Glamourer/Gui/Tabs/HeaderDrawer.cs @@ -1,6 +1,6 @@ using Dalamud.Interface; using Dalamud.Interface.Utility; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/NpcTab/LocalNpcAppearanceData.cs b/Glamourer/Gui/Tabs/NpcTab/LocalNpcAppearanceData.cs index 1b70e27..7941c13 100644 --- a/Glamourer/Gui/Tabs/NpcTab/LocalNpcAppearanceData.cs +++ b/Glamourer/Gui/Tabs/NpcTab/LocalNpcAppearanceData.cs @@ -2,7 +2,7 @@ using Glamourer.Designs; using Glamourer.GameData; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs b/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs index 29fe7ef..c6166a3 100644 --- a/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs +++ b/Glamourer/Gui/Tabs/NpcTab/NpcPanel.cs @@ -6,7 +6,7 @@ using Glamourer.Gui.Customization; using Glamourer.Gui.Equipment; using Glamourer.Gui.Tabs.DesignTab; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/NpcTab/NpcSelector.cs b/Glamourer/Gui/Tabs/NpcTab/NpcSelector.cs index 8497ab4..847b65e 100644 --- a/Glamourer/Gui/Tabs/NpcTab/NpcSelector.cs +++ b/Glamourer/Gui/Tabs/NpcTab/NpcSelector.cs @@ -1,5 +1,5 @@ using Glamourer.GameData; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Extensions; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/NpcTab/NpcTab.cs b/Glamourer/Gui/Tabs/NpcTab/NpcTab.cs index 318e017..4efa4c3 100644 --- a/Glamourer/Gui/Tabs/NpcTab/NpcTab.cs +++ b/Glamourer/Gui/Tabs/NpcTab/NpcTab.cs @@ -1,5 +1,5 @@ using Dalamud.Interface.Utility; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Widgets; namespace Glamourer.Gui.Tabs.NpcTab; diff --git a/Glamourer/Gui/Tabs/SettingsTab/CodeDrawer.cs b/Glamourer/Gui/Tabs/SettingsTab/CodeDrawer.cs index 1dc9331..b4d3740 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/CodeDrawer.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/CodeDrawer.cs @@ -1,7 +1,7 @@ using Dalamud.Interface; using Glamourer.Services; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Filesystem; using OtterGui.Raii; using OtterGui.Services; diff --git a/Glamourer/Gui/Tabs/SettingsTab/CollectionCombo.cs b/Glamourer/Gui/Tabs/SettingsTab/CollectionCombo.cs index 7080b4d..98ba870 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/CollectionCombo.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/CollectionCombo.cs @@ -1,6 +1,6 @@ using Dalamud.Interface; using Glamourer.Interop.Penumbra; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Log; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs b/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs index 5c4fec3..87490db 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/CollectionOverrideDrawer.cs @@ -1,7 +1,7 @@ using Dalamud.Interface; using Glamourer.Interop.Penumbra; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Services; @@ -123,7 +123,7 @@ public class CollectionOverrideDrawer( { if (source) { - ImGui.SetDragDropPayload("DraggingOverride", null, 0); + ImGui.SetDragDropPayload("DraggingOverride", nint.Zero, 0); ImGui.TextUnformatted($"Reordering Override #{idx + 1}..."); _dragDropIndex = idx; } diff --git a/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs b/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs index 0a84adc..11af9b9 100644 --- a/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs +++ b/Glamourer/Gui/Tabs/SettingsTab/SettingsTab.cs @@ -1,5 +1,4 @@ -using Dalamud.Bindings.ImGui; -using Dalamud.Game.ClientState.Keys; +using Dalamud.Game.ClientState.Keys; using Dalamud.Interface; using Dalamud.Interface.Components; using Dalamud.Interface.Utility; @@ -9,8 +8,7 @@ using Glamourer.Designs; using Glamourer.Gui.Tabs.DesignTab; using Glamourer.Interop; using Glamourer.Interop.PalettePlus; -using Glamourer.Services; -using OtterGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui.Text; using OtterGui.Widgets; @@ -29,8 +27,7 @@ public class SettingsTab( CollectionOverrideDrawer overrides, CodeDrawer codeDrawer, Glamourer glamourer, - AutoDesignApplier autoDesignApplier, - PcpService pcpService) + AutoDesignApplier autoDesignApplier) : ITab { private readonly VirtualKey[] _validKeys = keys.GetValidVirtualKeys().Prepend(VirtualKey.NO_KEY).ToArray(); @@ -92,15 +89,6 @@ public class SettingsTab( Checkbox("Auto-Reload Gear"u8, "Automatically reload equipment pieces on your own character when changing any mod options in Penumbra in their associated collection."u8, config.AutoRedrawEquipOnChanges, v => config.AutoRedrawEquipOnChanges = v); - Checkbox("Attach to PCP-Handling"u8, - "Add the actor's glamourer state when a PCP is created by Penumbra, and create a design and apply it if possible when a PCP is installed by Penumbra."u8, - config.AttachToPcp, pcpService.Set); - var active = config.DeleteDesignModifier.IsActive(); - ImGui.SameLine(); - if (ImUtf8.ButtonEx("Delete all PCP Designs"u8, "Deletes all designs tagged with 'PCP' from the design list."u8, disabled: !active)) - pcpService.CleanPcpDesigns(); - if (!active) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"\nHold {config.DeleteDesignModifier} while clicking."); Checkbox("Revert Manual Changes on Zone Change"u8, "Restores the old behaviour of reverting your character to its game or automation base whenever you change the zone."u8, config.RevertManualChangesOnZoneChange, v => config.RevertManualChangesOnZoneChange = v); @@ -114,9 +102,6 @@ public class SettingsTab( "Apply all settings as temporary settings so they will be reset when Glamourer or the game shut down."u8, config.UseTemporarySettings, v => config.UseTemporarySettings = v); - Checkbox("Prevent Random Design Repeats"u8, - "When using random designs, prevent the same design from being chosen twice in a row."u8, - config.PreventRandomRepeats, v => config.PreventRandomRepeats = v); ImGui.NewLine(); } @@ -125,8 +110,6 @@ public class SettingsTab( if (!ImUtf8.CollapsingHeader("Design Defaults")) return; - Checkbox("Locked Designs"u8, "Newly created designs will be locked to prevent unintended changes."u8, - config.DefaultDesignSettings.Locked, v => config.DefaultDesignSettings.Locked = v); Checkbox("Show in Quick Design Bar"u8, "Newly created designs will be shown in the quick design bar by default."u8, config.DefaultDesignSettings.ShowQuickDesignBar, v => config.DefaultDesignSettings.ShowQuickDesignBar = v); Checkbox("Reset Advanced Dyes"u8, "Newly created designs will be configured to reset advanced dyes on application by default."u8, @@ -136,28 +119,6 @@ public class SettingsTab( Checkbox("Reset Temporary Settings"u8, "Newly created designs will be configured to clear all advanced settings applied by Glamourer to the collection by default."u8, config.DefaultDesignSettings.ResetTemporarySettings, v => config.DefaultDesignSettings.ResetTemporarySettings = v); - - var tmp = config.PcpFolder; - ImGui.SetNextItemWidth(0.4f * ImGui.GetContentRegionAvail().X); - if (ImUtf8.InputText("##pcpFolder"u8, ref tmp)) - config.PcpFolder = tmp; - - if (ImGui.IsItemDeactivatedAfterEdit()) - config.Save(); - - ImGuiUtil.LabeledHelpMarker("Default PCP Organizational Folder", - "The folder any designs created due to penumbra character packs are moved to on creation.\nLeave blank to import into Root."); - - tmp = config.PcpColor; - ImGui.SetNextItemWidth(0.4f * ImGui.GetContentRegionAvail().X); - if (ImUtf8.InputText("##pcpColor"u8, ref tmp)) - config.PcpColor = tmp; - - if (ImGui.IsItemDeactivatedAfterEdit()) - config.Save(); - - ImGuiUtil.LabeledHelpMarker("Default PCP Design Color", - "The name of the color group any designs created due to penumbra character packs are assigned.\nLeave blank for no specific color assignment."); } private void DrawInterfaceSettings() @@ -286,8 +247,8 @@ public class SettingsTab( private void DrawQuickDesignBoxes() { - var showAuto = config.EnableAutoDesigns; - var numColumns = 9 - (showAuto ? 0 : 2) - (config.UseTemporarySettings ? 0 : 1); + var showAuto = config.EnableAutoDesigns; + var numColumns = 8 - (showAuto ? 0 : 2) - (config.UseTemporarySettings ? 0 : 1); ImGui.NewLine(); ImUtf8.Text("Show the Following Buttons in the Quick Design Bar:"u8); ImGui.Dummy(Vector2.Zero); @@ -304,8 +265,7 @@ public class SettingsTab( ("Reapply Auto", showAuto, QdbButtons.ReapplyAutomation), ("Revert Equip", true, QdbButtons.RevertEquip), ("Revert Customize", true, QdbButtons.RevertCustomize), - ("Revert Advanced Customization", true, QdbButtons.RevertAdvancedCustomization), - ("Revert Advanced Dyes", true, QdbButtons.RevertAdvancedDyes), + ("Revert Advanced", true, QdbButtons.RevertAdvanced), ("Reset Settings", config.UseTemporarySettings, QdbButtons.ResetSettings), ]; diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs index 8644aeb..903257b 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs @@ -5,7 +5,7 @@ using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui.Text; using Penumbra.GameData.Enums; @@ -123,7 +123,7 @@ public class UnlockOverview( var unlocked = customizeUnlocks.IsUnlocked(customize, out var time); var icon = customizations.Manager.GetIcon(customize.IconId); var hasIcon = icon.TryGetWrap(out var wrap, out _); - ImGui.Image(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, iconSize, Vector2.Zero, Vector2.One, + ImGui.Image(wrap?.ImGuiHandle ?? icon.GetWrapOrEmpty().ImGuiHandle, iconSize, Vector2.Zero, Vector2.One, unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); if (favorites.Contains(_selected3, _selected2, customize.Index, customize.Value)) @@ -135,7 +135,7 @@ public class UnlockOverview( using var tt = ImRaii.Tooltip(); var size = new Vector2(wrap!.Width, wrap.Height); if (size.X >= iconSize.X && size.Y >= iconSize.Y) - ImGui.Image(wrap.Handle, size); + ImGui.Image(wrap.ImGuiHandle, size); ImGui.TextUnformatted(unlockData.Name); ImGui.TextUnformatted($"{customize.Index.ToDefaultName()} {customize.Value.Value}"); ImGui.TextUnformatted(unlocked ? $"Unlocked on {time:g}" : "Not unlocked."); @@ -194,7 +194,7 @@ public class UnlockOverview( if (!textures.TryLoadIcon(item.IconId.Id, out var iconHandle)) return; - var (icon, size) = (iconHandle.Handle, new Vector2(iconHandle.Width, iconHandle.Height)); + var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height)); ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); @@ -265,7 +265,7 @@ public class UnlockOverview( if (!textures.TryLoadIcon(item.IconId.Id, out var iconHandle)) return; - var (icon, size) = (iconHandle.Handle, new Vector2(iconHandle.Width, iconHandle.Height)); + var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height)); ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs index d75f2dc..6d9ce51 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs @@ -6,7 +6,7 @@ using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Table; diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlocksTab.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlocksTab.cs index 661b2a4..c2e06e5 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlocksTab.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlocksTab.cs @@ -1,6 +1,6 @@ using Dalamud.Interface; using Dalamud.Interface.Windowing; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Raii; using OtterGui; using OtterGui.Widgets; diff --git a/Glamourer/Gui/UiHelpers.cs b/Glamourer/Gui/UiHelpers.cs index 94ddb06..1ec79d7 100644 --- a/Glamourer/Gui/UiHelpers.cs +++ b/Glamourer/Gui/UiHelpers.cs @@ -2,7 +2,7 @@ using Dalamud.Interface; using Dalamud.Interface.Utility; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using Lumina.Misc; using OtterGui; using OtterGui.Raii; diff --git a/Glamourer/Interop/CrestService.cs b/Glamourer/Interop/CrestService.cs index 2b55f94..95b3587 100644 --- a/Glamourer/Interop/CrestService.cs +++ b/Glamourer/Interop/CrestService.cs @@ -67,7 +67,7 @@ public sealed unsafe class CrestService : EventWrapperRef3 _crestChangeHook = null!; private void CrestChangeDetour(DrawDataContainer* container, byte crestFlags) @@ -122,7 +122,7 @@ public sealed unsafe class CrestService : EventWrapperRef3IsFreeCompanyCrestVisibleOnSlot(index); + return model.AsHuman->IsFreeCompanyCrestVisibleOnSlot(index) != 0; } case CrestType.Offhand: { @@ -130,7 +130,7 @@ public sealed unsafe class CrestService : EventWrapperRef3IsFreeCompanyCrestVisibleOnSlot(index); + return model.AsWeapon->IsFreeCompanyCrestVisibleOnSlot(index) != 0; } } diff --git a/Glamourer/Interop/ImportService.cs b/Glamourer/Interop/ImportService.cs index c6e90fd..b9dfbe1 100644 --- a/Glamourer/Interop/ImportService.cs +++ b/Glamourer/Interop/ImportService.cs @@ -3,7 +3,7 @@ using Dalamud.Interface.ImGuiNotification; using Glamourer.Designs; using Glamourer.Interop.CharaFile; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Classes; using Penumbra.GameData.Enums; using Penumbra.GameData.Files; diff --git a/Glamourer/Interop/Material/LiveColorTablePreviewer.cs b/Glamourer/Interop/Material/LiveColorTablePreviewer.cs index 3b9edb7..94cb9ca 100644 --- a/Glamourer/Interop/Material/LiveColorTablePreviewer.cs +++ b/Glamourer/Interop/Material/LiveColorTablePreviewer.cs @@ -1,5 +1,5 @@ using Dalamud.Plugin.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Services; using Penumbra.GameData.Files.MaterialStructs; using Penumbra.GameData.Structs; @@ -114,9 +114,8 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable var frame = DateTimeOffset.UtcNow.UtcTicks; var hueByte = frame % (steps * frameLength) / frameLength; var hue = (float)hueByte / steps; - Vector3 ret; - ImGui.ColorConvertHSVtoRGB(hue, 1, 1, &ret.X, &ret.Y, &ret.Z); - return ret; + ImGui.ColorConvertHSVtoRGB(hue, 1, 1, out var r, out var g, out var b); + return new Vector3(r, g, b); } public void Dispose() diff --git a/Glamourer/Interop/Material/MaterialManager.cs b/Glamourer/Interop/Material/MaterialManager.cs index 43e500b..9eccb29 100644 --- a/Glamourer/Interop/Material/MaterialManager.cs +++ b/Glamourer/Interop/Material/MaterialManager.cs @@ -62,7 +62,7 @@ public sealed unsafe class MaterialManager : IRequiredService, IDisposable var drawData = type switch { - MaterialValueIndex.DrawObjectType.Human => GetTempSlot((Human*)characterBase, (HumanSlot)slotId), + MaterialValueIndex.DrawObjectType.Human => GetTempSlot((Human*)characterBase, slotId), _ => GetTempSlot((Weapon*)characterBase), }; var mode = PrepareColorSet.GetMode(material); @@ -192,24 +192,12 @@ public sealed unsafe class MaterialManager : IRequiredService, IDisposable } /// We need to get the temporary set, variant and stain that is currently being set if it is available. - private static CharacterWeapon GetTempSlot(Human* human, HumanSlot slotId) + private static CharacterWeapon GetTempSlot(Human* human, byte slotId) { - if (human->ChangedEquipData is null) - return slotId.ToSpecificEnum() switch - { - EquipSlot slot => ((Model)human).GetArmor(slot).ToWeapon(0), - BonusItemFlag bonus => ((Model)human).GetBonus(bonus).ToWeapon(0), - _ => default, - }; + if (human->ChangedEquipData == null) + return ((Model)human).GetArmor(((uint)slotId).ToEquipSlot()).ToWeapon(0); - if (!slotId.ToSlotIndex(out var index)) - return default; - - var item = (ChangedEquipData*)human->ChangedEquipData + index; - if (index < 10) - return ((CharacterArmor*)item)->ToWeapon(0); - - return new CharacterWeapon(item->BonusModel, 0, item->BonusVariant, StainIds.None); + return ((CharacterArmor*)human->ChangedEquipData + slotId * 3)->ToWeapon(0); } /// diff --git a/Glamourer/Interop/Material/MaterialService.cs b/Glamourer/Interop/Material/MaterialService.cs index 4893e14..a5f2b36 100644 --- a/Glamourer/Interop/Material/MaterialService.cs +++ b/Glamourer/Interop/Material/MaterialService.cs @@ -1,5 +1,6 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; +using Lumina.Data.Files; using Penumbra.GameData.Files.MaterialStructs; using Penumbra.GameData.Interop; using Texture = FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Texture; @@ -68,9 +69,9 @@ public static unsafe class MaterialService return null; var material = (MaterialResourceHandle*) model.AsCharacterBase->MaterialsSpan[index].Value; - if (material == null || material->DataSet == null || material->DataSetSize < sizeof(ColorTable.Table) || !material->HasColorTable) + if (material == null || material->ColorTable == null) return null; - return (ColorTable.Table*)material->DataSet; + return (ColorTable.Table*)material->ColorTable; } } diff --git a/Glamourer/Interop/Material/MaterialValueIndex.cs b/Glamourer/Interop/Material/MaterialValueIndex.cs index eb3f71f..712b0d5 100644 --- a/Glamourer/Interop/Material/MaterialValueIndex.cs +++ b/Glamourer/Interop/Material/MaterialValueIndex.cs @@ -50,18 +50,6 @@ public readonly record struct MaterialValueIndex( return idx > 2 ? Invalid : new MaterialValueIndex(DrawObjectType.Human, (byte)(idx + 16), 0, 0); } - public string SlotName() - { - var slot = ToEquipSlot(); - if (slot is not EquipSlot.Unknown) - return slot.ToName(); - - if (DrawObject is DrawObjectType.Human && SlotIndex is 16) - return BonusItemFlag.Glasses.ToString(); - - return EquipSlot.Unknown.ToName(); - } - public EquipSlot ToEquipSlot() => DrawObject switch { @@ -71,13 +59,6 @@ public readonly record struct MaterialValueIndex( _ => EquipSlot.Unknown, }; - public BonusItemFlag ToBonusSlot() - => DrawObject switch - { - DrawObjectType.Human when SlotIndex > 15 => ((uint)SlotIndex - 16).ToBonusSlot(), - _ => BonusItemFlag.Unknown, - }; - public unsafe bool TryGetModel(Actor actor, out Model model) { if (!actor.Valid) diff --git a/Glamourer/Interop/Material/PrepareColorSet.cs b/Glamourer/Interop/Material/PrepareColorSet.cs index 821a152..dfa6811 100644 --- a/Glamourer/Interop/Material/PrepareColorSet.cs +++ b/Glamourer/Interop/Material/PrepareColorSet.cs @@ -1,4 +1,5 @@ using Dalamud.Hooking; +using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; @@ -50,6 +51,10 @@ public sealed unsafe class PrepareColorSet private delegate Texture* Delegate(MaterialResourceHandle* material, StainId stainId1, StainId stainId2); + // TODO use CS when stabilized in Dalamud. + [Signature("E8 ?? ?? ?? ?? 48 8B FB EB 07")] + private static delegate* unmanaged _readStainingTemplate = null; + private Texture* Detour(MaterialResourceHandle* material, StainId stainId1, StainId stainId2) { Glamourer.Log.Excessive($"[{Name}] Triggered with 0x{(nint)material:X} {stainId1.Id} {stainId2.Id}."); @@ -69,20 +74,20 @@ public sealed unsafe class PrepareColorSet public static bool TryGetColorTable(MaterialResourceHandle* material, StainIds stainIds, out ColorTable.Table table) { - if (material->DataSet == null || material->DataSetSize < sizeof(ColorTable.Table) || !material->HasColorTable) + if (material->ColorTable == null) { table = default; return false; } - var newTable = *(ColorTable.Table*)material->DataSet; + var newTable = *(ColorTable.Table*)material->ColorTable; if (GetDyeTable(material, out var dyeTable)) { if (stainIds.Stain1.Id != 0) - material->ReadStainingTemplate(dyeTable, stainIds.Stain1.Id, (Half*)&newTable, 0); + _readStainingTemplate(material, dyeTable, stainIds.Stain1.Id, (Half*)(&newTable), 0); if (stainIds.Stain2.Id != 0) - material->ReadStainingTemplate(dyeTable, stainIds.Stain2.Id, (Half*)&newTable, 1); + _readStainingTemplate(material, dyeTable, stainIds.Stain2.Id, (Half*)(&newTable), 1); } table = newTable; diff --git a/Glamourer/Interop/Penumbra/PenumbraService.cs b/Glamourer/Interop/Penumbra/PenumbraService.cs index 4d70a3f..3f93551 100644 --- a/Glamourer/Interop/Penumbra/PenumbraService.cs +++ b/Glamourer/Interop/Penumbra/PenumbraService.cs @@ -2,7 +2,6 @@ using Dalamud.Plugin; using Glamourer.Events; using Glamourer.State; -using Newtonsoft.Json.Linq; using OtterGui.Classes; using Penumbra.Api.Enums; using Penumbra.Api.Helpers; @@ -50,8 +49,6 @@ public class PenumbraService : IDisposable private readonly EventSubscriber _creatingCharacterBase; private readonly EventSubscriber _createdCharacterBase; private readonly EventSubscriber _modSettingChanged; - private readonly EventSubscriber _pcpParsed; - private readonly EventSubscriber _pcpCreated; private global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier? _collectionByIdentifier; private global::Penumbra.Api.IpcSubscribers.GetCollections? _collections; @@ -104,8 +101,6 @@ public class PenumbraService : IDisposable _createdCharacterBase = global::Penumbra.Api.IpcSubscribers.CreatedCharacterBase.Subscriber(pi); _creatingCharacterBase = global::Penumbra.Api.IpcSubscribers.CreatingCharacterBase.Subscriber(pi); _modSettingChanged = global::Penumbra.Api.IpcSubscribers.ModSettingChanged.Subscriber(pi); - _pcpCreated = global::Penumbra.Api.IpcSubscribers.CreatingPcp.Subscriber(pi); - _pcpParsed = global::Penumbra.Api.IpcSubscribers.ParsingPcp.Subscriber(pi); Reattach(); } @@ -140,18 +135,6 @@ public class PenumbraService : IDisposable remove => _modSettingChanged.Event -= value; } - public event Action PcpCreated - { - add => _pcpCreated.Event += value; - remove => _pcpCreated.Event -= value; - } - - public event Action PcpParsed - { - add => _pcpParsed.Event += value; - remove => _pcpParsed.Event -= value; - } - public Dictionary GetCollections() => Available ? _collections!.Invoke() : []; @@ -189,14 +172,14 @@ public class PenumbraService : IDisposable if (_queryTemporaryModSettings != null) { - var tempEc = _queryTemporaryModSettings.Invoke(collection, modDirectory, out var tempTuple, out source, 0, modName); + var tempEc = _queryTemporaryModSettings.Invoke(collection, modDirectory, out var tempTuple, out source); if (tempEc is PenumbraApiEc.Success && tempTuple != null) return new ModSettings(tempTuple.Value.Settings, tempTuple.Value.Priority, tempTuple.Value.Enabled, tempTuple.Value.ForceInherit, false); } source = string.Empty; - var (ec2, tuple2) = _getCurrentSettings!.Invoke(collection, modDirectory, modName); + var (ec2, tuple2) = _getCurrentSettings!.Invoke(collection, modDirectory); if (ec2 is not PenumbraApiEc.Success) return ModSettings.Empty; @@ -282,7 +265,7 @@ public class PenumbraService : IDisposable if (!Available) return; - if (_openModPage!.Invoke(TabType.Mods, mod.DirectoryName, mod.Name) == PenumbraApiEc.ModMissing) + if (_openModPage!.Invoke(TabType.Mods, mod.DirectoryName) == PenumbraApiEc.ModMissing) Glamourer.Messager.NotificationMessage($"Could not open the mod {mod.Name}, no fitting mod was found in your Penumbra install.", NotificationType.Info, false); } @@ -366,14 +349,14 @@ public class PenumbraService : IDisposable var ex = settings.Remove ? index.HasValue - ? _removeTemporaryModSettingsPlayer!.Invoke(index.Value.Index, mod.DirectoryName, key, mod.Name) - : _removeTemporaryModSettings!.Invoke(collection, mod.DirectoryName, key, mod.Name) + ? _removeTemporaryModSettingsPlayer!.Invoke(index.Value.Index, mod.DirectoryName, key) + : _removeTemporaryModSettings!.Invoke(collection, mod.DirectoryName, key) : index.HasValue ? _setTemporaryModSettingsPlayer!.Invoke(index.Value.Index, mod.DirectoryName, settings.ForceInherit, settings.Enabled, settings.Priority, - settings.Settings.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList)kvp.Value), name, key, mod.Name) + settings.Settings.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList)kvp.Value), name, key) : _setTemporaryModSettings!.Invoke(collection, mod.DirectoryName, settings.ForceInherit, settings.Enabled, settings.Priority, - settings.Settings.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList)kvp.Value), name, key, mod.Name); + settings.Settings.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList)kvp.Value), name, key); switch (ex) { case PenumbraApiEc.InvalidArgument: @@ -401,8 +384,8 @@ public class PenumbraService : IDisposable private void SetModPermanent(StringBuilder sb, Mod mod, ModSettings settings, Guid collection) { var ec = settings.ForceInherit - ? _inheritMod!.Invoke(collection, mod.DirectoryName, true, mod.Name) - : _setMod!.Invoke(collection, mod.DirectoryName, settings.Enabled, mod.Name); + ? _inheritMod!.Invoke(collection, mod.DirectoryName, true) + : _setMod!.Invoke(collection, mod.DirectoryName, settings.Enabled); switch (ec) { case PenumbraApiEc.ModMissing: @@ -416,14 +399,14 @@ public class PenumbraService : IDisposable if (settings.ForceInherit || !settings.Enabled) return; - ec = _setModPriority!.Invoke(collection, mod.DirectoryName, settings.Priority, mod.Name); + ec = _setModPriority!.Invoke(collection, mod.DirectoryName, settings.Priority); Debug.Assert(ec is PenumbraApiEc.Success or PenumbraApiEc.NothingChanged, "Setting Priority should not be able to fail."); foreach (var (setting, list) in settings.Settings) { ec = list.Count == 1 - ? _setModSetting!.Invoke(collection, mod.DirectoryName, setting, list[0], mod.Name) - : _setModSettings!.Invoke(collection, mod.DirectoryName, setting, list, mod.Name); + ? _setModSetting!.Invoke(collection, mod.DirectoryName, setting, list[0]) + : _setModSettings!.Invoke(collection, mod.DirectoryName, setting, list); switch (ec) { case PenumbraApiEc.OptionGroupMissing: sb.AppendLine($"Could not find the option group {setting} in mod {mod.Name}."); break; @@ -531,30 +514,28 @@ public class PenumbraService : IDisposable _clickSubscriber.Enable(); _creatingCharacterBase.Enable(); _createdCharacterBase.Enable(); - _pcpCreated.Enable(); - _pcpParsed.Enable(); _modSettingChanged.Enable(); - _collectionByIdentifier = new global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier(_pluginInterface); - _collections = new global::Penumbra.Api.IpcSubscribers.GetCollections(_pluginInterface); - _redraw = new global::Penumbra.Api.IpcSubscribers.RedrawObject(_pluginInterface); - _checkCutsceneParent = new global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndexFunc(_pluginInterface).Invoke(); - _getGameObject = new global::Penumbra.Api.IpcSubscribers.GetGameObjectFromDrawObjectFunc(_pluginInterface).Invoke(); - _objectCollection = new global::Penumbra.Api.IpcSubscribers.GetCollectionForObject(_pluginInterface); - _getMods = new global::Penumbra.Api.IpcSubscribers.GetModList(_pluginInterface); - _currentCollection = new global::Penumbra.Api.IpcSubscribers.GetCollection(_pluginInterface); - _getCurrentSettings = new global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings(_pluginInterface); - _inheritMod = new global::Penumbra.Api.IpcSubscribers.TryInheritMod(_pluginInterface); - _setMod = new global::Penumbra.Api.IpcSubscribers.TrySetMod(_pluginInterface); - _setModPriority = new global::Penumbra.Api.IpcSubscribers.TrySetModPriority(_pluginInterface); - _setModSetting = new global::Penumbra.Api.IpcSubscribers.TrySetModSetting(_pluginInterface); - _setModSettings = new global::Penumbra.Api.IpcSubscribers.TrySetModSettings(_pluginInterface); - _openModPage = new global::Penumbra.Api.IpcSubscribers.OpenMainWindow(_pluginInterface); - _getChangedItems = new global::Penumbra.Api.IpcSubscribers.GetChangedItems(_pluginInterface); - _setTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings(_pluginInterface); - _setTemporaryModSettingsPlayer = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettingsPlayer(_pluginInterface); - _removeTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettings(_pluginInterface); + _collectionByIdentifier = new global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier(_pluginInterface); + _collections = new global::Penumbra.Api.IpcSubscribers.GetCollections(_pluginInterface); + _redraw = new global::Penumbra.Api.IpcSubscribers.RedrawObject(_pluginInterface); + _checkCutsceneParent = new global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndexFunc(_pluginInterface).Invoke(); + _getGameObject = new global::Penumbra.Api.IpcSubscribers.GetGameObjectFromDrawObjectFunc(_pluginInterface).Invoke(); + _objectCollection = new global::Penumbra.Api.IpcSubscribers.GetCollectionForObject(_pluginInterface); + _getMods = new global::Penumbra.Api.IpcSubscribers.GetModList(_pluginInterface); + _currentCollection = new global::Penumbra.Api.IpcSubscribers.GetCollection(_pluginInterface); + _getCurrentSettings = new global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings(_pluginInterface); + _inheritMod = new global::Penumbra.Api.IpcSubscribers.TryInheritMod(_pluginInterface); + _setMod = new global::Penumbra.Api.IpcSubscribers.TrySetMod(_pluginInterface); + _setModPriority = new global::Penumbra.Api.IpcSubscribers.TrySetModPriority(_pluginInterface); + _setModSetting = new global::Penumbra.Api.IpcSubscribers.TrySetModSetting(_pluginInterface); + _setModSettings = new global::Penumbra.Api.IpcSubscribers.TrySetModSettings(_pluginInterface); + _openModPage = new global::Penumbra.Api.IpcSubscribers.OpenMainWindow(_pluginInterface); + _getChangedItems = new global::Penumbra.Api.IpcSubscribers.GetChangedItems(_pluginInterface); + _setTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings(_pluginInterface); + _setTemporaryModSettingsPlayer = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettingsPlayer(_pluginInterface); + _removeTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettings(_pluginInterface); _removeTemporaryModSettingsPlayer = new global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettingsPlayer(_pluginInterface); - _removeAllTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettings(_pluginInterface); + _removeAllTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettings(_pluginInterface); _removeAllTemporaryModSettingsPlayer = new global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettingsPlayer(_pluginInterface); _queryTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.QueryTemporaryModSettings(_pluginInterface); @@ -585,8 +566,6 @@ public class PenumbraService : IDisposable _creatingCharacterBase.Disable(); _createdCharacterBase.Disable(); _modSettingChanged.Disable(); - _pcpCreated.Disable(); - _pcpParsed.Disable(); if (Available) { _collectionByIdentifier = null; @@ -633,7 +612,5 @@ public class PenumbraService : IDisposable _initializedEvent.Dispose(); _disposedEvent.Dispose(); _modSettingChanged.Dispose(); - _pcpCreated.Dispose(); - _pcpParsed.Dispose(); } } diff --git a/Glamourer/Interop/VieraEarService.cs b/Glamourer/Interop/VieraEarService.cs deleted file mode 100644 index a6afd1d..0000000 --- a/Glamourer/Interop/VieraEarService.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Dalamud.Hooking; -using Dalamud.Plugin.Services; -using FFXIVClientStructs.FFXIV.Client.Game.Character; -using Glamourer.Events; -using Penumbra.GameData; -using Penumbra.GameData.Interop; - -namespace Glamourer.Interop; - -public unsafe class VieraEarService : IDisposable -{ - private readonly PenumbraReloaded _penumbra; - private readonly IGameInteropProvider _interop; - public readonly VieraEarStateChanged Event; - - public VieraEarService(VieraEarStateChanged visorStateChanged, IGameInteropProvider interop, PenumbraReloaded penumbra) - { - _interop = interop; - _penumbra = penumbra; - Event = visorStateChanged; - _setupVieraEarHook = Create(); - _penumbra.Subscribe(Restore, PenumbraReloaded.Priority.VieraEarService); - } - - public void Dispose() - { - _setupVieraEarHook.Dispose(); - _penumbra.Unsubscribe(Restore); - } - - /// Obtain the current state of viera ears for the given draw object (true: toggled). - public static unsafe bool GetVieraEarState(Model characterBase) - => characterBase is { IsCharacterBase: true, VieraEarsVisible: true }; - - /// Manually set the state of the Visor for the given draw object. - /// The draw object. - /// The desired state (true: toggled). - /// Whether the state was changed. - public bool SetVieraEarState(Model human, bool on) - { - if (!human.IsHuman) - return false; - - var oldState = GetVieraEarState(human); - Glamourer.Log.Verbose($"[SetVieraEarState] Invoked manually on 0x{human.Address:X} switching from {oldState} to {on}."); - if (oldState == on) - return false; - - human.VieraEarsVisible = on; - return true; - } - - private delegate void UpdateVieraEarDelegateInternal(DrawDataContainer* drawData, byte on); - - private Hook _setupVieraEarHook; - - private void SetupVieraEarDetour(DrawDataContainer* drawData, byte value) - { - Actor actor = drawData->OwnerObject; - var originalOn = value != 0; - var on = originalOn; - // Invoke an event that can change the requested value - Event.Invoke(actor, ref on); - - Glamourer.Log.Verbose( - $"[SetVieraEarState] Invoked from game on 0x{actor.Address:X} switching to {on} (original {originalOn} from {value})."); - - _setupVieraEarHook.Original(drawData, on ? (byte)1 : (byte)0); - } - - private unsafe Hook Create() - { - var hook = _interop.HookFromSignature(Sigs.SetupVieraEars, SetupVieraEarDetour); - hook.Enable(); - return hook; - } - - private void Restore() - { - _setupVieraEarHook.Dispose(); - _setupVieraEarHook = Create(); - } -} diff --git a/Glamourer/Interop/VisorService.cs b/Glamourer/Interop/VisorService.cs index 83262e4..9763682 100644 --- a/Glamourer/Interop/VisorService.cs +++ b/Glamourer/Interop/VisorService.cs @@ -36,7 +36,7 @@ public class VisorService : IDisposable /// The draw object. /// The desired state (true: toggled). /// Whether the state was changed. - public unsafe bool SetVisorState(Model human, bool on) + public bool SetVisorState(Model human, bool on) { if (!human.IsHuman) return false; @@ -46,8 +46,6 @@ public class VisorService : IDisposable if (oldState == on) return false; - // No clue what this flag does, but it's necessary for toggling static visors on or off, e.g. Alternate Cap (6229-1). - human.AsHuman->StateFlags |= (CharacterBase.StateFlag)0x40000000; SetupVisorDetour(human, human.GetArmor(EquipSlot.Head).Set.Id, on); return true; } diff --git a/Glamourer/Interop/WeaponService.cs b/Glamourer/Interop/WeaponService.cs index 54f318b..b0bdd19 100644 --- a/Glamourer/Interop/WeaponService.cs +++ b/Glamourer/Interop/WeaponService.cs @@ -13,7 +13,7 @@ public unsafe class WeaponService : IDisposable private readonly WeaponLoading _event; private readonly ThreadLocal _inUpdate = new(() => false); - private readonly delegate* unmanaged[Stdcall] + private readonly delegate* unmanaged[Stdcall] _original; public WeaponService(WeaponLoading @event, IGameInteropProvider interop) @@ -22,7 +22,7 @@ public unsafe class WeaponService : IDisposable _loadWeaponHook = interop.HookFromAddress((nint)DrawDataContainer.MemberFunctionPointers.LoadWeapon, LoadWeaponDetour); _original = - (delegate* unmanaged[Stdcall] < DrawDataContainer*, uint, ulong, byte, byte, byte, byte, int, void >) + (delegate* unmanaged[Stdcall] < DrawDataContainer*, uint, ulong, byte, byte, byte, byte, void >) DrawDataContainer.MemberFunctionPointers.LoadWeapon; _loadWeaponHook.Enable(); } @@ -36,14 +36,13 @@ public unsafe class WeaponService : IDisposable // redrawOnEquality controls whether the game does anything if the new weapon is identical to the old one. // skipGameObject seems to control whether the new weapons are written to the game object or just influence the draw object. (1 = skip, 0 = change) // unk4 seemed to be the same as unk1. - // unk5 is new in 7.30 and is checked at the beginning of the function to call some timeline related function. private delegate void LoadWeaponDelegate(DrawDataContainer* drawData, uint slot, ulong weapon, byte redrawOnEquality, byte unk2, - byte skipGameObject, byte unk4, byte unk5); + byte skipGameObject, byte unk4); private readonly Hook _loadWeaponHook; private void LoadWeaponDetour(DrawDataContainer* drawData, uint slot, ulong weaponValue, byte redrawOnEquality, byte unk2, - byte skipGameObject, byte unk4, byte unk5) + byte skipGameObject, byte unk4) { if (!_inUpdate.Value) { @@ -65,21 +64,21 @@ public unsafe class WeaponService : IDisposable else if (weaponValue == actor.GetMainhand().Value && weaponValue != 0) _event.Invoke(actor, EquipSlot.MainHand, ref tmpWeapon); - _loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4, unk5); + _loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4); if (tmpWeapon.Value != weapon.Value) { if (tmpWeapon.Skeleton.Id == 0) tmpWeapon.Stains = StainIds.None; - _loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4, unk5); + _loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4); } Glamourer.Log.Excessive( - $"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}, {unk5}"); + $"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}"); } else { - _loadWeaponHook.Original(drawData, slot, weaponValue, redrawOnEquality, unk2, skipGameObject, unk4, unk5); + _loadWeaponHook.Original(drawData, slot, weaponValue, redrawOnEquality, unk2, skipGameObject, unk4); } } @@ -90,18 +89,18 @@ public unsafe class WeaponService : IDisposable { case EquipSlot.MainHand: _inUpdate.Value = true; - _original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0, 0); + _original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0); _inUpdate.Value = false; return; case EquipSlot.OffHand: _inUpdate.Value = true; - _original(&character.AsCharacter->DrawData, 1, weapon.Value, 1, 0, 1, 0, 0); + _original(&character.AsCharacter->DrawData, 1, weapon.Value, 1, 0, 1, 0); _inUpdate.Value = false; return; case EquipSlot.BothHand: _inUpdate.Value = true; - _original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0, 0); - _original(&character.AsCharacter->DrawData, 1, CharacterWeapon.Empty.Value, 1, 0, 1, 0, 0); + _original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0); + _original(&character.AsCharacter->DrawData, 1, CharacterWeapon.Empty.Value, 1, 0, 1, 0); _inUpdate.Value = false; return; } diff --git a/Glamourer/Services/BackupService.cs b/Glamourer/Services/BackupService.cs index 511cca6..3abf13a 100644 --- a/Glamourer/Services/BackupService.cs +++ b/Glamourer/Services/BackupService.cs @@ -1,10 +1,9 @@ using OtterGui.Classes; using OtterGui.Log; -using OtterGui.Services; namespace Glamourer.Services; -public class BackupService : IAsyncService +public class BackupService { private readonly Logger _logger; private readonly DirectoryInfo _configDirectory; @@ -15,7 +14,7 @@ public class BackupService : IAsyncService _logger = logger; _fileNames = GlamourerFiles(fileNames); _configDirectory = new DirectoryInfo(fileNames.ConfigDirectory); - Awaiter = Task.Run(() => Backup.CreateAutomaticBackup(logger, new DirectoryInfo(fileNames.ConfigDirectory), _fileNames)); + Backup.CreateAutomaticBackup(logger, _configDirectory, _fileNames); } /// Create a permanent backup with a given name for migrations. @@ -41,9 +40,4 @@ public class BackupService : IAsyncService return list; } - - public Task Awaiter { get; } - - public bool Finished - => Awaiter.IsCompletedSuccessfully; } diff --git a/Glamourer/Services/CodeService.cs b/Glamourer/Services/CodeService.cs index 4a82f0e..af2e88b 100644 --- a/Glamourer/Services/CodeService.cs +++ b/Glamourer/Services/CodeService.cs @@ -50,8 +50,7 @@ public class CodeService | CodeFlag.OopsMiqote | CodeFlag.OopsRoegadyn | CodeFlag.OopsAuRa - | CodeFlag.OopsHrothgar - | CodeFlag.OopsViera; + | CodeFlag.OopsHrothgar; public const CodeFlag FullCodes = CodeFlag.Face | CodeFlag.Manderville | CodeFlag.Smiles; @@ -251,4 +250,3 @@ public class CodeService _ => (false, 0, string.Empty, string.Empty, string.Empty), }; } - diff --git a/Glamourer/Services/CommandService.cs b/Glamourer/Services/CommandService.cs index d2feac0..3d40fa9 100644 --- a/Glamourer/Services/CommandService.cs +++ b/Glamourer/Services/CommandService.cs @@ -9,7 +9,7 @@ using Glamourer.Gui; using Glamourer.Gui.Tabs.DesignTab; using Glamourer.Interop.Penumbra; using Glamourer.State; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Extensions; @@ -96,12 +96,6 @@ public class CommandService : IDisposable, IApiService _config.Ephemeral.LockMainWindow = !_config.Ephemeral.LockMainWindow; _config.Ephemeral.Save(); return; - case "automation": - var newValue = !_config.EnableAutoDesigns; - _config.EnableAutoDesigns = newValue; - _autoDesignApplier.OnEnableAutoDesignsChanged(newValue); - _config.Save(); - return; default: _chat.Print("Use without argument to toggle the main window."); _chat.Print(new SeStringBuilder().AddText("Use ").AddPurple("/glamour").AddText(" instead of ").AddRed("/glamourer") @@ -413,7 +407,7 @@ public class CommandService : IDisposable, IApiService foreach (var identifier in identifiers) { if (_stateManager.TryGetValue(identifier, out var state)) - _stateManager.ResetState(state, StateSource.Manual, isFinal: true); + _stateManager.ResetState(state, StateSource.Manual); } diff --git a/Glamourer/Services/ConfigMigrationService.cs b/Glamourer/Services/ConfigMigrationService.cs index ef39f1a..3f997c9 100644 --- a/Glamourer/Services/ConfigMigrationService.cs +++ b/Glamourer/Services/ConfigMigrationService.cs @@ -24,20 +24,9 @@ public class ConfigMigrationService(SaveService saveService, FixedDesignMigrator MigrateV4To5(); MigrateV5To6(); MigrateV6To7(); - MigrateV7To8(); AddColors(config, true); } - private void MigrateV7To8() - { - if (_config.Version > 7) - return; - - if (_config.QdbButtons.HasFlag(QdbButtons.RevertAdvancedDyes)) - _config.QdbButtons |= QdbButtons.RevertAdvancedCustomization; - _config.Version = 8; - } - private void MigrateV6To7() { if (_config.Version > 6) @@ -54,7 +43,7 @@ public class ConfigMigrationService(SaveService saveService, FixedDesignMigrator return; if (_data["ShowRevertAdvancedParametersButton"]?.ToObject() ?? true) - _config.QdbButtons |= QdbButtons.RevertAdvancedCustomization; + _config.QdbButtons |= QdbButtons.RevertAdvanced; _config.Version = 6; } diff --git a/Glamourer/Services/DesignResolver.cs b/Glamourer/Services/DesignResolver.cs index 8bb5cd2..68b54bb 100644 --- a/Glamourer/Services/DesignResolver.cs +++ b/Glamourer/Services/DesignResolver.cs @@ -4,7 +4,7 @@ using Glamourer.Designs; using Glamourer.Designs.Special; using Glamourer.Gui; using Glamourer.Gui.Tabs.DesignTab; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui.Services; using OtterGui.Classes; diff --git a/Glamourer/Services/ItemManager.cs b/Glamourer/Services/ItemManager.cs index a885b54..5d6f074 100644 --- a/Glamourer/Services/ItemManager.cs +++ b/Glamourer/Services/ItemManager.cs @@ -145,10 +145,8 @@ public class ItemManager // Only from early designs as migration. if (!id.IsBonusItem || id.Id == 0) { - if (IsBonusItemValid(slot, (BonusItemId)id.Id, out var item)) - return item; - - return EquipItem.BonusItemNothing(slot); + IsBonusItemValid(slot, (BonusItemId)id.Id, out var item); + return item; } if (!id.IsCustom) @@ -176,36 +174,6 @@ public class ItemManager return NothingItem(offhandType); } - public bool FindClosestShield(ItemId id, out EquipItem item) - { - var list = ItemData.ByType[FullEquipType.Shield]; - try - { - item = list.Where(i => i.ItemId.Id > id.Id && i.ItemId.Id - id.Id < 50).MinBy(i => i.ItemId.Id); - return true; - } - catch - { - item = default; - return false; - } - } - - public bool FindClosestSword(ItemId id, out EquipItem item) - { - var list = ItemData.ByType[FullEquipType.Sword]; - try - { - item = list.Where(i => i.ItemId.Id < id.Id && id.Id - i.ItemId.Id < 50).MaxBy(i => i.ItemId.Id); - return true; - } - catch - { - item = default; - return false; - } - } - public EquipItem Identify(EquipSlot slot, PrimaryId id, SecondaryId type, Variant variant, FullEquipType mainhandType = FullEquipType.Unknown) { diff --git a/Glamourer/Services/PcpService.cs b/Glamourer/Services/PcpService.cs deleted file mode 100644 index 3363172..0000000 --- a/Glamourer/Services/PcpService.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Glamourer.Designs; -using Glamourer.Interop.Penumbra; -using Glamourer.State; -using Newtonsoft.Json.Linq; -using OtterGui.Services; -using Penumbra.GameData.Actors; -using Penumbra.GameData.Interop; - -namespace Glamourer.Services; - -public class PcpService : IRequiredService -{ - private readonly Configuration _config; - private readonly PenumbraService _penumbra; - private readonly ActorObjectManager _objects; - private readonly StateManager _state; - private readonly DesignConverter _designConverter; - private readonly DesignManager _designManager; - - public PcpService(Configuration config, PenumbraService penumbra, ActorObjectManager objects, StateManager state, - DesignConverter designConverter, DesignManager designManager) - { - _config = config; - _penumbra = penumbra; - _objects = objects; - _state = state; - _designConverter = designConverter; - _designManager = designManager; - - _config.AttachToPcp = !_config.AttachToPcp; - Set(!_config.AttachToPcp); - } - - public void CleanPcpDesigns() - { - var designs = _designManager.Designs.Where(d => d.Tags.Contains("PCP")).ToList(); - Glamourer.Log.Information($"[PCPService] Deleting {designs.Count} designs containing the tag PCP."); - foreach (var design in designs) - _designManager.Delete(design); - } - - public void Set(bool value) - { - if (value == _config.AttachToPcp) - return; - - _config.AttachToPcp = value; - _config.Save(); - if (value) - { - Glamourer.Log.Information("[PCPService] Attached to PCP handling."); - _penumbra.PcpCreated += OnPcpCreation; - _penumbra.PcpParsed += OnPcpParse; - } - else - { - Glamourer.Log.Information("[PCPService] Detached from PCP handling."); - _penumbra.PcpCreated -= OnPcpCreation; - _penumbra.PcpParsed -= OnPcpParse; - } - } - - private void OnPcpParse(JObject jObj, string modDirectory, Guid collection) - { - Glamourer.Log.Debug("[PCPService] Parsing PCP file."); - if (jObj["Glamourer"] is not JObject glamourer) - return; - - if (glamourer["Version"]!.ToObject() is not 1) - return; - - if (_designConverter.FromJObject(glamourer["Design"] as JObject, true, true) is not { } designBase) - return; - - var actorIdentifier = _objects.Actors.FromJson(jObj["Actor"] as JObject); - if (!actorIdentifier.IsValid) - return; - - var time = new DateTimeOffset(jObj["Time"]?.ToObject() ?? DateTime.UtcNow); - var design = _designManager.CreateClone(designBase, - $"{_config.PcpFolder}/{actorIdentifier} - {jObj["Note"]?.ToObject() ?? string.Empty}", true); - _designManager.AddTag(design, "PCP"); - _designManager.SetWriteProtection(design, true); - _designManager.AddMod(design, new Mod(modDirectory, modDirectory), new ModSettings([], 0, true, false, false)); - _designManager.ChangeDescription(design, $"PCP design created for {actorIdentifier} on {time}."); - _designManager.ChangeResetAdvancedDyes(design, true); - _designManager.SetQuickDesign(design, false); - _designManager.ChangeColor(design, _config.PcpColor); - - Glamourer.Log.Debug("[PCPService] Created PCP design."); - if (_state.GetOrCreate(actorIdentifier, _objects.TryGetValue(actorIdentifier, out var data) ? data.Objects[0] : Actor.Null, - out var state)) - { - _state.ApplyDesign(state!, design, ApplySettings.Manual); - Glamourer.Log.Debug($"[PCPService] Applied PCP design to {actorIdentifier.Incognito(null)}"); - } - } - - private void OnPcpCreation(JObject jObj, ushort index, string path) - { - Glamourer.Log.Debug("[PCPService] Adding Glamourer data to PCP file."); - var actorIdentifier = _objects.Actors.FromJson(jObj["Actor"] as JObject); - if (!actorIdentifier.IsValid) - return; - - if (!_state.GetOrCreate(actorIdentifier, _objects.Objects[(int)index], out var state)) - { - Glamourer.Log.Debug($"[PCPService] Could not get or create state for actor {index}."); - return; - } - - var design = _designConverter.Convert(state, ApplicationRules.All); - jObj["Glamourer"] = new JObject - { - ["Version"] = 1, - ["Design"] = design.JsonSerialize(), - }; - } -} diff --git a/Glamourer/Services/ServiceManager.cs b/Glamourer/Services/ServiceManager.cs index 6cfb4b6..78a0bf0 100644 --- a/Glamourer/Services/ServiceManager.cs +++ b/Glamourer/Services/ServiceManager.cs @@ -71,7 +71,6 @@ public static class StaticServiceManager private static ServiceManager AddEvents(this ServiceManager services) => services.AddSingleton() - .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() @@ -97,7 +96,6 @@ public static class StaticServiceManager private static ServiceManager AddInterop(this ServiceManager services) => services.AddSingleton() - .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() @@ -114,8 +112,7 @@ public static class StaticServiceManager .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() - .AddSingleton(); + .AddSingleton(); private static ServiceManager AddDesigns(this ServiceManager services) => services.AddSingleton() diff --git a/Glamourer/Services/TextureService.cs b/Glamourer/Services/TextureService.cs index a0ec443..29c2343 100644 --- a/Glamourer/Services/TextureService.cs +++ b/Glamourer/Services/TextureService.cs @@ -1,4 +1,3 @@ -using Dalamud.Bindings.ImGui; using Dalamud.Interface; using Dalamud.Interface.Textures.TextureWraps; using Dalamud.Plugin.Services; @@ -13,30 +12,30 @@ public sealed class TextureService(IUiBuilder uiBuilder, IDataManager dataManage { private readonly IDalamudTextureWrap?[] _slotIcons = CreateSlotIcons(uiBuilder); - public (ImTextureID, Vector2, bool) GetIcon(EquipItem item, EquipSlot slot) + public (nint, Vector2, bool) GetIcon(EquipItem item, EquipSlot slot) { if (item.IconId.Id != 0 && TryLoadIcon(item.IconId.Id, out var ret)) - return (ret.Handle, new Vector2(ret.Width, ret.Height), false); + return (ret.ImGuiHandle, new Vector2(ret.Width, ret.Height), false); var idx = slot.ToIndex(); return idx < 12 && _slotIcons[idx] != null - ? (_slotIcons[idx]!.Handle, new Vector2(_slotIcons[idx]!.Width, _slotIcons[idx]!.Height), true) - : (default, Vector2.Zero, true); + ? (_slotIcons[idx]!.ImGuiHandle, new Vector2(_slotIcons[idx]!.Width, _slotIcons[idx]!.Height), true) + : (nint.Zero, Vector2.Zero, true); } - public (ImTextureID, Vector2, bool) GetIcon(EquipItem item, BonusItemFlag slot) + public (nint, Vector2, bool) GetIcon(EquipItem item, BonusItemFlag slot) { if (item.IconId.Id != 0 && TryLoadIcon(item.IconId.Id, out var ret)) - return (ret.Handle, new Vector2(ret.Width, ret.Height), false); + return (ret.ImGuiHandle, new Vector2(ret.Width, ret.Height), false); var idx = slot.ToIndex(); if (idx == uint.MaxValue) - return (default, Vector2.Zero, true); + return (nint.Zero, Vector2.Zero, true); idx += 12; return idx < 13 && _slotIcons[idx] != null - ? (_slotIcons[idx]!.Handle, new Vector2(_slotIcons[idx]!.Width, _slotIcons[idx]!.Height), true) - : (default, Vector2.Zero, true); + ? (_slotIcons[idx]!.ImGuiHandle, new Vector2(_slotIcons[idx]!.Width, _slotIcons[idx]!.Height), true) + : (nint.Zero, Vector2.Zero, true); } public void Dispose() diff --git a/Glamourer/State/FunModule.cs b/Glamourer/State/FunModule.cs index 6abb03a..ae7160c 100644 --- a/Glamourer/State/FunModule.cs +++ b/Glamourer/State/FunModule.cs @@ -4,7 +4,7 @@ using Glamourer.Designs; using Glamourer.GameData; using Glamourer.Gui; using Glamourer.Services; -using Dalamud.Bindings.ImGui; +using ImGuiNET; using OtterGui; using OtterGui.Classes; using OtterGui.Extensions; diff --git a/Glamourer/State/StateApplier.cs b/Glamourer/State/StateApplier.cs index 9800445..698151f 100644 --- a/Glamourer/State/StateApplier.cs +++ b/Glamourer/State/StateApplier.cs @@ -262,14 +262,6 @@ public class StateApplier( _visor.SetVisorState(actor.Model, value); return; } - case MetaIndex.EarState: - foreach (var actor in data.Objects.Where(a => a.Model.IsHuman)) - { - var model = actor.Model; - model.VieraEarsVisible = value; - } - - return; } } @@ -385,7 +377,7 @@ public class StateApplier( var actors = ChangeMetaState(state, MetaIndex.Wetness, true); if (redraw) { - if (withLock && actors.Valid) + if (withLock) state.TempLock(); ForceRedraw(actors); } @@ -410,7 +402,6 @@ public class StateApplier( ChangeMetaState(actors, MetaIndex.HatState, state.ModelData.IsHatVisible()); ChangeMetaState(actors, MetaIndex.WeaponState, state.ModelData.IsWeaponVisible()); ChangeMetaState(actors, MetaIndex.VisorState, state.ModelData.IsVisorToggled()); - ChangeMetaState(actors, MetaIndex.EarState, state.ModelData.AreEarsVisible()); ChangeCrests(actors, state.ModelData.CrestVisibility); ChangeParameters(actors, state.OnlyChangedParameters(), state.ModelData.Parameters); ChangeMaterialValues(actors, state.Materials); @@ -420,6 +411,6 @@ public class StateApplier( return actors; } - public ActorData GetData(ActorState state) + private ActorData GetData(ActorState state) => _objects.TryGetValue(state.Identifier, out var data) ? data : ActorData.Invalid; } diff --git a/Glamourer/State/StateIndex.cs b/Glamourer/State/StateIndex.cs index dff05a3..e3f1863 100644 --- a/Glamourer/State/StateIndex.cs +++ b/Glamourer/State/StateIndex.cs @@ -189,9 +189,8 @@ public readonly record struct StateIndex(int Value) : IEqualityOperators MetaFlag.HatState, MetaVisorState => MetaFlag.VisorState, MetaWeaponState => MetaFlag.WeaponState, - MetaEarState => MetaFlag.EarState, MetaModelId => true, CrestHead => CrestFlag.Head, diff --git a/Glamourer/State/StateListener.cs b/Glamourer/State/StateListener.cs index 4b70718..90520b2 100644 --- a/Glamourer/State/StateListener.cs +++ b/Glamourer/State/StateListener.cs @@ -9,7 +9,6 @@ using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; -using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Object; using Glamourer.GameData; using Penumbra.GameData.DataContainers; @@ -40,7 +39,6 @@ public class StateListener : IDisposable private readonly WeaponLoading _weaponLoading; private readonly HeadGearVisibilityChanged _headGearVisibility; private readonly VisorStateChanged _visorState; - private readonly VieraEarStateChanged _vieraEarState; private readonly WeaponVisibilityChanged _weaponVisibility; private readonly StateFinalized _stateFinalized; private readonly AutoDesignApplier _autoDesignApplier; @@ -64,7 +62,7 @@ public class StateListener : IDisposable WeaponVisibilityChanged weaponVisibility, HeadGearVisibilityChanged headGearVisibility, AutoDesignApplier autoDesignApplier, FunModule funModule, HumanModelList humans, StateApplier applier, MovedEquipment movedEquipment, ActorObjectManager objects, GPoseService gPose, ChangeCustomizeService changeCustomizeService, CustomizeService customizations, ICondition condition, - CrestService crestService, BonusSlotUpdating bonusSlotUpdating, StateFinalized stateFinalized, VieraEarStateChanged vieraEarState) + CrestService crestService, BonusSlotUpdating bonusSlotUpdating, StateFinalized stateFinalized) { _manager = manager; _items = items; @@ -90,7 +88,6 @@ public class StateListener : IDisposable _crestService = crestService; _bonusSlotUpdating = bonusSlotUpdating; _stateFinalized = stateFinalized; - _vieraEarState = vieraEarState; Subscribe(); } @@ -269,7 +266,7 @@ public class StateListener : IDisposable private void OnGearsetDataLoaded(Actor actor, Model model) { - if (!actor.Valid || _condition[ConditionFlag.CreatingCharacter] && actor.Index >= ObjectIndex.CutsceneStart) + if (!actor.Valid || (_condition[ConditionFlag.CreatingCharacter] && actor.Index >= ObjectIndex.CutsceneStart)) return; // ensure actor and state are valid. @@ -713,44 +710,6 @@ public class StateListener : IDisposable } } - /// Handle visor state changes made by the game. - private void OnVieraEarChange(Actor actor, ref bool value) - { - // Value is inverted compared to our own handling. - - // Skip updates when in customize update. - if (ChangeCustomizeService.InUpdate.InMethod) - return; - - if (!actor.IsCharacter) - return; - - if (_condition[ConditionFlag.CreatingCharacter] && actor.Index >= ObjectIndex.CutsceneStart) - return; - - if (!actor.Identifier(_actors, out var identifier)) - return; - - if (!_manager.TryGetValue(identifier, out var state)) - return; - - // Update visor base state. - if (state.BaseData.SetEarsVisible(!value)) - { - // if base state changed, either overwrite the actual value if we have fixed values, - // or overwrite the stored model state with the new one. - if (state.Sources[MetaIndex.EarState].IsFixed()) - value = !state.ModelData.AreEarsVisible(); - else - _manager.ChangeMetaState(state, MetaIndex.EarState, !value, ApplySettings.Game); - } - else - { - // if base state did not change, overwrite the value with the model state one. - value = !state.ModelData.AreEarsVisible(); - } - } - /// Handle Hat Visibility changes. These act on the game object. private void OnHeadGearVisibilityChange(Actor actor, ref bool value) { @@ -843,7 +802,6 @@ public class StateListener : IDisposable _movedEquipment.Subscribe(OnMovedEquipment, MovedEquipment.Priority.StateListener); _weaponLoading.Subscribe(OnWeaponLoading, WeaponLoading.Priority.StateListener); _visorState.Subscribe(OnVisorChange, VisorStateChanged.Priority.StateListener); - _vieraEarState.Subscribe(OnVieraEarChange, VieraEarStateChanged.Priority.StateListener); _headGearVisibility.Subscribe(OnHeadGearVisibilityChange, HeadGearVisibilityChanged.Priority.StateListener); _weaponVisibility.Subscribe(OnWeaponVisibilityChange, WeaponVisibilityChanged.Priority.StateListener); _changeCustomizeService.Subscribe(OnCustomizeChange, ChangeCustomizeService.Priority.StateListener); @@ -862,7 +820,6 @@ public class StateListener : IDisposable _movedEquipment.Unsubscribe(OnMovedEquipment); _weaponLoading.Unsubscribe(OnWeaponLoading); _visorState.Unsubscribe(OnVisorChange); - _vieraEarState.Unsubscribe(OnVieraEarChange); _headGearVisibility.Unsubscribe(OnHeadGearVisibilityChange); _weaponVisibility.Unsubscribe(OnWeaponVisibilityChange); _changeCustomizeService.Unsubscribe(OnCustomizeChange); diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs index e8926d6..2dda310 100644 --- a/Glamourer/State/StateManager.cs +++ b/Glamourer/State/StateManager.cs @@ -158,7 +158,6 @@ public sealed class StateManager( // Visor state is a flag on the game object, but we can see the actual state on the draw object. ret.SetVisor(VisorService.GetVisorState(model)); - ret.SetEarsVisible(model.VieraEarsVisible); foreach (var slot in CrestExtensions.AllRelevantSet) ret.SetCrest(slot, CrestService.GetModelCrest(actor, slot)); @@ -187,7 +186,7 @@ public sealed class StateManager( off = actor.GetOffhand(); FistWeaponHack(ref ret, ref main, ref off); ret.SetVisor(actor.AsCharacter->DrawData.IsVisorToggled); - ret.SetEarsVisible(actor.ShowVieraEars); + foreach (var slot in CrestExtensions.AllRelevantSet) ret.SetCrest(slot, actor.GetCrest(slot)); @@ -271,63 +270,16 @@ public sealed class StateManager( state.Materials.Clear(); - var objects = ActorData.Invalid; + var actors = ActorData.Invalid; if (source is not StateSource.Game) - objects = Applier.ApplyAll(state, redraw, true); + actors = Applier.ApplyAll(state, redraw, true); Glamourer.Log.Verbose( - $"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {objects.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChangeType.Reset, source, state, objects, null); + $"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]"); + StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null); // only invoke if we define this reset call as the final call in our state update. - if (isFinal) - StateFinalized.Invoke(StateFinalizationType.Revert, objects); - } - - public void ResetAdvancedDyes(ActorState state, StateSource source, uint key = 0) - { - if (!state.Unlock(key) || !state.ModelData.IsHuman) - return; - - state.ModelData.Parameters = state.BaseData.Parameters; - - foreach (var flag in CustomizeParameterExtensions.AllFlags) - state.Sources[flag] = StateSource.Game; - - var objects = Applier.GetData(state); - if (source is not StateSource.Game) - foreach (var (idx, mat) in state.Materials.Values) - Applier.ChangeMaterialValue(state, objects, MaterialValueIndex.FromKey(idx), mat.Game); - - state.Materials.Clear(); - - Glamourer.Log.Verbose( - $"Reset advanced dye state of {state.Identifier.Incognito(null)} to game base. [Affecting {objects.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChangeType.Reset, source, state, objects, null); - // Update that we have completed a full operation. (We can do this directly as nothing else is linked) - StateFinalized.Invoke(StateFinalizationType.RevertAdvanced, objects); - } - - public void ResetAdvancedCustomizations(ActorState state, StateSource source, uint key = 0) - { - if (!state.Unlock(key) || !state.ModelData.IsHuman) - return; - - state.ModelData.Parameters = state.BaseData.Parameters; - - foreach (var flag in CustomizeParameterExtensions.AllFlags) - state.Sources[flag] = StateSource.Game; - - var objects = ActorData.Invalid; - if (source is not StateSource.Game) - objects = Applier.ChangeParameters(state, CustomizeParameterExtensions.All, true); - - state.Materials.Clear(); - - Glamourer.Log.Verbose( - $"Reset advanced customization and dye state of {state.Identifier.Incognito(null)} to game base. [Affecting {objects.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChangeType.Reset, source, state, objects, null); - // Update that we have completed a full operation. (We can do this directly as nothing else is linked) - StateFinalized.Invoke(StateFinalizationType.RevertAdvanced, objects); + if(isFinal) + StateFinalized.Invoke(StateFinalizationType.Revert, actors); } public void ResetAdvancedState(ActorState state, StateSource source, uint key = 0) @@ -516,7 +468,7 @@ public sealed class StateManager( || !actor.Model.IsHuman || CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), false); StateChanged.Invoke(StateChangeType.Reapply, source, state, data, null); - if (isFinal) + if(isFinal) StateFinalized.Invoke(StateFinalizationType.Reapply, data); } diff --git a/Glamourer/packages.lock.json b/Glamourer/packages.lock.json index 30a6d00..e6f2fe5 100644 --- a/Glamourer/packages.lock.json +++ b/Glamourer/packages.lock.json @@ -1,18 +1,18 @@ { "version": 1, "dependencies": { - "net10.0-windows7.0": { + "net9.0-windows7.0": { "DalamudPackager": { "type": "Direct", - "requested": "[14.0.0, )", - "resolved": "14.0.0", - "contentHash": "9c1q/eAeAs82mkQWBOaCvbt3GIQxAIadz5b/7pCXDIy9nHPtnRc+tDXEvKR+M36Wvi7n+qBTevRupkLUQp6DFA==" + "requested": "[12.0.0, )", + "resolved": "12.0.0", + "contentHash": "J5TJLV3f16T/E2H2P17ClWjtfEBPpq3yxvqW46eN36JCm6wR+EaoaYkqG9Rm5sHqs3/nK/vKjWWyvEs/jhKoXw==" }, "DotNet.ReproducibleBuilds": { "type": "Direct", - "requested": "[1.2.39, )", - "resolved": "1.2.39", - "contentHash": "fcFN01tDTIQqDuTwr1jUQK/geofiwjG5DycJQOnC72i1SsLAk1ELe+apBOuZ11UMQG8YKFZG1FgvjZPbqHyatg==" + "requested": "[1.2.25, )", + "resolved": "1.2.25", + "contentHash": "xCXiw7BCxHJ8pF6wPepRUddlh2dlQlbr81gXA72hdk4FLHkKXas7EH/n+fk5UCA/YfMqG1Z6XaPiUjDbUNBUzg==" }, "Vortice.Direct3D11": { "type": "Direct", @@ -24,16 +24,6 @@ "Vortice.DXGI": "3.4.2-beta" } }, - "FlatSharp.Compiler": { - "type": "Transitive", - "resolved": "7.9.0", - "contentHash": "MU6808xvdbWJ3Ev+5PKalqQuzvVbn1DzzQH8txRDHGFUNDvHjd+ejqpvnYc9BSJ8Qp8VjkkpJD8OzRYilbPp3A==" - }, - "FlatSharp.Runtime": { - "type": "Transitive", - "resolved": "7.9.0", - "contentHash": "Bm8+WqzEsWNpxqrD5x4x+zQ8dyINlToCreM5FI2oNSfUVc9U9ZB+qztX/jd8rlJb3r0vBSlPwVLpw0xBtPa3Vw==" - }, "JetBrains.Annotations": { "type": "Transitive", "resolved": "2024.3.0", @@ -105,10 +95,8 @@ "penumbra.gamedata": { "type": "Project", "dependencies": { - "FlatSharp.Compiler": "[7.9.0, )", - "FlatSharp.Runtime": "[7.9.0, )", "OtterGui": "[1.0.0, )", - "Penumbra.Api": "[5.13.0, )", + "Penumbra.Api": "[5.6.1, )", "Penumbra.String": "[1.0.6, )" } }, diff --git a/OtterGui b/OtterGui index 6f32364..abfce28 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 6f3236453b1edfaa25c8edcc8b39a9d9b2fc18ac +Subproject commit abfce28e0bacdea841f029f59bc19971c43814d8 diff --git a/Penumbra.Api b/Penumbra.Api index e4934cc..f578091 160000 --- a/Penumbra.Api +++ b/Penumbra.Api @@ -1 +1 @@ -Subproject commit e4934ccca0379f22dadf989ab2d34f30b3c5c7ea +Subproject commit f578091fa579fb098c21036b492ff6e6088184c9 diff --git a/Penumbra.GameData b/Penumbra.GameData index 2ff50e6..002260d 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit 2ff50e68f7c951f0f8b25957a400a2e32ed9d6dc +Subproject commit 002260d9815e571f1496c50374f5b712818e9880 diff --git a/Penumbra.String b/Penumbra.String index 0315144..2896c05 160000 --- a/Penumbra.String +++ b/Penumbra.String @@ -1 +1 @@ -Subproject commit 0315144ab5614c11911e2a4dddf436fb18c5d7e3 +Subproject commit 2896c0561f60827f97408650d52a15c38f4d9d10 diff --git a/repo.json b/repo.json index fd4c07f..3e8e6dc 100644 --- a/repo.json +++ b/repo.json @@ -17,19 +17,19 @@ "Character" ], "InternalName": "Glamourer", - "AssemblyVersion": "1.5.1.5", - "TestingAssemblyVersion": "1.5.1.5", + "AssemblyVersion": "1.3.8.5", + "TestingAssemblyVersion": "1.3.8.5", "RepoUrl": "https://github.com/Ottermandias/Glamourer", "ApplicableVersion": "any", - "DalamudApiLevel": 13, - "TestingDalamudApiLevel": 13, + "DalamudApiLevel": 12, + "TestingDalamudApiLevel": 12, "IsHide": "False", "IsTestingExclusive": "False", "DownloadCount": 1, "LastUpdate": 1618608322, - "DownloadLinkInstall": "https://github.com/Ottermandias/Glamourer/releases/download/1.5.1.5/Glamourer.zip", - "DownloadLinkUpdate": "https://github.com/Ottermandias/Glamourer/releases/download/1.5.1.5/Glamourer.zip", - "DownloadLinkTesting": "https://github.com/Ottermandias/Glamourer/releases/download/1.5.1.5/Glamourer.zip", + "DownloadLinkInstall": "https://github.com/Ottermandias/Glamourer/releases/download/1.3.8.5/Glamourer.zip", + "DownloadLinkUpdate": "https://github.com/Ottermandias/Glamourer/releases/download/1.3.8.5/Glamourer.zip", + "DownloadLinkTesting": "https://github.com/Ottermandias/Glamourer/releases/download/1.3.8.5/Glamourer.zip", "IconUrl": "https://raw.githubusercontent.com/Ottermandias/Glamourer/main/images/icon.png" } ]