Track actor positions in ActorMap.

This commit is contained in:
Paul Chote
2013-09-21 16:06:39 +12:00
parent b00cc6108d
commit e03ec690ff
8 changed files with 64 additions and 8 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}