diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index f62abf5771..39bde429a0 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -182,7 +182,7 @@ namespace OpenRA.GameRules if (!world.Map.IsInMap(cell)) return false; - var cellInfo = world.GetTerrainInfo(cell); + var cellInfo = world.Map.GetTerrainInfo(cell); if (!ValidTargets.Intersect(cellInfo.TargetTypes).Any() || InvalidTargets.Intersect(cellInfo.TargetTypes).Any()) return false; diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 1d99ab4512..2b0e6ec38a 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -19,6 +19,7 @@ using OpenRA.FileSystem; using OpenRA.Network; using OpenRA.Traits; using OpenRA.Graphics; +using OpenRA.Support; namespace OpenRA { @@ -537,5 +538,83 @@ namespace OpenRA } } } + + public int GetTerrainIndex(CPos cell) + { + var custom = CustomTerrain[cell.X, cell.Y]; + var tileSet = Rules.TileSets[Tileset]; + return custom != -1 ? custom : tileSet.GetTerrainIndex(MapTiles.Value[cell.X, cell.Y]); + } + + public TerrainTypeInfo GetTerrainInfo(CPos cell) + { + var tileSet = Rules.TileSets[Tileset]; + return tileSet[GetTerrainIndex(cell)]; + } + + public CPos Clamp(CPos xy) + { + var r = Bounds; + return xy.Clamp(new Rectangle(r.X, r.Y, r.Width - 1, r.Height - 1)); + } + + public CPos ChooseRandomCell(MersenneTwister rand) + { + return new CPos( + rand.Next(Bounds.Left, Bounds.Right), + rand.Next(Bounds.Top, Bounds.Bottom)); + } + + public CPos ChooseRandomEdgeCell(MersenneTwister rand) + { + var isX = rand.Next(2) == 0; + var edge = rand.Next(2) == 0; + + return new CPos( + isX ? rand.Next(Bounds.Left, Bounds.Right) : (edge ? Bounds.Left : Bounds.Right), + !isX ? rand.Next(Bounds.Top, Bounds.Bottom) : (edge ? Bounds.Top : Bounds.Bottom)); + } + + public WRange DistanceToEdge(WPos pos, WVec dir) + { + var tl = Bounds.TopLeftAsCPos().TopLeft; + var br = Bounds.BottomRightAsCPos().BottomRight; + var x = dir.X == 0 ? int.MaxValue : ((dir.X < 0 ? tl.X : br.X) - pos.X) / dir.X; + 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/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index e9f60a31bb..6cb45b801e 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -145,7 +145,7 @@ namespace OpenRA.Traits if (!world.Map.IsInMap(a.X, a.Y)) return false; - if (!rt.Info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type)) + if (!rt.Info.AllowedTerrainTypes.Contains(world.Map.GetTerrainInfo(a).Type)) return false; if (!rt.Info.AllowUnderActors && world.ActorMap.AnyUnitsAt(a)) diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index 968dd636dc..478e18fe75 100644 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -55,84 +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 int GetTerrainIndex(this World world, CPos cell) - { - var custom = world.Map.CustomTerrain[cell.X, cell.Y]; - return custom != -1 ? custom : world.TileSet.GetTerrainIndex(world.Map.MapTiles.Value[cell.X, cell.Y]); - } - - public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell) - { - return world.TileSet[world.GetTerrainIndex(cell)]; - } - - public static CPos ClampToWorld(this World world, CPos xy) - { - var r = world.Map.Bounds; - return xy.Clamp(new Rectangle(r.X,r.Y,r.Width-1, r.Height-1)); - } - - public static CPos ChooseRandomEdgeCell(this World w) - { - var isX = w.SharedRandom.Next(2) == 0; - var edge = w.SharedRandom.Next(2) == 0; - - return new CPos( - isX ? w.SharedRandom.Next(w.Map.Bounds.Left, w.Map.Bounds.Right) - : (edge ? w.Map.Bounds.Left : w.Map.Bounds.Right), - !isX ? w.SharedRandom.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom) - : (edge ? w.Map.Bounds.Top : w.Map.Bounds.Bottom)); - } - - public static CPos ChooseRandomCell(this World w, MersenneTwister r) - { - return new CPos( - r.Next(w.Map.Bounds.Left, w.Map.Bounds.Right), - r.Next(w.Map.Bounds.Top, w.Map.Bounds.Bottom)); - } - - public static WRange DistanceToMapEdge(this World w, WPos pos, WVec dir) - { - var tl = w.Map.Bounds.TopLeftAsCPos().TopLeft; - var br = w.Map.Bounds.BottomRightAsCPos().BottomRight; - var x = dir.X == 0 ? int.MaxValue : ((dir.X < 0 ? tl.X : br.X) - pos.X) / dir.X; - 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 static bool HasVoices(this Actor a) { var selectable = a.Info.Traits.GetOrDefault(); diff --git a/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs b/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs index 6cbf576513..28a6ee9754 100644 --- a/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs +++ b/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs @@ -49,7 +49,7 @@ namespace OpenRA.Mods.Cnc foreach (var kv in self.OccupiesSpace.OccupiedCells()) { totalTiles++; - if (info.SafeTerrain.Contains(self.World.GetTerrainInfo(kv.First).Type)) + if (info.SafeTerrain.Contains(self.World.Map.GetTerrainInfo(kv.First).Type)) safeTiles++; } diff --git a/OpenRA.Mods.RA/AI/HackyAI.cs b/OpenRA.Mods.RA/AI/HackyAI.cs index 9e4a1a555c..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,8 +365,8 @@ namespace OpenRA.Mods.RA.AI return enemyBase != null ? findPos(enemyBase.CenterPosition, defenseCenter) : null; case BuildingType.Refinery: - var tilesPos = world.FindTilesInCircle(baseCenter, MaxBaseDistance) - .Where(a => resourceTypeIndices.Contains(world.GetTerrainIndex(new CPos(a.X, a.Y)))); + var tilesPos = Map.FindTilesInCircle(baseCenter, MaxBaseDistance) + .Where(a => resourceTypeIndices.Contains(Map.GetTerrainIndex(new CPos(a.X, a.Y)))); if (tilesPos.Any()) { var pos = tilesPos.MinBy(a => (a.CenterPosition - baseCenter.CenterPosition).LengthSquared); @@ -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/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index b633bdb6f7..5400e021c9 100755 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -171,7 +171,7 @@ namespace OpenRA.Mods.RA.Air if (self.World.ActorMap.AnyUnitsAt(cell)) return false; - var type = self.World.GetTerrainInfo(cell).Type; + var type = self.World.Map.GetTerrainInfo(cell).Type; return info.LandableTerrainTypes.Contains(type); } diff --git a/OpenRA.Mods.RA/Air/Helicopter.cs b/OpenRA.Mods.RA/Air/Helicopter.cs index 4bf2b8740d..55e5eb04d0 100755 --- a/OpenRA.Mods.RA/Air/Helicopter.cs +++ b/OpenRA.Mods.RA/Air/Helicopter.cs @@ -50,7 +50,7 @@ namespace OpenRA.Mods.RA.Air if (order.OrderString == "Move") { - var cell = self.World.ClampToWorld(order.TargetLocation); + var cell = self.World.Map.Clamp(order.TargetLocation); var t = Target.FromCell(cell); self.SetTargetLine(t, Color.Green); diff --git a/OpenRA.Mods.RA/Air/Plane.cs b/OpenRA.Mods.RA/Air/Plane.cs index 17acafee1e..652df7166b 100755 --- a/OpenRA.Mods.RA/Air/Plane.cs +++ b/OpenRA.Mods.RA/Air/Plane.cs @@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA.Air { UnReserve(); - var cell = self.World.ClampToWorld(order.TargetLocation); + var cell = self.World.Map.Clamp(order.TargetLocation); var t = Target.FromCell(cell); self.SetTargetLine(t, Color.Green); self.CancelActivity(); diff --git a/OpenRA.Mods.RA/Buildings/Bib.cs b/OpenRA.Mods.RA/Buildings/Bib.cs index ec5aeec250..894fd715ec 100755 --- a/OpenRA.Mods.RA/Buildings/Bib.cs +++ b/OpenRA.Mods.RA/Buildings/Bib.cs @@ -44,6 +44,7 @@ namespace OpenRA.Mods.RA.Buildings var centerOffset = FootprintUtils.CenterOffset(bi); var location = self.Location; var rows = info.HasMinibib ? 1 : 2; + var map = self.World.Map; for (var i = 0; i < rows * width; i++) { @@ -52,7 +53,7 @@ namespace OpenRA.Mods.RA.Buildings var cellOffset = new CVec(i % width, i / width + bibOffset); // Some mods may define terrain-specific bibs - var terrain = self.World.GetTerrainInfo(location + cellOffset).Type; + var terrain = map.GetTerrainInfo(location + cellOffset).Type; var testSequence = info.Sequence + "-" + terrain; var sequence = anim.HasSequence(testSequence) ? testSequence : info.Sequence; anim.PlayFetchIndex(sequence, () => index); diff --git a/OpenRA.Mods.RA/Buildings/Building.cs b/OpenRA.Mods.RA/Buildings/Building.cs index ca18c8d8b2..72b21c42b9 100644 --- a/OpenRA.Mods.RA/Buildings/Building.cs +++ b/OpenRA.Mods.RA/Buildings/Building.cs @@ -69,8 +69,8 @@ namespace OpenRA.Mods.RA.Buildings if (buildingTraits.Contains() && !(buildingTraits.Get().HasMinibib)) buildingMaxBounds += new CVec(0, 1); - var scanStart = world.ClampToWorld(topLeft - new CVec(Adjacent, Adjacent)); - var scanEnd = world.ClampToWorld(topLeft + buildingMaxBounds + new CVec(Adjacent, Adjacent)); + var scanStart = world.Map.Clamp(topLeft - new CVec(Adjacent, Adjacent)); + var scanEnd = world.Map.Clamp(topLeft + buildingMaxBounds + new CVec(Adjacent, Adjacent)); var nearnessCandidates = new List(); diff --git a/OpenRA.Mods.RA/Buildings/LaysTerrain.cs b/OpenRA.Mods.RA/Buildings/LaysTerrain.cs index 3dbe0b51f6..a44cdc2381 100755 --- a/OpenRA.Mods.RA/Buildings/LaysTerrain.cs +++ b/OpenRA.Mods.RA/Buildings/LaysTerrain.cs @@ -48,17 +48,19 @@ namespace OpenRA.Mods.RA.Buildings public void AddedToWorld(Actor self) { + var map = self.World.Map; + if (template.PickAny) { // Fill the footprint with random variants foreach (var c in FootprintUtils.Tiles(self)) { // Only place on allowed terrain types - if (!info.TerrainTypes.Contains(self.World.GetTerrainInfo(c).Type)) + if (!info.TerrainTypes.Contains(map.GetTerrainInfo(c).Type)) continue; // Don't place under other buildings or custom terrain - if (bi.GetBuildingAt(c) != self || self.World.Map.CustomTerrain[c.X, c.Y] != -1) + if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c.X, c.Y] != -1) continue; var index = Game.CosmeticRandom.Next(template.TilesCount); @@ -74,11 +76,11 @@ namespace OpenRA.Mods.RA.Buildings var c = origin + new CVec(i % template.Size.X, i / template.Size.X); // Only place on allowed terrain types - if (!info.TerrainTypes.Contains(self.World.GetTerrainInfo(c).Type)) + if (!info.TerrainTypes.Contains(map.GetTerrainInfo(c).Type)) continue; // Don't place under other buildings or custom terrain - if (bi.GetBuildingAt(c) != self || self.World.Map.CustomTerrain[c.X, c.Y] != -1) + if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c.X, c.Y] != -1) continue; layer.AddTile(c, new TileReference(template.Id, (byte)i)); diff --git a/OpenRA.Mods.RA/Buildings/Util.cs b/OpenRA.Mods.RA/Buildings/Util.cs index 34dc19d896..a3264c4dba 100644 --- a/OpenRA.Mods.RA/Buildings/Util.cs +++ b/OpenRA.Mods.RA/Buildings/Util.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Buildings if (world.WorldActor.Trait().GetBuildingAt(a) != null) return false; if (world.ActorMap.GetUnitsAt(a).Any(b => b != toIgnore)) return false; - return world.Map.IsInMap(a) && bi.TerrainTypes.Contains(world.GetTerrainInfo(a).Type); + return world.Map.IsInMap(a) && bi.TerrainTypes.Contains(world.Map.GetTerrainInfo(a).Type); } public static bool CanPlaceBuilding(this World world, string name, BuildingInfo building, CPos topLeft, Actor toIgnore) diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index fc6c371da5..b4d1da5b5c 100755 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA if (!world.Map.IsInMap(targetTile)) return; - var isWater = pos.Z <= 0 && world.GetTerrainInfo(targetTile).IsWater; + var isWater = pos.Z <= 0 && world.Map.GetTerrainInfo(targetTile).IsWater; var explosionType = isWater ? warhead.WaterExplosion : warhead.Explosion; var explosionTypePalette = isWater ? warhead.WaterExplosionPalette : warhead.ExplosionPalette; @@ -53,17 +53,17 @@ 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) { - var smudgeType = world.GetTerrainInfo(sc).AcceptsSmudgeType.FirstOrDefault(t => warhead.SmudgeType.Contains(t)); + var smudgeType = world.Map.GetTerrainInfo(sc).AcceptsSmudgeType.FirstOrDefault(t => warhead.SmudgeType.Contains(t)); if (smudgeType == null) continue; SmudgeLayer smudgeLayer; @@ -84,7 +84,7 @@ namespace OpenRA.Mods.RA } else { - var smudgeType = world.GetTerrainInfo(targetTile).AcceptsSmudgeType.FirstOrDefault(t => warhead.SmudgeType.Contains(t)); + var smudgeType = world.Map.GetTerrainInfo(targetTile).AcceptsSmudgeType.FirstOrDefault(t => warhead.SmudgeType.Contains(t)); if (smudgeType != null) { SmudgeLayer smudgeLayer; @@ -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/Crate.cs b/OpenRA.Mods.RA/Crate.cs index dbb798ce48..0c0bb85728 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -93,7 +93,7 @@ namespace OpenRA.Mods.RA { if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false; - var type = self.World.GetTerrainInfo(cell).Type; + var type = self.World.Map.GetTerrainInfo(cell).Type; if (!info.TerrainTypes.Contains(type)) return false; diff --git a/OpenRA.Mods.RA/CrateSpawner.cs b/OpenRA.Mods.RA/CrateSpawner.cs index 6956863acd..f4d218086a 100644 --- a/OpenRA.Mods.RA/CrateSpawner.cs +++ b/OpenRA.Mods.RA/CrateSpawner.cs @@ -89,8 +89,8 @@ namespace OpenRA.Mods.RA if (info.DeliveryAircraft != null) { var crate = w.CreateActor(false, crateActor, new TypeDictionary { new OwnerInit(w.WorldActor.Owner) }); - var startPos = w.ChooseRandomEdgeCell(); - var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].Traits.Get().CruiseAltitude; + var startPos = w.Map.ChooseRandomEdgeCell(w.SharedRandom); + var altitude = w.Map.Rules.Actors[info.DeliveryAircraft].Traits.Get().CruiseAltitude; var plane = w.CreateActor(info.DeliveryAircraft, new TypeDictionary { new CenterPositionInit(startPos.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)), @@ -114,10 +114,10 @@ namespace OpenRA.Mods.RA { for (var n = 0; n < maxTries; n++) { - var p = self.World.ChooseRandomCell(self.World.SharedRandom); + var p = self.World.Map.ChooseRandomCell(self.World.SharedRandom); // Is this valid terrain? - var terrainType = self.World.GetTerrainInfo(p).Type; + var terrainType = self.World.Map.GetTerrainInfo(p).Type; if (!(inWater ? info.ValidWater : info.ValidGround).Contains(terrainType)) continue; diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index 994dd98cf0..17aa2e5c5d 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -160,9 +160,8 @@ namespace OpenRA.Mods.RA.Effects var shouldExplode = (pos.Z < 0) // Hit the ground || (dist.LengthSquared < MissileCloseEnough.Range * MissileCloseEnough.Range) // Within range || (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel - || (!info.High && world.ActorMap.GetUnitsAt(cell) - .Any(a => a.HasTrait())) // Hit a wall - || (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.GetTerrainInfo(cell).Type != info.BoundToTerrainType); // Hit incompatible terrain + || (!info.High && world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait())) // Hit a wall + || (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.Map.GetTerrainInfo(cell).Type != info.BoundToTerrainType); // Hit incompatible terrain if (shouldExplode) Explode(world); diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index 3d2144ed03..810ee851ae 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false; - if (!info.AllowedTerrain.Contains(self.World.GetTerrainInfo(cell).Type)) + if (!info.AllowedTerrain.Contains(self.World.Map.GetTerrainInfo(cell).Type)) return false; if (!checkTransientActors) diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index f6b4117381..931855b75a 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -104,7 +104,7 @@ namespace OpenRA.Mods.RA.Move if (!world.Map.IsInMap(cell.X, cell.Y)) return int.MaxValue; - var index = world.GetTerrainIndex(cell); + var index = world.Map.GetTerrainIndex(cell); if (index == -1) return int.MaxValue; @@ -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; @@ -385,7 +389,7 @@ namespace OpenRA.Mods.RA.Move public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "Move") - PerformMove(self, self.World.ClampToWorld(order.TargetLocation), + PerformMove(self, self.World.Map.Clamp(order.TargetLocation), order.Queued && !self.IsIdle); if (order.OrderString == "Stop") @@ -481,7 +485,7 @@ namespace OpenRA.Mods.RA.Move public int MovementSpeedForCell(Actor self, CPos cell) { - var index = self.World.GetTerrainIndex(cell); + var index = self.World.Map.GetTerrainIndex(cell); if (index == -1) return 0; @@ -574,7 +578,7 @@ namespace OpenRA.Mods.RA.Move cursor = "move"; if (self.Owner.Shroud.IsExplored(location)) - cursor = self.World.GetTerrainInfo(location).CustomCursor ?? cursor; + cursor = self.World.Map.GetTerrainInfo(location).CustomCursor ?? cursor; if (!self.World.Map.IsInMap(location) || (self.Owner.Shroud.IsExplored(location) && unitType.MovementCostForCell(self.World, location) == int.MaxValue)) 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/Render/RenderLandingCraft.cs b/OpenRA.Mods.RA/Render/RenderLandingCraft.cs index eb210b6c44..e0b8fd96c7 100644 --- a/OpenRA.Mods.RA/Render/RenderLandingCraft.cs +++ b/OpenRA.Mods.RA/Render/RenderLandingCraft.cs @@ -45,8 +45,8 @@ namespace OpenRA.Mods.RA.Render if (self.CenterPosition.Z > 0 || move.IsMoving) return false; - return cargo.CurrentAdjacentCells - .Any(c => self.World.Map.IsInMap(c) && info.OpenTerrainTypes.Contains(self.World.GetTerrainInfo(c).Type)); + return cargo.CurrentAdjacentCells.Any(c => self.World.Map.IsInMap(c) + && info.OpenTerrainTypes.Contains(self.World.Map.GetTerrainInfo(c).Type)); } void Open() diff --git a/OpenRA.Mods.RA/Render/WithCrateBody.cs b/OpenRA.Mods.RA/Render/WithCrateBody.cs index d16004de80..e6523b6e6a 100755 --- a/OpenRA.Mods.RA/Render/WithCrateBody.cs +++ b/OpenRA.Mods.RA/Render/WithCrateBody.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Render public void OnLanded() { - var seq = self.World.GetTerrainInfo(self.Location).IsWater ? "water" : "land"; + var seq = self.World.Map.GetTerrainInfo(self.Location).IsWater ? "water" : "land"; anim.PlayRepeating(seq); } } diff --git a/OpenRA.Mods.RA/Scripting/Global/MapGlobal.cs b/OpenRA.Mods.RA/Scripting/Global/MapGlobal.cs index 58a050bb72..881c2d6310 100644 --- a/OpenRA.Mods.RA/Scripting/Global/MapGlobal.cs +++ b/OpenRA.Mods.RA/Scripting/Global/MapGlobal.cs @@ -46,13 +46,13 @@ namespace OpenRA.Mods.RA.Scripting [Desc("Returns a random cell inside the visible region of the map.")] public CPos RandomCell() { - return context.World.ChooseRandomCell(context.World.SharedRandom); + return context.World.Map.ChooseRandomCell(context.World.SharedRandom); } [Desc("Returns a random cell on the visible border of the map.")] public CPos RandomEdgeCell() { - return context.World.ChooseRandomEdgeCell(); + return context.World.Map.ChooseRandomEdgeCell(context.World.SharedRandom); } [Desc("Returns true if there is only one human player.")] diff --git a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs index ec0607dc34..76bfc98db5 100644 --- a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs +++ b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs @@ -339,13 +339,13 @@ namespace OpenRA.Mods.RA.Scripting [LuaGlobal] public CPos GetRandomCell() { - return world.ChooseRandomCell(world.SharedRandom); + return world.Map.ChooseRandomCell(world.SharedRandom); } [LuaGlobal] public CPos GetRandomEdgeCell() { - return world.ChooseRandomEdgeCell(); + return world.Map.ChooseRandomEdgeCell(world.SharedRandom); } [LuaGlobal] 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/AirstrikePower.cs b/OpenRA.Mods.RA/SupportPowers/AirstrikePower.cs index e0eb70c3b5..d6394aa99d 100644 --- a/OpenRA.Mods.RA/SupportPowers/AirstrikePower.cs +++ b/OpenRA.Mods.RA/SupportPowers/AirstrikePower.cs @@ -65,8 +65,8 @@ namespace OpenRA.Mods.RA var altitude = self.World.Map.Rules.Actors[info.UnitType].Traits.Get().CruiseAltitude.Range; var target = order.TargetLocation.CenterPosition + new WVec(0, 0, altitude); - var startEdge = target - (self.World.DistanceToMapEdge(target, -delta) + info.Cordon).Range * delta / 1024; - var finishEdge = target + (self.World.DistanceToMapEdge(target, delta) + info.Cordon).Range * delta / 1024; + var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Range * delta / 1024; + var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Range * delta / 1024; Actor flare = null; Actor camera = null; diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs index 92cf55cba5..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()) @@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA if (!self.Owner.Shroud.IsExplored(a) || !self.Owner.Shroud.IsExplored(b)) return false; - if (self.World.GetTerrainIndex(a) != self.World.GetTerrainIndex(b)) + if (self.World.Map.GetTerrainIndex(a) != self.World.Map.GetTerrainIndex(b)) return false; } @@ -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); } diff --git a/OpenRA.Mods.RA/SupportPowers/ParatroopersPower.cs b/OpenRA.Mods.RA/SupportPowers/ParatroopersPower.cs index 6644fd40b3..b09ce2dd5f 100644 --- a/OpenRA.Mods.RA/SupportPowers/ParatroopersPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ParatroopersPower.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA var info = (ParatroopersPowerInfo)Info; var items = info.DropItems; - var startPos = self.World.ChooseRandomEdgeCell(); + var startPos = self.World.Map.ChooseRandomEdgeCell(self.World.SharedRandom); self.World.AddFrameEndTask(w => { diff --git a/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs b/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs index 00a16c0649..7af7fc93b4 100644 --- a/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs +++ b/OpenRA.Mods.RA/SupportPowers/SpyPlanePower.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA { base.Activate(self, order, manager); - var enterCell = self.World.ChooseRandomEdgeCell(); + var enterCell = self.World.Map.ChooseRandomEdgeCell(self.World.SharedRandom); var altitude = self.World.Map.Rules.Actors["u2"].Traits.Get().CruiseAltitude; var plane = self.World.CreateActor("u2", new TypeDictionary diff --git a/OpenRA.Mods.RA/World/DomainIndex.cs b/OpenRA.Mods.RA/World/DomainIndex.cs index 994505913b..569d49620c 100644 --- a/OpenRA.Mods.RA/World/DomainIndex.cs +++ b/OpenRA.Mods.RA/World/DomainIndex.cs @@ -169,7 +169,7 @@ namespace OpenRA.Mods.RA bool CanTraverseTile(World world, CPos p) { - var terrainOffset = world.GetTerrainIndex(p); + var terrainOffset = world.Map.GetTerrainIndex(p); return (movementClass & (1 << terrainOffset)) > 0; }