From ea32c204505f91616b0e1feafdb0e0cc451d6fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Sun, 8 Mar 2015 11:28:48 +0100 Subject: [PATCH] Changed the harvester heuristic so that now takes into account the distance from the initial search location. This makes harvesters somewhat more "intelligent" and gather nearer resources. Also solved several regressions introduced in the recent changes in the Pathfinder --- AUTHORS | 1 + .../Activities/FindResources.cs | 20 ++++++++++++++----- .../Pathfinder/PathCacheStorage.cs | 1 - OpenRA.Mods.Common/Pathfinder/PathSearch.cs | 7 +++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4f00700894..3c5585926b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -38,6 +38,7 @@ Also thanks to: * D2k Sardaukar * Daniel Derejvanik (Harisson) * Danny Keary (Dan9550) + * David Jiménez (Rydra) * David Russell (DavidARussell) * DeadlySurprise * Erasmus Schroder (rasco) diff --git a/OpenRA.Mods.Common/Activities/FindResources.cs b/OpenRA.Mods.Common/Activities/FindResources.cs index e2f559bd57..d2f3444f1a 100644 --- a/OpenRA.Mods.Common/Activities/FindResources.cs +++ b/OpenRA.Mods.Common/Activities/FindResources.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -58,28 +59,28 @@ namespace OpenRA.Mods.Common.Activities { // Avoid this cell: if (avoidCell.HasValue && loc == avoidCell.Value) - return Constants.CellCost; + return EstimateDistance(loc, searchFromLoc) + Constants.CellCost; // Don't harvest out of range: var distSquared = (loc - searchFromLoc).LengthSquared; if (distSquared > searchRadiusSquared) - return Constants.CellCost * 2; + return EstimateDistance(loc, searchFromLoc) + Constants.CellCost * 2; // Get the resource at this location: var resType = resLayer.GetResource(loc); if (resType == null) - return Constants.CellCost; + return EstimateDistance(loc, searchFromLoc) + Constants.CellCost; // Can the harvester collect this kind of resource? if (!harvInfo.Resources.Contains(resType.Info.Name)) - return Constants.CellCost; + return EstimateDistance(loc, searchFromLoc) + Constants.CellCost; if (territory != null) { // Another harvester has claimed this resource: ResourceClaim claim; if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) - return Constants.CellCost; + return EstimateDistance(loc, searchFromLoc) + Constants.CellCost; } return 0; @@ -123,6 +124,15 @@ namespace OpenRA.Mods.Common.Activities return Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(), new FindResources()); } + // Diagonal distance heuristic + static int EstimateDistance(CPos here, CPos destination) + { + var diag = Math.Min(Math.Abs(here.X - destination.X), Math.Abs(here.Y - destination.Y)); + var straight = Math.Abs(here.X - destination.X) + Math.Abs(here.Y - destination.Y); + + return Constants.CellCost * straight + (Constants.DiagonalCellCost - 2 * Constants.CellCost) * diag; + } + public override IEnumerable GetTargets(Actor self) { yield return Target.FromCell(self.World, self.Location); diff --git a/OpenRA.Mods.Common/Pathfinder/PathCacheStorage.cs b/OpenRA.Mods.Common/Pathfinder/PathCacheStorage.cs index 3e04f9aed2..fca898eb36 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathCacheStorage.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathCacheStorage.cs @@ -60,7 +60,6 @@ namespace OpenRA.Mods.Common.Pathfinder return null; } - cached.Tick = world.WorldTick; return cached.Result; } diff --git a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs index 577fad1d6d..8f8a782706 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs @@ -88,6 +88,13 @@ namespace OpenRA.Mods.Common.Pathfinder var currentCell = Graph[currentMinNode]; Graph[currentMinNode] = new CellInfo(currentCell.CostSoFar, currentCell.EstimatedTotal, currentCell.PreviousPos, CellStatus.Closed); + if (Graph.CustomCost != null) + { + var c = Graph.CustomCost(currentMinNode); + if (c == int.MaxValue) + return currentMinNode; + } + foreach (var connection in Graph.GetConnections(currentMinNode)) { // Calculate the cost up to that point