rodecomp/Source/Contents/NavigationRoute.cpp
ragnarok-clanker d4d8129b0d Decompile 2 functions in Source/Contents/NavigationRoute.cpp, Source/Contents/NavigationManager.h
Batch #1752 by ragnarok-clanker: 0 byte-identical, 2 confirmed by peer review.

- fn_19603 CNavigationManager::MapCellToView: logic confirmed by peer review
- fn_19608 CNavigationManager::RouteText: logic confirmed by peer review

Reviewed-by: ragnarok-clanker
2026-10-28 22:09:32 +00:00

394 lines
10 KiB
C++

#include "Contents/NavigationManager.h"
#include "Contents/MessageTable.h"
#include "Utility/Text/FormatString.h"
#include "Client/Registry.h"
#include "Client/Session.h"
#include "Resource/ResourceMgr.h"
#include "UI/Window/UIWindow.h"
#include "UI/Window/UIWindowMgr.h"
#include "Utility/RegistryKey.h"
#include <cstdio>
#include <cstring>
// OFFSET: 0x00B88800
// FUNCTION: fn_19376
CNaviInfo* CNavigationManager::FindObject(const char* name) const {
for (CNaviInfo* info : this->data.destinations) {
if (info->HasName(name)) {
return info;
}
}
return nullptr;
}
// OFFSET: 0x00B88840
// FUNCTION: fn_19377
CNavi_Link* CNaviData::FindLink(unsigned int key, bool byId) {
if (byId) {
for (CNavi_Link* object : this->objects) {
if (object->HasId(key)) {
return object;
}
}
return nullptr;
}
if (this->objects.empty() || key >= this->objects.size()) {
return nullptr;
}
return this->objects[key];
}
// OFFSET: 0x00B88910
// FUNCTION: fn_19379
int NaviCell::GetY() const {
return this->y;
}
// OFFSET: 0x00B88930
// FUNCTION: fn_19381
void CNaviData::ClearAll() {
this->Clear();
for (CNavi_Link*& object : this->objects) {
if (object != nullptr) {
delete object;
}
object = nullptr;
}
this->objects.clear();
for (CNaviInfo*& info : this->destinations) {
if (info != nullptr) {
delete info;
}
info = nullptr;
}
this->destinations.clear();
}
// OFFSET: 0x00B8CF70
// FUNCTION: fn_19432
bool CNavi_Object::HasId(const unsigned int& id) const {
return static_cast<unsigned int>(this->id) == id;
}
// OFFSET: 0x00B8D0D0
// FUNCTION: fn_19433
bool CNavi_Object::IsNamed(const char* name) const {
if (name == nullptr) {
return false;
}
return this->name == std::string(name);
}
// OFFSET: 0x00B8E8E0
// FUNCTION: fn_19496
int CNaviInfo::GetCellX() const {
return this->cellX;
}
// OFFSET: 0x00B97750
// FUNCTION: fn_19600
bool CNavigationManager::BuildRoute(int startX, int startY, int destX, int destY, bool collectCells) {
this->movementRoute.points.clear();
const bool found = this->pathFinder.FindPath(0, startX, startY, 8, 8, destX, destY, 1, this->movementRoute, 15);
this->pathFinder.Reset();
if (!collectCells) {
return found;
}
this->cells.clear();
if (!found) {
return found;
}
CNaviInfo* info = this->FindObject(g_session.m_navigationPlayerMap);
if (info == nullptr) {
const std::string resolved = ResourceMgr::Instance().aliases.ResolveMapName(g_session.m_navigationPlayerMap);
info = this->FindObject(resolved.c_str());
if (info == nullptr) {
return found;
}
}
const int height = info->GetCellY();
const int width = info->GetCellX();
int offsetX;
int offsetY;
const float scale = this->FitToSquare(&offsetX, &offsetY, width, height, 126.0f);
for (const MovementRoutePoint& point : this->movementRoute.points) {
NaviCell cell;
cell.x = static_cast<int>(point.x * scale + offsetX);
cell.y = static_cast<int>(126.0f - (point.y * scale + offsetY));
bool exists = false;
for (const NaviCell& other : this->cells) {
if (other.x == cell.x && other.y == cell.y) {
exists = true;
break;
}
}
if (!exists) {
this->cells.push_back(cell);
}
}
if (g_windowMgr.window_4F174 != nullptr) {
g_windowMgr.window_4F174->Invalidate();
}
return found;
}
// OFFSET: 0x00B97E90
// FUNCTION: fn_19603
NaviCell* CNavigationManager::MapCellToView(NaviCell* out, const char* mapName, int cellX, int cellY, float size) {
CNaviInfo* info = this->FindObject(mapName);
if (info == nullptr) {
const std::string resolved = ResourceMgr::Instance().aliases.ResolveMapName(mapName);
info = this->FindObject(resolved.c_str());
}
out->x = -1;
out->y = -1;
if (info != nullptr) {
const int height = info->GetCellY();
const int width = info->GetCellX();
int offsetX;
int offsetY;
const float scale = this->FitToSquare(&offsetX, &offsetY, width, height, size);
out->x = static_cast<int>(cellX * scale + offsetX);
out->y = static_cast<int>(static_cast<int>(size) - (cellY * scale + offsetY));
}
return out;
}
// OFFSET: 0x00B98630
// FUNCTION: fn_19608
std::string CNavigationManager::RouteText() {
char buffer[0x32];
std::memset(buffer, 0, sizeof(buffer));
CNaviInfo* info = this->data.GetInfo();
if (info != nullptr) {
NaviCell cell;
if (this->data.GetCell(&cell)->x > 0) {
NaviCell cellY;
NaviCell cellX;
const int y = this->data.GetCell(&cellY)->y;
const int x = this->data.GetCell(&cellX)->x;
StringFormat(buffer, sizeof(buffer), static_cast<std::size_t>(-1), "[%s] -> %s %d %d", LookupMessage(3585), info->GetName(), x, y);
} else {
StringFormat(buffer, sizeof(buffer), static_cast<std::size_t>(-1), "[%s] %s", LookupMessage(3585), info->GetName());
}
}
this->routeText.assign(buffer, std::strlen(buffer));
return this->routeText;
}
// OFFSET: 0x00B8D270
// FUNCTION: fn_19434
bool CNaviInfo::HasName(const char* name) const {
return std::strcmp(this->name.c_str(), name) == 0;
}
// OFFSET: 0x00B97FC0
// FUNCTION: fn_19604
std::string CNavigationManager::SelectedNodeText() {
char buffer[0x32];
std::memset(buffer, 0, sizeof(buffer));
if (!this->nodes.empty() && this->selectedNode >= 0) {
if (this->nodes.size() <= static_cast<unsigned>(this->selectedNode)) {
this->selectedNodeText.assign(buffer, std::strlen(buffer));
return this->selectedNodeText;
}
CNavi_Object* node = this->nodes[this->selectedNode];
NaviCell cellY;
NaviCell cellX;
const int y = node->GetCell(&cellY)->y;
const int x = node->GetCell(&cellX)->x;
std::sprintf(buffer, "%s %d %d...", node->GetInfo()->GetName(), x, y);
} else if (this->unknown_1258 == 2) {
CNaviInfo* info = this->data.GetInfo();
if (info != nullptr) {
NaviCell cellY;
NaviCell cellX;
const int y = this->data.GetCell(&cellY)->y;
const int x = this->data.GetCell(&cellX)->x;
std::sprintf(buffer, "%s %d %d...", info->GetName(), x, y);
}
}
this->selectedNodeText.assign(buffer, std::strlen(buffer));
return this->selectedNodeText;
}
// OFFSET: 0x00B981A0
// FUNCTION: fn_19605
std::string CNavigationManager::SubDestinationText() {
char buffer[0x32];
std::memset(buffer, 0, sizeof(buffer));
CNaviInfo* info = this->data.GetInfo();
if (info != nullptr) {
NaviCell cell;
if (this->data.GetCell(&cell)->x > 0) {
NaviCell cellY;
NaviCell cellX;
const int y = this->data.GetCell(&cellY)->y;
const int x = this->data.GetCell(&cellX)->x;
std::sprintf(buffer, ">.%s %d %d", info->GetName(), x, y);
} else {
std::sprintf(buffer, ">.%s", info->GetName());
}
}
this->subDestinationText.assign(buffer, std::strlen(buffer));
return this->subDestinationText;
}
// OFFSET: 0x00B982D0
// FUNCTION: fn_19606
std::string CNavigationManager::DestinationText() {
char buffer[0x32];
std::memset(buffer, 0, sizeof(buffer));
if (!this->nodes.empty() && this->selectedNode >= 0) {
if (this->nodes.size() <= static_cast<unsigned>(this->selectedNode)) {
this->destinationText.assign(buffer, std::strlen(buffer));
return this->destinationText;
}
CNavi_Object* node = this->nodes[this->selectedNode];
NaviCell cellY;
NaviCell cellX;
const int y = node->GetCell(&cellY)->y;
const int x = node->GetCell(&cellX)->x;
std::sprintf(buffer, "%s %d %d", node->GetInfo()->GetName(), x, y);
} else if (this->unknown_1258 == 2) {
CNaviInfo* info = this->data.GetInfo();
if (info != nullptr) {
NaviCell cellY;
NaviCell cellX;
const int y = this->data.GetCell(&cellY)->y;
const int x = this->data.GetCell(&cellX)->x;
std::sprintf(buffer, "%s %d %d", info->GetName(), x, y);
}
}
this->destinationText.assign(buffer, std::strlen(buffer));
return this->destinationText;
}
// OFFSET: 0x00B984C0
// FUNCTION: fn_19607
std::string CNavigationManager::DestinationTitle() {
char buffer[0x32];
std::memset(buffer, 0, sizeof(buffer));
if (!this->nodes.empty() && this->selectedNode >= 0) {
if (this->nodes.size() <= static_cast<unsigned>(this->selectedNode)) {
this->destinationTitle.assign(buffer, std::strlen(buffer));
return this->destinationTitle;
}
this->destinationTitle.assign(this->nodes[this->selectedNode]->GetInfo()->GetTitle());
return this->destinationTitle;
}
if (this->unknown_1258 == 2) {
NaviCell cell;
this->data.GetCell(&cell);
CNaviInfo* info = this->data.GetInfo();
if (info != nullptr) {
this->destinationTitle.assign(info->GetTitle());
return this->destinationTitle;
}
}
this->destinationTitle.assign(buffer, std::strlen(buffer));
return this->destinationTitle;
}
// OFFSET: 0x00B996D0
// FUNCTION: fn_19613
void CNavigationManager::LoadSettings() {
RegistryKey key;
std::string subKey(g_subKey);
subKey += "\Navigation";
if (key.Open(HKEY_LOCAL_MACHINE, subKey.c_str())) {
DWORD viewIcon = 0;
if (key.Query("ViewIcon", REG_DWORD, reinterpret_cast<BYTE*>(&viewIcon), sizeof(viewIcon))) {
this->viewIcon = viewIcon;
}
}
}
// OFFSET: 0x00B9C020
// FUNCTION: fn_19618
float CNavigationManager::FitToSquare(int* offsetX, int* offsetY, int width, int height, float size) const {
float scale;
if (width > height) {
scale = size / width;
*offsetY = static_cast<int>((width - height) * 0.5f * scale);
*offsetX = 0;
} else if (width < height) {
scale = size / height;
*offsetX = static_cast<int>((height - width) * 0.5f * scale);
*offsetY = 0;
} else {
*offsetY = 0;
scale = size / width;
*offsetX = 0;
}
return scale;
}
// OFFSET: 0x00B888F0
// FUNCTION: fn_19378
NaviCell* CNaviData::GetCell(NaviCell* out) {
out->x = this->cellX;
out->y = this->cellY;
return out;
}
// OFFSET: 0x00B88920
// FUNCTION: fn_19380
CNaviInfo* CNaviData::GetInfo() {
return this->info;
}
// OFFSET: 0x00B88A00
// FUNCTION: fn_45449
void CNaviData::Clear() {
this->startLinks.clear();
this->info = nullptr;
this->cellX = 0;
this->cellY = 0;
this->range = 50000;
this->endLinks.clear();
for (NaviDataEntry& entry : this->entries) {
entry.previous = -1;
entry.link = nullptr;
entry.cost = 0;
}
this->entries.clear();
}
// OFFSET: 0x00B8CD60
// FUNCTION: fn_19430
CNavi_Object::~CNavi_Object() {
this->id = -1;
this->type = 101;
this->index = -1;
this->name.clear();
this->title.clear();
this->cellX = 0;
this->cellY = 0;
this->info = nullptr;
this->links.clear();
}