From 9b3e13ffebc0a8770e37044210f8c6ca0f2dc799 Mon Sep 17 00:00:00 2001 From: Jackson <9527380+Jaksuhn@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:43:54 +0100 Subject: [PATCH 1/6] Update AgentMiragePrismPrismSetConvert.cs --- .../Agent/AgentMiragePrismPrismSetConvert.cs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs index 13105c599..eb77d1f6d 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs @@ -27,9 +27,17 @@ public partial struct AgentData { [FieldOffset(0x0C)] public ushort CrystallizeAddonId; // MiragePrismPrismBoxCrystallize, the opener [FieldOffset(0x0E)] public ushort PrismBoxAddonId; // MiragePrismPrismBoxAddonId + [FieldOffset(0x10)] public SetConvertState State; + [FieldOffset(0x14)] public uint SelectedSetIndex; [FieldOffset(0x18)] public int ContextMenuItemIndex; - - [FieldOffset(0x2C)] public bool EnableSorting; + [FieldOffset(0x1C)] public uint YesNoAddonId; + [FieldOffset(0x24)] public uint GlamourPrismCount; + /// Index for + [FieldOffset(0x28)] public uint PrismBoxIndex; + [FieldOffset(0x2C), Obsolete("Renamed to EnableStoring")] public bool EnableSorting; + [FieldOffset(0x2C)] public bool EnableStoring; // false = preview mode + [FieldOffset(0x2D)] public bool StoreInExistingOutfit; // false = will be a new outfit, set on Open + [FieldOffset(0x38)] public uint ItemSetCount; [FieldOffset(0x40), FixedSizeArray] internal FixedSizeArray5 _itemSets; [FieldOffset(0x2C0)] public uint NumItemsInSet; @@ -43,6 +51,7 @@ public partial struct AgentData { public struct ItemSet { [FieldOffset(0x00)] public uint ItemId; [FieldOffset(0x04)] public uint IconId; + [FieldOffset(0x08)] public uint SlotUnlockMask; [FieldOffset(0x10)] public Utf8String Name; } @@ -51,7 +60,7 @@ public struct ItemSet { public struct ItemSetItem { [FieldOffset(0x00)] public uint ItemId; [FieldOffset(0x04)] public uint IconId; - [FieldOffset(0x08)] private uint SlotIndex; // probably? seems to match MainHand, OffHand, Head, Body etc. + [FieldOffset(0x08)] public uint MirageStoreSetItemColumn; // column index of MirageStoreSetItem [FieldOffset(0x0C)] public InventoryType InventoryType; @@ -76,3 +85,12 @@ public partial struct HandInItem { } } } + +public enum SetConvertState : uint { + None = 0, // idle/closed + Loading = 1, // loads the icons/names + Unk2 = 2, + Unk3 = 3, + RefreshHandInSlots = 4, + Ready = 5, +} From ca30910d3165f62fd810df7950ef15b291e17046 Mon Sep 17 00:00:00 2001 From: Jackson <9527380+Jaksuhn@users.noreply.github.com> Date: Fri, 26 Jun 2026 19:59:53 +0100 Subject: [PATCH 2/6] pretty sure these are right --- .../Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs | 8 ++++---- ida/data.yml | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs index eb77d1f6d..cc4e40e22 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs @@ -27,7 +27,7 @@ public partial struct AgentData { [FieldOffset(0x0C)] public ushort CrystallizeAddonId; // MiragePrismPrismBoxCrystallize, the opener [FieldOffset(0x0E)] public ushort PrismBoxAddonId; // MiragePrismPrismBoxAddonId - [FieldOffset(0x10)] public SetConvertState State; + [FieldOffset(0x10)] public AddonState State; [FieldOffset(0x14)] public uint SelectedSetIndex; [FieldOffset(0x18)] public int ContextMenuItemIndex; [FieldOffset(0x1C)] public uint YesNoAddonId; @@ -42,8 +42,8 @@ public partial struct AgentData { [FieldOffset(0x40), FixedSizeArray] internal FixedSizeArray5 _itemSets; [FieldOffset(0x2C0)] public uint NumItemsInSet; [FieldOffset(0x2C4), FixedSizeArray] internal FixedSizeArray9 _items; - [FieldOffset(0x408)] private uint Unk408; - [FieldOffset(0x40C)] private uint Unk40C; + [FieldOffset(0x408)] public uint HandInItemCount; + [FieldOffset(0x40C)] public uint HandInItemValidCount; // ones that are able to be turned in (i.e. 100% condition) [FieldOffset(0x410), FixedSizeArray] internal FixedSizeArray190 _handIns; [FieldOffset(0x18D8)] public Utf8String HandInItemName; // for tooltip? @@ -86,7 +86,7 @@ public partial struct HandInItem { } } -public enum SetConvertState : uint { +public enum AddonState : uint { None = 0, // idle/closed Loading = 1, // loads the icons/names Unk2 = 2, diff --git a/ida/data.yml b/ida/data.yml index 82964d8ef..9b5baab47 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -1840,6 +1840,8 @@ classes: 0x140893120: Clear 0x1408931E0: RequestPrismBox 0x140893380: IsSetSlotUnlocked + 0x1408935F0: StoreOutfitAsNewEntry + 0x140893840: StoreOutfitIntoExistingEntry 0x140893B20: RestorePrismBoxItem 0x140893D00: RestorePrismBoxSetItem 0x1408945F0: RequestGlamourPlates @@ -14173,6 +14175,8 @@ classes: funcs: 0x140DB0840: Open # todo: check this (7.4) 0x140DB0B10: OpenPreview + 0x140DB1EB0: PopulateHandInItems + 0x140DB2980: ValidateItems Client::UI::Agent::AgentMiragePrismPrismSetConvert::AgentData: funcs: #fail 0x140C36B10: ctor # inlined (7.3) From 5e5fdfec3d356c59e81840a6e61eea9f413e7754 Mon Sep 17 00:00:00 2001 From: Jackson <9527380+Jaksuhn@users.noreply.github.com> Date: Sat, 27 Jun 2026 00:40:40 +0100 Subject: [PATCH 3/6] yeah they were right --- .../FFXIV/Client/Game/MirageManager.cs | 18 ++++++++++++++++++ .../Agent/AgentMiragePrismPrismSetConvert.cs | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs b/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs index afe5f50e3..efd3f0f81 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs @@ -48,6 +48,24 @@ public unsafe partial struct MirageManager { [MemberFunction("E8 ?? ?? ?? ?? 84 C0 75 ?? 0B F3")] public partial bool IsSetSlotUnlocked(uint itemIndex, int slot); + /// + /// Deposits gear into dresser as a new outfit set. + /// + /// Which outfit set this is (MirageStoreSetItem row id). + /// Containers where each piece is. Must be in order of MirageStoreSetItem. Leftover slots use + /// Slots where each piece is. Leftovers must be 0. + [MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 08 48 8B 47 28")] + public partial bool StoreOutfitAsNewPrismBoxEntry(uint setItemId, InventoryType* containers, ushort* slots); + + /// + /// Deposits gear into dresser into an existing outfit set. + /// + /// Which dresser slot the outfit occupies ( index). + /// Same as + /// Same as + [MemberFunction("E8 ?? ?? ?? ?? EB 1A E8 ?? ?? ?? ?? 8B 57 40")] + public partial bool StoreOutfitIntoExistingPrismBoxEntry(uint prismBoxIndex, InventoryType* containers, ushort* slots); + [GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x48)] public partial struct GlamourPlate { diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs index cc4e40e22..a78441ea3 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismSetConvert.cs @@ -18,6 +18,14 @@ public unsafe partial struct AgentMiragePrismPrismSetConvert { // OpenPreview in data.yml public void Open(uint itemId) => Open(itemId, InventoryType.Invalid, 0, 0, 0, false); + /// Scans inventory for matching pieces and populates . + [MemberFunction("E8 ?? ?? ?? ?? 83 BB ?? ?? ?? ?? ?? 74 AA")] + public partial void PopulateHandInItems(InventoryType container, int slot, int a3); + + /// Validates and refreshes the SetConvert addon. + [MemberFunction("E9 ?? ?? ?? ?? 48 83 C4 28 41 5E 5D E9 ?? ?? ?? ?? 48 83 C4 28")] + public partial void ValidateItems(); + [GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x1940)] public partial struct AgentData { From a43e8c2701044004a669f8898d366e4a4ee54cd3 Mon Sep 17 00:00:00 2001 From: Jackson <9527380+Jaksuhn@users.noreply.github.com> Date: Sat, 27 Jun 2026 00:45:53 +0100 Subject: [PATCH 4/6] Update MirageManager.cs --- FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs b/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs index efd3f0f81..33e8b3b9a 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs @@ -1,3 +1,5 @@ +using FFXIVClientStructs.FFXIV.Client.UI.Agent; + namespace FFXIVClientStructs.FFXIV.Client.Game; // Client::Game::MirageManager @@ -51,7 +53,7 @@ public unsafe partial struct MirageManager { /// /// Deposits gear into dresser as a new outfit set. /// - /// Which outfit set this is (MirageStoreSetItem row id). + /// MirageStoreSetItem row id /// Containers where each piece is. Must be in order of MirageStoreSetItem. Leftover slots use /// Slots where each piece is. Leftovers must be 0. [MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 08 48 8B 47 28")] @@ -60,7 +62,7 @@ public unsafe partial struct MirageManager { /// /// Deposits gear into dresser into an existing outfit set. /// - /// Which dresser slot the outfit occupies ( index). + /// index (see also ) /// Same as /// Same as [MemberFunction("E8 ?? ?? ?? ?? EB 1A E8 ?? ?? ?? ?? 8B 57 40")] From 263d1905512a11637d9837f48975484abe0fd094 Mon Sep 17 00:00:00 2001 From: Jackson <9527380+Jaksuhn@users.noreply.github.com> Date: Sat, 27 Jun 2026 11:56:34 +0100 Subject: [PATCH 5/6] crystallize nodes --- .../UI/AddonMiragePrismPrismBoxCrystallize.cs | 24 +++++++++++++++++++ .../UI/Agent/AgentMiragePrismPrismBox.cs | 7 ++++++ .../Component/GUI/AtkComponentTreeList.cs | 3 +++ ida/data.yml | 9 +++++++ 4 files changed, 43 insertions(+) create mode 100644 FFXIVClientStructs/FFXIV/Client/UI/AddonMiragePrismPrismBoxCrystallize.cs diff --git a/FFXIVClientStructs/FFXIV/Client/UI/AddonMiragePrismPrismBoxCrystallize.cs b/FFXIVClientStructs/FFXIV/Client/UI/AddonMiragePrismPrismBoxCrystallize.cs new file mode 100644 index 000000000..8995505d8 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/UI/AddonMiragePrismPrismBoxCrystallize.cs @@ -0,0 +1,24 @@ +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace FFXIVClientStructs.FFXIV.Client.UI; + +// Client::UI::AddonMiragePrismPrismBoxCrystallize +// Component::GUI::AtkUnitBase +// Component::GUI::AtkEventListener +[Addon("MiragePrismPrismBoxCrystallize")] +[GenerateInterop] +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x2E0)] +public unsafe partial struct AddonMiragePrismPrismBoxCrystallize { + [FieldOffset(0x238)] public AtkComponentTreeList* ItemTreeList; + [FieldOffset(0x240)] private void* Unk240; // icon renderer? + [FieldOffset(0x248)] private void* Unk248; // text renderer? + [FieldOffset(0x250)] private void* Unk250; // I think it's some callback to the tree list populator + [FieldOffset(0x268)] public AtkComponentCheckBox* GearsetFilterCheckbox; + [FieldOffset(0x270), FixedSizeArray] internal FixedSizeArray6 _categoryLabels; + [FieldOffset(0x2A0)] private byte Unk2A0; + [FieldOffset(0x2A8)] public AtkComponentDropDownList* CategoryDropDown; + [FieldOffset(0x2B0)] public AtkComponentButton* CategoryPrevButton; + [FieldOffset(0x2B8)] public AtkComponentButton* CategoryNextButton; + [FieldOffset(0x2D8)] public bool IsTooltipVisible; +} diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismBox.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismBox.cs index 37147d6e3..4a45bbba7 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismBox.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentMiragePrismPrismBox.cs @@ -24,6 +24,9 @@ public unsafe partial struct AgentMiragePrismPrismBox { [MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 0F B6 43 3A")] public partial void UpdateItems(bool resetTabIndex, bool a2); + + [MemberFunction("E8 ?? ?? ?? ?? 84 C0 0F 84 ?? ?? ?? ?? 48 8B 46 28 C6 80 ?? ?? ?? ?? ??")] + public partial bool PopulateCrystallizeAndFireRefresh(); } [GenerateInterop] @@ -48,15 +51,19 @@ public unsafe partial struct MiragePrismPrismBoxData { [FieldOffset(0x11AE70)] public uint ItemCount; [FieldOffset(0x11AE74)] public uint FilterSettingsAddonId; [FieldOffset(0x11AE78)] public bool IsPopulatingList; + [FieldOffset(0x11AE79)] public bool IsPopulatingComplete; [FieldOffset(0x11AE7B)] private byte Unk11AE7B; [FieldOffset(0x11AE7C)] public bool IsAddonReady; [FieldOffset(0x11AE7D)] private byte Unk11AE7D; [FieldOffset(0x11AE7E)] private byte Unk11AE7E; [FieldOffset(0x11AE7F)] public bool IsPositionSaved; + [FieldOffset(0x11AE80)] private int Unk11AE80; // something with the category [FieldOffset(0x11AE84)] public int CrystallizeCategory; [FieldOffset(0x11AE88)] public ushort CrystallizeItemIndex; [FieldOffset(0x11AE8A)] public ushort CrystallizeItemCount; + [FieldOffset(0x11AE8C)] public ushort CrystallizeTreeRowCount; + [FieldOffset(0x11AE8E)] private ushort Unk11AE8E; // cursor related? [FieldOffset(0x11AE90), FixedSizeArray] internal FixedSizeArray140 _crystallizeItems; [FieldOffset(0x11BDE0)] public PrismBoxCrystallizeItem CrystallizeSelectedItem; diff --git a/FFXIVClientStructs/FFXIV/Component/GUI/AtkComponentTreeList.cs b/FFXIVClientStructs/FFXIV/Component/GUI/AtkComponentTreeList.cs index 4edaefbbb..85c2625d6 100644 --- a/FFXIVClientStructs/FFXIV/Component/GUI/AtkComponentTreeList.cs +++ b/FFXIVClientStructs/FFXIV/Component/GUI/AtkComponentTreeList.cs @@ -28,6 +28,9 @@ public unsafe partial struct AtkComponentTreeList : ICreatable Date: Sun, 28 Jun 2026 13:32:58 +0100 Subject: [PATCH 6/6] change name --- FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs | 8 ++++---- ida/data.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs b/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs index 33e8b3b9a..d71db4165 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/MirageManager.cs @@ -57,16 +57,16 @@ public unsafe partial struct MirageManager { /// Containers where each piece is. Must be in order of MirageStoreSetItem. Leftover slots use /// Slots where each piece is. Leftovers must be 0. [MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 08 48 8B 47 28")] - public partial bool StoreOutfitAsNewPrismBoxEntry(uint setItemId, InventoryType* containers, ushort* slots); + public partial bool StoreNewOutfit(uint setItemId, InventoryType* containers, ushort* slots); /// /// Deposits gear into dresser into an existing outfit set. /// /// index (see also ) - /// Same as - /// Same as + /// Same as + /// Same as [MemberFunction("E8 ?? ?? ?? ?? EB 1A E8 ?? ?? ?? ?? 8B 57 40")] - public partial bool StoreOutfitIntoExistingPrismBoxEntry(uint prismBoxIndex, InventoryType* containers, ushort* slots); + public partial bool StoreExistingOutfit(uint prismBoxIndex, InventoryType* containers, ushort* slots); [GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x48)] diff --git a/ida/data.yml b/ida/data.yml index fbdc3e787..5e55efdbd 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -1840,8 +1840,8 @@ classes: 0x140893120: Clear 0x1408931E0: RequestPrismBox 0x140893380: IsSetSlotUnlocked - 0x1408935F0: StoreOutfitAsNewEntry - 0x140893840: StoreOutfitIntoExistingEntry + 0x1408935F0: StoreNewOutfit + 0x140893840: StoreExistingOutfit 0x140893B20: RestorePrismBoxItem 0x140893D00: RestorePrismBoxSetItem 0x1408945F0: RequestGlamourPlates