diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index 70d5c10b32..c47a048674 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -869,6 +869,8 @@
+
+
diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/AircraftCanHoverGeneralization.cs b/OpenRA.Mods.Common/UpdateRules/Rules/AircraftCanHoverGeneralization.cs
new file mode 100644
index 0000000000..530f0be943
--- /dev/null
+++ b/OpenRA.Mods.Common/UpdateRules/Rules/AircraftCanHoverGeneralization.cs
@@ -0,0 +1,48 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2018 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 System.Collections.Generic;
+using System.Linq;
+
+namespace OpenRA.Mods.Common.UpdateRules.Rules
+{
+ public class AircraftCanHoverGeneralization : UpdateRule
+ {
+ public override string Name { get { return "Split Aircraft.CanHover into multiple parameters"; } }
+ public override string Description
+ {
+ get
+ {
+ return "Aircraft VTOL behaviour has been moved from CanHover to a new VTOL parameter.\n" +
+ "Aircraft taking off automatically after reloading has been moved from CanHover to a new TakeOffOnResupply parameter.\n" +
+ "Actors that set CanHover: true are updated with appropriate defaults for these parameters.";
+ }
+ }
+
+ public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode)
+ {
+ foreach (var aircraft in actorNode.ChildrenMatching("Aircraft"))
+ {
+ var canHover = aircraft.LastChildMatching("CanHover");
+ if (canHover != null && canHover.NodeValue())
+ {
+ if (!aircraft.ChildrenMatching("TakeOffOnResupply").Any())
+ aircraft.AddNode("TakeOffOnResupply", true);
+
+ if (!aircraft.ChildrenMatching("VTOL").Any())
+ aircraft.AddNode("VTOL", true);
+ }
+ }
+
+ yield break;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/RemoveMobileOnRails.cs b/OpenRA.Mods.Common/UpdateRules/Rules/RemoveMobileOnRails.cs
new file mode 100644
index 0000000000..2b00bbdfbf
--- /dev/null
+++ b/OpenRA.Mods.Common/UpdateRules/Rules/RemoveMobileOnRails.cs
@@ -0,0 +1,45 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2018 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 System;
+using System.Collections.Generic;
+using System.Linq;
+using OpenRA.Mods.Common.UpdateRules;
+
+namespace OpenRA.Mods.Common.UpdateRules.Rules
+{
+ public class RemoveMobileOnRails : UpdateRule
+ {
+ public override string Name { get { return "Notify Mobile.OnRails removal"; } }
+ public override string Description
+ {
+ get
+ {
+ return "The OnRails parameter on Mobile has been removed.\n" +
+ "Actors that want to duplicate the left-right movement of the original Tiberian Dawn gunboat\n" +
+ "should replace the Mobile and AttackTurreted traits with TDGunboat and AttackTDGunboatTurreted.";
+ }
+ }
+
+ public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode)
+ {
+ var removedOnRails = actorNode.ChildrenMatching("Mobile")
+ .Sum(m => m.Value.Nodes.RemoveAll(n => n.Key == "OnRails"));
+
+ if (removedOnRails == 0)
+ yield break;
+
+ yield return "Mobile.OnRails is no longer supported for actor type {0}.\n".F(actorNode.Key)
+ + "If you want to duplicate the left-right movement of the original Tiberian Dawn gunboat\n"
+ + "you must manually replace Mobile with the new TDGunboat trait, and AttackTurreted with AttackTDGunboatTurreted.";
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
index 92373c284c..a3d4a2ac37 100644
--- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
+++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
@@ -34,6 +34,12 @@ namespace OpenRA.Mods.Common.UpdateRules
Justification = "Extracting update lists to temporary variables obfuscates the definitions.")]
static readonly UpdatePath[] Paths =
{
+ new UpdatePath("incomplete-release-20171014", "release-20180218", new UpdateRule[]
+ {
+ new RemoveMobileOnRails(),
+ new AircraftCanHoverGeneralization()
+ }),
+
new UpdatePath("release-20180218", "release-20180307", new UpdateRule[0]),
new UpdatePath("release-20180307", new UpdateRule[]