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 IMove : ITeleportable { int Altitude { get; set; } }
|
||||||
|
public interface INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking, CPos cell); }
|
||||||
|
|
||||||
public interface IFacing
|
public interface IFacing
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user