Drop targets when switching to a more restrictive stance.

This commit is contained in:
Paul Chote
2019-05-19 16:29:59 +01:00
committed by abcdefg30
parent 62b5d22e53
commit 3ca9d4b773
10 changed files with 233 additions and 18 deletions

View File

@@ -20,25 +20,29 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Cnc.Activities namespace OpenRA.Mods.Cnc.Activities
{ {
public class LeapAttack : Activity public class LeapAttack : Activity, IActivityNotifyStanceChanged
{ {
readonly AttackLeapInfo info; readonly AttackLeapInfo info;
readonly AttackLeap attack; readonly AttackLeap attack;
readonly Mobile mobile; readonly Mobile mobile;
readonly bool allowMovement; readonly bool allowMovement;
readonly bool forceAttack;
Target target; Target target;
Target lastVisibleTarget; Target lastVisibleTarget;
bool useLastVisibleTarget; bool useLastVisibleTarget;
WDist lastVisibleMinRange; WDist lastVisibleMinRange;
WDist lastVisibleMaxRange; WDist lastVisibleMaxRange;
BitSet<TargetableType> lastVisibleTargetTypes;
Player lastVisibleOwner;
public LeapAttack(Actor self, Target target, bool allowMovement, AttackLeap attack, AttackLeapInfo info) public LeapAttack(Actor self, Target target, bool allowMovement, bool forceAttack, AttackLeap attack, AttackLeapInfo info)
{ {
this.target = target; this.target = target;
this.info = info; this.info = info;
this.attack = attack; this.attack = attack;
this.allowMovement = allowMovement; this.allowMovement = allowMovement;
this.forceAttack = forceAttack;
mobile = self.Trait<Mobile>(); mobile = self.Trait<Mobile>();
// The target may become hidden between the initial order request and the first tick (e.g. if queued) // The target may become hidden between the initial order request and the first tick (e.g. if queued)
@@ -49,6 +53,17 @@ namespace OpenRA.Mods.Cnc.Activities
lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleTarget = Target.FromPos(target.CenterPosition);
lastVisibleMinRange = attack.GetMinimumRangeVersusTarget(target); lastVisibleMinRange = attack.GetMinimumRangeVersusTarget(target);
lastVisibleMaxRange = attack.GetMaximumRangeVersusTarget(target); lastVisibleMaxRange = attack.GetMaximumRangeVersusTarget(target);
if (target.Type == TargetType.Actor)
{
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
}
else if (target.Type == TargetType.FrozenActor)
{
lastVisibleOwner = target.FrozenActor.Owner;
lastVisibleTargetTypes = target.FrozenActor.TargetTypes;
}
} }
} }
@@ -76,6 +91,8 @@ namespace OpenRA.Mods.Cnc.Activities
lastVisibleTarget = Target.FromTargetPositions(target); lastVisibleTarget = Target.FromTargetPositions(target);
lastVisibleMinRange = attack.GetMinimumRangeVersusTarget(target); lastVisibleMinRange = attack.GetMinimumRangeVersusTarget(target);
lastVisibleMaxRange = attack.GetMaximumRangeVersusTarget(target); lastVisibleMaxRange = attack.GetMaximumRangeVersusTarget(target);
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
} }
var oldUseLastVisibleTarget = useLastVisibleTarget; var oldUseLastVisibleTarget = useLastVisibleTarget;
@@ -141,5 +158,15 @@ namespace OpenRA.Mods.Cnc.Activities
{ {
attack.IsAiming = false; attack.IsAiming = false;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes))
target = Target.Invalid;
}
} }
} }

View File

@@ -73,7 +73,7 @@ namespace OpenRA.Mods.Cnc.Traits
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack)
{ {
return new LeapAttack(self, newTarget, allowMove, this, info); return new LeapAttack(self, newTarget, allowMove, forceAttack, this, info);
} }
} }
} }

View File

@@ -75,18 +75,20 @@ namespace OpenRA.Mods.Cnc.Traits
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack)
{ {
return new ChargeAttack(this, newTarget); return new ChargeAttack(this, newTarget, forceAttack);
} }
class ChargeAttack : Activity class ChargeAttack : Activity, IActivityNotifyStanceChanged
{ {
readonly AttackTesla attack; readonly AttackTesla attack;
readonly Target target; readonly Target target;
readonly bool forceAttack;
public ChargeAttack(AttackTesla attack, Target target) public ChargeAttack(AttackTesla attack, Target target, bool forceAttack)
{ {
this.attack = attack; this.attack = attack;
this.target = target; this.target = target;
this.forceAttack = forceAttack;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -114,6 +116,26 @@ namespace OpenRA.Mods.Cnc.Traits
QueueChild(self, new ChargeFire(attack, target)); QueueChild(self, new ChargeFire(attack, target));
return this; return this;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (target.Type == TargetType.Actor)
{
var a = target.Actor;
if (!autoTarget.HasValidTargetPriority(self, a.Owner, a.GetEnabledTargetTypes()))
Cancel(self, true);
}
else if (target.Type == TargetType.FrozenActor)
{
var fa = target.FrozenActor;
if (!autoTarget.HasValidTargetPriority(self, fa.Owner, fa.TargetTypes))
Cancel(self, true);
}
}
} }
class ChargeFire : Activity class ChargeFire : Activity

View File

@@ -17,22 +17,26 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Activities namespace OpenRA.Mods.Common.Activities
{ {
public class FlyAttack : Activity public class FlyAttack : Activity, IActivityNotifyStanceChanged
{ {
readonly Aircraft aircraft; readonly Aircraft aircraft;
readonly AttackAircraft attackAircraft; readonly AttackAircraft attackAircraft;
readonly Rearmable rearmable; readonly Rearmable rearmable;
readonly bool forceAttack;
readonly int ticksUntilTurn; readonly int ticksUntilTurn;
Target target; Target target;
Target lastVisibleTarget; Target lastVisibleTarget;
WDist lastVisibleMaximumRange; WDist lastVisibleMaximumRange;
BitSet<TargetableType> lastVisibleTargetTypes;
Player lastVisibleOwner;
bool useLastVisibleTarget; bool useLastVisibleTarget;
bool hasTicked; bool hasTicked;
public FlyAttack(Actor self, Target target) public FlyAttack(Actor self, Target target, bool forceAttack)
{ {
this.target = target; this.target = target;
this.forceAttack = forceAttack;
aircraft = self.Trait<Aircraft>(); aircraft = self.Trait<Aircraft>();
attackAircraft = self.Trait<AttackAircraft>(); attackAircraft = self.Trait<AttackAircraft>();
rearmable = self.TraitOrDefault<Rearmable>(); rearmable = self.TraitOrDefault<Rearmable>();
@@ -45,6 +49,17 @@ namespace OpenRA.Mods.Common.Activities
{ {
lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleTarget = Target.FromPos(target.CenterPosition);
lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target); lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target);
if (target.Type == TargetType.Actor)
{
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
}
else if (target.Type == TargetType.FrozenActor)
{
lastVisibleOwner = target.FrozenActor.Owner;
lastVisibleTargetTypes = target.FrozenActor.TargetTypes;
}
} }
} }
@@ -92,6 +107,8 @@ namespace OpenRA.Mods.Common.Activities
{ {
lastVisibleTarget = Target.FromTargetPositions(target); lastVisibleTarget = Target.FromTargetPositions(target);
lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target); lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target);
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
} }
var oldUseLastVisibleTarget = useLastVisibleTarget; var oldUseLastVisibleTarget = useLastVisibleTarget;
@@ -144,5 +161,15 @@ namespace OpenRA.Mods.Common.Activities
return this; return this;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes))
attackAircraft.RequestedTarget = Target.Invalid;
}
} }
} }

View File

@@ -17,21 +17,25 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Activities namespace OpenRA.Mods.Common.Activities
{ {
public class HeliAttack : Activity public class HeliAttack : Activity, IActivityNotifyStanceChanged
{ {
readonly Aircraft aircraft; readonly Aircraft aircraft;
readonly AttackAircraft attackAircraft; readonly AttackAircraft attackAircraft;
readonly Rearmable rearmable; readonly Rearmable rearmable;
readonly bool forceAttack;
Target target; Target target;
Target lastVisibleTarget; Target lastVisibleTarget;
WDist lastVisibleMaximumRange; WDist lastVisibleMaximumRange;
BitSet<TargetableType> lastVisibleTargetTypes;
Player lastVisibleOwner;
bool useLastVisibleTarget; bool useLastVisibleTarget;
bool hasTicked; bool hasTicked;
public HeliAttack(Actor self, Target target) public HeliAttack(Actor self, Target target, bool forceAttack)
{ {
this.target = target; this.target = target;
this.forceAttack = forceAttack;
aircraft = self.Trait<Aircraft>(); aircraft = self.Trait<Aircraft>();
attackAircraft = self.Trait<AttackAircraft>(); attackAircraft = self.Trait<AttackAircraft>();
rearmable = self.TraitOrDefault<Rearmable>(); rearmable = self.TraitOrDefault<Rearmable>();
@@ -43,6 +47,17 @@ namespace OpenRA.Mods.Common.Activities
{ {
lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleTarget = Target.FromPos(target.CenterPosition);
lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target); lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target);
if (target.Type == TargetType.Actor)
{
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
}
else if (target.Type == TargetType.FrozenActor)
{
lastVisibleOwner = target.FrozenActor.Owner;
lastVisibleTargetTypes = target.FrozenActor.TargetTypes;
}
} }
} }
@@ -90,6 +105,8 @@ namespace OpenRA.Mods.Common.Activities
{ {
lastVisibleTarget = Target.FromTargetPositions(target); lastVisibleTarget = Target.FromTargetPositions(target);
lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target); lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target);
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
} }
var oldUseLastVisibleTarget = useLastVisibleTarget; var oldUseLastVisibleTarget = useLastVisibleTarget;
@@ -156,5 +173,15 @@ namespace OpenRA.Mods.Common.Activities
return this; return this;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes))
attackAircraft.RequestedTarget = Target.Invalid;
}
} }
} }

View File

@@ -20,7 +20,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Activities namespace OpenRA.Mods.Common.Activities
{ {
/* non-turreted attack */ /* non-turreted attack */
public class Attack : Activity public class Attack : Activity, IActivityNotifyStanceChanged
{ {
[Flags] [Flags]
protected enum AttackStatus { UnableToAttack, NeedsToTurn, NeedsToMove, Attacking } protected enum AttackStatus { UnableToAttack, NeedsToTurn, NeedsToMove, Attacking }
@@ -35,6 +35,8 @@ namespace OpenRA.Mods.Common.Activities
protected Target target; protected Target target;
Target lastVisibleTarget; Target lastVisibleTarget;
WDist lastVisibleMaximumRange; WDist lastVisibleMaximumRange;
BitSet<TargetableType> lastVisibleTargetTypes;
Player lastVisibleOwner;
bool useLastVisibleTarget; bool useLastVisibleTarget;
bool wasMovingWithinRange; bool wasMovingWithinRange;
@@ -62,6 +64,17 @@ namespace OpenRA.Mods.Common.Activities
lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleTarget = Target.FromPos(target.CenterPosition);
lastVisibleMaximumRange = attackTraits.Where(x => !x.IsTraitDisabled) lastVisibleMaximumRange = attackTraits.Where(x => !x.IsTraitDisabled)
.Min(x => x.GetMaximumRangeVersusTarget(target)); .Min(x => x.GetMaximumRangeVersusTarget(target));
if (target.Type == TargetType.Actor)
{
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
}
else if (target.Type == TargetType.FrozenActor)
{
lastVisibleOwner = target.FrozenActor.Owner;
lastVisibleTargetTypes = target.FrozenActor.TargetTypes;
}
} }
} }
@@ -88,6 +101,9 @@ namespace OpenRA.Mods.Common.Activities
lastVisibleTarget = Target.FromTargetPositions(target); lastVisibleTarget = Target.FromTargetPositions(target);
lastVisibleMaximumRange = attackTraits.Where(x => !x.IsTraitDisabled) lastVisibleMaximumRange = attackTraits.Where(x => !x.IsTraitDisabled)
.Min(x => x.GetMaximumRangeVersusTarget(target)); .Min(x => x.GetMaximumRangeVersusTarget(target));
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
} }
var oldUseLastVisibleTarget = useLastVisibleTarget; var oldUseLastVisibleTarget = useLastVisibleTarget;
@@ -211,5 +227,15 @@ namespace OpenRA.Mods.Common.Activities
foreach (var a in armaments) foreach (var a in armaments)
a.CheckFire(self, facing, target); a.CheckFire(self, facing, target);
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes))
target = Target.Invalid;
}
} }
} }

View File

@@ -38,9 +38,9 @@ namespace OpenRA.Mods.Common.Traits
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack)
{ {
if (aircraftInfo.CanHover) if (aircraftInfo.CanHover)
return new HeliAttack(self, newTarget); return new HeliAttack(self, newTarget, forceAttack);
return new FlyAttack(self, newTarget); return new FlyAttack(self, newTarget, forceAttack);
} }
protected override bool CanAttack(Actor self, Target target) protected override bool CanAttack(Actor self, Target target)

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
public override object Create(ActorInitializer init) { return new AttackFollow(init.Self, this); } public override object Create(ActorInitializer init) { return new AttackFollow(init.Self, this); }
} }
public class AttackFollow : AttackBase, INotifyOwnerChanged, IDisableAutoTarget public class AttackFollow : AttackBase, INotifyOwnerChanged, IDisableAutoTarget, INotifyStanceChanged
{ {
public new readonly AttackFollowInfo Info; public new readonly AttackFollowInfo Info;
public Target RequestedTarget; public Target RequestedTarget;
@@ -161,7 +161,27 @@ namespace OpenRA.Mods.Common.Traits
(OpportunityTargetIsPersistentTarget && OpportunityTarget.Type != TargetType.Invalid); (OpportunityTargetIsPersistentTarget && OpportunityTarget.Type != TargetType.Invalid);
} }
class AttackActivity : Activity void INotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel opportunity targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || OpportunityForceAttack)
return;
if (OpportunityTarget.Type == TargetType.Actor)
{
var a = OpportunityTarget.Actor;
if (!autoTarget.HasValidTargetPriority(self, a.Owner, a.GetEnabledTargetTypes()))
OpportunityTarget = Target.Invalid;
}
else if (OpportunityTarget.Type == TargetType.FrozenActor)
{
var fa = OpportunityTarget.FrozenActor;
if (!autoTarget.HasValidTargetPriority(self, fa.Owner, fa.TargetTypes))
OpportunityTarget = Target.Invalid;
}
}
class AttackActivity : Activity, IActivityNotifyStanceChanged
{ {
readonly AttackFollow attack; readonly AttackFollow attack;
readonly RevealsShroud[] revealsShroud; readonly RevealsShroud[] revealsShroud;
@@ -173,6 +193,8 @@ namespace OpenRA.Mods.Common.Traits
bool useLastVisibleTarget; bool useLastVisibleTarget;
WDist lastVisibleMaximumRange; WDist lastVisibleMaximumRange;
WDist lastVisibleMinimumRange; WDist lastVisibleMinimumRange;
BitSet<TargetableType> lastVisibleTargetTypes;
Player lastVisibleOwner;
bool wasMovingWithinRange; bool wasMovingWithinRange;
bool hasTicked; bool hasTicked;
@@ -193,6 +215,17 @@ namespace OpenRA.Mods.Common.Traits
lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleTarget = Target.FromPos(target.CenterPosition);
lastVisibleMaximumRange = attack.GetMaximumRangeVersusTarget(target); lastVisibleMaximumRange = attack.GetMaximumRangeVersusTarget(target);
lastVisibleMinimumRange = attack.GetMinimumRangeVersusTarget(target); lastVisibleMinimumRange = attack.GetMinimumRangeVersusTarget(target);
if (target.Type == TargetType.Actor)
{
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
}
else if (target.Type == TargetType.FrozenActor)
{
lastVisibleOwner = target.FrozenActor.Owner;
lastVisibleTargetTypes = target.FrozenActor.TargetTypes;
}
} }
} }
@@ -238,6 +271,8 @@ namespace OpenRA.Mods.Common.Traits
lastVisibleTarget = Target.FromTargetPositions(target); lastVisibleTarget = Target.FromTargetPositions(target);
lastVisibleMaximumRange = attack.GetMaximumRangeVersusTarget(target); lastVisibleMaximumRange = attack.GetMaximumRangeVersusTarget(target);
lastVisibleMinimumRange = attack.GetMinimumRange(); lastVisibleMinimumRange = attack.GetMinimumRange();
lastVisibleOwner = target.Actor.Owner;
lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes();
// Try and sit at least one cell away from the min or max ranges to give some leeway if the target starts moving. // Try and sit at least one cell away from the min or max ranges to give some leeway if the target starts moving.
if (move != null && target.Actor.Info.HasTraitInfo<IMoveInfo>()) if (move != null && target.Actor.Info.HasTraitInfo<IMoveInfo>())
@@ -312,6 +347,16 @@ namespace OpenRA.Mods.Common.Traits
QueueChild(self, move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red), true); QueueChild(self, move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red), true);
return this; return this;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes))
attack.RequestedTarget = Target.Invalid;
}
} }
} }
} }

View File

@@ -27,21 +27,23 @@ namespace OpenRA.Mods.Common.Traits
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack)
{ {
return new SetTarget(this, newTarget, allowMove); return new SetTarget(this, newTarget, allowMove, forceAttack);
} }
// Some 3rd-party mods rely on this being public // Some 3rd-party mods rely on this being public
public class SetTarget : Activity public class SetTarget : Activity, IActivityNotifyStanceChanged
{ {
readonly AttackOmni attack; readonly AttackOmni attack;
readonly bool allowMove; readonly bool allowMove;
readonly bool forceAttack;
Target target; Target target;
public SetTarget(AttackOmni attack, Target target, bool allowMove) public SetTarget(AttackOmni attack, Target target, bool allowMove, bool forceAttack)
{ {
this.target = target; this.target = target;
this.attack = attack; this.attack = attack;
this.allowMove = allowMove; this.allowMove = allowMove;
this.forceAttack = forceAttack;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -55,6 +57,26 @@ namespace OpenRA.Mods.Common.Traits
attack.DoAttack(self, target); attack.DoAttack(self, target);
return this; return this;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
{
// Cancel non-forced targets when switching to a more restrictive stance if they are no longer valid for auto-targeting
if (newStance > oldStance || forceAttack)
return;
if (target.Type == TargetType.Actor)
{
var a = target.Actor;
if (!autoTarget.HasValidTargetPriority(self, a.Owner, a.GetEnabledTargetTypes()))
target = Target.Invalid;
}
else if (target.Type == TargetType.FrozenActor)
{
var fa = target.FrozenActor;
if (!autoTarget.HasValidTargetPriority(self, fa.Owner, fa.TargetTypes))
target = Target.Invalid;
}
}
} }
} }
} }

View File

@@ -313,6 +313,25 @@ namespace OpenRA.Mods.Common.Traits
ab.AttackTarget(target, false, allowMove); ab.AttackTarget(target, false, allowMove);
} }
public bool HasValidTargetPriority(Actor self, Player owner, BitSet<TargetableType> targetTypes)
{
if (Stance <= UnitStance.ReturnFire)
return false;
return activeTargetPriorities.Any(ati =>
{
// Incompatible stances
if (!ati.ValidStances.HasStance(self.Owner.Stances[owner]))
return false;
// Incompatible target types
if (!ati.ValidTargets.Overlaps(targetTypes) || ati.InvalidTargets.Overlaps(targetTypes))
return false;
return true;
});
}
Target ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanRange, bool allowMove, bool allowTurn) Target ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanRange, bool allowMove, bool allowTurn)
{ {
var chosenTarget = Target.Invalid; var chosenTarget = Target.Invalid;