From fb1f8c4e018d4f9f4dc71a79d200eb33a5ffff0c Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Mon, 5 Sep 2016 19:20:51 +0200 Subject: [PATCH 1/5] Remove brain-dead logic from TakeOff 1. TakeOff's Tick() method never checks itself whether it is canceled 2. If NextActivity is null, TakeOff is the only activity on the queue 3. Takeoff canceling the queue then just cancels itself, with no effect at all 4. If Takeoff however is running as an inner activity, it will cancel the complete main queue, wrecking all sorts of havoc --- OpenRA.Mods.Common/Activities/Air/TakeOff.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Air/TakeOff.cs b/OpenRA.Mods.Common/Activities/Air/TakeOff.cs index 689519e2ce..42cba9054b 100644 --- a/OpenRA.Mods.Common/Activities/Air/TakeOff.cs +++ b/OpenRA.Mods.Common/Activities/Air/TakeOff.cs @@ -28,9 +28,6 @@ namespace OpenRA.Mods.Common.Activities public override Activity Tick(Actor self) { - if (NextActivity == null) - self.CancelActivity(); - aircraft.UnReserve(); var host = aircraft.GetActorBelow(); From 351c23169352df5856a5edd540da0bbe3643bfd5 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Mon, 5 Sep 2016 19:24:26 +0200 Subject: [PATCH 2/5] Use the yield reservation logic for helicopters as well. Oops. --- OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs index e2d7ba11a3..dd3df1e8d8 100644 --- a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs +++ b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs @@ -49,9 +49,11 @@ namespace OpenRA.Mods.Common.Activities else { // Helicopters should take off from their helipad immediately after resupplying. - // HACK: NextActivity needs to be appended here because otherwise TakeOff does stupid things. + // HACK: Append NextActivity to TakeOff to avoid moving to the Rallypoint (if NextActivity is non-null). inner = ActivityUtils.SequenceActivities( - aircraft.GetResupplyActivities(host).Append(new TakeOff(self)).Append(NextActivity).ToArray()); + aircraft.GetResupplyActivities(host) + .Append(new CallFunc(() => aircraft.MayYieldReservation = true)) + .Append(new TakeOff(self)).Append(NextActivity).ToArray()); } } else From daa1f16e987a26120436aa31a38f06223dc5fc9b Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Mon, 5 Sep 2016 19:59:01 +0200 Subject: [PATCH 3/5] Prevent an infinite loop when planes go out of ammo and all airfields are gone --- OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index 6056113c0b..9ca9e7aaeb 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -112,7 +112,11 @@ namespace OpenRA.Mods.Common.Activities new FlyCircleTimed(self, plane.Info.NumberOfTicksToVerifyAvailableAirport), this); else + { + // Prevent an infinite loop in case we'd return to the activity that called ReturnToBase in the first place. Go idle instead. + Cancel(self); return NextActivity; + } } List landingProcedures = new List(); From 9fbda6b598d9872c3b8d357936270d22c93c03ed Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Mon, 12 Sep 2016 23:01:16 +0200 Subject: [PATCH 4/5] Fix helicopters not taking off when their target got covered by shroud --- OpenRA.Mods.Common/Activities/Air/HeliAttack.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index cb00a2af7f..8a429e6f01 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -60,9 +60,9 @@ namespace OpenRA.Mods.Common.Activities { var newTarget = Target.FromCell(self.World, self.World.Map.CellContaining(target.CenterPosition)); - self.CancelActivity(); + Cancel(self); self.SetTargetLine(newTarget, Color.Green); - return ActivityUtils.SequenceActivities(new HeliFly(self, newTarget)); + return new HeliFly(self, newTarget); } // If any AmmoPool is depleted and no weapon is valid against target, return to helipad to reload and then resume the activity From 852d9477647bf242aafcc9976b2800ccebdac649 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Thu, 15 Sep 2016 20:50:56 +0200 Subject: [PATCH 5/5] Fix setting MayYieldReservation when there is no reservation --- .../Air/AllowYieldingReservation.cs | 32 +++++++++++++++++++ .../Activities/Air/ResupplyAircraft.cs | 4 +-- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 10 +++++- 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 OpenRA.Mods.Common/Activities/Air/AllowYieldingReservation.cs diff --git a/OpenRA.Mods.Common/Activities/Air/AllowYieldingReservation.cs b/OpenRA.Mods.Common/Activities/Air/AllowYieldingReservation.cs new file mode 100644 index 0000000000..751845d9f7 --- /dev/null +++ b/OpenRA.Mods.Common/Activities/Air/AllowYieldingReservation.cs @@ -0,0 +1,32 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using OpenRA.Activities; +using OpenRA.Mods.Common.Traits; + +namespace OpenRA.Mods.Common.Activities +{ + public class AllowYieldingReservation : Activity + { + readonly Aircraft aircraft; + + public AllowYieldingReservation(Actor self) + { + aircraft = self.Trait(); + } + + public override Activity Tick(Actor self) + { + aircraft.AllowYieldingReservation(); + return NextActivity; + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs index dd3df1e8d8..f481ba7652 100644 --- a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs +++ b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Activities { inner = ActivityUtils.SequenceActivities( aircraft.GetResupplyActivities(host) - .Append(new CallFunc(() => aircraft.MayYieldReservation = true)) + .Append(new AllowYieldingReservation(self)) .Append(new WaitFor(() => NextActivity != null || aircraft.ReservedActor == null)) .ToArray()); } @@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Activities // HACK: Append NextActivity to TakeOff to avoid moving to the Rallypoint (if NextActivity is non-null). inner = ActivityUtils.SequenceActivities( aircraft.GetResupplyActivities(host) - .Append(new CallFunc(() => aircraft.MayYieldReservation = true)) + .Append(new AllowYieldingReservation(self)) .Append(new TakeOff(self)).Append(NextActivity).ToArray()); } } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index f7b5de4468..d779655ae1 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -83,6 +83,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 2c9f5b090f..ec3634bf81 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.Traits public CPos TopLeft { get { return self.World.Map.CellContaining(CenterPosition); } } public int TurnSpeed { get { return Info.TurnSpeed; } } public Actor ReservedActor { get; private set; } - public bool MayYieldReservation; + public bool MayYieldReservation { get; private set; } bool airborne; bool cruising; @@ -282,6 +282,14 @@ namespace OpenRA.Mods.Common.Traits } } + public void AllowYieldingReservation() + { + if (reservation == null) + return; + + MayYieldReservation = true; + } + public void UnReserve() { if (reservation == null)