Decompile 3 functions in Source/Contents/NavigationRoute.cpp, Source/Contents/NavigationSource.cpp, ...
Batch #7526 by secret: 0 byte-identical, 3 confirmed by peer review. - fn_19616 CNavigationManager::LoadReplayState: logic confirmed by peer review - fn_19617 CNavigationManager::ResumeRoute: logic confirmed by peer review - fn_19573 CNavigationManager::RouteFromPlayer: logic confirmed by peer review Peer-reviewed-by: eAthena, Yommy Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
parent
bdcc7352e2
commit
1422899c9e
2 changed files with 336 additions and 0 deletions
|
|
@ -1560,5 +1560,194 @@ struct NavigationReplayHeader {
|
|||
static_assert(sizeof(NavigationReplayHeader) == 6);
|
||||
|
||||
// OFFSET: 0x00B9B080
|
||||
// FUNCTION: fn_19616
|
||||
int CNavigationManager::LoadReplayState(const std::vector<unsigned char>& data) {
|
||||
g_windowMgr.CloseWindow(203);
|
||||
this->Reset(true);
|
||||
if (data.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<char> buffer;
|
||||
NavigationReplayHeader header;
|
||||
unsigned offset = 6;
|
||||
header.Read(data.data());
|
||||
if (header.tag != 8000) {
|
||||
offset = static_cast<unsigned>(-1);
|
||||
} else {
|
||||
while (offset < data.size()) {
|
||||
header.Read(data.data() + offset);
|
||||
offset += 6;
|
||||
if (header.tag == 8001) {
|
||||
this->ResumeRoute();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (header.tag) {
|
||||
case 8002:
|
||||
std::memcpy(&this->unknown_127D, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8003:
|
||||
std::memcpy(&this->unknown_127E, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8004:
|
||||
std::memcpy(&this->unknown_127C, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8005:
|
||||
std::memcpy(&this->unknown_1280, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8006: {
|
||||
buffer.resize(header.size + 1);
|
||||
std::memcpy(buffer.data(), data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
NavigationTarget target = this->ReadTarget(buffer.data(), header.size);
|
||||
if (target.object != nullptr) {
|
||||
this->states.push_back(target);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8007:
|
||||
buffer.resize(header.size + 1);
|
||||
std::memcpy(buffer.data(), data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
this->currentTarget = this->ReadTarget(buffer.data(), header.size);
|
||||
break;
|
||||
case 8008:
|
||||
buffer.resize(header.size + 1);
|
||||
std::memcpy(buffer.data(), data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
this->savedTarget = this->ReadTarget(buffer.data(), header.size);
|
||||
break;
|
||||
case 8009:
|
||||
std::memcpy(&this->unknown_124C, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8010:
|
||||
std::memcpy(&this->unknown_1250, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8011:
|
||||
std::memcpy(&this->unknown_1254, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8012:
|
||||
std::memcpy(&this->unknown_1258, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8013:
|
||||
std::memcpy(&this->unknown_125C, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8014:
|
||||
std::memcpy(&this->unknown_1260, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8015:
|
||||
buffer.resize(header.size + 1);
|
||||
std::memcpy(buffer.data(), data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
this->unknown_1264 = buffer.data();
|
||||
break;
|
||||
case 8016:
|
||||
std::memcpy(&this->unknown_1284, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8017:
|
||||
std::memcpy(&this->unknown_117C, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8018:
|
||||
std::memcpy(&this->routeResult, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8019:
|
||||
std::memcpy(&this->unknown_115C, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8020:
|
||||
std::memcpy(&this->selectedNode, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
case 8021: {
|
||||
buffer.resize(header.size + 1);
|
||||
std::memcpy(buffer.data(), data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
const int* route = reinterpret_cast<const int*>(buffer.data());
|
||||
int x = route[2];
|
||||
int y = route[3];
|
||||
if (this->savedTarget.object != nullptr) {
|
||||
const int type = this->savedTarget.type;
|
||||
CNaviInfo* info;
|
||||
bool found = true;
|
||||
if (type == 2) {
|
||||
CNavi_Object* object = static_cast<CNavi_Object*>(this->savedTarget.object);
|
||||
info = object->GetInfo();
|
||||
NaviCell cell;
|
||||
const NaviCell* position = object->GetCell(&cell);
|
||||
x = position->x;
|
||||
y = position->y;
|
||||
} else if (type == 3) {
|
||||
info = static_cast<CNavi_Object*>(this->savedTarget.object)->GetInfo();
|
||||
x = -1;
|
||||
y = -1;
|
||||
} else if (type == 1) {
|
||||
x = -1;
|
||||
y = -1;
|
||||
info = static_cast<CNaviInfo*>(this->savedTarget.object);
|
||||
} else if (type == 0) {
|
||||
info = static_cast<CNaviInfo*>(this->savedTarget.object);
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
if (found) {
|
||||
this->data.SetDestination(info, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
||||
if (mode && mode->scene && mode->scene->terrain) {
|
||||
this->ground = mode->scene->ground;
|
||||
this->pathFinder.attr = mode->scene->terrain;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8022: {
|
||||
buffer.resize(header.size + 1);
|
||||
std::memcpy(buffer.data(), data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
CNavi_Link* node = this->ReadObject(buffer.data());
|
||||
if (node != nullptr) {
|
||||
this->nodes.push_back(node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8023:
|
||||
std::memcpy(&this->unknown_1248, data.data() + offset, header.size);
|
||||
offset += header.size;
|
||||
break;
|
||||
default:
|
||||
offset += header.size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return static_cast<int>(offset);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B9BFC0
|
||||
// FUNCTION: fn_19617
|
||||
void CNavigationManager::ResumeRoute() {
|
||||
if (this->unknown_1258 == 1) {
|
||||
this->LoadTargetPreview();
|
||||
g_windowMgr.EnsureWindow(203);
|
||||
} else if (this->unknown_1258 == 2) {
|
||||
this->ShowRouteResult(this->RouteFromPlayer(), 1, *reinterpret_cast<WindowDialogs*>(&g_windowMgr));
|
||||
if (!this->unknown_1248) {
|
||||
g_windowMgr.EnsureWindow(203);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -614,6 +614,153 @@ void CNavigationManager::ClearCurrentObject() {
|
|||
}
|
||||
|
||||
// OFFSET: 0x00B95280
|
||||
// FUNCTION: fn_19573
|
||||
int CNavigationManager::RouteFromPlayer() {
|
||||
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) {
|
||||
this->unknown_117C = false;
|
||||
this->unknown_115C = false;
|
||||
this->unknown_12B4 = false;
|
||||
return -93;
|
||||
}
|
||||
}
|
||||
|
||||
int result = -96;
|
||||
this->unknown_117C = false;
|
||||
this->unknown_115C = false;
|
||||
this->unknown_12B4 = false;
|
||||
NaviCell player;
|
||||
player.x = 0;
|
||||
player.y = 0;
|
||||
if (CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode())) {
|
||||
mode->PlayerCell(&player.x, &player.y);
|
||||
}
|
||||
|
||||
if (this->data.GetInfo() == info) {
|
||||
const int type = this->savedTarget.type;
|
||||
if (type != 2 && type != 0) {
|
||||
int code = type == 1 ? 6 : -96;
|
||||
if (type == 3) {
|
||||
code = 8;
|
||||
}
|
||||
this->CancelRoute();
|
||||
return code;
|
||||
}
|
||||
|
||||
NaviCell cell;
|
||||
if (player.x == this->data.GetCell(&cell)->x && player.y == this->data.GetCell(&cell)->y) {
|
||||
this->movementRoute.points.clear();
|
||||
PathCell point = {player.x, player.y, 0, 0};
|
||||
this->movementRoute.points.push_back(point);
|
||||
this->CancelRoute();
|
||||
return 11;
|
||||
}
|
||||
|
||||
NaviCell destination;
|
||||
if (this->BuildRoute(player.x, player.y, this->data.GetCell(&destination)->x, this->data.GetCell(&cell)->y, true)) {
|
||||
this->nodes.clear();
|
||||
this->routeResult = std::abs(player.x - this->data.GetCell(&destination)->x) + std::abs(player.y - this->data.GetCell(&cell)->y);
|
||||
this->selectedNode = -1;
|
||||
this->currentTarget = this->savedTarget;
|
||||
this->LoadTargetPreview();
|
||||
const int targetType = this->savedTarget.type;
|
||||
result = targetType == 2 ? 7 : -96;
|
||||
this->unknown_117C = true;
|
||||
this->unknown_115C = true;
|
||||
this->unknown_12B4 = true;
|
||||
if (targetType == 0) {
|
||||
result = 9;
|
||||
this->unknown_1258 = 2;
|
||||
return result;
|
||||
}
|
||||
if (targetType == 2) {
|
||||
this->unknown_1258 = 2;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NaviCell start = player;
|
||||
if (this->nodes.empty() || info == nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
||||
if (mode && mode->scene && mode->scene->terrain) {
|
||||
this->ground = mode->scene->ground;
|
||||
this->pathFinder.attr = mode->scene->terrain;
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<unsigned int> candidates;
|
||||
for (int index = static_cast<int>(this->nodes.size()) - 1; index > 0; --index) {
|
||||
if (this->nodes[index]->GetInfo() != info) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const NaviCell linked = this->nodes[index - 1]->GetLinkedCell();
|
||||
if (linked.x == start.x && linked.y == start.y) {
|
||||
NaviCell cellX;
|
||||
NaviCell cellY;
|
||||
if (this->BuildRoute(start.x, start.y, this->nodes[index]->GetCell(&cellX)->x, this->nodes[index]->GetCell(&cellY)->y, true)) {
|
||||
this->selectedNode = index;
|
||||
this->SelectTarget(index);
|
||||
this->unknown_117C = true;
|
||||
goto selected;
|
||||
}
|
||||
} else {
|
||||
candidates.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->nodes[0]->GetInfo() == info) {
|
||||
this->movementRoute.points.clear();
|
||||
NaviCell cellX;
|
||||
NaviCell cellY;
|
||||
if (start.x == this->nodes[0]->GetCell(&cellX)->x && start.y == this->nodes[0]->GetCell(&cellY)->y) {
|
||||
PathCell point = {start.x, start.y, 0, 0};
|
||||
this->movementRoute.points.push_back(point);
|
||||
} else if (!this->BuildRoute(start.x, start.y, this->nodes[0]->GetCell(&cellX)->x, this->nodes[0]->GetCell(&cellY)->y, true)) {
|
||||
goto search;
|
||||
}
|
||||
this->selectedNode = 0;
|
||||
this->SelectTarget(0);
|
||||
this->unknown_117C = true;
|
||||
goto selected;
|
||||
}
|
||||
|
||||
search:
|
||||
for (int index = 0; index < static_cast<int>(candidates.size()); ++index) {
|
||||
NaviCell cellX;
|
||||
NaviCell cellY;
|
||||
if (this->BuildRoute(start.x, start.y, this->nodes[candidates[index]]->GetCell(&cellX)->x, this->nodes[candidates[index]]->GetCell(&cellY)->y, true)) {
|
||||
this->selectedNode = candidates[index];
|
||||
this->SelectTarget(candidates[index]);
|
||||
this->unknown_117C = true;
|
||||
goto selected;
|
||||
}
|
||||
}
|
||||
|
||||
this->unknown_117C = false;
|
||||
if (this->nodes[0]->GetType() != 400) {
|
||||
return result;
|
||||
}
|
||||
this->selectedNode = 0;
|
||||
this->SelectTarget(0);
|
||||
}
|
||||
|
||||
selected:
|
||||
if (this->selectedNode == 0 && this->nodes[0]->GetType() == 400) {
|
||||
result = 4;
|
||||
} else {
|
||||
result = 5;
|
||||
}
|
||||
this->unknown_1258 = 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B95AD0
|
||||
// FUNCTION: fn_19576
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue