From 2c66ee8c13e1e2f518882125763868966cf312dc Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sat, 29 Oct 2016 17:38:10 +0200 Subject: [PATCH] Add native support for uninterruptible activities This pattern occurs a few times throughout the code, so it makes sense to bake it into the Activity class itself. --- OpenRA.Game/Activities/Activity.cs | 13 ++++++++++- OpenRA.Game/Activities/CallFunc.cs | 9 +------- OpenRA.Game/Actor.cs | 6 +++-- .../Activities/Air/FallToEarth.cs | 4 +--- .../Activities/Air/FlyAttack.cs | 8 +++---- .../Activities/Air/ResupplyAircraft.cs | 8 +++---- .../Activities/DeliverResources.cs | 4 +--- OpenRA.Mods.Common/Activities/DeliverUnit.cs | 8 +++---- OpenRA.Mods.Common/Activities/Enter.cs | 6 +++-- .../Activities/HarvesterDockSequence.cs | 4 ++-- .../Activities/Move/AttackMoveActivity.cs | 8 +++---- OpenRA.Mods.Common/Activities/Move/Drag.cs | 4 +--- OpenRA.Mods.Common/Activities/Move/Move.cs | 8 +++---- .../Activities/Move/MoveAdjacentTo.cs | 8 +++---- OpenRA.Mods.Common/Activities/Parachute.cs | 4 +--- OpenRA.Mods.Common/Activities/PickupUnit.cs | 8 +++---- OpenRA.Mods.Common/Activities/Sell.cs | 4 +--- OpenRA.Mods.Common/Activities/Wait.cs | 22 +++++++++---------- .../Activities/WaitForTransport.cs | 8 ++++--- OpenRA.Mods.Common/Scripting/CallLuaFunc.cs | 7 ++++-- 20 files changed, 76 insertions(+), 75 deletions(-) diff --git a/OpenRA.Game/Activities/Activity.cs b/OpenRA.Game/Activities/Activity.cs index 124db71267..57987226c1 100644 --- a/OpenRA.Game/Activities/Activity.cs +++ b/OpenRA.Game/Activities/Activity.cs @@ -18,14 +18,25 @@ namespace OpenRA.Activities public abstract class Activity { public Activity NextActivity { get; set; } + public bool IsInterruptible { get; protected set; } protected bool IsCanceled { get; private set; } + public Activity() + { + IsInterruptible = true; + } + public abstract Activity Tick(Actor self); - public virtual void Cancel(Actor self) + public virtual bool Cancel(Actor self) { + if (!IsInterruptible) + return false; + IsCanceled = true; NextActivity = null; + + return true; } public virtual void Queue(Activity activity) diff --git a/OpenRA.Game/Activities/CallFunc.cs b/OpenRA.Game/Activities/CallFunc.cs index f19dc129ce..2f5a52554d 100644 --- a/OpenRA.Game/Activities/CallFunc.cs +++ b/OpenRA.Game/Activities/CallFunc.cs @@ -19,22 +19,15 @@ namespace OpenRA.Activities public CallFunc(Action a, bool interruptable) { this.a = a; - this.interruptable = interruptable; + IsInterruptible = interruptable; } Action a; - bool interruptable; public override Activity Tick(Actor self) { if (a != null) a(); return NextActivity; } - - public override void Cancel(Actor self) - { - if (interruptable) - base.Cancel(self); - } } } diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 17cb712691..78eed676ce 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -206,10 +206,12 @@ namespace OpenRA CurrentActivity.Queue(nextActivity); } - public void CancelActivity() + public bool CancelActivity() { if (CurrentActivity != null) - CurrentActivity.Cancel(this); + return CurrentActivity.Cancel(this); + + return true; } public override int GetHashCode() diff --git a/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs b/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs index 282b7b968e..a578e3fa6e 100644 --- a/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs +++ b/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs @@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Activities public FallToEarth(Actor self, FallsToEarthInfo info) { this.info = info; + IsInterruptible = false; aircraft = self.Trait(); if (info.Spins) acceleration = self.World.SharedRandom.Next(2) * 2 - 1; @@ -57,8 +58,5 @@ namespace OpenRA.Mods.Common.Activities return this; } - - // Cannot be cancelled - public override void Cancel(Actor self) { } } } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index a1b31b1b92..d5b96318db 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -68,13 +68,13 @@ namespace OpenRA.Mods.Common.Activities return this; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (!IsCanceled && inner != null) - inner.Cancel(self); + if (!IsCanceled && inner != null && !inner.Cancel(self)) + return false; // NextActivity must always be set to null: - base.Cancel(self); + return base.Cancel(self); } } } diff --git a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs index f481ba7652..7cb0d985ac 100644 --- a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs +++ b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs @@ -63,12 +63,12 @@ namespace OpenRA.Mods.Common.Activities return inner == null || inner == NextActivity ? NextActivity : this; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (!IsCanceled && inner != null) - inner.Cancel(self); + if (!IsCanceled && inner != null && !inner.Cancel(self)) + return false; - base.Cancel(self); + return base.Cancel(self); } } } diff --git a/OpenRA.Mods.Common/Activities/DeliverResources.cs b/OpenRA.Mods.Common/Activities/DeliverResources.cs index 07513d346b..07a009fe3b 100644 --- a/OpenRA.Mods.Common/Activities/DeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/DeliverResources.cs @@ -30,6 +30,7 @@ namespace OpenRA.Mods.Common.Activities { movement = self.Trait(); harv = self.Trait(); + IsInterruptible = false; } public override Activity Tick(Actor self) @@ -79,8 +80,5 @@ namespace OpenRA.Mods.Common.Activities return ActivityUtils.SequenceActivities(new Wait(10), this); } - - // Cannot be cancelled - public override void Cancel(Actor self) { } } } diff --git a/OpenRA.Mods.Common/Activities/DeliverUnit.cs b/OpenRA.Mods.Common/Activities/DeliverUnit.cs index cbb91be573..da92aa0294 100644 --- a/OpenRA.Mods.Common/Activities/DeliverUnit.cs +++ b/OpenRA.Mods.Common/Activities/DeliverUnit.cs @@ -207,12 +207,12 @@ namespace OpenRA.Mods.Common.Activities }); } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (innerActivity != null) - innerActivity.Cancel(self); + if (!IsCanceled && innerActivity != null && !innerActivity.Cancel(self)) + return false; - base.Cancel(self); + return base.Cancel(self); } } } diff --git a/OpenRA.Mods.Common/Activities/Enter.cs b/OpenRA.Mods.Common/Activities/Enter.cs index 02d2b39dce..b5d2f364dd 100644 --- a/OpenRA.Mods.Common/Activities/Enter.cs +++ b/OpenRA.Mods.Common/Activities/Enter.cs @@ -112,13 +112,15 @@ namespace OpenRA.Mods.Common.Activities inner.Cancel(self); } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { AbortOrExit(self); if (nextState < State.Exiting) - base.Cancel(self); + return base.Cancel(self); else NextActivity = null; + + return true; } ReserveStatus TryReserveElseTryAlternateReserve(Actor self) diff --git a/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs b/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs index f4c9e3a757..124d5d6358 100644 --- a/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs +++ b/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs @@ -81,10 +81,10 @@ namespace OpenRA.Mods.Common.Activities throw new InvalidOperationException("Invalid harvester dock state"); } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { dockingState = State.Undock; - base.Cancel(self); + return base.Cancel(self); } public override IEnumerable GetTargets(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs b/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs index 6bf1e1b39d..89c6ebb2e7 100644 --- a/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs +++ b/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs @@ -46,12 +46,12 @@ namespace OpenRA.Mods.Common.Activities return this; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (inner != null) - inner.Cancel(self); + if (!IsCanceled && inner != null && !inner.Cancel(self)) + return false; - base.Cancel(self); + return base.Cancel(self); } public override IEnumerable GetTargets(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Move/Drag.cs b/OpenRA.Mods.Common/Activities/Move/Drag.cs index e3edc8950c..878641e5ca 100644 --- a/OpenRA.Mods.Common/Activities/Move/Drag.cs +++ b/OpenRA.Mods.Common/Activities/Move/Drag.cs @@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Activities this.start = start; this.end = end; this.length = length; + IsInterruptible = false; } public override Activity Tick(Actor self) @@ -62,8 +63,5 @@ namespace OpenRA.Mods.Common.Activities { yield return Target.FromPos(end); } - - // Cannot be cancelled - public override void Cancel(Actor self) { } } } diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 7fff6ec86e..14b57f6bca 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -272,10 +272,10 @@ namespace OpenRA.Mods.Common.Activities return Pair.New(nextCell, subCell); } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { path = NoPath; - base.Cancel(self); + return base.Cancel(self); } public override IEnumerable GetTargets(Actor self) @@ -331,10 +331,10 @@ namespace OpenRA.Mods.Common.Activities } } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { Move.Cancel(self); - base.Cancel(self); + return base.Cancel(self); } public override void Queue(Activity activity) diff --git a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs index 9c434f2a9c..6dd4b0e343 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs @@ -161,12 +161,12 @@ namespace OpenRA.Mods.Common.Activities return Target.None; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (inner != null) - inner.Cancel(self); + if (!IsCanceled && inner != null && !inner.Cancel(self)) + return false; - base.Cancel(self); + return base.Cancel(self); } } } diff --git a/OpenRA.Mods.Common/Activities/Parachute.cs b/OpenRA.Mods.Common/Activities/Parachute.cs index c8056f7a69..834e63f721 100644 --- a/OpenRA.Mods.Common/Activities/Parachute.cs +++ b/OpenRA.Mods.Common/Activities/Parachute.cs @@ -37,6 +37,7 @@ namespace OpenRA.Mods.Common.Activities para = self.Info.TraitInfo(); fallVector = new WVec(0, 0, para.FallRate); this.dropPosition = dropPosition; + IsInterruptible = false; } Activity FirstTick(Actor self) @@ -91,8 +92,5 @@ namespace OpenRA.Mods.Common.Activities { NextActivity = activity; } - - // Cannot be cancelled - public override void Cancel(Actor self) { } } } diff --git a/OpenRA.Mods.Common/Activities/PickupUnit.cs b/OpenRA.Mods.Common/Activities/PickupUnit.cs index 1ffec9be7e..56e47f2c26 100644 --- a/OpenRA.Mods.Common/Activities/PickupUnit.cs +++ b/OpenRA.Mods.Common/Activities/PickupUnit.cs @@ -157,12 +157,12 @@ namespace OpenRA.Mods.Common.Activities }); } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (innerActivity != null) - innerActivity.Cancel(self); + if (!IsCanceled && innerActivity != null && !innerActivity.Cancel(self)) + return false; - base.Cancel(self); + return base.Cancel(self); } } } diff --git a/OpenRA.Mods.Common/Activities/Sell.cs b/OpenRA.Mods.Common/Activities/Sell.cs index d5131551bb..b1b9e1afd8 100644 --- a/OpenRA.Mods.Common/Activities/Sell.cs +++ b/OpenRA.Mods.Common/Activities/Sell.cs @@ -27,6 +27,7 @@ namespace OpenRA.Mods.Common.Activities health = self.TraitOrDefault(); sellableInfo = self.Info.TraitInfo(); playerResources = self.Owner.PlayerActor.Trait(); + IsInterruptible = false; } public override Activity Tick(Actor self) @@ -45,8 +46,5 @@ namespace OpenRA.Mods.Common.Activities self.Dispose(); return this; } - - // Cannot be cancelled - public override void Cancel(Actor self) { } } } diff --git a/OpenRA.Mods.Common/Activities/Wait.cs b/OpenRA.Mods.Common/Activities/Wait.cs index e73d026198..db0199c811 100644 --- a/OpenRA.Mods.Common/Activities/Wait.cs +++ b/OpenRA.Mods.Common/Activities/Wait.cs @@ -17,13 +17,12 @@ namespace OpenRA.Mods.Common.Activities public class Wait : Activity { int remainingTicks; - bool interruptable = true; public Wait(int period) { remainingTicks = period; } public Wait(int period, bool interruptable) { remainingTicks = period; - this.interruptable = interruptable; + IsInterruptible = interruptable; } public override Activity Tick(Actor self) @@ -31,26 +30,25 @@ namespace OpenRA.Mods.Common.Activities return (remainingTicks-- == 0) ? NextActivity : this; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (!interruptable) - return; + if (!base.Cancel(self)) + return false; remainingTicks = 0; - base.Cancel(self); + return true; } } public class WaitFor : Activity { Func f; - bool interruptable = true; public WaitFor(Func f) { this.f = f; } public WaitFor(Func f, bool interruptable) { this.f = f; - this.interruptable = interruptable; + IsInterruptible = interruptable; } public override Activity Tick(Actor self) @@ -58,13 +56,13 @@ namespace OpenRA.Mods.Common.Activities return (f == null || f()) ? NextActivity : this; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (!interruptable) - return; + if (!base.Cancel(self)) + return false; f = null; - base.Cancel(self); + return true; } } } diff --git a/OpenRA.Mods.Common/Activities/WaitForTransport.cs b/OpenRA.Mods.Common/Activities/WaitForTransport.cs index f8ca43542f..95ae844f3e 100644 --- a/OpenRA.Mods.Common/Activities/WaitForTransport.cs +++ b/OpenRA.Mods.Common/Activities/WaitForTransport.cs @@ -41,10 +41,12 @@ namespace OpenRA.Mods.Common.Activities return this; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { - if (inner != null) - inner.Cancel(self); + if (!IsCanceled && inner != null && !inner.Cancel(self)) + return false; + + return base.Cancel(self); } } } diff --git a/OpenRA.Mods.Common/Scripting/CallLuaFunc.cs b/OpenRA.Mods.Common/Scripting/CallLuaFunc.cs index a398804715..1e36e4310f 100644 --- a/OpenRA.Mods.Common/Scripting/CallLuaFunc.cs +++ b/OpenRA.Mods.Common/Scripting/CallLuaFunc.cs @@ -43,10 +43,13 @@ namespace OpenRA.Mods.Common.Activities return NextActivity; } - public override void Cancel(Actor self) + public override bool Cancel(Actor self) { + if (!base.Cancel(self)) + return false; + Dispose(); - base.Cancel(self); + return true; } public void Dispose()