HPF handles searches from unreachable source cells into cut off areas.

If a path search is performed by the HierarchicalPathFinder when the source cell is unreachable location, a path is still allowed and starts from one of the cells adjacent to the location. If moving into one of these cells results in the actor moving into an isolated area that cannot reach the target this would previously crash as no abstract path could be found. Now we handle such locations by giving them a unreachable cost so the path search will not attempt to explore them.

Imagine a map split into two by a one tile wide line of impassable cliffs. If an actor is on top of these cliffs it is allowed to path because it can "jump off" the cliff and move into the cell immediately either side of it. However it is important which side it chooses to jump into, as one it has moved off the cliff it loses access to the other side. The previous error came about because the path might try and search on the side that couldn't reach the target location. Now we avoid that being considered.
This commit is contained in:
RoosterDragon
2022-12-03 12:37:09 +00:00
committed by Paul Chote
parent 11e5d19f32
commit d8ebb96077
2 changed files with 47 additions and 14 deletions

View File

@@ -182,7 +182,11 @@ namespace OpenRA.Mods.Common.Pathfinder
return;
}
var estimatedCost = heuristic(location) * heuristicWeightPercentage / 100;
var heuristicCost = heuristic(location);
if (heuristicCost == PathGraph.PathCostForInvalidPath)
return;
var estimatedCost = heuristicCost * heuristicWeightPercentage / 100;
Graph[location] = new CellInfo(CellStatus.Open, initialCost, initialCost + estimatedCost, location);
var connection = new GraphConnection(location, estimatedCost);
openQueue.Add(connection);
@@ -237,14 +241,22 @@ namespace OpenRA.Mods.Common.Pathfinder
(neighborInfo.Status == CellStatus.Open && costSoFarToNeighbor >= neighborInfo.CostSoFar))
continue;
// Now we may seriously consider this direction using heuristics. If the cell has
// already been processed, we can reuse the result (just the difference between the
// estimated total and the cost so far)
// Now we may seriously consider this direction using heuristics.
int estimatedRemainingCostToTarget;
if (neighborInfo.Status == CellStatus.Open)
{
// If the cell has already been processed, we can reuse the result
// (just the difference between the estimated total and the cost so far)
estimatedRemainingCostToTarget = neighborInfo.EstimatedTotalCost - neighborInfo.CostSoFar;
}
else
estimatedRemainingCostToTarget = heuristic(neighbor) * heuristicWeightPercentage / 100;
{
// If the heuristic reports the cell is unreachable, we won't consider it.
var heuristicCost = heuristic(neighbor);
if (heuristicCost == PathGraph.PathCostForInvalidPath)
continue;
estimatedRemainingCostToTarget = heuristicCost * heuristicWeightPercentage / 100;
}
recorder?.Add(currentMinNode, neighbor, costSoFarToNeighbor, estimatedRemainingCostToTarget);