diff --git a/OpenRA.Mods.Common/Activities/Air/TakeOff.cs b/OpenRA.Mods.Common/Activities/Air/TakeOff.cs index 38a854a34b..e22caa1369 100644 --- a/OpenRA.Mods.Common/Activities/Air/TakeOff.cs +++ b/OpenRA.Mods.Common/Activities/Air/TakeOff.cs @@ -36,8 +36,7 @@ namespace OpenRA.Mods.Common.Activities if (self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition).Length >= aircraft.Info.MinAirborneAltitude) return; - // We are taking off, so remove reservation and influence in ground cells. - aircraft.UnReserve(); + // We are taking off, so remove influence in ground cells. aircraft.RemoveInfluence(); if (aircraft.Info.TakeoffSounds.Length > 0) diff --git a/OpenRA.Mods.Common/Activities/Resupply.cs b/OpenRA.Mods.Common/Activities/Resupply.cs index 566a941903..6c062f4839 100644 --- a/OpenRA.Mods.Common/Activities/Resupply.cs +++ b/OpenRA.Mods.Common/Activities/Resupply.cs @@ -191,6 +191,8 @@ namespace OpenRA.Mods.Common.Activities QueueChild(move.MoveTo(rp.Location, repairableNear != null ? null : host.Actor)); else QueueChild(new TakeOff(self)); + + aircraft.UnReserve(); } // Aircraft without TakeOffOnResupply remain on the resupplier until something else needs it diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 11ca8a91fe..8efc2f8786 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -506,25 +506,15 @@ namespace OpenRA.Mods.Common.Traits MayYieldReservation = true; } - public void UnReserve(bool takeOff = false) + public void UnReserve() { if (reservation == null) return; - // Move to the host's rally point if it has one - var rp = ReservedActor != null ? ReservedActor.TraitOrDefault() : null; - reservation.Dispose(); reservation = null; ReservedActor = null; MayYieldReservation = false; - - if (takeOff && self.World.Map.DistanceAboveTerrain(CenterPosition).Length <= LandAltitude.Length) - { - self.QueueActivity(new TakeOff(self)); - if (rp != null) - self.QueueActivity(new AttackMoveActivity(self, () => MoveTo(rp.Location, null, targetLineColor: Color.OrangeRed))); - } } bool AircraftCanEnter(Actor a, TargetModifiers modifiers) diff --git a/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs b/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs index 1b618b4867..3b7ae41b46 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs @@ -10,6 +10,7 @@ #endregion using System; +using OpenRA.Mods.Common.Activities; using OpenRA.Primitives; using OpenRA.Traits; @@ -18,10 +19,16 @@ namespace OpenRA.Mods.Common.Traits [Desc("Reserve landing places for aircraft.")] class ReservableInfo : TraitInfo { } - public class Reservable : ITick, INotifyOwnerChanged, INotifySold, INotifyActorDisposing + public class Reservable : ITick, INotifyOwnerChanged, INotifySold, INotifyActorDisposing, INotifyCreated { Actor reservedFor; Aircraft reservedForAircraft; + RallyPoint rallyPoint; + + void INotifyCreated.Created(Actor self) + { + rallyPoint = self.TraitOrDefault(); + } void ITick.Tick(Actor self) { @@ -41,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits public IDisposable Reserve(Actor self, Actor forActor, Aircraft forAircraft) { if (reservedForAircraft != null && reservedForAircraft.MayYieldReservation) - reservedForAircraft.UnReserve(true); + UnReserve(self); reservedFor = forActor; reservedForAircraft = forAircraft; @@ -71,17 +78,27 @@ namespace OpenRA.Mods.Common.Traits return res == null || res.reservedForAircraft == null || res.reservedForAircraft.MayYieldReservation || res.reservedFor == forActor; } - private void UnReserve() + void UnReserve(Actor self) { if (reservedForAircraft != null) - reservedForAircraft.UnReserve(true); + { + if (reservedForAircraft.GetActorBelow() == self) + { + if (rallyPoint != null) + reservedFor.QueueActivity(reservedForAircraft.MoveTo(rallyPoint.Location, null, targetLineColor: Color.Green)); + else + reservedFor.QueueActivity(new TakeOff(reservedFor)); + } + + reservedForAircraft.UnReserve(); + } } - void INotifyActorDisposing.Disposing(Actor self) { UnReserve(); } + void INotifyActorDisposing.Disposing(Actor self) { UnReserve(self); } - void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UnReserve(); } + void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UnReserve(self); } - void INotifySold.Selling(Actor self) { UnReserve(); } - void INotifySold.Sold(Actor self) { UnReserve(); } + void INotifySold.Selling(Actor self) { UnReserve(self); } + void INotifySold.Sold(Actor self) { UnReserve(self); } } }