Fix moves being reported as blocked when already at the destination.

When a move is made where the source and target locations are the same and no actual moving is required, a path of length 0 is returned. When a move cannot be made as there is no valid route, a path of length 0 is also returned. This means Move is unable to tell the difference between no movement required, and no path is possible. Currently it will hit the `hadNoPath` case and report CompleteDestinationBlocked.

To fix the scenario where the source and target location match, track a alreadyAtDestination field. When this scenario triggers, report CompleteDestinationReached instead.

This fixes activities that were using this result to inform their next actions. e.g. MoveOntoAndTurn would previously cancel the Turn portion of the activity, believing that the destination could not be reached. Now, it knows the destination was reached (since we are already there!) and will perform the turn.
This commit is contained in:
RoosterDragon
2024-08-15 21:42:35 +01:00
committed by Gustas
parent 8101c70c91
commit 0c4dff77c9
5 changed files with 52 additions and 25 deletions

View File

@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Activities
protected int searchCellsTick = -1;
protected virtual List<CPos> CalculatePathToTarget(Actor self, BlockedByActor check)
protected virtual (bool AlreadyAtDestination, List<CPos> Path) CalculatePathToTarget(Actor self, BlockedByActor check)
{
// PERF: Assume that candidate cells don't change within a tick to avoid repeated queries
// when Move enumerates different BlockedByActor values.
@@ -125,14 +125,21 @@ namespace OpenRA.Mods.Common.Activities
SearchCells.Clear();
searchCellsTick = self.World.WorldTick;
foreach (var cell in Util.AdjacentCells(self.World, Target))
{
if (Mobile.CanStayInCell(cell) && Mobile.CanEnterCell(cell))
{
if (cell == self.Location)
return (true, PathFinder.NoPath);
SearchCells.Add(cell);
}
}
}
if (SearchCells.Count == 0)
return PathFinder.NoPath;
return (false, PathFinder.NoPath);
return Mobile.PathFinder.FindPathToTargetCells(self, self.Location, SearchCells, check);
return (false, Mobile.PathFinder.FindPathToTargetCells(self, self.Location, SearchCells, check));
}
public override IEnumerable<Target> GetTargets(Actor self)