Dispose of old update rules

This commit is contained in:
Gustas
2025-05-09 17:31:46 +03:00
committed by Matthias Mailänder
parent c27511dd66
commit 4be3add30a
25 changed files with 0 additions and 1395 deletions

View File

@@ -1,32 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 AddControlGroups : UpdateRule
{
public override string Name => "Add new ControlGroups trait.";
public override string Description => "A new trait ControlGroups was added, splitting logic away from Selection.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
if (actorNode.ChildrenMatching("Selection").Any(x => !x.IsRemoval())
&& !actorNode.ChildrenMatching("ControlGroups").Any())
actorNode.AddNode(new MiniYamlNodeBuilder("ControlGroups", ""));
yield break;
}
}
}

View File

@@ -1,37 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 AttackBomberFacingTolerance : UpdateRule
{
public override string Name => "Adds the old default value for AttackBomber FacingTolerance.";
public override string Description => "The tolerance for attack angle was defined twice on AttackBomber. This override has to be defined in the rules now.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var attackBomber in actorNode.ChildrenMatching("AttackBomber", includeRemovals: false))
{
var facingTolerance = attackBomber.LastChildMatching("FacingTolerance");
if (facingTolerance != null)
continue;
var facingToleranceNode = new MiniYamlNodeBuilder("FacingTolerance", FieldSaver.FormatValue(new WAngle(8)));
attackBomber.AddNode(facingToleranceNode);
}
yield break;
}
}
}

View File

@@ -1,39 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 AttackFrontalFacingTolerance : UpdateRule
{
public override string Name => "Adds the old default value for AttackFrontal's FacingTolerance.";
public override string Description =>
"The tolerance for the attack angle was defined twice on AttackFrontal. " +
"This override has to be defined in the rules now.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var attackFrontal in actorNode.ChildrenMatching("AttackFrontal", includeRemovals: false))
{
var facingTolerance = attackFrontal.LastChildMatching("FacingTolerance");
if (facingTolerance != null)
continue;
var facingToleranceNode = new MiniYamlNodeBuilder("FacingTolerance", FieldSaver.FormatValue(WAngle.Zero));
attackFrontal.AddNode(facingToleranceNode);
}
yield break;
}
}
}

View File

@@ -1,55 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 ConvertBoundsToWDist : UpdateRule
{
public override string Name => "Convert Interactable and Selection bounds from pixels to WDist.";
public override string Description =>
"The Bounds and DecorationBounds fields on Interactable and Selectable have been converted from pixels to WDist.\n" +
"All bounds must be scaled by 1024 (Rectangular map grid) or 1448 (Isometric map grid) divided by your mod tile size.";
readonly string[] traits = ["Interactable", "Selectable", "IsometricSelectable"];
readonly string[] fields = ["Bounds", "DecorationBounds"];
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
var grid = modData.Manifest.Get<MapGrid>();
var tileSize = modData.DefaultTerrainInfo.Values.First().TileSize;
var tileScale = grid.TileScale;
foreach (var trait in traits)
{
foreach (var traitNode in actorNode.ChildrenMatching(trait))
{
foreach (var field in fields)
{
foreach (var fieldNode in traitNode.ChildrenMatching(field))
{
var value = fieldNode.NodeValue<int[]>();
for (var i = 0; i < value.Length; i++)
value[i] = value[i] * tileScale / (i % 2 == 1 ? tileSize.Height : tileSize.Width);
fieldNode.ReplaceValue(FieldSaver.FormatValue(value));
}
}
}
}
yield break;
}
}
}

View File

@@ -1,33 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RemoveDomainIndex : UpdateRule
{
public override string Name => "Remove DomainIndex from World and add path finder overlays.";
public override string Description => "The DomainIndex trait was removed from World. Two overlay traits were added at the same time.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
if (actorNode.RemoveNodes("DomainIndex") > 0)
{
actorNode.AddNode(new MiniYamlNodeBuilder("PathFinderOverlay", ""));
actorNode.AddNode(new MiniYamlNodeBuilder("HierarchicalPathFinderOverlay", ""));
}
yield break;
}
}
}

View File

@@ -1,72 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RemovePlaceBuildingPalette : UpdateRule
{
public override string Name => "*PlaceBuildingPreview palette overrides have been removed.";
public override string Description =>
"The palette overrides on the ActorPreviewPlaceBuildingPreview, FootprintPlaceBuildingPreview\n" +
"SequencePlaceBuildingPreview, and D2kActorPreviewPlaceBuildingPreview traits have been removed.\n" +
"New Alpha and LineBuildSegmentAlpha properties have been added in their place.";
readonly List<string> locations = [];
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Count > 0)
yield return
"The *Palette fields have been removed from the *PlaceBuildingPreview traits.\n" +
"You may wish to inspect the following definitions and define new Alpha or\n" +
"LineBuildSegmentAlpha properties as appropriate to recreate transparency effects:\n" +
UpdateUtils.FormatMessageList(locations);
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
var removed = 0;
foreach (var node in actorNode.ChildrenMatching("ActorPreviewPlaceBuildingPreview"))
{
removed += node.RemoveNodes("OverridePalette");
removed += node.RemoveNodes("OverridePaletteIsPlayerPalette");
removed += node.RemoveNodes("LineBuildSegmentPalette");
}
foreach (var node in actorNode.ChildrenMatching("D2kActorPreviewPlaceBuildingPreview"))
{
removed += node.RemoveNodes("OverridePalette");
removed += node.RemoveNodes("OverridePaletteIsPlayerPalette");
removed += node.RemoveNodes("LineBuildSegmentPalette");
}
foreach (var node in actorNode.ChildrenMatching("FootprintPlaceBuildingPreview"))
removed += node.RemoveNodes("LineBuildSegmentPalette");
foreach (var node in actorNode.ChildrenMatching("SequencePlaceBuildingPreview"))
{
removed += node.RemoveNodes("SequencePalette");
removed += node.RemoveNodes("SequencePaletteIsPlayerPalette");
removed += node.RemoveNodes("LineBuildSegmentPalette");
}
if (removed > 0)
locations.Add($"{actorNode.Key} ({actorNode.Location.Name})");
yield break;
}
}
}

View File

@@ -1,28 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RemovePlayerHighlightPalette : UpdateRule
{
public override string Name => "PlayerHighlightPalette trait has been removed.";
public override string Description => "PlayerHighlightPalette trait has been removed. Its functionality is now automatically provided by the engine.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
actorNode.RemoveNodes("PlayerHighlightPalette");
yield break;
}
}
}

View File

@@ -1,30 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RemoveRenderSpritesScale : UpdateRule
{
public override string Name => "Remove RenderSprites.Scale.";
public override string Description => "The Scale option was removed from RenderSprites. Scale can now be defined on individual sequence definitions.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var renderSprites in actorNode.ChildrenMatching("RenderSprites"))
if (renderSprites.RemoveNodes("Scale") > 0)
yield return $"The actor-level scaling has been removed from {actorNode.Key} ({actorNode.Location.Name}).\n" +
"You must manually define Scale on its sequences instead.";
}
}
}

View File

@@ -1,124 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RemoveResourceType : UpdateRule
{
public override string Name => "Remove ResourceType definitions.";
public override string Description =>
"The ResourceType trait has been removed, and resource definitions moved to the\n" +
"ResourceLayer, EditorResourceLayer, ResourceRenderer, and PlayerResources traits.";
MiniYamlBuilder resourceLayer;
MiniYamlBuilder resourceRenderer;
MiniYamlBuilder values;
public override IEnumerable<string> BeforeUpdate(ModData modData)
{
resourceLayer = new MiniYamlBuilder("");
resourceRenderer = new MiniYamlBuilder("");
values = new MiniYamlBuilder("");
yield break;
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (resourceLayer.Nodes.Count > 0)
yield return "Add the following definitions to your ResourceLayer and EditorResourceLayer definitions:\n\t" +
"RecalculateResourceDensity: true\n\t" +
resourceLayer.ToLines("ResourceTypes").JoinWith("\n\t");
if (resourceLayer.Nodes.Count > 0)
yield return "Add the following definitions to your ResourceRenderer definition:\n\t" +
resourceRenderer.ToLines("ResourceTypes").JoinWith("\n\t");
if (values.Nodes.Count > 0)
yield return "Add the following definition to your ^BasePlayer definition:\n\t" +
"PlayerResources:\n\t\t" +
values.ToLines("ResourceValues").JoinWith("\n\t\t");
if (resourceLayer.Nodes.Count > 0)
yield return "Support for AllowUnderActors, AllowUnderBuildings, and AllowOnRamps have been removed.\n" +
"You must define a custom ResourceLayer subclass if you want to customize the default behaviour.";
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var resourceNode in actorNode.ChildrenMatching("ResourceType"))
{
var typeNode = resourceNode.LastChildMatching("Type");
if (typeNode != null)
{
var resourceLayerNode = new MiniYamlNodeBuilder(new MiniYamlNode(typeNode.Value.Value, ""));
resourceLayer.Nodes.Add(resourceLayerNode);
var resourceRendererNode = new MiniYamlNodeBuilder(new MiniYamlNode(typeNode.Value.Value, ""));
resourceRenderer.Nodes.Add(resourceRendererNode);
var indexNode = resourceNode.LastChildMatching("ResourceType");
if (indexNode != null)
{
indexNode.RenameKey("ResourceIndex");
resourceLayerNode.AddNode(indexNode);
}
var terrainTypeNode = resourceNode.LastChildMatching("TerrainType");
if (terrainTypeNode != null)
resourceLayerNode.AddNode(terrainTypeNode);
var allowedTerrainNode = resourceNode.LastChildMatching("AllowedTerrainTypes");
if (allowedTerrainNode != null)
resourceLayerNode.AddNode(allowedTerrainNode);
var maxDensityNode = resourceNode.LastChildMatching("MaxDensity");
if (maxDensityNode != null)
resourceLayerNode.AddNode(maxDensityNode);
var valueNode = resourceNode.LastChildMatching("ValuePerUnit");
if (valueNode != null)
values.Nodes.Add(new MiniYamlNodeBuilder(typeNode.Value.Value, valueNode.Value.Value));
var imageNode = resourceNode.LastChildMatching("Image");
if (imageNode != null)
resourceRendererNode.AddNode(imageNode);
var sequencesNode = resourceNode.LastChildMatching("Sequences");
if (sequencesNode != null)
resourceRendererNode.AddNode(sequencesNode);
var paletteNode = resourceNode.LastChildMatching("Palette");
if (paletteNode != null)
resourceRendererNode.AddNode(paletteNode);
var nameNode = resourceNode.LastChildMatching("Name");
if (nameNode != null)
resourceRendererNode.AddNode(nameNode);
}
else
yield return "Unable to process definition:\n" +
resourceNode.Value.ToLines(resourceNode.Key).JoinWith("\n") + "\n\n" +
"This override has been removed and must be manually reimplemented if still needed.";
}
actorNode.RemoveNodes("ResourceType");
foreach (var resourceRendererNode in actorNode.ChildrenMatching("ResourceRenderer"))
resourceRendererNode.RemoveNodes("RenderTypes");
foreach (var resourceRendererNode in actorNode.ChildrenMatching("D2kResourceRenderer"))
resourceRendererNode.RemoveNodes("RenderTypes");
}
}
}

View File

@@ -1,105 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RemoveSmokeTrailWhenDamaged : UpdateRule
{
public override string Name { get { return "'SmokeTrailWhenDamaged' has been removed in favor of using 'LeavesTrails'."; } }
public override string Description
{
get
{
return "'SmokeTrailWhenDamaged' was removed.";
}
}
readonly Dictionary<string, List<string>> locations = [];
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Count > 0)
yield return "Some actor(s) defined a MinDamage of neither 'Heavy' nor 'Undamaged' on SmokeTrailWhenDamaged before update.\n" +
"Review the following definitions and add custom GrandConditionOnDamageState configs as required:\n" +
UpdateUtils.FormatMessageList(locations.Select(
kv => kv.Key + ":\n" + UpdateUtils.FormatMessageList(kv.Value)));
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
var locationKey = $"{actorNode.Key} ({actorNode.Location.Name})";
var anyConditionalSmokeTrail = false;
foreach (var smokeTrail in actorNode.ChildrenMatching("SmokeTrailWhenDamaged"))
{
var spriteNode = smokeTrail.LastChildMatching("Sprite");
if (spriteNode != null)
smokeTrail.RenameChildrenMatching("Sprite", "Image");
else
smokeTrail.AddNode("Image", FieldSaver.FormatValue("smokey"));
var intervalNode = smokeTrail.LastChildMatching("Interval");
if (intervalNode != null)
{
var interval = intervalNode.NodeValue<int>();
smokeTrail.RenameChildrenMatching("Interval", "MovingInterval");
smokeTrail.AddNode("StationaryInterval", FieldSaver.FormatValue(interval));
}
else
{
smokeTrail.AddNode("MovingInterval", FieldSaver.FormatValue(3));
smokeTrail.AddNode("StationaryInterval", FieldSaver.FormatValue(3));
}
var minDamageNode = smokeTrail.LastChildMatching("MinDamage");
var isConditional = true;
if (minDamageNode != null)
{
var minDamage = minDamageNode.NodeValue<string>();
if (minDamage == "Undamaged")
isConditional = false;
else if (minDamage != "Heavy")
locations.GetOrAdd(locationKey).Add(smokeTrail.Key);
smokeTrail.RemoveNode(minDamageNode);
}
smokeTrail.AddNode("SpawnAtLastPosition", FieldSaver.FormatValue(false));
smokeTrail.AddNode("TrailWhileStationary", FieldSaver.FormatValue(true));
smokeTrail.AddNode("Type", FieldSaver.FormatValue("CenterPosition"));
if (isConditional)
{
smokeTrail.AddNode("RequiresCondition", FieldSaver.FormatValue("enable-smoke"));
anyConditionalSmokeTrail = true;
}
smokeTrail.RenameChildrenMatching("Sequence", "Sequences");
smokeTrail.RenameChildrenMatching("Offset", "Offsets");
smokeTrail.RenameKey("LeavesTrails");
}
if (anyConditionalSmokeTrail)
{
var grantCondition = new MiniYamlNodeBuilder("GrantConditionOnDamageState@SmokeTrail", "");
grantCondition.AddNode("Condition", FieldSaver.FormatValue("enable-smoke"));
actorNode.AddNode(grantCondition);
}
yield break;
}
}
}

View File

@@ -1,33 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RenameCloakTypes : UpdateRule
{
public override string Name => "Rename 'CloakTypes' to 'DetectionTypes'";
public override string Description => "Rename 'CloakTypes' to 'DetectionTypes' in order to make it clearer as well as make space for 'CloakType' in Cloak";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var traitNode in actorNode.ChildrenMatching("Cloak"))
traitNode.RenameChildrenMatching("CloakTypes", "DetectionTypes");
foreach (var traitNode in actorNode.ChildrenMatching("DetectCloaked"))
traitNode.RenameChildrenMatching("CloakTypes", "DetectionTypes");
yield break;
}
}
}

View File

@@ -1,53 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RenameContrailProperties : UpdateRule
{
public override string Name => "Rename contrail color properties";
public override string Description =>
"Rename contrail color properties `Color` to `StartColor` and `UsePlayerColor` to `StartColorUsePlayerColor` " +
"in traits and weapons to account for added `EndColor` functionality";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var traitNode in actorNode.ChildrenMatching("Contrail"))
{
traitNode.RenameChildrenMatching("Color", "StartColor");
traitNode.RenameChildrenMatching("UsePlayerColor", "StartColorUsePlayerColor");
}
yield break;
}
public override IEnumerable<string> UpdateWeaponNode(ModData modData, MiniYamlNodeBuilder weaponNode)
{
foreach (var traitNode in weaponNode.ChildrenMatching("Projectile").Where(n => n.Value.Value == "Missile"))
{
traitNode.RenameChildrenMatching("ContrailColor", "ContrailStartColor");
traitNode.RenameChildrenMatching("ContrailUsePlayerColor", "ContrailStartColorUsePlayerColor");
}
foreach (var traitNode in weaponNode.ChildrenMatching("Projectile").Where(n => n.Value.Value == "Bullet"))
{
traitNode.RenameChildrenMatching("ContrailColor", "ContrailStartColor");
traitNode.RenameChildrenMatching("ContrailUsePlayerColor", "ContrailStartColorUsePlayerColor");
}
yield break;
}
}
}

View File

@@ -1,33 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RenameMPTraits : UpdateRule
{
public override string Name => "Several traits spawning map actors and players have been renamed.";
public override string Description =>
"'SpawnMPUnits' was renamed to 'SpawnStartingUnits', 'MPStartUnits' to 'StartingUnits', 'MPStartLocations' to " +
"'MapStartingLocations', and 'CreateMPPlayers' to 'CreateMapPlayers'.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
actorNode.RenameChildrenMatching("SpawnMPUnits", "SpawnStartingUnits");
actorNode.RenameChildrenMatching("MPStartUnits", "StartingUnits");
actorNode.RenameChildrenMatching("MPStartLocations", "MapStartingLocations");
actorNode.RenameChildrenMatching("CreateMPPlayers", "CreateMapPlayers");
yield break;
}
}
}

View File

@@ -1,32 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 RenameSupportPowerDescription : UpdateRule
{
public override string Name => "Support powers now use 'Name' and 'Description' fields like units.";
public override string Description => "'Description' was renamed to 'Name' and 'LongDesc' was renamed to 'Description'.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var traitNode in actorNode.ChildrenContaining("Power"))
{
traitNode.RenameChildrenMatching("Description", "Name");
traitNode.RenameChildrenMatching("LongDesc", "Description");
}
yield break;
}
}
}

View File

@@ -1,43 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 ReplaceCrateSecondsWithTicks : UpdateRule
{
public override string Name => "Changed Crate Lifetime to Duration and use ticks and renamed PanicLength to PanicDuration.";
public override string Description =>
"Crate.Lifetime was the last non-sound-related place to still use 'seconds'\n" +
"by multiplying with 25 internally. Converted to use ticks like everything else.\n" +
"Also renamed Lifetime to Duration and ScaredyCat.PanicLength to PanicDuration to match other places.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var crateNode in actorNode.ChildrenMatching("Crate"))
{
foreach (var lifetimeNode in crateNode.ChildrenMatching("Lifetime"))
{
var lifetime = lifetimeNode.NodeValue<int>();
lifetimeNode.Value.Value = FieldSaver.FormatValue(lifetime * 25);
lifetimeNode.RenameKey("Duration");
}
}
foreach (var scNode in actorNode.ChildrenMatching("ScaredyCat"))
scNode.RenameChildrenMatching("PanicLength", "PanicDuration");
yield break;
}
}
}

View File

@@ -1,36 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 ReplaceResourceValueModifiers : UpdateRule
{
public override string Name => "HarvesterResourceMultiplier and RefineryResourceMultiplier replaced with ResourceValueMultiplier.";
public override string Description =>
"The HarvesterResourceMultiplier trait has been removed, " +
"and the RefineryResourceMultiplier trait renamed to ResourceValueMultiplier.";
bool notified;
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
if (actorNode.RemoveNodes("HarvesterResourceModifier") > 0 && !notified)
{
notified = true;
yield return "The HarvesterResourceMultiplier trait is no longer supported and has been removed.";
}
actorNode.RenameChildrenMatching("RefineryResourceMultiplier", "ResourceValueMultiplier");
}
}
}

View File

@@ -1,31 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 ReplaceSequenceEmbeddedPalette : UpdateRule
{
public override string Name => "Replace Sequence EmbeddedPalette with HasEmbeddedPalette.";
public override string Description => "The EmbeddedPalette sequence option was replaced with a boolean HasEmbeddedPalette.";
public override IEnumerable<string> UpdateSequenceNode(ModData modData, MiniYamlNodeBuilder sequenceNode)
{
foreach (var sequence in sequenceNode.Value.Nodes)
if (sequence.RemoveNodes("EmbeddedPalette") > 0)
sequence.AddNode("HasEmbeddedPalette", true);
yield break;
}
}
}

View File

@@ -1,58 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 ReplaceShadowPalette : UpdateRule
{
public override string Name => "Removed ShadowPalette from WithShadow and projectiles.";
public override string Description =>
"The ShadowPalette field has been replaced by ShadowColor on projectiles.\n" +
"The Palette field on WithShadow and ShadowPalette on WithParachute have similarly been replaced with ShadowColor.";
readonly List<string> locations = [];
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Count > 0)
yield return "The shadow palette overrides have been removed from the following locations:\n" +
UpdateUtils.FormatMessageList(locations) + "\n\n" +
"You may wish to inspect and change these.";
locations.Clear();
}
public override IEnumerable<string> UpdateWeaponNode(ModData modData, MiniYamlNodeBuilder weaponNode)
{
foreach (var projectileNode in weaponNode.ChildrenMatching("Projectile"))
if (projectileNode.RemoveNodes("ShadowPalette") > 0)
locations.Add($"{weaponNode.Key}: {weaponNode.Key} ({weaponNode.Location.Name})");
yield break;
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var node in actorNode.ChildrenMatching("WithShadow"))
if (node.RemoveNodes("Palette") > 0)
locations.Add($"{actorNode.Key}: {node.Key} ({actorNode.Location.Name})");
foreach (var node in actorNode.ChildrenMatching("WithParachute"))
if (node.RemoveNodes("ShadowPalette") > 0)
locations.Add($"{actorNode.Key}: {node.Key} ({actorNode.Location.Name})");
yield break;
}
}
}

View File

@@ -1,43 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 ReplaceWithColoredOverlayPalette : UpdateRule
{
public override string Name => "WithColoredOverlay Palette changed to Color.";
public override string Description => "The Palette field has been removed from WithColoredOverlay. You must now specify the Color directly.";
readonly List<string> locations = [];
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Count > 0)
yield return
"You must define new Color fields on the following traits:\n" +
UpdateUtils.FormatMessageList(locations);
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var node in actorNode.ChildrenMatching("WithColoredOverlay"))
if (node.RemoveNodes("Palette") > 0)
locations.Add($"{actorNode.Key}: {node.Key} ({actorNode.Location.Name})");
yield break;
}
}
}

View File

@@ -1,40 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 SplitNukePowerMissileImage : UpdateRule
{
public override string Name => "NukePower now defines the image for the missile with MissileImage.";
public override string Description =>
"NukePower used MissileWeapon field for as the name for missile image too.\n" +
"This function has been moved to its own MissileImage field.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var nukePowerNode in actorNode.ChildrenMatching("NukePower"))
{
var missileWeaponNode = nukePowerNode.ChildrenMatching("MissileWeapon").FirstOrDefault();
if (missileWeaponNode != null)
{
var weapon = missileWeaponNode.NodeValue<string>();
nukePowerNode.AddNode(new MiniYamlNodeBuilder("MissileImage", weapon));
}
}
yield break;
}
}
}

View File

@@ -1,113 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 UnhardcodeBaseBuilderBotModule : UpdateRule, IBeforeUpdateActors
{
MiniYamlNodeBuilder defenses;
// Excludes AttackBomber and AttackTDGunboatTurreted as actors with these AttackBase traits aren't supposed to be controlled.
readonly string[] attackBase =
[
"AttackLeap",
"AttackPopupTurreted",
"AttackAircraft",
"AttackTesla",
"AttackCharges",
"AttackFollow",
"AttackTurreted",
"AttackFrontal",
"AttackGarrisoned",
"AttackOmni",
"AttackSwallow"
];
readonly string[] buildings = ["Building", "EnergyWall", "D2kBuilding"];
bool anyAdded;
public override string Name => "BaseBuilderBotModule got new fields to configure buildings that are defenses.";
public override string Description => "DefenseTypes were added.";
public IEnumerable<string> BeforeUpdateActors(ModData modData, List<MiniYamlNodeBuilder> resolvedActors)
{
var defenses = new List<string>();
foreach (var actor in resolvedActors)
{
if (actor.Key.StartsWith('^'))
continue;
var isBuildable = false;
var isBuilding = false;
var canAttack = false;
foreach (var trait in actor.Value.Nodes)
{
if (trait.IsRemoval())
continue;
if (trait.KeyMatches("Buildable", includeRemovals: false))
{
isBuildable = true;
continue;
}
if (buildings.Any(v => trait.KeyMatches(v, includeRemovals: false)))
{
isBuilding = true;
continue;
}
if (attackBase.Any(ab => trait.KeyMatches(ab, includeRemovals: false)))
canAttack = true;
}
if (isBuildable && isBuilding && canAttack)
{
var name = actor.Key.ToLowerInvariant();
if (!defenses.Contains(name))
defenses.Add(name);
}
}
this.defenses = new MiniYamlNodeBuilder("DefenseTypes", FieldSaver.FormatValue(defenses));
yield break;
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (anyAdded)
yield return "`BaseBuilderBotModule` was unhardcoded and a new field added: `DefenseTypes`. Please verify the automated changes.";
anyAdded = false;
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var squadManager in actorNode.ChildrenMatching("BaseBuilderBotModule", includeRemovals: false))
{
if (!squadManager.ChildrenMatching(defenses.Key, includeRemovals: false).Any())
{
squadManager.AddNode(defenses);
anyAdded = true;
}
}
yield break;
}
}
}

View File

@@ -1,155 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 UnhardcodeSquadManager : UpdateRule, IBeforeUpdateActors
{
readonly List<MiniYamlNodeBuilder> addNodes = [];
// Excludes AttackBomber and AttackTDGunboatTurreted as actors with these AttackBase traits aren't supposed to be controlled.
readonly string[] attackBase =
[
"AttackLeap",
"AttackPopupTurreted",
"AttackAircraft",
"AttackTesla",
"AttackCharges",
"AttackFollow",
"AttackTurreted",
"AttackFrontal",
"AttackGarrisoned",
"AttackOmni",
"AttackSwallow"
];
readonly string[] vipsNames = ["Harvester", "BaseBuilding"];
readonly string[] buildings = ["Building", "EnergyWall", "D2kBuilding"];
readonly string[] excludedBuildings = ["LineBuild", "Plug"];
public override string Name => "SquadManagerBotModule got new fields to configure ground attacks and defensive actions.";
public override string Description => "AirUnitsTypes and ProtectionTypes were added.";
public IEnumerable<string> BeforeUpdateActors(ModData modData, List<MiniYamlNodeBuilder> resolvedActors)
{
var aircraft = new List<string>();
var vips = new List<string>();
foreach (var actor in resolvedActors)
{
if (actor.Key.StartsWith('^'))
continue;
var isVip = false;
var isBuildable = false;
var isBuilding = false;
var isAircraft = false;
var isExcluded = false;
var canAttack = false;
var isKillable = false;
foreach (var trait in actor.Value.Nodes)
{
if (trait.IsRemoval())
continue;
if (trait.KeyMatches("Buildable", includeRemovals: false))
{
isBuildable = true;
continue;
}
if (trait.KeyMatches("Aircraft", includeRemovals: false))
{
isAircraft = true;
continue;
}
if (trait.KeyMatches("Health", includeRemovals: false))
{
isKillable = true;
continue;
}
if (vipsNames.Any(v => trait.KeyMatches(v, includeRemovals: false)))
{
isVip = true;
continue;
}
if (buildings.Any(b => trait.KeyMatches(b, includeRemovals: false)))
{
isBuilding = true;
continue;
}
if (excludedBuildings.Any(eb => trait.KeyMatches(eb, includeRemovals: false)))
{
isExcluded = true;
continue;
}
if (attackBase.Any(ab => trait.KeyMatches(ab, includeRemovals: false)))
canAttack = true;
}
if (isAircraft && isBuildable && canAttack && isKillable)
{
var name = actor.Key.ToLowerInvariant();
if (!aircraft.Contains(name))
aircraft.Add(name);
}
if (isBuildable && isKillable && (isVip || (isBuilding && !isExcluded)))
{
var name = actor.Key.ToLowerInvariant();
if (!vips.Contains(name))
vips.Add(name);
}
}
addNodes.Add(new MiniYamlNodeBuilder("AirUnitsTypes", FieldSaver.FormatValue(aircraft)));
addNodes.Add(new MiniYamlNodeBuilder("ProtectionTypes", FieldSaver.FormatValue(vips)));
yield break;
}
bool anyAdded = false;
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var squadManager in actorNode.ChildrenMatching("SquadManagerBotModule", includeRemovals: false))
{
foreach (var addNode in addNodes)
{
if (!squadManager.ChildrenMatching(addNode.Key, includeRemovals: false).Any())
{
squadManager.AddNode(addNode);
anyAdded = true;
}
}
}
yield break;
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (anyAdded)
yield return "`SquadManagerBotModule` was unhardcoded and new fields added: `AirUnitsTypes` and `ProtectionTypes`. Please verify the automated changes.";
anyAdded = false;
}
}
}

View File

@@ -1,48 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 UnhardcodeVeteranProductionIconOverlay : UpdateRule
{
public override string Name => "VeteranProductionIconOverlay is changed to ProductionIconOverlayManager giving it more customisation.";
public override string Description => "ProductionIconOverlayManager now works with the new WithProductionIconOverlay trait, instead of ProducibleWithLevel.";
readonly List<string> locations = [];
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Count != 0)
yield return "Icon overlay logic has been split from ProducibleWithLevel to WithProductionIconOverlay trait.\n" +
"If you have been using VeteranProductionIconOverlay trait, add WithProductionIconOverlay to following actors:\n" +
UpdateUtils.FormatMessageList(locations);
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var veteranProductionIconOverlay in actorNode.ChildrenMatching("VeteranProductionIconOverlay"))
{
veteranProductionIconOverlay.RenameKey("ProductionIconOverlayManager");
veteranProductionIconOverlay.AddNode(new MiniYamlNodeBuilder("Type", "Veterancy"));
}
foreach (var producibleWithLevel in actorNode.ChildrenMatching("ProducibleWithLevel"))
locations.Add($"{actorNode.Key}: {producibleWithLevel.Key} ({actorNode.Location.Name})");
yield break;
}
}
}

View File

@@ -1,92 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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 UseMillisecondsForSounds : UpdateRule
{
public override string Name => "Convert announcement/notifier intervals to real (milli)seconds.";
public override string Description =>
"AnnounceOnKill.Interval, Harvester- and BaseAttackNotifier.NotifyInterval and\n" +
"ResourceStorageWarning.AdviceInterval were using 'fake' seconds (value * 25 ticks).\n" +
"PowerManager.AdviceInterval and PlayerResources.InsufficientFundsNotificationDelay were using ticks.\n" +
"Converted all of those to use real milliseconds instead.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var announce in actorNode.ChildrenMatching("AnnounceOnKill"))
{
var intervalNode = announce.LastChildMatching("Interval");
if (intervalNode != null)
{
var interval = intervalNode.NodeValue<int>();
intervalNode.Value.Value = FieldSaver.FormatValue(interval * 1000);
}
}
foreach (var notifier in actorNode.ChildrenMatching("BaseAttackNotifier"))
{
var notifyIntervalNode = notifier.LastChildMatching("NotifyInterval");
if (notifyIntervalNode != null)
{
var notifyInterval = notifyIntervalNode.NodeValue<int>();
notifyIntervalNode.Value.Value = FieldSaver.FormatValue(notifyInterval * 1000);
}
}
foreach (var notifier in actorNode.ChildrenMatching("HarvesterAttackNotifier"))
{
var notifyIntervalNode = notifier.LastChildMatching("NotifyInterval");
if (notifyIntervalNode != null)
{
var notifyInterval = notifyIntervalNode.NodeValue<int>();
notifyIntervalNode.Value.Value = FieldSaver.FormatValue(notifyInterval * 1000);
}
}
foreach (var rsw in actorNode.ChildrenMatching("ResourceStorageWarning"))
{
var adviceIntervalNode = rsw.LastChildMatching("AdviceInterval");
if (adviceIntervalNode != null)
{
var adviceInterval = adviceIntervalNode.NodeValue<int>();
adviceIntervalNode.Value.Value = FieldSaver.FormatValue(adviceInterval * 1000);
}
}
foreach (var pm in actorNode.ChildrenMatching("PowerManager"))
{
var adviceIntervalNode = pm.LastChildMatching("AdviceInterval");
if (adviceIntervalNode != null)
{
var adviceInterval = adviceIntervalNode.NodeValue<int>();
adviceIntervalNode.Value.Value = FieldSaver.FormatValue(adviceInterval * 40);
}
}
foreach (var pr in actorNode.ChildrenMatching("PlayerResources"))
{
var noFundsIntervalNode = pr.LastChildMatching("InsufficientFundsNotificationDelay");
if (noFundsIntervalNode != null)
{
var noFundsInterval = noFundsIntervalNode.NodeValue<int>();
noFundsIntervalNode.Value.Value = FieldSaver.FormatValue(noFundsInterval * 40);
noFundsIntervalNode.RenameKey("InsufficientFundsNotificationInterval");
}
}
yield break;
}
}
}

View File

@@ -31,36 +31,6 @@ namespace OpenRA.Mods.Common.UpdateRules
// release-to-bleed path. // release-to-bleed path.
static readonly UpdatePath[] Paths = static readonly UpdatePath[] Paths =
[ [
new("release-20210321", "release-20230225",
[
new RenameMPTraits(),
new RemovePlayerHighlightPalette(),
new ReplaceWithColoredOverlayPalette(),
new RemoveRenderSpritesScale(),
new RemovePlaceBuildingPalette(),
new ReplaceShadowPalette(),
new ReplaceResourceValueModifiers(),
new RemoveResourceType(),
new ConvertBoundsToWDist(),
new RemoveSmokeTrailWhenDamaged(),
new ReplaceCrateSecondsWithTicks(),
new UseMillisecondsForSounds(),
new RenameSupportPowerDescription(),
new AttackBomberFacingTolerance(),
new AttackFrontalFacingTolerance(),
new RenameCloakTypes(),
new SplitNukePowerMissileImage(),
new ReplaceSequenceEmbeddedPalette(),
new UnhardcodeVeteranProductionIconOverlay(),
new RenameContrailProperties(),
new RemoveDomainIndex(),
new AddControlGroups(),
// Execute these rules last to avoid premature yaml merge crashes.
new UnhardcodeSquadManager(),
new UnhardcodeBaseBuilderBotModule(),
]),
new("release-20230225", "release-20231010", new("release-20230225", "release-20231010",
[ [
new TextNotificationsDisplayWidgetRemoveTime(), new TextNotificationsDisplayWidgetRemoveTime(),