New crush code, now with less bs
This commit is contained in:
@@ -35,7 +35,6 @@ namespace OpenRA
|
||||
public PathFinder( World world )
|
||||
{
|
||||
this.world = world;
|
||||
var map = world.Map;
|
||||
}
|
||||
|
||||
class CachedPath
|
||||
|
||||
@@ -306,6 +306,7 @@ namespace OpenRA.Traits.Activities
|
||||
{
|
||||
self.CenterLocation = Util.CenterOfCell( mobile.toCell );
|
||||
mobile.fromCell = mobile.toCell;
|
||||
mobile.FinishedMoving(self);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
public readonly TerrainType[] TerrainTypes;
|
||||
public readonly float[] TerrainSpeeds;
|
||||
public readonly string[] Crushes;
|
||||
public readonly int WaitAverage = 60;
|
||||
public readonly int WaitSpread = 20;
|
||||
|
||||
@@ -39,6 +40,7 @@ namespace OpenRA.Traits
|
||||
public class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMove
|
||||
{
|
||||
public readonly Actor self;
|
||||
public readonly MobileInfo Info;
|
||||
public readonly Dictionary<TerrainType,float> TerrainCost;
|
||||
public readonly Dictionary<TerrainType,float> TerrainSpeed;
|
||||
|
||||
@@ -67,6 +69,7 @@ namespace OpenRA.Traits
|
||||
public Mobile(ActorInitializer init, MobileInfo info)
|
||||
{
|
||||
this.self = init.self;
|
||||
this.Info = info;
|
||||
this.__fromCell = this.__toCell = init.location;
|
||||
AddInfluence();
|
||||
|
||||
@@ -137,9 +140,19 @@ namespace OpenRA.Traits
|
||||
|
||||
public virtual bool CanEnterCell(int2 cell, Actor ignoreActor, bool checkTransientActors)
|
||||
{
|
||||
if (!self.World.WorldActor.traits.Get<BuildingInfluence>().CanMoveHere(cell, ignoreActor))
|
||||
return false;
|
||||
// Check for buildings
|
||||
var building = self.World.WorldActor.traits.Get<BuildingInfluence>().GetBuildingBlocking(cell);
|
||||
if (building != null && building != ignoreActor)
|
||||
{
|
||||
var crushable = building.traits.WithInterface<ICrushable>();
|
||||
if (crushable.Count() == 0)
|
||||
return false;
|
||||
|
||||
if (!crushable.Any(b => b.CrushClasses.Intersect(Info.Crushes).Any()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check mobile actors
|
||||
if (checkTransientActors)
|
||||
{
|
||||
var canShare = self.traits.Contains<SharesCell>();
|
||||
@@ -150,16 +163,27 @@ namespace OpenRA.Traits
|
||||
// only allow 5 in a cell
|
||||
if (shareable.Count() >= 5)
|
||||
return false;
|
||||
|
||||
|
||||
// We can enter a cell with nonshareable units if we can crush all of them
|
||||
if (nonshareable.Any(
|
||||
a => !self.World.IsActorCrushableByActor(a, self)))
|
||||
if (nonshareable.Any(a => !(a.traits.Contains<ICrushable>() &&
|
||||
a.traits.WithInterface<ICrushable>().Any(b => b.CrushClasses.Intersect(Info.Crushes).Any()))))
|
||||
return false;
|
||||
}
|
||||
|
||||
return MovementCostForCell(self, cell) < float.PositiveInfinity;
|
||||
}
|
||||
|
||||
public virtual void FinishedMoving(Actor self)
|
||||
{
|
||||
var crushable = self.World.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(self.Location).Where(a => a != self && a.traits.Contains<ICrushable>());
|
||||
foreach (var a in crushable)
|
||||
{
|
||||
var crushActions = a.traits.WithInterface<ICrushable>().Where(b => b.CrushClasses.Intersect(Info.Crushes).Any());
|
||||
foreach (var b in crushActions)
|
||||
b.OnCrush(self);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual float MovementCostForCell(Actor self, int2 cell)
|
||||
{
|
||||
if (!self.World.Map.IsInMap(cell.X,cell.Y))
|
||||
|
||||
@@ -115,8 +115,7 @@ namespace OpenRA.Traits
|
||||
public interface ICrushable
|
||||
{
|
||||
void OnCrush(Actor crusher);
|
||||
bool IsCrushableBy(UnitMovementType umt, Player player);
|
||||
bool IsPathableCrush(UnitMovementType umt, Player player);
|
||||
IEnumerable<string> CrushClasses { get; }
|
||||
}
|
||||
|
||||
public struct Renderable
|
||||
|
||||
@@ -65,6 +65,12 @@ 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)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace OpenRA.Traits
|
||||
|
||||
public HazardLayer( World world )
|
||||
{
|
||||
map = world.Map;
|
||||
hazards = new List<Pair<Actor, Hazard>>[world.Map.MapSize.X, world.Map.MapSize.Y];
|
||||
for (int i = 0; i < world.Map.MapSize.X; i++)
|
||||
for (int j = 0; j < world.Map.MapSize.Y; j++)
|
||||
|
||||
@@ -49,27 +49,6 @@ namespace OpenRA.Traits
|
||||
|
||||
public void Tick( Actor self )
|
||||
{
|
||||
// Does this belong here? NO, but it's your mess.
|
||||
|
||||
// Get the crushable actors
|
||||
foreach (var aa in self.World.Queries.WithTrait<ICrushable>())
|
||||
{
|
||||
var a = aa.Actor;
|
||||
// Are there any units in the same cell that can crush this?
|
||||
foreach( var ios in a.traits.WithInterface<IOccupySpace>() )
|
||||
foreach( var cell in ios.OccupiedCells() )
|
||||
{
|
||||
// There should only be one (counterexample: An infantry and a tank try to pick up a crate at the same time.)
|
||||
// If there is more than one, do action on the first crusher
|
||||
var crusher = GetUnitsAt(cell).Where(b => a != b && self.World.IsActorCrushableByActor(a, b)).FirstOrDefault();
|
||||
if (crusher != null)
|
||||
{
|
||||
// Apply the crush action
|
||||
foreach (var crush in a.traits.WithInterface<ICrushable>())
|
||||
crush.OnCrush(crusher);
|
||||
}
|
||||
}
|
||||
}
|
||||
SanityCheck( self );
|
||||
}
|
||||
|
||||
|
||||
@@ -49,29 +49,6 @@ namespace OpenRA
|
||||
.Buildable;
|
||||
}
|
||||
|
||||
public static bool IsActorCrushableByActor(this World world, Actor a, Actor b)
|
||||
{
|
||||
return false;
|
||||
//var movement = b.traits.GetOrDefault<IMove>();
|
||||
//return movement != null && world.IsActorCrushableByMovementType(a, movement.GetMovementType());
|
||||
}
|
||||
|
||||
// Todo: Reenable crushing based on actor, not umt
|
||||
/*
|
||||
public static bool IsActorPathableToCrush(this World world, Actor a, UnitMovementType umt)
|
||||
{
|
||||
return a != null &&
|
||||
a.traits.WithInterface<ICrushable>()
|
||||
.Any(c => c.IsPathableCrush(umt, a.Owner));
|
||||
}
|
||||
|
||||
public static bool IsActorCrushableByMovementType(this World world, Actor a, UnitMovementType umt)
|
||||
{
|
||||
return a != null &&
|
||||
a.traits.WithInterface<ICrushable>()
|
||||
.Any(c => c.IsCrushableBy(umt, a.Owner));
|
||||
}
|
||||
*/
|
||||
public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation)
|
||||
{
|
||||
var loc = mouseLocation + Game.viewport.Location;
|
||||
|
||||
Reference in New Issue
Block a user