diff --git a/Glamourer/Automation/AutoDesign.cs b/Glamourer/Automation/AutoDesign.cs index 7ceea6a..9fc8ca7 100644 --- a/Glamourer/Automation/AutoDesign.cs +++ b/Glamourer/Automation/AutoDesign.cs @@ -1,9 +1,9 @@ using Glamourer.Designs; using Glamourer.Designs.Special; using Glamourer.GameData; -using Glamourer.Interop.Structs; using Newtonsoft.Json.Linq; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Automation; diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs index 03fdda6..a3b912d 100644 --- a/Glamourer/Automation/AutoDesignApplier.cs +++ b/Glamourer/Automation/AutoDesignApplier.cs @@ -5,12 +5,13 @@ using Glamourer.Designs.Links; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Interop.Material; -using Glamourer.Interop.Structs; using Glamourer.State; using Penumbra.GameData.Actors; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; +using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Automation; diff --git a/Glamourer/Events/HeadGearVisibilityChanged.cs b/Glamourer/Events/HeadGearVisibilityChanged.cs index 91454b3..d8f722b 100644 --- a/Glamourer/Events/HeadGearVisibilityChanged.cs +++ b/Glamourer/Events/HeadGearVisibilityChanged.cs @@ -1,5 +1,5 @@ -using Glamourer.Interop.Structs; using OtterGui.Classes; +using Penumbra.GameData.Interop; namespace Glamourer.Events; diff --git a/Glamourer/Events/SlotUpdating.cs b/Glamourer/Events/SlotUpdating.cs index 97f9be9..8a766fb 100644 --- a/Glamourer/Events/SlotUpdating.cs +++ b/Glamourer/Events/SlotUpdating.cs @@ -1,6 +1,6 @@ -using Glamourer.Interop.Structs; using OtterGui.Classes; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Events; diff --git a/Glamourer/Events/VisorStateChanged.cs b/Glamourer/Events/VisorStateChanged.cs index d71eccd..8e70002 100644 --- a/Glamourer/Events/VisorStateChanged.cs +++ b/Glamourer/Events/VisorStateChanged.cs @@ -1,5 +1,5 @@ -using Glamourer.Interop.Structs; using OtterGui.Classes; +using Penumbra.GameData.Interop; namespace Glamourer.Events; diff --git a/Glamourer/Events/WeaponLoading.cs b/Glamourer/Events/WeaponLoading.cs index 41da2aa..fda0b2f 100644 --- a/Glamourer/Events/WeaponLoading.cs +++ b/Glamourer/Events/WeaponLoading.cs @@ -1,6 +1,6 @@ -using Glamourer.Interop.Structs; using OtterGui.Classes; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Events; diff --git a/Glamourer/Events/WeaponVisibilityChanged.cs b/Glamourer/Events/WeaponVisibilityChanged.cs index a94eabf..f75fa68 100644 --- a/Glamourer/Events/WeaponVisibilityChanged.cs +++ b/Glamourer/Events/WeaponVisibilityChanged.cs @@ -1,5 +1,5 @@ -using Glamourer.Interop.Structs; using OtterGui.Classes; +using Penumbra.GameData.Interop; namespace Glamourer.Events; diff --git a/Glamourer/Glamourer.csproj b/Glamourer/Glamourer.csproj index 87954e9..a552f17 100644 --- a/Glamourer/Glamourer.csproj +++ b/Glamourer/Glamourer.csproj @@ -1,6 +1,6 @@  - net7.0-windows + net8.0-windows preview x64 Glamourer diff --git a/Glamourer/Gui/Materials/AdvancedDyePopup.cs b/Glamourer/Gui/Materials/AdvancedDyePopup.cs index df00e1c..c2dbdbe 100644 --- a/Glamourer/Gui/Materials/AdvancedDyePopup.cs +++ b/Glamourer/Gui/Materials/AdvancedDyePopup.cs @@ -5,7 +5,6 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; using FFXIVClientStructs.Interop; using Glamourer.Designs; using Glamourer.Interop.Material; -using Glamourer.Interop.Structs; using Glamourer.State; using ImGuiNET; using OtterGui; @@ -13,6 +12,7 @@ using OtterGui.Raii; using OtterGui.Services; using Penumbra.GameData.Enums; using Penumbra.GameData.Files; +using Penumbra.GameData.Interop; using Penumbra.String; namespace Glamourer.Gui.Materials; diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs index 3cf50f5..b8ecd53 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs @@ -18,6 +18,8 @@ using OtterGui.Raii; using Penumbra.GameData.Actors; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; +using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Gui.Tabs.ActorTab; diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs index 98fbcab..2130efe 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTesterPanel.cs @@ -58,7 +58,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelGetAllCustomizationFromCharacter); ImGui.TableNextColumn(); base64 = GlamourerIpc.GetAllCustomizationFromCharacterSubscriber(_pluginInterface) - .Invoke(_objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); if (base64 != null) ImGuiUtil.CopyOnClickSelectable(base64); else @@ -66,7 +66,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelGetAllCustomizationFromLockedCharacter); ImGui.TableNextColumn(); - var base64Locked = GlamourerIpc.GetAllCustomizationFromLockedCharacterSubscriber(_pluginInterface).Invoke(_objectManager.Objects[_gameObjectIndex] as Character, 1337); + var base64Locked = GlamourerIpc.GetAllCustomizationFromLockedCharacterSubscriber(_pluginInterface).Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex), 1337); if (base64Locked != null) ImGuiUtil.CopyOnClickSelectable(base64Locked); else @@ -80,7 +80,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelRevertCharacter); ImGui.TableNextColumn(); if (ImGui.Button("Revert##Character")) - GlamourerIpc.RevertCharacterSubscriber(_pluginInterface).Invoke(_objectManager.Objects[_gameObjectIndex] as Character); + GlamourerIpc.RevertCharacterSubscriber(_pluginInterface).Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAll); ImGui.TableNextColumn(); @@ -96,13 +96,13 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Apply##AllCharacter")) GlamourerIpc.ApplyAllToCharacterSubscriber(_pluginInterface) - .Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(_base64Apply, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllOnceToCharacter); ImGui.TableNextColumn(); if (ImGui.Button("Apply Once##AllCharacter")) GlamourerIpc.ApplyAllOnceToCharacterSubscriber(_pluginInterface) - .Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(_base64Apply, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyEquipment); ImGui.TableNextColumn(); @@ -113,7 +113,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Apply##EquipCharacter")) GlamourerIpc.ApplyOnlyEquipmentToCharacterSubscriber(_pluginInterface) - .Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(_base64Apply, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyCustomization); ImGui.TableNextColumn(); @@ -124,7 +124,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Apply##CustomizeCharacter")) GlamourerIpc.ApplyOnlyCustomizationToCharacterSubscriber(_pluginInterface) - .Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(_base64Apply, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyByGuid); ImGui.TableNextColumn(); @@ -140,25 +140,25 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Apply##ByGuidCharacter") && Guid.TryParse(_designIdentifier, out var guid2)) GlamourerIpc.ApplyByGuidToCharacterSubscriber(_pluginInterface) - .Invoke(guid2, _objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(guid2, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyByGuidOnceToCharacter); ImGui.TableNextColumn(); if (ImGui.Button("Apply Once##ByGuidCharacter") && Guid.TryParse(_designIdentifier, out var guid2Once)) GlamourerIpc.ApplyByGuidOnceToCharacterSubscriber(_pluginInterface) - .Invoke(guid2Once, _objectManager.Objects[_gameObjectIndex] as Character); + .Invoke(guid2Once, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex)); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllLock); ImGui.TableNextColumn(); if (ImGui.Button("Apply With Lock##CustomizeCharacter")) GlamourerIpc.ApplyAllToCharacterLockSubscriber(_pluginInterface) - .Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character, 1337); + .Invoke(_base64Apply, _objectManager.Objects.GetDalamudCharacter(_gameObjectIndex), 1337); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelUnlock); ImGui.TableNextColumn(); if (ImGui.Button("Unlock##CustomizeCharacter")) GlamourerIpc.UnlockSubscriber(_pluginInterface) - .Invoke(_objectManager.Objects[_gameObjectIndex] as Character, 1337); + .Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex), 1337); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelUnlockAll); ImGui.TableNextColumn(); @@ -170,7 +170,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Revert##CustomizeCharacter")) GlamourerIpc.RevertToAutomationCharacterSubscriber(_pluginInterface) - .Invoke(_objectManager.Objects[_gameObjectIndex] as Character, 1337); + .Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex), 1337); ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelGetDesignList); @@ -184,7 +184,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Set##SetItem")) _setItemEc = (GlamourerIpc.GlamourerErrorCode)GlamourerIpc.SetItemSubscriber(_pluginInterface) - .Invoke(_objectManager.Objects[_gameObjectIndex] as Character, (byte)_slot, _customItemId.Id, _stainId.Id, 1337); + .Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex), (byte)_slot, _customItemId.Id, _stainId.Id, 1337); if (_setItemEc != GlamourerIpc.GlamourerErrorCode.Success) { ImGui.SameLine(); @@ -195,7 +195,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag ImGui.TableNextColumn(); if (ImGui.Button("Set Once##SetItem")) _setItemOnceEc = (GlamourerIpc.GlamourerErrorCode)GlamourerIpc.SetItemOnceSubscriber(_pluginInterface) - .Invoke(_objectManager.Objects[_gameObjectIndex] as Character, (byte)_slot, _customItemId.Id, _stainId.Id, 1337); + .Invoke(_objectManager.Objects.GetDalamudCharacter(_gameObjectIndex), (byte)_slot, _customItemId.Id, _stainId.Id, 1337); if (_setItemOnceEc != GlamourerIpc.GlamourerErrorCode.Success) { ImGui.SameLine(); @@ -229,7 +229,7 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag { var tmp = _customItemId.Id; if (ImGuiUtil.InputUlong("Custom Item ID", ref tmp)) - _customItemId = (CustomItemId)tmp; + _customItemId = tmp; var width = ImGui.GetContentRegionAvail().X; EquipSlotCombo.Draw("Equip Slot", string.Empty, ref _slot); var value = (int)_stainId.Id; diff --git a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs index e5f691d..2268ee5 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs @@ -1,5 +1,4 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using FFXIVClientStructs.FFXIV.Shader; using Glamourer.GameData; using Glamourer.Interop; using Glamourer.Interop.Structs; @@ -8,7 +7,9 @@ using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; +using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Gui.Tabs.DebugTab; @@ -30,7 +31,7 @@ public unsafe class ModelEvaluationPanel( public void Draw() { ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0); - var actor = (Actor)_objectManager.Objects.GetObjectAddress(_gameObjectIndex); + var actor = _objectManager.Objects[_gameObjectIndex]; var model = actor.Model; using var table = ImRaii.Table("##evaluationTable", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg); ImGui.TableNextColumn(); diff --git a/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs b/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs index e53a1f7..6b9a7a3 100644 --- a/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/PenumbraPanel.cs @@ -1,12 +1,12 @@ using Dalamud.Interface.Utility; using Glamourer.Interop.Penumbra; -using Glamourer.Interop.Structs; using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.Api.Enums; using Penumbra.GameData.Enums; using Penumbra.GameData.Gui.Debug; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Gui.Tabs.DebugTab; diff --git a/Glamourer/Interop/ChangeCustomizeService.cs b/Glamourer/Interop/ChangeCustomizeService.cs index d055adc..cfff90f 100644 --- a/Glamourer/Interop/ChangeCustomizeService.cs +++ b/Glamourer/Interop/ChangeCustomizeService.cs @@ -2,8 +2,8 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using Glamourer.Events; -using Glamourer.Interop.Structs; using OtterGui.Classes; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop; diff --git a/Glamourer/Interop/CrestService.cs b/Glamourer/Interop/CrestService.cs index 7764573..75e2a81 100644 --- a/Glamourer/Interop/CrestService.cs +++ b/Glamourer/Interop/CrestService.cs @@ -3,9 +3,9 @@ using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Glamourer.Interop.Structs; using OtterGui.Classes; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; namespace Glamourer.Interop; diff --git a/Glamourer/Interop/JobService.cs b/Glamourer/Interop/JobService.cs index bff849e..1797809 100644 --- a/Glamourer/Interop/JobService.cs +++ b/Glamourer/Interop/JobService.cs @@ -2,9 +2,9 @@ using Dalamud.Hooking; using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; -using Glamourer.Interop.Structs; using Penumbra.GameData; using Penumbra.GameData.DataContainers; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop; @@ -21,7 +21,7 @@ public class JobService : IDisposable public event Action? JobChanged; - public JobService(DictJob jobs, DictJobGroup jobGroups, IDataManager gameData, IGameInteropProvider interop) + public JobService(DictJob jobs, DictJobGroup jobGroups, IGameInteropProvider interop) { interop.InitializeFromAttributes(this); _characterDataOffset = Marshal.OffsetOf(nameof(Character.CharacterData)); diff --git a/Glamourer/Interop/Material/LiveColorTablePreviewer.cs b/Glamourer/Interop/Material/LiveColorTablePreviewer.cs index 5e1fa06..e732472 100644 --- a/Glamourer/Interop/Material/LiveColorTablePreviewer.cs +++ b/Glamourer/Interop/Material/LiveColorTablePreviewer.cs @@ -1,5 +1,4 @@ using Dalamud.Plugin.Services; -using Glamourer.Interop.Structs; using ImGuiNET; using OtterGui.Services; using Penumbra.GameData.Files; @@ -9,9 +8,9 @@ namespace Glamourer.Interop.Material; public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable { - private readonly IObjectTable _objects; - private readonly IFramework _framework; - private readonly DirectXService _directXService; + private readonly global::Penumbra.GameData.Interop.ObjectManager _objects; + private readonly IFramework _framework; + private readonly DirectXService _directXService; public MaterialValueIndex LastValueIndex { get; private set; } = MaterialValueIndex.Invalid; public MtrlFile.ColorTable LastOriginalColorTable { get; private set; } @@ -20,7 +19,7 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable private ObjectIndex _objectIndex = ObjectIndex.AnyIndex; private MtrlFile.ColorTable _originalColorTable; - public LiveColorTablePreviewer(IObjectTable objects, IFramework framework, DirectXService directXService) + public LiveColorTablePreviewer(global::Penumbra.GameData.Interop.ObjectManager objects, IFramework framework, DirectXService directXService) { _objects = objects; _framework = framework; @@ -33,7 +32,7 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable if (LastValueIndex.DrawObject is MaterialValueIndex.DrawObjectType.Invalid || _lastObjectIndex == ObjectIndex.AnyIndex) return; - var actor = (Actor)_objects.GetObjectAddress(_lastObjectIndex.Index); + var actor = _objects[_lastObjectIndex]; if (actor.IsCharacter && LastValueIndex.TryGetTexture(actor, out var texture)) _directXService.ReplaceColorTable(texture, LastOriginalColorTable); @@ -51,7 +50,7 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable return; } - var actor = (Actor)_objects.GetObjectAddress(_objectIndex.Index); + var actor = _objects[_objectIndex]; if (!actor.IsCharacter) { _valueIndex = MaterialValueIndex.Invalid; diff --git a/Glamourer/Interop/Material/MaterialManager.cs b/Glamourer/Interop/Material/MaterialManager.cs index 40af5a2..1fb758b 100644 --- a/Glamourer/Interop/Material/MaterialManager.cs +++ b/Glamourer/Interop/Material/MaterialManager.cs @@ -2,12 +2,12 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; using Glamourer.Designs; using Glamourer.Interop.Penumbra; -using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Services; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; using Penumbra.GameData.Files; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop.Material; diff --git a/Glamourer/Interop/Material/MaterialService.cs b/Glamourer/Interop/Material/MaterialService.cs index 48b5fe7..03165a3 100644 --- a/Glamourer/Interop/Material/MaterialService.cs +++ b/Glamourer/Interop/Material/MaterialService.cs @@ -1,7 +1,7 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; -using Glamourer.Interop.Structs; using Lumina.Data.Files; +using Penumbra.GameData.Interop; using static Penumbra.GameData.Files.MtrlFile; using Texture = FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Texture; diff --git a/Glamourer/Interop/Material/MaterialValueIndex.cs b/Glamourer/Interop/Material/MaterialValueIndex.cs index f461637..ec9996b 100644 --- a/Glamourer/Interop/Material/MaterialValueIndex.cs +++ b/Glamourer/Interop/Material/MaterialValueIndex.cs @@ -1,9 +1,9 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.Interop; -using Glamourer.Interop.Structs; using Newtonsoft.Json; using Penumbra.GameData.Enums; using Penumbra.GameData.Files; +using Penumbra.GameData.Interop; namespace Glamourer.Interop.Material; diff --git a/Glamourer/Interop/Material/PrepareColorSet.cs b/Glamourer/Interop/Material/PrepareColorSet.cs index 0f5be0d..5257c4e 100644 --- a/Glamourer/Interop/Material/PrepareColorSet.cs +++ b/Glamourer/Interop/Material/PrepareColorSet.cs @@ -2,11 +2,11 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; -using Glamourer.Interop.Structs; using OtterGui.Classes; using OtterGui.Services; using Penumbra.GameData.Enums; using Penumbra.GameData.Files; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop.Material; diff --git a/Glamourer/Interop/MetaService.cs b/Glamourer/Interop/MetaService.cs index b6bd511..a862e59 100644 --- a/Glamourer/Interop/MetaService.cs +++ b/Glamourer/Interop/MetaService.cs @@ -2,7 +2,7 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.Character; using Glamourer.Events; -using Glamourer.Interop.Structs; +using Penumbra.GameData.Interop; namespace Glamourer.Interop; diff --git a/Glamourer/Interop/ObjectManager.cs b/Glamourer/Interop/ObjectManager.cs index c44fcd0..6a1d8a1 100644 --- a/Glamourer/Interop/ObjectManager.cs +++ b/Glamourer/Interop/ObjectManager.cs @@ -4,28 +4,15 @@ using FFXIVClientStructs.FFXIV.Client.Game.Control; using Glamourer.Interop.Structs; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; namespace Glamourer.Interop; -public class ObjectManager : IReadOnlyDictionary +public class ObjectManager(IFramework framework, IClientState clientState, global::Penumbra.GameData.Interop.ObjectManager objects, ActorManager actors, ITargetManager targets) + : IReadOnlyDictionary { - private readonly IFramework _framework; - private readonly IClientState _clientState; - private readonly IObjectTable _objects; - private readonly ActorManager _actors; - private readonly ITargetManager _targets; - - public IObjectTable Objects - => _objects; - - public ObjectManager(IFramework framework, IClientState clientState, IObjectTable objects, ActorManager actors, ITargetManager targets) - { - _framework = framework; - _clientState = clientState; - _objects = objects; - _actors = actors; - _targets = targets; - } + public global::Penumbra.GameData.Interop.ObjectManager Objects + => objects; public DateTime LastUpdate { get; private set; } @@ -41,39 +28,39 @@ public class ObjectManager : IReadOnlyDictionary public void Update() { - var lastUpdate = _framework.LastUpdate; + var lastUpdate = framework.LastUpdate; if (lastUpdate <= LastUpdate) return; LastUpdate = lastUpdate; - World = (ushort)(_clientState.LocalPlayer?.CurrentWorld.Id ?? 0u); + World = (ushort)(clientState.LocalPlayer?.CurrentWorld.Id ?? 0u); _identifiers.Clear(); _allWorldIdentifiers.Clear(); _nonOwnedIdentifiers.Clear(); for (var i = 0; i < (int)ScreenActor.CutsceneStart; ++i) { - Actor character = _objects.GetObjectAddress(i); - if (character.Identifier(_actors, out var identifier)) + var character = objects[i]; + if (character.Identifier(actors, out var identifier)) HandleIdentifier(identifier, character); } for (var i = (int)ScreenActor.CutsceneStart; i < (int)ScreenActor.CutsceneEnd; ++i) { - Actor character = _objects.GetObjectAddress(i); + var character = objects[i]; // Technically the game does not create holes in cutscenes or GPose. // But for Brio compatibility, we allow holes in GPose. // Since GPose always has the event actor in the first cutscene slot, we can still optimize in this case. if (!character.Valid && i == (int)ScreenActor.CutsceneStart) break; - HandleIdentifier(character.GetIdentifier(_actors), character); + HandleIdentifier(character.GetIdentifier(actors), character); } void AddSpecial(ScreenActor idx, string label) { - Actor actor = _objects.GetObjectAddress((int)idx); - if (actor.Identifier(_actors, out var ident)) + var actor = objects[(int)idx]; + if (actor.Identifier(actors, out var ident)) { var data = new ActorData(actor, label); _identifiers.Add(ident, data); @@ -89,10 +76,10 @@ public class ObjectManager : IReadOnlyDictionary AddSpecial(ScreenActor.Card7, "Card Actor 7"); AddSpecial(ScreenActor.Card8, "Card Actor 8"); - for (var i = (int)ScreenActor.ScreenEnd; i < _objects.Length; ++i) + for (var i = (int)ScreenActor.ScreenEnd; i < objects.Count; ++i) { - Actor character = _objects.GetObjectAddress(i); - if (character.Identifier(_actors, out var identifier)) + var character = objects[i]; + if (character.Identifier(actors, out var identifier)) HandleIdentifier(identifier, character); } @@ -117,7 +104,7 @@ public class ObjectManager : IReadOnlyDictionary if (identifier.Type is IdentifierType.Player or IdentifierType.Owned) { - var allWorld = _actors.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue, + var allWorld = actors.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue, identifier.Kind, identifier.DataId); @@ -134,7 +121,7 @@ public class ObjectManager : IReadOnlyDictionary if (identifier.Type is IdentifierType.Owned) { - var nonOwned = _actors.CreateNpc(identifier.Kind, identifier.DataId); + var nonOwned = actors.CreateNpc(identifier.Kind, identifier.DataId); if (!_nonOwnedIdentifiers.TryGetValue(nonOwned, out var nonOwnedData)) { nonOwnedData = new ActorData(character, nonOwned.ToString()); @@ -148,26 +135,26 @@ public class ObjectManager : IReadOnlyDictionary } public Actor GPosePlayer - => _objects.GetObjectAddress((int)ScreenActor.GPosePlayer); + => objects[(int)ScreenActor.GPosePlayer]; public Actor Player - => _objects.GetObjectAddress(0); + => objects[0]; public unsafe Actor Target - => _clientState.IsGPosing ? TargetSystem.Instance()->GPoseTarget : TargetSystem.Instance()->Target; + => clientState.IsGPosing ? TargetSystem.Instance()->GPoseTarget : TargetSystem.Instance()->Target; public Actor Focus - => _targets.FocusTarget?.Address ?? nint.Zero; + => targets.FocusTarget?.Address ?? nint.Zero; public Actor MouseOver - => _targets.MouseOverTarget?.Address ?? nint.Zero; + => targets.MouseOverTarget?.Address ?? nint.Zero; public (ActorIdentifier Identifier, ActorData Data) PlayerData { get { Update(); - return Player.Identifier(_actors, out var ident) && _identifiers.TryGetValue(ident, out var data) + return Player.Identifier(actors, out var ident) && _identifiers.TryGetValue(ident, out var data) ? (ident, data) : (ident, ActorData.Invalid); } @@ -178,7 +165,7 @@ public class ObjectManager : IReadOnlyDictionary get { Update(); - return Target.Identifier(_actors, out var ident) && _identifiers.TryGetValue(ident, out var data) + return Target.Identifier(actors, out var ident) && _identifiers.TryGetValue(ident, out var data) ? (ident, data) : (ident, ActorData.Invalid); } diff --git a/Glamourer/Interop/Penumbra/ModSettingApplier.cs b/Glamourer/Interop/Penumbra/ModSettingApplier.cs index 198c6ad..2b72fff 100644 --- a/Glamourer/Interop/Penumbra/ModSettingApplier.cs +++ b/Glamourer/Interop/Penumbra/ModSettingApplier.cs @@ -1,8 +1,8 @@ using Glamourer.Designs.Links; -using Glamourer.Interop.Structs; using Glamourer.Services; using Glamourer.State; using OtterGui.Services; +using Penumbra.GameData.Interop; namespace Glamourer.Interop.Penumbra; diff --git a/Glamourer/Interop/Penumbra/PenumbraService.cs b/Glamourer/Interop/Penumbra/PenumbraService.cs index 7f26e4f..4e1d9c4 100644 --- a/Glamourer/Interop/Penumbra/PenumbraService.cs +++ b/Glamourer/Interop/Penumbra/PenumbraService.cs @@ -1,11 +1,11 @@ using Dalamud.Interface.Internal.Notifications; using Dalamud.Plugin; using Glamourer.Events; -using Glamourer.Interop.Structs; using OtterGui.Classes; using Penumbra.Api; using Penumbra.Api.Enums; using Penumbra.Api.Helpers; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop.Penumbra; diff --git a/Glamourer/Interop/ScalingService.cs b/Glamourer/Interop/ScalingService.cs index c7b80cb..c148bbd 100644 --- a/Glamourer/Interop/ScalingService.cs +++ b/Glamourer/Interop/ScalingService.cs @@ -3,7 +3,7 @@ using Dalamud.Hooking; using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; -using Glamourer.Interop.Structs; +using Penumbra.GameData.Interop; using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character; namespace Glamourer.Interop; diff --git a/Glamourer/Interop/Structs/Actor.cs b/Glamourer/Interop/Structs/Actor.cs deleted file mode 100644 index a5164d7..0000000 --- a/Glamourer/Interop/Structs/Actor.cs +++ /dev/null @@ -1,142 +0,0 @@ -using Penumbra.GameData.Actors; -using FFXIVClientStructs.FFXIV.Client.Game.Character; -using FFXIVClientStructs.FFXIV.Client.Game.Object; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; -using Penumbra.String; - -namespace Glamourer.Interop.Structs; - -public readonly unsafe struct Actor : IEquatable -{ - private Actor(nint address) - => Address = address; - - public static readonly Actor Null = new(nint.Zero); - - public readonly nint Address; - - public GameObject* AsObject - => (GameObject*)Address; - - public Character* AsCharacter - => (Character*)Address; - - public bool Valid - => Address != nint.Zero; - - public bool IsCharacter - => Valid && AsObject->IsCharacter(); - - public static implicit operator Actor(nint? pointer) - => new(pointer ?? nint.Zero); - - public static implicit operator Actor(GameObject* pointer) - => new((nint)pointer); - - public static implicit operator Actor(Character* pointer) - => new((nint)pointer); - - public static implicit operator nint(Actor actor) - => actor.Address; - - public bool IsGPoseOrCutscene - => Index.Index is >= (int)ScreenActor.CutsceneStart and < (int)ScreenActor.CutsceneEnd; - - public bool IsTransformed - => AsCharacter->CharacterData.TransformationId != 0; - - public ActorIdentifier GetIdentifier(ActorManager actors) - => actors.FromObject(AsObject, out _, true, true, false); - - public ByteString Utf8Name - => Valid ? new ByteString(AsObject->Name) : ByteString.Empty; - - public bool Identifier(ActorManager actors, out ActorIdentifier ident) - { - if (Valid) - { - ident = GetIdentifier(actors); - return ident.IsValid; - } - - ident = ActorIdentifier.Invalid; - return false; - } - - public ObjectIndex Index - => Valid ? AsObject->ObjectIndex : ObjectIndex.AnyIndex; - - public Model Model - => Valid ? AsObject->DrawObject : null; - - public byte Job - => IsCharacter ? AsCharacter->CharacterData.ClassJob : (byte)0; - - public static implicit operator bool(Actor actor) - => actor.Address != nint.Zero; - - public static bool operator true(Actor actor) - => actor.Address != nint.Zero; - - public static bool operator false(Actor actor) - => actor.Address == nint.Zero; - - public static bool operator !(Actor actor) - => actor.Address == nint.Zero; - - public bool Equals(Actor other) - => Address == other.Address; - - public override bool Equals(object? obj) - => obj is Actor other && Equals(other); - - public override int GetHashCode() - => Address.GetHashCode(); - - public static bool operator ==(Actor lhs, Actor rhs) - => lhs.Address == rhs.Address; - - public static bool operator !=(Actor lhs, Actor rhs) - => lhs.Address != rhs.Address; - - /// Only valid for characters. - public CharacterArmor GetArmor(EquipSlot slot) - => ((CharacterArmor*)&AsCharacter->DrawData.Head)[slot.ToIndex()]; - - public bool GetCrest(CrestFlag slot) - => CrestBitfield.HasFlag(slot); - - public CharacterWeapon GetMainhand() - => new(AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.MainHand).ModelId.Value); - - public CharacterWeapon GetOffhand() - => new(AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.OffHand).ModelId.Value); - - public CustomizeArray GetCustomize() - => *(CustomizeArray*)&AsCharacter->DrawData.CustomizeData; - - // TODO remove this when available in ClientStructs - internal ref CrestFlag CrestBitfield - => ref *(CrestFlag*)((byte*)Address + 0x1BBB); - - public override string ToString() - => $"0x{Address:X}"; - - public OnlineStatus OnlineStatus - => (OnlineStatus)AsCharacter->CharacterData.OnlineStatus; -} - -public enum OnlineStatus : byte -{ - Normal = 0x00, - Mentor = 0x1B, - PvEMentor = 0x1C, - TradeMentor = 0x1D, - PvPMentor = 0x1E, - Busy = 0x0C, - Away = 0x11, - MeldMateria = 0x15, - RolePlaying = 0x16, - LookingForGroup = 0x17, -} diff --git a/Glamourer/Interop/Structs/ActorData.cs b/Glamourer/Interop/Structs/ActorData.cs index c1a0ea4..5cfbcbe 100644 --- a/Glamourer/Interop/Structs/ActorData.cs +++ b/Glamourer/Interop/Structs/ActorData.cs @@ -1,4 +1,5 @@ using OtterGui.Log; +using Penumbra.GameData.Interop; namespace Glamourer.Interop.Structs; @@ -15,7 +16,7 @@ public readonly struct ActorData public ActorData(Actor actor, string label) { - Objects = new List { actor }; + Objects = [actor]; Label = label; } @@ -23,7 +24,7 @@ public readonly struct ActorData private ActorData(bool _) { - Objects = new List(0); + Objects = []; Label = string.Empty; } diff --git a/Glamourer/Interop/Structs/Model.cs b/Glamourer/Interop/Structs/Model.cs deleted file mode 100644 index fc7b880..0000000 --- a/Glamourer/Interop/Structs/Model.cs +++ /dev/null @@ -1,259 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.Game.Character; -using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using FFXIVClientStructs.FFXIV.Shader; -using Glamourer.GameData; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; -using Object = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.Object; -using ObjectType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType; - -namespace Glamourer.Interop.Structs; - -public readonly unsafe struct Model : IEquatable -{ - private Model(nint address) - => Address = address; - - public readonly nint Address; - - public static readonly Model Null = new(0); - - public DrawObject* AsDrawObject - => (DrawObject*)Address; - - public CharacterBase* AsCharacterBase - => (CharacterBase*)Address; - - public Weapon* AsWeapon - => (Weapon*)Address; - - public Human* AsHuman - => (Human*)Address; - - public static implicit operator Model(nint? pointer) - => new(pointer ?? nint.Zero); - - public static implicit operator Model(Object* pointer) - => new((nint)pointer); - - public static implicit operator Model(DrawObject* pointer) - => new((nint)pointer); - - public static implicit operator Model(Human* pointer) - => new((nint)pointer); - - public static implicit operator Model(CharacterBase* pointer) - => new((nint)pointer); - - public static implicit operator nint(Model model) - => model.Address; - - public bool Valid - => Address != nint.Zero; - - public bool IsCharacterBase - => Valid && AsDrawObject->Object.GetObjectType() == ObjectType.CharacterBase; - - public bool IsHuman - => IsCharacterBase && AsCharacterBase->GetModelType() == CharacterBase.ModelType.Human; - - public bool IsWeapon - => IsCharacterBase && AsCharacterBase->GetModelType() == CharacterBase.ModelType.Weapon; - - public static implicit operator bool(Model actor) - => actor.Address != nint.Zero; - - public static bool operator true(Model actor) - => actor.Address != nint.Zero; - - public static bool operator false(Model actor) - => actor.Address == nint.Zero; - - public static bool operator !(Model actor) - => actor.Address == nint.Zero; - - public bool Equals(Model other) - => Address == other.Address; - - public override bool Equals(object? obj) - => obj is Model other && Equals(other); - - public override int GetHashCode() - => Address.GetHashCode(); - - public static bool operator ==(Model lhs, Model rhs) - => lhs.Address == rhs.Address; - - public static bool operator !=(Model lhs, Model rhs) - => lhs.Address != rhs.Address; - - /// Only valid for humans. - public CharacterArmor GetArmor(EquipSlot slot) - => ((CharacterArmor*)&AsHuman->Head)[slot.ToIndex()]; - - public CustomizeArray GetCustomize() - => *(CustomizeArray*)&AsHuman->Customize; - - public (Model Address, CharacterWeapon Data) GetMainhand() - { - Model weapon = AsDrawObject->Object.ChildObject; - return !weapon.IsWeapon - ? (Null, CharacterWeapon.Empty) - : (weapon, new CharacterWeapon(weapon.AsWeapon->ModelSetId, weapon.AsWeapon->SecondaryId, (Variant)weapon.AsWeapon->Variant, - (StainId)weapon.AsWeapon->ModelUnknown)); - } - - public (Model Address, CharacterWeapon Data) GetOffhand() - { - var mainhand = AsDrawObject->Object.ChildObject; - if (mainhand == null) - return (Null, CharacterWeapon.Empty); - - Model offhand = mainhand->NextSiblingObject; - if (offhand == mainhand || !offhand.IsWeapon) - return (Null, CharacterWeapon.Empty); - - return (offhand, new CharacterWeapon(offhand.AsWeapon->ModelSetId, offhand.AsWeapon->SecondaryId, (Variant)offhand.AsWeapon->Variant, - (StainId)offhand.AsWeapon->ModelUnknown)); - } - - /// Obtain the mainhand and offhand and their data by guesstimating which child object is which. - public (Model Mainhand, Model Offhand, CharacterWeapon MainData, CharacterWeapon OffData) GetWeapons() - { - var (first, second, count) = GetChildrenWeapons(); - switch (count) - { - case 0: return (Null, Null, CharacterWeapon.Empty, CharacterWeapon.Empty); - case 1: - return (first, Null, new CharacterWeapon(first.AsWeapon->ModelSetId, first.AsWeapon->SecondaryId, - (Variant)first.AsWeapon->Variant, - (StainId)first.AsWeapon->ModelUnknown), CharacterWeapon.Empty); - default: - var (main, off) = DetermineMainhand(first, second); - var mainData = new CharacterWeapon(main.AsWeapon->ModelSetId, main.AsWeapon->SecondaryId, (Variant)main.AsWeapon->Variant, - (StainId)main.AsWeapon->ModelUnknown); - var offData = new CharacterWeapon(off.AsWeapon->ModelSetId, off.AsWeapon->SecondaryId, (Variant)off.AsWeapon->Variant, - (StainId)off.AsWeapon->ModelUnknown); - return (main, off, mainData, offData); - } - } - - /// Obtain the mainhand and offhand and their data by using the drawdata container from the corresponding actor. - public (Model Mainhand, Model Offhand, CharacterWeapon MainData, CharacterWeapon OffData) GetWeapons(Actor actor) - { - if (!Valid || !actor.IsCharacter || actor.Model.Address != Address) - return (Null, Null, CharacterWeapon.Empty, CharacterWeapon.Empty); - - Model main = actor.AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.MainHand).DrawObject; - var mainData = CharacterWeapon.Empty; - if (main.IsWeapon) - mainData = new CharacterWeapon(main.AsWeapon->ModelSetId, main.AsWeapon->SecondaryId, (Variant)main.AsWeapon->Variant, - (StainId)main.AsWeapon->ModelUnknown); - else - main = Null; - Model off = actor.AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.OffHand).DrawObject; - var offData = CharacterWeapon.Empty; - if (off.IsWeapon) - offData = new CharacterWeapon(off.AsWeapon->ModelSetId, off.AsWeapon->SecondaryId, (Variant)off.AsWeapon->Variant, - (StainId)off.AsWeapon->ModelUnknown); - else - off = Null; - return (main, off, mainData, offData); - } - - public CustomizeParameterData GetParameterData() - { - if (!IsHuman) - return default; - - var cBuffer1 = AsHuman->CustomizeParameterCBuffer; - var cBuffer2 = AsHuman->DecalColorCBuffer; - var ptr1 = (CustomizeParameter*)(cBuffer1 == null ? null : cBuffer1->UnsafeSourcePointer); - var ptr2 = (DecalParameters*)(cBuffer2 == null ? null : cBuffer2->UnsafeSourcePointer); - return CustomizeParameterData.FromParameters(ptr1 != null ? *ptr1 : default, ptr2 != null ? *ptr2 : default); - } - - public void ApplyParameterData(CustomizeParameterFlag flags, in CustomizeParameterData data) - { - if (!IsHuman) - return; - - if (flags.HasFlag(CustomizeParameterFlag.DecalColor)) - { - var cBufferDecal = AsHuman->DecalColorCBuffer; - var ptrDecal = (DecalParameters*)(cBufferDecal == null ? null : cBufferDecal->UnsafeSourcePointer); - if (ptrDecal != null) - data.Apply(ref *ptrDecal); - } - - flags &= ~CustomizeParameterFlag.DecalColor; - var cBuffer = AsHuman->CustomizeParameterCBuffer; - var ptr = (CustomizeParameter*)(cBuffer == null ? null : cBuffer->UnsafeSourcePointer); - if (ptr != null) - data.Apply(ref *ptr, flags); - } - - public bool ApplySingleParameterData(CustomizeParameterFlag flag, in CustomizeParameterData data) - { - if (!IsHuman) - return false; - - if (flag is CustomizeParameterFlag.DecalColor) - { - var cBuffer = AsHuman->DecalColorCBuffer; - var ptr = (DecalParameters*)(cBuffer == null ? null : cBuffer->UnsafeSourcePointer); - if (ptr == null) - return false; - - data.Apply(ref *ptr); - return true; - } - else - { - var cBuffer = AsHuman->CustomizeParameterCBuffer; - var ptr = (CustomizeParameter*)(cBuffer == null ? null : cBuffer->UnsafeSourcePointer); - if (ptr == null) - return false; - - data.ApplySingle(ref *ptr, flag); - return true; - } - } - - private (Model, Model, int) GetChildrenWeapons() - { - Span weapons = stackalloc Model[2]; - weapons[0] = Null; - weapons[1] = Null; - var count = 0; - - if (!Valid || AsDrawObject->Object.ChildObject == null) - return (weapons[0], weapons[1], count); - - Model starter = AsDrawObject->Object.ChildObject; - var iterator = starter; - do - { - if (iterator.IsWeapon) - weapons[count++] = iterator; - if (count == 2) - return (weapons[0], weapons[1], count); - - iterator = iterator.AsDrawObject->Object.NextSiblingObject; - } while (iterator.Address != starter.Address); - - return (weapons[0], weapons[1], count); - } - - /// I don't know a safe way to do this but in experiments this worked. - /// The first uint at +0x8 was set to non-zero for the mainhand and zero for the offhand. - private static (Model Mainhand, Model Offhand) DetermineMainhand(Model first, Model second) - { - var discriminator1 = *(ulong*)(first.Address + 0x10); - var discriminator2 = *(ulong*)(second.Address + 0x10); - return discriminator1 == 0 && discriminator2 != 0 ? (second, first) : (first, second); - } - - public override string ToString() - => $"0x{Address:X}"; -} diff --git a/Glamourer/Interop/Structs/ModelExtensions.cs b/Glamourer/Interop/Structs/ModelExtensions.cs new file mode 100644 index 0000000..207c72c --- /dev/null +++ b/Glamourer/Interop/Structs/ModelExtensions.cs @@ -0,0 +1,67 @@ +using FFXIVClientStructs.FFXIV.Shader; +using Glamourer.GameData; +using Penumbra.GameData.Interop; + +namespace Glamourer.Interop.Structs; + +public static unsafe class ModelExtensions +{ + public static CustomizeParameterData GetParameterData(this Model model) + { + if (!model.IsHuman) + return default; + + var cBuffer1 = model.AsHuman->CustomizeParameterCBuffer; + var cBuffer2 = model.AsHuman->DecalColorCBuffer; + var ptr1 = (CustomizeParameter*)(cBuffer1 == null ? null : cBuffer1->UnsafeSourcePointer); + var ptr2 = (DecalParameters*)(cBuffer2 == null ? null : cBuffer2->UnsafeSourcePointer); + return CustomizeParameterData.FromParameters(ptr1 != null ? *ptr1 : default, ptr2 != null ? *ptr2 : default); + } + + public static void ApplyParameterData(this Model model, CustomizeParameterFlag flags, in CustomizeParameterData data) + { + if (!model.IsHuman) + return; + + if (flags.HasFlag(CustomizeParameterFlag.DecalColor)) + { + var cBufferDecal = model.AsHuman->DecalColorCBuffer; + var ptrDecal = (DecalParameters*)(cBufferDecal == null ? null : cBufferDecal->UnsafeSourcePointer); + if (ptrDecal != null) + data.Apply(ref *ptrDecal); + } + + flags &= ~CustomizeParameterFlag.DecalColor; + var cBuffer = model.AsHuman->CustomizeParameterCBuffer; + var ptr = (CustomizeParameter*)(cBuffer == null ? null : cBuffer->UnsafeSourcePointer); + if (ptr != null) + data.Apply(ref *ptr, flags); + } + + public static bool ApplySingleParameterData(this Model model, CustomizeParameterFlag flag, in CustomizeParameterData data) + { + if (!model.IsHuman) + return false; + + if (flag is CustomizeParameterFlag.DecalColor) + { + var cBuffer = model.AsHuman->DecalColorCBuffer; + var ptr = (DecalParameters*)(cBuffer == null ? null : cBuffer->UnsafeSourcePointer); + if (ptr == null) + return false; + + data.Apply(ref *ptr); + return true; + } + else + { + var cBuffer = model.AsHuman->CustomizeParameterCBuffer; + var ptr = (CustomizeParameter*)(cBuffer == null ? null : cBuffer->UnsafeSourcePointer); + if (ptr == null) + return false; + + data.ApplySingle(ref *ptr, flag); + return true; + } + } +} diff --git a/Glamourer/Interop/UpdateSlotService.cs b/Glamourer/Interop/UpdateSlotService.cs index 0891945..f2f7423 100644 --- a/Glamourer/Interop/UpdateSlotService.cs +++ b/Glamourer/Interop/UpdateSlotService.cs @@ -2,9 +2,9 @@ using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using Glamourer.Events; -using Glamourer.Interop.Structs; using Penumbra.GameData; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop; diff --git a/Glamourer/Interop/VisorService.cs b/Glamourer/Interop/VisorService.cs index 082f6b8..4232446 100644 --- a/Glamourer/Interop/VisorService.cs +++ b/Glamourer/Interop/VisorService.cs @@ -1,10 +1,9 @@ using Dalamud.Hooking; using Dalamud.Plugin.Services; -using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using Glamourer.Events; -using Glamourer.Interop.Structs; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; namespace Glamourer.Interop; diff --git a/Glamourer/Interop/WeaponService.cs b/Glamourer/Interop/WeaponService.cs index da7d9dd..d2aac1a 100644 --- a/Glamourer/Interop/WeaponService.cs +++ b/Glamourer/Interop/WeaponService.cs @@ -2,8 +2,8 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.Character; using Glamourer.Events; -using Glamourer.Interop.Structs; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.Interop; diff --git a/Glamourer/Services/CollectionOverrideService.cs b/Glamourer/Services/CollectionOverrideService.cs index 7cdbc47..a7c4364 100644 --- a/Glamourer/Services/CollectionOverrideService.cs +++ b/Glamourer/Services/CollectionOverrideService.cs @@ -1,11 +1,11 @@ using Glamourer.Interop.Penumbra; -using Glamourer.Interop.Structs; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; using OtterGui.Filesystem; using OtterGui.Services; using Penumbra.GameData.Actors; +using Penumbra.GameData.Interop; namespace Glamourer.Services; diff --git a/Glamourer/Services/CommandService.cs b/Glamourer/Services/CommandService.cs index 0b32cfc..e2edd2d 100644 --- a/Glamourer/Services/CommandService.cs +++ b/Glamourer/Services/CommandService.cs @@ -5,16 +5,16 @@ using Glamourer.Automation; using Glamourer.Designs; using Glamourer.Designs.Special; using Glamourer.Gui; -using Glamourer.Interop; using Glamourer.Interop.Penumbra; -using Glamourer.Interop.Structs; using Glamourer.State; using ImGuiNET; using OtterGui; using OtterGui.Classes; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; +using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.Services; diff --git a/Glamourer/Services/DalamudServices.cs b/Glamourer/Services/DalamudServices.cs index 14100b1..66cb97b 100644 --- a/Glamourer/Services/DalamudServices.cs +++ b/Glamourer/Services/DalamudServices.cs @@ -26,5 +26,6 @@ public class DalamudServices services.AddDalamudService(pi); services.AddDalamudService(pi); services.AddDalamudService(pi); + services.AddDalamudService(pi); } } diff --git a/Glamourer/State/FunModule.cs b/Glamourer/State/FunModule.cs index 7ddc42f..25b8946 100644 --- a/Glamourer/State/FunModule.cs +++ b/Glamourer/State/FunModule.cs @@ -2,15 +2,15 @@ using Dalamud.Interface.Internal.Notifications; using Glamourer.Designs; using Glamourer.Gui; -using Glamourer.Interop; -using Glamourer.Interop.Structs; using Glamourer.Services; using ImGuiNET; using OtterGui; using OtterGui.Classes; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; using CustomizeIndex = Penumbra.GameData.Enums.CustomizeIndex; +using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.State; diff --git a/Glamourer/State/StateListener.cs b/Glamourer/State/StateListener.cs index bf7b869..ff227a8 100644 --- a/Glamourer/State/StateListener.cs +++ b/Glamourer/State/StateListener.cs @@ -12,6 +12,8 @@ using Dalamud.Plugin.Services; using Glamourer.GameData; using Penumbra.GameData.DataContainers; using Glamourer.Designs; +using Penumbra.GameData.Interop; +using ObjectManager = Glamourer.Interop.ObjectManager; namespace Glamourer.State; @@ -550,10 +552,10 @@ public class StateListener : IDisposable /// only if we kept track of state of someone who went to the aesthetician, /// or if they used other tools to change things. /// - private UpdateState UpdateBaseData(Actor actor, ActorState state, CustomizeArray customize, bool checkTransform) + private unsafe UpdateState UpdateBaseData(Actor actor, ActorState state, CustomizeArray customize, bool checkTransform) { // Customize array does not agree between game object and draw object => transformation. - if (checkTransform && !actor.GetCustomize().Equals(customize)) + if (checkTransform && !actor.Customize->Equals(customize)) return UpdateState.Transformed; // Customize array did not change to stored state. diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs index 5519f8d..7fe2264 100644 --- a/Glamourer/State/StateManager.cs +++ b/Glamourer/State/StateManager.cs @@ -12,7 +12,7 @@ using Penumbra.GameData.Actors; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; -using System; +using Penumbra.GameData.Interop; namespace Glamourer.State; @@ -163,7 +163,7 @@ public sealed class StateManager( else { // Obtain all data from the game object. - ret.Customize = actor.GetCustomize(); + ret.Customize = *actor.Customize; foreach (var slot in EquipSlotExtensions.EqdpSlots) { diff --git a/Glamourer/State/WorldSets.cs b/Glamourer/State/WorldSets.cs index 5a26b77..eca0988 100644 --- a/Glamourer/State/WorldSets.cs +++ b/Glamourer/State/WorldSets.cs @@ -1,5 +1,5 @@ -using Glamourer.Interop.Structs; -using Penumbra.GameData.Enums; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using Penumbra.GameData.Structs; namespace Glamourer.State; @@ -344,10 +344,10 @@ public class WorldSets } - private unsafe (byte, byte, Race, Gender) GetData(Actor actor) + private static unsafe (byte, byte, Race, Gender) GetData(Actor actor) { - var customize = actor.GetCustomize(); - return (actor.AsCharacter->CharacterData.Level, actor.Job, customize.Race, customize.Gender); + var customize = actor.Customize; + return (actor.AsCharacter->CharacterData.Level, actor.Job, customize->Race, customize->Gender); } public void Apply(Actor actor, Random rng, Span armor) @@ -356,7 +356,7 @@ public class WorldSets Apply(level, job, race, gender, rng, armor); } - public void Apply(byte level, byte job, Race race, Gender gender, Random rng, Span armor) + private void Apply(byte level, byte job, Race race, Gender gender, Random rng, Span armor) { var opt = GetGroup(level, job, race, gender, rng); if (opt == null) @@ -375,7 +375,7 @@ public class WorldSets Apply(level, job, race, gender, rng, ref armor, slot); } - public void Apply(byte level, byte job, Race race, Gender gender, Random rng, ref CharacterArmor armor, EquipSlot slot) + private void Apply(byte level, byte job, Race race, Gender gender, Random rng, ref CharacterArmor armor, EquipSlot slot) { var opt = GetGroup(level, job, race, gender, rng); if (opt == null) @@ -398,7 +398,7 @@ public class WorldSets Apply(level, job, race, gender, rng, ref weapon, slot); } - public void Apply(byte level, byte job, Race race, Gender gender, Random rng, ref CharacterWeapon weapon, EquipSlot slot) + private void Apply(byte level, byte job, Race race, Gender gender, Random rng, ref CharacterWeapon weapon, EquipSlot slot) { var opt = GetGroup(level, job, race, gender, rng); if (opt == null) diff --git a/OtterGui b/OtterGui index d71f854..b4b1436 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit d71f8540a2c2efb4f2cb96e4706bb056397daf0a +Subproject commit b4b14367d8235eabedd561ad3626beb1d2a83889 diff --git a/Penumbra.Api b/Penumbra.Api index 34921fd..d2a1406 160000 --- a/Penumbra.Api +++ b/Penumbra.Api @@ -1 +1 @@ -Subproject commit 34921fd2c5a9aff5d34aef664bdb78331e8b9436 +Subproject commit d2a1406bc32f715c0687613f02e3f74caf7ceea9 diff --git a/Penumbra.GameData b/Penumbra.GameData index d0db2f1..74a3057 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit d0db2f1fbc3ce26d0756da5118157e5fc723c62f +Subproject commit 74a305768880cd783b21e85ef97e9be77b119885 diff --git a/Penumbra.String b/Penumbra.String index 620a7ed..14e00f7 160000 --- a/Penumbra.String +++ b/Penumbra.String @@ -1 +1 @@ -Subproject commit 620a7edf009b92288257ce7d64fffb8fba44d8b5 +Subproject commit 14e00f77d42bc677e02325660db765ef11932560