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: