1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System; 13 using System.Collections.Generic; 14 using OpenRA.Activities; 15 using OpenRA.Mods.Common.Traits; 16 using OpenRA.Primitives; 17 using OpenRA.Traits; 18 19 namespace OpenRA.Mods.Common.Activities 20 { 21 public abstract class HarvesterDockSequence : Activity 22 { 23 protected enum DockingState { Wait, Turn, Dock, Loop, Undock, Complete } 24 25 protected readonly Actor Refinery; 26 protected readonly Harvester Harv; 27 protected readonly int DockAngle; 28 protected readonly bool IsDragRequired; 29 protected readonly WVec DragOffset; 30 protected readonly int DragLength; 31 protected readonly WPos StartDrag; 32 protected readonly WPos EndDrag; 33 34 protected DockingState dockingState; 35 HarvesterDockSequence(Actor self, Actor refinery, int dockAngle, bool isDragRequired, WVec dragOffset, int dragLength)36 public HarvesterDockSequence(Actor self, Actor refinery, int dockAngle, bool isDragRequired, WVec dragOffset, int dragLength) 37 { 38 dockingState = DockingState.Turn; 39 Refinery = refinery; 40 DockAngle = dockAngle; 41 IsDragRequired = isDragRequired; 42 DragOffset = dragOffset; 43 DragLength = dragLength; 44 Harv = self.Trait<Harvester>(); 45 StartDrag = self.CenterPosition; 46 EndDrag = refinery.CenterPosition + DragOffset; 47 } 48 Tick(Actor self)49 public override bool Tick(Actor self) 50 { 51 switch (dockingState) 52 { 53 case DockingState.Wait: 54 return false; 55 56 case DockingState.Turn: 57 dockingState = DockingState.Dock; 58 QueueChild(new Turn(self, DockAngle)); 59 if (IsDragRequired) 60 QueueChild(new Drag(self, StartDrag, EndDrag, DragLength)); 61 return false; 62 63 case DockingState.Dock: 64 if (Refinery.IsInWorld && !Refinery.IsDead) 65 foreach (var nd in Refinery.TraitsImplementing<INotifyDocking>()) 66 nd.Docked(Refinery, self); 67 68 OnStateDock(self); 69 return false; 70 71 case DockingState.Loop: 72 if (!Refinery.IsInWorld || Refinery.IsDead || Harv.TickUnload(self, Refinery)) 73 dockingState = DockingState.Undock; 74 75 return false; 76 77 case DockingState.Undock: 78 OnStateUndock(self); 79 return false; 80 81 case DockingState.Complete: 82 if (Refinery.IsInWorld && !Refinery.IsDead) 83 foreach (var nd in Refinery.TraitsImplementing<INotifyDocking>()) 84 nd.Undocked(Refinery, self); 85 86 Harv.LastLinkedProc = Harv.LinkedProc; 87 Harv.LinkProc(self, null); 88 if (IsDragRequired) 89 QueueChild(new Drag(self, EndDrag, StartDrag, DragLength)); 90 91 return true; 92 } 93 94 throw new InvalidOperationException("Invalid harvester dock state"); 95 } 96 Cancel(Actor self, bool keepQueue = false)97 public override void Cancel(Actor self, bool keepQueue = false) 98 { 99 dockingState = DockingState.Undock; 100 base.Cancel(self); 101 } 102 GetTargets(Actor self)103 public override IEnumerable<Target> GetTargets(Actor self) 104 { 105 yield return Target.FromActor(Refinery); 106 } 107 TargetLineNodes(Actor self)108 public override IEnumerable<TargetLineNode> TargetLineNodes(Actor self) 109 { 110 yield return new TargetLineNode(Target.FromActor(Refinery), Color.Green); 111 } 112 OnStateDock(Actor self)113 public abstract void OnStateDock(Actor self); 114 OnStateUndock(Actor self)115 public abstract void OnStateUndock(Actor self); 116 } 117 } 118