From ef665df2e9ca2e776baad3a493b12112d7ebedcd Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 22 Sep 2010 10:13:13 +1200 Subject: [PATCH] refactor activity queueing --- OpenRA.Game/Actor.cs | 11 ++------- OpenRA.Game/Traits/Activities/Drag.cs | 10 +++++++- OpenRA.Game/Traits/Activities/Idle.cs | 10 +++++++- OpenRA.Game/Traits/Activities/Move.cs | 23 +++++++++++------ OpenRA.Game/Traits/Activities/RemoveSelf.cs | 11 +++------ OpenRA.Game/Traits/Activities/Sell.cs | 10 +++++++- OpenRA.Game/Traits/Activities/Turn.cs | 12 +++------ OpenRA.Game/Traits/TraitsInterfaces.cs | 26 +++++++++++++++++++- OpenRA.Game/Traits/Util.cs | 2 +- OpenRA.Mods.RA/Activities/Attack.cs | 13 +++++----- OpenRA.Mods.RA/Activities/CallFunc.cs | 10 +++++++- OpenRA.Mods.RA/Activities/CaptureBuilding.cs | 9 +++---- OpenRA.Mods.RA/Activities/DeliverOre.cs | 16 +++++++++--- OpenRA.Mods.RA/Activities/Demolish.cs | 10 +++----- OpenRA.Mods.RA/Activities/EnterTransport.cs | 10 +++----- OpenRA.Mods.RA/Activities/Fly.cs | 11 +++------ OpenRA.Mods.RA/Activities/FlyAttack.cs | 19 +++++--------- OpenRA.Mods.RA/Activities/FlyTimed.cs | 19 ++++++++------ OpenRA.Mods.RA/Activities/Follow.cs | 22 ++++++----------- OpenRA.Mods.RA/Activities/Harvest.cs | 12 +++++++-- OpenRA.Mods.RA/Activities/HeliAttack.cs | 12 +++------ OpenRA.Mods.RA/Activities/HeliFly.cs | 12 +++------ OpenRA.Mods.RA/Activities/HeliLand.cs | 10 +++----- OpenRA.Mods.RA/Activities/HeliReturn.cs | 11 +++------ OpenRA.Mods.RA/Activities/IdleAnimation.cs | 10 +++++++- OpenRA.Mods.RA/Activities/Infiltrate.cs | 8 +++--- OpenRA.Mods.RA/Activities/Land.cs | 11 +++------ OpenRA.Mods.RA/Activities/LayMines.cs | 22 ++++++++--------- OpenRA.Mods.RA/Activities/Leap.cs | 12 +++------ OpenRA.Mods.RA/Activities/Rearm.cs | 10 +++----- OpenRA.Mods.RA/Activities/Repair.cs | 10 +++----- OpenRA.Mods.RA/Activities/RepairBuilding.cs | 13 ++++------ OpenRA.Mods.RA/Activities/ReturnToBase.cs | 11 +++------ OpenRA.Mods.RA/Activities/Teleport.cs | 8 ++---- OpenRA.Mods.RA/Activities/Transform.cs | 12 +++------ OpenRA.Mods.RA/Activities/UnloadCargo.cs | 13 +++------- OpenRA.Mods.RA/Activities/Wait.cs | 14 ++++++++--- 37 files changed, 229 insertions(+), 236 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index ce2985e3c0..fe2ac3a27d 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -151,16 +151,9 @@ namespace OpenRA public void QueueActivity( IActivity nextActivity ) { if( currentActivity == null ) - { currentActivity = nextActivity; - return; - } - var act = currentActivity; - while( act.NextActivity != null ) - { - act = act.NextActivity; - } - act.NextActivity = nextActivity; + else + currentActivity.Queue( nextActivity ); } public void CancelActivity() diff --git a/OpenRA.Game/Traits/Activities/Drag.cs b/OpenRA.Game/Traits/Activities/Drag.cs index c39b6e1f5c..62824bed87 100644 --- a/OpenRA.Game/Traits/Activities/Drag.cs +++ b/OpenRA.Game/Traits/Activities/Drag.cs @@ -14,7 +14,7 @@ namespace OpenRA.Traits.Activities { public class Drag : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } float2 endLocation; float2 startLocation; @@ -40,5 +40,13 @@ namespace OpenRA.Traits.Activities } public void Cancel(Actor self) { } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Game/Traits/Activities/Idle.cs b/OpenRA.Game/Traits/Activities/Idle.cs index c8b284bc8a..362150cdc5 100644 --- a/OpenRA.Game/Traits/Activities/Idle.cs +++ b/OpenRA.Game/Traits/Activities/Idle.cs @@ -12,9 +12,17 @@ namespace OpenRA.Traits.Activities { class Idle : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } public IActivity Tick(Actor self) { return NextActivity; } public void Cancel(Actor self) {} + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Game/Traits/Activities/Move.cs b/OpenRA.Game/Traits/Activities/Move.cs index 6c73686faf..e7b9b61efb 100755 --- a/OpenRA.Game/Traits/Activities/Move.cs +++ b/OpenRA.Game/Traits/Activities/Move.cs @@ -17,7 +17,7 @@ namespace OpenRA.Traits.Activities { public class Move : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } int2? destination; int nearEnough; @@ -164,9 +164,7 @@ namespace OpenRA.Traits.Activities Log.Write("debug", "Turn: #{0} from {1} to {2}", self.ActorID, mobile.Facing, firstFacing); - return new Turn( firstFacing ) - { NextActivity = this } - .Tick( self ); + return Util.SequenceActivities( new Turn( firstFacing ), this ).Tick( self ); } else { @@ -261,6 +259,14 @@ namespace OpenRA.Traits.Activities NextActivity = null; } + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } + abstract class MovePart : IActivity { public readonly Move move; @@ -280,11 +286,14 @@ namespace OpenRA.Traits.Activities this.moveFractionTotal = (int)(( to - from ).Length*3); } - public IActivity NextActivity { get { return move; } set { move.NextActivity = value; } } - public void Cancel( Actor self ) { - NextActivity.Cancel( self ); + move.Cancel( self ); + } + + public void Queue( IActivity activity ) + { + move.Queue( activity ); } public IActivity Tick( Actor self ) diff --git a/OpenRA.Game/Traits/Activities/RemoveSelf.cs b/OpenRA.Game/Traits/Activities/RemoveSelf.cs index 4e9d57f5ee..cff8b64727 100644 --- a/OpenRA.Game/Traits/Activities/RemoveSelf.cs +++ b/OpenRA.Game/Traits/Activities/RemoveSelf.cs @@ -10,18 +10,13 @@ namespace OpenRA.Traits.Activities { - public class RemoveSelf : IActivity + public class RemoveSelf : CancelableActivity { - bool isCanceled; - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; self.Destroy(); return null; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Game/Traits/Activities/Sell.cs b/OpenRA.Game/Traits/Activities/Sell.cs index 1c13b05aab..c4491905d0 100644 --- a/OpenRA.Game/Traits/Activities/Sell.cs +++ b/OpenRA.Game/Traits/Activities/Sell.cs @@ -12,7 +12,7 @@ namespace OpenRA.Traits.Activities { class Sell : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } bool started; @@ -55,5 +55,13 @@ namespace OpenRA.Traits.Activities } public void Cancel(Actor self) { /* never gonna give you up.. */ } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Game/Traits/Activities/Turn.cs b/OpenRA.Game/Traits/Activities/Turn.cs index 50e91b5e78..fcc223049e 100755 --- a/OpenRA.Game/Traits/Activities/Turn.cs +++ b/OpenRA.Game/Traits/Activities/Turn.cs @@ -12,9 +12,8 @@ using System.Linq; namespace OpenRA.Traits.Activities { - public class Turn : IActivity + public class Turn : CancelableActivity { - public IActivity NextActivity { get; set; } int desiredFacing; public Turn( int desiredFacing ) @@ -22,8 +21,9 @@ namespace OpenRA.Traits.Activities this.desiredFacing = desiredFacing; } - public IActivity Tick( Actor self ) + public override IActivity Tick( Actor self ) { + if (IsCanceled) return NextActivity; var facing = self.Trait(); if( desiredFacing == facing.Facing ) @@ -32,11 +32,5 @@ namespace OpenRA.Traits.Activities return this; } - - public void Cancel( Actor self ) - { - desiredFacing = self.Trait().Facing; - NextActivity = null; - } } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 675909c98a..445e40f870 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -170,9 +170,33 @@ namespace OpenRA.Traits public interface IActivity { - IActivity NextActivity { get; set; } IActivity Tick(Actor self); void Cancel(Actor self); + void Queue(IActivity activity); + } + + public abstract class CancelableActivity : IActivity + { + protected IActivity NextActivity { get; private set; } + protected bool IsCanceled { get; private set; } + + public abstract IActivity Tick( Actor self ); + protected virtual void OnCancel() {} + + public void Cancel( Actor self ) + { + IsCanceled = true; + NextActivity = null; + OnCancel(); + } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } public interface IRenderOverlay { void Render(); } diff --git a/OpenRA.Game/Traits/Util.cs b/OpenRA.Game/Traits/Util.cs index 27a080074e..bd6d5850e1 100755 --- a/OpenRA.Game/Traits/Util.cs +++ b/OpenRA.Game/Traits/Util.cs @@ -113,7 +113,7 @@ namespace OpenRA.Traits public static IActivity SequenceActivities(params IActivity[] acts) { return acts.Reverse().Aggregate( - (next, a) => { a.NextActivity = next; return a; }); + (next, a) => { a.Queue( next ); return a; }); } public static Color ArrayToColor(int[] x) { return Color.FromArgb(x[0], x[1], x[2]); } diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index 638c0ca44e..c1fe9096ba 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -15,7 +15,7 @@ using OpenRA.Traits.Activities; namespace OpenRA.Mods.RA.Activities { /* non-turreted attack */ - public class Attack : IActivity + public class Attack : CancelableActivity { Target Target; int Range; @@ -26,10 +26,11 @@ namespace OpenRA.Mods.RA.Activities Range = range; } - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } - public IActivity Tick( Actor self ) + public override IActivity Tick( Actor self ) { + if (IsCanceled) return NextActivity; var facing = self.Trait(); if (!Target.IsValid) return NextActivity; @@ -37,7 +38,7 @@ namespace OpenRA.Mods.RA.Activities var targetCell = Util.CellContaining(Target.CenterLocation); if ((targetCell - self.Location).LengthSquared >= Range * Range) - return new Move( Target, Range ) { NextActivity = this }; + return Util.SequenceActivities( new Move( Target, Range ), this ); var desiredFacing = Util.GetFacing((targetCell - self.Location).ToFloat2(), 0); var renderUnit = self.TraitOrDefault(); @@ -47,7 +48,7 @@ namespace OpenRA.Mods.RA.Activities if (Util.QuantizeFacing(facing.Facing, numDirs) != Util.QuantizeFacing(desiredFacing, numDirs)) { - return new Turn( desiredFacing ) { NextActivity = this }; + return Util.SequenceActivities( new Turn( desiredFacing ), this ); } var attack = self.Trait(); @@ -55,7 +56,5 @@ namespace OpenRA.Mods.RA.Activities attack.DoAttack(self); return this; } - - public void Cancel(Actor self) { Target = Target.None; } } } diff --git a/OpenRA.Mods.RA/Activities/CallFunc.cs b/OpenRA.Mods.RA/Activities/CallFunc.cs index 8dfe042321..092d0a5af4 100644 --- a/OpenRA.Mods.RA/Activities/CallFunc.cs +++ b/OpenRA.Mods.RA/Activities/CallFunc.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Activities Action a; bool interruptable; - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } public IActivity Tick(Actor self) { @@ -40,5 +40,13 @@ namespace OpenRA.Mods.RA.Activities a = null; NextActivity = null; } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Mods.RA/Activities/CaptureBuilding.cs b/OpenRA.Mods.RA/Activities/CaptureBuilding.cs index 61e65a0aff..dfb9f859bf 100644 --- a/OpenRA.Mods.RA/Activities/CaptureBuilding.cs +++ b/OpenRA.Mods.RA/Activities/CaptureBuilding.cs @@ -12,16 +12,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class CaptureBuilding : IActivity + class CaptureBuilding : CancelableActivity { Target target; public CaptureBuilding(Actor target) { this.target = Target.FromActor(target); } - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { + if (IsCanceled) return NextActivity; if (!target.IsValid) return NextActivity; if ((target.Actor.Location - self.Location).Length > 1) return NextActivity; @@ -41,7 +40,5 @@ namespace OpenRA.Mods.RA.Activities }); return NextActivity; } - - public void Cancel(Actor self) { target = Target.None; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/DeliverOre.cs b/OpenRA.Mods.RA/Activities/DeliverOre.cs index 5c4af026f0..c6202faba0 100755 --- a/OpenRA.Mods.RA/Activities/DeliverOre.cs +++ b/OpenRA.Mods.RA/Activities/DeliverOre.cs @@ -15,7 +15,7 @@ namespace OpenRA.Mods.RA.Activities { public class DeliverResources : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } bool isDocking; @@ -32,25 +32,33 @@ namespace OpenRA.Mods.RA.Activities harv.ChooseNewProc(self, null); if (harv.LinkedProc == null) // no procs exist; check again in 1s. - return new Wait(25) { NextActivity = this }; + return Util.SequenceActivities( new Wait(25), this ); var proc = harv.LinkedProc; if( self.Location != proc.Location + proc.Trait().DeliverOffset ) { - return new Move(proc.Location + proc.Trait().DeliverOffset, 0) { NextActivity = this }; + return Util.SequenceActivities( new Move(proc.Location + proc.Trait().DeliverOffset, 0), this ); } else if (!isDocking) { isDocking = true; proc.Trait().OnDock(self, this); } - return new Wait(10) { NextActivity = this }; + return Util.SequenceActivities( new Wait(10), this ); } public void Cancel(Actor self) { // TODO: allow canceling of deliver orders? } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index eab7bfd823..d10de360cd 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -13,15 +13,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class Demolish : IActivity + class Demolish : CancelableActivity { Target target; - public IActivity NextActivity { get; set; } public Demolish( Actor target ) { this.target = Target.FromActor(target); } - public IActivity Tick(Actor self) - { + public override IActivity Tick(Actor self) + { + if( IsCanceled ) return NextActivity; if (!target.IsValid) return NextActivity; if ((target.Actor.Location - self.Location).Length > 1) return NextActivity; @@ -31,7 +31,5 @@ namespace OpenRA.Mods.RA.Activities () => { if (target.IsValid) target.Actor.Kill(self); }))); return NextActivity; } - - public void Cancel(Actor self) { target = Target.None; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/EnterTransport.cs b/OpenRA.Mods.RA/Activities/EnterTransport.cs index eb66d1ac8b..0ac42bde6f 100644 --- a/OpenRA.Mods.RA/Activities/EnterTransport.cs +++ b/OpenRA.Mods.RA/Activities/EnterTransport.cs @@ -12,10 +12,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class EnterTransport : IActivity + class EnterTransport : CancelableActivity { - public IActivity NextActivity { get; set; } - bool isCanceled; public Actor transport; public EnterTransport(Actor self, Actor transport) @@ -23,9 +21,9 @@ namespace OpenRA.Mods.RA.Activities this.transport = transport; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; if (transport == null || !transport.IsInWorld) return NextActivity; var cargo = transport.Trait(); @@ -43,7 +41,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/Fly.cs b/OpenRA.Mods.RA/Activities/Fly.cs index b8ef96e660..7810e01c3d 100644 --- a/OpenRA.Mods.RA/Activities/Fly.cs +++ b/OpenRA.Mods.RA/Activities/Fly.cs @@ -14,21 +14,18 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class Fly : IActivity + public class Fly : CancelableActivity { public readonly float2 Pos; - bool isCanceled; public Fly(float2 pos) { Pos = pos; } public Fly(int2 pos) { Pos = Util.CenterOfCell(pos); } - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { var cruiseAltitude = self.Info.Traits.Get().CruiseAltitude; - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; var d = Pos - self.CenterLocation; if (d.LengthSquared < 50) /* close enough */ @@ -46,8 +43,6 @@ namespace OpenRA.Mods.RA.Activities FlyUtil.Fly(self, cruiseAltitude); return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } public static class FlyUtil diff --git a/OpenRA.Mods.RA/Activities/FlyAttack.cs b/OpenRA.Mods.RA/Activities/FlyAttack.cs index fc64f4656e..adb56e0d67 100644 --- a/OpenRA.Mods.RA/Activities/FlyAttack.cs +++ b/OpenRA.Mods.RA/Activities/FlyAttack.cs @@ -12,15 +12,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class FlyAttack : IActivity + public class FlyAttack : CancelableActivity { - public IActivity NextActivity { get; set; } Target Target; public FlyAttack(Target target) { Target = target; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { + if (IsCanceled) return NextActivity; if (!Target.IsValid) return NextActivity; @@ -33,29 +33,22 @@ namespace OpenRA.Mods.RA.Activities new FlyTimed(50), this); } - - public void Cancel(Actor self) { Target = Target.None; NextActivity = null; } } - public class FlyCircle : IActivity + public class FlyCircle : CancelableActivity { - public IActivity NextActivity { get; set; } int2 Target; - bool isCanceled; public FlyCircle(int2 target) { Target = target; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) - return NextActivity; + if( IsCanceled ) return NextActivity; return Util.SequenceActivities( new Fly(Util.CenterOfCell(Target)), new FlyTimed(50), this); } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/FlyTimed.cs b/OpenRA.Mods.RA/Activities/FlyTimed.cs index b6f5c7121d..48ead5d901 100644 --- a/OpenRA.Mods.RA/Activities/FlyTimed.cs +++ b/OpenRA.Mods.RA/Activities/FlyTimed.cs @@ -12,27 +12,25 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class FlyTimed : IActivity + public class FlyTimed : CancelableActivity { - public IActivity NextActivity { get; set; } int remainingTicks; public FlyTimed(int ticks) { remainingTicks = ticks; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { + if( IsCanceled ) return NextActivity; var targetAltitude = self.Info.Traits.Get().CruiseAltitude; if (remainingTicks-- == 0) return NextActivity; FlyUtil.Fly(self, targetAltitude); return this; } - - public void Cancel(Actor self) { remainingTicks = 0; NextActivity = null; } } public class FlyOffMap : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } bool isCanceled; public bool Interruptible = true; @@ -52,6 +50,13 @@ namespace OpenRA.Mods.RA.Activities NextActivity = null; } } - } + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } + } } diff --git a/OpenRA.Mods.RA/Activities/Follow.cs b/OpenRA.Mods.RA/Activities/Follow.cs index 55b298071c..3b2790b178 100644 --- a/OpenRA.Mods.RA/Activities/Follow.cs +++ b/OpenRA.Mods.RA/Activities/Follow.cs @@ -13,7 +13,7 @@ using OpenRA.Traits.Activities; namespace OpenRA.Mods.RA.Activities { - public class Follow : IActivity + public class Follow : CancelableActivity { Target Target; int Range; @@ -24,24 +24,18 @@ namespace OpenRA.Mods.RA.Activities Range = range; } - public IActivity NextActivity { get; set; } - - public IActivity Tick( Actor self ) + public override IActivity Tick( Actor self ) { - if (!Target.IsValid) - return NextActivity; + if (IsCanceled) return NextActivity; + if (!Target.IsValid) return NextActivity; var inRange = ( Util.CellContaining( Target.CenterLocation ) - self.Location ).LengthSquared < Range * Range; - if( !inRange ) - return new Move( Target, Range ) { NextActivity = this }; + if( inRange ) return this; - return this; - } - - public void Cancel(Actor self) - { - Target = Target.None; + var ret = new Move( Target, Range ); + ret.Queue( this ); + return ret; } } } diff --git a/OpenRA.Mods.RA/Activities/Harvest.cs b/OpenRA.Mods.RA/Activities/Harvest.cs index c5e93788a8..2a7bfe4e0f 100755 --- a/OpenRA.Mods.RA/Activities/Harvest.cs +++ b/OpenRA.Mods.RA/Activities/Harvest.cs @@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA.Activities { public class Harvest : IActivity { - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } bool isHarvesting = false; public IActivity Tick( Actor self ) @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Activities harv.LastHarvestedCell = self.Location; if( harv.IsFull ) - return new DeliverResources { NextActivity = NextActivity }; + return Util.SequenceActivities( new DeliverResources(), NextActivity ); if (HarvestThisTile(self)) return this; @@ -74,5 +74,13 @@ namespace OpenRA.Mods.RA.Activities } public void Cancel(Actor self) { } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Mods.RA/Activities/HeliAttack.cs b/OpenRA.Mods.RA/Activities/HeliAttack.cs index f2c0216fb5..13a7a86032 100644 --- a/OpenRA.Mods.RA/Activities/HeliAttack.cs +++ b/OpenRA.Mods.RA/Activities/HeliAttack.cs @@ -14,17 +14,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class HeliAttack : IActivity + public class HeliAttack : CancelableActivity { Target target; public HeliAttack( Target target ) { this.target = target; } - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (!target.IsValid) - return NextActivity; + if (IsCanceled) return NextActivity; + if (!target.IsValid) return NextActivity; var limitedAmmo = self.TraitOrDefault(); if (limitedAmmo != null && !limitedAmmo.HasAmmo()) @@ -53,7 +51,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { target = Target.None; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/HeliFly.cs b/OpenRA.Mods.RA/Activities/HeliFly.cs index 37c532c160..5bfcb68fec 100644 --- a/OpenRA.Mods.RA/Activities/HeliFly.cs +++ b/OpenRA.Mods.RA/Activities/HeliFly.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class HeliFly : IActivity + class HeliFly : CancelableActivity { public readonly float2 Dest; public HeliFly(float2 dest) @@ -22,13 +22,9 @@ namespace OpenRA.Mods.RA.Activities Dest = dest; } - public IActivity NextActivity { get; set; } - bool isCanceled; - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) - return NextActivity; + if (IsCanceled) return NextActivity; var info = self.Info.Traits.Get(); var aircraft = self.Trait(); @@ -57,7 +53,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/HeliLand.cs b/OpenRA.Mods.RA/Activities/HeliLand.cs index b0d7ecf2c8..92ee54f1bb 100644 --- a/OpenRA.Mods.RA/Activities/HeliLand.cs +++ b/OpenRA.Mods.RA/Activities/HeliLand.cs @@ -12,17 +12,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class HeliLand : IActivity + class HeliLand : CancelableActivity { public HeliLand(bool requireSpace) { this.requireSpace = requireSpace; } bool requireSpace; - bool isCanceled; - public IActivity NextActivity { get; set; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; var aircraft = self.Trait(); if (aircraft.Altitude == 0) return NextActivity; @@ -33,7 +31,5 @@ namespace OpenRA.Mods.RA.Activities --aircraft.Altitude; return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/HeliReturn.cs b/OpenRA.Mods.RA/Activities/HeliReturn.cs index 8eeaad0af6..e80f7ced17 100644 --- a/OpenRA.Mods.RA/Activities/HeliReturn.cs +++ b/OpenRA.Mods.RA/Activities/HeliReturn.cs @@ -14,11 +14,8 @@ using OpenRA.Traits.Activities; namespace OpenRA.Mods.RA.Activities { - public class HeliReturn : IActivity + public class HeliReturn : CancelableActivity { - public IActivity NextActivity { get; set; } - bool isCanceled; - static Actor ChooseHelipad(Actor self) { var rearmBuildings = self.Info.Traits.Get().RearmBuildings; @@ -27,9 +24,9 @@ namespace OpenRA.Mods.RA.Activities !Reservable.IsReserved(a)); } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; var dest = ChooseHelipad(self); var initialFacing = self.Info.Traits.Get().InitialFacing; @@ -54,7 +51,5 @@ namespace OpenRA.Mods.RA.Activities new Rearm(), NextActivity); } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/IdleAnimation.cs b/OpenRA.Mods.RA/Activities/IdleAnimation.cs index 8dd01f17c2..23738512a0 100644 --- a/OpenRA.Mods.RA/Activities/IdleAnimation.cs +++ b/OpenRA.Mods.RA/Activities/IdleAnimation.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities this.delay = delay; } - public IActivity NextActivity { get; set; } + IActivity NextActivity { get; set; } bool active = true; public IActivity Tick(Actor self) @@ -43,5 +43,13 @@ namespace OpenRA.Mods.RA.Activities active = false; NextActivity = null; } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } } diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index c88eea579b..2f1fceaf3f 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -12,14 +12,14 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class Infiltrate : IActivity + class Infiltrate : CancelableActivity { Actor target; public Infiltrate(Actor target) { this.target = target; } - public IActivity NextActivity { get; set; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { + if (IsCanceled) return NextActivity; if (target == null || target.IsDead()) return NextActivity; if (target.Owner == self.Owner) return NextActivity; @@ -30,7 +30,5 @@ namespace OpenRA.Mods.RA.Activities return NextActivity; } - - public void Cancel(Actor self) { target = null; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/Land.cs b/OpenRA.Mods.RA/Activities/Land.cs index 757cef3c2f..dd08e32d74 100644 --- a/OpenRA.Mods.RA/Activities/Land.cs +++ b/OpenRA.Mods.RA/Activities/Land.cs @@ -14,21 +14,18 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class Land : IActivity + public class Land : CancelableActivity { - bool isCanceled; Target Target; public Land(Target t) { Target = t; } - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { if (!Target.IsValid) Cancel(self); - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; var d = Target.CenterLocation - self.CenterLocation; if (d.LengthSquared < 50) /* close enough */ @@ -49,7 +46,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/LayMines.cs b/OpenRA.Mods.RA/Activities/LayMines.cs index 20f5f7e0b8..1ab5672a74 100644 --- a/OpenRA.Mods.RA/Activities/LayMines.cs +++ b/OpenRA.Mods.RA/Activities/LayMines.cs @@ -17,14 +17,11 @@ namespace OpenRA.Mods.RA.Activities { // assumes you have Minelayer on that unit - class LayMines : IActivity + class LayMines : CancelableActivity { - bool canceled = false; - public IActivity NextActivity { get; set; } - - public IActivity Tick( Actor self ) + public override IActivity Tick( Actor self ) { - if (canceled) return NextActivity; + if (IsCanceled) return NextActivity; var limitedAmmo = self.TraitOrDefault(); if (!limitedAmmo.HasAmmo()) @@ -37,8 +34,11 @@ namespace OpenRA.Mods.RA.Activities if (rearmTarget == null) return new Wait(20); - return new Move(Util.CellContaining(rearmTarget.CenterLocation), rearmTarget) - { NextActivity = new Rearm() { NextActivity = new Repair(rearmTarget) { NextActivity = this } } }; + return Util.SequenceActivities( + new Move(Util.CellContaining(rearmTarget.CenterLocation), rearmTarget), + new Rearm(), + new Repair(rearmTarget), + this ); } var ml = self.Trait(); @@ -46,14 +46,14 @@ namespace OpenRA.Mods.RA.Activities ShouldLayMine(self, self.Location)) { LayMine(self); - return new Wait(20) { NextActivity = this }; // a little wait after placing each mine, for show + return Util.SequenceActivities( new Wait(20), this ); // a little wait after placing each mine, for show } for (var n = 0; n < 20; n++) // dont get stuck forever here { var p = ml.minefield.Random(self.World.SharedRandom); if (ShouldLayMine(self, p)) - return new Move(p, 0) { NextActivity = this }; + return Util.SequenceActivities( new Move(p, 0), this ); } // todo: return somewhere likely to be safe (near fix) so we're not sitting out in the minefield. @@ -80,7 +80,5 @@ namespace OpenRA.Mods.RA.Activities new OwnerInit( self.Owner ), })); } - - public void Cancel( Actor self ) { canceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/Leap.cs b/OpenRA.Mods.RA/Activities/Leap.cs index 1d51627377..55797661e9 100644 --- a/OpenRA.Mods.RA/Activities/Leap.cs +++ b/OpenRA.Mods.RA/Activities/Leap.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class Leap : IActivity + class Leap : CancelableActivity { Target target; float2 initialLocation; @@ -31,12 +31,10 @@ namespace OpenRA.Mods.RA.Activities Sound.Play("dogg5p.aud", self.CenterLocation); } - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (!target.IsValid) - return NextActivity; + if (IsCanceled) return NextActivity; + if (!target.IsValid) return NextActivity; t += (1f / delay); @@ -54,7 +52,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { target = new Target(); NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/Rearm.cs b/OpenRA.Mods.RA/Activities/Rearm.cs index b78821f858..71f5040e63 100644 --- a/OpenRA.Mods.RA/Activities/Rearm.cs +++ b/OpenRA.Mods.RA/Activities/Rearm.cs @@ -14,17 +14,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class Rearm : IActivity + public class Rearm : CancelableActivity { - public IActivity NextActivity { get; set; } - bool isCanceled; int remainingTicks = ticksPerPip; const int ticksPerPip = 25 * 2; - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; var limitedAmmo = self.TraitOrDefault(); if (limitedAmmo == null) return NextActivity; @@ -43,7 +41,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/Repair.cs b/OpenRA.Mods.RA/Activities/Repair.cs index a27800f616..b7058fbac2 100644 --- a/OpenRA.Mods.RA/Activities/Repair.cs +++ b/OpenRA.Mods.RA/Activities/Repair.cs @@ -14,18 +14,16 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class Repair : IActivity + public class Repair : CancelableActivity { - public IActivity NextActivity { get; set; } - bool isCanceled; int remainingTicks; Actor host; public Repair(Actor host) { this.host = host; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; if (host != null && !host.IsInWorld) return NextActivity; if (remainingTicks == 0) { @@ -58,7 +56,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/RepairBuilding.cs b/OpenRA.Mods.RA/Activities/RepairBuilding.cs index 8ee7370a03..e737c71175 100644 --- a/OpenRA.Mods.RA/Activities/RepairBuilding.cs +++ b/OpenRA.Mods.RA/Activities/RepairBuilding.cs @@ -12,16 +12,15 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class RepairBuilding : IActivity + class RepairBuilding : CancelableActivity { Target target; public RepairBuilding(Actor target) { this.target = Target.FromActor(target); } - public IActivity NextActivity { get; set; } - - public IActivity Tick(Actor self) - { + public override IActivity Tick(Actor self) + { + if (IsCanceled) return NextActivity; if (!target.IsValid) return NextActivity; if ((target.Actor.Location - self.Location).Length > 1) return NextActivity; @@ -34,8 +33,6 @@ namespace OpenRA.Mods.RA.Activities self.Destroy(); return NextActivity; - } - - public void Cancel(Actor self) { target = Target.None; NextActivity = null; } + } } } diff --git a/OpenRA.Mods.RA/Activities/ReturnToBase.cs b/OpenRA.Mods.RA/Activities/ReturnToBase.cs index 1526616410..083fb9f18c 100644 --- a/OpenRA.Mods.RA/Activities/ReturnToBase.cs +++ b/OpenRA.Mods.RA/Activities/ReturnToBase.cs @@ -14,11 +14,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class ReturnToBase : IActivity + public class ReturnToBase : CancelableActivity { - public IActivity NextActivity { get; set; } - - bool isCanceled; bool isCalculated; Actor dest; @@ -88,9 +85,9 @@ namespace OpenRA.Mods.RA.Activities this.dest = dest; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; if (!isCalculated) Calculate(self); @@ -101,7 +98,5 @@ namespace OpenRA.Mods.RA.Activities new Land(Target.FromActor(dest)), NextActivity); } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/Teleport.cs b/OpenRA.Mods.RA/Activities/Teleport.cs index 1f57788ffa..41574dff81 100755 --- a/OpenRA.Mods.RA/Activities/Teleport.cs +++ b/OpenRA.Mods.RA/Activities/Teleport.cs @@ -13,10 +13,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - public class Teleport : IActivity + public class Teleport : CancelableActivity { - public IActivity NextActivity { get; set; } - int2 destination; public Teleport(int2 destination) @@ -24,12 +22,10 @@ namespace OpenRA.Mods.RA.Activities this.destination = destination; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { self.TraitsImplementing().FirstOrDefault().SetPosition(self, destination); return NextActivity; } - - public void Cancel(Actor self) { } } } diff --git a/OpenRA.Mods.RA/Activities/Transform.cs b/OpenRA.Mods.RA/Activities/Transform.cs index 26d32ec0e8..66adcca6f0 100644 --- a/OpenRA.Mods.RA/Activities/Transform.cs +++ b/OpenRA.Mods.RA/Activities/Transform.cs @@ -17,12 +17,11 @@ using OpenRA.FileFormats; namespace OpenRA.Mods.RA.Activities { - class Transform : IActivity + class Transform : CancelableActivity { string actor = null; int2 offset; string[] sounds = null; - bool isCanceled; int facing; RenderBuilding rb; @@ -34,10 +33,7 @@ namespace OpenRA.Mods.RA.Activities this.facing = facing; rb = self.TraitOrDefault(); } - - public IActivity NextActivity { get; set; } - void DoTransform(Actor self) { // Hack: repeat the first frame of the make anim instead @@ -70,9 +66,9 @@ namespace OpenRA.Mods.RA.Activities } bool started = false; - public IActivity Tick( Actor self ) + public override IActivity Tick( Actor self ) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; if (started) return this; if (rb == null) @@ -88,7 +84,5 @@ namespace OpenRA.Mods.RA.Activities } return this; } - - public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } } diff --git a/OpenRA.Mods.RA/Activities/UnloadCargo.cs b/OpenRA.Mods.RA/Activities/UnloadCargo.cs index b089d6f3c7..66cd235e2c 100644 --- a/OpenRA.Mods.RA/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.RA/Activities/UnloadCargo.cs @@ -16,11 +16,8 @@ using System.Drawing; namespace OpenRA.Mods.RA.Activities { - public class UnloadCargo : IActivity + public class UnloadCargo : CancelableActivity { - public IActivity NextActivity { get; set; } - bool isCanceled; - int2? ChooseExitTile(Actor self, Actor cargo) { // is anyone still hogging this tile? @@ -38,16 +35,16 @@ namespace OpenRA.Mods.RA.Activities return null; } - public IActivity Tick(Actor self) + public override IActivity Tick(Actor self) { - if (isCanceled) return NextActivity; + if (IsCanceled) return NextActivity; // if we're a thing that can turn, turn to the // right facing for the unload animation var facing = self.TraitOrDefault(); var unloadFacing = self.Info.Traits.Get().UnloadFacing; if (facing != null && facing.Facing != unloadFacing) - return new Turn(unloadFacing) { NextActivity = this }; + return Util.SequenceActivities( new Turn(unloadFacing), this ); // todo: handle the BS of open/close sequences, which are inconsistent, // for reasons that probably make good sense to the westwood guys. @@ -82,7 +79,5 @@ namespace OpenRA.Mods.RA.Activities return this; } - - public void Cancel(Actor self) { NextActivity = null; isCanceled = true; } } } diff --git a/OpenRA.Mods.RA/Activities/Wait.cs b/OpenRA.Mods.RA/Activities/Wait.cs index d1bbfb1f0d..23cf985e15 100644 --- a/OpenRA.Mods.RA/Activities/Wait.cs +++ b/OpenRA.Mods.RA/Activities/Wait.cs @@ -16,7 +16,8 @@ namespace OpenRA.Mods.RA.Activities { int remainingTicks; bool interruptable = true; - + IActivity NextActivity { get; set; } + public Wait(int period) { remainingTicks = period; } public Wait(int period, bool interruptable) { @@ -24,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities this.interruptable = interruptable; } - public IActivity Tick(Actor self) + public virtual IActivity Tick(Actor self) { if (remainingTicks-- == 0) return NextActivity; return this; @@ -38,6 +39,13 @@ namespace OpenRA.Mods.RA.Activities remainingTicks = 0; NextActivity = null; } - public IActivity NextActivity { get; set; } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } } }