From b12475b7a5fc271b134a730519415405a0c5bbfa Mon Sep 17 00:00:00 2001 From: AtmoOmen Date: Sat, 8 Aug 2026 18:36:40 +0800 Subject: [PATCH] Update InstanceContentText related structs for 7.55hf1 --- .../Game/InstanceContent/ContentDirector.cs | 12 ++++ .../InstanceContentDirector.cs | 3 + .../Scheduler/Clip/InstanceContentTextClip.cs | 59 +++++++++++++++++++ ida/data.yml | 15 +++++ 4 files changed, 89 insertions(+) create mode 100644 FFXIVClientStructs/FFXIV/Client/System/Scheduler/Clip/InstanceContentTextClip.cs diff --git a/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/ContentDirector.cs b/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/ContentDirector.cs index 6d9537cb2b..f66fdc2ca4 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/ContentDirector.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/ContentDirector.cs @@ -15,11 +15,14 @@ public unsafe partial struct ContentDirector { [FieldOffset(0x528)] public DutyActionManager DutyActionManager; + [FieldOffset(0xC88)] public Utf8String* InstanceContentTexts; [FieldOffset(0xC90)] public MapEffectList* MapEffects; [FieldOffset(0xC98)] private DynamicEventContainer* DynamicEvents; /// This might also be a countdown until the content starts (e.g. Frontlines), then the actual time left of the content. [FieldOffset(0xCF0)] public float ContentTimeLeft; + [FieldOffset(0xCFC)] public uint InstanceContentTextStartRowId; + [FieldOffset(0xD00)] public uint InstanceContentTextRowCount; [VirtualFunction(303)] public partial uint GetCurrentLevel(); @@ -38,6 +41,15 @@ public unsafe partial struct ContentDirector { [VirtualFunction(329)] public partial uint GetContentTimeMax(); + [VirtualFunction(354)] + public partial Utf8String* GetInstanceContentText(uint rowId); + + [MemberFunction("40 55 56 41 57 48 83 EC ?? 44 8B FA 4C 89 74 24")] + public partial void* LoadInstanceContentTexts(uint startRowId, uint rowCount); + + [MemberFunction("2B 91 FC 0C 00 00 4C 8B C9 8B C2 49 8B D0 48 6B C8 68 49 03 89 88 0C 00 00 E9 ?? ?? ?? ??")] + public partial void SetInstanceContentText(uint rowId, CStringPointer text); + /// Changes the state of a map effect. /// Index into MapEffects. /// The new state for this MapEffect. diff --git a/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/InstanceContentDirector.cs b/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/InstanceContentDirector.cs index e0f0484952..c8e8207b0e 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/InstanceContentDirector.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/InstanceContent/InstanceContentDirector.cs @@ -83,6 +83,9 @@ public unsafe partial struct InstanceContentDirector { [FieldOffset(0xDE0)] public ContentDirector.MapEffectList ManagedSharedGroups; + /// InstanceContentTextData Row 0 - 11 + [FieldOffset(0x1A60), FixedSizeArray] internal FixedSizeArray12 _commonInstanceContentTexts; + /// Dispatches updates specific to the content. This ends up calling ProcessContentSpecificDirectorUpdate and unrolls the parameters array. [VirtualFunction(380)] public partial void DispatchContentSpecificDirectorUpdate(uint category, uint* parameters); diff --git a/FFXIVClientStructs/FFXIV/Client/System/Scheduler/Clip/InstanceContentTextClip.cs b/FFXIVClientStructs/FFXIV/Client/System/Scheduler/Clip/InstanceContentTextClip.cs new file mode 100644 index 0000000000..27be5b60a1 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/Scheduler/Clip/InstanceContentTextClip.cs @@ -0,0 +1,59 @@ +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace FFXIVClientStructs.FFXIV.Client.System.Scheduler.Clip; + +// Client::System::Scheduler::Clip::InstanceContentTextClip +[GenerateInterop] +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0xD0)] +[VirtualTable("48 8D 05 ?? ?? ?? ?? 33 D2 C7 41 ?? ?? ?? ?? ?? 48 89 51 ?? 88 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 48 89 51 ?? 89 51 ?? 48 89 51 ?? 89 51 ?? 89 91 ?? ?? ?? ?? C7 41 ?? ?? ?? ?? ?? C7 81 ?? ?? ?? ?? ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? 48 89 01 48 8B C1 66 C7 81 ?? ?? ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? 88 91 ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? 48 89 91 ?? ?? ?? ?? C3", 3, 63)] +public unsafe partial struct InstanceContentTextClip { + [FieldOffset(0x48), CExporterIgnore] public InstanceContentTextClipData* Data; + + /// InstanceContentTextData + [FieldOffset(0x98)] public CStringPointer Text; + + /// BNpcName + [FieldOffset(0xA0)] public CStringPointer Speaker; + + [FieldOffset(0xA8)] public uint ResolvedRowId; + [FieldOffset(0xAC)] public uint ResolvedBNpcNameRowId; + [FieldOffset(0xB0)] public bool Finished; + + /// The TalkSubtitle addon ID, or zero when the addon is not open. + [FieldOffset(0xB4)] public uint AddonId; + + [FieldOffset(0xB8)] public float ElapsedTime; + [FieldOffset(0xBC)] public float SubtitleScaleX; + [FieldOffset(0xC0)] public float SubtitleScaleY; + [FieldOffset(0xC4)] public float SubtitlePositionX; + [FieldOffset(0xC8)] public float SubtitlePositionY; + + [VirtualFunction(7)] public partial bool IsFinished(); + [VirtualFunction(16)] public partial bool ResolveText(); + [VirtualFunction(31)] public partial void Publish(); + + [MemberFunction("E8 ?? ?? ?? ?? 33 ED 84 C0 0F 84 ?? ?? ?? ?? 48 89 9C 24 ?? ?? ?? ?? 48 8D 44 24 ?? BB")] + public partial bool UpdateTalkSubtitleLayout(float* scaleX, float* scaleY, float* positionY, float* positionX); + + [MemberFunction("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B D9 48 63 EA")] + public partial void OpenOrUpdateTalkSubtitle(int eventKind, AtkValue* values, uint valueCount); + + [StructLayout(LayoutKind.Explicit, Size = 0x1C)] + public struct InstanceContentTextClipData { + [FieldOffset(0x0C)] public InstanceContentTextDisplayMode DisplayMode; + [FieldOffset(0x10)] public uint RowId; + [FieldOffset(0x14)] public uint BNpcNameRowId; + + /// The display duration in seconds. + [FieldOffset(0x18)] public float Duration; + } + + public enum InstanceContentTextDisplayMode : uint { + /// Displays the text through UIModule.ShowBattleTalkImage. + BattleTalkImage, + + /// Displays the text in the TalkSubtitle addon. + TalkSubtitle, + } +} diff --git a/ida/data.yml b/ida/data.yml index 1a6e07623a..e47fa110b6 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -18337,8 +18337,11 @@ classes: 329: GetContentTimeMax 330: GetContentTypeIconId 335: SetExperience + 354: GetInstanceContentText funcs: 0x140B6E290: ctor + 0x140B6B760: LoadInstanceContentTexts + 0x140B6B850: SetInstanceContentText 0x140B6FE60: ApplyMapEffect 0x140B6FCD0: PlayMapEffectTimeline 0x140B70DE0: IsPlayCutscene @@ -27177,6 +27180,18 @@ classes: base: Client::System::Scheduler::Clip::BaseClip funcs: 0x141906170: ctor + Client::System::Scheduler::Clip::InstanceContentTextClip: + vtbls: + - ea: 0x14232A288 + base: Client::System::Scheduler::Clip::BaseClip + vfuncs: + 7: IsFinished + 16: ResolveText + 31: Publish + funcs: + 0x1419101F0: ctor + 0x141910AA0: UpdateTalkSubtitleLayout + 0x141910CC0: OpenOrUpdateTalkSubtitle Client::System::Scheduler::Base::SceneConnectionBlock: vtbls: - ea: 0x142453BA0