Split off the upgrade rules of the previous release cycle.

This commit is contained in:
Zimmermann Gyula
2018-07-29 13:51:08 +02:00
committed by abcdefg30
parent f9bc1113b5
commit 6027a123d4
20 changed files with 24 additions and 20 deletions

View File

@@ -0,0 +1,47 @@
#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 AddShakeToBridge : UpdateRule
{
public override string Name { get { return "Screen shaking was removed from dying bridges."; } }
public override string Description
{
get
{
return "'Bridges' (and 'GroundLevelBridges') no longer shake the screen on their own.\n" +
"The 'ShakeOnDeath' trait is to be used instead.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
if (actorNode.ChildrenMatching("Bridge").Any())
AddShakeNode(actorNode);
else if (actorNode.ChildrenMatching("GroundLevelBridge").Any())
AddShakeNode(actorNode);
yield break;
}
void AddShakeNode(MiniYamlNode actorNode)
{
var shake = new MiniYamlNode("ShakeOnDeath", "");
shake.AddNode("Duration", "15");
shake.AddNode("Intensity", "6");
actorNode.AddNode(shake);
}
}
}

View File

@@ -0,0 +1,38 @@
#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 ChangeIntensityToDuration : UpdateRule
{
public override string Name { get { return "Add a 'Duration' parameter to 'ShakeOnDeath'."; } }
public override string Description
{
get
{
return "The 'Intensity' parameter on 'ShakeOnDeath' has been used as duration\n" +
"by accident. A new 'Duration' parameter was added to fix that.\n" +
"Definitions of 'Intensity' will be automatically renamed to 'Duration'.\n" +
"The old 'Intensity' parameter will now change the intensity as intended.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var sod in actorNode.ChildrenMatching("ShakeOnDeath"))
sod.RenameChildrenMatching("Intensity", "Duration");
yield break;
}
}
}

View File

@@ -0,0 +1,68 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class DefineGroundCorpseDefault : UpdateRule
{
public override string Name { get { return "Move Parachutable GroundCorpseSequence default to yaml"; } }
public override string Description
{
get
{
return "Parachutable's GroundCorpseSequence 'corpse' default has been moved to yaml.";
}
}
Tuple<string, string, string, List<string>>[] fields =
{
Tuple.Create("Parachutable", "GroundCorpseSequence", "corpse", new List<string>()),
};
string BuildMessage(Tuple<string, string, string, List<string>> field)
{
return "The default value for {0}.{1} has been removed.\n".F(field.Item1, field.Item2) +
"You may wish to explicitly define `{0}: {1}` on the `{2}` trait \n".F(field.Item2, field.Item3, field.Item1) +
"definitions on the following actors (if they have not already been inherited from a parent).\n" +
UpdateUtils.FormatMessageList(field.Item4);
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
foreach (var field in fields)
{
if (field.Item4.Any())
yield return BuildMessage(field);
field.Item4.Clear();
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var field in fields)
{
foreach (var traitNode in actorNode.ChildrenMatching(field.Item1))
{
var node = traitNode.LastChildMatching(field.Item2);
if (node == null)
field.Item4.Add("{0} ({1})".F(actorNode.Key, traitNode.Location.Filename));
}
}
yield break;
}
}
}

View File

@@ -0,0 +1,156 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class DefineLocomotors : UpdateRule
{
public override string Name { get { return "Introduce global Locomotor definitions"; } }
public override string Description
{
get
{
return "A large number of properties have been moved from the actor-level Mobile trait\n" +
"to either world-level Locomotor traits or new actor-level GrantCondition* traits.\n" +
"Conditions for subterranean and jumpjet behaviours are migrated,\n" +
"and affected Mobile traits are listed for inspection.";
}
}
readonly List<Tuple<string, string>> locations = new List<Tuple<string, string>>();
bool subterraneanUsed;
bool jumpjetUsed;
readonly string[] locomotorFields =
{
"TerrainSpeeds", "Crushes", "CrushDamageTypes", "SharesCell", "MoveIntoShroud"
};
readonly string[] subterraneanFields =
{
"SubterraneanTransitionCost", "SubterraneanTransitionTerrainTypes",
"SubterraneanTransitionOnRamps", "SubterraneanTransitionDepth",
"SubterraneanTransitionPalette", "SubterraneanTransitionSound",
};
readonly string[] jumpjetFields =
{
"JumpjetTransitionCost", "JumpjetTransitionTerrainTypes", "JumpjetTransitionOnRamps"
};
public override IEnumerable<string> AfterUpdate(ModData modData)
{
var message = "You must define a set of Locomotor traits on the World actor for the different\n"
+ "movement classes used in your mod (e.g. Infantry, Vehicles, Tanks, Ships, etc)\n"
+ "and replace any definitions/overrides of the following properties on each\n"
+ "actor with a Locomotor field referencing the appropriate locomotor type.\n\n"
+ "The standard Locomotor definition contains the following fields:\n"
+ UpdateUtils.FormatMessageList(locomotorFields) + "\n\n";
if (subterraneanUsed)
message += "Actors using the subterranean logic should reference a SubterraneanLocomotor\n"
+ "instance that extends Locomotor with additional fields:\n"
+ UpdateUtils.FormatMessageList(subterraneanFields) + "\n\n";
if (jumpjetUsed)
message += "Actors using the jump-jet logic should reference a JumpjetLocomotor\n"
+ "instance that extends Locomotor with additional fields:\n"
+ UpdateUtils.FormatMessageList(jumpjetFields) + "\n\n";
message += "Condition definitions have been automatically migrated.\n"
+ "The following definitions reference fields that must be manually moved to Locomotors:\n"
+ UpdateUtils.FormatMessageList(locations.Select(n => n.Item1 + " (" + n.Item2 + ")"));
if (locations.Any())
yield return message;
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
var addNodes = new List<MiniYamlNode>();
foreach (var mobileNode in actorNode.ChildrenMatching("Mobile"))
{
var checkFields = locomotorFields.Append(subterraneanFields).Append(jumpjetFields);
if (checkFields.Any(f => mobileNode.ChildrenMatching(f).Any()))
locations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
var tunnelConditionNode = mobileNode.LastChildMatching("TunnelCondition");
if (tunnelConditionNode != null)
{
var grantNode = new MiniYamlNode("GrantConditionOnTunnelLayer", "");
tunnelConditionNode.MoveAndRenameNode(mobileNode, grantNode, "Condition");
addNodes.Add(grantNode);
}
var subterraneanNode = mobileNode.LastChildMatching("Subterranean");
if (subterraneanNode != null)
{
subterraneanUsed = true;
mobileNode.RemoveNodes("Subterranean");
var conditionNode = mobileNode.LastChildMatching("SubterraneanCondition");
if (conditionNode != null)
conditionNode.RenameKey("Condition");
var transitionImageNode = mobileNode.LastChildMatching("SubterraneanTransitionImage");
var transitionSequenceNode = mobileNode.LastChildMatching("SubterraneanTransitionSequence");
var transitionPaletteNode = mobileNode.LastChildMatching("SubterraneanTransitionPalette");
var transitionSoundNode = mobileNode.LastChildMatching("SubterraneanTransitionSound");
var nodes = new[]
{
conditionNode,
transitionImageNode,
transitionSequenceNode,
transitionPaletteNode,
transitionSoundNode
};
if (nodes.Any(n => n != null))
{
var grantNode = new MiniYamlNode("GrantConditionOnSubterraneanLayer", "");
foreach (var node in nodes)
if (node != null)
node.MoveNode(mobileNode, grantNode);
addNodes.Add(grantNode);
}
}
var jumpjetNode = mobileNode.LastChildMatching("Jumpjet");
if (jumpjetNode != null)
{
jumpjetUsed = true;
mobileNode.RemoveNodes("Jumpjet");
var conditionNode = mobileNode.LastChildMatching("JumpjetCondition");
if (conditionNode != null)
{
var grantNode = new MiniYamlNode("GrantConditionOnJumpjetLayer", "");
conditionNode.MoveAndRenameNode(mobileNode, grantNode, "Condition");
addNodes.Add(grantNode);
}
}
}
foreach (var node in addNodes)
actorNode.AddNode(node);
yield break;
}
}
}

View File

@@ -0,0 +1,46 @@
#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 DefineOwnerLostAction : UpdateRule
{
public override string Name { get { return "Add OwnerLostAction to player-controlled actors"; } }
public override string Description
{
get
{
return "A new OwnerLostAction trait has been introduced to control what happens to a\n" +
"player's actors when they are defeated. A warning is displayed notifying that\nthis trait must be added to actors.";
}
}
bool reported;
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (!reported)
yield return "All player-controlled (or player-capturable) actors should define an OwnerLostAction trait\n" +
"specifying an action (Kill, Dispose, ChangeOwner) to apply when the actor's owner is defeated.\n" +
"You must manually define this trait on the appropriate default actor templates.\n" +
"Actors missing this trait will remain controllable by their owner after they have been defeated.";
reported = true;
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
yield break;
}
}
}

View File

@@ -0,0 +1,74 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class DefineSoundDefaults : UpdateRule
{
public override string Name { get { return "Move mod-specific sound defaults to yaml"; } }
public override string Description
{
get
{
return "Mod-specific default sound values have been removed from several traits\n" +
"(" + fields.Select(f => f.Item1 + "." + f.Item2).JoinWith(", ") + ")\n" +
"Uses of these traits are listed for inspection so the values can be overriden in yaml.";
}
}
Tuple<string, string, string, List<string>>[] fields =
{
Tuple.Create("ParaDrop", "ChuteSound", "chute1.aud", new List<string>()),
Tuple.Create("EjectOnDeath", "ChuteSound", "chute1.aud", new List<string>()),
Tuple.Create("ProductionParadrop", "ChuteSound", "chute1.aud", new List<string>()),
Tuple.Create("Building", "BuildSounds", "placbldg.aud, build5.aud", new List<string>()),
Tuple.Create("Building", "UndeploySounds", "cashturn.aud", new List<string>())
};
string BuildMessage(Tuple<string, string, string, List<string>> field)
{
return "The default value for {0}.{1} has been removed.\n".F(field.Item1, field.Item2) +
"You may wish to explicitly define `{0}: {1}` on the `{2}` trait \n".F(field.Item2, field.Item3, field.Item1) +
"definitions on the following actors (if they have not already been inherited from a parent).\n" +
UpdateUtils.FormatMessageList(field.Item4);
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
foreach (var field in fields)
{
if (field.Item4.Any())
yield return BuildMessage(field);
field.Item4.Clear();
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var field in fields)
{
foreach (var traitNode in actorNode.ChildrenMatching(field.Item1))
{
var node = traitNode.LastChildMatching(field.Item2);
if (node == null)
field.Item4.Add("{0} ({1})".F(actorNode.Key, traitNode.Location.Filename));
}
}
yield break;
}
}
}

View File

@@ -0,0 +1,50 @@
#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 DefineSquadExcludeHarvester : UpdateRule
{
public override string Name { get { return "Add harvesters to ExcludeFromSquads"; } }
public override string Description
{
get
{
return "HackyAI no longer automatically excludes actors with Harvester trait from attack squads.\n" +
"They need to be explicitly added to ExcludeFromSquads. HackyAI instances are listed for inspection.";
}
}
readonly List<string> locations = new List<string>();
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Any())
yield return "The automatic exclusion of harvesters from AI squads has been removed.\n" +
"You may wish to add your harvester-type actors to `ExcludeFromSquads` under `UnitCommonNames`\n" +
"on the following definitions:\n" +
UpdateUtils.FormatMessageList(locations);
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var hackyAINode in actorNode.ChildrenMatching("HackyAI"))
locations.Add("{0} ({1})".F(hackyAINode.Key, hackyAINode.Location.Filename));
yield break;
}
}
}

View File

@@ -0,0 +1,59 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class IgnoreAbstractActors : UpdateRule
{
readonly Dictionary<string, List<MiniYamlNode>> actors = new Dictionary<string, List<MiniYamlNode>>();
public override string Name { get { return "Abstract actors are ignored while parsing rules"; } }
public override string Description
{
get
{
return "Actor ids starting with '^' are now reserved for abstract inheritance templates.\n" +
"Definitions that may be affected are listed for inspection so that they can be renamed if necessary.";
}
}
public override IEnumerable<string> BeforeUpdate(ModData modData)
{
actors.Clear();
yield break;
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
if (!actorNode.Key.StartsWith("^", StringComparison.Ordinal))
yield break;
var name = actorNode.Key;
if (!actors.ContainsKey(name))
actors[name] = new List<MiniYamlNode>();
actors[name].Add(actorNode);
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (actors.Any())
yield return "Actor ids starting with '^' are now reserved for abstract\n" +
"inheritance templates, and will not be parsed by the game.\n" +
"Check the following definitions and rename them if they are not used for inheritance:\n" +
UpdateUtils.FormatMessageList(actors.Select(n => n.Key + " (" + n.Value.Select(v => v.Location.Filename).JoinWith(", ") + ")"));
}
}
}

View File

@@ -0,0 +1,54 @@
#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 MoveHackyAISupportPowerDecisions : UpdateRule
{
public override string Name { get { return "Move HackyAI SupportPowerDecisions to a trait property"; } }
public override string Description
{
get
{
return "The SupportPowerDefinitions on HackyAI are moved from top-level trait properties\n" +
"to children of a single SupportPowerDecisions property.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var hackyAINode in actorNode.ChildrenMatching("HackyAI"))
{
var children = hackyAINode.ChildrenMatching("SupportPowerDecision");
if (!children.Any())
continue;
var parent = hackyAINode.LastChildMatching("SupportPowerDecisions");
if (parent == null)
{
parent = new MiniYamlNode("SupportPowerDecisions", "");
hackyAINode.AddNode(parent);
}
foreach (var child in children.ToList())
{
var split = child.Key.Split('@');
child.MoveAndRenameNode(hackyAINode, parent, split.Length > 1 ? split[1] : "Default", false);
}
}
yield break;
}
}
}

View File

@@ -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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class RemoveCanUndeployFromGrantConditionOnDeploy : UpdateRule
{
public override string Name { get { return "Remove CanUndeploy from GrantConditionOnDeploy."; } }
public override string Description
{
get
{
return "The CanUndeploy property was removed from the GrantConditionOnDeploy trait.\n" +
"Pausing the trait itself achieves the same effect now.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var gcod in actorNode.ChildrenMatching("GrantConditionOnDeploy"))
{
var canUndeploy = gcod.LastChildMatching("CanUndeploy");
if (canUndeploy == null)
continue;
gcod.RemoveNode(canUndeploy);
if (canUndeploy.NodeValue<bool>())
continue;
var deployedCondition = gcod.LastChildMatching("DeployedCondition");
gcod.AddNode("PauseOnCondition", deployedCondition.Value.Value);
}
yield break;
}
}
}

View File

@@ -0,0 +1,89 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class RemovePaletteFromCurrentTileset : UpdateRule
{
public override string Name { get { return "Remove PaletteFromCurrentTileset trait"; } }
public override string Description
{
get
{
return "The PaletteFromCurrentTileset trait and Palette field on TileSets have been removed.\n" +
"Terrain palettes are now explicitly defined on the world actor.\n" +
"Palette definitions are generated based on the Tileset metadata.";
}
}
readonly Dictionary<string, string> tilesetPalettes = new Dictionary<string, string>();
readonly List<Tuple<string, int[]>> paletteTraits = new List<Tuple<string, int[]>>();
string BuildYaml(string palette, int[] shadow, string tileset, string filename)
{
return "PaletteFromFile@{0}:\n Name: {1}\n Tileset: {2}\n Filename: {3}\n ShadowIndex: {4}".F(
palette + '-' + tileset.ToLower(), palette, tileset, filename, FieldSaver.FormatValue(shadow));
}
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (tilesetPalettes.Any() && paletteTraits.Any())
yield return "You must add the following to your palette definitions:\n"
+ paletteTraits.Select(p => tilesetPalettes.Select(kv =>
BuildYaml(p.Item1, p.Item2, kv.Key, kv.Value)).JoinWith("\n")).JoinWith("\n");
paletteTraits.Clear();
yield break;
}
public override IEnumerable<string> UpdateTilesetNode(ModData modData, MiniYamlNode tilesetNode)
{
if (tilesetNode.Key == "General")
{
var idNode = tilesetNode.LastChildMatching("Id");
if (idNode == null)
yield break;
var paletteNode = tilesetNode.LastChildMatching("Palette");
if (paletteNode != null)
tilesetPalettes[idNode.Value.Value] = paletteNode.Value.Value;
tilesetNode.RemoveNodes("Palette");
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var paletteNode in actorNode.ChildrenMatching("PaletteFromCurrentTileset"))
{
var name = "terrain";
var shadow = new int[] { };
var shadowNode = paletteNode.LastChildMatching("ShadowIndex");
if (shadowNode != null)
shadow = shadowNode.NodeValue<int[]>();
var nameNode = paletteNode.LastChildMatching("Name");
if (nameNode != null)
name = nameNode.Value.Value;
paletteTraits.Add(Tuple.Create(name, shadow));
}
actorNode.RemoveNodes("PaletteFromCurrentTileset");
yield break;
}
}
}

View File

@@ -0,0 +1,37 @@
#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 RemoveTerrainTypeIsWaterFlag : UpdateRule
{
public override string Name { get { return "Remove TerrainType IsWater flag"; } }
public override string Description
{
get
{
return "The IsWater flag on terrain type definitions has been unused for some time.\n" +
"This flag has now been removed from the tileset yaml.";
}
}
public override IEnumerable<string> UpdateTilesetNode(ModData modData, MiniYamlNode tilesetNode)
{
if (tilesetNode.Key == "Terrain")
foreach (var type in tilesetNode.Value.Nodes)
type.Value.Nodes.RemoveAll(n => n.Key == "IsWater");
yield break;
}
}
}

View File

@@ -0,0 +1,53 @@
#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 RemoveWeaponScanRadius : UpdateRule
{
public override string Name { get { return "Remove Weapon ScanRadius parameters"; } }
public override string Description
{
get
{
return "The *ScanRadius parameters have been removed from weapon projectiles and warheads.\n" +
"These values are now automatically determined by the engine.\n" +
"CreateEffect.ImpactActors: False has been added to replace VictimScanRadius: 0";
}
}
public override IEnumerable<string> UpdateWeaponNode(ModData modData, MiniYamlNode weaponNode)
{
foreach (var node in weaponNode.ChildrenMatching("Warhead"))
{
if (node.Value.Value == "CreateEffect")
{
var victimScanRadius = node.LastChildMatching("VictimScanRadius");
if (victimScanRadius != null && victimScanRadius.NodeValue<int>() == 0)
node.AddNode("ImpactActors", "false");
node.RemoveNodes("VictimScanRadius");
}
}
var projectile = weaponNode.LastChildMatching("Projectile");
if (projectile != null)
{
projectile.RemoveNodes("BounceBlockerScanRadius");
projectile.RemoveNodes("BlockerScanRadius");
projectile.RemoveNodes("AreaVictimScanRadius");
}
yield break;
}
}
}

View File

@@ -0,0 +1,53 @@
#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 RemoveWithReloadingSpriteTurret : UpdateRule
{
public override string Name { get { return "Remove WithReloadingSpriteTurret trait"; } }
public override string Description
{
get
{
return "WithReloadingSpriteTurret has been superseded by conditions.\n" +
"Instances of this trait are replaced by WithSpriteTurret.";
}
}
readonly List<string> locations = new List<string>();
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Any())
yield return "WithReloadingSpriteTurret has been replaced by WithSpriteTurret\n" +
"You should use AmmoPool.AmmoConditions to switch turret type when reloading\n" +
"to restore the previous behaviour on the following actors:\n" +
UpdateUtils.FormatMessageList(locations);
locations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var turret in actorNode.ChildrenMatching("WithReloadingSpriteTurret"))
{
turret.RenameKey("WithSpriteTurret");
locations.Add("{0} ({1})".F(actorNode.Key, turret.Location.Filename));
}
yield break;
}
}
}

View File

@@ -0,0 +1,42 @@
#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 RenameEmitInfantryOnSell : UpdateRule
{
public override string Name { get { return "EmitInfantryOnSell renamed to SpawnActorsOnSell"; } }
public override string Description
{
get
{
return "The EmitInfantryOnSell trait was renamed to SpawnActorsOnSell and the default\n" +
"actor type to spawn was removed. Uses of the old traits and defaults are updated\n" +
"to account for this.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var eios in actorNode.ChildrenMatching("EmitInfantryOnSell"))
{
eios.RenameKey("SpawnActorsOnSell");
var actortypes = eios.LastChildMatching("ActorTypes");
if (actortypes == null)
eios.AddNode("ActorTypes", "e1");
}
yield break;
}
}
}

View File

@@ -0,0 +1,44 @@
#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 RenameWormSpawner : UpdateRule
{
public override string Name { get { return "WormSpawner renamed and generalized to ActorSpawner"; } }
public override string Description
{
get
{
return "The D2k-specific WormSpawner trait was renamed to ActorSpawner, generalized,\n" +
"and moved into the common mod code. Uses of the old traits are updated to account for this.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var spawner in actorNode.ChildrenMatching("WormSpawner"))
spawner.RenameKey("ActorSpawner");
foreach (var manager in actorNode.ChildrenMatching("WormManager"))
{
manager.RenameKey("ActorSpawnManager");
var signature = manager.LastChildMatching("WormSignature");
if (signature != null)
signature.RenameKey("Actors");
}
yield break;
}
}
}

View File

@@ -0,0 +1,179 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class SplitAimAnimations : UpdateRule
{
public override string Name { get { return "Introduce WithAimAnimation and WithTurretAimAnimation traits"; } }
public override string Description
{
get
{
return "WithAttackAnimation.AimSequence, WithTurretAttackAnimation.AimSequence\n" +
"as well as WithSpriteTurret.AimSequence have been split to new With*AimAnimation traits.\n" +
"Furthermore, ReloadPrefixes have been removed in favor of condition-based solutions.";
}
}
readonly List<Tuple<string, string>> aimAnimLocations = new List<Tuple<string, string>>();
readonly List<Tuple<string, string>> reloadPrefixLocations = new List<Tuple<string, string>>();
public override IEnumerable<string> AfterUpdate(ModData modData)
{
var message1 = "AimSequences have been split to With*AimAnimation.\n"
+ "The following actors have been updated and might need manual adjustments:\n"
+ UpdateUtils.FormatMessageList(aimAnimLocations.Select(n => n.Item1 + " (" + n.Item2 + ")"));
if (aimAnimLocations.Any())
yield return message1;
aimAnimLocations.Clear();
var message2 = "ReloadPrefixes have been removed.\n"
+ "Instead, grant a condition on reloading via Armament.ReloadingCondition to enable\n"
+ "an alternate sprite body (with reloading sequences) on the following actors:\n"
+ UpdateUtils.FormatMessageList(reloadPrefixLocations.Select(n => n.Item1 + " (" + n.Item2 + ")"));
if (reloadPrefixLocations.Any())
yield return message2;
reloadPrefixLocations.Clear();
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
var turretAttack = actorNode.LastChildMatching("WithTurretAttackAnimation");
if (turretAttack != null)
{
var attackSequence = turretAttack.LastChildMatching("AttackSequence");
var aimSequence = turretAttack.LastChildMatching("AimSequence");
var reloadPrefix = turretAttack.LastChildMatching("ReloadPrefix");
if (aimSequence != null)
aimAnimLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
if (reloadPrefix != null)
reloadPrefixLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
// If only AttackSequence is not null, just rename AttackSequence to Sequence.
// If only the prefix isn't null (extremely unlikely, but you never know), just rename the trait.
// If AttackSequence is null but AimSequence isn't, rename the trait and property.
// If both aren't null, split/copy everything relevant to the new WithTurretAimAnimation.
// If both are null (extremely unlikely), do nothing.
if (attackSequence != null && aimSequence == null)
attackSequence.RenameKey("Sequence");
else if (attackSequence == null && aimSequence == null && reloadPrefix != null)
{
turretAttack.RemoveNode(reloadPrefix);
turretAttack.RenameKey("WithTurretAimAnimation");
}
else if (attackSequence == null && aimSequence != null)
{
turretAttack.RenameKey("WithTurretAimAnimation");
aimSequence.RenameKey("Sequence");
if (reloadPrefix != null)
turretAttack.RemoveNode(reloadPrefix);
}
else if (attackSequence != null && aimSequence != null)
{
var turretAim = new MiniYamlNode("WithTurretAimAnimation", "");
aimSequence.MoveAndRenameNode(turretAttack, turretAim, "Sequence");
var turret = turretAttack.LastChildMatching("Turret");
var armament = turretAttack.LastChildMatching("Armament");
if (reloadPrefix != null)
turretAttack.RemoveNode(reloadPrefix);
if (turret != null)
turretAim.AddNode(turret);
if (armament != null)
turretAim.AddNode(armament);
attackSequence.RenameKey("Sequence");
actorNode.AddNode(turretAim);
}
}
var spriteTurret = actorNode.LastChildMatching("WithSpriteTurret");
if (spriteTurret != null)
{
var aimSequence = spriteTurret.LastChildMatching("AimSequence");
if (aimSequence != null)
{
aimAnimLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
var aimAnim = new MiniYamlNode("WithTurretAimAnimation", "");
aimSequence.MoveAndRenameNode(spriteTurret, aimAnim, "Sequence");
actorNode.AddNode(aimAnim);
}
}
var attackAnim = actorNode.LastChildMatching("WithAttackAnimation");
if (attackAnim != null)
{
var attackSequence = attackAnim.LastChildMatching("AttackSequence");
var aimSequence = attackAnim.LastChildMatching("AimSequence");
var reloadPrefix = attackAnim.LastChildMatching("ReloadPrefix");
if (aimSequence != null)
aimAnimLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
if (reloadPrefix != null)
reloadPrefixLocations.Add(Tuple.Create(actorNode.Key, actorNode.Location.Filename));
// If only AttackSequence is not null, just rename AttackSequence to Sequence.
// If only the prefix isn't null (extremely unlikely, but you never know), just rename the trait.
// If AttackSequence is null but AimSequence isn't, rename the trait and property.
// If both sequences aren't null, split/copy everything relevant to the new WithAimAnimation.
// If both sequences and the prefix are null (extremely unlikely), do nothing.
if (attackSequence != null && aimSequence == null && reloadPrefix == null)
attackSequence.RenameKey("Sequence");
else if (attackSequence == null && aimSequence == null && reloadPrefix != null)
{
attackAnim.RemoveNode(reloadPrefix);
attackAnim.RenameKey("WithAimAnimation");
}
else if (attackSequence == null && aimSequence != null)
{
attackAnim.RenameKey("WithAimAnimation");
aimSequence.RenameKey("Sequence");
if (reloadPrefix != null)
attackAnim.RemoveNode(reloadPrefix);
}
else if (attackSequence != null && aimSequence != null)
{
var aimAnim = new MiniYamlNode("WithAimAnimation", "");
aimSequence.MoveAndRenameNode(attackAnim, aimAnim, "Sequence");
var body = attackAnim.LastChildMatching("Body");
var armament = attackAnim.LastChildMatching("Armament");
if (reloadPrefix != null)
attackAnim.RemoveNode(reloadPrefix);
if (body != null)
aimAnim.AddNode(body);
if (armament != null)
aimAnim.AddNode(armament);
attackSequence.RenameKey("Sequence");
actorNode.AddNode(aimAnim);
}
}
yield break;
}
}
}

View File

@@ -0,0 +1,69 @@
#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 SplitRepairDecoration : UpdateRule
{
public override string Name { get { return "WithBuildingRepairDecoration trait split from RepairableBuilding"; } }
public override string Description
{
get
{
return "Rendering for the building repair indicator has been moved to a new\n" +
"WithBuildingRepairDecoration trait. The indicator definitions are automatically\n" +
"migrated from RepairableBuilding to WithBuildingRepairDecoration.";
}
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
// RepairableBuilding is hardcoded to only support one instance per actor
var rb = actorNode.LastChildMatching("RepairableBuilding");
if (rb != null)
{
var imageNode = rb.LastChildMatching("IndicatorImage");
var sequenceNode = rb.LastChildMatching("IndicatorSequence");
var paletteNode = rb.LastChildMatching("IndicatorPalette");
var palettePrefixNode = rb.LastChildMatching("IndicatorPalettePrefix");
var decoration = new MiniYamlNode("WithBuildingRepairDecoration", "");
decoration.AddNode("Image", imageNode != null ? imageNode.Value.Value : "allyrepair");
decoration.AddNode("Sequence", sequenceNode != null ? sequenceNode.Value.Value : "repair");
decoration.AddNode("ReferencePoint", "Center");
if (paletteNode != null)
{
decoration.AddNode("Palette", paletteNode.Value.Value);
}
else
{
decoration.AddNode("Palette", palettePrefixNode != null ? palettePrefixNode.Value.Value : "player");
decoration.AddNode("IsPlayerPalette", true);
}
actorNode.AddNode(decoration);
rb.RemoveNode(imageNode);
rb.RemoveNode(sequenceNode);
rb.RemoveNode(paletteNode);
rb.RemoveNode(palettePrefixNode);
}
if (actorNode.LastChildMatching("-RepairableBuilding") != null)
actorNode.AddNode("-WithBuildingRepairDecoration", "");
yield break;
}
}
}