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