Improved the performance and intelligence of resource harvesting by

refactoring the Harvesters' pathfinding. Now they in first place assess
which is the closest resource inside their search area and then a path is
calculated

Changed the way harvesters find resources by always trying to find the
closest resource to their refinery.

Changed the strategy of finding to find resources in Annulus.
This commit is contained in:
David Jiménez
2015-03-13 14:58:22 +01:00
committed by reaperrr
parent a0dc38c252
commit 787609d51e
6 changed files with 154 additions and 132 deletions

View File

@@ -164,7 +164,7 @@ namespace OpenRA.Mods.Common.Traits
// 4 harvesters clogs up the refinery's delivery location:
if (occupancy >= 3)
return int.MaxValue;
return Constants.InvalidNode;
// Prefer refineries with less occupancy (multiplier is to offset distance cost):
return occupancy * 12;
@@ -209,8 +209,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var n in notify)
n.MovingToResources(self, moveTo, next);
self.QueueActivity(new FindResources(self));
return;
self.QueueActivity(next);
}
}
}
@@ -320,51 +319,46 @@ namespace OpenRA.Mods.Common.Traits
self.CancelActivity();
CPos? loc;
if (order.TargetLocation != CPos.Zero)
{
var loc = order.TargetLocation;
var territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
loc = order.TargetLocation;
var territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
if (territory != null)
{
// Find the nearest claimable cell to the order location (useful for group-select harvest):
loc = mobile.NearestCell(loc, p => mobile.CanEnterCell(p) && territory.ClaimResource(self, p), 1, 6);
loc = mobile.NearestCell(loc.Value, p => mobile.CanEnterCell(p) && territory.ClaimResource(self, p), 1, 6);
}
else
{
// Find the nearest cell to the order location (useful for group-select harvest):
var taken = new HashSet<CPos>();
loc = mobile.NearestCell(loc, p => mobile.CanEnterCell(p) && taken.Add(p), 1, 6);
loc = mobile.NearestCell(loc.Value, p => mobile.CanEnterCell(p) && taken.Add(p), 1, 6);
}
self.QueueActivity(mobile.MoveTo(loc, 0));
self.SetTargetLine(Target.FromCell(self.World, loc), Color.Red);
var notify = self.TraitsImplementing<INotifyHarvesterAction>();
var next = new FindResources(self);
foreach (var n in notify)
n.MovingToResources(self, loc, next);
LastOrderLocation = loc;
}
else
{
// A bot order gives us a CPos.Zero TargetLocation, so find some good resources for him:
var loc = FindNextResourceForBot(self);
loc = FindNextResourceForBot(self);
// No more resources? Oh well.
if (!loc.HasValue)
return;
self.QueueActivity(mobile.MoveTo(loc.Value, 0));
self.SetTargetLine(Target.FromCell(self.World, loc.Value), Color.Red);
LastOrderLocation = loc;
}
var next = new FindResources(self);
self.QueueActivity(next);
self.SetTargetLine(Target.FromCell(self.World, loc.Value), Color.Red);
var notify = self.TraitsImplementing<INotifyHarvesterAction>();
foreach (var n in notify)
n.MovingToResources(self, loc.Value, next);
LastOrderLocation = loc;
// This prevents harvesters returning to an empty patch when the player orders them to a new patch:
LastHarvestedCell = LastOrderLocation;
self.QueueActivity(new FindResources(self));
}
else if (order.OrderString == "Deliver")
{
@@ -413,32 +407,31 @@ namespace OpenRA.Mods.Common.Traits
// Find any harvestable resources:
var path = self.World.WorldActor.Trait<IPathFinder>().FindPath(
PathSearch.Search(self.World, mobileInfo, self, true)
.WithHeuristic(loc =>
PathSearch.Search(self.World, mobileInfo, self, true,
loc =>
{
// Get the resource at this location:
var resType = resLayer.GetResource(loc);
if (resType == null)
return Constants.CellCost;
return false;
// Can the harvester collect this kind of resource?
if (!harvInfo.Resources.Contains(resType.Info.Name))
return Constants.CellCost;
return false;
if (territory != null)
{
// Another harvester has claimed this resource:
ResourceClaim claim;
if (territory.IsClaimedByAnyoneElse(self, loc, out claim))
return Constants.CellCost;
return false;
}
return 0;
return true;
})
.FromPoint(self.Location));
if (path.Count == 0)
return (CPos?)null;
return null;
return path[0];
}