From 430ec1d26836a18752328e3d1615febc58ac96bb Mon Sep 17 00:00:00 2001 From: AtmoOmen Date: Sun, 3 May 2026 21:26:16 +0800 Subject: [PATCH 1/7] PointMenu --- .../FFXIV/Client/UI/AddonPointMenu.cs | 35 ++++++++ .../FFXIV/Client/UI/Agent/AgentPointMenu.cs | 89 +++++++++++++++++++ ida/data.yml | 6 ++ 3 files changed, 130 insertions(+) create mode 100644 FFXIVClientStructs/FFXIV/Client/UI/AddonPointMenu.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs diff --git a/FFXIVClientStructs/FFXIV/Client/UI/AddonPointMenu.cs b/FFXIVClientStructs/FFXIV/Client/UI/AddonPointMenu.cs new file mode 100644 index 000000000..eac40b881 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/UI/AddonPointMenu.cs @@ -0,0 +1,35 @@ +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace FFXIVClientStructs.FFXIV.Client.UI; + +// Client::UI::AddonPointMenu +// Component::GUI::AtkUnitBase +// Component::GUI::AtkEventListener +[Addon("PointMenu")] +[GenerateInterop] +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x260)] +public unsafe partial struct AddonPointMenu { + [FieldOffset(0x238)] public StdVector> Entries; + + [FieldOffset(0x250)] public TooltipContext* TooltipContextData; + + [FieldOffset(0x258)] public int PendingFocusIndex; // Focus target index consumed in OnRefresh, then reset to -1 + + [StructLayout(LayoutKind.Explicit, Size = 0xA0)] + public struct Entry { + [FieldOffset(0x18)] public AtkComponentBase* Checkbox; + [FieldOffset(0x20)] public AtkResNode* TitleNode; + [FieldOffset(0x28)] public AtkResNode* ClickAreaNode; + [FieldOffset(0x30)] public Utf8String Title; // Entry title set by AgentPointMenu.SendEntryToAddon + [FieldOffset(0x98)] public byte IsActive; // Whether this entry is active (State > 0) + [FieldOffset(0x99)] public byte IsHovered; // Hover state flag, cleared each frame in Update + } + + [StructLayout(LayoutKind.Explicit, Size = 0x20)] + public struct TooltipContext { + [FieldOffset(0x08)] public AtkResNode* RootNode; + [FieldOffset(0x10)] public AtkTextNode* TextNode; + [FieldOffset(0x18)] public AtkResNode* BackgroundNode; + } +} diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs new file mode 100644 index 000000000..086888a75 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs @@ -0,0 +1,89 @@ +namespace FFXIVClientStructs.FFXIV.Client.UI.Agent; + +// Client::UI::Agent::AgentPointMenu +// Client::UI::Agent::AgentInterface +// Component::GUI::AtkModuleInterface::AtkEventInterface +[Agent(AgentId.PointMenu)] +[GenerateInterop] +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x48)] +public unsafe partial struct AgentPointMenu { + [FieldOffset(0x28)] public PointMenuContext* Context; + [FieldOffset(0x30)] public CompletionTree* CompletionData; + [FieldOffset(0x38)] public int Phase; + [FieldOffset(0x3C)] public int SelectedIndex; + [FieldOffset(0x40)] private uint unkInt40; + [FieldOffset(0x44)] private byte unkByte44; + + // Allocates a PointMenuContext and loads Excel Sheet PointMenu (1181) + [MemberFunction("40 55 41 56 41 57 48 83 EC ?? 48 8B 01 45 8B F8")] + public partial PointMenuContext* CreateContext(uint eventType, int unk); + + [MemberFunction("48 89 5C 24 ?? 48 89 74 24 ?? 55 57 41 54 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 0F 29 B4 24")] + public partial void SendEntryToAddon(uint index); + + [StructLayout(LayoutKind.Explicit, Size = 0x140)] + public struct PointMenuContext { + [FieldOffset(0x00)] public AgentPointMenu* Agent; + [FieldOffset(0x08)] private void* unk08; + [FieldOffset(0x10)] private void* unk10; + [FieldOffset(0x18)] public ExcelSheetWaiter SheetWaiter; + [FieldOffset(0xB8)] public Utf8String TitleText; + [FieldOffset(0x120)] public StdVector Entries; + [FieldOffset(0x138)] public uint EventType; + [FieldOffset(0x13C)] public bool IsLoaded; + } + + [StructLayout(LayoutKind.Explicit, Size = 0xA0)] + public struct ExcelSheetWaiter { + [FieldOffset(0x30)] public void* ScratchBuffer; + [FieldOffset(0x38)] private void* unk38; + [FieldOffset(0x40)] private void* unk40; + [FieldOffset(0x48)] private void* unkData48; + [FieldOffset(0x50)] private void* unkData50; + [FieldOffset(0x58)] private void* unk58; + [FieldOffset(0x60)] private void* unk60; + [FieldOffset(0x68)] private void* unk68; + [FieldOffset(0x70)] public void* OnLoadedCallback; + [FieldOffset(0x78)] public void* OnFailedCallback; + [FieldOffset(0x80)] public void* CallbackParam; + [FieldOffset(0x88)] public int SheetNumber; + [FieldOffset(0x8C)] private int unk8C; + [FieldOffset(0x90)] private void* unk90; + [FieldOffset(0x98)] private ushort flags98; + } + + [StructLayout(LayoutKind.Explicit, Size = 0x10)] + public struct CompletionTree { + [FieldOffset(0x00)] public CompletionTreeNode* Head; + [FieldOffset(0x08)] public ulong Count; + } + + [StructLayout(LayoutKind.Explicit, Size = 0x24)] + public struct CompletionTreeNode { + [FieldOffset(0x00)] public CompletionTreeNode* Left; + [FieldOffset(0x08)] public CompletionTreeNode* Parent; + [FieldOffset(0x10)] public CompletionTreeNode* Right; + [FieldOffset(0x18)] public byte Color; + [FieldOffset(0x19)] public byte IsNil; + [FieldOffset(0x1C)] public int Key; + [FieldOffset(0x20)] public int Bitfield; + } + + [StructLayout(LayoutKind.Explicit, Size = 0x88)] + public struct PointMenuEntry { + [FieldOffset(0x00)] public float X; + [FieldOffset(0x04)] public float Y; + [FieldOffset(0x08)] public float ClickAreaX; + [FieldOffset(0x0C)] public float ClickAreaY; + [FieldOffset(0x10)] public float ClickAreaWidth; + [FieldOffset(0x14)] public float ClickAreaHeight; + [FieldOffset(0x1A)] public byte State; + [FieldOffset(0x1B)] public byte IsElliptical; + [FieldOffset(0x1C)] public byte NavUp; + [FieldOffset(0x1D)] public byte NavDown; + [FieldOffset(0x1E)] public byte NavLeft; + [FieldOffset(0x1F)] public byte NavRight; + [FieldOffset(0x20)] public Utf8String Text; + } +} diff --git a/ida/data.yml b/ida/data.yml index b6d531c87..92ed93d54 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -15043,6 +15043,9 @@ classes: base: Client::UI::Agent::AgentInterface funcs: 0x140A6AAE0: ctor + 0x140A6ACF0: CreateContext + 0x140A6B390: SendEntryToAddon + 0x140AD30A0: Dtor Client::UI::Agent::AgentTradeScreenImage: vtbls: - ea: 0x142199040 @@ -23148,6 +23151,9 @@ classes: base: Component::GUI::AtkUnitBase funcs: 0x1413F3B80: ctor + 0x1413F3C60: Finalizer + 0x1413F5130: ShowTooltip + 0x1414467C0: Dtor Client::UI::AddonTradeScreenImage: # 910 vtbls: - ea: 0x142259CD0 From bc18205d586ead7531a63e9cf255b048974b4afd Mon Sep 17 00:00:00 2001 From: AtmoOmen Date: Sun, 3 May 2026 21:30:44 +0800 Subject: [PATCH 2/7] CompletionData --- .../FFXIV/Client/UI/Agent/AgentPointMenu.cs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs index 086888a75..0300d22a5 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs @@ -9,7 +9,7 @@ namespace FFXIVClientStructs.FFXIV.Client.UI.Agent; [StructLayout(LayoutKind.Explicit, Size = 0x48)] public unsafe partial struct AgentPointMenu { [FieldOffset(0x28)] public PointMenuContext* Context; - [FieldOffset(0x30)] public CompletionTree* CompletionData; + [FieldOffset(0x30)] public StdMap* CompletionData; [FieldOffset(0x38)] public int Phase; [FieldOffset(0x3C)] public int SelectedIndex; [FieldOffset(0x40)] private uint unkInt40; @@ -53,23 +53,6 @@ public struct ExcelSheetWaiter { [FieldOffset(0x98)] private ushort flags98; } - [StructLayout(LayoutKind.Explicit, Size = 0x10)] - public struct CompletionTree { - [FieldOffset(0x00)] public CompletionTreeNode* Head; - [FieldOffset(0x08)] public ulong Count; - } - - [StructLayout(LayoutKind.Explicit, Size = 0x24)] - public struct CompletionTreeNode { - [FieldOffset(0x00)] public CompletionTreeNode* Left; - [FieldOffset(0x08)] public CompletionTreeNode* Parent; - [FieldOffset(0x10)] public CompletionTreeNode* Right; - [FieldOffset(0x18)] public byte Color; - [FieldOffset(0x19)] public byte IsNil; - [FieldOffset(0x1C)] public int Key; - [FieldOffset(0x20)] public int Bitfield; - } - [StructLayout(LayoutKind.Explicit, Size = 0x88)] public struct PointMenuEntry { [FieldOffset(0x00)] public float X; From c5ce3bd621ec0542779a19f52802c7fd32a45bc8 Mon Sep 17 00:00:00 2001 From: AtmoOmen Date: Sun, 3 May 2026 21:39:35 +0800 Subject: [PATCH 3/7] should remove --- .../FFXIV/Client/UI/Agent/AgentPointMenu.cs | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs index 0300d22a5..6aa5c7668 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs @@ -1,3 +1,5 @@ +using FFXIVClientStructs.FFXIV.Common.Component.Excel; + namespace FFXIVClientStructs.FFXIV.Client.UI.Agent; // Client::UI::Agent::AgentPointMenu @@ -34,25 +36,6 @@ public struct PointMenuContext { [FieldOffset(0x13C)] public bool IsLoaded; } - [StructLayout(LayoutKind.Explicit, Size = 0xA0)] - public struct ExcelSheetWaiter { - [FieldOffset(0x30)] public void* ScratchBuffer; - [FieldOffset(0x38)] private void* unk38; - [FieldOffset(0x40)] private void* unk40; - [FieldOffset(0x48)] private void* unkData48; - [FieldOffset(0x50)] private void* unkData50; - [FieldOffset(0x58)] private void* unk58; - [FieldOffset(0x60)] private void* unk60; - [FieldOffset(0x68)] private void* unk68; - [FieldOffset(0x70)] public void* OnLoadedCallback; - [FieldOffset(0x78)] public void* OnFailedCallback; - [FieldOffset(0x80)] public void* CallbackParam; - [FieldOffset(0x88)] public int SheetNumber; - [FieldOffset(0x8C)] private int unk8C; - [FieldOffset(0x90)] private void* unk90; - [FieldOffset(0x98)] private ushort flags98; - } - [StructLayout(LayoutKind.Explicit, Size = 0x88)] public struct PointMenuEntry { [FieldOffset(0x00)] public float X; From 9ab28c420049bb4164aaa92b09ea0c6d9d159062 Mon Sep 17 00:00:00 2001 From: AtmoOmen <110901588+AtmoOmen@users.noreply.github.com> Date: Fri, 8 May 2026 22:56:56 +0800 Subject: [PATCH 4/7] Update ida/data.yml Co-authored-by: wolfcomp <4028289+wolfcomp@users.noreply.github.com> --- ida/data.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ida/data.yml b/ida/data.yml index 92ed93d54..2fcfbbe68 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -23153,7 +23153,6 @@ classes: 0x1413F3B80: ctor 0x1413F3C60: Finalizer 0x1413F5130: ShowTooltip - 0x1414467C0: Dtor Client::UI::AddonTradeScreenImage: # 910 vtbls: - ea: 0x142259CD0 From 218bc45abf3c3d224e9b12b3831434f006cf2182 Mon Sep 17 00:00:00 2001 From: AtmoOmen <110901588+AtmoOmen@users.noreply.github.com> Date: Fri, 8 May 2026 22:57:08 +0800 Subject: [PATCH 5/7] Update ida/data.yml Co-authored-by: wolfcomp <4028289+wolfcomp@users.noreply.github.com> --- ida/data.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ida/data.yml b/ida/data.yml index 2fcfbbe68..733df5211 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -15045,7 +15045,6 @@ classes: 0x140A6AAE0: ctor 0x140A6ACF0: CreateContext 0x140A6B390: SendEntryToAddon - 0x140AD30A0: Dtor Client::UI::Agent::AgentTradeScreenImage: vtbls: - ea: 0x142199040 From 4906e5751854fe12e88b5b74947ae181eb97507d Mon Sep 17 00:00:00 2001 From: AtmoOmen <110901588+AtmoOmen@users.noreply.github.com> Date: Fri, 8 May 2026 22:57:15 +0800 Subject: [PATCH 6/7] Update FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs Co-authored-by: wolfcomp <4028289+wolfcomp@users.noreply.github.com> --- FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs index 6aa5c7668..83d538416 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentPointMenu.cs @@ -21,7 +21,7 @@ public unsafe partial struct AgentPointMenu { [MemberFunction("40 55 41 56 41 57 48 83 EC ?? 48 8B 01 45 8B F8")] public partial PointMenuContext* CreateContext(uint eventType, int unk); - [MemberFunction("48 89 5C 24 ?? 48 89 74 24 ?? 55 57 41 54 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 0F 29 B4 24")] + [MemberFunction("E8 ?? ?? ?? ?? FF C3 3B DE 72 F0")] public partial void SendEntryToAddon(uint index); [StructLayout(LayoutKind.Explicit, Size = 0x140)] From a573b1734cc1e7995eee151c1ef619c56aa17915 Mon Sep 17 00:00:00 2001 From: AtmoOmen <110901588+AtmoOmen@users.noreply.github.com> Date: Fri, 8 May 2026 22:57:23 +0800 Subject: [PATCH 7/7] Update ida/data.yml Co-authored-by: wolfcomp <4028289+wolfcomp@users.noreply.github.com> --- ida/data.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ida/data.yml b/ida/data.yml index 733df5211..8aeb458b2 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -23150,7 +23150,6 @@ classes: base: Component::GUI::AtkUnitBase funcs: 0x1413F3B80: ctor - 0x1413F3C60: Finalizer 0x1413F5130: ShowTooltip Client::UI::AddonTradeScreenImage: # 910 vtbls: