From b703a836791e6a3620b9f6c7cbeb70b842f4fa22 Mon Sep 17 00:00:00 2001 From: bash Date: Sat, 16 May 2026 16:48:10 +0200 Subject: [PATCH] fix(Core/Travel): Trust travelnode waypoints when AC mmap rejects segments --- src/Ai/Base/Actions/MovementActions.cpp | 38 ++++++++++--------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/Ai/Base/Actions/MovementActions.cpp b/src/Ai/Base/Actions/MovementActions.cpp index 456ab96f3..f4f33e268 100644 --- a/src/Ai/Base/Actions/MovementActions.cpp +++ b/src/Ai/Base/Actions/MovementActions.cpp @@ -3221,34 +3221,26 @@ bool MovementAction::RefineWalkPoints(std::vector& walkPoints) WorldPosition aPos(mapId, a.x, a.y, a.z); WorldPosition bPos(mapId, b.x, b.y, b.z); - // Per-segment mmap query against the live navmesh. The - // travel-node graph stores offline-baked waypoints; if the - // straight line A->B crosses geometry the live navmesh has - // (mountain, ledge, model edit since offline gen), this - // returns either an mmap-routed path around it (NORMAL/ - // INCOMPLETE) or empty (NOT_USING_PATH was rejected as - // "would walk through walls"). + // Per-segment mmap query: routes around geometry the offline + // graph didn't account for, or returns empty if unreachable. std::vector segPath = bPos.getPathStepFrom(aPos, bot); - if (segPath.empty()) + // Trust the raw waypoint pair when mmap can't validate it — + // navmesh gaps/tile-edge artifacts on short segments shouldn't + // kill an active plan. Travelnode waypoints are authoritative. + bool const trustRaw = segPath.empty() || + TravelPath::IsPathCheating(segPath, aPos.distance(bPos)); + + if (trustRaw) { - // Live mmap refuses A->B. Caller should abort the plan - // and let MoveFarTo's own probe re-derive a route. - return false; + if (i == 0) + refined.emplace_back(a); + refined.emplace_back(b); + continue; } - // Reject "pathfinder cheating" — same checks the offline gen - // applies to BuildPath. Catches cached segments where the - // live navmesh still produces a near-vertical hop or a - // 2-point straight line through geometry. - if (TravelPath::IsPathCheating(segPath, aPos.distance(bPos))) - { - return false; - } - - // First segment: include its start point so the spline - // begins from the original A. Later segments: skip the first - // point — it duplicates the previous segment's tail. + // Include the first segment's start; skip subsequent starts + // to avoid duplicating the prior segment's tail. size_t startK = (i == 0) ? 0 : 1; for (size_t k = startK; k < segPath.size(); ++k) refined.emplace_back(segPath[k].GetPositionX(),