diff --git a/OpenRA.Mods.Common/Activities/FindResources.cs b/OpenRA.Mods.Common/Activities/FindResources.cs index 05e643aca7..24e1bcf6cb 100644 --- a/OpenRA.Mods.Common/Activities/FindResources.cs +++ b/OpenRA.Mods.Common/Activities/FindResources.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Activities readonly IPathFinder pathFinder; readonly DomainIndex domainIndex; - CPos? avoidCell; + CPos? orderLocation; public FindResources(Actor self) { @@ -41,10 +41,18 @@ namespace OpenRA.Mods.Common.Activities domainIndex = self.World.WorldActor.Trait(); } - public FindResources(Actor self, CPos avoidCell) + public FindResources(Actor self, CPos orderLocation) : this(self) { - this.avoidCell = avoidCell; + this.orderLocation = orderLocation; + } + + protected override void OnFirstRun(Actor self) + { + // Without this, multiple "Harvest" orders queued directly after each other + // will be skipped because the harvester starts off full. + if (harv.IsFull) + QueueChild(self, new DeliverResources(self)); } public override Activity Tick(Actor self) @@ -59,7 +67,17 @@ namespace OpenRA.Mods.Common.Activities return NextActivity; if (harv.IsFull) + { return NextActivity; + } + + // If an explicit order is given, direct the harvester to the ordered location instead of the previous + // harvested cell for the initial search. + if (orderLocation != null) + { + harv.LastHarvestedCell = orderLocation; + orderLocation = null; + } var closestHarvestablePosition = ClosestHarvestablePos(self); @@ -67,7 +85,13 @@ namespace OpenRA.Mods.Common.Activities // or get out of the way and do not disturb. if (!closestHarvestablePosition.HasValue) { - harv.LastSearchFailed = true; + // If no resources are found near the current field, search near the refinery instead. + // If that doesn't help, give up for now. + if (harv.LastHarvestedCell != null) + harv.LastHarvestedCell = null; + else + harv.LastSearchFailed = true; + var lastproc = harv.LastLinkedProc ?? harv.LinkedProc; if (lastproc != null && !lastproc.Disposed) { @@ -95,10 +119,6 @@ namespace OpenRA.Mods.Common.Activities harv.LastSearchFailed = false; - // If not given a direct order, assume ordered to the first resource location we find: - if (!harv.LastOrderLocation.HasValue) - harv.LastOrderLocation = closestHarvestablePosition; - foreach (var n in self.TraitsImplementing()) n.MovingToResources(self, closestHarvestablePosition.Value, new FindResources(self)); @@ -118,8 +138,8 @@ namespace OpenRA.Mods.Common.Activities return self.Location; // Determine where to search from and how far to search: - var searchFromLoc = GetSearchFromLocation(self); - var searchRadius = harv.LastOrderLocation.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius; + var searchFromLoc = harv.LastHarvestedCell ?? GetSearchFromLocation(self); + var searchRadius = harv.LastHarvestedCell.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius; var searchRadiusSquared = searchRadius * searchRadius; // Find any harvestable resources: @@ -128,14 +148,13 @@ namespace OpenRA.Mods.Common.Activities domainIndex.IsPassable(self.Location, loc, locomotorInfo) && harv.CanHarvestCell(self, loc) && claimLayer.CanClaimCell(self, loc)) .WithCustomCost(loc => { - if ((avoidCell.HasValue && loc == avoidCell.Value) || - (loc - self.Location).LengthSquared > searchRadiusSquared) + if ((loc - searchFromLoc).LengthSquared > searchRadiusSquared) return int.MaxValue; return 0; }) - .FromPoint(self.Location) - .FromPoint(searchFromLoc)) + .FromPoint(searchFromLoc) + .FromPoint(self.Location)) path = pathFinder.FindPath(search); if (path.Count > 0) @@ -151,12 +170,12 @@ namespace OpenRA.Mods.Common.Activities CPos GetSearchFromLocation(Actor self) { - if (harv.LastOrderLocation.HasValue) - return harv.LastOrderLocation.Value; - else if (harv.LastLinkedProc != null) + if (harv.LastLinkedProc != null) return harv.LastLinkedProc.Location + harv.LastLinkedProc.Trait().DeliveryOffset; - else if (harv.LinkedProc != null) + + if (harv.LinkedProc != null) return harv.LinkedProc.Location + harv.LinkedProc.Trait().DeliveryOffset; + return self.Location; } } diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index ab7613cb69..270cf66a50 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -82,14 +82,14 @@ namespace OpenRA.Mods.Common.Traits } public class Harvester : IIssueOrder, IResolveOrder, IPips, IOrderVoice, - ISpeedModifier, ISync, INotifyCreated, INotifyIdle, INotifyBlockingMove + ISpeedModifier, ISync, INotifyCreated, INotifyIdle { public readonly HarvesterInfo Info; readonly Mobile mobile; readonly ResourceLayer resLayer; readonly ResourceClaimLayer claimLayer; readonly Dictionary contents = new Dictionary(); - bool idleSmart = false; + bool idleSmart; INotifyHarvesterAction[] notifyHarvesterAction; ConditionManager conditionManager; int conditionToken = ConditionManager.InvalidConditionToken; @@ -101,7 +101,6 @@ namespace OpenRA.Mods.Common.Traits [Sync] public Actor LinkedProc = null; [Sync] int currentUnloadTicks; public CPos? LastHarvestedCell = null; - public CPos? LastOrderLocation = null; [Sync] public int ContentValue @@ -121,6 +120,7 @@ namespace OpenRA.Mods.Common.Traits mobile = self.Trait(); resLayer = self.World.WorldActor.Trait(); claimLayer = self.World.WorldActor.Trait(); + idleSmart = info.SearchOnCreation; self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null))); } @@ -130,8 +130,6 @@ namespace OpenRA.Mods.Common.Traits notifyHarvesterAction = self.TraitsImplementing().ToArray(); conditionManager = self.TraitOrDefault(); UpdateCondition(self); - if (Info.SearchOnCreation) - idleSmart = true; } public void SetProcLines(Actor proc) @@ -242,26 +240,6 @@ namespace OpenRA.Mods.Common.Traits UpdateCondition(self); } - void INotifyBlockingMove.OnNotifyBlockingMove(Actor self, Actor blocking) - { - // I'm blocking someone else from moving to my location: - var act = self.CurrentActivity; - - // If I'm just waiting around then get out of the way: - if (act is Wait) - { - self.CancelActivity(); - - var cell = self.Location; - var moveTo = mobile.NearestMoveableCell(cell, 2, 5); - self.QueueActivity(mobile.MoveTo(moveTo, 0)); - self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false); - - // Find more resources but not at this location: - self.QueueActivity(new FindResources(self, cell)); - } - } - void INotifyIdle.TickIdle(Actor self) { // Should we be intelligent while idle? @@ -383,12 +361,7 @@ namespace OpenRA.Mods.Common.Traits self.SetTargetLine(Target.FromCell(self.World, loc), Color.Red); // FindResources takes care of calling INotifyHarvesterAction - self.QueueActivity(order.Queued, new FindResources(self)); - - LastOrderLocation = loc; - - // This prevents harvesters returning to an empty patch when the player orders them to a new patch: - LastHarvestedCell = LastOrderLocation; + self.QueueActivity(order.Queued, new FindResources(self, loc)); } else if (order.OrderString == "Deliver") {