diff --git a/OpenRA.Game/ActorInitializer.cs b/OpenRA.Game/ActorInitializer.cs index 71ee1eb43f..f342c21d24 100755 --- a/OpenRA.Game/ActorInitializer.cs +++ b/OpenRA.Game/ActorInitializer.cs @@ -10,6 +10,7 @@ using System.Linq; using OpenRA.FileFormats; +using OpenRA.Traits; namespace OpenRA { diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 5e339a3f97..96e9c36fa4 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -83,7 +83,6 @@ - @@ -239,6 +238,7 @@ + diff --git a/OpenRA.Game/ActorMap.cs b/OpenRA.Game/Traits/World/ActorMap.cs similarity index 59% rename from OpenRA.Game/ActorMap.cs rename to OpenRA.Game/Traits/World/ActorMap.cs index 5fc8ac1f8f..06afa295f0 100644 --- a/OpenRA.Game/ActorMap.cs +++ b/OpenRA.Game/Traits/World/ActorMap.cs @@ -12,10 +12,15 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Traits; -namespace OpenRA +namespace OpenRA.Traits { public enum SubCell { FullCell, TopLeft, TopRight, Center, BottomLeft, BottomRight } + class ActorMapInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new ActorMap(init.world); } + } + public class ActorMap { class InfluenceNode @@ -28,29 +33,31 @@ namespace OpenRA InfluenceNode[,] influence; Map map; - public ActorMap( World world ) + public ActorMap(World world) { map = world.Map; influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y]; - world.ActorAdded += a => Add( a, a.OccupiesSpace ); - world.ActorRemoved += a => Remove( a, a.OccupiesSpace ); + world.ActorAdded += a => Add(a, a.OccupiesSpace); + world.ActorRemoved += a => Remove(a, a.OccupiesSpace); } public IEnumerable GetUnitsAt(CPos a) { - if (!map.IsInMap(a)) yield break; + if (!map.IsInMap(a)) + yield break; - for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next ) + for (var i = influence[a.X, a.Y]; i != null; i = i.next) if (!i.actor.Destroyed) yield return i.actor; } public IEnumerable GetUnitsAt(CPos a, SubCell sub) { - if (!map.IsInMap(a)) yield break; + if (!map.IsInMap(a)) + yield break; - for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next ) + for (var i = influence[a.X, a.Y]; i != null; i = i.next) if (!i.actor.Destroyed && (i.subCell == sub || i.subCell == SubCell.FullCell)) yield return i.actor; } @@ -60,7 +67,7 @@ namespace OpenRA if (!AnyUnitsAt(a)) return true; - return new[]{ SubCell.TopLeft, SubCell.TopRight, SubCell.Center, + return new[] { SubCell.TopLeft, SubCell.TopRight, SubCell.Center, SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b)); } @@ -69,54 +76,55 @@ namespace OpenRA if (!HasFreeSubCell(a)) return null; - return new[]{ SubCell.TopLeft, SubCell.TopRight, SubCell.Center, + return new[] { SubCell.TopLeft, SubCell.TopRight, SubCell.Center, SubCell.BottomLeft, SubCell.BottomRight }.First(b => !AnyUnitsAt(a,b)); } public bool AnyUnitsAt(CPos a) { - return influence[ a.X, a.Y ] != null; + return influence[a.X, a.Y] != null; } public bool AnyUnitsAt(CPos a, SubCell sub) { - for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next ) + for (var i = influence[a.X, a.Y]; i != null; i = i.next) if (i.subCell == sub || i.subCell == SubCell.FullCell) return true; return false; } - public void Add( Actor self, IOccupySpace unit ) - { - if (unit != null) - foreach( var c in unit.OccupiedCells() ) - influence[ c.First.X, c.First.Y ] = new InfluenceNode { next = influence[ c.First.X, c.First.Y ], subCell = c.Second, actor = self }; - } - - public void Remove( Actor self, IOccupySpace unit ) + public void Add(Actor self, IOccupySpace unit) { if (unit != null) foreach (var c in unit.OccupiedCells()) - RemoveInner( ref influence[ c.First.X, c.First.Y ], self ); + influence[c.First.X, c.First.Y] = new InfluenceNode { next = influence[c.First.X, c.First.Y], subCell = c.Second, actor = self }; } - void RemoveInner( ref InfluenceNode influenceNode, Actor toRemove ) + public void Remove(Actor self, IOccupySpace unit) { - if( influenceNode == null ) + if (unit != null) + foreach (var c in unit.OccupiedCells()) + RemoveInner(ref influence[c.First.X, c.First.Y], self); + } + + void RemoveInner(ref InfluenceNode influenceNode, Actor toRemove) + { + if (influenceNode == null) return; - else if( influenceNode.actor == toRemove ) + else if (influenceNode.actor == toRemove) influenceNode = influenceNode.next; if (influenceNode != null) - RemoveInner( ref influenceNode.next, toRemove ); + RemoveInner(ref influenceNode.next, toRemove); } public void Update(Actor self, IOccupySpace unit) { Remove(self, unit); - if (!self.IsDead()) Add(self, unit); + if (!self.IsDead()) + Add(self, unit); } } } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 0d22448ebf..01e27d1649 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -123,7 +123,7 @@ namespace OpenRA SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed); WorldActor = CreateActor("World", new TypeDictionary()); - ActorMap = new ActorMap(this); + ActorMap = WorldActor.Trait(); ScreenMap = WorldActor.Trait(); // Add players diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 2f45b021a7..4909e4f53d 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -207,6 +207,7 @@ Player: World: ScreenMap: + ActorMap: LoadWidgetAtGameStart: Widget: INGAME_ROOT CncMenuPaletteEffect: diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index 401d19e266..e9bc422318 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -358,6 +358,7 @@ Player: World: ScreenMap: + ActorMap: LoadWidgetAtGameStart: Widget: INGAME_ROOT ScreenShaker: diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 49a0920f8a..384c8e8d58 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -530,6 +530,7 @@ Player: World: ScreenMap: + ActorMap: LoadWidgetAtGameStart: Widget: INGAME_ROOT ScreenShaker: diff --git a/mods/ts/rules/system.yaml b/mods/ts/rules/system.yaml index cc885b62ed..52cc6ddb03 100644 --- a/mods/ts/rules/system.yaml +++ b/mods/ts/rules/system.yaml @@ -43,6 +43,7 @@ Player: World: ScreenMap: + ActorMap: LoadWidgetAtGameStart: Widget: INGAME_ROOT BuildingInfluence: