Fix the autotarget bug that made turrets uncontrollable in combat

This commit is contained in:
ScottNZ
2013-08-13 01:31:04 +12:00
parent ef968a0caf
commit 115a447b2f
3 changed files with 36 additions and 31 deletions

View File

@@ -164,6 +164,12 @@ namespace OpenRA.Mods.RA
self.QueueActivity(GetAttackActivity(self, target, allowMove)); self.QueueActivity(GetAttackActivity(self, target, allowMove));
} }
public bool IsReachableTarget(Target target, bool allowMove)
{
return HasAnyValidWeapons(target)
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (self.HasTrait<IMove>() && allowMove));
}
class AttackOrderTargeter : IOrderTargeter class AttackOrderTargeter : IOrderTargeter
{ {
readonly bool negativeDamage; readonly bool negativeDamage;

View File

@@ -10,7 +10,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move; using OpenRA.Mods.RA.Move;
@@ -20,12 +19,12 @@ namespace OpenRA.Mods.RA
{ {
class AttackTurretedInfo : AttackBaseInfo, Requires<TurretedInfo> class AttackTurretedInfo : AttackBaseInfo, Requires<TurretedInfo>
{ {
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 class AttackTurreted : AttackBase, INotifyBuildComplete, ISync
{ {
protected Target target; public Target Target { get; protected set; }
protected IEnumerable<Turreted> turrets; protected IEnumerable<Turreted> turrets;
[Sync] protected bool buildComplete; [Sync] protected bool buildComplete;
@@ -34,9 +33,9 @@ namespace OpenRA.Mods.RA
turrets = self.TraitsImplementing<Turreted>(); turrets = self.TraitsImplementing<Turreted>();
} }
protected override bool CanAttack( Actor self, Target target ) protected override bool CanAttack(Actor self, Target target)
{ {
if( self.HasTrait<Building>() && !buildComplete ) if (self.HasTrait<Building>() && !buildComplete)
return false; return false;
if (!target.IsValid) return false; if (!target.IsValid) return false;
@@ -47,19 +46,19 @@ namespace OpenRA.Mods.RA
canAttack = true; 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) public override void Tick(Actor self)
{ {
base.Tick(self); base.Tick(self);
DoAttack( self, target ); DoAttack(self, Target);
IsAttacking = target.IsValid; IsAttacking = Target.IsValid;
} }
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) 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) public override void ResolveOrder(Actor self, Order order)
@@ -67,7 +66,7 @@ namespace OpenRA.Mods.RA
base.ResolveOrder(self, order); base.ResolveOrder(self, order);
if (order.OrderString == "Stop") if (order.OrderString == "Stop")
target = Target.Invalid; Target = Target.Invalid;
} }
public virtual void BuildingComplete(Actor self) { buildComplete = true; } public virtual void BuildingComplete(Actor self) { buildComplete = true; }
@@ -77,15 +76,15 @@ namespace OpenRA.Mods.RA
readonly Target target; readonly Target target;
readonly bool allowMove; readonly bool allowMove;
public AttackActivity( Target newTarget, bool allowMove ) public AttackActivity(Target newTarget, bool allowMove)
{ {
this.target = newTarget; this.target = newTarget;
this.allowMove = allowMove; 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; 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)); var range = WRange.FromCells(Math.Max(0, (int)weapon.Weapon.Range - RangeTolerance));
attack.target = target; attack.Target = target;
if (allowMove && self.HasTrait<Mobile>() && !self.Info.Traits.Get<MobileInfo>().OnRails) if (allowMove && self.HasTrait<Mobile>() && !self.Info.Traits.Get<MobileInfo>().OnRails)
return Util.SequenceActivities(new Follow(target, range), this); return Util.SequenceActivities(new Follow(target, range), this);
} }

View File

@@ -38,6 +38,7 @@ namespace OpenRA.Mods.RA
{ {
readonly AutoTargetInfo Info; readonly AutoTargetInfo Info;
readonly AttackBase attack; readonly AttackBase attack;
readonly AttackTurreted at;
[Sync] public int nextScanTime = 0; [Sync] public int nextScanTime = 0;
public UnitStance stance; public UnitStance stance;
@@ -52,6 +53,7 @@ namespace OpenRA.Mods.RA
attack = self.Trait<AttackBase>(); attack = self.Trait<AttackBase>();
stance = Info.InitialStance; stance = Info.InitialStance;
predictedStance = stance; predictedStance = stance;
at = self.TraitOrDefault<AttackTurreted>();
} }
public void ResolveOrder(Actor self, Order order) public void ResolveOrder(Actor self, Order order)
@@ -68,7 +70,6 @@ namespace OpenRA.Mods.RA
if (stance < UnitStance.ReturnFire) return; if (stance < UnitStance.ReturnFire) return;
// not a lot we can do about things we can't hurt... although maybe we should automatically run away? // not a lot we can do about things we can't hurt... although maybe we should automatically run away?
var attack = self.Trait<AttackBase>();
if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker))) return; 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. // 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; 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) public void TickIdle(Actor self)
{ {
if (stance < UnitStance.Defend) return; if (stance < UnitStance.Defend) return;
var target = ScanForTarget(self, null); if (at == null || !at.IsReachableTarget(at.Target, Info.AllowMovement && stance != UnitStance.Defend))
if (target != null) ScanAndAttack(self);
{
TargetedActor = target;
var t = Target.FromActor(target);
self.SetTargetLine(t, Color.Red, false);
attack.AttackTarget(t, false, Info.AllowMovement && stance != UnitStance.Defend);
}
} }
public void Tick(Actor self) public void Tick(Actor self)
@@ -116,10 +111,15 @@ namespace OpenRA.Mods.RA
{ {
var targetActor = ScanForTarget(self, null); var targetActor = ScanForTarget(self, null);
if (targetActor != null) if (targetActor != null)
Attack(self, targetActor);
}
void Attack(Actor self, Actor targetActor)
{ {
TargetedActor = targetActor; TargetedActor = targetActor;
attack.AttackTarget(Target.FromActor(targetActor), false, Info.AllowMovement && stance != UnitStance.Defend); 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) Actor ChooseTarget(Actor self, WRange range)