Skip to content
Permalink
Browse files

Allow opportunity fire for aircraft.

  • Loading branch information...
tovl committed Mar 31, 2019
1 parent 7ef2ef1 commit 9213dde5e0a9bdbc0cf9dcd6b8c38a8d0b1736a2
@@ -63,14 +63,10 @@ public override Activity Tick(Actor self)

if (IsCanceling)
{
// Cancel the requested target, but keep firing on it while in range
attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget;
attackAircraft.RequestedTarget = Target.Invalid;
return NextActivity;
}

// Check that AttackFollow hasn't cancelled the target by modifying attack.Target
// Having both this and AttackFollow modify that field is a horrible hack.
if (hasTicked && attackAircraft.RequestedTarget.Type == TargetType.Invalid)
return NextActivity;

@@ -61,14 +61,10 @@ public override Activity Tick(Actor self)

if (IsCanceling)
{
// Cancel the requested target, but keep firing on it while in range
attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget;
attackAircraft.RequestedTarget = Target.Invalid;
return NextActivity;
}

// Check that AttackFollow hasn't cancelled the target by modifying attack.Target
// Having both this and AttackFollow modify that field is a horrible hack.
if (hasTicked && attackAircraft.RequestedTarget.Type == TargetType.Invalid)
return NextActivity;

@@ -190,10 +190,9 @@ protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack)
return AttackStatus.NeedsToMove;
}

var targetedPosition = attack.GetTargetPosition(pos, target);
var desiredFacing = (targetedPosition - pos).Yaw.Facing;
if (!Util.FacingWithinTolerance(facing.Facing, desiredFacing, ((AttackFrontalInfo)attack.Info).FacingTolerance))
if (!attack.TargetInFiringArc(self, target))
{
var desiredFacing = (attack.GetTargetPosition(pos, target) - pos).Yaw.Facing;
attackStatus |= AttackStatus.NeedsToTurn;
QueueChild(self, new Turn(self, desiredFacing), true);
return AttackStatus.NeedsToTurn;
@@ -55,7 +55,7 @@ public override Activity Tick(Actor self)

if (attack == null && autoTarget != null)
{
var target = autoTarget.ScanForTarget(self, true);
var target = autoTarget.ScanForTarget(self, true, true);
if (target.Type != TargetType.Invalid)
{
if (inner != null)
@@ -20,17 +20,6 @@ public class AttackAircraftInfo : AttackFollowInfo, Requires<AircraftInfo>
[Desc("Delay, in game ticks, before non-hovering aircraft turns to attack.")]
public readonly int AttackTurnDelay = 50;

[Desc("Tolerance for attack angle. Range [0, 128], 128 covers 360 degrees.")]
public readonly int FacingTolerance = 0;

public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
base.RulesetLoaded(rules, ai);

if (FacingTolerance < 0 || FacingTolerance > 128)
throw new YamlException("Facing tolerance must be in range of [0, 128], 128 covers 360 degrees.");
}

public override object Create(ActorInitializer init) { return new AttackAircraft(init.Self, this); }
}

@@ -64,14 +53,7 @@ protected override bool CanAttack(Actor self, Target target)
if (!base.CanAttack(self, target))
return false;

var pos = self.CenterPosition;
var targetedPosition = GetTargetPosition(pos, target);
var delta = targetedPosition - pos;

if (delta.HorizontalLengthSquared == 0)
return true;

return Util.FacingWithinTolerance(facing.Facing, delta.Yaw.Facing, AttackAircraftInfo.FacingTolerance);
return TargetInFiringArc(self, target);
}
}
}
@@ -18,8 +18,6 @@ namespace OpenRA.Mods.Common.Traits
{
public class AttackBomberInfo : AttackBaseInfo
{
public readonly int FacingTolerance = 2;

public override object Create(ActorInitializer init) { return new AttackBomber(init.Self, this); }
}

@@ -49,10 +47,7 @@ void ITick.Tick(Actor self)

inAttackRange = false;

var f = facing.Facing;
var delta = target.CenterPosition - self.CenterPosition;
var facingToTarget = delta.HorizontalLengthSquared != 0 ? delta.Yaw.Facing : f;
facingTarget = Math.Abs(facingToTarget - f) % 256 <= info.FacingTolerance;
facingTarget = TargetInFiringArc(self, target);

foreach (var a in Armaments)
{
@@ -39,6 +39,17 @@ public abstract class AttackBaseInfo : PausableConditionalTraitInfo

[VoiceReference] public readonly string Voice = "Action";

[Desc("Tolerance for attack angle. Range [0, 128], 128 covers 360 degrees.")]
public readonly int FacingTolerance = 128;

public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
base.RulesetLoaded(rules, ai);

if (FacingTolerance < 0 || FacingTolerance > 128)
throw new YamlException("Facing tolerance must be in range of [0, 128], 128 covers 360 degrees.");
}

public override abstract object Create(ActorInitializer init);
}

@@ -101,6 +112,21 @@ protected virtual Func<IEnumerable<Armament>> InitializeGetArmaments(Actor self)
return () => armaments;
}

public bool TargetInFiringArc(Actor self, Target target)
{
if (facing == null)
return true;

var pos = self.CenterPosition;
var targetedPosition = GetTargetPosition(pos, target);
var delta = targetedPosition - pos;

if (delta.HorizontalLengthSquared == 0)
return true;

return Util.FacingWithinTolerance(facing.Facing, delta.Yaw.Facing, Info.FacingTolerance);
}

protected virtual bool CanAttack(Actor self, Target target)
{
if (!self.IsInWorld || IsTraitDisabled || IsTraitPaused)
@@ -58,7 +58,10 @@ protected bool CanAimAtTarget(Actor self, Target target, bool forceAttack)
var armaments = ChooseArmamentsForTarget(target, forceAttack);
foreach (var a in armaments)
if (target.IsInRange(pos, a.MaxRange()) && (a.Weapon.MinRange == WDist.Zero || !target.IsInRange(pos, a.Weapon.MinRange)))
return true;
{
if (TargetInFiringArc(self, target))
return true;
}

return false;
}
@@ -96,7 +99,7 @@ protected override void Tick(Actor self)
if (!IsAiming && ((AttackFollowInfo)Info).OpportunityFire && autoTarget != null &&
!autoTarget.IsTraitDisabled && autoTarget.Stance >= UnitStance.Defend)
{
OpportunityTarget = autoTarget.ScanForTarget(self, false);
OpportunityTarget = autoTarget.ScanForTarget(self, false, false);
opportunityForceAttack = false;

if (OpportunityTarget.Type != TargetType.Invalid)
@@ -17,16 +17,6 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Unit got to face the target")]
public class AttackFrontalInfo : AttackBaseInfo, Requires<IFacingInfo>
{
public readonly int FacingTolerance = 0;

public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
base.RulesetLoaded(rules, ai);

if (FacingTolerance < 0 || FacingTolerance > 128)
throw new YamlException("Facing tolerance must be in range of [0, 128], 128 covers 360 degrees.");
}

public override object Create(ActorInitializer init) { return new AttackFrontal(init.Self, this); }
}

@@ -45,14 +35,7 @@ protected override bool CanAttack(Actor self, Target target)
if (!base.CanAttack(self, target))
return false;

var pos = self.CenterPosition;
var targetedPosition = GetTargetPosition(pos, target);
var delta = targetedPosition - pos;

if (delta.HorizontalLengthSquared == 0)
return true;

return Util.FacingWithinTolerance(facing.Facing, delta.Yaw.Facing, info.FacingTolerance);
return TargetInFiringArc(self, target);
}

public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack)
@@ -24,6 +24,9 @@ public class AutoTargetInfo : ConditionalTraitInfo, Requires<AttackBaseInfo>, IE
[Desc("It will try to hunt down the enemy if it is set to AttackAnything.")]
public readonly bool AllowMovement = true;

[Desc("It will try to pivot to face the enemy if stance is not HoldFire.")]
public readonly bool AllowTurning = true;

[Desc("Set to a value >1 to override weapons maximum range for this.")]
public readonly int ScanRadius = -1;

@@ -228,7 +231,8 @@ void INotifyIdle.TickIdle(Actor self)
return;

var allowMove = Info.AllowMovement && Stance > UnitStance.Defend;
ScanAndAttack(self, allowMove);
var allowTurn = Info.AllowTurning && Stance > UnitStance.HoldFire;
ScanAndAttack(self, allowMove, allowTurn);
}

void ITick.Tick(Actor self)
@@ -240,7 +244,7 @@ void ITick.Tick(Actor self)
--nextScanTime;
}

public Target ScanForTarget(Actor self, bool allowMove)
public Target ScanForTarget(Actor self, bool allowMove, bool allowTurn)
{
if (nextScanTime <= 0 && ActiveAttackBases.Any())
{
@@ -253,17 +257,17 @@ public Target ScanForTarget(Actor self, bool allowMove)
if (attackStances != OpenRA.Traits.Stance.None)
{
var range = Info.ScanRadius > 0 ? WDist.FromCells(Info.ScanRadius) : ab.GetMaximumRange();
return ChooseTarget(self, ab, attackStances, range, allowMove);
return ChooseTarget(self, ab, attackStances, range, allowMove, allowTurn);
}
}
}

return Target.Invalid;
}

public void ScanAndAttack(Actor self, bool allowMove)
public void ScanAndAttack(Actor self, bool allowMove, bool allowTurn)
{
var target = ScanForTarget(self, allowMove);
var target = ScanForTarget(self, allowMove, allowTurn);
if (target.Type != TargetType.Invalid)
Attack(self, target, allowMove);
}
@@ -276,7 +280,7 @@ void Attack(Actor self, Target target, bool allowMove)
ab.AttackTarget(target, false, allowMove);
}

Target ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanRange, bool allowMove)
Target ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanRange, bool allowMove, bool allowTurn)
{
var chosenTarget = Target.Invalid;
var chosenTargetPriority = int.MinValue;
@@ -345,6 +349,9 @@ Target ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanR
if (!armaments.Any())
continue;

if (!allowTurn && !ab.TargetInFiringArc(self, target))
continue;

// Evaluate whether we want to target this actor
var targetRange = (target.CenterPosition - self.CenterPosition).Length;
foreach (var ati in validPriorities)
@@ -210,6 +210,7 @@ A10:
Speed: 373
Repulsable: False
AttackBomber:
FacingTolerance: 2
Armaments: gun, bombs
Armament@GUNS:
Name: gun
@@ -92,6 +92,7 @@ frigate:
ornithopter:
Inherits: ^Plane
AttackBomber:
FacingTolerance: 2
Armament:
Weapon: OrniBomb
Health:
@@ -40,6 +40,7 @@ BADR:
BADR.Bomber:
Inherits: ^NeutralPlane
AttackBomber:
FacingTolerance: 2
Armament:
Weapon: ParaBomb
Health:

0 comments on commit 9213dde

Please sign in to comment.
You can’t perform that action at this time.