From 0a9eb1ff83250dd6c830f4f63e4177752a94bec5 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Sat, 11 Apr 2020 17:59:30 +0100 Subject: [PATCH] Fix units stuck on transit-only when resupplying --- OpenRA.Mods.Common/Activities/Move/Move.cs | 7 ++++++- OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs | 3 ++- OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs | 6 +++--- OpenRA.Mods.Common/Activities/Resupply.cs | 6 ++++++ OpenRA.Mods.Common/Traits/Mobile.cs | 6 ++++++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 922f0f64be..5fb74f87ad 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -347,10 +347,15 @@ namespace OpenRA.Mods.Common.Activities } public override void Cancel(Actor self, bool keepQueue = false) + { + Cancel(self, keepQueue, false); + } + + public void Cancel(Actor self, bool keepQueue, bool forceClearPath) { // We need to clear the path here in order to prevent MovePart queueing new instances of itself // when the unit is making a turn. - if (path != null && mobile.CanStayInCell(mobile.ToCell)) + if (path != null && (forceClearPath || mobile.CanStayInCell(mobile.ToCell))) path.Clear(); base.Cancel(self, keepQueue); diff --git a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs index 7f83636d37..6561f8a15d 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs @@ -78,7 +78,8 @@ namespace OpenRA.Mods.Common.Activities protected virtual IEnumerable CandidateMovementCells(Actor self) { - return Util.AdjacentCells(self.World, Target); + return Util.AdjacentCells(self.World, Target) + .Where(c => Mobile.CanStayInCell(c)); } protected override void OnFirstRun(Actor self) diff --git a/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs b/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs index 0dfae9694d..c79ac68951 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveWithinRange.cs @@ -33,13 +33,13 @@ namespace OpenRA.Mods.Common.Activities { // We are now in range. Don't move any further! // HACK: This works around the pathfinder not returning the shortest path - return AtCorrectRange(self.CenterPosition) && Mobile.CanInteractWithGroundLayer(self); + return AtCorrectRange(self.CenterPosition) && Mobile.CanInteractWithGroundLayer(self) && Mobile.CanStayInCell(self.Location); } protected override bool ShouldRepath(Actor self, CPos targetLocation) { return lastVisibleTargetLocation != targetLocation && (!AtCorrectRange(self.CenterPosition) - || !Mobile.CanInteractWithGroundLayer(self)); + || !Mobile.CanInteractWithGroundLayer(self) || !Mobile.CanStayInCell(self.Location)); } protected override IEnumerable CandidateMovementCells(Actor self) @@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Activities var minCells = minRange.Length / 1024; return map.FindTilesInAnnulus(lastVisibleTargetLocation, minCells, maxCells) - .Where(c => AtCorrectRange(map.CenterOfSubCell(c, Mobile.FromSubCell))); + .Where(c => Mobile.CanStayInCell(c) && AtCorrectRange(map.CenterOfSubCell(c, Mobile.FromSubCell))); } bool AtCorrectRange(WPos origin) diff --git a/OpenRA.Mods.Common/Activities/Resupply.cs b/OpenRA.Mods.Common/Activities/Resupply.cs index d162c34c55..657215141c 100644 --- a/OpenRA.Mods.Common/Activities/Resupply.cs +++ b/OpenRA.Mods.Common/Activities/Resupply.cs @@ -171,6 +171,12 @@ namespace OpenRA.Mods.Common.Activities public override void Cancel(Actor self, bool keepQueue = false) { + // HACK: force move activities to ignore the transit-only cells when cancelling + // The idle handler will take over and move them into a safe cell + if (ChildActivity != null) + foreach (var c in ChildActivity.ActivitiesImplementing()) + c.Cancel(self, false, true); + foreach (var t in transportCallers) t.MovementCancelled(self); diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 33ceaea7f0..80e915eb4d 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -866,7 +866,13 @@ namespace OpenRA.Mods.Common.Traits void INotifyBecomingIdle.OnBecomingIdle(Actor self) { if (self.Location.Layer == 0) + { + // Make sure that units aren't left idling in a transit-only cell + // HACK: activities should be making sure that this can't happen in the first place! + if (!Locomotor.CanStayInCell(self.Location)) + self.QueueActivity(MoveTo(self.Location, evaluateNearestMovableCell: true)); return; + } var cml = self.World.WorldActor.TraitsImplementing() .First(l => l.Index == self.Location.Layer);