From 17bb7694a8cb3905a2b6a7e9b317e479a944605e Mon Sep 17 00:00:00 2001 From: Knightmore <35805408+Knightmore@users.noreply.github.com> Date: Sun, 17 May 2026 15:08:17 +0200 Subject: [PATCH 1/2] AgentCabinet and AddonCabinet --- .../FFXIV/Client/UI/AddonCabinet.cs | 34 +++++++++++++++++++ .../FFXIV/Client/UI/Agent/AgentCabinet.cs | 12 +++++-- 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 FFXIVClientStructs/FFXIV/Client/UI/AddonCabinet.cs diff --git a/FFXIVClientStructs/FFXIV/Client/UI/AddonCabinet.cs b/FFXIVClientStructs/FFXIV/Client/UI/AddonCabinet.cs new file mode 100644 index 000000000..68c46002f --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/UI/AddonCabinet.cs @@ -0,0 +1,34 @@ +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace FFXIVClientStructs.FFXIV.Client.UI; + +// Client::UI::AddonCabinet +// Component::GUI::AtkUnitBase +// Component::GUI::AtkEventListener +[Addon("Cabinet")] +[GenerateInterop] +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x4B88)] +public unsafe partial struct AddonCabinet { + // Count of populated slots = NumberArrayData[0x30][0]. Slots past that count are stale. + [FieldOffset(0x238), FixedSizeArray] internal FixedSizeArray140 _itemSlots; + + // Category names shown in the dropdown, populated from AtkValue args on setup. + [FieldOffset(0x4838), FixedSizeArray] internal FixedSizeArray7 _categoryNames; + + [FieldOffset(0x4B10)] public AtkComponentList* ItemList; + [FieldOffset(0x4B18)] public AtkResNode* TimelineNode; + [FieldOffset(0x4B28)] public AtkComponentDropDownList* CategoryDropDown; + [FieldOffset(0x4B58)] public AtkComponentButton* CloseButton; + [FieldOffset(0x4B60)] public uint CategoryIndex; // 0xFFFFFFFF until first render + + [StructLayout(LayoutKind.Explicit, Size = 0x80)] + public struct ItemSlot { + [FieldOffset(0x00)] public Utf8String Name; + [FieldOffset(0x68)] public uint Unk68; // ItemCache.Unk74; fed to image node renderer + [FieldOffset(0x6C)] public uint InventorySlotIndex; // slot index within the found InventoryContainer + [FieldOffset(0x70)] public uint InventoryContainerType; // InventoryType where the item is held/equipped + [FieldOffset(0x74)] public uint ItemsArrayIndex; // index into AgentCabinet.Items[] + [FieldOffset(0x78)] public float ConditionNormalized; // item condition as Condition / 30000f + } +} diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs index af373c212..1e6fb79f7 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs @@ -9,9 +9,17 @@ namespace FFXIVClientStructs.FFXIV.Client.UI.Agent; [StructLayout(LayoutKind.Explicit, Size = 0x4AD8)] public unsafe partial struct AgentCabinet { [FieldOffset(0x30)] public uint ConfirmationAddonId; - [FieldOffset(0x34)] public uint SelectedIndex; + [FieldOffset(0x34)] public uint SelectedIndex; // index into Items[] + [FieldOffset(0x38)] public uint OpenMode; // 0 = normal cabinet, 2 = MiragePrism plate selection + [FieldOffset(0x40)] public uint SelectedItemId; // game item ID of the selected item - [FieldOffset(0x4AB0)] public CabinetItem* Items; // length: Cabinet RowCount + [FieldOffset(0x49)] public byte SelectedCategoryIndex; // dropdown selection as (index + 1); + [FieldOffset(0x4A)] public byte PendingUpdate; // set to 1 on category change; triggers item list rebuild in Update + + [FieldOffset(0x50), FixedSizeArray] internal FixedSizeArray140 _itemCaches; + + [FieldOffset(0x4AB0)] public CabinetItem* Items; // all valid Cabinet rows sorted by category; length: ItemCount + [FieldOffset(0x4AB8)] public uint ItemCount; // total valid Cabinet rows across all categories [StructLayout(LayoutKind.Explicit, Size = 0x10)] public struct CabinetItem { From bf79349f5ad018d7ac2a7f03964e886f9c167429 Mon Sep 17 00:00:00 2001 From: Knightmore <35805408+Knightmore@users.noreply.github.com> Date: Mon, 18 May 2026 13:44:54 +0200 Subject: [PATCH 2/2] Change PendingUpdate type from byte to bool Changed PendingUpdate from byte to bool for better clarity. --- FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs index 1e6fb79f7..c8fe4e8ea 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentCabinet.cs @@ -14,7 +14,7 @@ public unsafe partial struct AgentCabinet { [FieldOffset(0x40)] public uint SelectedItemId; // game item ID of the selected item [FieldOffset(0x49)] public byte SelectedCategoryIndex; // dropdown selection as (index + 1); - [FieldOffset(0x4A)] public byte PendingUpdate; // set to 1 on category change; triggers item list rebuild in Update + [FieldOffset(0x4A)] public bool PendingUpdate; // set to true on category change; triggers item list rebuild in Update [FieldOffset(0x50), FixedSizeArray] internal FixedSizeArray140 _itemCaches;