diff --git a/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs b/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs index 660aab06b0..a99ab10aca 100644 --- a/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs +++ b/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs @@ -62,7 +62,7 @@ namespace OpenRA.Mods.Cnc.Traits if (hasTicked && attack.RequestedTarget.Type == TargetType.Invalid) return NextActivity; - attack.RequestedTarget = target; + attack.SetRequestedTarget(self, target); hasTicked = true; } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index e1ad51e861..47ca76a614 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -79,14 +79,7 @@ namespace OpenRA.Mods.Common.Activities if (IsCanceling) { // Cancel the requested target, but keep firing on it while in range - if (attackAircraft.Info.PersistentTargeting) - { - attackAircraft.OpportunityTarget = attackAircraft.RequestedTarget; - attackAircraft.OpportunityForceAttack = attackAircraft.RequestedForceAttack; - attackAircraft.OpportunityTargetIsPersistentTarget = true; - } - - attackAircraft.RequestedTarget = Target.Invalid; + attackAircraft.ClearRequestedTarget(); return NextActivity; } @@ -99,8 +92,8 @@ namespace OpenRA.Mods.Common.Activities return this; bool targetIsHiddenActor; - attackAircraft.RequestedTarget = target = target.Recalculate(self.Owner, out targetIsHiddenActor); - attackAircraft.RequestedTargetLastTick = self.World.WorldTick; + target = target.Recalculate(self.Owner, out targetIsHiddenActor); + attackAircraft.SetRequestedTarget(self, target, forceAttack); hasTicked = true; if (!targetIsHiddenActor && target.Type == TargetType.Actor) @@ -121,7 +114,7 @@ namespace OpenRA.Mods.Common.Activities // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) { - attackAircraft.RequestedTarget = Target.Invalid; + attackAircraft.ClearRequestedTarget(); return NextActivity; } @@ -141,7 +134,7 @@ namespace OpenRA.Mods.Common.Activities // We've reached the assumed position but it is not there - give up if (checkTarget.IsInRange(pos, lastVisibleMaximumRange)) { - attackAircraft.RequestedTarget = Target.Invalid; + attackAircraft.ClearRequestedTarget(); return NextActivity; } @@ -184,7 +177,7 @@ namespace OpenRA.Mods.Common.Activities return; if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes)) - attackAircraft.RequestedTarget = Target.Invalid; + attackAircraft.ClearRequestedTarget(); } } } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs index ad218d9b44..38d80c8a69 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs @@ -32,15 +32,34 @@ namespace OpenRA.Mods.Common.Traits public class AttackFollow : AttackBase, INotifyOwnerChanged, IDisableAutoTarget, INotifyStanceChanged { public new readonly AttackFollowInfo Info; - public Target RequestedTarget; - public bool RequestedForceAttack; - public int RequestedTargetLastTick; - public Target OpportunityTarget; - public bool OpportunityForceAttack; - public bool OpportunityTargetIsPersistentTarget; + public Target RequestedTarget { get; private set; } + public Target OpportunityTarget { get; private set; } Mobile mobile; AutoTarget autoTarget; + int requestedTargetLastTick; + bool requestedForceAttack; + bool opportunityForceAttack; + bool opportunityTargetIsPersistentTarget; + + public void SetRequestedTarget(Actor self, Target target, bool isForceAttack = false) + { + RequestedTarget = target; + requestedForceAttack = isForceAttack; + requestedTargetLastTick = self.World.WorldTick; + } + + public void ClearRequestedTarget() + { + if (Info.PersistentTargeting) + { + OpportunityTarget = RequestedTarget; + opportunityForceAttack = requestedForceAttack; + opportunityTargetIsPersistentTarget = true; + } + + RequestedTarget = Target.Invalid; + } public AttackFollow(Actor self, AttackFollowInfo info) : base(self, info) @@ -78,10 +97,10 @@ namespace OpenRA.Mods.Common.Traits if (IsTraitDisabled) { RequestedTarget = OpportunityTarget = Target.Invalid; - OpportunityTargetIsPersistentTarget = false; + opportunityTargetIsPersistentTarget = false; } - if (RequestedTargetLastTick != self.World.WorldTick) + if (requestedTargetLastTick != self.World.WorldTick) { // Activities tick before traits, so if we are here it means the activity didn't run // (either queued next or already cancelled) and we need to recalculate the target ourself @@ -95,7 +114,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); } @@ -104,17 +123,17 @@ namespace OpenRA.Mods.Common.Traits IsAiming = false; if (OpportunityTarget.Type != TargetType.Invalid) - IsAiming = CanAimAtTarget(self, OpportunityTarget, OpportunityForceAttack); + IsAiming = CanAimAtTarget(self, OpportunityTarget, opportunityForceAttack); if (!IsAiming && Info.OpportunityFire && autoTarget != null && !autoTarget.IsTraitDisabled && autoTarget.Stance >= UnitStance.Defend) { OpportunityTarget = autoTarget.ScanForTarget(self, false, false); - OpportunityForceAttack = false; - OpportunityTargetIsPersistentTarget = false; + opportunityForceAttack = false; + opportunityTargetIsPersistentTarget = false; if (OpportunityTarget.Type != TargetType.Invalid) - IsAiming = CanAimAtTarget(self, OpportunityTarget, OpportunityForceAttack); + IsAiming = CanAimAtTarget(self, OpportunityTarget, opportunityForceAttack); } if (IsAiming) @@ -137,34 +156,34 @@ namespace OpenRA.Mods.Common.Traits if (!queued) { RequestedTarget = target; - RequestedForceAttack = forceAttack; - RequestedTargetLastTick = self.World.WorldTick; + requestedForceAttack = forceAttack; + requestedTargetLastTick = self.World.WorldTick; } } public override void OnStopOrder(Actor self) { RequestedTarget = OpportunityTarget = Target.Invalid; - OpportunityTargetIsPersistentTarget = false; + opportunityTargetIsPersistentTarget = false; base.OnStopOrder(self); } void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { RequestedTarget = OpportunityTarget = Target.Invalid; - OpportunityTargetIsPersistentTarget = false; + opportunityTargetIsPersistentTarget = false; } bool IDisableAutoTarget.DisableAutoTarget(Actor self) { return RequestedTarget.Type != TargetType.Invalid || - (OpportunityTargetIsPersistentTarget && OpportunityTarget.Type != TargetType.Invalid); + (opportunityTargetIsPersistentTarget && OpportunityTarget.Type != TargetType.Invalid); } 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) + if (newStance > oldStance || opportunityForceAttack) return; if (OpportunityTarget.Type == TargetType.Actor) @@ -241,14 +260,7 @@ namespace OpenRA.Mods.Common.Traits if (IsCanceling) { // Cancel the requested target, but keep firing on it while in range - if (attack.Info.PersistentTargeting) - { - attack.OpportunityTarget = attack.RequestedTarget; - attack.OpportunityForceAttack = attack.RequestedForceAttack; - attack.OpportunityTargetIsPersistentTarget = true; - } - - attack.RequestedTarget = Target.Invalid; + attack.ClearRequestedTarget(); return NextActivity; } @@ -261,9 +273,8 @@ namespace OpenRA.Mods.Common.Traits return this; bool targetIsHiddenActor; - attack.RequestedForceAttack = forceAttack; - attack.RequestedTarget = target = target.Recalculate(self.Owner, out targetIsHiddenActor); - attack.RequestedTargetLastTick = self.World.WorldTick; + target = target.Recalculate(self.Owner, out targetIsHiddenActor); + attack.SetRequestedTarget(self, target, forceAttack); hasTicked = true; if (!targetIsHiddenActor && target.Type == TargetType.Actor) @@ -305,7 +316,7 @@ namespace OpenRA.Mods.Common.Traits // Either we are in range and can see the target, or we've lost track of it and should give up if (wasMovingWithinRange && targetIsHiddenActor) { - attack.RequestedTarget = Target.Invalid; + attack.ClearRequestedTarget(); return NextActivity; } @@ -316,7 +327,7 @@ namespace OpenRA.Mods.Common.Traits // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) { - attack.RequestedTarget = Target.Invalid; + attack.ClearRequestedTarget(); return NextActivity; } @@ -329,7 +340,7 @@ namespace OpenRA.Mods.Common.Traits { if (useLastVisibleTarget) { - attack.RequestedTarget = Target.Invalid; + attack.ClearRequestedTarget(); return NextActivity; } @@ -339,7 +350,7 @@ namespace OpenRA.Mods.Common.Traits // We can't move into range, so give up if (move == null || maxRange == WDist.Zero || maxRange < minRange) { - attack.RequestedTarget = Target.Invalid; + attack.ClearRequestedTarget(); return NextActivity; } @@ -355,7 +366,7 @@ namespace OpenRA.Mods.Common.Traits return; if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes)) - attack.RequestedTarget = Target.Invalid; + attack.ClearRequestedTarget(); } } }