diff --git a/OpenRA.Game/Traits/Building.cs b/OpenRA.Game/Traits/Building.cs index b4a42cd6f7..bb3ca451e8 100644 --- a/OpenRA.Game/Traits/Building.cs +++ b/OpenRA.Game/Traits/Building.cs @@ -53,9 +53,11 @@ namespace OpenRA.Traits { this.self = init.self; this.topLeft = init.Get(); - Info = self.Info.Traits.Get(); - - PlayerPower = init.self.Owner.PlayerActor.Trait(); + this.Info = self.Info.Traits.Get(); + this.PlayerPower = init.self.Owner.PlayerActor.Trait(); + + var uim = init.world.WorldActor.Trait(); + uim.Add( init.self, this ); } public int GetPowerUsage() diff --git a/OpenRA.Game/Traits/World/BuildingInfluence.cs b/OpenRA.Game/Traits/World/BuildingInfluence.cs index 9085cd435b..d3868916b2 100644 --- a/OpenRA.Game/Traits/World/BuildingInfluence.cs +++ b/OpenRA.Game/Traits/World/BuildingInfluence.cs @@ -10,6 +10,7 @@ using OpenRA.FileFormats; using OpenRA.GameRules; +using System; namespace OpenRA.Traits { @@ -20,34 +21,31 @@ namespace OpenRA.Traits public class BuildingInfluence { - bool[,] blocked; Actor[,] influence; Map map; public BuildingInfluence( World world ) { map = world.Map; - - blocked = new bool[map.MapSize.X, map.MapSize.Y]; + influence = new Actor[map.MapSize.X, map.MapSize.Y]; - + world.ActorAdded += - a => { if (a.HasTrait()) + a => { if (a.HasTrait()) ChangeInfluence(a, a.Trait(), true); }; world.ActorRemoved += - a => { if (a.HasTrait()) + a => { if (a.HasTrait()) ChangeInfluence(a, a.Trait(), false); }; } void ChangeInfluence( Actor a, Building building, bool isAdd ) { - foreach( var u in Footprint.UnpathableTiles( a.Info.Name, a.Info.Traits.Get(), a.Location ) ) - if( map.IsInMap( u ) ) - blocked[ u.X, u.Y ] = isAdd; - foreach( var u in Footprint.Tiles( a.Info.Name, a.Info.Traits.Get(), a.Location ) ) - if( map.IsInMap( u ) ) - influence[ u.X, u.Y ] = isAdd ? a : null; + { + if( !map.IsInMap( u ) ) + throw new InvalidOperationException( "building outside map bounds" ); + influence[ u.X, u.Y ] = isAdd ? a : null; + } } public Actor GetBuildingAt(int2 cell) @@ -55,21 +53,5 @@ namespace OpenRA.Traits if (!map.IsInMap(cell)) return null; return influence[cell.X, cell.Y]; } - - public Actor GetBuildingBlocking(int2 cell) - { - if (!map.IsInMap(cell) || !blocked[cell.X, cell.Y]) return null; - return influence[cell.X, cell.Y]; - } - - public bool CanMoveHere(int2 cell) - { - return map.IsInMap(cell) && !blocked[cell.X, cell.Y]; - } - - public bool CanMoveHere(int2 cell, Actor toIgnore) - { - return map.IsInMap(cell) && - (!blocked[cell.X, cell.Y] || influence[cell.X, cell.Y] == toIgnore); - } - }} + } +} diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 1650ff0945..a0104ba2dc 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -222,39 +222,21 @@ namespace OpenRA.Mods.RA.Move public static bool CanEnterCell( World world, MobileInfo mi, int2 cell, Actor ignoreActor, bool checkTransientActors ) { - var bim = world.WorldActor.Trait(); var uim = world.WorldActor.Trait(); - return Mobile.CanEnterCell( mi, world, uim, bim, cell, ignoreActor, checkTransientActors ); + return Mobile.CanEnterCell( mi, world, uim, cell, ignoreActor, checkTransientActors ); } public bool CanEnterCell( int2 cell, Actor ignoreActor, bool checkTransientActors ) { - var bim = self.World.WorldActor.Trait(); var uim = self.World.WorldActor.Trait(); - return CanEnterCell( Info, self.World, uim, bim, cell, ignoreActor, checkTransientActors ); + return CanEnterCell( Info, self.World, uim, cell, ignoreActor, checkTransientActors ); } - public static bool CanEnterCell( MobileInfo mobileInfo, World world, UnitInfluence uim, BuildingInfluence bim, int2 cell, Actor ignoreActor, bool checkTransientActors ) + public static bool CanEnterCell( MobileInfo mobileInfo, World world, UnitInfluence uim, int2 cell, Actor ignoreActor, bool checkTransientActors ) { if (MovementCostForCell(mobileInfo, world, cell) == int.MaxValue) return false; - // Check for buildings - var building = bim.GetBuildingBlocking(cell); - if (building != null && building != ignoreActor) - { - if (mobileInfo.Crushes == null) - return false; - - var crushable = building.TraitsImplementing(); - if (crushable.Count() == 0) - return false; - - if (!crushable.Any(b => b.CrushClasses.Intersect(mobileInfo.Crushes).Any())) - return false; - } - - // Check mobile actors var blockingActors = uim.GetUnitsAt( cell ).Where( x => x != ignoreActor ).ToList(); if (checkTransientActors && blockingActors.Count > 0) { diff --git a/OpenRA.Mods.RA/Move/PathSearch.cs b/OpenRA.Mods.RA/Move/PathSearch.cs index 5b4e5cba2c..f65ac05a8d 100755 --- a/OpenRA.Mods.RA/Move/PathSearch.cs +++ b/OpenRA.Mods.RA/Move/PathSearch.cs @@ -27,13 +27,11 @@ namespace OpenRA.Mods.RA.Move public bool inReverse; MobileInfo mobileInfo; - BuildingInfluence bim; UnitInfluence uim; public PathSearch(World world, MobileInfo mobileInfo) { this.world = world; - bim = world.WorldActor.Trait(); uim = world.WorldActor.Trait(); cellInfo = InitCellInfo(); this.mobileInfo = mobileInfo; @@ -107,7 +105,7 @@ namespace OpenRA.Mods.RA.Move if (costHere == int.MaxValue) continue; - if (!Mobile.CanEnterCell(mobileInfo, world, uim, bim, newHere, ignoreBuilding, checkForBlocked)) + if (!Mobile.CanEnterCell(mobileInfo, world, uim, newHere, ignoreBuilding, checkForBlocked)) continue; if (customBlock != null && customBlock(newHere)) diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index 238bb2e0dc..7fa16bc9ec 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -98,13 +98,12 @@ namespace OpenRA.Mods.RA // required for 3-arg CanEnterCell //var mobile = newUnit.Trait(); var mobileInfo = producee.Traits.Get(); - var bim = self.World.WorldActor.Trait(); var uim = self.World.WorldActor.Trait(); // Pick a spawn/exit point pair // Todo: Reorder in a synced random way foreach (var s in self.Info.Traits.WithInterface()) - if( Mobile.CanEnterCell( mobileInfo, self.World, uim, bim, self.Location + s.ExitCell,self,true ) ) + if( Mobile.CanEnterCell( mobileInfo, self.World, uim, self.Location + s.ExitCell,self,true ) ) { DoProduction(self, producee, s); return true; diff --git a/OpenRA.Mods.RA/ReservableProduction.cs b/OpenRA.Mods.RA/ReservableProduction.cs index a6635ec6f8..b333cfdea4 100644 --- a/OpenRA.Mods.RA/ReservableProduction.cs +++ b/OpenRA.Mods.RA/ReservableProduction.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA foreach (var s in self.Info.Traits.WithInterface()) { var exit = self.Location + s.ExitCell; - if (!self.World.WorldActor.Trait().GetUnitsAt( exit ).Any()) + if (!self.World.WorldActor.Trait().GetUnitsAt( exit ).Any( x => x != self )) { var newUnit = self.World.CreateActor( producee.Name, new TypeDictionary {