Fix the autotarget bug that made turrets uncontrollable in combat
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -45,21 +44,21 @@ namespace OpenRA.Mods.RA
|
|||||||
foreach (var t in turrets)
|
foreach (var t in turrets)
|
||||||
if (t.FaceTarget(self, target))
|
if (t.FaceTarget(self, target))
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
TargetedActor = targetActor;
|
}
|
||||||
attack.AttackTarget(Target.FromActor(targetActor), false, Info.AllowMovement && stance != UnitStance.Defend);
|
|
||||||
}
|
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)
|
Actor ChooseTarget(Actor self, WRange range)
|
||||||
@@ -150,5 +150,5 @@ namespace OpenRA.Mods.RA
|
|||||||
[Desc("Will not get automatically targeted by enemy (like walls)")]
|
[Desc("Will not get automatically targeted by enemy (like walls)")]
|
||||||
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }
|
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }
|
||||||
class AutoTargetIgnore { }
|
class AutoTargetIgnore { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user