diff --git a/OpenRA.Mods.Common/Activities/DeliverResources.cs b/OpenRA.Mods.Common/Activities/DeliverResources.cs index ddb9627188..138a7bb275 100644 --- a/OpenRA.Mods.Common/Activities/DeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/DeliverResources.cs @@ -65,8 +65,7 @@ namespace OpenRA.Mods.Common.Activities self.SetTargetLine(Target.FromActor(proc), Color.Green, false); if (self.Location != proc.Location + iao.DeliveryOffset) { - var notify = self.TraitsImplementing(); - foreach (var n in notify) + foreach (var n in self.TraitsImplementing()) n.MovingToRefinery(self, proc, this); return ActivityUtils.SequenceActivities(movement.MoveTo(proc.Location + iao.DeliveryOffset, 0), this); diff --git a/OpenRA.Mods.Common/Activities/FindResources.cs b/OpenRA.Mods.Common/Activities/FindResources.cs index 6b91843d5d..33374825db 100644 --- a/OpenRA.Mods.Common/Activities/FindResources.cs +++ b/OpenRA.Mods.Common/Activities/FindResources.cs @@ -55,10 +55,8 @@ namespace OpenRA.Mods.Common.Activities if (NextInQueue != null) return NextInQueue; - var deliver = new DeliverResources(self); - if (harv.IsFull) - return ActivityUtils.SequenceActivities(deliver, NextActivity); + return ActivityUtils.SequenceActivities(new DeliverResources(self), NextActivity); var closestHarvestablePosition = ClosestHarvestablePos(self); @@ -67,20 +65,18 @@ namespace OpenRA.Mods.Common.Activities if (!closestHarvestablePosition.HasValue) { if (!harv.IsEmpty) - return deliver; + return new DeliverResources(self); harv.LastSearchFailed = true; var unblockCell = harv.LastHarvestedCell ?? (self.Location + harvInfo.UnblockCell); var moveTo = mobile.NearestMoveableCell(unblockCell, 2, 5); self.QueueActivity(mobile.MoveTo(moveTo, 1)); - self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false); - // TODO: The harvest-deliver-return sequence is a horrible mess of duplicated code and edge-cases - var notify = self.TraitsImplementing(); - foreach (var n in notify) + foreach (var n in self.TraitsImplementing()) n.MovingToResources(self, moveTo, this); + self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false); var randFrames = self.World.SharedRandom.Next(100, 175); // Avoid creating an activity cycle @@ -100,13 +96,10 @@ namespace OpenRA.Mods.Common.Activities if (!harv.LastOrderLocation.HasValue) harv.LastOrderLocation = closestHarvestablePosition; - self.SetTargetLine(Target.FromCell(self.World, closestHarvestablePosition.Value), Color.Red, false); - - // TODO: The harvest-deliver-return sequence is a horrible mess of duplicated code and edge-cases - var notify = self.TraitsImplementing(); - foreach (var n in notify) + foreach (var n in self.TraitsImplementing()) n.MovingToResources(self, closestHarvestablePosition.Value, this); + self.SetTargetLine(Target.FromCell(self.World, closestHarvestablePosition.Value), Color.Red, false); return ActivityUtils.SequenceActivities(mobile.MoveTo(closestHarvestablePosition.Value, 1), new HarvestResource(self), this); } } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index ae18e962f3..e2e9160f54 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -316,6 +316,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/AutoCarryable.cs b/OpenRA.Mods.Common/Traits/AutoCarryable.cs index 5791d56160..b376a12eca 100644 --- a/OpenRA.Mods.Common/Traits/AutoCarryable.cs +++ b/OpenRA.Mods.Common/Traits/AutoCarryable.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new AutoCarryable(init.Self, this); } } - public class AutoCarryable : Carryable, INotifyHarvesterAction, ICallForTransport + public class AutoCarryable : Carryable, ICallForTransport { readonly AutoCarryableInfo info; Activity afterLandActivity; @@ -38,21 +38,6 @@ namespace OpenRA.Mods.Common.Traits public WDist MinimumDistance { get { return info.MinDistance; } } - void INotifyHarvesterAction.MovingToResources(Actor self, CPos targetCell, Activity next) { RequestTransport(self, targetCell, next); } - - void INotifyHarvesterAction.MovingToRefinery(Actor self, Actor refineryActor, Activity next) - { - var iao = refineryActor.Trait(); - RequestTransport(self, refineryActor.Location + iao.DeliveryOffset, next); - } - - void INotifyHarvesterAction.MovementCancelled(Actor self) { MovementCancelled(self); } - - // We do not handle Harvested notification - void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource) { } - void INotifyHarvesterAction.Docked() { } - void INotifyHarvesterAction.Undocked() { } - // No longer want to be carried void ICallForTransport.MovementCancelled(Actor self) { MovementCancelled(self); } void ICallForTransport.RequestTransport(Actor self, CPos destination, Activity afterLandActivity) { RequestTransport(self, destination, afterLandActivity); } diff --git a/OpenRA.Mods.Common/Traits/CarryableHarvester.cs b/OpenRA.Mods.Common/Traits/CarryableHarvester.cs new file mode 100644 index 0000000000..94b721a1d5 --- /dev/null +++ b/OpenRA.Mods.Common/Traits/CarryableHarvester.cs @@ -0,0 +1,57 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 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, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Linq; +using OpenRA.Activities; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + public class CarryableHarvesterInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new CarryableHarvester(); } + } + + public class CarryableHarvester : INotifyCreated, INotifyHarvesterAction + { + ICallForTransport[] transports; + + void INotifyCreated.Created(Actor self) + { + transports = self.TraitsImplementing().ToArray(); + } + + void INotifyHarvesterAction.MovingToResources(Actor self, CPos targetCell, Activity next) + { + foreach (var t in transports) + t.RequestTransport(self, targetCell, next); + } + + void INotifyHarvesterAction.MovingToRefinery(Actor self, Actor refineryActor, Activity next) + { + var iao = refineryActor.Trait(); + var location = refineryActor.Location + iao.DeliveryOffset; + foreach (var t in transports) + t.RequestTransport(self, location, next); + } + + void INotifyHarvesterAction.MovementCancelled(Actor self) + { + foreach (var t in transports) + t.MovementCancelled(self); + } + + void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource) { } + void INotifyHarvesterAction.Docked() { } + void INotifyHarvesterAction.Undocked() { } + } +} diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index 46068bde7f..f1e5ac002f 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -83,9 +83,9 @@ namespace OpenRA.Mods.Common.Traits readonly Mobile mobile; readonly ResourceLayer resLayer; readonly ResourceClaimLayer claimLayer; - Dictionary contents = new Dictionary(); - INotifyHarvesterAction[] notify; + readonly Dictionary contents = new Dictionary(); bool idleSmart = true; + INotifyHarvesterAction[] notifyHarvesterAction; int idleDuration; [Sync] public bool LastSearchFailed; @@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits void INotifyCreated.Created(Actor self) { - notify = self.TraitsImplementing().ToArray(); + notifyHarvesterAction = self.TraitsImplementing().ToArray(); // Note: This is queued in a FrameEndTask because otherwise the activity is dropped/overridden while moving out of a factory. if (Info.SearchOnCreation) @@ -233,11 +233,8 @@ namespace OpenRA.Mods.Common.Traits var unblockCell = LastHarvestedCell ?? (deliveryLoc + Info.UnblockCell); var moveTo = mobile.NearestMoveableCell(unblockCell, 1, 5); - // TODO: The harvest-deliver-return sequence is a horrible mess of duplicated code and edge-cases - var notify = self.TraitsImplementing(); - var findResources = new FindResources(self); - foreach (var n in notify) - n.MovingToResources(self, moveTo, findResources); + // FindResources takes care of calling INotifyHarvesterAction + self.QueueActivity(new FindResources(self)); self.QueueActivity(mobile.MoveTo(moveTo, 1)); self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false); @@ -381,12 +378,10 @@ namespace OpenRA.Mods.Common.Traits loc = self.Location; } - var findResources = new FindResources(self); - self.QueueActivity(findResources); self.SetTargetLine(Target.FromCell(self.World, loc.Value), Color.Red); - foreach (var n in notify) - n.MovingToResources(self, loc.Value, findResources); + // FindResources takes care of calling INotifyHarvesterAction + self.QueueActivity(new FindResources(self)); LastOrderLocation = loc; @@ -414,16 +409,14 @@ namespace OpenRA.Mods.Common.Traits self.SetTargetLine(order.Target, Color.Green); self.CancelActivity(); + self.QueueActivity(new DeliverResources(self)); - var deliver = new DeliverResources(self); - self.QueueActivity(deliver); - - foreach (var n in notify) - n.MovingToRefinery(self, targetActor, deliver); + foreach (var n in notifyHarvesterAction) + n.MovingToRefinery(self, targetActor, new DeliverResources(self)); } else if (order.OrderString == "Stop" || order.OrderString == "Move") { - foreach (var n in notify) + foreach (var n in notifyHarvesterAction) n.MovementCancelled(self); // Turn off idle smarts to obey the stop/move: diff --git a/OpenRA.Mods.Common/Traits/Render/WithHarvestOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithHarvestOverlay.cs index 8a3770173d..f7fc075e2c 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithHarvestOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithHarvestOverlay.cs @@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits.Render p => ZOffsetFromCenter(self, p, 0)), info.Palette); } - public void Harvested(Actor self, ResourceType resource) + void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource) { if (visible) return; @@ -59,11 +59,11 @@ namespace OpenRA.Mods.Common.Traits.Render anim.PlayThen(info.Sequence, () => visible = false); } - public void MovingToResources(Actor self, CPos targetCell, Activity next) { } - public void MovingToRefinery(Actor self, Actor targetRefinery, Activity next) { } - public void MovementCancelled(Actor self) { } - public void Docked() { } - public void Undocked() { } + void INotifyHarvesterAction.MovingToResources(Actor self, CPos targetCell, Activity next) { } + void INotifyHarvesterAction.MovingToRefinery(Actor self, Actor targetRefinery, Activity next) { } + void INotifyHarvesterAction.MovementCancelled(Actor self) { } + void INotifyHarvesterAction.Docked() { } + void INotifyHarvesterAction.Undocked() { } public static int ZOffsetFromCenter(Actor self, WPos pos, int offset) { diff --git a/mods/d2k/rules/vehicles.yaml b/mods/d2k/rules/vehicles.yaml index be6122c69f..076643e59e 100644 --- a/mods/d2k/rules/vehicles.yaml +++ b/mods/d2k/rules/vehicles.yaml @@ -73,6 +73,7 @@ harvester: BaleUnloadDelay: 5 SearchFromProcRadius: 30 SearchFromOrderRadius: 15 + CarryableHarvester: Health: HP: 45000 Armor: