diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 60e34ed772..55ae30fc65 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -591,6 +591,9 @@ + + + @@ -876,6 +879,7 @@ + diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/ScaleDefaultModHealth.cs b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleDefaultModHealth.cs new file mode 100644 index 0000000000..c71a2ca58d --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleDefaultModHealth.cs @@ -0,0 +1,33 @@ +#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 OpenRA.Primitives; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class ScaleDefaultModHealth : ScaleModHealth + { + static readonly Dictionary ModScales = new Dictionary() + { + { "cnc", 100 }, + { "ra", 100 }, + { "d2k", 10 }, + { "ts", 100 } + }; + + public override IEnumerable BeforeUpdate(ModData modData) + { + ModScales.TryGetValue(modData.Manifest.Id, out scale); + return base.BeforeUpdate(modData); + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealth.cs b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealth.cs new file mode 100644 index 0000000000..2542cd7f1f --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealth.cs @@ -0,0 +1,111 @@ +#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 OpenRA.Primitives; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class ScaleModHealth : UpdateRule + { + public override string Name { get { return "Scale health and damage in the default OpenRA mods"; } } + public override string Description + { + get + { + return "All health and damage values are increased by a factor of 100 (ra, cnc, ts) or 10 (d2k)\n" + + "in order to reduce numerical inaccuracies in damage calculations."; + } + } + + static readonly Dictionary[]> TraitMapping = new Dictionary[]>() + { + { "Health", new[] { Pair.New("HP", string.Empty) } }, + { "SelfHealing", new[] { Pair.New("Step", "500") } }, + { "RepairsUnits", new[] { Pair.New("HpPerStep", "1000") } }, + { "RepairableBuilding", new[] { Pair.New("RepairStep", "700") } }, + { "Burns", new[] { Pair.New("Damage", "100") } }, + { "DamagedByTerrain", new[] { Pair.New("Damage", string.Empty) } }, + }; + + static readonly Dictionary WarheadMapping = new Dictionary() + { + { "SpreadDamage", "Damage" }, + { "TargetDamage", "Damage" }, + }; + + public ScaleModHealth(int scale = 100) + { + this.scale = scale; + } + + protected int scale; + + bool updated; + + public override IEnumerable BeforeUpdate(ModData modData) + { + updated = false; + yield break; + } + + public override IEnumerable AfterUpdate(ModData modData) + { + if (updated) + yield return "Health and damage values have been muliplied by a factor of {0}.\n".F(scale) + + "The increased calculation precision will affect game balance and may need to be manually adjusted.\n"; + } + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + foreach (var kv in TraitMapping) + { + foreach (var trait in actorNode.ChildrenMatching(kv.Key)) + { + foreach (var parameter in kv.Value) + { + var node = trait.LastChildMatching(parameter.First); + if (node != null) + node.ReplaceValue((scale * node.NodeValue()).ToString()); + else if (!string.IsNullOrEmpty(parameter.Second)) + trait.AddNode(parameter.First, parameter.Second); + + updated = true; + } + } + } + + yield break; + } + + public override IEnumerable UpdateWeaponNode(ModData modData, MiniYamlNode weaponNode) + { + foreach (var warheadNode in weaponNode.ChildrenMatching("Warhead")) + { + var name = warheadNode.NodeValue(); + if (name == null) + continue; + + string parameterName; + if (!WarheadMapping.TryGetValue(name, out parameterName)) + continue; + + foreach (var node in warheadNode.ChildrenMatching(parameterName)) + { + node.ReplaceValue((scale * node.NodeValue()).ToString()); + updated = true; + } + } + + yield break; + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealthBy10.cs b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealthBy10.cs new file mode 100644 index 0000000000..7c41d91e77 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealthBy10.cs @@ -0,0 +1,24 @@ +#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 ScaleModHealthBy10 : ScaleModHealth + { + public override IEnumerable BeforeUpdate(ModData modData) + { + scale = 10; + return base.BeforeUpdate(modData); + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealthBy100.cs b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealthBy100.cs new file mode 100644 index 0000000000..6cfece9d94 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/ScaleModHealthBy100.cs @@ -0,0 +1,24 @@ +#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 ScaleModHealthBy100 : ScaleModHealth + { + public override IEnumerable BeforeUpdate(ModData modData) + { + scale = 100; + return base.BeforeUpdate(modData); + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs index 1bcfde03b8..789c2f1f47 100644 --- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs +++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs @@ -42,7 +42,8 @@ namespace OpenRA.Mods.Common.UpdateRules new CapturableChanges(), new DecoupleSelfReloading(), new RemovePlayerPaletteTileset(), - new RenameWithTurreted() + new RenameWithTurreted(), + new ScaleDefaultModHealth() }), new UpdatePath("release-20180218", "release-20180307", new UpdateRule[0]),