From 206e4fb558549e3355b512fd34a94054df37ad02 Mon Sep 17 00:00:00 2001 From: Bob Date: Fri, 29 Jan 2010 19:57:21 +1300 Subject: [PATCH] BIM/UIM become traits on World; Added World.WorldActor --- OpenRa.Game/Graphics/Minimap.cs | 2 +- OpenRa.Game/OpenRa.Game.csproj | 4 +-- OpenRa.Game/Ore.cs | 3 +- OpenRa.Game/PathFinder.cs | 2 +- OpenRa.Game/PathSearch.cs | 9 +++--- OpenRa.Game/Traits/Activities/Move.cs | 10 +++--- OpenRa.Game/Traits/Activities/UnloadCargo.cs | 2 +- .../BuildingInfluence.cs} | 25 +++++++++------ OpenRa.Game/Traits/ConstructionYard.cs | 4 +-- OpenRa.Game/Traits/Crate.cs | 2 +- OpenRa.Game/Traits/Mobile.cs | 12 +++---- OpenRa.Game/Traits/Production.cs | 2 +- .../Traits/RenderBuildingWarFactory.cs | 2 +- .../UnitInfluence.cs} | 31 ++++++++++--------- OpenRa.Game/UiOverlay.cs | 2 +- OpenRa.Game/World.cs | 11 ++----- OpenRa.Game/WorldUtils.cs | 6 ++-- OpenRa.Mods.RA/Mine.cs | 2 +- OpenRa.Mods.RA/Minelayer.cs | 2 +- mods/ra/merge-rules.yaml | 2 ++ mods/ra/rules.yaml | 2 ++ 21 files changed, 73 insertions(+), 64 deletions(-) rename OpenRa.Game/{BuildingInfluenceMap.cs => Traits/BuildingInfluence.cs} (69%) mode change 100644 => 100755 rename OpenRa.Game/{UnitInfluenceMap.cs => Traits/UnitInfluence.cs} (74%) mode change 100644 => 100755 diff --git a/OpenRa.Game/Graphics/Minimap.cs b/OpenRa.Game/Graphics/Minimap.cs index b56b91a53d..b5d7efe8e1 100644 --- a/OpenRa.Game/Graphics/Minimap.cs +++ b/OpenRa.Game/Graphics/Minimap.cs @@ -108,7 +108,7 @@ namespace OpenRa.Graphics for (var y = 0; y < 128; y++) for (var x = 0; x < 128; x++) { - var b = world.BuildingInfluence.GetBuildingAt(new int2(x, y)); + var b = world.WorldActor.traits.Get().GetBuildingAt(new int2(x, y)); if (b != null) *(c + (y * bitmapData.Stride >> 2) + x) = (b.Owner != null ? playerColors[(int)b.Owner.Palette] : colors[4]).ToArgb(); diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 308239c03e..b47af8bcb1 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -160,7 +160,6 @@ - @@ -202,6 +201,7 @@ + @@ -258,6 +258,7 @@ + @@ -266,7 +267,6 @@ - diff --git a/OpenRa.Game/Ore.cs b/OpenRa.Game/Ore.cs index 06c24e44fc..34318cd38b 100644 --- a/OpenRa.Game/Ore.cs +++ b/OpenRa.Game/Ore.cs @@ -1,5 +1,6 @@ using System; using OpenRa.FileFormats; +using OpenRa.Traits; namespace OpenRa { @@ -28,7 +29,7 @@ namespace OpenRa public static bool OreCanSpreadInto(this World world, int i, int j) { - if (world.BuildingInfluence.GetBuildingAt(new int2(i, j)) != null) + if (world.WorldActor.traits.Get().GetBuildingAt(new int2(i, j)) != null) return false; return TerrainCosts.Cost(UnitMovementType.Wheel, diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index 2fac57d5b4..c9e5e07a65 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -57,7 +57,7 @@ namespace OpenRa return q => p != q && ((p - q).LengthSquared < dist * dist) && - (world.UnitInfluence.GetUnitsAt(q).Any()); + (world.WorldActor.traits.Get().GetUnitsAt(q).Any()); } public List FindPath( PathSearch search ) diff --git a/OpenRa.Game/PathSearch.cs b/OpenRa.Game/PathSearch.cs index c18e263709..abd07e1945 100755 --- a/OpenRa.Game/PathSearch.cs +++ b/OpenRa.Game/PathSearch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using IjwFramework.Collections; using OpenRa.Graphics; +using OpenRa.Traits; namespace OpenRa { @@ -47,7 +48,7 @@ namespace OpenRa if (thisCost == float.PositiveInfinity) return p.Location; - foreach( int2 d in Util.directions ) + foreach( int2 d in Graphics.Util.directions ) { int2 newHere = p.Location + d; @@ -61,14 +62,14 @@ namespace OpenRa if (costHere == float.PositiveInfinity) continue; - if (!world.BuildingInfluence.CanMoveHere(newHere) && - world.BuildingInfluence.GetBuildingAt(newHere) != ignoreBuilding) + if (!world.WorldActor.traits.Get().CanMoveHere(newHere) && + world.WorldActor.traits.Get().GetBuildingAt(newHere) != ignoreBuilding) continue; if (world.Map.IsOverlaySolid(newHere)) continue; // Replicate real-ra behavior of not being able to enter a cell if there is a mixture of crushable and uncrushable units - if (checkForBlocked && (world.UnitInfluence.GetUnitsAt(newHere).Any(a => !world.IsActorPathableToCrush(a, umt)))) + if (checkForBlocked && (world.WorldActor.traits.Get().GetUnitsAt(newHere).Any(a => !world.IsActorPathableToCrush(a, umt)))) continue; if (customBlock != null && customBlock(newHere)) diff --git a/OpenRa.Game/Traits/Activities/Move.cs b/OpenRa.Game/Traits/Activities/Move.cs index b5cec75a2e..a12fd1c032 100755 --- a/OpenRa.Game/Traits/Activities/Move.cs +++ b/OpenRa.Game/Traits/Activities/Move.cs @@ -57,13 +57,13 @@ namespace OpenRa.Traits.Activities bool CanEnterCell( int2 c, Actor self ) { - if (!self.World.BuildingInfluence.CanMoveHere(c) - && self.World.BuildingInfluence.GetBuildingAt(c) != ignoreBuilding) + if (!self.World.WorldActor.traits.Get().CanMoveHere(c) + && self.World.WorldActor.traits.Get().GetBuildingAt(c) != ignoreBuilding) return false; // Cannot enter a cell if any unit inside is uncrushable // This will need to be updated for multiple-infantry-in-a-cell - return (!self.World.UnitInfluence.GetUnitsAt(c).Any(a => a != self && !self.World.IsActorCrushableByActor(a, self))); + return (!self.World.WorldActor.traits.Get().GetUnitsAt(c).Any(a => a != self && !self.World.IsActorCrushableByActor(a, self))); } public IActivity Tick( Actor self ) @@ -144,10 +144,10 @@ namespace OpenRa.Traits.Activities return null; } - self.World.UnitInfluence.Remove( self, mobile ); + self.World.WorldActor.traits.Get().Remove( self, mobile ); var newPath = getPath(self, mobile).TakeWhile(a => a != self.Location).ToList(); - self.World.UnitInfluence.Add( self, mobile ); + self.World.WorldActor.traits.Get().Add( self, mobile ); if (newPath.Count != 0) path = newPath; diff --git a/OpenRa.Game/Traits/Activities/UnloadCargo.cs b/OpenRa.Game/Traits/Activities/UnloadCargo.cs index 2d4ac9f803..48b28464d6 100644 --- a/OpenRa.Game/Traits/Activities/UnloadCargo.cs +++ b/OpenRa.Game/Traits/Activities/UnloadCargo.cs @@ -13,7 +13,7 @@ namespace OpenRa.Traits.Activities int2? ChooseExitTile(Actor self) { // is anyone still hogging this tile? - if (self.World.UnitInfluence.GetUnitsAt(self.Location).Count() > 1) + if (self.World.WorldActor.traits.Get().GetUnitsAt(self.Location).Count() > 1) return null; for (var i = -1; i < 2; i++) diff --git a/OpenRa.Game/BuildingInfluenceMap.cs b/OpenRa.Game/Traits/BuildingInfluence.cs old mode 100644 new mode 100755 similarity index 69% rename from OpenRa.Game/BuildingInfluenceMap.cs rename to OpenRa.Game/Traits/BuildingInfluence.cs index bd2ab8cea7..8559af84b2 --- a/OpenRa.Game/BuildingInfluenceMap.cs +++ b/OpenRa.Game/Traits/BuildingInfluence.cs @@ -1,19 +1,27 @@ -using OpenRa.GameRules; -using OpenRa.Traits; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.GameRules; -namespace OpenRa +namespace OpenRa.Traits { - public class BuildingInfluenceMap + public class BuildingInfluenceInfo : ITraitInfo + { + public object Create( Actor self ) { return new BuildingInfluence( self ); } + } + + public class BuildingInfluence { bool[,] blocked = new bool[128, 128]; Actor[,] influence = new Actor[128, 128]; - public BuildingInfluenceMap( World world ) + public BuildingInfluence( Actor self ) { - world.ActorAdded += + self.World.ActorAdded += a => { if (a.traits.Contains()) ChangeInfluence(a, a.traits.Get(), true); }; - world.ActorRemoved += + self.World.ActorRemoved += a => { if (a.traits.Contains()) ChangeInfluence(a, a.traits.Get(), false); }; } @@ -44,5 +52,4 @@ namespace OpenRa { return IsValid(cell) && !blocked[cell.X, cell.Y]; } - } -} + }} diff --git a/OpenRa.Game/Traits/ConstructionYard.cs b/OpenRa.Game/Traits/ConstructionYard.cs index d616c468f3..3e03aeff1b 100644 --- a/OpenRa.Game/Traits/ConstructionYard.cs +++ b/OpenRa.Game/Traits/ConstructionYard.cs @@ -52,10 +52,10 @@ namespace OpenRa.Traits public bool CanEnterCell(int2 a) { - if (!self.World.BuildingInfluence.CanMoveHere(a)) return false; + if (!self.World.WorldActor.traits.Get().CanMoveHere(a)) return false; var crushable = true; - foreach (Actor actor in self.World.UnitInfluence.GetUnitsAt(a)) + foreach (Actor actor in self.World.WorldActor.traits.Get().GetUnitsAt(a)) { if (actor == self) continue; diff --git a/OpenRa.Game/Traits/Crate.cs b/OpenRa.Game/Traits/Crate.cs index 25dd401a42..9f3b4ae881 100644 --- a/OpenRa.Game/Traits/Crate.cs +++ b/OpenRa.Game/Traits/Crate.cs @@ -38,7 +38,7 @@ namespace OpenRa.Traits public Crate(Actor self) { this.self = self; - self.World.UnitInfluence.Add(self, this); + self.World.WorldActor.traits.Get().Add(self, this); } public void OnCrush(Actor crusher) diff --git a/OpenRa.Game/Traits/Mobile.cs b/OpenRa.Game/Traits/Mobile.cs index 0685158677..54615f799c 100644 --- a/OpenRa.Game/Traits/Mobile.cs +++ b/OpenRa.Game/Traits/Mobile.cs @@ -19,7 +19,7 @@ namespace OpenRa.Traits public int2 fromCell { get { return __fromCell; } - set { self.World.UnitInfluence.Remove(self, this); __fromCell = value; self.World.UnitInfluence.Add(self, this); } + set { self.World.WorldActor.traits.Get().Remove(self, this); __fromCell = value; self.World.WorldActor.traits.Get().Add(self, this); } } public int2 toCell { @@ -28,11 +28,11 @@ namespace OpenRa.Traits { if (self.Location != value) { - self.World.UnitInfluence.Remove(self, this); + self.World.WorldActor.traits.Get().Remove(self, this); self.Location = value; self.Owner.Shroud.Explore(self); } - self.World.UnitInfluence.Add(self, this); + self.World.WorldActor.traits.Get().Add(self, this); } } @@ -40,7 +40,7 @@ namespace OpenRa.Traits { this.self = self; __fromCell = toCell; - self.World.UnitInfluence.Add(self, this); + self.World.WorldActor.traits.Get().Add(self, this); } public void TeleportTo(Actor self, int2 xy) @@ -91,10 +91,10 @@ namespace OpenRa.Traits public bool CanEnterCell(int2 a) { - if (!self.World.BuildingInfluence.CanMoveHere(a)) return false; + if (!self.World.WorldActor.traits.Get().CanMoveHere(a)) return false; var crushable = true; - foreach (Actor actor in self.World.UnitInfluence.GetUnitsAt(a)) + foreach (Actor actor in self.World.WorldActor.traits.Get().GetUnitsAt(a)) { if (actor == self) continue; diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs index ecaecaf12c..a188e7ffec 100755 --- a/OpenRa.Game/Traits/Production.cs +++ b/OpenRa.Game/Traits/Production.cs @@ -32,7 +32,7 @@ namespace OpenRa.Traits public bool Produce( Actor self, ActorInfo producee ) { var location = CreationLocation( self, producee ); - if( location == null || self.World.UnitInfluence.GetUnitsAt( location.Value ).Any() ) + if( location == null || self.World.WorldActor.traits.Get().GetUnitsAt( location.Value ).Any() ) return false; var newUnit = self.World.CreateActor( producee.Name, location.Value, self.Owner ); diff --git a/OpenRa.Game/Traits/RenderBuildingWarFactory.cs b/OpenRa.Game/Traits/RenderBuildingWarFactory.cs index 0270bc73e3..67756fda8b 100644 --- a/OpenRa.Game/Traits/RenderBuildingWarFactory.cs +++ b/OpenRa.Game/Traits/RenderBuildingWarFactory.cs @@ -34,7 +34,7 @@ namespace OpenRa.Traits public void Tick(Actor self) { var b = self.GetBounds(false); - if (isOpen && !self.World.UnitInfluence.GetUnitsAt(((1/24f) * self.CenterLocation).ToInt2()).Any()) + if (isOpen && !self.World.WorldActor.traits.Get().GetUnitsAt(((1/24f) * self.CenterLocation).ToInt2()).Any()) { isOpen = false; roof.PlayBackwardsThen(GetPrefix(self) + "build-top", () => roof.Play(GetPrefix(self) + "idle-top")); diff --git a/OpenRa.Game/UnitInfluenceMap.cs b/OpenRa.Game/Traits/UnitInfluence.cs old mode 100644 new mode 100755 similarity index 74% rename from OpenRa.Game/UnitInfluenceMap.cs rename to OpenRa.Game/Traits/UnitInfluence.cs index 114523f091..f119050985 --- a/OpenRa.Game/UnitInfluenceMap.cs +++ b/OpenRa.Game/Traits/UnitInfluence.cs @@ -1,33 +1,36 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using OpenRa.Traits; +using System.Text; +using System.Diagnostics; -namespace OpenRa +namespace OpenRa.Traits { - public class UnitInfluenceMap + public class UnitInfluenceInfo : ITraitInfo + { + public object Create( Actor self ) { return new UnitInfluence( self ); } + } + + public class UnitInfluence : ITick { - readonly World world; List[,] influence = new List[128, 128]; readonly int2 searchDistance = new int2(2,2); - public UnitInfluenceMap( World world ) + public UnitInfluence( Actor self ) { - this.world = world; for (int i = 0; i < 128; i++) for (int j = 0; j < 128; j++) influence[ i, j ] = new List(); - world.ActorRemoved += a => Remove( a, a.traits.GetOrDefault() ); + self.World.ActorRemoved += a => Remove( a, a.traits.GetOrDefault() ); } - public void Tick() + public void Tick( Actor self ) { // Does this belong here? NO, but it's your mess. // Get the crushable actors - foreach (var a in world.Actors.Where(b => b.traits.Contains())) + foreach (var a in self.World.Actors.Where(b => b.traits.Contains())) { // Are there any units in the same cell that can crush this? foreach( var ios in a.traits.WithInterface() ) @@ -35,7 +38,7 @@ namespace OpenRa { // There should only be one (counterexample: An infantry and a tank try to pick up a crate at the same time.) // If there is more than one, do action on the first crusher - var crusher = GetUnitsAt(cell).Where(b => a != b && world.IsActorCrushableByActor(a, b)).FirstOrDefault(); + var crusher = GetUnitsAt(cell).Where(b => a != b && self.World.IsActorCrushableByActor(a, b)).FirstOrDefault(); if (crusher != null) { Log.Write("{0} crushes {1}", crusher.Info.Name, a.Info.Name); @@ -45,11 +48,11 @@ namespace OpenRa } } } - SanityCheck(); + SanityCheck( self ); } [Conditional( "SANITY_CHECKS" )] - void SanityCheck() + void SanityCheck( Actor self ) { for( int y = 0 ; y < 128 ; y++ ) for( int x = 0 ; x < 128 ; x++ ) @@ -58,7 +61,7 @@ namespace OpenRa if (!a.traits.Get().OccupiedCells().Contains( new int2( x, y ) ) ) throw new InvalidOperationException( "UIM: Sanity check failed A" ); - foreach( Actor a in world.Actors ) + foreach( Actor a in self.World.Actors ) foreach( var ios in a.traits.WithInterface() ) foreach( var cell in ios.OccupiedCells() ) if (!influence[cell.X, cell.Y].Contains(a)) diff --git a/OpenRa.Game/UiOverlay.cs b/OpenRa.Game/UiOverlay.cs index 555ab223b7..cf6d7cab49 100644 --- a/OpenRa.Game/UiOverlay.cs +++ b/OpenRa.Game/UiOverlay.cs @@ -39,7 +39,7 @@ namespace OpenRa if (ShowUnitDebug) for (var j = 0; j < 128; j++) for (var i = 0; i < 128; i++) - if (world.UnitInfluence.GetUnitsAt(new int2(i, j)).Any()) + if (world.WorldActor.traits.Get().GetUnitsAt(new int2(i, j)).Any()) spriteRenderer.DrawSprite(unitDebug, Game.CellSize * new float2(i, j), 0); } diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index c3fb15b429..f57fff653d 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -33,8 +33,7 @@ namespace OpenRa } } - public readonly BuildingInfluenceMap BuildingInfluence; - public readonly UnitInfluenceMap UnitInfluence; + public readonly Actor WorldActor; public readonly PathFinder PathFinder; @@ -60,16 +59,12 @@ namespace OpenRa SpriteSheetBuilder.Initialize( Map ); Timer.Time( "Tileset: {0}" ); - BuildingInfluence = new BuildingInfluenceMap( this ); - UnitInfluence = new UnitInfluenceMap( this ); - Timer.Time( "BIM/UIM: {0}" ); - oreFrequency = (int)(Rules.General.GrowthRate * 60 * 25); oreTicks = oreFrequency; Map.InitOreDensity(); Timer.Time( "Ore: {0}" ); - CreateActor("World", new int2(int.MaxValue, int.MaxValue), null); + WorldActor = CreateActor("World", new int2(int.MaxValue, int.MaxValue), null); for (int i = 0; i < 8; i++) players[i] = new Player(this, i, Game.LobbyInfo.Clients.FirstOrDefault(a => a.Index == i)); @@ -133,8 +128,6 @@ namespace OpenRa frameEndActions = new List>(); foreach (var a in acts) a(this); - UnitInfluence.Tick(); - Minimap.Update(); foreach (var player in players.Values) player.Tick(); diff --git a/OpenRa.Game/WorldUtils.cs b/OpenRa.Game/WorldUtils.cs index 83f126fad1..46ad76a93a 100755 --- a/OpenRa.Game/WorldUtils.cs +++ b/OpenRa.Game/WorldUtils.cs @@ -17,8 +17,8 @@ namespace OpenRa public static bool IsCellBuildable(this World world, int2 a, UnitMovementType umt, Actor toIgnore) { - if (world.BuildingInfluence.GetBuildingAt(a) != null) return false; - if (world.UnitInfluence.GetUnitsAt(a).Any(b => b != toIgnore)) return false; + if (world.WorldActor.traits.Get().GetBuildingAt(a) != null) return false; + if (world.WorldActor.traits.Get().GetUnitsAt(a).Any(b => b != toIgnore)) return false; return world.Map.IsInMap(a.X, a.Y) && TerrainCosts.Cost(umt, @@ -130,7 +130,7 @@ namespace OpenRa { for( int x = scanStart.X ; x < scanEnd.X ; x++ ) { - var at = world.BuildingInfluence.GetBuildingAt( new int2( x, y ) ); + var at = world.WorldActor.traits.Get().GetBuildingAt( new int2( x, y ) ); if( at != null && at.Owner == p ) nearnessCandidates.Add( new int2( x, y ) ); } diff --git a/OpenRa.Mods.RA/Mine.cs b/OpenRa.Mods.RA/Mine.cs index b205e9e1c3..2525bd07a9 100644 --- a/OpenRa.Mods.RA/Mine.cs +++ b/OpenRa.Mods.RA/Mine.cs @@ -21,7 +21,7 @@ namespace OpenRa.Mods.RA public Mine(Actor self) { this.self = self; - self.World.UnitInfluence.Add(self, this); + self.World.WorldActor.traits.Get().Add(self, this); } public void OnCrush(Actor crusher) diff --git a/OpenRa.Mods.RA/Minelayer.cs b/OpenRa.Mods.RA/Minelayer.cs index e3419fecd5..35f6bdabef 100644 --- a/OpenRa.Mods.RA/Minelayer.cs +++ b/OpenRa.Mods.RA/Minelayer.cs @@ -18,7 +18,7 @@ namespace OpenRa.Mods.RA return null; // Ensure that the cell is empty except for the minelayer - if (self.World.UnitInfluence.GetUnitsAt(xy).Any(a => a != self)) + if (self.World.WorldActor.traits.Get().GetUnitsAt(xy).Any(a => a != self)) return null; if (mi.Button == MouseButton.Right && underCursor == self) diff --git a/mods/ra/merge-rules.yaml b/mods/ra/merge-rules.yaml index 839ce8d8bd..1d03e703ad 100644 --- a/mods/ra/merge-rules.yaml +++ b/mods/ra/merge-rules.yaml @@ -68,6 +68,8 @@ World: WaterPaletteRotation: ChronoshiftPaletteEffect: LightPaletteRotator: + BuildingInfluence: + UnitInfluence: MGG: GeneratesGap: diff --git a/mods/ra/rules.yaml b/mods/ra/rules.yaml index b9baabb446..71cdb75245 100644 --- a/mods/ra/rules.yaml +++ b/mods/ra/rules.yaml @@ -69,6 +69,8 @@ World: WaterPaletteRotation: ChronoshiftPaletteEffect: LightPaletteRotator: + BuildingInfluence: + UnitInfluence: MGG: GeneratesGap: