Move FindTilesInCircle from WorldUtils to Map
This commit is contained in:
@@ -573,5 +573,38 @@ namespace OpenRA
|
||||
var y = dir.Y == 0 ? int.MaxValue : ((dir.Y < 0 ? tl.Y : br.Y) - pos.Y) / dir.Y;
|
||||
return new WRange(Math.Min(x, y) * dir.Length);
|
||||
}
|
||||
|
||||
public const int MaxTilesInCircleRange = 50;
|
||||
static List<CVec>[] TilesByDistance = InitTilesByDistance(MaxTilesInCircleRange);
|
||||
|
||||
static List<CVec>[] InitTilesByDistance(int max)
|
||||
{
|
||||
var ts = new List<CVec>[max + 1];
|
||||
for (var i = 0; i < max + 1; i++)
|
||||
ts [i] = new List<CVec>();
|
||||
|
||||
for (var j = -max; j <= max; j++)
|
||||
for (var i = -max; i <= max; i++)
|
||||
if (max * max >= i * i + j * j)
|
||||
ts [(int)Math.Ceiling(Math.Sqrt(i * i + j * j))].Add(new CVec(i, j));
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
public IEnumerable<CPos> FindTilesInCircle(CPos center, int range)
|
||||
{
|
||||
if (range >= TilesByDistance.Length)
|
||||
throw new InvalidOperationException("FindTilesInCircle supports queries for only <= {0}".F(MaxTilesInCircleRange));
|
||||
|
||||
for(var i = 0; i <= range; i++)
|
||||
{
|
||||
foreach(var offset in TilesByDistance[i])
|
||||
{
|
||||
var t = offset + center;
|
||||
if (Bounds.Contains(t.X, t.Y))
|
||||
yield return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,39 +55,6 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<CPos> FindTilesInCircle(this World world, CPos a, int r)
|
||||
{
|
||||
if (r >= TilesByDistance.Length)
|
||||
throw new InvalidOperationException("FindTilesInCircle supports queries for only <= {0}".F(MaxRange));
|
||||
|
||||
for(var i = 0; i <= r; i++)
|
||||
{
|
||||
foreach(var offset in TilesByDistance[i])
|
||||
{
|
||||
var t = offset + a;
|
||||
if (world.Map.Bounds.Contains(t.X, t.Y))
|
||||
yield return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static List<CVec>[] InitTilesByDistance(int max)
|
||||
{
|
||||
var ts = new List<CVec>[max+1];
|
||||
for (var i = 0; i < max+1; i++)
|
||||
ts[i] = new List<CVec>();
|
||||
|
||||
for (var j = -max; j <= max; j++)
|
||||
for (var i = -max; i <= max; i++)
|
||||
if (max * max >= i * i + j * j)
|
||||
ts[(int)Math.Ceiling(Math.Sqrt(i*i + j*j))].Add(new CVec(i,j));
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
public const int MaxRange = 50;
|
||||
static List<CVec>[] TilesByDistance = InitTilesByDistance(MaxRange);
|
||||
|
||||
public static CPos ChooseRandomEdgeCell(this World w)
|
||||
{
|
||||
var isX = w.SharedRandom.Next(2) == 0;
|
||||
|
||||
@@ -345,7 +345,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
{
|
||||
for (var k = MaxBaseDistance; k >= 0; k--)
|
||||
{
|
||||
var tlist = world.FindTilesInCircle(center, k)
|
||||
var tlist = Map.FindTilesInCircle(center, k)
|
||||
.OrderBy(a => (a.CenterPosition - pos).LengthSquared);
|
||||
|
||||
foreach (var t in tlist)
|
||||
@@ -365,7 +365,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
return enemyBase != null ? findPos(enemyBase.CenterPosition, defenseCenter) : null;
|
||||
|
||||
case BuildingType.Refinery:
|
||||
var tilesPos = world.FindTilesInCircle(baseCenter, MaxBaseDistance)
|
||||
var tilesPos = Map.FindTilesInCircle(baseCenter, MaxBaseDistance)
|
||||
.Where(a => resourceTypeIndices.Contains(Map.GetTerrainIndex(new CPos(a.X, a.Y))));
|
||||
if (tilesPos.Any())
|
||||
{
|
||||
@@ -377,7 +377,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
case BuildingType.Building:
|
||||
for (var k = 0; k < maxBaseDistance; k++)
|
||||
{
|
||||
foreach (var t in world.FindTilesInCircle(baseCenter, k))
|
||||
foreach (var t in Map.FindTilesInCircle(baseCenter, k))
|
||||
{
|
||||
if (world.CanPlaceBuilding(actorType, bi, t, null))
|
||||
{
|
||||
@@ -696,7 +696,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
// Won't work for shipyards...
|
||||
CPos ChooseRallyLocationNear(CPos startPos)
|
||||
{
|
||||
var possibleRallyPoints = world.FindTilesInCircle(startPos, Info.RallyPointScanRadius)
|
||||
var possibleRallyPoints = Map.FindTilesInCircle(startPos, Info.RallyPointScanRadius)
|
||||
.Where(IsRallyPointValid);
|
||||
|
||||
if (!possibleRallyPoints.Any())
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
bool screenFlash;
|
||||
string sound;
|
||||
|
||||
const int maxCellSearchRange = WorldUtils.MaxRange;
|
||||
const int maxCellSearchRange = Map.MaxTilesInCircleRange;
|
||||
|
||||
public Teleport(Actor chronosphere, CPos destination, int? maximumDistance, bool killCargo, bool screenFlash, string sound)
|
||||
{
|
||||
@@ -90,7 +90,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
CPos? ChooseBestDestinationCell(Actor self, CPos destination)
|
||||
{
|
||||
var restrictTo = maximumDistance == null ? null : self.World.FindTilesInCircle(self.Location, maximumDistance.Value);
|
||||
var restrictTo = maximumDistance == null ? null : self.World.Map.FindTilesInCircle(self.Location, maximumDistance.Value);
|
||||
|
||||
if (maximumDistance != null)
|
||||
destination = restrictTo.MinBy(x => (x - destination).LengthSquared);
|
||||
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
var searched = new List<CPos>();
|
||||
for (int r = 1; r <= maxCellSearchRange || (maximumDistance != null && r <= maximumDistance); r++)
|
||||
{
|
||||
foreach (var tile in self.World.FindTilesInCircle(destination, r).Except(searched))
|
||||
foreach (var tile in self.World.Map.FindTilesInCircle(destination, r).Except(searched))
|
||||
{
|
||||
if (self.Owner.Shroud.IsExplored(tile)
|
||||
&& (restrictTo == null || (restrictTo != null && restrictTo.Contains(tile)))
|
||||
|
||||
@@ -53,12 +53,12 @@ namespace OpenRA.Mods.RA
|
||||
if (warhead.Size[0] > 0)
|
||||
{
|
||||
var resLayer = world.WorldActor.Trait<ResourceLayer>();
|
||||
var allCells = world.FindTilesInCircle(targetTile, warhead.Size[0]).ToList();
|
||||
var allCells = world.Map.FindTilesInCircle(targetTile, warhead.Size[0]).ToList();
|
||||
|
||||
// `smudgeCells` might want to just be an outer shell of the cells:
|
||||
IEnumerable<CPos> smudgeCells = allCells;
|
||||
if (warhead.Size.Length == 2)
|
||||
smudgeCells = smudgeCells.Except(world.FindTilesInCircle(targetTile, warhead.Size[1]));
|
||||
smudgeCells = smudgeCells.Except(world.Map.FindTilesInCircle(targetTile, warhead.Size[1]));
|
||||
|
||||
// Draw the smudges:
|
||||
foreach (var sc in smudgeCells)
|
||||
@@ -110,17 +110,21 @@ namespace OpenRA.Mods.RA
|
||||
var damage = (int)GetDamageToInflict(pos, victim, warhead, weapon, firepowerModifier, true);
|
||||
victim.InflictDamage(firedBy, damage, warhead);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DamageModel.PerCell:
|
||||
{
|
||||
foreach (var t in world.FindTilesInCircle(targetTile, warhead.Size[0]))
|
||||
foreach (var t in world.Map.FindTilesInCircle(targetTile, warhead.Size[0]))
|
||||
{
|
||||
foreach (var unit in world.ActorMap.GetUnitsAt(t))
|
||||
{
|
||||
var damage = (int)GetDamageToInflict(pos, unit, warhead, weapon, firepowerModifier, false);
|
||||
unit.InflictDamage(firedBy, damage, warhead);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DamageModel.HealthPercentage:
|
||||
{
|
||||
@@ -135,9 +139,11 @@ namespace OpenRA.Mods.RA
|
||||
var healthInfo = victim.Info.Traits.Get<HealthInfo>();
|
||||
damage = (float)(damage / 100 * healthInfo.HP);
|
||||
}
|
||||
|
||||
victim.InflictDamage(firedBy, (int)damage, warhead);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -324,13 +324,15 @@ namespace OpenRA.Mods.RA.Move
|
||||
var searched = new List<CPos>();
|
||||
// Limit search to a radius of 10 tiles
|
||||
for (int r = minRange; r < maxRange; r++)
|
||||
foreach (var tile in self.World.FindTilesInCircle(target, r).Except(searched))
|
||||
{
|
||||
foreach (var tile in self.World.Map.FindTilesInCircle(target, r).Except(searched))
|
||||
{
|
||||
if (CanEnterCell(tile))
|
||||
return tile;
|
||||
|
||||
searched.Add(tile);
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find a cell
|
||||
return target;
|
||||
@@ -343,13 +345,15 @@ namespace OpenRA.Mods.RA.Move
|
||||
|
||||
var searched = new List<CPos>();
|
||||
for (int r = minRange; r < maxRange; r++)
|
||||
foreach (var tile in self.World.FindTilesInCircle(target, r).Except(searched))
|
||||
{
|
||||
foreach (var tile in self.World.Map.FindTilesInCircle(target, r).Except(searched))
|
||||
{
|
||||
if (check(tile))
|
||||
return tile;
|
||||
|
||||
searched.Add(tile);
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find a cell
|
||||
return target;
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace OpenRA.Mods.RA.Move
|
||||
|
||||
// Select only the tiles that are within range from the requested SubCell
|
||||
// This assumes that the SubCell does not change during the path traversal
|
||||
var tilesInRange = world.FindTilesInCircle(targetCell, range.Range / 1024 + 1)
|
||||
var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Range / 1024 + 1)
|
||||
.Where(t => (t.CenterPosition - target).LengthSquared <= rangeSquared
|
||||
&& mi.CanEnterCell(self.World, self, t, null, true, true));
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA
|
||||
var total = (double)world.Map.Bounds.Width * world.Map.Bounds.Height;
|
||||
MapControl = world.Actors
|
||||
.Where(a => !a.IsDead() && a.IsInWorld && a.Owner == player && a.HasTrait<RevealsShroud>())
|
||||
.SelectMany(a => world.FindTilesInCircle(a.Location, a.Trait<RevealsShroud>().Range.Clamp(WRange.Zero, WRange.FromCells(50)).Range / 1024))
|
||||
.SelectMany(a => world.Map.FindTilesInCircle(a.Location, a.Trait<RevealsShroud>().Range.Clamp(WRange.Zero, WRange.FromCells(50)).Range / 1024))
|
||||
.Distinct()
|
||||
.Count() / total;
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ namespace OpenRA.Mods.RA
|
||||
return;
|
||||
|
||||
// Spawn support units in an annulus around the base actor
|
||||
var supportSpawnCells = w.FindTilesInCircle(sp, unitGroup.OuterSupportRadius)
|
||||
.Except(w.FindTilesInCircle(sp, unitGroup.InnerSupportRadius));
|
||||
var supportSpawnCells = w.Map.FindTilesInCircle(sp, unitGroup.OuterSupportRadius)
|
||||
.Except(w.Map.FindTilesInCircle(sp, unitGroup.InnerSupportRadius));
|
||||
|
||||
foreach (var s in unitGroup.SupportActors)
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA
|
||||
public IEnumerable<Actor> UnitsInRange(CPos xy)
|
||||
{
|
||||
var range = ((ChronoshiftPowerInfo)Info).Range;
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var tiles = self.World.Map.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(self.World.ActorMap.GetUnitsAt(t));
|
||||
@@ -69,8 +69,8 @@ namespace OpenRA.Mods.RA
|
||||
return false;
|
||||
|
||||
var range = ((ChronoshiftPowerInfo)Info).Range;
|
||||
var sourceTiles = self.World.FindTilesInCircle(xy, range);
|
||||
var destTiles = self.World.FindTilesInCircle(sourceLocation, range);
|
||||
var sourceTiles = self.World.Map.FindTilesInCircle(xy, range);
|
||||
var destTiles = self.World.Map.FindTilesInCircle(sourceLocation, range);
|
||||
|
||||
using (var se = sourceTiles.GetEnumerator())
|
||||
using (var de = destTiles.GetEnumerator())
|
||||
@@ -134,7 +134,7 @@ namespace OpenRA.Mods.RA
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
|
||||
var tiles = world.FindTilesInCircle(xy, range);
|
||||
var tiles = world.Map.FindTilesInCircle(xy, range);
|
||||
var pal = wr.Palette("terrain");
|
||||
foreach (var t in tiles)
|
||||
yield return new SpriteRenderable(tile, t.CenterPosition, WVec.Zero, -511, pal, 1f, true);
|
||||
@@ -216,11 +216,11 @@ namespace OpenRA.Mods.RA
|
||||
var pal = wr.Palette("terrain");
|
||||
|
||||
// Source tiles
|
||||
foreach (var t in world.FindTilesInCircle(sourceLocation, range))
|
||||
foreach (var t in world.Map.FindTilesInCircle(sourceLocation, range))
|
||||
yield return new SpriteRenderable(sourceTile, t.CenterPosition, WVec.Zero, -511, pal, 1f, true);
|
||||
|
||||
// Destination tiles
|
||||
foreach (var t in world.FindTilesInCircle(xy, range))
|
||||
foreach (var t in world.Map.FindTilesInCircle(xy, range))
|
||||
yield return new SpriteRenderable(sourceTile, t.CenterPosition, WVec.Zero, -511, pal, 1f, true);
|
||||
|
||||
// Unit previews
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.RA
|
||||
public IEnumerable<Actor> UnitsInRange(CPos xy)
|
||||
{
|
||||
int range = ((IronCurtainPowerInfo)Info).Range;
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var tiles = self.World.Map.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(self.World.ActorMap.GetUnitsAt(t));
|
||||
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
|
||||
var pal = wr.Palette("terrain");
|
||||
foreach (var t in world.FindTilesInCircle(xy, range))
|
||||
foreach (var t in world.Map.FindTilesInCircle(xy, range))
|
||||
yield return new SpriteRenderable(tile, t.CenterPosition, WVec.Zero, -511, pal, 1f, true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user