diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 6b344d3785..c3d62c08e9 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -16,6 +16,7 @@ using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Effects; +using OpenRA.Mods.Common.Pathfinder; using OpenRA.Primitives; using OpenRA.Traits; @@ -381,7 +382,7 @@ namespace OpenRA.Mods.Common.Traits } public class Mobile : ConditionalTrait, INotifyCreated, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove, - IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier + IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle { const int AverageTicksBeforePathing = 5; const int SpreadTicksBeforePathing = 5; @@ -987,5 +988,34 @@ namespace OpenRA.Mods.Common.Traits if (CanEnterCell(self.Location, self, false)) init.Add(new HuskSpeedInit(MovementSpeedForCell(self, self.Location))); } + + CPos? ClosestGroundCell() + { + var above = new CPos(TopLeft.X, TopLeft.Y); + if (CanEnterCell(above)) + return above; + + var pathFinder = self.World.WorldActor.Trait(); + List path; + using (var search = PathSearch.Search(self.World, Info, self, true, + loc => loc.Layer == 0 && CanEnterCell(loc)) + .FromPoint(self.Location)) + path = pathFinder.FindPath(search); + + if (path.Count > 0) + return path[0]; + + return null; + } + + void INotifyBecomingIdle.OnBecomingIdle(Actor self) + { + if (TopLeft.Layer == 0) + return; + + var moveTo = ClosestGroundCell(); + if (moveTo != null) + self.QueueActivity(MoveTo(moveTo.Value, 0)); + } } }