Split off the upgrade rules of the previous release cycle.
This commit is contained in:
committed by
abcdefg30
parent
f9bc1113b5
commit
6027a123d4
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(", ") + ")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user