Index: source/simulation2/components/CCmpUnitMotion.cpp =================================================================== --- source/simulation2/components/CCmpUnitMotion.cpp +++ source/simulation2/components/CCmpUnitMotion.cpp @@ -498,6 +498,8 @@ } } + bool RejectSuboptimalPath(const WaypointPath& path, const CFixedVector2D& pos); + /** * Handle the result of an asynchronous path query. */ @@ -619,6 +621,24 @@ REGISTER_COMPONENT_TYPE(UnitMotion) +bool CCmpUnitMotion::RejectSuboptimalPath(const WaypointPath& path, const CFixedVector2D& pos) +{ + if (path.m_Waypoints.empty()) + return false; + + PathGoal goal; + if (!ComputeGoal(goal, m_MoveRequest)) + return false; + + // Reject the new path if it does not lead us closer to the target's position. + if (goal.DistanceToPoint(pos) <= goal.DistanceToPoint(CFixedVector2D(path.m_Waypoints.front().x, path.m_Waypoints.front().z))) + { + IncrementFailedPathComputationAndMaybeNotify(); + return true; + } + return false; +} + void CCmpUnitMotion::PathResult(u32 ticket, const WaypointPath& path) { // Ignore obsolete path requests @@ -641,6 +661,9 @@ if (ticketType == Ticket::LONG_PATH) { + if (RejectSuboptimalPath(path, pos)) + return; + m_LongPath = path; m_PretendLongPathIsCorrect = false; @@ -670,6 +693,9 @@ return; } + if (m_LongPath.m_Waypoints.empty() && RejectSuboptimalPath(path, pos)) + return; + m_ShortPath = path; if (!m_ShortPath.m_Waypoints.empty())