use UIM (was BIM) to determine what cells a building blocks

This commit is contained in:
Bob
2010-11-03 16:42:53 +13:00
committed by Chris Forbes
parent f5b8b18d86
commit c3fc7b98f3
6 changed files with 23 additions and 60 deletions

View File

@@ -53,9 +53,11 @@ namespace OpenRA.Traits
{ {
this.self = init.self; this.self = init.self;
this.topLeft = init.Get<LocationInit,int2>(); this.topLeft = init.Get<LocationInit,int2>();
Info = self.Info.Traits.Get<BuildingInfo>(); this.Info = self.Info.Traits.Get<BuildingInfo>();
this.PlayerPower = init.self.Owner.PlayerActor.Trait<PowerManager>();
PlayerPower = init.self.Owner.PlayerActor.Trait<PowerManager>(); var uim = init.world.WorldActor.Trait<UnitInfluence>();
uim.Add( init.self, this );
} }
public int GetPowerUsage() public int GetPowerUsage()

View File

@@ -10,6 +10,7 @@
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.GameRules; using OpenRA.GameRules;
using System;
namespace OpenRA.Traits namespace OpenRA.Traits
{ {
@@ -20,7 +21,6 @@ namespace OpenRA.Traits
public class BuildingInfluence public class BuildingInfluence
{ {
bool[,] blocked;
Actor[,] influence; Actor[,] influence;
Map map; Map map;
@@ -28,7 +28,6 @@ namespace OpenRA.Traits
{ {
map = world.Map; map = world.Map;
blocked = new bool[map.MapSize.X, map.MapSize.Y];
influence = new Actor[map.MapSize.X, map.MapSize.Y]; influence = new Actor[map.MapSize.X, map.MapSize.Y];
world.ActorAdded += world.ActorAdded +=
@@ -41,13 +40,12 @@ namespace OpenRA.Traits
void ChangeInfluence( Actor a, Building building, bool isAdd ) void ChangeInfluence( Actor a, Building building, bool isAdd )
{ {
foreach( var u in Footprint.UnpathableTiles( a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), 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<BuildingInfo>(), a.Location ) ) foreach( var u in Footprint.Tiles( a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), 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) public Actor GetBuildingAt(int2 cell)
@@ -55,21 +53,5 @@ namespace OpenRA.Traits
if (!map.IsInMap(cell)) return null; if (!map.IsInMap(cell)) return null;
return influence[cell.X, cell.Y]; 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);
}
}}

View File

@@ -222,39 +222,21 @@ namespace OpenRA.Mods.RA.Move
public static bool CanEnterCell( World world, MobileInfo mi, int2 cell, Actor ignoreActor, bool checkTransientActors ) public static bool CanEnterCell( World world, MobileInfo mi, int2 cell, Actor ignoreActor, bool checkTransientActors )
{ {
var bim = world.WorldActor.Trait<BuildingInfluence>();
var uim = world.WorldActor.Trait<UnitInfluence>(); var uim = world.WorldActor.Trait<UnitInfluence>();
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 ) public bool CanEnterCell( int2 cell, Actor ignoreActor, bool checkTransientActors )
{ {
var bim = self.World.WorldActor.Trait<BuildingInfluence>();
var uim = self.World.WorldActor.Trait<UnitInfluence>(); var uim = self.World.WorldActor.Trait<UnitInfluence>();
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) if (MovementCostForCell(mobileInfo, world, cell) == int.MaxValue)
return false; 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<ICrushable>();
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(); var blockingActors = uim.GetUnitsAt( cell ).Where( x => x != ignoreActor ).ToList();
if (checkTransientActors && blockingActors.Count > 0) if (checkTransientActors && blockingActors.Count > 0)
{ {

View File

@@ -27,13 +27,11 @@ namespace OpenRA.Mods.RA.Move
public bool inReverse; public bool inReverse;
MobileInfo mobileInfo; MobileInfo mobileInfo;
BuildingInfluence bim;
UnitInfluence uim; UnitInfluence uim;
public PathSearch(World world, MobileInfo mobileInfo) public PathSearch(World world, MobileInfo mobileInfo)
{ {
this.world = world; this.world = world;
bim = world.WorldActor.Trait<BuildingInfluence>();
uim = world.WorldActor.Trait<UnitInfluence>(); uim = world.WorldActor.Trait<UnitInfluence>();
cellInfo = InitCellInfo(); cellInfo = InitCellInfo();
this.mobileInfo = mobileInfo; this.mobileInfo = mobileInfo;
@@ -107,7 +105,7 @@ namespace OpenRA.Mods.RA.Move
if (costHere == int.MaxValue) if (costHere == int.MaxValue)
continue; continue;
if (!Mobile.CanEnterCell(mobileInfo, world, uim, bim, newHere, ignoreBuilding, checkForBlocked)) if (!Mobile.CanEnterCell(mobileInfo, world, uim, newHere, ignoreBuilding, checkForBlocked))
continue; continue;
if (customBlock != null && customBlock(newHere)) if (customBlock != null && customBlock(newHere))

View File

@@ -98,13 +98,12 @@ namespace OpenRA.Mods.RA
// required for 3-arg CanEnterCell // required for 3-arg CanEnterCell
//var mobile = newUnit.Trait<Mobile>(); //var mobile = newUnit.Trait<Mobile>();
var mobileInfo = producee.Traits.Get<MobileInfo>(); var mobileInfo = producee.Traits.Get<MobileInfo>();
var bim = self.World.WorldActor.Trait<BuildingInfluence>();
var uim = self.World.WorldActor.Trait<UnitInfluence>(); var uim = self.World.WorldActor.Trait<UnitInfluence>();
// Pick a spawn/exit point pair // Pick a spawn/exit point pair
// Todo: Reorder in a synced random way // Todo: Reorder in a synced random way
foreach (var s in self.Info.Traits.WithInterface<ExitInfo>()) foreach (var s in self.Info.Traits.WithInterface<ExitInfo>())
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); DoProduction(self, producee, s);
return true; return true;

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA
foreach (var s in self.Info.Traits.WithInterface<ExitInfo>()) foreach (var s in self.Info.Traits.WithInterface<ExitInfo>())
{ {
var exit = self.Location + s.ExitCell; var exit = self.Location + s.ExitCell;
if (!self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt( exit ).Any()) if (!self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt( exit ).Any( x => x != self ))
{ {
var newUnit = self.World.CreateActor( producee.Name, new TypeDictionary var newUnit = self.World.CreateActor( producee.Name, new TypeDictionary
{ {