Prevent items without size from being added to SpatiallyPartitioned.
Items with no size act unexpectedly as they can fail to be returned when querying partition bins as they do not intersect along the top or left edges of the bin. We prevent such items being added in the first place to avoid this scenario. As a side effect - we must now prevent any Immobile items that do not have size from being added to the screen map.
This commit is contained in:
@@ -30,14 +30,22 @@ namespace OpenRA.Primitives
|
|||||||
itemBoundsBins = Exts.MakeArray(rows * cols, _ => new Dictionary<T, Rectangle>());
|
itemBoundsBins = Exts.MakeArray(rows * cols, _ => new Dictionary<T, Rectangle>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ValidateBounds(Rectangle bounds)
|
||||||
|
{
|
||||||
|
if (bounds.Width <= 0 || bounds.Height <= 0)
|
||||||
|
throw new ArgumentException("bounds must be non-empty.", "bounds");
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(T item, Rectangle bounds)
|
public void Add(T item, Rectangle bounds)
|
||||||
{
|
{
|
||||||
|
ValidateBounds(bounds);
|
||||||
itemBounds.Add(item, bounds);
|
itemBounds.Add(item, bounds);
|
||||||
MutateBins(item, bounds, addItem);
|
MutateBins(item, bounds, addItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(T item, Rectangle bounds)
|
public void Update(T item, Rectangle bounds)
|
||||||
{
|
{
|
||||||
|
ValidateBounds(bounds);
|
||||||
MutateBins(item, itemBounds[item], removeItem);
|
MutateBins(item, itemBounds[item], removeItem);
|
||||||
MutateBins(item, itemBounds[item] = bounds, addItem);
|
MutateBins(item, itemBounds[item] = bounds, addItem);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,14 +55,18 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
self.World.ActorMap.AddPosition(self, this);
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
|
||||||
|
if (!self.Bounds.Size.IsEmpty)
|
||||||
|
self.World.ScreenMap.Add(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemovedFromWorld(Actor self)
|
public void RemovedFromWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.RemoveInfluence(self, this);
|
self.World.ActorMap.RemoveInfluence(self, this);
|
||||||
self.World.ActorMap.RemovePosition(self, this);
|
self.World.ActorMap.RemovePosition(self, this);
|
||||||
self.World.ScreenMap.Remove(self);
|
|
||||||
|
if (!self.Bounds.Size.IsEmpty)
|
||||||
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user