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.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()

View File

@@ -10,6 +10,7 @@
using OpenRA.FileFormats;
using OpenRA.GameRules;
using System;
namespace OpenRA.Traits
{
@@ -20,7 +21,6 @@ namespace OpenRA.Traits
public class BuildingInfluence
{
bool[,] blocked;
Actor[,] influence;
Map map;
@@ -28,7 +28,6 @@ namespace OpenRA.Traits
{
map = world.Map;
blocked = new bool[map.MapSize.X, map.MapSize.Y];
influence = new Actor[map.MapSize.X, map.MapSize.Y];
world.ActorAdded +=
@@ -41,35 +40,18 @@ namespace OpenRA.Traits
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 ) )
if( map.IsInMap( u ) )
{
if( !map.IsInMap( u ) )
throw new InvalidOperationException( "building outside map bounds" );
influence[ u.X, u.Y ] = isAdd ? a : null;
}
}
public Actor GetBuildingAt(int2 cell)
{
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);
}
}}

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 )
{
var bim = world.WorldActor.Trait<BuildingInfluence>();
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 )
{
var bim = self.World.WorldActor.Trait<BuildingInfluence>();
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)
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();
if (checkTransientActors && blockingActors.Count > 0)
{

View File

@@ -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<BuildingInfluence>();
uim = world.WorldActor.Trait<UnitInfluence>();
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))

View File

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

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA
foreach (var s in self.Info.Traits.WithInterface<ExitInfo>())
{
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
{