From 11c8cda0c38ad0ac71c58557d34480925307cebd Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 18 Jun 2017 11:58:21 +0000 Subject: [PATCH] Fix queued move activities. --- OpenRA.Mods.Common/Activities/Move/Move.cs | 42 ++++++++++++++++++---- OpenRA.Mods.Common/Traits/Mobile.cs | 38 +++----------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 153d81e68ae2..c3f1697de167 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -23,6 +23,8 @@ namespace OpenRA.Mods.Common.Activities { public class Move : Activity { + const int AverageTicksBeforePathing = 5; + const int SpreadTicksBeforePathing = 5; static readonly List NoPath = new List(); readonly Mobile mobile; @@ -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) @@ -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(); - getPath = () => self.World.WorldActor.Trait() - .FindUnitPath(mobile.ToCell, destination, self, ignoreActor); + getPath = () => + { + if (!this.destination.HasValue) + return NoPath; + + return self.World.WorldActor.Trait() + .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 @@ List 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 @@ -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; } @@ -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; } diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 1f856b4234c1..c2e7f630a895 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -384,10 +384,6 @@ public int MovementCostToEnterCell(WorldMovementInfo worldMovementInfo, Actor se public class Mobile : ConditionalTrait, 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> speedModifiers; public bool IsMoving { get; set; } @@ -621,33 +617,6 @@ public CPos NearestCell(CPos target, Func 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") @@ -655,8 +624,11 @@ public void ResolveOrder(Actor self, Order order) 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")