Track actor positions in ActorMap.
This commit is contained in:
@@ -20,7 +20,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
class Waypoint : IOccupySpace, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
|
class Waypoint : IOccupySpace, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
|
||||||
{
|
{
|
||||||
[Sync] CPos location;
|
[Sync] readonly CPos location;
|
||||||
|
|
||||||
public Waypoint(ActorInitializer init)
|
public Waypoint(ActorInitializer init)
|
||||||
{
|
{
|
||||||
@@ -34,12 +34,14 @@ namespace OpenRA.Traits
|
|||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,19 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
public enum SubCell { FullCell, TopLeft, TopRight, Center, BottomLeft, BottomRight }
|
public enum SubCell { FullCell, TopLeft, TopRight, Center, BottomLeft, BottomRight }
|
||||||
|
|
||||||
class ActorMapInfo : ITraitInfo
|
public class ActorMapInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
public object Create(ActorInitializer init) { return new ActorMap(init.world); }
|
[Desc("Size of partition bins (cells)")]
|
||||||
|
public readonly int BinSize = 10;
|
||||||
|
|
||||||
|
public object Create(ActorInitializer init) { return new ActorMap(init.world, this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ActorMap
|
public class ActorMap
|
||||||
@@ -30,13 +34,25 @@ namespace OpenRA.Traits
|
|||||||
public Actor actor;
|
public Actor actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly ActorMapInfo info;
|
||||||
|
readonly Map map;
|
||||||
InfluenceNode[,] influence;
|
InfluenceNode[,] influence;
|
||||||
Map map;
|
|
||||||
|
|
||||||
public ActorMap(World world)
|
List<Actor>[] actors;
|
||||||
|
int rows, cols;
|
||||||
|
|
||||||
|
public ActorMap(World world, ActorMapInfo info)
|
||||||
{
|
{
|
||||||
|
this.info = info;
|
||||||
map = world.Map;
|
map = world.Map;
|
||||||
influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y];
|
influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y];
|
||||||
|
|
||||||
|
cols = world.Map.MapSize.X / info.BinSize + 1;
|
||||||
|
rows = world.Map.MapSize.Y / info.BinSize + 1;
|
||||||
|
actors = new List<Actor>[rows * cols];
|
||||||
|
for (var j = 0; j < rows; j++)
|
||||||
|
for (var i = 0; i < cols; i++)
|
||||||
|
actors[j * cols + i] = new List<Actor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Actor> GetUnitsAt(CPos a)
|
public IEnumerable<Actor> GetUnitsAt(CPos a)
|
||||||
@@ -114,5 +130,25 @@ namespace OpenRA.Traits
|
|||||||
if (influenceNode != null)
|
if (influenceNode != null)
|
||||||
RemoveInfluenceInner(ref influenceNode.next, toRemove);
|
RemoveInfluenceInner(ref influenceNode.next, toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddPosition(Actor a, IOccupySpace ios)
|
||||||
|
{
|
||||||
|
var pos = ios.CenterPosition;
|
||||||
|
var i = (pos.X / info.BinSize).Clamp(0, cols - 1);
|
||||||
|
var j = (pos.Y / info.BinSize).Clamp(0, rows - 1);
|
||||||
|
actors[j*cols + i].Add(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePosition(Actor a, IOccupySpace ios)
|
||||||
|
{
|
||||||
|
foreach (var bin in actors)
|
||||||
|
bin.Remove(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdatePosition(Actor a, IOccupySpace ios)
|
||||||
|
{
|
||||||
|
RemovePosition(a, ios);
|
||||||
|
AddPosition(a, ios);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,10 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
CenterPosition = pos;
|
CenterPosition = pos;
|
||||||
|
|
||||||
if (self.IsInWorld)
|
if (self.IsInWorld)
|
||||||
|
{
|
||||||
self.World.ScreenMap.Update(self);
|
self.World.ScreenMap.Update(self);
|
||||||
|
self.World.ActorMap.UpdatePosition(self, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changes position, but not altitude
|
// Changes position, but not altitude
|
||||||
@@ -116,12 +119,14 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,12 +161,14 @@ namespace OpenRA.Mods.RA.Buildings
|
|||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,9 +103,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public void SetPosition(Actor self, CPos cell)
|
public void SetPosition(Actor self, CPos cell)
|
||||||
{
|
{
|
||||||
if (self.IsInWorld)
|
self.World.ActorMap.RemoveInfluence(self, this);
|
||||||
self.World.ActorMap.RemoveInfluence(self, this);
|
|
||||||
|
|
||||||
Location = cell;
|
Location = cell;
|
||||||
CenterPosition = cell.CenterPosition;
|
CenterPosition = cell.CenterPosition;
|
||||||
|
|
||||||
@@ -117,6 +115,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (self.IsInWorld)
|
if (self.IsInWorld)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.UpdatePosition(self, this);
|
||||||
self.World.ScreenMap.Update(self);
|
self.World.ScreenMap.Update(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,12 +128,14 @@ namespace OpenRA.Mods.RA
|
|||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,18 +76,21 @@ namespace OpenRA.Mods.RA
|
|||||||
CenterPosition = pos;
|
CenterPosition = pos;
|
||||||
TopLeft = pos.ToCPos();
|
TopLeft = pos.ToCPos();
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.UpdatePosition(self, this);
|
||||||
self.World.ScreenMap.Update(self);
|
self.World.ScreenMap.Update(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,12 +66,14 @@ namespace OpenRA.Mods.RA
|
|||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,18 +232,23 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
{
|
{
|
||||||
CenterPosition = pos;
|
CenterPosition = pos;
|
||||||
if (self.IsInWorld)
|
if (self.IsInWorld)
|
||||||
|
{
|
||||||
self.World.ScreenMap.Update(self);
|
self.World.ScreenMap.Update(self);
|
||||||
|
self.World.ActorMap.UpdatePosition(self, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
self.World.ActorMap.AddInfluence(self, this);
|
self.World.ActorMap.AddInfluence(self, this);
|
||||||
|
self.World.ActorMap.AddPosition(self, this);
|
||||||
self.World.ScreenMap.Add(self);
|
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.ScreenMap.Remove(self);
|
self.World.ScreenMap.Remove(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user