diff --git a/Source/Contents/NavigationManager.h b/Source/Contents/NavigationManager.h index eeb5d7e7..55235cb4 100644 --- a/Source/Contents/NavigationManager.h +++ b/Source/Contents/NavigationManager.h @@ -363,6 +363,10 @@ public: void CancelRoute(); void DrawRoute(const float* matrix); void CheckArrival(int cellX, int cellY); + int RouteFromPlayer(); + int Navigate(int cellX, int cellY); + int LoadReplayState(const std::vector& data); + void ResumeRoute(); /* 0000 */ CNaviData data; /* 004C */ CPathFinder pathFinder; diff --git a/Source/Contents/NavigationRoute.cpp b/Source/Contents/NavigationRoute.cpp index f93c061b..81b86ad2 100644 --- a/Source/Contents/NavigationRoute.cpp +++ b/Source/Contents/NavigationRoute.cpp @@ -1478,3 +1478,87 @@ void CNavigationManager::CancelRoute() { } g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(2309)), 0x62B0FF, 0, 0, 0); } + +// OFFSET: 0x00B97B90 +// FUNCTION: fn_19602 +int CNavigationManager::Navigate(int cellX, int cellY) { + int x = cellX; + int y = cellY; + if (this->savedTarget.object != nullptr) { + const int type = this->savedTarget.type; + CNaviInfo* info; + if (type == 2) { + CNavi_Object* object = static_cast(this->savedTarget.object); + info = object->GetInfo(); + NaviCell cell; + const NaviCell* position = object->GetCell(&cell); + x = position->x; + y = position->y; + } else if (type == 3 || type == 1 || type != 0) { + goto request; + } else { + info = static_cast(this->savedTarget.object); + } + + bool sameMap = std::strcmp(info->GetName(), g_session.m_navigationPlayerMap) == 0; + if (!sameMap) { + const std::string resolved = ResourceMgr::Instance().aliases.ResolveMapName(g_session.m_navigationPlayerMap); + sameMap = std::strcmp(info->GetName(), resolved.c_str()) == 0; + } + + if (sameMap) { + if (CGameMode* mode = static_cast(g_modeMgr.GetGameMode())) { + int playerX; + int playerY; + mode->PlayerCell(&playerX, &playerY); + if (playerX <= x + 1 && playerX >= x - 1 && playerY <= y + 1 && playerY >= y - 1) { + return 11; + } + } + } + } + +request: + if (this->RequestRoute(cellX, cellY) == -99) { + if (!this->RouteToSavedTarget(cellX, cellY)) { + return -97; + } + if (!this->CollectStartLinks()) { + return -98; + } + const int type = this->savedTarget.type; + this->routeResult = + this->data.FindRoute(&this->nodes, type != 2 && type != 0, this->unknown_127C, this->unknown_127D, this->unknown_127E, this->unknown_1280); + if (this->routeResult == 0) { + return -96; + } + } + return this->RouteFromPlayer(); +} + +#pragma pack(push, 1) +struct NavigationReplayHeader { + /* 0000 */ std::int16_t tag; + /* 0002 */ int size; + + NavigationReplayHeader() : tag(0), size(0) { + } + + ~NavigationReplayHeader() { + this->tag = 0; + this->size = 0; + } + + void Read(const unsigned char* source) { + this->size = 0; + this->tag = 0; + std::memcpy(this, source, sizeof(*this)); + } +}; +#pragma pack(pop) + +static_assert(sizeof(NavigationReplayHeader) == 6); + +// OFFSET: 0x00B9B080 + +// OFFSET: 0x00B9BFC0 diff --git a/Source/Contents/NavigationSource.cpp b/Source/Contents/NavigationSource.cpp index db416eea..a80f7da3 100644 --- a/Source/Contents/NavigationSource.cpp +++ b/Source/Contents/NavigationSource.cpp @@ -1,5 +1,8 @@ #include "Contents/NavigationManager.h" +#include "Client/Mode/CGameMode.h" +#include "Client/Mode/ModeMgr.h" #include "Client/Session.h" +#include "Contents/World/World.h" #include "Resource/ResourceMgr.h" #include "Utility/Text/FormatString.h" #include "UI/Window/UINavigationWnd.h" @@ -610,6 +613,8 @@ void CNavigationManager::ClearCurrentObject() { this->currentTarget.object = nullptr; } +// OFFSET: 0x00B95280 + // OFFSET: 0x00B95AD0 // FUNCTION: fn_19576 void CNavigationManager::ClearStates() {