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.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()
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user