From c194daa8a1b3116700bedb8e1c61a5772d297979 Mon Sep 17 00:00:00 2001 From: bash Date: Sun, 31 May 2026 13:49:59 +0200 Subject: [PATCH] fix(Core/Travel): GetFullPath now reuses failed probe waypoints as startPath via cropPathTo (matches reference) --- src/Mgr/Travel/TravelNode.cpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Mgr/Travel/TravelNode.cpp b/src/Mgr/Travel/TravelNode.cpp index 225dd4658..d0cf80c61 100644 --- a/src/Mgr/Travel/TravelNode.cpp +++ b/src/Mgr/Travel/TravelNode.cpp @@ -1705,14 +1705,14 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uin // Probe-first short-circuit (matches reference exactly): if a 40-step // mmap probe from bot to destination reaches within spellDistance of // dest, use the probe directly and skip graph routing. Otherwise - // fall through to the graph A* below — the failed probe waypoints - // would ideally feed into getRoute as startPath (reference does - // this; we don't yet — TODO). + // the probe waypoints are kept as `beginPath` and fed into per- + // candidate startPath cropping below. + std::vector beginPath; if (botPos.GetMapId() == destination.GetMapId()) { - std::vector probe = destination.getPathFromPath({botPos}, bot, 40); - if (destination.isPathTo(probe, sPlayerbotAIConfig.spellDistance)) - return TravelPath(probe); + beginPath = destination.getPathFromPath({botPos}, bot, 40); + if (destination.isPathTo(beginPath, sPlayerbotAIConfig.spellDistance)) + return TravelPath(beginPath); } std::shared_lock guard(m_nMapMtx); @@ -1815,10 +1815,17 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uin } // 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; - std::vector pathToStart; - bool startPathOk = false; - if (bot && botPos.GetMapId() == startNodePos.GetMapId()) + std::vector pathToStart = beginPath; + bool startPathOk = !pathToStart.empty() && + startNodePos.cropPathTo(pathToStart, maxStartDistance); + + if (!startPathOk && bot && botPos.GetMapId() == startNodePos.GetMapId()) { pathToStart = botPos.getPathTo(startNodePos, bot); startPathOk = startNodePos.isPathTo(pathToStart, maxStartDistance); @@ -1831,7 +1838,10 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uin 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); route.cleanTempNodes(); return path;