From ba735b2993d5e2daa6fa7685e5fe2384db544764 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Sat, 31 Oct 2026 16:02:15 +0000 Subject: [PATCH] Decompile fn_23499 (CSession::LoadMapPosTable) Batch #8254 by eAthena: 0 byte-identical, 1 confirmed by peer review. - fn_23499 CSession::LoadMapPosTable: logic confirmed by peer review Peer-reviewed-by: Yommy, System4z, pedrao Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Session.h | 22 ++++++- Source/Contents/MapNameTable.cpp | 106 +++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/Source/Client/Session.h b/Source/Client/Session.h index 2596cfdb..fc9c6cbc 100644 --- a/Source/Client/Session.h +++ b/Source/Client/Session.h @@ -54,6 +54,18 @@ struct AchievementRecordPacket { }; #pragma pack(pop) +struct MapPosRect { + /* 0000 */ int left; + /* 0004 */ int top; + /* 0008 */ int right; + /* 000C */ int bottom; +}; + +struct MapPosEntry { + /* 0000 */ MapPosRect rect; + /* 0010 */ int valid; +}; + struct SessionRecord6178Entry { /* 0000 */ std::string unknown_0000; /* 0018 */ int unknown_0018; @@ -305,7 +317,12 @@ public: /* 52C4 */ std::vector m_robeNames; /* 52D0 */ std::vector m_navigationForbiddenMaps; /* 52DC */ std::vector> m_commandOptions; - /* 52E8 */ unsigned char unknown_52E8[0x44]; + /* 52E8 */ unsigned char unknown_52E8[0x28]; + /* 5310 */ std::map m_mapPositions; + /* 5318 */ std::map* m_mapPosLists; + /* 531C */ std::map m_mapPosBounds; + /* 5324 */ int unknown_5324; + /* 5328 */ int m_mapPosListCount; /* 532C */ int unknown_532C; /* 5330 */ int unknown_5330; /* 5334 */ int unknown_5334; @@ -567,6 +584,7 @@ public: void LoadDamageSkinSettings(); bool LoadExceptionMinimapNameTable(); bool LoadMapNameTable(); + bool LoadMapPosTable(); bool LoadFogParameters(); void ClearHomunStatus(); std::pair* InsertPair(int key, int value); @@ -995,6 +1013,8 @@ static_assert(offsetof(SubChatWndInfo, x) == 0x34); static_assert(offsetof(CSession, m_noSubChatWnds) == 0x73C); static_assert(offsetof(CSession, m_subChatWnds) == 0x744); static_assert(offsetof(CSession, m_prohibitionLog) == 0x754); +static_assert(offsetof(CSession, m_mapPositions) == 0x5310); +static_assert(offsetof(CSession, m_mapPosListCount) == 0x5328); static_assert(offsetof(SessionRecord6144, unknown_002C) == 0x2C); static_assert(offsetof(SessionRecord6144, unknown_0030) == 0x30); static_assert(offsetof(CSession, m_additionalSkills) == 0x4); diff --git a/Source/Contents/MapNameTable.cpp b/Source/Contents/MapNameTable.cpp index 98000ea2..a7a977c4 100644 --- a/Source/Contents/MapNameTable.cpp +++ b/Source/Contents/MapNameTable.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -85,3 +86,108 @@ bool CSession::LoadMapNameTable() { return loaded; } + +// OFFSET: 0x00DE8970 +// FUNCTION: fn_23499 +bool CSession::LoadMapPosTable() { + this->m_mapPosLists = nullptr; + this->m_mapPositions.clear(); + this->m_mapPosBounds.clear(); + + CFile file; + if (!file.Open("mapPosTable.txt", 0, true, false)) { + return false; + } + + const char* cursor = static_cast(file.GetData()); + const char* end = cursor + file.GetSize(); + int currentId = 0; + std::string name; + std::vector fields; + std::string token; + int boundsValid = 0; + MapPosRect bounds = {}; + const char* start = cursor; + for (; cursor < end; ++cursor) { + switch (*cursor) { + case '\n': + case '\r': + start = cursor + 1; + break; + case '@': + if (this->m_mapPosListCount == -1) { + this->m_mapPosListCount = std::atoi(std::string(start, cursor).c_str()); + this->m_mapPosLists = new std::map[this->m_mapPosListCount]; + } + break; + case '#': + if (token.size() == 0) { + token.assign(start, cursor - start); + const int id = std::atoi(std::string(start, cursor).c_str()); + if (currentId != id && boundsValid != 0) { + MapPosEntry& entry = this->m_mapPosBounds[currentId]; + entry.rect = bounds; + entry.valid = boundsValid; + bounds = {}; + boundsValid = 0; + currentId = id; + } + } else if (name.size() == 0) { + name.assign(start, cursor - start); + } else if (fields.size() < 3) { + fields.push_back(std::string(start, cursor)); + } else { + const std::string last(start, cursor); + fields.push_back(last); + const int bottom = std::atoi(fields[3].c_str()); + const int right = std::atoi(fields[2].c_str()); + const int top = std::atoi(fields[1].c_str()); + MapPosRect rect; + rect.left = std::atoi(fields[0].c_str()); + rect.top = top; + rect.right = right; + rect.bottom = bottom; + + MapPosEntry& listed = this->m_mapPosLists[currentId][name]; + listed.rect = rect; + listed.valid = 1; + MapPosEntry& position = this->m_mapPositions[name]; + position.rect = rect; + position.valid = 1; + + if (boundsValid == 0) { + bounds = rect; + boundsValid = 1; + } else { + if (bounds.right < right) { + bounds.right = right; + } + if (bounds.bottom < bottom) { + bounds.bottom = bottom; + } + if (rect.left < bounds.left) { + bounds.left = rect.left; + } + if (top < bounds.top) { + bounds.top = top; + } + } + + token.clear(); + name.clear(); + fields.clear(); + } + start = cursor + 1; + break; + } + } + + if (boundsValid != 0) { + MapPosEntry& entry = this->m_mapPosBounds[currentId]; + entry.rect = bounds; + entry.valid = boundsValid; + } + + file.Close(); + return true; +}