Rework harvester resource claiming:

* Maintains lists of claims, and only restricts
   reservations for friendly units.
 * Removes OnNotifyResourceClaimLost; it's not
   clear whether that is still useful, and it
   prevents future necessary cleanups.
 * Moves other code without changing behaviour.

This fixed stale claims from dead units and enemy
claims from preventing otherwise valid harvest
activities.
This commit is contained in:
Paul Chote
2017-07-15 12:36:41 +00:00
committed by reaperrr
parent 9097837e6d
commit afd8b9ab86
9 changed files with 79 additions and 192 deletions

View File

@@ -263,8 +263,7 @@ namespace OpenRA.Mods.Common.AI
public Player Player { get; private set; }
readonly DomainIndex domainIndex;
readonly ResourceLayer resLayer;
readonly ResourceClaimLayer territory;
readonly ResourceClaimLayer claimLayer;
readonly IPathFinder pathfinder;
readonly Func<Actor, bool> isEnemyUnit;
@@ -311,8 +310,7 @@ namespace OpenRA.Mods.Common.AI
return;
domainIndex = World.WorldActor.Trait<DomainIndex>();
resLayer = World.WorldActor.Trait<ResourceLayer>();
territory = World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
claimLayer = World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
pathfinder = World.WorldActor.Trait<IPathFinder>();
isEnemyUnit = unit =>
@@ -769,19 +767,22 @@ namespace OpenRA.Mods.Common.AI
return targets.MinByOrDefault(target => (target.Actor.CenterPosition - capturer.CenterPosition).LengthSquared);
}
CPos FindNextResource(Actor harvester)
CPos FindNextResource(Actor actor, Harvester harv)
{
var harvInfo = harvester.Info.TraitInfo<HarvesterInfo>();
var mobileInfo = harvester.Info.TraitInfo<MobileInfo>();
var mobileInfo = actor.Info.TraitInfo<MobileInfo>();
var passable = (uint)mobileInfo.GetMovementClass(World.Map.Rules.TileSet);
Func<CPos, bool> isValidResource = cell =>
domainIndex.IsPassable(actor.Location, cell, mobileInfo, passable) &&
harv.CanHarvestCell(actor, cell) &&
claimLayer.CanClaimCell(actor, cell);
var path = pathfinder.FindPath(
PathSearch.Search(World, mobileInfo, harvester, true,
loc => domainIndex.IsPassable(harvester.Location, loc, mobileInfo, passable) && harvester.CanHarvestAt(loc, resLayer, harvInfo, territory))
PathSearch.Search(World, mobileInfo, actor, true, isValidResource)
.WithCustomCost(loc => World.FindActorsInCircle(World.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
.Where(u => !u.IsDead && harvester.Owner.Stances[u.Owner] == Stance.Enemy)
.Where(u => !u.IsDead && actor.Owner.Stances[u.Owner] == Stance.Enemy)
.Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (World.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
.FromPoint(harvester.Location));
.FromPoint(actor.Location));
if (path.Count == 0)
return CPos.Zero;
@@ -809,7 +810,7 @@ namespace OpenRA.Mods.Common.AI
continue;
// Tell the idle harvester to quit slacking:
var newSafeResourcePatch = FindNextResource(harvester);
var newSafeResourcePatch = FindNextResource(harvester, harv);
BotDebug("AI: Harvester {0} is idle. Ordering to {1} in search for new resources.".F(harvester, newSafeResourcePatch));
QueueOrder(new Order("Harvest", harvester, false) { TargetLocation = newSafeResourcePatch });
}