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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user