diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index ecef9032e1..e92d3de7ad 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -585,10 +585,14 @@ + + + + diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/ChangeBuildableArea.cs b/OpenRA.Mods.Common/UpdateRules/Rules/ChangeBuildableArea.cs new file mode 100644 index 0000000000..2249ef6019 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/ChangeBuildableArea.cs @@ -0,0 +1,51 @@ +#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; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class ChangeBuildableArea : UpdateRule + { + public override string Name { get { return "Require 'AreaTypes' on 'GivesBuildableArea'"; } } + public override string Description + { + get + { + return "'AreaTypes' are now mandatory on 'GivesBuildableArea'.\n" + + "A 'RequiresBuildableArea' trait was added and 'Building.Adjacent' was moved there."; + } + } + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + var givesBuildableArea = actorNode.LastChildMatching("GivesBuildableArea"); + if (givesBuildableArea != null) + givesBuildableArea.AddNode("AreaTypes", "building"); + + var building = actorNode.LastChildMatching("Building"); + if (building != null) + { + var requiresBuildableArea = new MiniYamlNode("RequiresBuildableArea", ""); + requiresBuildableArea.AddNode("AreaTypes", "building"); + + var adjacent = building.LastChildMatching("Adjacent"); + if (adjacent != null) + requiresBuildableArea.AddNode(adjacent); + + actorNode.AddNode(requiresBuildableArea); + building.RemoveNodes("Adjacent"); + } + + yield break; + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/ChangeCanPowerDown.cs b/OpenRA.Mods.Common/UpdateRules/Rules/ChangeCanPowerDown.cs new file mode 100644 index 0000000000..e56635d339 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/ChangeCanPowerDown.cs @@ -0,0 +1,67 @@ +#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; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class ChangeCanPowerDown : UpdateRule + { + public override string Name { get { return "Provide a condition in 'CanPowerDown' instead of using 'Actor.Disabled'"; } } + public override string Description + { + get + { + return "'CanPowerDown' now provides a condition instead of using the legacy 'Actor.Disabled' boolean.\n" + + "Review your condition setup to make sure all relevant traits are disabled by that condition."; + } + } + + bool displayed; + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + var canPowerDown = actorNode.LastChildMatching("CanPowerDown"); + if (canPowerDown == null) + yield break; + + canPowerDown.AddNode("PowerdownCondition", "powerdown"); + + var image = canPowerDown.LastChildMatching("IndicatorImage"); + var seq = canPowerDown.LastChildMatching("IndicatorSequence"); + var pal = canPowerDown.LastChildMatching("IndicatorPalette"); + var imageValue = image != null ? image.NodeValue() : "poweroff"; + var seqValue = seq != null ? seq.NodeValue() : "offline"; + var palValue = pal != null ? pal.NodeValue() : "chrome"; + + var indicator = new MiniYamlNode("WithDecoration@POWERDOWN", ""); + indicator.AddNode("Image", imageValue); + indicator.AddNode("Sequence", seqValue); + indicator.AddNode("Palette", palValue); + indicator.AddNode("RequiresCondition", "powerdown"); + indicator.AddNode("ReferencePoint", "Center"); + + actorNode.AddNode(indicator); + if (image != null) + canPowerDown.RemoveNodes("IndicatorImage"); + if (seq != null) + canPowerDown.RemoveNodes("IndicatorSequence"); + if (pal != null) + canPowerDown.RemoveNodes("IndicatorPalette"); + + if (!displayed) + { + displayed = true; + yield return "'CanPowerDown' now provides a condition. You might need to review your condition setup."; + } + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/DropPauseAnimationWhenDisabled.cs b/OpenRA.Mods.Common/UpdateRules/Rules/DropPauseAnimationWhenDisabled.cs new file mode 100644 index 0000000000..b76dda0ef5 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/DropPauseAnimationWhenDisabled.cs @@ -0,0 +1,41 @@ +#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; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class DropPauseAnimationWhenDisabled : UpdateRule + { + public override string Name { get { return "Drop 'PauseAnimationWhenDisabled' from 'WithSpriteBody', replacing it with conditions."; } } + public override string Description + { + get + { + return "'WithSpriteBody' is a 'PausableConditionalTrait' now, allowing to drop the 'PauseAnimationWhenDisabled' property\n" + + "and to use 'PauseCondition' instead. (With a default value of 'disabled' in this case.)"; + } + } + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + var pauseAnimation = actorNode.LastChildMatching("PauseAnimationWhenDisabled"); + if (pauseAnimation == null) + yield break; + + pauseAnimation.RenameKey("PauseCondition"); + pauseAnimation.ReplaceValue("disabled"); + + yield return "'PauseAnimationWhenDisabled' was removed from 'WithSpriteBody' and replaced by conditions.\n" + + "You might need to review your condition setup."; + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/RemoveOutOfAmmo.cs b/OpenRA.Mods.Common/UpdateRules/Rules/RemoveOutOfAmmo.cs new file mode 100644 index 0000000000..920906f529 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/RemoveOutOfAmmo.cs @@ -0,0 +1,75 @@ +#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 RemoveOutOfAmmo : UpdateRule + { + public override string Name { get { return "Replace 'Armament.OutOfAmmo' by pausing on condition"; } } + public override string Description + { + get + { + return "'Armament.OutOfAmmo' has been replaced by pausing on condition\n" + + "(which is usually provided by AmmoPool)."; + } + } + + bool messageDisplayed; + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + var reloadAmmoPool = actorNode.LastChildMatching("ReloadAmmoPool"); + var armaments = actorNode.ChildrenMatching("Armament"); + var ammoPools = actorNode.ChildrenMatching("AmmoPool"); + + if (reloadAmmoPool != null || !armaments.Any() || !ammoPools.Any()) + yield break; + + foreach (var pool in ammoPools) + { + var nameNode = pool.LastChildMatching("Armaments"); + var name = nameNode != null ? nameNode.NodeValue() : "primary, secondary"; + var anyMatchingArmament = false; + var ammoNoAmmo = new MiniYamlNode("AmmoCondition", "ammo"); + var armNoAmmo = new MiniYamlNode("PauseOnCondition", "!ammo"); + + foreach (var arma in armaments) + { + var armaNameNode = arma.LastChildMatching("Name"); + var armaName = armaNameNode != null ? armaNameNode.NodeValue() : "primary"; + if (name.Contains(armaName)) + { + anyMatchingArmament = true; + arma.AddNode(armNoAmmo); + } + } + + if (anyMatchingArmament) + { + pool.AddNode(ammoNoAmmo); + if (!messageDisplayed) + { + yield return "Aircraft returning to base is now triggered when all armaments are paused via condition.\n" + + "Check if any of your actors with AmmoPools may need further changes."; + + messageDisplayed = true; + } + } + } + + yield break; + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs index 5c38530f1a..31c3cb0ffa 100644 --- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs +++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs @@ -44,7 +44,11 @@ namespace OpenRA.Mods.Common.UpdateRules new RemovePlayerPaletteTileset(), new RenameWithTurreted(), new ScaleDefaultModHealth(), - new ScaleSupportPowerSecondsToTicks() + new ScaleSupportPowerSecondsToTicks(), + new ChangeBuildableArea(), + new ChangeCanPowerDown(), + new DropPauseAnimationWhenDisabled(), + new RemoveOutOfAmmo() }), new UpdatePath("release-20180218", "release-20180307", new UpdateRule[0]),