Harvesters no longer block each other during low-ore contention and wait for a random amount of time while idle to search for more resources.

This commit is contained in:
James Dunne
2012-06-24 17:01:21 -05:00
parent 80123b6aa4
commit 845379e577
4 changed files with 44 additions and 6 deletions

View File

@@ -132,6 +132,7 @@ namespace OpenRA.Traits
} }
public interface IMove : ITeleportable { int Altitude { get; set; } } public interface IMove : ITeleportable { int Altitude { get; set; } }
public interface INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking, CPos cell); }
public interface IFacing public interface IFacing
{ {

View File

@@ -20,6 +20,17 @@ namespace OpenRA.Mods.RA.Activities
{ {
public class FindResources : Activity public class FindResources : Activity
{ {
CPos avoidCell;
public FindResources()
{
}
public FindResources(CPos avoidCell)
{
this.avoidCell = avoidCell;
}
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (IsCanceled || NextActivity != null) return NextActivity; if (IsCanceled || NextActivity != null) return NextActivity;
@@ -53,6 +64,8 @@ namespace OpenRA.Mods.RA.Activities
}) })
.WithHeuristic(loc => .WithHeuristic(loc =>
{ {
if (loc == avoidCell) 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;
if (distSquared > (12 * 12)) if (distSquared > (12 * 12))
@@ -69,6 +82,7 @@ namespace OpenRA.Mods.RA.Activities
ResourceClaim claim; ResourceClaim claim;
if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) return 1; if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) return 1;
#if false
// Is anyone covering the location already? // Is anyone covering the location already?
// NOTE(jsd): This is required to prevent harvester deadlocking. // NOTE(jsd): This is required to prevent harvester deadlocking.
var unitsAtLoc = var unitsAtLoc =
@@ -76,6 +90,7 @@ namespace OpenRA.Mods.RA.Activities
where u != self where u != self
select u; select u;
if (unitsAtLoc.Any()) return 1; if (unitsAtLoc.Any()) return 1;
#endif
return 0; return 0;
}) })
@@ -90,23 +105,24 @@ namespace OpenRA.Mods.RA.Activities
{ {
// Get out of the way if we are: // Get out of the way if we are:
harv.UnblockRefinery(self); harv.UnblockRefinery(self);
int randFrames = 125 + self.World.SharedRandom.Next(-35, 35);
if (NextActivity != null) if (NextActivity != null)
return Util.SequenceActivities(NextActivity, new Wait(90), this); return Util.SequenceActivities(NextActivity, new Wait(randFrames), new FindResources());
else else
return Util.SequenceActivities(new Wait(90), this); return Util.SequenceActivities(new Wait(randFrames), new FindResources());
} }
} }
// Attempt to claim a resource as ours: // Attempt to claim a resource as ours:
if (!territory.ClaimResource(self, path[0])) if (!territory.ClaimResource(self, path[0]))
return Util.SequenceActivities(new Wait(25), this); return Util.SequenceActivities(new Wait(25), new FindResources());
// If not given a direct order, assume ordered to the first resource location we find: // If not given a direct order, assume ordered to the first resource location we find:
if (harv.LastOrderLocation == null) if (harv.LastOrderLocation == null)
harv.LastOrderLocation = path[0]; harv.LastOrderLocation = path[0];
self.SetTargetLine(Target.FromCell(path[0]), Color.Red, false); self.SetTargetLine(Target.FromCell(path[0]), Color.Red, false);
return Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(), this); return Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(), new FindResources());
} }
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -30,7 +30,8 @@ namespace OpenRA.Mods.RA
} }
public class Harvester : IIssueOrder, IResolveOrder, IPips, public class Harvester : IIssueOrder, IResolveOrder, IPips,
IExplodeModifier, IOrderVoice, ISpeedModifier, ISync, INotifyResourceClaimLost, INotifyIdle IExplodeModifier, IOrderVoice, ISpeedModifier, ISync,
INotifyResourceClaimLost, INotifyIdle, INotifyBlockingMove
{ {
Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>(); Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
@@ -120,16 +121,31 @@ namespace OpenRA.Mods.RA
// Get out of the way: // Get out of the way:
var mobile = self.Trait<Mobile>(); var mobile = self.Trait<Mobile>();
var harv = self.Trait<Harvester>(); var harv = self.Trait<Harvester>();
// TODO: would like an interruptible move here
var moveTo = harv.LastHarvestedCell ?? (deliveryLoc + new CVec(0, 4)); var moveTo = harv.LastHarvestedCell ?? (deliveryLoc + new CVec(0, 4));
self.QueueActivity(mobile.MoveTo(moveTo, 1)); self.QueueActivity(mobile.MoveTo(moveTo, 1));
self.SetTargetLine(Target.FromCell(moveTo), Color.Red, false); self.SetTargetLine(Target.FromCell(moveTo), Color.Red, false);
self.World.WorldActor.Trait<ResourceClaimLayer>().ClaimResource(self, moveTo); self.World.WorldActor.Trait<ResourceClaimLayer>().ClaimResource(self, moveTo);
self.QueueActivity(new FindResources());
return; return;
} }
} }
} }
public void OnNotifyBlockingMove(Actor self, Actor blocking, CPos cell)
{
// I'm blocking someone else from moving to my location:
Activity act = self.GetCurrentActivity();
// If I'm just waiting around, then get out of the way:
if (act.GetType() == typeof(Wait))
{
self.CancelActivity();
var mobile = self.Trait<Mobile>();
self.QueueActivity(mobile.MoveTo(mobile.NearestMoveableCell(cell, 2, 5), 0));
// Find more resources but not at this location:
self.QueueActivity(new FindResources(cell));
}
}
public void TickIdle(Actor self) public void TickIdle(Actor self)
{ {
// Are we not empty? Deliver resources: // Are we not empty? Deliver resources:

View File

@@ -178,6 +178,11 @@ namespace OpenRA.Mods.RA.Move
var nudge = blocker.TraitOrDefault<INudge>(); var nudge = blocker.TraitOrDefault<INudge>();
if (nudge != null) if (nudge != null)
nudge.OnNudge(blocker, self, false); nudge.OnNudge(blocker, self, false);
// Notify the blocker that he's blocking our move:
INotifyBlockingMove moveBlocked;
if ((moveBlocked = blocker.TraitOrDefault<INotifyBlockingMove>()) != null)
moveBlocked.OnNotifyBlockingMove(blocker, self, nextCell);
} }
Pair<CPos, SubCell>? PopPath(Actor self, Mobile mobile) Pair<CPos, SubCell>? PopPath(Actor self, Mobile mobile)