Make locomotor cache and nudging logic aware of mobile trait status.

This commit is contained in:
tovl
2019-09-16 22:48:40 +02:00
committed by teinarss
parent 7e5b1abc0e
commit c4d1468f62
3 changed files with 45 additions and 12 deletions

View File

@@ -331,8 +331,7 @@ namespace OpenRA.Mods.Common.Activities
else else
{ {
var cellInfo = notStupidCells var cellInfo = notStupidCells
.SelectMany(c => self.World.ActorMap.GetActorsAt(c) .SelectMany(c => self.World.ActorMap.GetActorsAt(c).Where(Mobile.Ismovable),
.Where(a => a.IsIdle && a.Info.HasTraitInfo<MobileInfo>()),
(c, a) => new { Cell = c, Actor = a }) (c, a) => new { Cell = c, Actor = a })
.RandomOrDefault(self.World.SharedRandom); .RandomOrDefault(self.World.SharedRandom);
if (cellInfo != null) if (cellInfo != null)

View File

@@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.Traits
INotifyMoving[] notifyMoving; INotifyMoving[] notifyMoving;
INotifyFinishedMoving[] notifyFinishedMoving; INotifyFinishedMoving[] notifyFinishedMoving;
IWrapMove[] moveWrappers; IWrapMove[] moveWrappers;
bool requireForceMove; public bool RequireForceMove;
public bool TurnToMove; public bool TurnToMove;
public bool IsBlocking { get; private set; } public bool IsBlocking { get; private set; }
@@ -308,11 +308,31 @@ namespace OpenRA.Mods.Common.Traits
self.World.RemoveFromMaps(self, this); self.World.RemoveFromMaps(self, this);
} }
protected override void TraitEnabled(Actor self)
{
self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace);
}
protected override void TraitDisabled(Actor self)
{
self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace);
}
protected override void TraitResumed(Actor self)
{
self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace);
}
protected override void TraitPaused(Actor self)
{
self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace);
}
#region Local misc stuff #region Local misc stuff
public void Nudge(Actor self, Actor nudger, bool force) public void Nudge(Actor self, Actor nudger, bool force)
{ {
if (IsTraitDisabled || IsTraitPaused || requireForceMove) if (IsTraitDisabled || IsTraitPaused || RequireForceMove)
return; return;
// Pick an adjacent available cell. // Pick an adjacent available cell.
@@ -342,8 +362,7 @@ namespace OpenRA.Mods.Common.Traits
else else
{ {
var cellInfo = notStupidCells var cellInfo = notStupidCells
.SelectMany(c => self.World.ActorMap.GetActorsAt(c) .SelectMany(c => self.World.ActorMap.GetActorsAt(c).Where(Ismovable),
.Where(a => a.IsIdle && a.Info.HasTraitInfo<MobileInfo>()),
(c, a) => new { Cell = c, Actor = a }) (c, a) => new { Cell = c, Actor = a })
.RandomOrDefault(self.World.SharedRandom); .RandomOrDefault(self.World.SharedRandom);
@@ -364,6 +383,18 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public static bool Ismovable(Actor otherActor)
{
if (!otherActor.IsIdle)
return false;
var mobile = otherActor.TraitOrDefault<Mobile>();
if (mobile == null || mobile.IsTraitDisabled || mobile.IsTraitPaused || mobile.RequireForceMove)
return false;
return true;
}
public bool IsLeaving() public bool IsLeaving()
{ {
if (CurrentMovementTypes.HasFlag(MovementType.Horizontal)) if (CurrentMovementTypes.HasFlag(MovementType.Horizontal))
@@ -844,7 +875,7 @@ namespace OpenRA.Mods.Common.Traits
void RequireForceMoveConditionChanged(Actor self, IReadOnlyDictionary<string, int> conditions) void RequireForceMoveConditionChanged(Actor self, IReadOnlyDictionary<string, int> conditions)
{ {
requireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions); RequireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions);
} }
IEnumerable<IOrderTargeter> IIssueOrder.Orders IEnumerable<IOrderTargeter> IIssueOrder.Orders
@@ -940,7 +971,7 @@ namespace OpenRA.Mods.Common.Traits
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor) public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
{ {
if (rejectMove || target.Type != TargetType.Terrain || (mobile.requireForceMove && !modifiers.HasModifier(TargetModifiers.ForceMove))) if (rejectMove || target.Type != TargetType.Terrain || (mobile.RequireForceMove && !modifiers.HasModifier(TargetModifiers.ForceMove)))
return false; return false;
var location = self.World.Map.CellContaining(target.CenterPosition); var location = self.World.Map.CellContaining(target.CenterPosition);

View File

@@ -331,9 +331,12 @@ namespace OpenRA.Mods.Common.Traits
// If the check allows: We are not blocked by units that we can force to move out of the way. // If the check allows: We are not blocked by units that we can force to move out of the way.
if (check <= BlockedByActor.Immovable && cellFlag.HasCellFlag(CellFlag.HasMovableActor) && if (check <= BlockedByActor.Immovable && cellFlag.HasCellFlag(CellFlag.HasMovableActor) &&
self.Owner.Stances[otherActor.Owner] == Stance.Ally && self.Owner.Stances[otherActor.Owner] == Stance.Ally)
otherActor.TraitOrDefault<IMove>() != null) {
var mobile = otherActor.TraitOrDefault<Mobile>();
if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.RequireForceMove)
return false; return false;
}
// If the check allows: we are not blocked by moving units. // If the check allows: we are not blocked by moving units.
if (check <= BlockedByActor.Stationary && cellFlag.HasCellFlag(CellFlag.HasMovingActor) && if (check <= BlockedByActor.Stationary && cellFlag.HasCellFlag(CellFlag.HasMovingActor) &&
@@ -484,7 +487,7 @@ namespace OpenRA.Mods.Common.Traits
var crushables = actor.TraitsImplementing<ICrushable>(); var crushables = actor.TraitsImplementing<ICrushable>();
var mobile = actor.OccupiesSpace as Mobile; var mobile = actor.OccupiesSpace as Mobile;
var isMovable = mobile != null; var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.RequireForceMove;
var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal); var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal);
if (crushables.Any()) if (crushables.Any())