diff --git a/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs b/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs index 55bdaa347e..84f28cb9d9 100644 --- a/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs +++ b/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs @@ -24,6 +24,7 @@ namespace OpenRA.Mods.Cnc enum State { Wait, + Turn, Dragin, Dock, Loop, @@ -41,7 +42,7 @@ namespace OpenRA.Mods.Cnc public HarvesterDockSequence(Actor self, Actor proc) { this.proc = proc; - state = State.Dragin; + state = State.Turn; harv = self.Trait(); rb = proc.Trait(); startDock = self.Trait().PxPosition; @@ -56,6 +57,9 @@ namespace OpenRA.Mods.Cnc { case State.Wait: return this; + case State.Turn: + state = State.Dragin; + return Util.SequenceActivities(new Turn(112), this); case State.Dragin: state = State.Dock; return Util.SequenceActivities(new Drag(startDock, endDock, 12), this); diff --git a/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs b/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs index 6a7173cb8c..143c5ace96 100644 --- a/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs +++ b/OpenRA.Mods.Cnc/TiberiumRefineryDockAction.cs @@ -19,69 +19,11 @@ using OpenRA.Mods.RA.Move; namespace OpenRA.Mods.Cnc { class TiberiumRefineryDockActionInfo : TraitInfo {} - class TiberiumRefineryDockAction : IAcceptOreDockAction, ITick, INotifyDamage, INotifySold, INotifyCapture + class TiberiumRefineryDockAction : OreRefineryDockAction { - Actor dockedHarv = null; - bool preventDock = false; - public void OnDock(Actor self, Actor harv, DeliverResources dockOrder) + public override IActivity DockSequence(Actor harv, Actor self) { - var mobile = harv.Trait(); - var harvester = harv.Trait(); - - harv.QueueActivity( new Turn(112) ); - - if (!preventDock) - { - harv.QueueActivity( new CallFunc( () => dockedHarv = harv, false ) ); - harv.QueueActivity( new HarvesterDockSequence(harv, self) ); - harv.QueueActivity( new CallFunc( () => dockedHarv = null, false ) ); - } - - // Tell the harvester to start harvesting - // TODO: This belongs on the harv idle activity - harv.QueueActivity( new CallFunc( () => - { - if (harvester.LastHarvestedCell != int2.Zero) - { - harv.QueueActivity( mobile.MoveTo(harvester.LastHarvestedCell, 5) ); - harv.SetTargetLine(Target.FromCell(harvester.LastHarvestedCell), Color.Red, false); - } - harv.QueueActivity( new Harvest() ); - })); - } - - public void Tick(Actor self) - { - // Harvester was killed while unloading - if (dockedHarv != null && dockedHarv.IsDead()) - { - self.Trait().CancelCustomAnim(self); - dockedHarv = null; - } - } - - void CancelDock(Actor self) - { - preventDock = true; - - // Cancel the dock sequence - if (dockedHarv != null && !dockedHarv.IsDead()) - dockedHarv.CancelActivity(); - } - - public void Selling (Actor self) { CancelDock(self); } - public void Sold (Actor self) {} - - public void Damaged (Actor self, AttackInfo e) - { - if (e.DamageState == DamageState.Dead) - CancelDock(self); - } - - public void OnCapture (Actor self, Actor captor, Player oldOwner, Player newOwner) - { - if (dockedHarv != null) - dockedHarv.ChangeOwner(newOwner); + return new HarvesterDockSequence(harv, self); } } } diff --git a/OpenRA.Mods.RA/Activities/RAHarvesterDockSequence.cs b/OpenRA.Mods.RA/Activities/RAHarvesterDockSequence.cs new file mode 100644 index 0000000000..930e480100 --- /dev/null +++ b/OpenRA.Mods.RA/Activities/RAHarvesterDockSequence.cs @@ -0,0 +1,94 @@ +#region Copyright & License Information +/* + * Copyright 2007-2010 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see LICENSE. + */ +#endregion + +using OpenRA.Mods.RA.Activities; +using OpenRA.Traits; +using OpenRA.Traits.Activities; +using System.Collections.Generic; +using OpenRA.Mods.RA.Move; +using OpenRA.Mods.RA.Render; +using System; + +namespace OpenRA.Mods.RA +{ + public class RAHarvesterDockSequence : IActivity + { + enum State + { + Wait, + Turn, + Dock, + Loop, + Undock, + Complete + }; + + readonly Actor proc; + readonly Harvester harv; + readonly RenderUnit ru; + State state; + + public RAHarvesterDockSequence(Actor self, Actor proc) + { + this.proc = proc; + state = State.Turn; + harv = self.Trait(); + ru = self.Trait(); + } + + IActivity NextActivity { get; set; } + + public IActivity Tick(Actor self) + { + switch (state) + { + case State.Wait: + return this; + case State.Turn: + state = State.Dock; + return Util.SequenceActivities(new Turn(64), this); + case State.Dock: + ru.PlayCustomAnimation(self, "dock", () => {ru.PlayCustomAnimRepeating(self, "dock-loop"); state = State.Loop;}); + state = State.Wait; + return this; + case State.Loop: + if (harv.TickUnload(self, proc)) + state = State.Undock; + return this; + case State.Undock: + ru.PlayCustomAnimBackwards(self, "dock", () => state = State.Complete); + state = State.Wait; + return this; + case State.Complete: + return NextActivity; + } + throw new InvalidOperationException("Invalid harvester dock state"); + } + + public void Cancel(Actor self) + { + state = State.Undock; + } + + public void Queue( IActivity activity ) + { + if( NextActivity != null ) + NextActivity.Queue( activity ); + else + NextActivity = activity; + } + + public IEnumerable GetCurrentPath() + { + yield break; + } + } +} + diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index c8c77b2507..7a921a31fc 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -328,6 +328,7 @@ + diff --git a/OpenRA.Mods.RA/OreRefineryDockAction.cs b/OpenRA.Mods.RA/OreRefineryDockAction.cs index 2951637a22..6737232524 100644 --- a/OpenRA.Mods.RA/OreRefineryDockAction.cs +++ b/OpenRA.Mods.RA/OreRefineryDockAction.cs @@ -17,43 +17,73 @@ using OpenRA.Mods.RA.Move; namespace OpenRA.Mods.RA { - class OreRefineryDockActionInfo : TraitInfo {} + public class OreRefineryDockActionInfo : TraitInfo {} - class OreRefineryDockAction : IAcceptOreDockAction, INotifyCapture + public class OreRefineryDockAction : IAcceptOreDockAction, INotifyCapture { - + public virtual IActivity DockSequence(Actor harv, Actor self) + { + return new RAHarvesterDockSequence(harv, self); + } + Actor dockedHarv = null; + bool preventDock = false; public void OnDock(Actor self, Actor harv, DeliverResources dockOrder) { + var mobile = harv.Trait(); var harvester = harv.Trait(); - - if (harv.Trait().Facing != 64) - harv.QueueActivity (new Turn (64)); - harv.QueueActivity (new CallFunc (() => + if (!preventDock) { - dockedHarv = harv; - var renderUnit = harv.Trait (); - if (renderUnit.anim.CurrentSequence.Name != "empty") - renderUnit.PlayCustomAnimation (harv, "empty", () => - { - harvester.Deliver(harv, self); - harv.QueueActivity( new CallFunc( () => dockedHarv = null, false ) ); - - if (harvester.LastHarvestedCell != int2.Zero) - { - var mobile = harv.Trait(); - harv.QueueActivity( mobile.MoveTo(harvester.LastHarvestedCell, 5) ); - harv.SetTargetLine(Target.FromCell(harvester.LastHarvestedCell), Color.Red, false); - } - harv.QueueActivity( new Harvest() ); - }); + harv.QueueActivity( new CallFunc( () => dockedHarv = harv, false ) ); + harv.QueueActivity( DockSequence(harv, self) ); + harv.QueueActivity( new CallFunc( () => dockedHarv = null, false ) ); + } + + // Tell the harvester to start harvesting + // TODO: This belongs on the harv idle activity + harv.QueueActivity( new CallFunc( () => + { + if (harvester.LastHarvestedCell != int2.Zero) + { + harv.QueueActivity( mobile.MoveTo(harvester.LastHarvestedCell, 5) ); + harv.SetTargetLine(Target.FromCell(harvester.LastHarvestedCell), Color.Red, false); + } + harv.QueueActivity( new Harvest() ); })); } + public void Tick(Actor self) + { + // Harvester was killed while unloading + if (dockedHarv != null && dockedHarv.IsDead()) + { + self.Trait().CancelCustomAnim(self); + dockedHarv = null; + } + } + + void CancelDock(Actor self) + { + preventDock = true; + + // Cancel the dock sequence + if (dockedHarv != null && !dockedHarv.IsDead()) + dockedHarv.CancelActivity(); + } + + public void Selling (Actor self) { CancelDock(self); } + public void Sold (Actor self) {} + + public void Damaged (Actor self, AttackInfo e) + { + if (e.DamageState == DamageState.Dead) + CancelDock(self); + } + public void OnCapture (Actor self, Actor captor, Player oldOwner, Player newOwner) - { - if (dockedHarv != null) + { + if (dockedHarv != null) dockedHarv.ChangeOwner(newOwner); } } diff --git a/OpenRA.Mods.RA/Render/RenderUnit.cs b/OpenRA.Mods.RA/Render/RenderUnit.cs index 6ed16ac5d3..a18d6090e6 100644 --- a/OpenRA.Mods.RA/Render/RenderUnit.cs +++ b/OpenRA.Mods.RA/Render/RenderUnit.cs @@ -37,7 +37,19 @@ namespace OpenRA.Mods.RA.Render { anim.PlayThen(newAnim, () => { anim.Play("idle"); if (after != null) after(); }); } + + public void PlayCustomAnimRepeating(Actor self, string name) + { + anim.PlayThen(name, + () => { PlayCustomAnimRepeating(self, name); }); + } + public void PlayCustomAnimBackwards(Actor self, string name, Action a) + { + anim.PlayBackwardsThen(name, + () => { anim.PlayRepeating("idle"); a(); }); + } + bool isSmoking; bool canSmoke; diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index c08bf63540..46833d22df 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -291,6 +291,7 @@ HARV: Harvester: Capacity: 20 Resources: Ore,Gems + UnloadTicksPerBale: 1 Health: HP: 600 Armor: diff --git a/mods/ra/sequences.yaml b/mods/ra/sequences.yaml index a591a21179..d57af36523 100644 --- a/mods/ra/sequences.yaml +++ b/mods/ra/sequences.yaml @@ -370,10 +370,12 @@ harv: Start: 32 Length: 8 Facings: 8 - empty: + dock: Start: 96 - Length: 15 - + Length: 8 + dock-loop: + Start: 104 + Length: 7 1tnk: idle: Start: 0