diff --git a/Source/Contents/MapInfoMgr.cpp b/Source/Contents/MapInfoMgr.cpp new file mode 100644 index 00000000..6fcb8707 --- /dev/null +++ b/Source/Contents/MapInfoMgr.cpp @@ -0,0 +1,182 @@ +#include "Contents/MapInfoMgr.h" +#include "Render/DeviceContext/DeviceContext.h" + +extern "C" { +#include +} + +#include +#include +#include + +// GLOBAL: gl_24842 +CMapInfoMgr* g_mapInfoMgr; + +// OFFSET: 0x006CE6A0 +// FUNCTION: fn_06483 +CMapInfoMgr::~CMapInfoMgr() { + this->m_maps.clear(); + if (this->m_display != nullptr) { + delete this->m_display; + this->m_display = nullptr; + } +} + +// OFFSET: 0x006CE820 +// FUNCTION: fn_06484 +void CMapInfoMgr::AddMapDisplayName(std::string map, std::string name, bool show) { + this->m_maps[map].m_displayName = name; + this->m_maps[map].m_showDisplayName = show; +} + +// OFFSET: 0x006CE8C0 +// FUNCTION: fn_06485 +void CMapInfoMgr::AddMapSignName(std::string map, std::string name, std::string subName) { + this->m_maps[map].m_sign = MapSignName{name, subName}; +} + +// OFFSET: 0x006CEAA0 +// FUNCTION: fn_06486 +bool CMapInfoMgr::Create() { + if (g_mapInfoMgr == nullptr) { + g_mapInfoMgr = new (std::nothrow) CMapInfoMgr(); + if (g_mapInfoMgr != nullptr) { + if (g_mapInfoMgr->m_initialized) { + return true; + } + + delete g_mapInfoMgr; + g_mapInfoMgr = nullptr; + } + } + + return false; +} + +// OFFSET: 0x006CED70 +// FUNCTION: fn_06488 +void CMapInfoMgr::Destroy() { + if (g_mapInfoMgr != nullptr) { + delete g_mapInfoMgr; + g_mapInfoMgr = nullptr; + } +} + +// OFFSET: 0x006CED90 +// FUNCTION: fn_06489 +const char* CMapInfoMgr::GetDisplayName(std::string map) { + const MapInfo* info = this->FindMapInfo(map); + if (info == nullptr) { + return this->m_emptyName.c_str(); + } + + return info->m_displayName.c_str(); +} + +// OFFSET: 0x006CEE20 +// FUNCTION: fn_06490 +MapInfo* CMapInfoMgr::FindMapInfo(std::string map) { + std::string name = map; + const std::size_t at = name.rfind('@'); + if (at != std::string::npos && at > 3) { + name.erase(at - 4, 3); + } + + const auto found = std::find_if(this->m_maps.begin(), this->m_maps.end(), [name](std::pair entry) { + return entry.first.compare(name) == 0; + }); + if (found == this->m_maps.end()) { + return nullptr; + } + + return &found->second; +} + +// OFFSET: 0x006CEF60 +// FUNCTION: fn_06491 +const char* CMapInfoMgr::GetSignSubName(std::string map) { + const MapInfo* info = this->FindMapInfo(map); + if (info == nullptr) { + return this->m_emptyName.c_str(); + } + + return info->m_sign.m_subName.c_str(); +} + +// OFFSET: 0x006CF600 +// FUNCTION: fn_06495 +int CMapInfoMgr::L_AddMapBackgroundBmp(lua_State* state) { + if (!lua_isstring(state, -2)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 1nd is must string"); + } else { + const std::string map = lua_tostring(state, -2); + if (!lua_isstring(state, -1)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 2st is must string"); + } else { + const std::string bmp = lua_tostring(state, -1); + lua_pushboolean(state, 1); + lua_pushstring(state, "good"); + g_mapInfoMgr->AddMapBackgroundBmp(map, bmp); + } + } + + return 2; +} + +// OFFSET: 0x006CF860 +// FUNCTION: fn_06496 +int CMapInfoMgr::L_AddMapDisplayName(lua_State* state) { + if (!lua_isstring(state, -3)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 1st is must string"); + } else { + const std::string map = lua_tostring(state, -3); + if (!lua_isstring(state, -2)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 2nd is must string"); + } else { + const std::string name = lua_tostring(state, -2); + if (lua_type(state, -1) != LUA_TBOOLEAN) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 3th is must boolean"); + } else { + const bool show = lua_toboolean(state, -1) > 0; + lua_pushboolean(state, 1); + lua_pushstring(state, "good"); + g_mapInfoMgr->AddMapDisplayName(map, name, show); + } + } + } + + return 2; +} + +// OFFSET: 0x006CFB10 +// FUNCTION: fn_06497 +int CMapInfoMgr::L_AddMapSignName(lua_State* state) { + if (!lua_isstring(state, -3)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 1st is must string"); + } else { + const std::string map = lua_tostring(state, -3); + if (!lua_isstring(state, -2)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 2nd is must string"); + } else { + const std::string name = lua_tostring(state, -2); + if (!lua_isstring(state, -1)) { + lua_pushboolean(state, 0); + lua_pushstring(state, "argument 3st is must string"); + } else { + const std::string subName = lua_tostring(state, -1); + lua_pushboolean(state, 1); + lua_pushstring(state, "good"); + g_mapInfoMgr->AddMapSignName(map, name, subName); + } + } + } + + return 2; +} diff --git a/Source/Contents/MapInfoMgr.h b/Source/Contents/MapInfoMgr.h new file mode 100644 index 00000000..36cbd550 --- /dev/null +++ b/Source/Contents/MapInfoMgr.h @@ -0,0 +1,80 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_MAPINFOMGR_H +#define RAGNAROK_SOURCE_CONTENTS_MAPINFOMGR_H + +#include +#include + +#include + +class CDC; +class CTexture; +struct lua_State; + +struct MapSignName { + /* 0000 */ std::string m_name; + /* 0018 */ std::string m_subName; +}; + +struct MapInfo { + /* 0000 */ std::string m_displayName; + /* 0018 */ bool m_showDisplayName; + /* 001C */ MapSignName m_sign; + /* 004C */ std::string m_backgroundBmp; +}; + +struct MapNameDisplay { + /* 0000 */ CTexture* m_texture; + /* 0004 */ CDC* m_dc; + /* 0008 */ unsigned short m_width; + /* 000A */ unsigned short m_height; + /* 000C */ DWORD m_startTime; + + // INLINED + ~MapNameDisplay() { + if (this->m_dc != nullptr) { + delete this->m_dc; + this->m_dc = nullptr; + } + } +}; + +class CMapInfoMgr { +public: + static bool Create(); + static void Destroy(); + static int L_AddMapBackgroundBmp(lua_State* state); + static int L_AddMapDisplayName(lua_State* state); + static int L_AddMapSignName(lua_State* state); + + /* 0004 */ bool m_initialized; + /* 0008 */ std::map m_maps; + /* 0010 */ std::string m_emptyName; + /* 0028 */ MapNameDisplay* m_display; + + virtual ~CMapInfoMgr(); + + // INLINED + CMapInfoMgr() : m_display(nullptr) { + this->m_initialized = true; + } + + void AddMapDisplayName(std::string map, std::string name, bool show); + void AddMapSignName(std::string map, std::string name, std::string subName); + // INLINED + void AddMapBackgroundBmp(std::string map, std::string bmp) { + this->m_maps[map].m_backgroundBmp = bmp; + } + MapInfo* FindMapInfo(std::string map); + const char* GetDisplayName(std::string map); + const char* GetSignSubName(std::string map); +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(MapInfo) == 0x64); +static_assert(sizeof(MapNameDisplay) == 0x10); +static_assert(sizeof(CMapInfoMgr) == 0x2C); +#endif + +extern CMapInfoMgr* g_mapInfoMgr; + +#endif diff --git a/Source/Contents/PrivateAirplaneMgr.cpp b/Source/Contents/PrivateAirplaneMgr.cpp new file mode 100644 index 00000000..93ad1405 --- /dev/null +++ b/Source/Contents/PrivateAirplaneMgr.cpp @@ -0,0 +1,29 @@ +#include "Contents/PrivateAirplaneMgr.h" + +extern "C" { +#include +} + +// GLOBAL: gl_24636 +CPrivateAirplaneMgr* g_privateAirplaneItems; + +// OFFSET: 0x006D0620 +// FUNCTION: fn_06505 +void CPrivateAirplaneMgr::Destroy() { + if (g_privateAirplaneItems != nullptr) { + delete g_privateAirplaneItems; + g_privateAirplaneItems = nullptr; + } +} + +// OFFSET: 0x006D0640 + +// OFFSET: 0x006D0860 + +// OFFSET: 0x006D0950 + +// OFFSET: 0x006D0EF0 + +// OFFSET: 0x006D10E0 + +// OFFSET: 0x006D1260 diff --git a/Source/Contents/PrivateAirplaneMgr.h b/Source/Contents/PrivateAirplaneMgr.h new file mode 100644 index 00000000..2c04f26e --- /dev/null +++ b/Source/Contents/PrivateAirplaneMgr.h @@ -0,0 +1,42 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_PRIVATEAIRPLANEMGR_H +#define RAGNAROK_SOURCE_CONTENTS_PRIVATEAIRPLANEMGR_H + +#include +#include + +struct lua_State; + +class CPrivateAirplaneMgr { +public: + static void Destroy(); + static int L_InsertNeedItem(lua_State* state); + static int L_InsertEndableMap(lua_State* state); + static int L_InsertStartableMap(lua_State* state); + + /* 0004 */ bool m_initialized; + /* 0008 */ std::set m_startableMaps; + /* 0010 */ std::set m_endableMaps; + /* 0018 */ std::set m_needItems; + + virtual ~CPrivateAirplaneMgr() = default; + + int GetNeedItem(int index); + bool IsEndableMap(std::string map); + bool IsStartableMap(std::string map); + // INLINED + void InsertStartableMap(std::string map) { + this->m_startableMaps.insert(map); + } + // INLINED + void InsertEndableMap(std::string map) { + this->m_endableMaps.insert(map); + } +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(CPrivateAirplaneMgr) == 0x20); +#endif + +extern CPrivateAirplaneMgr* g_privateAirplaneItems; + +#endif diff --git a/data/compile.json b/data/compile.json index 48802308..64dc97fa 100644 --- a/data/compile.json +++ b/data/compile.json @@ -392,6 +392,7 @@ "Source/Contents/Jobs/JobInheritance.cpp": 4, "Source/Contents/Jobs/JobNameInitialization.cpp": 4, "Source/Contents/Jobs/JobNames.cpp": 4, + "Source/Contents/MapInfoMgr.cpp": 4, "Source/Contents/MapPropertyMgr.cpp": 4, "Source/Contents/MapSkyMgr.cpp": 4, "Source/Contents/MessageTable.cpp": 4, @@ -450,6 +451,7 @@ "Source/Contents/PetTalk.cpp": 4, "Source/Contents/PetTalkNames.cpp": 4, "Source/Contents/PlayerNameDictionary.cpp": 4, + "Source/Contents/PrivateAirplaneMgr.cpp": 4, "Source/Contents/RenewQuestMgr.cpp": 4, "Source/Contents/RobeOpacity.cpp": 4, "Source/Contents/RobeResources.cpp": 4,