use UIM (was BIM) to determine what cells a building blocks
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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,13 +40,12 @@ 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 ) )
|
||||
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);
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user