Fix MoveWithinRange not moving far enough for min range checks.

MoveWithinRange was only moving the unit far enough away so the center of the target was above the minimum distance. However, the min range checks in the attack code require all positions on the target to be above the minimum distance. For large targets (e.g. buildings) this means some of the target was still too close, and the unit would get stuck in a loop.

Now MoveWithinRange uses the same range checks in order to ensure units are moved the correct distances.
This commit is contained in:
RoosterDragon
2015-10-29 22:59:20 +00:00
parent 0997f5b52f
commit 26d7d59c1a

View File

@@ -32,14 +32,12 @@ namespace OpenRA.Mods.Common.Activities
{ {
// We are now in range. Don't move any further! // We are now in range. Don't move any further!
// HACK: This works around the pathfinder not returning the shortest path // HACK: This works around the pathfinder not returning the shortest path
var cp = self.CenterPosition; return AtCorrectRange(self.CenterPosition);
return Target.IsInRange(cp, maxRange) && !Target.IsInRange(cp, minRange);
} }
protected override bool ShouldRepath(Actor self, CPos oldTargetPosition) protected override bool ShouldRepath(Actor self, CPos oldTargetPosition)
{ {
var cp = self.CenterPosition; return targetPosition != oldTargetPosition && !AtCorrectRange(self.CenterPosition);
return targetPosition != oldTargetPosition && (!Target.IsInRange(cp, maxRange) || Target.IsInRange(cp, minRange));
} }
protected override IEnumerable<CPos> CandidateMovementCells(Actor self) protected override IEnumerable<CPos> CandidateMovementCells(Actor self)
@@ -48,15 +46,13 @@ namespace OpenRA.Mods.Common.Activities
var maxCells = (maxRange.Length + 1023) / 1024; var maxCells = (maxRange.Length + 1023) / 1024;
var minCells = minRange.Length / 1024; var minCells = minRange.Length / 1024;
var outerSq = maxRange.LengthSquared; return map.FindTilesInAnnulus(targetPosition, minCells, maxCells)
var innerSq = minRange.LengthSquared; .Where(c => AtCorrectRange(map.CenterOfCell(c)));
var center = Target.CenterPosition; }
return map.FindTilesInAnnulus(targetPosition, minCells + 1, maxCells).Where(c => bool AtCorrectRange(WPos origin)
{ {
var dxSq = (map.CenterOfCell(c) - center).HorizontalLengthSquared; return Target.IsInRange(origin, maxRange) && !Target.IsInRange(origin, minRange);
return dxSq >= innerSq && dxSq <= outerSq;
});
} }
} }
} }