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 INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking, CPos cell); }
public interface IFacing
{

View File

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

View File

@@ -30,7 +30,8 @@ namespace OpenRA.Mods.RA
}
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>();
@@ -120,16 +121,31 @@ namespace OpenRA.Mods.RA
// Get out of the way:
var mobile = self.Trait<Mobile>();
var harv = self.Trait<Harvester>();
// TODO: would like an interruptible move here
var moveTo = harv.LastHarvestedCell ?? (deliveryLoc + new CVec(0, 4));
self.QueueActivity(mobile.MoveTo(moveTo, 1));
self.SetTargetLine(Target.FromCell(moveTo), Color.Red, false);
self.World.WorldActor.Trait<ResourceClaimLayer>().ClaimResource(self, moveTo);
self.QueueActivity(new FindResources());
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)
{
// Are we not empty? Deliver resources:

View File

@@ -178,6 +178,11 @@ namespace OpenRA.Mods.RA.Move
var nudge = blocker.TraitOrDefault<INudge>();
if (nudge != null)
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)