Fixed harvesters for AI to search the entire map when no more resources nearby.

This commit is contained in:
James Dunne
2012-06-24 20:24:53 -05:00
parent 1fa70d259f
commit b59a0e8c0d
3 changed files with 75 additions and 5 deletions

View File

@@ -260,6 +260,25 @@ namespace OpenRA.Mods.RA.AI
else else
assignRolesTicks = Info.AssignRolesInterval; assignRolesTicks = Info.AssignRolesInterval;
// Find idle harvesters and give them orders:
foreach (var a in activeUnits)
{
var harv = a.TraitOrDefault<Harvester>();
if (harv == null) continue;
if (!a.IsIdle)
{
Activity act = a.GetCurrentActivity();
// A Wait activity is technically idle:
if ((act.GetType() != typeof(OpenRA.Mods.RA.Activities.Wait)) &&
(act.NextActivity == null || act.NextActivity.GetType() != typeof(OpenRA.Mods.RA.Activities.FindResources)))
continue;
}
if (!harv.IsEmpty) continue;
// Tell the idle harvester to quit slacking:
world.IssueOrder(new Order("Harvest", a, false));
}
var newUnits = self.World.ActorsWithTrait<IMove>() var newUnits = self.World.ActorsWithTrait<IMove>()
.Where(a => a.Actor.Owner == p && !a.Actor.HasTrait<BaseBuilding>() .Where(a => a.Actor.Owner == p && !a.Actor.HasTrait<BaseBuilding>()
&& !activeUnits.Contains(a.Actor)) && !activeUnits.Contains(a.Actor))
@@ -275,12 +294,12 @@ namespace OpenRA.Mods.RA.AI
activeUnits.Add(a); activeUnits.Add(a);
} }
/* Create an attack force when we have enough units around our base. */ /* Create an attack force when we have enough units around our base. */
// (don't bother leaving any behind for defense.) // (don't bother leaving any behind for defense.)
int randomizedSquadSize = Info.SquadSize - 4 + random.Next(200); int randomizedSquadSize = Info.SquadSize - 4 + random.Next(200);
if (unitsHangingAroundTheBase.Count >= randomizedSquadSize) if (unitsHangingAroundTheBase.Count >= randomizedSquadSize)
{ {
BotDebug("Launch an attack."); BotDebug("Launch an attack.");
@@ -426,7 +445,7 @@ namespace OpenRA.Mods.RA.AI
world.IssueOrder(new Order("DeployTransform", mcv, false)); world.IssueOrder(new Order("DeployTransform", mcv, false));
} }
else else
BotDebug("AI: Can't find BaseBuildUnit."); BotDebug("AI: Can't find BaseBuildUnit.");
} }
internal IEnumerable<ProductionQueue> FindQueues(string category) internal IEnumerable<ProductionQueue> FindQueues(string category)

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Activities
{ {
public class FindResources : Activity public class FindResources : Activity
{ {
CPos avoidCell; CPos? avoidCell;
public FindResources() public FindResources()
{ {
@@ -64,7 +64,8 @@ namespace OpenRA.Mods.RA.Activities
}) })
.WithHeuristic(loc => .WithHeuristic(loc =>
{ {
if (loc == avoidCell) return 1; // Avoid this cell:
if (avoidCell.HasValue && loc == avoidCell.Value) return 1;
// Don't harvest out of range: // Don't harvest out of range:
int distSquared = (loc - (harv.LastOrderLocation ?? harv.LinkedProc.Location)).LengthSquared; int distSquared = (loc - (harv.LastOrderLocation ?? harv.LinkedProc.Location)).LengthSquared;

View File

@@ -268,6 +268,20 @@ namespace OpenRA.Mods.RA
LastOrderLocation = loc; LastOrderLocation = loc;
} }
else
{
// A bot order gives us a CPos.Zero TargetLocation, so find some good resources for him:
CPos? loc = FindNextResourceForBot(self);
// No more resources? Oh well.
if (!loc.HasValue)
return;
self.QueueActivity(mobile.MoveTo(loc.Value, 0));
self.SetTargetLine(Target.FromCell(loc.Value), Color.Red);
LastOrderLocation = loc;
}
self.QueueActivity(new FindResources()); self.QueueActivity(new FindResources());
} }
else if (order.OrderString == "Deliver") else if (order.OrderString == "Deliver")
@@ -290,6 +304,42 @@ namespace OpenRA.Mods.RA
} }
} }
CPos? FindNextResourceForBot(Actor self)
{
// NOTE: This is only used for the AI to find the next available resource to harvest.
var harvInfo = self.Info.Traits.Get<HarvesterInfo>();
var mobile = self.Trait<Mobile>();
var mobileInfo = self.Info.Traits.Get<MobileInfo>();
var resLayer = self.World.WorldActor.Trait<ResourceLayer>();
var territory = self.World.WorldActor.Trait<ResourceClaimLayer>();
// Find any harvestable resources:
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
PathSearch.Search(self.World, mobileInfo, self.Owner, true)
.WithHeuristic(loc =>
{
// Get the resource at this location:
var resType = resLayer.GetResource(loc);
if (resType == null) return 1;
// Can the harvester collect this kind of resource?
if (!harvInfo.Resources.Contains(resType.info.Name)) return 1;
// Another harvester has claimed this resource:
ResourceClaim claim;
if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) return 1;
return 0;
})
.FromPoint(self.Location)
);
if (path.Count == 0)
return (CPos?)null;
return path[0];
}
public void OnNotifyResourceClaimLost(Actor self, ResourceClaim claim, Actor claimer) public void OnNotifyResourceClaimLost(Actor self, ResourceClaim claim, Actor claimer)
{ {
if (self == claimer) return; if (self == claimer) return;