From 26d7d59c1a93da520bda7d20edaa3c5275c14a37 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Thu, 29 Oct 2015 22:59:20 +0000 Subject: [PATCH] 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. --- .../Activities/Move/MoveWithinRange.cs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs b/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs index a9e6074b78..80bef9a5c0 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs @@ -32,14 +32,12 @@ namespace OpenRA.Mods.Common.Activities { // We are now in range. Don't move any further! // HACK: This works around the pathfinder not returning the shortest path - var cp = self.CenterPosition; - return Target.IsInRange(cp, maxRange) && !Target.IsInRange(cp, minRange); + return AtCorrectRange(self.CenterPosition); } protected override bool ShouldRepath(Actor self, CPos oldTargetPosition) { - var cp = self.CenterPosition; - return targetPosition != oldTargetPosition && (!Target.IsInRange(cp, maxRange) || Target.IsInRange(cp, minRange)); + return targetPosition != oldTargetPosition && !AtCorrectRange(self.CenterPosition); } protected override IEnumerable CandidateMovementCells(Actor self) @@ -48,15 +46,13 @@ namespace OpenRA.Mods.Common.Activities var maxCells = (maxRange.Length + 1023) / 1024; var minCells = minRange.Length / 1024; - var outerSq = maxRange.LengthSquared; - var innerSq = minRange.LengthSquared; - var center = Target.CenterPosition; + return map.FindTilesInAnnulus(targetPosition, minCells, maxCells) + .Where(c => AtCorrectRange(map.CenterOfCell(c))); + } - return map.FindTilesInAnnulus(targetPosition, minCells + 1, maxCells).Where(c => - { - var dxSq = (map.CenterOfCell(c) - center).HorizontalLengthSquared; - return dxSq >= innerSq && dxSq <= outerSq; - }); + bool AtCorrectRange(WPos origin) + { + return Target.IsInRange(origin, maxRange) && !Target.IsInRange(origin, minRange); } } }