Skip to content

Commit 7545cf6

Browse files
committed
Merge branch 'ca-engine/1.08.1-extras-from-others' into ca-engine/1.08.1
2 parents d51874a + c95178d commit 7545cf6

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,16 @@ static CPos AbstractCellForLocalCells(List<CPos> cells, byte layer)
390390
// Make sure the abstract cell is one of the available local cells.
391391
// This ensures each abstract cell we generate is unique.
392392
// We'll choose an abstract node as close to the middle of the region as possible.
393+
// If there are multiple equally close cells, choose the leftmost/topmost (arbitrary tiebreaker).
394+
// This is important so we always choose the same abstract cell, no matter the ordering of the list.
393395
var abstractCell = desired;
394396
var distance = int.MaxValue;
395397
foreach (var cell in cells)
396398
{
397399
var newDistance = (cell - desired).LengthSquared;
398-
if (distance > newDistance)
400+
if (distance > newDistance ||
401+
(distance == newDistance && abstractCell.X > cell.X) ||
402+
(distance == newDistance && abstractCell.X == cell.X && abstractCell.Y > cell.Y))
399403
{
400404
distance = newDistance;
401405
abstractCell = cell;
@@ -416,6 +420,8 @@ static CPos AbstractCellForLocalCells(List<CPos> cells, byte layer)
416420
using (var search = GetLocalPathSearch(
417421
null, new[] { src }, src, customCost, null, BlockedByActor.None, false, grid, 100, null, false, null))
418422
{
423+
// Determinism: The order of visited cells from ExpandAll can be perturbed by cell cost changes.
424+
// Processing of this list must not take any implicit dependencies on its ordering.
419425
var localCellsInRegion = search.ExpandAll();
420426
var abstractCell = AbstractCellForLocalCells(localCellsInRegion, gridLayer);
421427
accessibleCells.ExceptWith(localCellsInRegion);
@@ -1164,9 +1170,7 @@ Func<CPos, bool, int> Heuristic(PathSearch abstractSearch, int estimatedSearchSi
11641170
}
11651171

11661172
if (maybeAbstractCell == null)
1167-
throw new Exception(
1168-
"The abstract path should never be searched for an unreachable point. " +
1169-
$"Cell {cell} failed lookup for an abstract cell.");
1173+
return PathGraph.PathCostForInvalidPath;
11701174
}
11711175

11721176
var abstractCell = maybeAbstractCell.Value;
@@ -1177,9 +1181,8 @@ Func<CPos, bool, int> Heuristic(PathSearch abstractSearch, int estimatedSearchSi
11771181
{
11781182
abstractSearch.TargetPredicate = c => c == abstractCell;
11791183
if (!abstractSearch.ExpandToTarget())
1180-
throw new Exception(
1181-
"The abstract path should never be searched for an unreachable point. " +
1182-
$"Abstract cell {abstractCell} failed to route to abstract cell.");
1184+
return PathGraph.PathCostForInvalidPath;
1185+
11831186
info = graph[abstractCell];
11841187
}
11851188

0 commit comments

Comments
 (0)