fix(Core/Travel): GetFullPath now reuses failed probe waypoints as startPath via cropPathTo (matches reference)

This commit is contained in:
bash 2026-05-31 13:49:59 +02:00
parent ac741cac80
commit c194daa8a1

View File

@ -1705,14 +1705,14 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uin
// Probe-first short-circuit (matches reference exactly): if a 40-step // Probe-first short-circuit (matches reference exactly): if a 40-step
// mmap probe from bot to destination reaches within spellDistance of // mmap probe from bot to destination reaches within spellDistance of
// dest, use the probe directly and skip graph routing. Otherwise // dest, use the probe directly and skip graph routing. Otherwise
// fall through to the graph A* below — the failed probe waypoints // the probe waypoints are kept as `beginPath` and fed into per-
// would ideally feed into getRoute as startPath (reference does // candidate startPath cropping below.
// this; we don't yet — TODO). std::vector<WorldPosition> beginPath;
if (botPos.GetMapId() == destination.GetMapId()) if (botPos.GetMapId() == destination.GetMapId())
{ {
std::vector<WorldPosition> probe = destination.getPathFromPath({botPos}, bot, 40); beginPath = destination.getPathFromPath({botPos}, bot, 40);
if (destination.isPathTo(probe, sPlayerbotAIConfig.spellDistance)) if (destination.isPathTo(beginPath, sPlayerbotAIConfig.spellDistance))
return TravelPath(probe); return TravelPath(beginPath);
} }
std::shared_lock<std::shared_timed_mutex> guard(m_nMapMtx); std::shared_lock<std::shared_timed_mutex> guard(m_nMapMtx);
@ -1815,10 +1815,17 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uin
} }
// Validate bot -> startNode is pathable within maxStartDistance. // Validate bot -> startNode is pathable within maxStartDistance.
// Reference reuses the (failed) probe waypoints first via
// cropPathTo, falling back to a fresh getPathTo only if the
// probe can't be cropped to reach startNode. This saves
// re-running mmap when the probe already covers part of
// the journey to startNode.
float const maxStartDistance = s->isTransport() ? 20.0f : 1.0f; float const maxStartDistance = s->isTransport() ? 20.0f : 1.0f;
std::vector<WorldPosition> pathToStart; std::vector<WorldPosition> pathToStart = beginPath;
bool startPathOk = false; bool startPathOk = !pathToStart.empty() &&
if (bot && botPos.GetMapId() == startNodePos.GetMapId()) startNodePos.cropPathTo(pathToStart, maxStartDistance);
if (!startPathOk && bot && botPos.GetMapId() == startNodePos.GetMapId())
{ {
pathToStart = botPos.getPathTo(startNodePos, bot); pathToStart = botPos.getPathTo(startNodePos, bot);
startPathOk = startNodePos.isPathTo(pathToStart, maxStartDistance); startPathOk = startNodePos.isPathTo(pathToStart, maxStartDistance);
@ -1831,7 +1838,10 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uin
continue; continue;
} }
// Both ends validated — build and return. // Both ends validated — build and return. Save the
// successful pathToStart back as beginPath so subsequent
// ResolveMovePath cycles can reuse it.
beginPath = pathToStart;
path = route.BuildPath(pathToStart, endProbe, bot); path = route.BuildPath(pathToStart, endProbe, bot);
route.cleanTempNodes(); route.cleanTempNodes();
return path; return path;