Make Attack use ChildActivities

This commit is contained in:
tovl
2019-02-16 19:56:28 +01:00
committed by Oliver Brakmann
parent 5ec47b47af
commit 6f213dddec
3 changed files with 32 additions and 58 deletions

View File

@@ -39,8 +39,6 @@ namespace OpenRA.Mods.Common.Activities
WDist minRange; WDist minRange;
WDist maxRange; WDist maxRange;
Activity turnActivity;
Activity moveActivity;
AttackStatus attackStatus = AttackStatus.UnableToAttack; AttackStatus attackStatus = AttackStatus.UnableToAttack;
public Attack(Actor self, Target target, bool allowMovement, bool forceAttack) public Attack(Actor self, Target target, bool allowMovement, bool forceAttack)
@@ -73,6 +71,12 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (ChildActivity != null)
{
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
return this;
}
if (IsCanceling) if (IsCanceling)
return NextActivity; return NextActivity;
@@ -114,12 +118,10 @@ namespace OpenRA.Mods.Common.Activities
// Move towards the last known position // Move towards the last known position
wasMovingWithinRange = true; wasMovingWithinRange = true;
return ActivityUtils.SequenceActivities(self, QueueChild(self, move.MoveWithinRange(target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red), true);
move.MoveWithinRange(target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red), return this;
this);
} }
turnActivity = moveActivity = null;
attackStatus = AttackStatus.UnableToAttack; attackStatus = AttackStatus.UnableToAttack;
foreach (var attack in attackTraits.Where(x => !x.IsTraitDisabled)) foreach (var attack in attackTraits.Where(x => !x.IsTraitDisabled))
@@ -128,26 +130,17 @@ namespace OpenRA.Mods.Common.Activities
attack.IsAiming = status == AttackStatus.Attacking || status == AttackStatus.NeedsToTurn; attack.IsAiming = status == AttackStatus.Attacking || status == AttackStatus.NeedsToTurn;
} }
if (attackStatus.HasFlag(AttackStatus.Attacking))
return this;
if (attackStatus.HasFlag(AttackStatus.NeedsToTurn))
return turnActivity;
if (attackStatus.HasFlag(AttackStatus.NeedsToMove)) if (attackStatus.HasFlag(AttackStatus.NeedsToMove))
{
wasMovingWithinRange = true; wasMovingWithinRange = true;
return moveActivity;
} if (attackStatus >= AttackStatus.NeedsToTurn)
return this;
return NextActivity; return NextActivity;
} }
protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack) protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack)
{ {
if (IsCanceling)
return AttackStatus.UnableToAttack;
if (!target.IsValidFor(self)) if (!target.IsValidFor(self))
return AttackStatus.UnableToAttack; return AttackStatus.UnableToAttack;
@@ -168,10 +161,7 @@ namespace OpenRA.Mods.Common.Activities
var sightRange = rs != null ? rs.Range : WDist.FromCells(2); var sightRange = rs != null ? rs.Range : WDist.FromCells(2);
attackStatus |= AttackStatus.NeedsToMove; attackStatus |= AttackStatus.NeedsToMove;
moveActivity = ActivityUtils.SequenceActivities(self, QueueChild(self, move.MoveWithinRange(target, sightRange, target.CenterPosition, Color.Red), true);
move.MoveWithinRange(target, sightRange, target.CenterPosition, Color.Red),
this);
return AttackStatus.NeedsToMove; return AttackStatus.NeedsToMove;
} }
@@ -196,10 +186,7 @@ namespace OpenRA.Mods.Common.Activities
attackStatus |= AttackStatus.NeedsToMove; attackStatus |= AttackStatus.NeedsToMove;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
moveActivity = ActivityUtils.SequenceActivities(self, QueueChild(self, move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red), true);
move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red),
this);
return AttackStatus.NeedsToMove; return AttackStatus.NeedsToMove;
} }
@@ -208,13 +195,12 @@ namespace OpenRA.Mods.Common.Activities
if (!Util.FacingWithinTolerance(facing.Facing, desiredFacing, ((AttackFrontalInfo)attack.Info).FacingTolerance)) if (!Util.FacingWithinTolerance(facing.Facing, desiredFacing, ((AttackFrontalInfo)attack.Info).FacingTolerance))
{ {
attackStatus |= AttackStatus.NeedsToTurn; attackStatus |= AttackStatus.NeedsToTurn;
turnActivity = ActivityUtils.SequenceActivities(self, new Turn(self, desiredFacing), this); QueueChild(self, new Turn(self, desiredFacing), true);
return AttackStatus.NeedsToTurn; return AttackStatus.NeedsToTurn;
} }
attackStatus |= AttackStatus.Attacking; attackStatus |= AttackStatus.Attacking;
attack.DoAttack(self, target, armaments); attack.DoAttack(self, target, armaments);
return AttackStatus.Attacking; return AttackStatus.Attacking;
} }
} }

View File

@@ -40,8 +40,6 @@ namespace OpenRA.Mods.Common.Activities
Target lastVisibleTarget; Target lastVisibleTarget;
protected CPos lastVisibleTargetLocation; protected CPos lastVisibleTargetLocation;
bool useLastVisibleTarget; bool useLastVisibleTarget;
Activity inner;
bool repath; bool repath;
public MoveAdjacentTo(Actor self, Target target, WPos? initialTargetPosition = null, Color? targetLineColor = null) public MoveAdjacentTo(Actor self, Target target, WPos? initialTargetPosition = null, Color? targetLineColor = null)
@@ -69,7 +67,7 @@ namespace OpenRA.Mods.Common.Activities
repath = true; repath = true;
} }
protected virtual bool ShouldStop(Actor self, CPos oldTargetPosition) protected virtual bool ShouldStop(Actor self)
{ {
return false; return false;
} }
@@ -95,23 +93,21 @@ namespace OpenRA.Mods.Common.Activities
lastVisibleTargetLocation = self.World.Map.CellContaining(target.CenterPosition); lastVisibleTargetLocation = self.World.Map.CellContaining(target.CenterPosition);
} }
// Target is equivalent to checkTarget variable in other activities
// value is either lastVisibleTarget or target based on visibility and validity
var targetIsValid = Target.IsValidFor(self);
var oldUseLastVisibleTarget = useLastVisibleTarget; var oldUseLastVisibleTarget = useLastVisibleTarget;
useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); useLastVisibleTarget = targetIsHiddenActor || !targetIsValid;
// Update target lines if required // Update target lines if required
if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue) if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue)
self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false); self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false);
// Target is hidden or dead, and we don't have a fallback position to move towards // Target is hidden or dead, and we don't have a fallback position to move towards
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) var noTarget = useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self);
return NextActivity;
// Target is equivalent to checkTarget variable in other activities
// value is either lastVisibleTarget or target based on visibility and validity
var targetIsValid = Target.IsValidFor(self);
// Inner move order has completed. // Inner move order has completed.
if (inner == null) if (ChildActivity == null)
{ {
// We are done here if the order was cancelled for any // We are done here if the order was cancelled for any
// reason except the target moving. // reason except the target moving.
@@ -119,24 +115,24 @@ namespace OpenRA.Mods.Common.Activities
return NextActivity; return NextActivity;
// Target has moved, and MoveAdjacentTo is still valid. // Target has moved, and MoveAdjacentTo is still valid.
inner = Mobile.MoveTo(() => CalculatePathToTarget(self)); ChildActivity = Mobile.MoveTo(() => CalculatePathToTarget(self));
repath = false; repath = false;
} }
// Cancel the current path if the activity asks to stop, or asks to repath // Cancel the current path if the activity asks to stop, or asks to repath
// The repath happens once the move activity stops in the next cell // The repath happens once the move activity stops in the next cell
var shouldStop = ShouldStop(self, oldTargetLocation); var shouldStop = ShouldStop(self);
var shouldRepath = targetIsValid && !repath && ShouldRepath(self, oldTargetLocation); var shouldRepath = targetIsValid && !repath && ShouldRepath(self, oldTargetLocation);
if (shouldStop || shouldRepath) if (shouldStop || shouldRepath || noTarget)
{ {
if (inner != null) if (ChildActivity != null)
inner.Cancel(self); ChildActivity.Cancel(self);
repath = shouldRepath; repath = shouldRepath;
} }
// Ticks the inner move activity to actually move the actor. // Ticks the inner move activity to actually move the actor.
inner = ActivityUtils.RunActivity(self, inner); ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
return this; return this;
} }
@@ -161,18 +157,10 @@ namespace OpenRA.Mods.Common.Activities
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)
{ {
if (inner != null) if (ChildActivity != null)
return inner.GetTargets(self); return ChildActivity.GetTargets(self);
return Target.None; return Target.None;
} }
public override void Cancel(Actor self, bool keepQueue = false)
{
if (!IsCanceling && inner != null)
inner.Cancel(self);
base.Cancel(self);
}
} }
} }

View File

@@ -29,16 +29,16 @@ namespace OpenRA.Mods.Common.Activities
this.maxRange = maxRange; this.maxRange = maxRange;
} }
protected override bool ShouldStop(Actor self, CPos oldTargetPosition) protected override bool ShouldStop(Actor self)
{ {
// We are now in range. Don't move any further! // We are now in range. Don't move any further!
// HACK: This works around the pathfinder not returning the shortest path // HACK: This works around the pathfinder not returning the shortest path
return AtCorrectRange(self.CenterPosition) && Mobile.CanInteractWithGroundLayer(self); return AtCorrectRange(self.CenterPosition) && Mobile.CanInteractWithGroundLayer(self);
} }
protected override bool ShouldRepath(Actor self, CPos oldTargetPosition) protected override bool ShouldRepath(Actor self, CPos targetLocation)
{ {
return lastVisibleTargetLocation != oldTargetPosition && (!AtCorrectRange(self.CenterPosition) return lastVisibleTargetLocation != targetLocation && (!AtCorrectRange(self.CenterPosition)
|| !Mobile.CanInteractWithGroundLayer(self)); || !Mobile.CanInteractWithGroundLayer(self));
} }