diff --git a/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs b/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs index d0333449d7..ba066942cc 100644 --- a/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs +++ b/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs @@ -629,9 +629,19 @@ namespace OpenRA.Mods.Common.Pathfinder var sourcesWithPathableNodes = new List(sourcesWithReachableNodes.Count); foreach (var source in sourcesWithReachableNodes) { - reverseAbstractSearch.TargetPredicate = cell => cell == source; - if (reverseAbstractSearch.ExpandToTarget()) - sourcesWithPathableNodes.Add(source); + // Check if we have already found a route to this node before we attempt to expand the search. + var sourceStatus = reverseAbstractSearch.Graph[source]; + if (sourceStatus.Status == CellStatus.Closed) + { + if (sourceStatus.CostSoFar != PathGraph.PathCostForInvalidPath) + sourcesWithPathableNodes.Add(source); + } + else + { + reverseAbstractSearch.TargetPredicate = cell => cell == source; + if (reverseAbstractSearch.ExpandToTarget()) + sourcesWithPathableNodes.Add(source); + } } if (sourcesWithPathableNodes.Count == 0) @@ -900,8 +910,8 @@ namespace OpenRA.Mods.Common.Pathfinder var abstractCell = gridInfo.AbstractCellForLocalCell(cell).Value; var info = graph[abstractCell]; - // Expand the abstract search if we have not visited the abstract cell. - if (info.Status == CellStatus.Unvisited) + // Expand the abstract search only if we have yet to get a route to the abstract cell. + if (info.Status != CellStatus.Closed) { abstractSearch.TargetPredicate = c => c == abstractCell; if (!abstractSearch.ExpandToTarget()) diff --git a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs index e8459b928b..e127192856 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs @@ -241,6 +241,11 @@ namespace OpenRA.Mods.Common.Pathfinder /// /// Expands the path search until a path is found, and returns whether a path is found successfully. /// + /// + /// If the path search has previously been expanded it will only return true if a path can be found during + /// *this* expansion of the search. If the search was expanded previously and the target is already + /// then this method will return false. + /// public bool ExpandToTarget() { while (CanExpand())