Fix queued move activities.
This commit is contained in:
@@ -23,6 +23,8 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
public class Move : Activity
|
||||
{
|
||||
const int AverageTicksBeforePathing = 5;
|
||||
const int SpreadTicksBeforePathing = 5;
|
||||
static readonly List<CPos> NoPath = new List<CPos>();
|
||||
|
||||
readonly Mobile mobile;
|
||||
@@ -38,6 +40,10 @@ namespace OpenRA.Mods.Common.Activities
|
||||
bool hasNotifiedBlocker;
|
||||
int waitTicksRemaining;
|
||||
|
||||
// To work around queued activity issues while minimizing changes to legacy behaviour
|
||||
int ticksBeforePathing;
|
||||
bool evaluateNearestMovableCell;
|
||||
|
||||
// Scriptable move order
|
||||
// Ignores lane bias and nearby units
|
||||
public Move(Actor self, CPos destination)
|
||||
@@ -57,15 +63,25 @@ namespace OpenRA.Mods.Common.Activities
|
||||
nearEnough = WDist.Zero;
|
||||
}
|
||||
|
||||
public Move(Actor self, CPos destination, WDist nearEnough, Actor ignoreActor = null)
|
||||
public Move(Actor self, CPos destination, WDist nearEnough, Actor ignoreActor = null, bool evaluateNearestMovableCell = false)
|
||||
{
|
||||
mobile = self.Trait<Mobile>();
|
||||
|
||||
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
|
||||
.FindUnitPath(mobile.ToCell, destination, self, ignoreActor);
|
||||
getPath = () =>
|
||||
{
|
||||
if (!this.destination.HasValue)
|
||||
return NoPath;
|
||||
|
||||
return self.World.WorldActor.Trait<IPathFinder>()
|
||||
.FindUnitPath(mobile.ToCell, this.destination.Value, self, ignoreActor);
|
||||
};
|
||||
|
||||
// Note: Will be recalculated from OnFirstRun if evaluateNearestMovableCell is true
|
||||
this.destination = destination;
|
||||
|
||||
this.nearEnough = nearEnough;
|
||||
this.ignoreActor = ignoreActor;
|
||||
this.evaluateNearestMovableCell = evaluateNearestMovableCell;
|
||||
}
|
||||
|
||||
public Move(Actor self, CPos destination, SubCell subCell, WDist nearEnough)
|
||||
@@ -122,6 +138,18 @@ namespace OpenRA.Mods.Common.Activities
|
||||
return path;
|
||||
}
|
||||
|
||||
protected override void OnFirstRun(Actor self)
|
||||
{
|
||||
ticksBeforePathing = AverageTicksBeforePathing +
|
||||
self.World.SharedRandom.Next(-SpreadTicksBeforePathing, SpreadTicksBeforePathing);
|
||||
|
||||
if (evaluateNearestMovableCell && destination.HasValue)
|
||||
{
|
||||
var movableDestination = mobile.NearestMoveableCell(destination.Value);
|
||||
destination = mobile.CanEnterCell(movableDestination) ? movableDestination : (CPos?)null;
|
||||
}
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
// If the actor is inside a tunnel then we must let them move
|
||||
@@ -137,9 +165,9 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
if (path == null)
|
||||
{
|
||||
if (mobile.TicksBeforePathing > 0)
|
||||
if (ticksBeforePathing > 0)
|
||||
{
|
||||
--mobile.TicksBeforePathing;
|
||||
--ticksBeforePathing;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -236,9 +264,9 @@ namespace OpenRA.Mods.Common.Activities
|
||||
if (--waitTicksRemaining >= 0)
|
||||
return null;
|
||||
|
||||
if (mobile.TicksBeforePathing > 0)
|
||||
if (ticksBeforePathing > 0)
|
||||
{
|
||||
--mobile.TicksBeforePathing;
|
||||
--ticksBeforePathing;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -384,10 +384,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class Mobile : ConditionalTrait<MobileInfo>, INotifyCreated, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove,
|
||||
IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle
|
||||
{
|
||||
const int AverageTicksBeforePathing = 5;
|
||||
const int SpreadTicksBeforePathing = 5;
|
||||
internal int TicksBeforePathing = 0;
|
||||
|
||||
readonly Actor self;
|
||||
readonly Lazy<IEnumerable<int>> speedModifiers;
|
||||
public bool IsMoving { get; set; }
|
||||
@@ -621,33 +617,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return target;
|
||||
}
|
||||
|
||||
void PerformMoveInner(Actor self, CPos targetLocation, bool queued)
|
||||
{
|
||||
var currentLocation = NearestMoveableCell(targetLocation);
|
||||
|
||||
if (!CanEnterCell(currentLocation))
|
||||
{
|
||||
if (queued) self.CancelActivity();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!queued) self.CancelActivity();
|
||||
|
||||
TicksBeforePathing = AverageTicksBeforePathing + self.World.SharedRandom.Next(-SpreadTicksBeforePathing, SpreadTicksBeforePathing);
|
||||
|
||||
self.QueueActivity(new Move(self, currentLocation, WDist.FromCells(8)));
|
||||
|
||||
self.SetTargetLine(Target.FromCell(self.World, currentLocation), Color.Green);
|
||||
}
|
||||
|
||||
protected void PerformMove(Actor self, CPos targetLocation, bool queued)
|
||||
{
|
||||
if (queued)
|
||||
self.QueueActivity(new CallFunc(() => PerformMoveInner(self, targetLocation, true)));
|
||||
else
|
||||
PerformMoveInner(self, targetLocation, false);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Move")
|
||||
@@ -655,8 +624,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!Info.MoveIntoShroud && !self.Owner.Shroud.IsExplored(order.TargetLocation))
|
||||
return;
|
||||
|
||||
PerformMove(self, self.World.Map.Clamp(order.TargetLocation),
|
||||
order.Queued && !self.IsIdle);
|
||||
if (!order.Queued)
|
||||
self.CancelActivity();
|
||||
|
||||
self.SetTargetLine(Target.FromCell(self.World, order.TargetLocation), Color.Green);
|
||||
self.QueueActivity(order.Queued, new Move(self, order.TargetLocation, WDist.FromCells(8), null, true));
|
||||
}
|
||||
|
||||
if (order.OrderString == "Stop")
|
||||
|
||||
Reference in New Issue
Block a user