diff --git a/OpenRA.Mods.Common/Traits/GainsExperience.cs b/OpenRA.Mods.Common/Traits/GainsExperience.cs index 7c0a55c7f9..c0deb86f02 100644 --- a/OpenRA.Mods.Common/Traits/GainsExperience.cs +++ b/OpenRA.Mods.Common/Traits/GainsExperience.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenRA.Mods.Common.Effects; using OpenRA.Primitives; using OpenRA.Traits; @@ -18,13 +19,13 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("This actor's experience increases when it has killed a GivesExperience actor.")] - public class GainsExperienceInfo : ITraitInfo, Requires, Requires + public class GainsExperienceInfo : ITraitInfo, Requires { [FieldLoader.Require] - [Desc("Upgrades to grant at each level.", + [Desc("Condition to grant at each level.", "Key is the XP requirements for each level as a percentage of our own value.", "Value is a list of the upgrade types to grant")] - public readonly Dictionary Upgrades = null; + public readonly Dictionary Conditions = null; [Desc("Palette for the level up sprite.")] [PaletteReference] public readonly string LevelUpPalette = "effect"; @@ -35,13 +36,14 @@ namespace OpenRA.Mods.Common.Traits public object Create(ActorInitializer init) { return new GainsExperience(init, this); } } - public class GainsExperience : ISync, IResolveOrder + public class GainsExperience : INotifyCreated, ISync, IResolveOrder { readonly Actor self; readonly GainsExperienceInfo info; - readonly UpgradeManager um; + readonly int initialExperience; - readonly List> nextLevel = new List>(); + readonly List> nextLevel = new List>(); + UpgradeManager um; // Stored as a percentage of our value [Sync] int experience = 0; @@ -54,16 +56,20 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; this.info = info; - MaxLevel = info.Upgrades.Count; - + MaxLevel = info.Conditions.Count; var cost = self.Info.TraitInfo().Cost; - foreach (var kv in info.Upgrades) + foreach (var kv in info.Conditions) nextLevel.Add(Pair.New(kv.Key * cost, kv.Value)); if (init.Contains()) - GiveExperience(init.Get(), info.SuppressLevelupAnimation); + initialExperience = init.Get(); + } - um = self.Trait(); + void INotifyCreated.Created(Actor self) + { + um = self.TraitOrDefault(); + if (initialExperience > 0) + GiveExperience(initialExperience, info.SuppressLevelupAnimation); } public bool CanGainLevel { get { return Level < MaxLevel; } } @@ -76,17 +82,18 @@ namespace OpenRA.Mods.Common.Traits public void GiveExperience(int amount, bool silent = false) { + if (amount < 0) + throw new ArgumentException("Revoking experience is not implemented.", "amount"); + experience += amount; while (Level < MaxLevel && experience >= nextLevel[Level].First) { - var upgrades = nextLevel[Level].Second; + if (um != null) + um.GrantCondition(self, nextLevel[Level].Second); Level++; - foreach (var u in upgrades) - um.GrantUpgrade(self, u, this); - if (!silent) { Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", "LevelUp", self.Owner.Faction.InternalName); diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index decab150d9..f07be9154c 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -675,6 +675,21 @@ namespace OpenRA.Mods.Common.UtilityCommands ConvertUpgradesToCondition(parent, node, "UndeployedUpgrades", "UndeployedCondition"); ConvertUpgradesToCondition(parent, node, "DeployedUpgrades", "DeployedCondition"); } + + if (node.Key == "GainsExperience") + { + var upgrades = node.Value.Nodes.FirstOrDefault(n => n.Key == "Upgrades"); + if (upgrades != null) + { + upgrades.Key = "Conditions"; + foreach (var n in upgrades.Value.Nodes) + { + var conditions = FieldLoader.GetValue("", n.Value.Value); + if (conditions.Length > 1) + Console.WriteLine("Unable to automatically migrate multiple GainsExperience upgrades to a condition. This must be corrected manually"); + } + } + } } UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index dae11b0b0f..b4dd0a4f0b 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -16,7 +16,7 @@ ^GainsExperience: GainsExperience: - Upgrades: + Conditions: 200: rank-veteran-1 400: rank-veteran-2 800: rank-veteran-3 diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 18a7091b96..ca0edf36ba 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -16,7 +16,7 @@ ^GainsExperience: GainsExperience: - Upgrades: + Conditions: 200: rank-veteran-1 400: rank-veteran-2 800: rank-veteran-3 diff --git a/mods/ra/maps/desert-shellmap/rules.yaml b/mods/ra/maps/desert-shellmap/rules.yaml index accc448782..96760317c5 100644 --- a/mods/ra/maps/desert-shellmap/rules.yaml +++ b/mods/ra/maps/desert-shellmap/rules.yaml @@ -17,7 +17,7 @@ World: GivesBounty: Percentage: 0 GainsExperience: - Upgrades: + Conditions: DamageMultiplier@UNKILLABLE: RequiresCondition: unkillable Modifier: 0 @@ -28,7 +28,7 @@ World: GivesBounty: Percentage: 0 GainsExperience: - Upgrades: + Conditions: DamageMultiplier@UNKILLABLE: RequiresCondition: unkillable Modifier: 0 @@ -39,7 +39,7 @@ World: GivesBounty: Percentage: 0 GainsExperience: - Upgrades: + Conditions: DeathSounds@NORMAL: VolumeMultiplier: 0.1 DeathSounds@BURNED: @@ -56,7 +56,7 @@ World: GivesBounty: Percentage: 0 GainsExperience: - Upgrades: + Conditions: DamageMultiplier@UNKILLABLE: RequiresCondition: unkillable Modifier: 0 diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 11fd6bb8e3..8e17e5ac05 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -15,7 +15,7 @@ ^GainsExperience: GainsExperience: - Upgrades: + Conditions: 200: rank-veteran-1 400: rank-veteran-2 800: rank-veteran-3 diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 870252e777..5b84a2cbf4 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -17,7 +17,7 @@ ^GainsExperience: GainsExperience: - Upgrades: + Conditions: 500: rank-veteran 1000: rank-elite FirepowerMultiplier@VETERAN: