diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 96e9c36fa4..410110aeee 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -184,7 +184,6 @@ - diff --git a/OpenRA.Game/Traits/World/ActorMap.cs b/OpenRA.Game/Traits/World/ActorMap.cs index 7a74294f40..26a845fb51 100644 --- a/OpenRA.Game/Traits/World/ActorMap.cs +++ b/OpenRA.Game/Traits/World/ActorMap.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Linq; using OpenRA.FileFormats; @@ -150,5 +151,30 @@ namespace OpenRA.Traits RemovePosition(a, ios); AddPosition(a, ios); } + + public IEnumerable ActorsInBox(WPos a, WPos b) + { + var left = Math.Min(a.X, b.X); + var top = Math.Min(a.Y, b.Y); + var right = Math.Max(a.X, b.X); + var bottom = Math.Max(a.Y, b.Y); + var i1 = (left / info.BinSize).Clamp(0, cols - 1); + var i2 = (right / info.BinSize).Clamp(0, cols - 1); + var j1 = (top / info.BinSize).Clamp(0, rows - 1); + var j2 = (bottom / info.BinSize).Clamp(0, rows - 1); + + for (var j = j1; j <= j2; j++) + { + for (var i = i1; i <= i2; i++) + { + foreach (var actor in actors[j*cols + i]) + { + var c = actor.CenterPosition; + if (left <= c.X && c.X <= right && top <= c.Y && c.Y <= bottom) + yield return actor; + } + } + } + } } } diff --git a/OpenRA.Game/Traits/World/SpatialBins.cs b/OpenRA.Game/Traits/World/SpatialBins.cs deleted file mode 100644 index a6b17a508c..0000000000 --- a/OpenRA.Game/Traits/World/SpatialBins.cs +++ /dev/null @@ -1,87 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; - -namespace OpenRA.Traits -{ - class SpatialBinsInfo : ITraitInfo - { - public readonly int BinSize = 8; - public object Create(ActorInitializer init) { return new SpatialBins( init.self, this ); } - } - - class SpatialBins : ITick - { - List[,] bins; - int scale; - - public SpatialBins(Actor self, SpatialBinsInfo info) - { - bins = new List[ - self.World.Map.MapSize.X / info.BinSize, - self.World.Map.MapSize.Y / info.BinSize]; - - scale = Game.CellSize * info.BinSize; - - for (var j = 0; j <= bins.GetUpperBound(1); j++) - for (var i = 0; i <= bins.GetUpperBound(0); i++) - bins[i, j] = new List(); - } - - public void Tick(Actor self) - { - for (var j = 0; j <= bins.GetUpperBound(1); j++) - for (var i = 0; i <= bins.GetUpperBound(0); i++) - bins[i, j].Clear(); - - foreach (var a in self.World.ActorsWithTrait()) - { - var bounds = a.Actor.ExtendedBounds.Value; - - if (bounds.Right <= Game.CellSize * self.World.Map.Bounds.Left) continue; - if (bounds.Bottom <= Game.CellSize * self.World.Map.Bounds.Top) continue; - if (bounds.Left >= Game.CellSize * self.World.Map.Bounds.Right) continue; - if (bounds.Top >= Game.CellSize * self.World.Map.Bounds.Bottom) continue; - - var i1 = Math.Max(0, bounds.Left / scale); - var i2 = Math.Min(bins.GetUpperBound(0), bounds.Right / scale); - var j1 = Math.Max(0, bounds.Top / scale); - var j2 = Math.Min(bins.GetUpperBound(1), bounds.Bottom / scale); - - for (var j = j1; j <= j2; j++) - for (var i = i1; i <= i2; i++) - bins[i, j].Add(a.Actor); - } - } - - IEnumerable ActorsInBins(int i1, int i2, int j1, int j2) - { - j1 = Math.Max(0, j1); j2 = Math.Min(j2, bins.GetUpperBound(1)); - i1 = Math.Max(0, i1); i2 = Math.Min(i2, bins.GetUpperBound(0)); - for (var j = j1; j <= j2; j++) - for (var i = i1; i <= i2; i++) - foreach (var a in bins[i, j]) - yield return a; - } - - public IEnumerable ActorsInBox(PPos a, PPos b) - { - var r = Rectangle.FromLTRB(a.X, a.Y, b.X, b.Y); - - return ActorsInBins(a.X / scale, b.X / scale, a.Y / scale, b.Y / scale) - .Distinct() - .Where(u => u.IsInWorld && u.ExtendedBounds.Value.IntersectsWith(r)); - } - } -} diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index b9c0d2a4b5..df54b6d96b 100755 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -32,16 +32,13 @@ namespace OpenRA public static IEnumerable FindActorsInBox(this World world, CPos tl, CPos br) { + // TODO: Support diamond boxes for isometric maps? return world.FindActorsInBox(tl.TopLeft, br.BottomRight); } public static IEnumerable FindActorsInBox(this World world, WPos tl, WPos br) { - var a = PPos.FromWPos(tl); - var b = PPos.FromWPos(br); - var u = PPos.Min(a, b); - var v = PPos.Max(a, b); - return world.WorldActor.Trait().ActorsInBox(u,v); + return world.ActorMap.ActorsInBox(tl, br); } public static Actor ClosestTo(this IEnumerable actors, Actor a) diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 4909e4f53d..748199d14b 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -365,8 +365,6 @@ World: BaseActor: mcv SupportActors: e1,e1,e1,e1,e1,e2,e2,e2,e3,e3,apc,mtnk SpawnMPUnits: - SpatialBins: - BinSize: 4 CrateSpawner: Minimum: 1 Maximum: 6 diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index e9bc422318..f719298a56 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -476,8 +476,6 @@ World: Races: ordos BaseActor: mcvo SpawnMPUnits: - SpatialBins: - BinSize: 4 PathFinder: ValidateOrder: DebugPauseState: diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 384c8e8d58..4881555cd3 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -682,8 +682,6 @@ World: OuterSupportRadius: 5 MPStartLocations: SpawnMPUnits: - SpatialBins: - BinSize: 4 PathFinder: ValidateOrder: DebugPauseState: diff --git a/mods/ts/rules/system.yaml b/mods/ts/rules/system.yaml index 52cc6ddb03..d0567f83e1 100644 --- a/mods/ts/rules/system.yaml +++ b/mods/ts/rules/system.yaml @@ -124,8 +124,6 @@ World: BaseActor: mcv MPStartLocations: SpawnMPUnits: - SpatialBins: - BinSize: 4 PathFinder: ValidateOrder: DebugPauseState: