Refactor FlyAttack to make strafing runs interruptible when target becomes invalid.
This commit is contained in:
@@ -24,7 +24,6 @@ namespace OpenRA.Mods.Common.Activities
|
||||
readonly AttackAircraft attackAircraft;
|
||||
readonly Rearmable rearmable;
|
||||
readonly bool forceAttack;
|
||||
readonly int ticksUntilTurn;
|
||||
readonly Color? targetLineColor;
|
||||
|
||||
Target target;
|
||||
@@ -35,6 +34,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
bool useLastVisibleTarget;
|
||||
bool hasTicked;
|
||||
bool returnToBase;
|
||||
int remainingTicksUntilTurn;
|
||||
|
||||
public FlyAttack(Actor self, Target target, bool forceAttack, Color? targetLineColor)
|
||||
{
|
||||
@@ -45,7 +45,6 @@ namespace OpenRA.Mods.Common.Activities
|
||||
aircraft = self.Trait<Aircraft>();
|
||||
attackAircraft = self.Trait<AttackAircraft>();
|
||||
rearmable = self.TraitOrDefault<Rearmable>();
|
||||
ticksUntilTurn = attackAircraft.Info.AttackTurnDelay;
|
||||
|
||||
// The target may become hidden between the initial order request and the first tick (e.g. if queued)
|
||||
// Moving to any position (even if quite stale) is still better than immediately giving up
|
||||
@@ -132,28 +131,33 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
var delta = attackAircraft.GetTargetPosition(pos, target) - pos;
|
||||
var desiredFacing = delta.HorizontalLengthSquared != 0 ? delta.Yaw.Facing : aircraft.Facing;
|
||||
var isAirborne = self.World.Map.DistanceAboveTerrain(pos).Length >= aircraft.Info.MinAirborneAltitude;
|
||||
|
||||
if (!isAirborne)
|
||||
QueueChild(new TakeOff(self));
|
||||
QueueChild(new TakeOff(self));
|
||||
|
||||
if (attackAircraft.Info.AttackType == AirAttackType.Strafe)
|
||||
var minimumRange = attackAircraft.Info.AttackType == AirAttackType.Strafe ? WDist.Zero : attackAircraft.GetMinimumRangeVersusTarget(target);
|
||||
|
||||
// When strafing we must move forward for a minimum number of ticks after passing the target.
|
||||
if (remainingTicksUntilTurn > 0)
|
||||
{
|
||||
if (target.IsInRange(pos, attackAircraft.GetMinimumRange()))
|
||||
QueueChild(new FlyTimed(ticksUntilTurn, self));
|
||||
Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
|
||||
remainingTicksUntilTurn--;
|
||||
}
|
||||
|
||||
QueueChild(new Fly(self, target, target.CenterPosition, Color.Red));
|
||||
QueueChild(new FlyTimed(ticksUntilTurn, self));
|
||||
}
|
||||
else
|
||||
// Move into range of the target.
|
||||
else if (!target.IsInRange(pos, lastVisibleMaximumRange) || target.IsInRange(pos, minimumRange))
|
||||
QueueChild(aircraft.MoveWithinRange(target, minimumRange, lastVisibleMaximumRange, target.CenterPosition, Color.Red));
|
||||
|
||||
// The aircraft must keep moving forward even if it is already in an ideal position.
|
||||
else if (!aircraft.Info.CanHover || attackAircraft.Info.AttackType == AirAttackType.Strafe)
|
||||
{
|
||||
var minimumRange = attackAircraft.GetMinimumRangeVersusTarget(target);
|
||||
if (!target.IsInRange(pos, lastVisibleMaximumRange) || target.IsInRange(pos, minimumRange))
|
||||
QueueChild(new Fly(self, target, minimumRange, lastVisibleMaximumRange, target.CenterPosition, Color.Red));
|
||||
else if (isAirborne) // Don't use 'else' to avoid conflict with TakeOff
|
||||
Fly.VerticalTakeOffOrLandTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude);
|
||||
Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
|
||||
remainingTicksUntilTurn = attackAircraft.Info.AttackTurnDelay;
|
||||
}
|
||||
|
||||
// Turn to face the target if required.
|
||||
else if (!attackAircraft.TargetInFiringArc(self, target, attackAircraft.Info.FacingTolerance))
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.TurnSpeed);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user