From adfef2dad0e424cf6d82481cce40048dd175e880 Mon Sep 17 00:00:00 2001 From: Haselnussbomber Date: Tue, 20 Jan 2026 17:58:27 +0100 Subject: [PATCH] Add MapDiscoveryManager --- .../FFXIV/Client/Game/MapDiscoveryManager.cs | 52 +++++++++++++++++++ ida/data.yml | 12 +++++ 2 files changed, 64 insertions(+) create mode 100644 FFXIVClientStructs/FFXIV/Client/Game/MapDiscoveryManager.cs diff --git a/FFXIVClientStructs/FFXIV/Client/Game/MapDiscoveryManager.cs b/FFXIVClientStructs/FFXIV/Client/Game/MapDiscoveryManager.cs new file mode 100644 index 000000000..6fefd7332 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Game/MapDiscoveryManager.cs @@ -0,0 +1,52 @@ +namespace FFXIVClientStructs.FFXIV.Client.Game; + +// Client::Game::MapDiscoveryManager +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0x1024)] +public unsafe partial struct MapDiscoveryManager { + [StaticAddress("48 8D 0D ?? ?? ?? ?? 0F B6 87 ?? ?? ?? ?? 88 05", 3)] + public static partial MapDiscoveryManager* Instance(); + + /// Maps with up to 16 discoverable regions + /// Index is DiscoveryIndex, used when DiscoveryArrayByte is true (from Map sheet) + [FieldOffset(0x000), FixedSizeArray] internal FixedSizeArray162 _mapsWithUpTo16Regions; + /// Maps with up to 32 discoverable regions + /// Index is DiscoveryIndex, used when DiscoveryArrayByte is false (from Map sheet) + [FieldOffset(0xA20), FixedSizeArray] internal FixedSizeArray48 _mapsWithUpTo32Regions; + [FieldOffset(0x1020)] public float ReportCooldown; + + [MemberFunction("48 89 5C 24 ?? 57 48 83 EC ?? 48 8B 05 ?? ?? ?? ?? 8B FA")] + public partial bool IsDiscoveryEnabledForMap(uint mapId); + + /// + /// Checks if a map region was discovered.
+ /// This runs an internal Map sheet lookup! + ///
+ /// The Map RowId + /// The region index + /// if discovered, otherwise. + [MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 ?? 44 0B F7")] + public partial bool IsMapRegionDiscovered(uint mapId, byte regionIndex); + + /// + /// Checks if a map region was discovered, without Map sheet lookup. + /// + /// DiscoveryIndex from the Map sheet + /// The region index + /// DiscoveryArrayByte from the Map sheet + /// if discovered, otherwise. + [MemberFunction("33 C0 4C 8B D1 66 3B C2 7F ?? 45 84 C9 74 ?? B8 ?? ?? ?? ?? 66 3B D0 73 ?? 48 0F BF C2")] + public partial bool IsRegionDiscovered(ushort discoveryIndex, byte regionIndex, bool isMapWithUpTo16Regions); + + [GenerateInterop] + [StructLayout(LayoutKind.Explicit, Size = 16)] + public partial struct DiscoveryTable16 { + [FieldOffset(0x00), FixedSizeArray] internal FixedSizeArray16 _discoveries; + } + + [GenerateInterop] + [StructLayout(LayoutKind.Explicit, Size = 32)] + public partial struct DiscoveryTable32 { + [FieldOffset(0x00), FixedSizeArray] internal FixedSizeArray32 _discoveries; + } +} diff --git a/ida/data.yml b/ida/data.yml index 39dfbbd24..0a745eb4a 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -550,6 +550,17 @@ classes: 0x140833D90: ResetBGM 0x140833DE0: SetBGMPlayState # static 0x140833E10: ctor + Client::Game::MapDiscoveryManager: + instances: + - ea: 0x1429BFFF0 + funcs: + 0x140835C00: ReadDiscoveryListPacket + 0x140835D30: ReadDiscoveryPacket + 0x140835F40: IsMapRegionDiscovered + 0x140836290: IsRegionDiscovered + 0x140836010: SendMapRangeEntered + 0x140836190: Update + 0x1408366A0: IsDiscoveryEnabledForMap Client::Game::Control::InputManager: instances: - ea: 0x1427AC640 @@ -5957,6 +5968,7 @@ classes: 0x140B9F380: HandleTreasureFadeOutPacket 0x140B9F410: HandleWeatherChangePacket 0x140B9F430: HandleDiscoveryPacket + 0x140B9F450: HandleDiscoveryListPacket 0x140B9F470: HandlePlayerTitleListPacket 0x140B9F4C0: HandleUpdatePartyPositionsPacket 0x140B9F4F0: HandleUpdateAllianceNormalPositionsPacket