diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 4d1ff9db93..b85df63d52 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -158,8 +158,19 @@ namespace OpenRa.Game { return FindUnits(a - new float2(r, r), a + new float2(r, r)) .Where(x => (x.CenterLocation - a).LengthSquared < r * r); - } - + } + + public static IEnumerable FindTilesInCircle(int2 a, int r) + { + var min = a - new int2(r, r); + var max = a + new int2(r, r); + + for (var j = min.Y; j <= max.Y; j++) + for (var i = min.X; i <= max.X; i++) + if (r * r >= (new int2(i, j) - a).LengthSquared) + yield return new int2(i, j); + } + public static IEnumerable SelectUnitsInBox(float2 a, float2 b) { return FindUnits(a, b).Where(x => x.Owner == LocalPlayer && x.traits.Contains()); diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index 10514752ff..58a3aa4485 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using IjwFramework.Collections; +using System.Linq; using OpenRa.FileFormats; using OpenRa.Game.Graphics; @@ -30,21 +31,32 @@ namespace OpenRa.Game return FindUnitPath(src, DefaultEstimator(dest), umt); } + public List FindUnitPathToRange(int2 src, int2 dest, UnitMovementType umt, int range) + { + var tilesInRange = Game.FindTilesInCircle(dest, range) + .Where(t => Game.IsCellBuildable(t, umt)) + .Select(t => t + map.Offset); + + var path = FindUnitPath(tilesInRange, DefaultEstimator(dest), umt); + path.Reverse(); + return path; + } + List FindUnitPath( int2 unitLocation, Func estimator, UnitMovementType umt ) { var startLocation = unitLocation + map.Offset; - - var cellInfo = new CellInfo[ 128, 128 ]; - - for( int x = 0 ; x < 128 ; x++ ) - for( int y = 0 ; y < 128 ; y++ ) - cellInfo[ x, y ] = new CellInfo( double.PositiveInfinity, new int2( x, y ), false ); - - return FindUnitPath( new[] {startLocation}, estimator, umt, map.Offset, cellInfo ); + return FindUnitPath( new[] {startLocation}, estimator, umt ); } - List FindUnitPath(IEnumerable startLocations, Func estimator, UnitMovementType umt, int2 offset, CellInfo[,] cellInfo) + List FindUnitPath(IEnumerable startLocations, Func estimator, UnitMovementType umt) { + var cellInfo = new CellInfo[128, 128]; + var offset = map.Offset; + + for (int x = 0; x < 128; x++) + for (int y = 0; y < 128; y++) + cellInfo[x, y] = new CellInfo(double.PositiveInfinity, new int2(x, y), false); + var queue = new PriorityQueue(); foreach (var sl in startLocations)