From ab94ea9715393e2ed5436cba8e0fbf163f33ea28 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 18 Aug 2019 15:13:26 +0000 Subject: [PATCH] Discourage harvesters from wandering too far from the refinery. --- .../Activities/FindAndDeliverResources.cs | 27 ++++++++++++++++++- OpenRA.Mods.Common/Traits/Harvester.cs | 3 +++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs index 36ae82fd8a..76c3cf323e 100644 --- a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Pathfinder; @@ -175,7 +176,8 @@ namespace OpenRA.Mods.Common.Activities } // Determine where to search from and how far to search: - var searchFromLoc = lastHarvestedCell ?? GetSearchFromProcLocation(self); + var procLoc = GetSearchFromProcLocation(self); + var searchFromLoc = lastHarvestedCell ?? procLoc; var searchRadius = lastHarvestedCell.HasValue ? harvInfo.SearchFromHarvesterRadius : harvInfo.SearchFromProcRadius; if (!searchFromLoc.HasValue) { @@ -185,6 +187,9 @@ namespace OpenRA.Mods.Common.Activities var searchRadiusSquared = searchRadius * searchRadius; + var procPos = procLoc.HasValue ? (WPos?)self.World.Map.CenterOfCell(procLoc.Value) : null; + var harvPos = self.CenterPosition; + // Find any harvestable resources: List path; using (var search = PathSearch.Search(self.World, mobile.Locomotor, self, true, loc => @@ -194,6 +199,26 @@ namespace OpenRA.Mods.Common.Activities if ((loc - searchFromLoc.Value).LengthSquared > searchRadiusSquared) return int.MaxValue; + // Add a cost modifier to harvestable cells to prefer resources that are closer to the refinery. + // This reduces the tendancy for harvesters to move in straight lines + if (procPos.HasValue && harvInfo.ResourceRefineryDirectionPenalty > 0 && harv.CanHarvestCell(self, loc)) + { + var pos = self.World.Map.CenterOfCell(loc); + + // Calculate harv-cell-refinery angle (cosine rule) + var aSq = (harvPos - procPos.Value).LengthSquared; + var bSq = (pos - procPos.Value).LengthSquared; + var cSq = (pos - harvPos).LengthSquared; + + if (bSq > 0 && cSq > 0) + { + var cosA = (int)(1024 * (bSq + cSq - aSq) / (2 * Exts.ISqrt(bSq * cSq))); + + // Cost modifier varies between 0 and ResourceRefineryDirectionPenalty + return Math.Abs(harvInfo.ResourceRefineryDirectionPenalty / 2) + harvInfo.ResourceRefineryDirectionPenalty * cosA / 2048; + } + } + return 0; }) .FromPoint(searchFromLoc.Value) diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index a016cc8662..85a69a736f 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -71,6 +71,9 @@ namespace OpenRA.Mods.Common.Traits [Desc("The pathfinding cost penalty applied for each harvester waiting to unload at a refinery.")] public readonly int UnloadQueueCostModifier = 12; + [Desc("The pathfinding cost penalty applied for cells directly away from the refinery.")] + public readonly int ResourceRefineryDirectionPenalty = 200; + [Desc("Does the unit queue harvesting runs instead of individual harvest actions?")] public readonly bool QueueFullLoad = false;