Track actor positions in ActorMap.
This commit is contained in:
@@ -20,7 +20,7 @@ namespace OpenRA.Traits
|
||||
|
||||
class Waypoint : IOccupySpace, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
|
||||
{
|
||||
[Sync] CPos location;
|
||||
[Sync] readonly CPos location;
|
||||
|
||||
public Waypoint(ActorInitializer init)
|
||||
{
|
||||
@@ -34,12 +34,14 @@ namespace OpenRA.Traits
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,15 +10,19 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
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
|
||||
@@ -30,13 +34,25 @@ namespace OpenRA.Traits
|
||||
public Actor actor;
|
||||
}
|
||||
|
||||
readonly ActorMapInfo info;
|
||||
readonly Map map;
|
||||
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;
|
||||
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)
|
||||
@@ -114,5 +130,25 @@ namespace OpenRA.Traits
|
||||
if (influenceNode != null)
|
||||
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;
|
||||
|
||||
if (self.IsInWorld)
|
||||
{
|
||||
self.World.ScreenMap.Update(self);
|
||||
self.World.ActorMap.UpdatePosition(self, this);
|
||||
}
|
||||
}
|
||||
|
||||
// Changes position, but not altitude
|
||||
@@ -116,12 +119,14 @@ namespace OpenRA.Mods.RA.Air
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,12 +161,14 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,9 +103,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void SetPosition(Actor self, CPos cell)
|
||||
{
|
||||
if (self.IsInWorld)
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
Location = cell;
|
||||
CenterPosition = cell.CenterPosition;
|
||||
|
||||
@@ -117,6 +115,7 @@ namespace OpenRA.Mods.RA
|
||||
if (self.IsInWorld)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.UpdatePosition(self, this);
|
||||
self.World.ScreenMap.Update(self);
|
||||
}
|
||||
}
|
||||
@@ -129,12 +128,14 @@ namespace OpenRA.Mods.RA
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,18 +76,21 @@ namespace OpenRA.Mods.RA
|
||||
CenterPosition = pos;
|
||||
TopLeft = pos.ToCPos();
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.UpdatePosition(self, this);
|
||||
self.World.ScreenMap.Update(self);
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,12 +66,14 @@ namespace OpenRA.Mods.RA
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,18 +232,23 @@ namespace OpenRA.Mods.RA.Move
|
||||
{
|
||||
CenterPosition = pos;
|
||||
if (self.IsInWorld)
|
||||
{
|
||||
self.World.ScreenMap.Update(self);
|
||||
self.World.ActorMap.UpdatePosition(self, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.AddInfluence(self, this);
|
||||
self.World.ActorMap.AddPosition(self, this);
|
||||
self.World.ScreenMap.Add(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
self.World.ActorMap.RemovePosition(self, this);
|
||||
self.World.ScreenMap.Remove(self);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user