From 060d5326ed80593909ace69b0e503f387c700435 Mon Sep 17 00:00:00 2001 From: Pavlos Touboulidis Date: Fri, 13 Jun 2014 14:24:53 +0300 Subject: [PATCH] Move FindTilesInCircle from WorldUtils to Map --- OpenRA.Game/Map/Map.cs | 33 +++++++++++++++++++ OpenRA.Game/WorldUtils.cs | 33 ------------------- OpenRA.Mods.RA/AI/HackyAI.cs | 8 ++--- OpenRA.Mods.RA/Activities/Teleport.cs | 6 ++-- OpenRA.Mods.RA/Combat.cs | 18 ++++++---- OpenRA.Mods.RA/Move/Mobile.cs | 8 +++-- OpenRA.Mods.RA/Move/PathFinder.cs | 2 +- OpenRA.Mods.RA/Player/PlayerStatistics.cs | 2 +- OpenRA.Mods.RA/SpawnMPUnits.cs | 4 +-- .../SupportPowers/ChronoshiftPower.cs | 12 +++---- .../SupportPowers/IronCurtainPower.cs | 4 +-- 11 files changed, 70 insertions(+), 60 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 04768aa2ac..e083b29c32 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -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[] TilesByDistance = InitTilesByDistance(MaxTilesInCircleRange); + + static List[] InitTilesByDistance(int max) + { + var ts = new List[max + 1]; + for (var i = 0; i < max + 1; i++) + ts [i] = new List(); + + 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 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; + } + } + } } } diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index 305087fd12..6b8aac0d0b 100644 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -55,39 +55,6 @@ namespace OpenRA } } - public static IEnumerable 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[] InitTilesByDistance(int max) - { - var ts = new List[max+1]; - for (var i = 0; i < max+1; i++) - ts[i] = new List(); - - 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[] TilesByDistance = InitTilesByDistance(MaxRange); - public static CPos ChooseRandomEdgeCell(this World w) { var isX = w.SharedRandom.Next(2) == 0; diff --git a/OpenRA.Mods.RA/AI/HackyAI.cs b/OpenRA.Mods.RA/AI/HackyAI.cs index e5367bea06..fb6ad7a4d4 100644 --- a/OpenRA.Mods.RA/AI/HackyAI.cs +++ b/OpenRA.Mods.RA/AI/HackyAI.cs @@ -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()) diff --git a/OpenRA.Mods.RA/Activities/Teleport.cs b/OpenRA.Mods.RA/Activities/Teleport.cs index b9b25f80ae..df12dc74fc 100755 --- a/OpenRA.Mods.RA/Activities/Teleport.cs +++ b/OpenRA.Mods.RA/Activities/Teleport.cs @@ -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(); 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))) diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index 32463be224..b4d1da5b5c 100755 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -53,12 +53,12 @@ namespace OpenRA.Mods.RA if (warhead.Size[0] > 0) { var resLayer = world.WorldActor.Trait(); - 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 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(); damage = (float)(damage / 100 * healthInfo.HP); } + victim.InflictDamage(firedBy, (int)damage, warhead); } - } break; + } + break; } } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 4b78a192f9..931855b75a 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -324,13 +324,15 @@ namespace OpenRA.Mods.RA.Move var searched = new List(); // 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(); 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; diff --git a/OpenRA.Mods.RA/Move/PathFinder.cs b/OpenRA.Mods.RA/Move/PathFinder.cs index 52a961831d..52e3ebfa80 100755 --- a/OpenRA.Mods.RA/Move/PathFinder.cs +++ b/OpenRA.Mods.RA/Move/PathFinder.cs @@ -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)); diff --git a/OpenRA.Mods.RA/Player/PlayerStatistics.cs b/OpenRA.Mods.RA/Player/PlayerStatistics.cs index 333e63e361..3672ce4d39 100644 --- a/OpenRA.Mods.RA/Player/PlayerStatistics.cs +++ b/OpenRA.Mods.RA/Player/PlayerStatistics.cs @@ -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()) - .SelectMany(a => world.FindTilesInCircle(a.Location, a.Trait().Range.Clamp(WRange.Zero, WRange.FromCells(50)).Range / 1024)) + .SelectMany(a => world.Map.FindTilesInCircle(a.Location, a.Trait().Range.Clamp(WRange.Zero, WRange.FromCells(50)).Range / 1024)) .Distinct() .Count() / total; } diff --git a/OpenRA.Mods.RA/SpawnMPUnits.cs b/OpenRA.Mods.RA/SpawnMPUnits.cs index 5cbcb50a6a..5b2e150d5a 100644 --- a/OpenRA.Mods.RA/SpawnMPUnits.cs +++ b/OpenRA.Mods.RA/SpawnMPUnits.cs @@ -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) { diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs index 30d78eb16c..ab91928434 100644 --- a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA public IEnumerable 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(); 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 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 diff --git a/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs b/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs index b857d40038..e125242c7f 100644 --- a/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.RA public IEnumerable 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(); 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); }