Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix queued move activities. #13528

Merged
merged 1 commit into from Jun 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 35 additions & 7 deletions OpenRA.Mods.Common/Activities/Move/Move.cs
Expand Up @@ -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;
Expand All @@ -38,6 +40,10 @@ public class Move : Activity
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)
Expand All @@ -57,15 +63,25 @@ public Move(Actor self, CPos destination)
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)
Expand Down Expand Up @@ -122,6 +138,18 @@ List<CPos> EvalPath()
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
Expand All @@ -137,9 +165,9 @@ public override Activity Tick(Actor self)

if (path == null)
{
if (mobile.TicksBeforePathing > 0)
if (ticksBeforePathing > 0)
{
--mobile.TicksBeforePathing;
--ticksBeforePathing;
return this;
}

Expand Down Expand Up @@ -236,9 +264,9 @@ void SanityCheckPath(Mobile mobile)
if (--waitTicksRemaining >= 0)
return null;

if (mobile.TicksBeforePathing > 0)
if (ticksBeforePathing > 0)
{
--mobile.TicksBeforePathing;
--ticksBeforePathing;
return null;
}

Expand Down
38 changes: 5 additions & 33 deletions OpenRA.Mods.Common/Traits/Mobile.cs
Expand Up @@ -384,10 +384,6 @@ public int MovementCostToEnterCell(WorldMovementInfo worldMovementInfo, Actor se
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; }
Expand Down Expand Up @@ -621,42 +617,18 @@ public CPos NearestCell(CPos target, Func<CPos, bool> check, int minRange, int m
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")
{
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")
Expand Down