From 30c2e6b4d214cf01c3ac94cafca93333146fa65e Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 18 Jul 2019 18:41:21 +0200 Subject: [PATCH] Remove Resupply re-queueing hack from Aircraft By preventing that other traits can remotely cancel Resupply or ReturnToBase. --- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 34 +++++-------------- .../Traits/Attack/AttackBase.cs | 7 ++++ .../Traits/Buildings/TransformsIntoMobile.cs | 9 ++++- OpenRA.Mods.Common/Traits/Mobile.cs | 1 + 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 422df5e97d..05f096b9b1 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -675,23 +675,6 @@ namespace OpenRA.Mods.Common.Traits protected virtual void OnBecomingIdle(Actor self) { - var altitude = self.World.Map.DistanceAboveTerrain(CenterPosition); - var atLandAltitude = altitude == LandAltitude; - - // Work-around to prevent players from accidentally canceling resupply by pressing 'Stop', - // by re-queueing Resupply as long as resupply hasn't finished and aircraft is still on resupplier. - // TODO: Investigate moving this back to ResolveOrder's "Stop" handling, - // once conflicts with other traits' "Stop" orders have been fixed. - if (atLandAltitude) - { - var host = GetActorBelow(); - if (host != null && (CanRearmAt(host) || CanRepairAt(host))) - { - self.QueueActivity(new Resupply(self, host, WDist.Zero)); - return; - } - } - if (Info.IdleBehavior == IdleBehaviorType.LeaveMap) { self.QueueActivity(new FlyOffMap(self)); @@ -701,16 +684,17 @@ namespace OpenRA.Mods.Common.Traits self.QueueActivity(new ReturnToBase(self, null, !Info.TakeOffOnResupply)); else { - if (atLandAltitude) + var dat = self.World.Map.DistanceAboveTerrain(CenterPosition); + if (dat == LandAltitude) { if (!CanLand(self.Location) && ReservedActor == null) self.QueueActivity(new TakeOff(self)); - // All remaining idle behaviors rely on not being atLandAltitude, so unconditionally return + // All remaining idle behaviors rely on not being at LandAltitude, so unconditionally return return; } - if (Info.IdleBehavior != IdleBehaviorType.Land && altitude != Info.CruiseAltitude) + if (Info.IdleBehavior != IdleBehaviorType.Land && dat != Info.CruiseAltitude) self.QueueActivity(new TakeOff(self)); else if (Info.IdleBehavior == IdleBehaviorType.Land && Info.LandableTerrainTypes.Count > 0) self.QueueActivity(new Land(self)); @@ -1034,13 +1018,13 @@ namespace OpenRA.Mods.Common.Traits } else if (orderString == "Stop") { - self.CancelActivity(); - - // HACK: If the player accidentally pressed 'Stop', we don't want this to cancel reservation. - // If unreserving is actually desired despite an actor below, it should be triggered from OnBecomingIdle. - if (GetActorBelow() != null) + // We don't want the Stop order to cancel a running Resupply activity. + // Resupply is always either the main activity or a child of ReturnToBase. + if (self.CurrentActivity is Resupply || + (self.CurrentActivity is ReturnToBase && GetActorBelow() != null)) return; + self.CancelActivity(); UnReserve(); } else if (orderString == "ReturnToBase" && rearmable != null && rearmable.Info.RearmActors.Any()) diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index 524e4d0364..336161404a 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Activities; +using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Warheads; using OpenRA.Primitives; using OpenRA.Support; @@ -206,6 +207,12 @@ namespace OpenRA.Mods.Common.Traits // Some 3rd-party mods rely on this being public public virtual void OnStopOrder(Actor self) { + // We don't want Stop orders from traits other than Mobile or Aircraft to cancel Resupply activity. + // Resupply is always either the main activity or a child of ReturnToBase. + // TODO: This should generally only cancel activities queued by this trait. + if (self.CurrentActivity == null || self.CurrentActivity is Resupply || self.CurrentActivity is ReturnToBase) + return; + self.CancelActivity(); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs index 20d635ed37..14fe590364 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs @@ -116,9 +116,16 @@ namespace OpenRA.Mods.Common.Traits if (currentTransform == null) self.QueueActivity(order.Queued, activity); } + else if (order.OrderString == "Stop") + { + // We don't want Stop orders from traits other than Mobile or Aircraft to cancel Resupply activity. + // Resupply is always either the main activity or a child of ReturnToBase. + // TODO: This should generally only cancel activities queued by this trait. + if (self.CurrentActivity == null || self.CurrentActivity is Resupply || self.CurrentActivity is ReturnToBase) + return; - if (order.OrderString == "Stop") self.CancelActivity(); + } } string IOrderVoice.VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 7493158bd2..c4958fab77 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -804,6 +804,7 @@ namespace OpenRA.Mods.Common.Traits self.QueueActivity(order.Queued, WrapMove(new Move(self, cell, WDist.FromCells(8), null, true))); } + // TODO: This should only cancel activities queued by this trait if (order.OrderString == "Stop") self.CancelActivity();