From 115a447b2f271444e6bbafecce458149bd2430cd Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Tue, 13 Aug 2013 01:31:04 +1200 Subject: [PATCH] Fix the autotarget bug that made turrets uncontrollable in combat --- OpenRA.Mods.RA/Attack/AttackBase.cs | 6 +++++ OpenRA.Mods.RA/Attack/AttackTurreted.cs | 29 +++++++++++----------- OpenRA.Mods.RA/AutoTarget.cs | 32 ++++++++++++------------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index d9ad4fbcc1..343bc7fcdd 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -164,6 +164,12 @@ namespace OpenRA.Mods.RA self.QueueActivity(GetAttackActivity(self, target, allowMove)); } + public bool IsReachableTarget(Target target, bool allowMove) + { + return HasAnyValidWeapons(target) + && (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (self.HasTrait() && allowMove)); + } + class AttackOrderTargeter : IOrderTargeter { readonly bool negativeDamage; diff --git a/OpenRA.Mods.RA/Attack/AttackTurreted.cs b/OpenRA.Mods.RA/Attack/AttackTurreted.cs index 4708273e88..ed3f2ef799 100644 --- a/OpenRA.Mods.RA/Attack/AttackTurreted.cs +++ b/OpenRA.Mods.RA/Attack/AttackTurreted.cs @@ -10,7 +10,6 @@ using System; using System.Collections.Generic; -using System.Linq; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Move; @@ -20,12 +19,12 @@ namespace OpenRA.Mods.RA { class AttackTurretedInfo : AttackBaseInfo, Requires { - public override object Create(ActorInitializer init) { return new AttackTurreted( init.self ); } + public override object Create(ActorInitializer init) { return new AttackTurreted(init.self); } } class AttackTurreted : AttackBase, INotifyBuildComplete, ISync { - protected Target target; + public Target Target { get; protected set; } protected IEnumerable turrets; [Sync] protected bool buildComplete; @@ -34,9 +33,9 @@ namespace OpenRA.Mods.RA turrets = self.TraitsImplementing(); } - protected override bool CanAttack( Actor self, Target target ) + protected override bool CanAttack(Actor self, Target target) { - if( self.HasTrait() && !buildComplete ) + if (self.HasTrait() && !buildComplete) return false; if (!target.IsValid) return false; @@ -45,21 +44,21 @@ namespace OpenRA.Mods.RA foreach (var t in turrets) if (t.FaceTarget(self, target)) canAttack = true; - if (!canAttack) return false; + if (!canAttack) return false; - return base.CanAttack( self, target ); + return base.CanAttack(self, target); } public override void Tick(Actor self) { base.Tick(self); - DoAttack( self, target ); - IsAttacking = target.IsValid; + DoAttack(self, Target); + IsAttacking = Target.IsValid; } public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) { - return new AttackActivity( newTarget, allowMove ); + return new AttackActivity(newTarget, allowMove); } public override void ResolveOrder(Actor self, Order order) @@ -67,7 +66,7 @@ namespace OpenRA.Mods.RA base.ResolveOrder(self, order); if (order.OrderString == "Stop") - target = Target.Invalid; + Target = Target.Invalid; } public virtual void BuildingComplete(Actor self) { buildComplete = true; } @@ -77,15 +76,15 @@ namespace OpenRA.Mods.RA readonly Target target; readonly bool allowMove; - public AttackActivity( Target newTarget, bool allowMove ) + public AttackActivity(Target newTarget, bool allowMove) { this.target = newTarget; this.allowMove = allowMove; } - public override Activity Tick( Actor self ) + public override Activity Tick(Actor self) { - if( IsCanceled || !target.IsValid ) return NextActivity; + if (IsCanceled || !target.IsValid) return NextActivity; if (self.IsDisabled()) return this; @@ -97,7 +96,7 @@ namespace OpenRA.Mods.RA { var range = WRange.FromCells(Math.Max(0, (int)weapon.Weapon.Range - RangeTolerance)); - attack.target = target; + attack.Target = target; if (allowMove && self.HasTrait() && !self.Info.Traits.Get().OnRails) return Util.SequenceActivities(new Follow(target, range), this); } diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 096565c330..5f8d0d54f0 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -38,6 +38,7 @@ namespace OpenRA.Mods.RA { readonly AutoTargetInfo Info; readonly AttackBase attack; + readonly AttackTurreted at; [Sync] public int nextScanTime = 0; public UnitStance stance; @@ -52,6 +53,7 @@ namespace OpenRA.Mods.RA attack = self.Trait(); stance = Info.InitialStance; predictedStance = stance; + at = self.TraitOrDefault(); } public void ResolveOrder(Actor self, Order order) @@ -68,7 +70,6 @@ namespace OpenRA.Mods.RA if (stance < UnitStance.ReturnFire) return; // not a lot we can do about things we can't hurt... although maybe we should automatically run away? - var attack = self.Trait(); if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker))) return; // don't retaliate against own units force-firing on us. it's usually not what the player wanted. @@ -78,22 +79,16 @@ namespace OpenRA.Mods.RA Aggressor = e.Attacker; - attack.AttackTarget(Target.FromActor(e.Attacker), false, Info.AllowMovement && stance != UnitStance.Defend); + if (at == null || !at.IsReachableTarget(at.Target, Info.AllowMovement && stance != UnitStance.Defend)) + Attack(self, e.Attacker); } public void TickIdle(Actor self) { if (stance < UnitStance.Defend) return; - var target = ScanForTarget(self, null); - if (target != null) - { - TargetedActor = target; - - var t = Target.FromActor(target); - self.SetTargetLine(t, Color.Red, false); - attack.AttackTarget(t, false, Info.AllowMovement && stance != UnitStance.Defend); - } + if (at == null || !at.IsReachableTarget(at.Target, Info.AllowMovement && stance != UnitStance.Defend)) + ScanAndAttack(self); } public void Tick(Actor self) @@ -116,10 +111,15 @@ namespace OpenRA.Mods.RA { var targetActor = ScanForTarget(self, null); if (targetActor != null) - { - TargetedActor = targetActor; - attack.AttackTarget(Target.FromActor(targetActor), false, Info.AllowMovement && stance != UnitStance.Defend); - } + Attack(self, targetActor); + } + + void Attack(Actor self, Actor targetActor) + { + TargetedActor = targetActor; + var target = Target.FromActor(targetActor); + self.SetTargetLine(target, Color.Red, false); + attack.AttackTarget(target, false, Info.AllowMovement && stance != UnitStance.Defend); } Actor ChooseTarget(Actor self, WRange range) @@ -150,5 +150,5 @@ namespace OpenRA.Mods.RA [Desc("Will not get automatically targeted by enemy (like walls)")] class AutoTargetIgnoreInfo : TraitInfo { } class AutoTargetIgnore { } - + }