Fixed harvesters for AI to search the entire map when no more resources nearby.
This commit is contained in:
@@ -260,6 +260,25 @@ namespace OpenRA.Mods.RA.AI
|
||||
else
|
||||
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>()
|
||||
.Where(a => a.Actor.Owner == p && !a.Actor.HasTrait<BaseBuilding>()
|
||||
&& !activeUnits.Contains(a.Actor))
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
public class FindResources : Activity
|
||||
{
|
||||
CPos avoidCell;
|
||||
CPos? avoidCell;
|
||||
|
||||
public FindResources()
|
||||
{
|
||||
@@ -64,7 +64,8 @@ namespace OpenRA.Mods.RA.Activities
|
||||
})
|
||||
.WithHeuristic(loc =>
|
||||
{
|
||||
if (loc == avoidCell) return 1;
|
||||
// Avoid this cell:
|
||||
if (avoidCell.HasValue && loc == avoidCell.Value) return 1;
|
||||
|
||||
// Don't harvest out of range:
|
||||
int distSquared = (loc - (harv.LastOrderLocation ?? harv.LinkedProc.Location)).LengthSquared;
|
||||
|
||||
@@ -268,6 +268,20 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
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());
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (self == claimer) return;
|
||||
|
||||
Reference in New Issue
Block a user