diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 4fa6ad33ba..e27c96bf67 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { static class UpgradeRules { - public const int MinimumSupportedVersion = 20151224; + public const int MinimumSupportedVersion = 20160508; internal static void TryUpdateColor(ref string value) { @@ -96,687 +96,6 @@ namespace OpenRA.Mods.Common.UtilityCommands { foreach (var node in nodes) { - if (engineVersion < 20151225 && depth == 2) - { - if (node.Key == "Color") - { - if (parent != null && parent.Key.StartsWith("FixedColorPalette")) - TryUpdateHSLColor(ref node.Value.Value); - else - TryUpdateColor(ref node.Value.Value); - } - else if (node.Key == "RadarPingColor" || node.Key == "SelectionBoxColor" || node.Key == "BarColor") - TryUpdateColor(ref node.Value.Value); - else if (node.Key == "Fog" || node.Key == "Shroud" || node.Key == "ParticleColors") - TryUpdateColors(ref node.Value.Value); - } - - // DeathType on Explodes was renamed to DeathTypes - if (engineVersion < 20151225) - { - if (node.Key == "Explodes") - { - var dt = node.Value.Nodes.FirstOrDefault(n => n.Key == "DeathType"); - if (dt != null) - dt.Key = "DeathTypes"; - } - } - - // Upgrades on DeployToUpgrade were renamed to DeployedUpgrades - if (engineVersion < 20151122) - { - if (node.Key == "DeployToUpgrade") - { - var u = node.Value.Nodes.FirstOrDefault(n => n.Key == "Upgrades"); - if (u != null) - u.Key = "DeployedUpgrades"; - } - } - - if (engineVersion < 20151225) - { - // Rename WithTurret to WithSpriteTurret - if (depth == 1 && node.Key.StartsWith("WithTurret")) - { - var parts = node.Key.Split('@'); - node.Key = "WithSpriteTurret"; - if (parts.Length > 1) - node.Key += "@" + parts[1]; - } - - if (depth == 1 && node.Key.StartsWith("-WithTurret")) - { - var parts = node.Key.Split('@'); - node.Key = "-WithSpriteTurret"; - if (parts.Length > 1) - node.Key += "@" + parts[1]; - } - - // Rename WithBarrel to WithSpriteBarrel - if (depth == 1 && node.Key.StartsWith("WithBarrel")) - { - var parts = node.Key.Split('@'); - node.Key = "WithSpriteBarrel"; - if (parts.Length > 1) - node.Key += "@" + parts[1]; - } - - if (depth == 1 && node.Key.StartsWith("-WithBarrel")) - { - var parts = node.Key.Split('@'); - node.Key = "-WithSpriteBarrel"; - if (parts.Length > 1) - node.Key += "@" + parts[1]; - } - - // Rename WithReloadingTurret to WithReloadingSpriteTurret - if (depth == 1 && node.Key.StartsWith("WithReloadingTurret")) - { - var parts = node.Key.Split('@'); - node.Key = "WithReloadingSpriteTurret"; - if (parts.Length > 1) - node.Key += "@" + parts[1]; - } - - if (depth == 1 && node.Key.StartsWith("-WithReloadingTurret")) - { - var parts = node.Key.Split('@'); - node.Key = "-WithReloadingSpriteTurret"; - if (parts.Length > 1) - node.Key += "@" + parts[1]; - } - } - - // Mobile actors immobilized by Carryable, Cargo, DeployToUpgrade, and/or others using upgrade(s) - if (engineVersion < 20151225 && depth == 0) - { - var notMobile = "notmobile"; - - var mobileNode = node.Value.Nodes.Find(n => n.Key == "Mobile"); - var carryableNode = node.Value.Nodes.Find(n => n.Key == "Carryable"); - var cargoNode = node.Value.Nodes.Find(n => n.Key == "Cargo"); - var deployToUpgradeNode = node.Value.Nodes.Find(n => n.Key == "DeployToUpgrade"); - var disableUpgradeNode = node.Value.Nodes.Find(n => n.Key == "DisableUpgrade"); - var disableMovementOnUpgradeNode = node.Value.Nodes.Find(n => n.Key == "DisableMovementOnUpgrade"); - - Action addNotMobileToTraitUpgrades = (trait, upgradesKey) => - { - if (trait != null) - { - var upgrades = trait.Value.Nodes.Find(u => u.Key == upgradesKey); - if (upgrades == null) - trait.Value.Nodes.Add(new MiniYamlNode(upgradesKey, notMobile)); - else if (string.IsNullOrEmpty(upgrades.Value.Value)) - upgrades.Value.Value = notMobile; - else if (!upgrades.Value.Value.Contains(notMobile)) - upgrades.Value.Value += ", " + notMobile; - } - }; - - if (mobileNode != null) - { - var mobileUpgrades = mobileNode.Value.Nodes.Find(n => n.Key == "UpgradeTypes"); - var mobileUpgradeMaxEnabledLevel = mobileNode.Value.Nodes.Find(n => n.Key == "UpgradeMaxEnabledLevel"); - var comma = new char[] { ',' }; - - Func addUpgradeMaxEnabledLevelNode = () => - { - if (mobileUpgradeMaxEnabledLevel == null) - { - mobileUpgradeMaxEnabledLevel = new MiniYamlNode("UpgradeMaxEnabledLevel", "0"); - mobileNode.Value.Nodes.Add(mobileUpgradeMaxEnabledLevel); - return true; - } - else - return mobileUpgradeMaxEnabledLevel.Value.Value == "0"; - }; - - // If exactly one upgrade type is in UpgradeTypes and UpgradeMaxEnabledLevel is/can be 0 , then use it as notmobile - if (mobileUpgrades != null && !string.IsNullOrEmpty(mobileUpgrades.Value.Value) - && !mobileUpgrades.Value.Value.Contains(",") && addUpgradeMaxEnabledLevelNode()) - notMobile = mobileUpgrades.Value.Value; - - if (mobileUpgradeMaxEnabledLevel != null && mobileUpgradeMaxEnabledLevel.Value.Value != "0") - Console.WriteLine("\t\t" + node.Key + " actor rules may require manual upgrading for immobilization upgrade logic."); - else - { - Action addImmobilizeUpgradeType = upgradeType => - { - if (mobileUpgrades == null) - { - mobileUpgrades = new MiniYamlNode("UpgradeTypes", upgradeType); - mobileNode.Value.Nodes.Add(mobileUpgrades); - } - else if (string.IsNullOrEmpty(mobileUpgrades.Value.Value)) - mobileUpgrades.Value.Value = upgradeType; - else if (!mobileUpgrades.Value.Value.Split(comma).Contains(upgradeType)) - mobileUpgrades.Value.Value += ", " + upgradeType; - }; - - Predicate addImmobilizeUpgradeTypes = upgradeTypes => - { - if (string.IsNullOrEmpty(upgradeTypes)) - return false; - - foreach (var upgradeType in upgradeTypes.Split(comma)) - addImmobilizeUpgradeType(upgradeType); - return true; - }; - - Predicate addUpgradeTypeFromTrait = trait => - { - var upgradeTypesNode = trait.Value.Nodes.Find(n => n.Key == "UpgradeTypes"); - if (upgradeTypesNode == null) - return false; - - addUpgradeMaxEnabledLevelNode(); - return addImmobilizeUpgradeTypes(upgradeTypesNode.Value.Value); - }; - - var noticeWritten = false; - - Action writeNotice = () => - { - if (noticeWritten) - return; - Console.WriteLine("\t\t" + node.Key + " actor rules may require manual upgrading for immobilization upgrade logic."); - noticeWritten = true; - }; - - if (disableUpgradeNode != null && !addUpgradeTypeFromTrait(disableUpgradeNode)) - { - writeNotice(); - Console.WriteLine("\t\t\tOne or more upgrades may need to be copied from the DisableUpgrade trait to the Mobile trait."); - } - - if (disableMovementOnUpgradeNode != null) - { - if (addUpgradeTypeFromTrait(disableMovementOnUpgradeNode)) - parent.Value.Nodes.Remove(disableMovementOnUpgradeNode); - else - { - writeNotice(); - Console.WriteLine("\t\t\tOne or more upgrades may need to be moved from the DisableMovementOnUpgrade trait to the Mobile trait."); - Console.WriteLine("\t\t\t\tRemember to remove the DisableMovementOnUpgrade trait."); - } - } - - if (carryableNode != null || cargoNode != null || deployToUpgradeNode != null) - { - addUpgradeMaxEnabledLevelNode(); - addImmobilizeUpgradeTypes(notMobile); - - addNotMobileToTraitUpgrades(carryableNode, "CarryableUpgrades"); - addNotMobileToTraitUpgrades(cargoNode, "LoadingUpgrades"); - addNotMobileToTraitUpgrades(deployToUpgradeNode, "DeployedUpgrades"); - } - } - } - else if (!node.Value.Nodes.Exists(n => n.Key == "Husk" || n.Key == "Building" || n.Key == "Aircraft" || n.Key == "Immobile")) - { - if (carryableNode != null || cargoNode != null || deployToUpgradeNode != null) - { - Console.WriteLine("\t\tIf " + node.Key - + " has a Mobile trait then adding the following with substituted by an immobilization upgrade for " - + node.Key + " may be neeeded:"); - - if (carryableNode != null) - { - Console.WriteLine("\t\t\tCarryable:"); - Console.WriteLine("\t\t\t\tCarryableUpgrades: "); - } - - if (cargoNode != null) - { - Console.WriteLine("\t\t\tCargo:"); - Console.WriteLine("\t\t\t\tLoadingUpgrades: "); - } - - if (deployToUpgradeNode != null) - { - Console.WriteLine("\t\t\tDeployToUpgrade:"); - Console.WriteLine("\t\t\t\tDeployedUpgrades: "); - } - } - - var disableUpgradeUpgradeTypesNode = disableUpgradeNode != null - ? disableUpgradeNode.Value.Nodes.Find(n => n.Key == "UpgradeTypes") - : null; - var disableMovementOnUpgradeUpgradeTypesNode = disableMovementOnUpgradeNode != null - ? disableMovementOnUpgradeNode.Value.Nodes.Find(n => n.Key == "UpgradeTypes") - : null; - - if (disableUpgradeUpgradeTypesNode != null || disableMovementOnUpgradeUpgradeTypesNode != null) - Console.WriteLine("\t\t" + node.Key + " actor rules may require manual upgrading for immobilization upgrade logic."); - - if (disableUpgradeUpgradeTypesNode != null) - Console.WriteLine("\t\t\tDisableUpgrade UpgradeTypes: " + disableUpgradeUpgradeTypesNode.Value.Value); - - if (disableMovementOnUpgradeUpgradeTypesNode != null) - Console.WriteLine("\t\t\tDisableMovementOnUpgrade UpgradeTypes: " + disableMovementOnUpgradeUpgradeTypesNode.Value.Value); - - if (disableMovementOnUpgradeNode != null) - node.Value.Nodes.Remove(disableMovementOnUpgradeNode); - } - } - - // 'CloseEnough' on 'RepairableNear' uses WDist now - if (engineVersion < 20151225) - { - if (node.Key == "RepairableNear") - { - var ce = node.Value.Nodes.FirstOrDefault(n => n.Key == "CloseEnough"); - if (ce != null && !ce.Value.Value.Contains("c")) - ce.Value.Value = ce.Value.Value + "c0"; - } - } - - // Added width support for line particles - if (engineVersion < 20151225 && node.Key == "WeatherOverlay") - { - var useSquares = node.Value.Nodes.FirstOrDefault(n => n.Key == "UseSquares"); - if (useSquares != null && !FieldLoader.GetValue("UseSquares", useSquares.Value.Value)) - node.Value.Nodes.Add(new MiniYamlNode("ParticleSize", "1, 1")); - } - - // Overhauled the actor decorations traits - if (engineVersion < 20151226) - { - if (depth == 1 && (node.Key.StartsWith("WithDecoration") || node.Key.StartsWith("WithRankDecoration"))) - { - node.Value.Nodes.RemoveAll(n => n.Key == "Scale"); - node.Value.Nodes.RemoveAll(n => n.Key == "Offset"); - var sd = node.Value.Nodes.FirstOrDefault(n => n.Key == "SelectionDecoration"); - if (sd != null) - sd.Key = "RequiresSelection"; - - var reference = node.Value.Nodes.FirstOrDefault(n => n.Key == "ReferencePoint"); - if (reference != null) - { - var values = FieldLoader.GetValue("ReferencePoint", reference.Value.Value); - values = values.Where(v => v != "HCenter" && v != "VCenter").ToArray(); - if (values.Length == 0) - values = new[] { "Center" }; - - reference.Value.Value = FieldSaver.FormatValue(values); - } - - var stance = Stance.Ally; - var showToAllies = node.Value.Nodes.FirstOrDefault(n => n.Key == "ShowToAllies"); - if (showToAllies != null && !FieldLoader.GetValue("ShowToAllies", showToAllies.Value.Value)) - stance ^= Stance.Ally; - var showToEnemies = node.Value.Nodes.FirstOrDefault(n => n.Key == "ShowToEnemies"); - if (showToEnemies != null && FieldLoader.GetValue("ShowToEnemies", showToEnemies.Value.Value)) - stance |= Stance.Enemy; - - if (stance != Stance.Ally) - node.Value.Nodes.Add(new MiniYamlNode("Stance", FieldSaver.FormatValue(stance))); - - node.Value.Nodes.RemoveAll(n => n.Key == "ShowToAllies"); - node.Value.Nodes.RemoveAll(n => n.Key == "ShowToEnemies"); - } - - if (depth == 1 && node.Key == "Fake") - { - node.Key = "WithDecoration@fake"; - node.Value.Nodes.Add(new MiniYamlNode("RequiresSelection", "true")); - node.Value.Nodes.Add(new MiniYamlNode("Image", "pips")); - node.Value.Nodes.Add(new MiniYamlNode("Sequence", "tag-fake")); - node.Value.Nodes.Add(new MiniYamlNode("ReferencePoint", "Top")); - node.Value.Nodes.Add(new MiniYamlNode("ZOffset", "256")); - } - - if (depth == 0 && node.Value.Nodes.Any(n => n.Key.StartsWith("PrimaryBuilding"))) - { - var decNodes = new List(); - decNodes.Add(new MiniYamlNode("RequiresSelection", "true")); - decNodes.Add(new MiniYamlNode("Image", "pips")); - decNodes.Add(new MiniYamlNode("Sequence", "tag-primary")); - decNodes.Add(new MiniYamlNode("ReferencePoint", "Top")); - decNodes.Add(new MiniYamlNode("ZOffset", "256")); - decNodes.Add(new MiniYamlNode("UpgradeTypes", "primary")); - decNodes.Add(new MiniYamlNode("UpgradeMinEnabledLevel", "1")); - node.Value.Nodes.Add(new MiniYamlNode("WithDecoration@primary", new MiniYaml("", decNodes))); - } - } - - // Refactored the low resources notification to a separate trait - if (engineVersion < 20151227 && node.Key == "Player") - { - var resourcesNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "PlayerResources"); - - if (resourcesNode != null) - { - var intervalNode = resourcesNode.Value.Nodes.FirstOrDefault(x => x.Key == "AdviceInterval"); - var storageNode = new MiniYamlNode("ResourceStorageWarning", ""); - - if (intervalNode != null) - { - // The time value is now in seconds, not ticks. We - // divide by 25 ticks per second at Normal. - int oldInterval; - if (int.TryParse(intervalNode.Value.Value, out oldInterval)) - storageNode.Value.Nodes.Add(new MiniYamlNode("AdviceInterval", (oldInterval / 25).ToString())); - resourcesNode.Value.Nodes.Remove(intervalNode); - } - - node.Value.Nodes.Add(storageNode); - } - } - - // Refactored Health.Radius to HitShapes - if (engineVersion < 20151227) - { - if (node.Key.StartsWith("Health")) - { - var radius = node.Value.Nodes.FirstOrDefault(x => x.Key == "Radius"); - if (radius != null) - { - var radiusValue = FieldLoader.GetValue("Radius", radius.Value.Value); - node.Value.Nodes.Add(new MiniYamlNode("Shape", "Circle")); - - var shape = node.Value.Nodes.First(x => x.Key == "Shape"); - shape.Value.Nodes.Add(new MiniYamlNode("Radius", radiusValue)); - - node.Value.Nodes.Remove(radius); - } - } - } - - // Remove obsolete TransformOnPassenger trait. - if (engineVersion < 20160102) - { - var removed = node.Value.Nodes.RemoveAll(x => x.Key.Contains("TransformOnPassenger")); - if (removed > 0) - { - Console.WriteLine("TransformOnPassenger has been removed."); - Console.WriteLine("Use the upgrades system to apply modifiers to the transport actor instead."); - } - } - - if (engineVersion < 20160103) - { - // Overhauled WithActiveAnimation -> WithIdleAnimation - if (node.Key == "WithActiveAnimation") - { - node.Key = "WithIdleAnimation"; - foreach (var n in node.Value.Nodes) - if (n.Key == "Sequence") - n.Key = "Sequences"; - } - } - - if (engineVersion < 20160107 && depth == 1 && node.Key.StartsWith("Cloak")) - { - var defaultCloakType = Traits.UncloakType.Attack - | Traits.UncloakType.Unload | Traits.UncloakType.Infiltrate | Traits.UncloakType.Demolish; - - // Merge Uncloak types - var t = defaultCloakType; - for (var i = node.Value.Nodes.Count - 1; i >= 0; i--) - { - var n = node.Value.Nodes[i]; - var v = string.Compare(n.Value.Value, "true", true) == 0; - Traits.UncloakType flag; - if (n.Key == "UncloakOnAttack") - flag = Traits.UncloakType.Attack; - else if (n.Key == "UncloakOnMove") - flag = Traits.UncloakType.Move; - else if (n.Key == "UncloakOnUnload") - flag = Traits.UncloakType.Unload; - else if (n.Key == "UncloakOnInfiltrate") - flag = Traits.UncloakType.Infiltrate; - else if (n.Key == "UncloakOnDemolish") - flag = Traits.UncloakType.Demolish; - else - continue; - t = v ? t | flag : t & ~flag; - node.Value.Nodes.Remove(n); - } - - if (t != defaultCloakType) - { - Console.WriteLine("\t\tCloak type: " + t.ToString()); - var ts = new List(); - if (t.HasFlag(Traits.UncloakType.Attack)) - ts.Add("Attack"); - if (t.HasFlag(Traits.UncloakType.Unload)) - ts.Add("Unload"); - if (t.HasFlag(Traits.UncloakType.Infiltrate)) - ts.Add("Infiltrate"); - if (t.HasFlag(Traits.UncloakType.Demolish)) - ts.Add("Demolish"); - if (t.HasFlag(Traits.UncloakType.Move)) - ts.Add("Move"); - node.Value.Nodes.Add(new MiniYamlNode("UncloakOn", ts.JoinWith(", "))); - } - } - - // Rename WithDockingOverlay to WithDockedOverlay - if (engineVersion < 20160116) - { - if (node.Key.StartsWith("WithDockingOverlay")) - node.Key = "WithDockedOverlay" + node.Key.Substring(18); - } - - if (engineVersion < 20160116) - { - if (node.Key == "DemoTruck") - node.Key = "AttackSuicides"; - } - - // Replaced GpsRemoveFrozenActor with FrozenUnderFogUpdatedByGps - if (engineVersion < 20160117) - { - if (node.Key == "GpsRemoveFrozenActor") - { - node.Key = "FrozenUnderFogUpdatedByGps"; - node.Value.Nodes.Clear(); - } - } - - // Removed arbitrary defaults from InfiltrateForCash - if (engineVersion < 20160118) - { - if (node.Key == "InfiltrateForCash") - { - if (!node.Value.Nodes.Any(n => n.Key == "Percentage")) - node.Value.Nodes.Add(new MiniYamlNode("Percentage", "50")); - - if (!node.Value.Nodes.Any(n => n.Key == "Minimum")) - node.Value.Nodes.Add(new MiniYamlNode("Minimum", "500")); - - var sound = node.Value.Nodes.FirstOrDefault(n => n.Key == "SoundToVictim"); - if (sound != null) - { - node.Value.Nodes.Remove(sound); - Console.WriteLine("The 'SoundToVictim' property of the 'InfiltrateForCash' trait has been"); - Console.WriteLine("replaced with a 'Notification' property. Please add the sound file"); - Console.WriteLine("'{0}' to your mod's audio notification yaml and".F(sound.Value.Value)); - Console.WriteLine("update your mod's rules accordingly."); - Console.WriteLine(); - } - } - } - - if (engineVersion < 20160301) - { - // Renamed ROT -> TurnSpeed - if (node.Key == "ROT") - node.Key = "TurnSpeed"; - } - - if (engineVersion < 20160320) - { - // Renamed Parachutable.CorpseSequenceCollection to Image - if (node.Key == "CorpseSequenceCollection") - node.Key = "Image"; - - // Renamed WithBuildingExplosion.SequenceCollection to Image - if (node.Key == "SequenceCollection") - node.Key = "Image"; - } - - if (engineVersion < 20160321) - { - var parentKey = parent != null ? parent.Key.Split('@').First() : null; - if (node.Key == "Ticks" && parentKey == "DrawLineToTarget") - node.Key = "Duration"; - if (node.Key == "ReloadTicks") - node.Key = "ReloadDelay"; - if (node.Key == "SelfReloadTicks") - node.Key = "SelfReloadDelay"; - if (node.Key == "LoadTicksPerBale") - node.Key = "BaleLoadDelay"; - if (node.Key == "UnloadTicksPerBale") - node.Key = "BaleUnloadDelay"; - if (node.Key == "TicksToHold") - node.Key = "HoldDuration"; - if (node.Key == "Ticks" && parentKey == "SelfHealing") - node.Key = "Delay"; - if (node.Key == "TicksToWaitBeforeReducingMoveRadius") - node.Key = "ReduceMoveRadiusDelay"; - if (node.Key == "MinIdleWaitTicks") - node.Key = "MinIdleDelay"; - if (node.Key == "MaxIdleWaitTicks") - node.Key = "MaxIdleWaitDelay"; - if (node.Key == "ReloadTime") - node.Key = "ReloadDelay"; - } - - // Got rid of most remaining usages of float in a bid to further reduce desync risk - if (engineVersion < 20160328) - { - // Migrated ProductionQueue BuildSpeed to use int percentage instead of float - if (node.Key.StartsWith("ProductionQueue") || node.Key.StartsWith("ClassicProductionQueue")) - { - var buildSpeedNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "BuildSpeed"); - if (buildSpeedNode != null) - { - // The BuildSpeed value is now an int percentage, so multiply the float with 100. - var oldValue = FieldLoader.GetValue("BuildSpeed", buildSpeedNode.Value.Value); - var newValue = (int)(oldValue * 100); - buildSpeedNode.Value.Value = newValue.ToString(); - } - } - - // Migrated StrategicVictoryConditions RatioRequired to use int percentage instead of float - if (node.Key.StartsWith("StrategicVictoryConditions")) - { - var ratioNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "RatioRequired"); - if (ratioNode != null) - { - // The RatioRequired value is now an int percentage, so multiply the float with 100. - var oldValue = FieldLoader.GetValue("RatioRequired", ratioNode.Value.Value); - var newValue = (int)(oldValue * 100); - ratioNode.Value.Value = newValue.ToString(); - } - } - - // Migrated Minelayer.MinefieldDepth to use WDist instead of float - if (node.Key.StartsWith("Minelayer")) - { - var depthNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "MinefieldDepth"); - if (depthNode != null) - { - // The MinefieldDepth value is now a WDist, so multiply the float value with 1024. - var oldValue = FieldLoader.GetValue("MinefieldDepth", depthNode.Value.Value); - var newValue = (int)(oldValue * 1024); - depthNode.Value.Value = newValue.ToString(); - } - } - - // Migrated SelfHealing to use int percentage instead of float - if (node.Key == "SelfHealing") - { - var healIfBelowNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "HealIfBelow"); - if (healIfBelowNode != null) - { - // The HealIfBelow value is now an int percentage, so multiply the float with 100. - var oldValue = FieldLoader.GetValue("HealIfBelow", healIfBelowNode.Value.Value); - var newValue = (int)(oldValue * 100); - healIfBelowNode.Value.Value = newValue.ToString(); - } - } - - // Migrated EmitInfantryOnSell to use int percentage instead of float - if (node.Key == "EmitInfantryOnSell") - { - var valueNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "ValuePercent"); - var minHPNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "MinHpPercent"); - - if (valueNode != null) - { - // The ValuePercent value is now an int percentage, but was previously geared towards - // percentage rather than float and divided by 100 internally so division by 100 is NOT needed. - var oldValue = FieldLoader.GetValue("ValuePercent", valueNode.Value.Value); - var newValue = (int)oldValue; - valueNode.Value.Value = newValue.ToString(); - } - - if (minHPNode != null) - { - // The MinHpPercent value is now an int percentage, but was previously geared towards - // percentage rather than float and divided by 100 internally so division by 100 is NOT needed. - var oldValue = FieldLoader.GetValue("MinHpPercent", minHPNode.Value.Value); - var newValue = (int)oldValue; - minHPNode.Value.Value = newValue.ToString(); - } - } - - // Migrated Captures and Capturable to use int percentage instead of float - if (node.Key == "Captures") - { - var sabotageHPRemNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "SabotageHPRemoval"); - if (sabotageHPRemNode != null) - { - // The SabotageHPRemoval value is now an int percentage, so multiply the float with 100. - var oldValue = FieldLoader.GetValue("SabotageHPRemoval", sabotageHPRemNode.Value.Value); - var newValue = (int)(oldValue * 100); - sabotageHPRemNode.Value.Value = newValue.ToString(); - } - } - - if (node.Key == "Capturable") - { - var captThreshNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "CaptureThreshold"); - if (captThreshNode != null) - { - // The CaptureThreshold value is now an int percentage, so multiply the float with 100. - var oldValue = FieldLoader.GetValue("CaptureThreshold", captThreshNode.Value.Value); - var newValue = (int)(oldValue * 100); - captThreshNode.Value.Value = newValue.ToString(); - } - } - } - - if (engineVersion < 20160402) - { - // Fix misleading property naming. - if (node.Key == "EffectSequence" && parent != null && parent.Key == "SpawnActorPower") - node.Key = "EffectImage"; - } - - if (engineVersion < 20160408) - { - var traitNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "InsufficientFundsWarning"); - if (traitNode != null) - { - var prNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "PlayerResources"); - if (prNode != null) - prNode.Value.Nodes.Add(new MiniYamlNode("InsufficientFundsNotification", new MiniYaml("InsufficientFunds"))); - - node.Value.Nodes.Remove(traitNode); - } - } - - if (engineVersion < 20160418) - { - // Removed FrozenUnderFog.StartsRevealed - if (node.Key == "FrozenUnderFog") - node.Value.Nodes.RemoveAll(x => x.Key == "StartsRevealed"); - } - if (engineVersion < 20160515) { // Use generic naming for building demolition using explosives. @@ -796,47 +115,6 @@ namespace OpenRA.Mods.Common.UtilityCommands { foreach (var node in nodes) { - if (engineVersion < 20160124) - { - node.Value.Nodes.RemoveAll(x => x.Key == "Charges"); - } - - // Enhance CreateEffectWarhead - if (engineVersion < 20160131) - { - if (node.Key.StartsWith("Warhead") && node.Value.Value == "CreateEffect") - { - // Add support for multiple explosions to CreateEffectWarhead - var explosionNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "Explosion"); - if (explosionNode != null) - explosionNode.Key = "Explosions"; - - // Add support for multiple impact sounds to CreateEffectWarhead - var impactSoundNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "ImpactSound"); - if (impactSoundNode != null) - impactSoundNode.Key = "ImpactSounds"; - } - } - - // Rename some speed-related Missile properties - if (engineVersion < 20160205) - { - var mod = Game.ModData.Manifest.Mod.Id; - if (mod == "ts") - { - if (node.Key == "Projectile" && node.Value.Value == "Missile") - { - node.Value.Nodes.Add(new MiniYamlNode("MinimumLaunchSpeed", "75")); - node.Value.Nodes.Add(new MiniYamlNode("Speed", "384")); - } - } - else - { - if (node.Key == "MaximumLaunchSpeed" && parent != null && parent.Value.Value == "Missile") - node.Key = "Speed"; - } - } - // Refactor Missile RangeLimit from ticks to WDist if (engineVersion < 20160501) {