diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index bcfe4bf413..45f963fa5c 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Activities aircraft = self.Trait(); attackAircraft = self.Trait(); rearmable = self.TraitOrDefault(); - ticksUntilTurn = attackAircraft.AttackAircraftInfo.AttackTurnDelay; + 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 @@ -64,7 +64,12 @@ namespace OpenRA.Mods.Common.Activities if (IsCanceling) { // Cancel the requested target, but keep firing on it while in range - attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget; + if (attackAircraft.Info.PersistentTargeting) + { + attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget; + attackAircraft.OpportunityForceAttack = attackAircraft.RequestedForceAttack; + } + attackAircraft.RequestedTarget = Target.Invalid; return NextActivity; } @@ -130,7 +135,6 @@ namespace OpenRA.Mods.Common.Activities if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length < aircraft.Info.MinAirborneAltitude) QueueChild(self, new TakeOff(self), true); - // TODO: This should fire each weapon at its maximum range if (attackAircraft != null && target.IsInRange(self.CenterPosition, attackAircraft.GetMinimumRange())) QueueChild(self, new FlyTimed(ticksUntilTurn, self), true); diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index c466e8b18d..143f2ae67e 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -62,7 +62,12 @@ namespace OpenRA.Mods.Common.Activities if (IsCanceling) { // Cancel the requested target, but keep firing on it while in range - attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget; + if (attackAircraft.Info.PersistentTargeting) + { + attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget; + attackAircraft.OpportunityForceAttack = attackAircraft.RequestedForceAttack; + } + attackAircraft.RequestedTarget = Target.Invalid; return NextActivity; } diff --git a/OpenRA.Mods.Common/Activities/Attack.cs b/OpenRA.Mods.Common/Activities/Attack.cs index 6aeee68d30..f934b4ee86 100644 --- a/OpenRA.Mods.Common/Activities/Attack.cs +++ b/OpenRA.Mods.Common/Activities/Attack.cs @@ -191,10 +191,9 @@ namespace OpenRA.Mods.Common.Activities 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, attack.Info.FacingTolerance)) { + var desiredFacing = (attack.GetTargetPosition(pos, target) - pos).Yaw.Facing; attackStatus |= AttackStatus.NeedsToTurn; QueueChild(self, new Turn(self, desiredFacing), true); return AttackStatus.NeedsToTurn; diff --git a/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs b/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs index 624ca90fb2..4ac04a4a82 100644 --- a/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs +++ b/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Activities 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) diff --git a/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs b/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs index b20070eecd..a6df9da8f8 100644 --- a/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs @@ -20,29 +20,18 @@ namespace OpenRA.Mods.Common.Traits [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); } } public class AttackAircraft : AttackFollow { - public readonly AttackAircraftInfo AttackAircraftInfo; + public new readonly AttackAircraftInfo Info; readonly AircraftInfo aircraftInfo; public AttackAircraft(Actor self, AttackAircraftInfo info) : base(self, info) { - AttackAircraftInfo = info; + Info = info; aircraftInfo = self.Info.TraitInfo(); } @@ -64,14 +53,7 @@ namespace OpenRA.Mods.Common.Traits 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, base.Info.FacingTolerance); } } } diff --git a/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs b/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs index cff0ed91e5..4820bf810a 100644 --- a/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs +++ b/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs @@ -18,7 +18,8 @@ namespace OpenRA.Mods.Common.Traits { public class AttackBomberInfo : AttackBaseInfo { - public readonly int FacingTolerance = 2; + [Desc("Tolerance for attack angle. Range [0, 128], 128 covers 360 degrees.")] + public readonly new int FacingTolerance = 2; public override object Create(ActorInitializer init) { return new AttackBomber(init.Self, this); } } @@ -49,10 +50,7 @@ namespace OpenRA.Mods.Common.Traits 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, info.FacingTolerance); foreach (var a in Armaments) { diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index 66a4263185..104b831061 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -39,6 +39,17 @@ namespace OpenRA.Mods.Common.Traits [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 @@ namespace OpenRA.Mods.Common.Traits return () => armaments; } + public bool TargetInFiringArc(Actor self, Target target, int facingTolerance) + { + 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, facingTolerance); + } + protected virtual bool CanAttack(Actor self, Target target) { if (!self.IsInWorld || IsTraitDisabled || IsTraitPaused) diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs index 330ae06b11..bc029af459 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs @@ -23,21 +23,28 @@ namespace OpenRA.Mods.Common.Traits [Desc("Automatically acquire and fire on targets of opportunity when not actively attacking.")] public readonly bool OpportunityFire = true; + [Desc("Keep firing on targets even after attack order is cancelled")] + public readonly bool PersistentTargeting = true; + public override object Create(ActorInitializer init) { return new AttackFollow(init.Self, this); } } public class AttackFollow : AttackBase, INotifyOwnerChanged { + public new readonly AttackFollowInfo Info; public Target RequestedTarget; - protected bool requestedForceAttack; + public bool RequestedForceAttack; public int RequestedTargetLastTick; public Target OpportunityTarget; - protected bool opportunityForceAttack; + public bool OpportunityForceAttack; Mobile mobile; AutoTarget autoTarget; public AttackFollow(Actor self, AttackFollowInfo info) - : base(self, info) { } + : base(self, info) + { + Info = info; + } protected override void Created(Actor self) { @@ -58,7 +65,8 @@ namespace OpenRA.Mods.Common.Traits 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, Info.FacingTolerance)) + return true; return false; } @@ -82,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits if (RequestedTarget.Type != TargetType.Invalid) { - IsAiming = CanAimAtTarget(self, RequestedTarget, requestedForceAttack); + IsAiming = CanAimAtTarget(self, RequestedTarget, RequestedForceAttack); if (IsAiming) DoAttack(self, RequestedTarget); } @@ -91,16 +99,16 @@ namespace OpenRA.Mods.Common.Traits IsAiming = false; if (OpportunityTarget.Type != TargetType.Invalid) - IsAiming = CanAimAtTarget(self, OpportunityTarget, opportunityForceAttack); + IsAiming = CanAimAtTarget(self, OpportunityTarget, OpportunityForceAttack); - if (!IsAiming && ((AttackFollowInfo)Info).OpportunityFire && autoTarget != null && + if (!IsAiming && Info.OpportunityFire && autoTarget != null && !autoTarget.IsTraitDisabled && autoTarget.Stance >= UnitStance.Defend) { - OpportunityTarget = autoTarget.ScanForTarget(self, false); - opportunityForceAttack = false; + OpportunityTarget = autoTarget.ScanForTarget(self, false, false); + OpportunityForceAttack = false; if (OpportunityTarget.Type != TargetType.Invalid) - IsAiming = CanAimAtTarget(self, OpportunityTarget, opportunityForceAttack); + IsAiming = CanAimAtTarget(self, OpportunityTarget, OpportunityForceAttack); } if (IsAiming) @@ -123,7 +131,7 @@ namespace OpenRA.Mods.Common.Traits if (!queued) { RequestedTarget = target; - requestedForceAttack = forceAttack; + RequestedForceAttack = forceAttack; RequestedTargetLastTick = self.World.WorldTick; } } @@ -186,8 +194,12 @@ namespace OpenRA.Mods.Common.Traits if (IsCanceling) { // Cancel the requested target, but keep firing on it while in range - attack.OpportunityTarget = attack.RequestedTarget; - attack.opportunityForceAttack = attack.requestedForceAttack; + if (attack.Info.PersistentTargeting) + { + attack.OpportunityTarget = attack.RequestedTarget; + attack.OpportunityForceAttack = attack.RequestedForceAttack; + } + attack.RequestedTarget = Target.Invalid; return NextActivity; } @@ -201,7 +213,7 @@ namespace OpenRA.Mods.Common.Traits return this; bool targetIsHiddenActor; - attack.requestedForceAttack = forceAttack; + attack.RequestedForceAttack = forceAttack; attack.RequestedTarget = target = target.Recalculate(self.Owner, out targetIsHiddenActor); attack.RequestedTargetLastTick = self.World.WorldTick; hasTicked = true; diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs b/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs index bc8545a3a8..d1f072bd1d 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs @@ -17,27 +17,20 @@ namespace OpenRA.Mods.Common.Traits [Desc("Unit got to face the target")] public class AttackFrontalInfo : AttackBaseInfo, Requires { - 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."); - } + [Desc("Tolerance for attack angle. Range [0, 128], 128 covers 360 degrees.")] + public readonly new int FacingTolerance = 0; public override object Create(ActorInitializer init) { return new AttackFrontal(init.Self, this); } } public class AttackFrontal : AttackBase { - readonly AttackFrontalInfo info; + public new readonly AttackFrontalInfo Info; public AttackFrontal(Actor self, AttackFrontalInfo info) : base(self, info) { - this.info = info; + this.Info = info; } protected override bool CanAttack(Actor self, Target target) @@ -45,14 +38,7 @@ namespace OpenRA.Mods.Common.Traits 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, Info.FacingTolerance); } public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index bd4e391a21..7db2afe944 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -24,6 +24,9 @@ namespace OpenRA.Mods.Common.Traits [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 @@ namespace OpenRA.Mods.Common.Traits 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 @@ namespace OpenRA.Mods.Common.Traits --nextScanTime; } - public Target ScanForTarget(Actor self, bool allowMove) + public Target ScanForTarget(Actor self, bool allowMove, bool allowTurn) { if (nextScanTime <= 0 && ActiveAttackBases.Any()) { @@ -253,7 +257,7 @@ namespace OpenRA.Mods.Common.Traits 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); } } } @@ -261,9 +265,9 @@ namespace OpenRA.Mods.Common.Traits 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 @@ namespace OpenRA.Mods.Common.Traits 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; @@ -353,6 +357,9 @@ namespace OpenRA.Mods.Common.Traits if (!armaments.Any()) continue; + if (!allowTurn && !ab.TargetInFiringArc(self, target, ab.Info.FacingTolerance)) + continue; + // Evaluate whether we want to target this actor var targetRange = (target.CenterPosition - self.CenterPosition).Length; foreach (var ati in validPriorities) diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index 28c6a30691..1b32e0258e 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -91,6 +91,8 @@ HELI: ScanRadius: 4 AttackAircraft: FacingTolerance: 20 + OpportunityFire: false + PersistentTargeting: false AmmoPool: Ammo: 10 PipCount: 5 @@ -150,6 +152,8 @@ ORCA: ScanRadius: 5 AttackAircraft: FacingTolerance: 20 + OpportunityFire: false + PersistentTargeting: false AmmoPool: Ammo: 6 PipCount: 6 diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 2b1ec38584..4475fd0ba4 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -475,6 +475,7 @@ WithInfantryBody: IdleSequences: idle1, idle2 StandSequences: stand, stand2 + AttackFrontal: ^CivInfantry: Inherits: ^Infantry diff --git a/mods/cnc/rules/infantry.yaml b/mods/cnc/rules/infantry.yaml index 88778f3831..039c63e0f2 100644 --- a/mods/cnc/rules/infantry.yaml +++ b/mods/cnc/rules/infantry.yaml @@ -22,7 +22,6 @@ E1: ScanRadius: 4 Armament: Weapon: M16 - AttackFrontal: WithInfantryBody: IdleSequences: idle1,idle2,idle3,idle4 DefaultAttackSequence: shoot @@ -55,7 +54,6 @@ E2: FireDelay: 15 TakeCover: ProneOffset: 300,0,-227 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: throw Explodes: @@ -91,7 +89,6 @@ E3: FireDelay: 5 TakeCover: ProneOffset: 180,0,-200 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot @@ -124,7 +121,6 @@ E4: MuzzleSequence: muzzle TakeCover: ProneOffset: 190,0,-198 - AttackFrontal: WithMuzzleOverlay: WithInfantryBody: DefaultAttackSequence: shoot @@ -159,7 +155,6 @@ E5: MuzzleSequence: muzzle TakeCover: ProneOffset: 190,0,-190 - AttackFrontal: WithMuzzleOverlay: -DamagedByTerrain: WithInfantryBody: @@ -196,6 +191,7 @@ E6: PlayerExperience: 50 Selectable: Priority: 5 + -AttackFrontal: RMBO: Inherits: ^Soldier diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 247f0935d2..4543a4f08f 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -335,6 +335,7 @@ Radius: 96 MapEditorData: Categories: Infantry + AttackFrontal: ^Plane: Inherits@1: ^ExistsInWorld diff --git a/mods/d2k/rules/infantry.yaml b/mods/d2k/rules/infantry.yaml index 2a0509bdec..1f2f0fd8ac 100644 --- a/mods/d2k/rules/infantry.yaml +++ b/mods/d2k/rules/infantry.yaml @@ -19,7 +19,6 @@ light_inf: Speed: 43 Armament: Weapon: LMG - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot @@ -52,6 +51,7 @@ engineer: -RevealOnFire: Voiced: VoiceSet: EngineerVoice + -AttackFrontal: trooper: Inherits: ^Infantry @@ -80,7 +80,6 @@ trooper: LocalOffset: 128,0,256 TakeCover: ProneOffset: 324,0,-204 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot @@ -130,6 +129,7 @@ thumper: Intensity: 1000 Falloff: 0, 0, 0, 100, 100, 100, 25, 11, 6, 4, 3, 2, 1, 0 RequiresCondition: deployed + -AttackFrontal: fremen: Inherits: ^Infantry @@ -159,7 +159,6 @@ fremen: Weapon: Fremen_S Armament@SECONDARY: Weapon: Fremen_L - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot Cloak: @@ -201,7 +200,6 @@ grenadier: FireDelay: 3 TakeCover: ProneOffset: 96,100,-64 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: throw Explodes: @@ -236,7 +234,6 @@ sardaukar: Weapon: M_LMG Armament@SECONDARY: Weapon: M_HMG - AttackFrontal: Voiced: VoiceSet: GenericVoice Explodes: @@ -295,6 +292,7 @@ saboteur: ValidDamageStates: Critical Voiced: VoiceSet: SaboteurVoice + -AttackFrontal: nsfremen: Inherits: fremen diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index c76a43a724..cdcccf8003 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -111,6 +111,7 @@ MIG: PauseOnCondition: !ammo AttackAircraft: FacingTolerance: 20 + PersistentTargeting: false Aircraft: CruiseAltitude: 2560 InitialFacing: 192 @@ -180,6 +181,7 @@ YAK: PauseOnCondition: !ammo AttackAircraft: FacingTolerance: 20 + PersistentTargeting: false Aircraft: CruiseAltitude: 2560 InitialFacing: 192 @@ -302,6 +304,7 @@ HELI: PauseOnCondition: !ammo AttackAircraft: FacingTolerance: 20 + PersistentTargeting: false Aircraft: LandWhenIdle: false TurnSpeed: 4 @@ -369,6 +372,7 @@ HIND: PauseOnCondition: !ammo AttackAircraft: FacingTolerance: 20 + PersistentTargeting: false Aircraft: LandWhenIdle: false TurnSpeed: 4 diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index e4367d141c..edfe0c4f19 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -448,6 +448,7 @@ StandSequences: stand,stand2 DetectCloaked: CloakTypes: Thief + AttackFrontal: ^CivInfantry: Inherits: ^Infantry diff --git a/mods/ra/rules/infantry.yaml b/mods/ra/rules/infantry.yaml index 5f9515773b..58d866012e 100644 --- a/mods/ra/rules/infantry.yaml +++ b/mods/ra/rules/infantry.yaml @@ -32,6 +32,7 @@ DOG: Armament: Weapon: DogJaw ReloadingCondition: attack-cooldown + -AttackFrontal: AttackLeap: Voice: Attack PauseOnCondition: attacking || attack-cooldown @@ -91,7 +92,6 @@ E1: Name: garrisoned Weapon: Vulcan MuzzleSequence: garrison-muzzle - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot RequiresCondition: !parachute @@ -139,7 +139,6 @@ E2: FireDelay: 15 TakeCover: ProneOffset: 256,64,-331 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: throw RequiresCondition: !parachute @@ -184,7 +183,6 @@ E3: Weapon: Dragon TakeCover: ProneOffset: 384,0,-395 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot RequiresCondition: !parachute @@ -231,7 +229,6 @@ E4: Weapon: Flamer TakeCover: ProneOffset: 160,0,-288 - AttackFrontal: Explodes: Weapon: VisualExplode EmptyWeapon: VisualExplode @@ -289,6 +286,7 @@ E6: VoiceSet: EngineerVoice Selectable: Priority: 5 + -AttackFrontal: SPY: Inherits: ^Soldier @@ -342,7 +340,6 @@ SPY: CloakTypes: Cloak, Thief Armament: Weapon: SilencedPPK - AttackFrontal: AttackMove: Voice: Move Voiced: @@ -400,7 +397,6 @@ E7: Name: garrisoned Weapon: Colt45 MuzzleSequence: garrison-muzzle - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot StandSequences: stand @@ -445,7 +441,6 @@ MEDI: OutsideRangeCursor: heal TargetStances: Ally ForceTargetStances: None - AttackFrontal: WithInfantryBody: IdleSequences: idle StandSequences: stand @@ -610,6 +605,7 @@ THF: ValidDamageStates: Critical Mobile: Speed: 71 + -AttackFrontal: SHOK: Inherits: ^Soldier @@ -690,7 +686,6 @@ SNIPER: Name: garrisoned Weapon: Sniper MuzzleSequence: garrison-muzzle - AttackFrontal: WithInfantryBody: DefaultAttackSequence: shoot Cloak: @@ -732,7 +727,6 @@ Zombie: Speed: 42 AutoTarget: ScanRadius: 5 - AttackFrontal: WithInfantryBody: DefaultAttackSequence: bite IdleSequences: idle1 diff --git a/mods/ts/rules/aircraft.yaml b/mods/ts/rules/aircraft.yaml index 7d3ecbd1de..0482ad6eb4 100644 --- a/mods/ts/rules/aircraft.yaml +++ b/mods/ts/rules/aircraft.yaml @@ -103,6 +103,7 @@ ORCA: PauseOnCondition: !ammo AttackAircraft: FacingTolerance: 20 + PersistentTargeting: false Voice: Attack PauseOnCondition: empdisable AmmoPool: @@ -158,6 +159,7 @@ ORCAB: AttackAircraft: Voice: Attack FacingTolerance: 20 + PersistentTargeting: false PauseOnCondition: empdisable AmmoPool: Ammo: 10 @@ -297,6 +299,7 @@ SCRIN: AttackAircraft: Voice: Attack FacingTolerance: 20 + PersistentTargeting: false PauseOnCondition: empdisable AmmoPool: Ammo: 15 @@ -346,6 +349,7 @@ APACHE: PauseOnCondition: !ammo AttackAircraft: FacingTolerance: 20 + PersistentTargeting: false Voice: Attack PauseOnCondition: empdisable AmmoPool: