diff --git a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs index 3125eabcec..114436d4db 100644 --- a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs @@ -30,6 +30,7 @@ namespace OpenRA.Mods.Common.Activities readonly Actor deliverActor; CPos? orderLocation; + CPos? lastHarvestedCell; bool hasDeliveredLoad; bool hasHarvestedCell; bool hasWaited; @@ -58,7 +59,7 @@ namespace OpenRA.Mods.Common.Activities // the previous harvested cell for the initial search. if (orderLocation != null) { - harv.LastHarvestedCell = orderLocation; + lastHarvestedCell = orderLocation; // If two "harvest" orders are issued consecutively, we deliver the load first if needed. // We have to make sure the actual "harvest" order is not skipped if a third order is queued, @@ -114,33 +115,35 @@ namespace OpenRA.Mods.Common.Activities return this; } - var closestHarvestableCell = ClosestHarvestablePos(self); + hasWaited = false; - // If no resources are found near the current field, search near the refinery instead. - // If that doesn't help, give up for now. + // Scan for resources. If no resources are found near the current field, search near the refinery + // instead. If that doesn't help, give up for now. + var closestHarvestableCell = ClosestHarvestablePos(self); if (!closestHarvestableCell.HasValue) { - if (harv.LastHarvestedCell != null) + if (lastHarvestedCell != null) { - harv.LastHarvestedCell = null; // Forces search from backup position. + lastHarvestedCell = null; // Forces search from backup position. closestHarvestableCell = ClosestHarvestablePos(self); harv.LastSearchFailed = !closestHarvestableCell.HasValue; } else harv.LastSearchFailed = true; } + else + harv.LastSearchFailed = false; + // If no harvestable position could be found and we are at the refinery, get out of the way + // of the refinery entrance. if (harv.LastSearchFailed) { - // If no harvestable position could be found and we are at the refinery, get out of the way - // of the refinery entrance. var lastproc = harv.LastLinkedProc ?? harv.LinkedProc; if (lastproc != null && !lastproc.Disposed) { var deliveryLoc = lastproc.Location + lastproc.Trait().DeliveryOffset; if (self.Location == deliveryLoc && harv.IsEmpty) { - // Get out of the way: var unblockCell = deliveryLoc + harv.Info.UnblockCell; var moveTo = mobile.NearestMoveableCell(unblockCell, 1, 5); self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Green, false); @@ -151,21 +154,9 @@ namespace OpenRA.Mods.Common.Activities return this; } - // Attempt to claim the target cell - if (!claimLayer.TryClaimCell(self, closestHarvestableCell.Value)) - { - QueueChild(self, new Wait(25), true); - return this; - } - - harv.LastSearchFailed = false; - - foreach (var n in self.TraitsImplementing()) - n.MovingToResources(self, closestHarvestableCell.Value, new FindAndDeliverResources(self)); - - self.SetTargetLine(Target.FromCell(self.World, closestHarvestableCell.Value), Color.Red, false); - QueueChild(self, mobile.MoveTo(closestHarvestableCell.Value, 1), true); - QueueChild(self, new HarvestResource(self)); + // If we get here, our search for resources was successful. Commence harvesting. + QueueChild(self, new HarvestResource(self, closestHarvestableCell.Value), true); + lastHarvestedCell = closestHarvestableCell.Value; hasHarvestedCell = true; return this; } @@ -191,8 +182,8 @@ namespace OpenRA.Mods.Common.Activities } // Determine where to search from and how far to search: - var searchFromLoc = harv.LastHarvestedCell ?? GetSearchFromLocation(self); - var searchRadius = harv.LastHarvestedCell.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius; + var searchFromLoc = lastHarvestedCell ?? GetSearchFromLocation(self); + var searchRadius = lastHarvestedCell.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius; var searchRadiusSquared = searchRadius * searchRadius; // Find any harvestable resources: diff --git a/OpenRA.Mods.Common/Activities/HarvestResource.cs b/OpenRA.Mods.Common/Activities/HarvestResource.cs index 58e81f59f0..a073165de0 100644 --- a/OpenRA.Mods.Common/Activities/HarvestResource.cs +++ b/OpenRA.Mods.Common/Activities/HarvestResource.cs @@ -11,6 +11,7 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -23,15 +24,27 @@ namespace OpenRA.Mods.Common.Activities readonly ResourceClaimLayer claimLayer; readonly ResourceLayer resLayer; readonly BodyOrientation body; + readonly IMove move; + readonly CPos targetCell; - public HarvestResource(Actor self) + public HarvestResource(Actor self, CPos targetcell) { harv = self.Trait(); harvInfo = self.Info.TraitInfo(); facing = self.Trait(); body = self.Trait(); + move = self.Trait(); claimLayer = self.World.WorldActor.Trait(); resLayer = self.World.WorldActor.Trait(); + this.targetCell = targetcell; + } + + protected override void OnFirstRun(Actor self) + { + // We can safely assume the claim is successful, since this is only called in the + // same actor-tick as the targetCell is selected. Therefore no other harvester + // would have been able to claim. + claimLayer.TryClaimCell(self, targetCell); } public override Activity Tick(Actor self) @@ -43,19 +56,22 @@ namespace OpenRA.Mods.Common.Activities return this; } - if (IsCanceling) - { - claimLayer.RemoveClaim(self); + if (IsCanceling || harv.IsFull) return NextActivity; + + // Move towards the target cell + if (self.Location != targetCell) + { + foreach (var n in self.TraitsImplementing()) + n.MovingToResources(self, targetCell, new FindAndDeliverResources(self)); + + self.SetTargetLine(Target.FromCell(self.World, targetCell), Color.Red, false); + QueueChild(self, move.MoveTo(targetCell, 0), true); + return this; } - harv.LastHarvestedCell = self.Location; - - if (harv.IsFull) - { - claimLayer.RemoveClaim(self); + if (!harv.CanHarvestCell(self, self.Location)) return NextActivity; - } // Turn to one of the harvestable facings if (harvInfo.HarvestFacings != 0) @@ -71,10 +87,7 @@ namespace OpenRA.Mods.Common.Activities var resource = resLayer.Harvest(self.Location); if (resource == null) - { - claimLayer.RemoveClaim(self); return NextActivity; - } harv.AcceptResource(self, resource); @@ -84,5 +97,10 @@ namespace OpenRA.Mods.Common.Activities QueueChild(self, new Wait(harvInfo.BaleLoadDelay), true); return this; } + + protected override void OnLastRun(Actor self) + { + claimLayer.RemoveClaim(self); + } } } diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index e32cfa9bc8..7bff64806c 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -101,7 +101,6 @@ namespace OpenRA.Mods.Common.Traits [Sync] public Actor LastLinkedProc = null; [Sync] public Actor LinkedProc = null; [Sync] int currentUnloadTicks; - public CPos? LastHarvestedCell = null; [Sync] public int ContentValue