diff --git a/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp b/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp index 51896c484..c3eb93a2f 100644 --- a/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp +++ b/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp @@ -131,6 +131,24 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest) if (path.empty()) return false; + // Progress guard: refuse to dispatch a path whose endpoint isn't + // meaningfully closer to dest than the bot already is. Prevents + // oscillation around terrain the mmap probe can route along but the + // bot can't actually traverse (cave entries with missing nav, narrow + // ledges, geometry that loops back). Reference doesn't have this + // guard but their RPG layer detects stuck via different signals; + // ours surfaces the issue here so the strategy can re-pick a POI. + { + float const distFromBot = botPos.distance(dest); + float const distFromPathEnd = path.getBack().distance(dest); + if (distFromPathEnd + 5.0f >= distFromBot) + { + EmitDebugMove("MoveFar", "no-progress", + dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ()); + return false; + } + } + // Walk dispatch. std::vector const& pts = path.getPointPath(); Movement::PointsArray points;