diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 836500e69f..59de2a6e3f 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -493,6 +493,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Upgrades/UpgradeOnDamage.cs b/OpenRA.Mods.Common/Traits/Upgrades/UpgradeOnDamage.cs new file mode 100644 index 0000000000..c058fcaa07 --- /dev/null +++ b/OpenRA.Mods.Common/Traits/Upgrades/UpgradeOnDamage.cs @@ -0,0 +1,71 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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 OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Applies an upgrade to actors within a specified range.")] + public class UpgradeOnDamageInfo : ITraitInfo, Requires + { + [UpgradeGrantedReference, FieldLoader.Require] + [Desc("The upgrades to grant.")] + public readonly string[] Upgrades = { }; + + [Desc("Play a random sound from this list when enabled.")] + public readonly string[] EnabledSounds = { }; + + [Desc("Play a random sound from this list when disabled.")] + public readonly string[] DisabledSounds = { }; + + [Desc("Levels of damage at which to grant upgrades.")] + public readonly DamageState ValidDamageStates = DamageState.Heavy | DamageState.Critical; + + public object Create(ActorInitializer init) { return new UpgradeOnDamage(init.Self, this); } + } + + public class UpgradeOnDamage : INotifyDamageStateChanged + { + readonly UpgradeOnDamageInfo info; + readonly UpgradeManager um; + + public UpgradeOnDamage(Actor self, UpgradeOnDamageInfo info) + { + this.info = info; + um = self.TraitOrDefault(); + } + + bool granted; + void INotifyDamageStateChanged.DamageStateChanged(Actor self, AttackInfo e) + { + if (um == null) + return; + + var rand = Game.CosmeticRandom; + if (!granted && info.ValidDamageStates.HasFlag(e.DamageState) && !info.ValidDamageStates.HasFlag(e.PreviousDamageState)) + { + granted = true; + var sound = info.EnabledSounds.RandomOrDefault(rand); + Game.Sound.Play(sound, self.CenterPosition); + foreach (var u in info.Upgrades) + um.GrantUpgrade(self, u, this); + } + else if (granted && !info.ValidDamageStates.HasFlag(e.DamageState) && info.ValidDamageStates.HasFlag(e.PreviousDamageState)) + { + granted = false; + var sound = info.DisabledSounds.RandomOrDefault(rand); + Game.Sound.Play(sound, self.CenterPosition); + foreach (var u in info.Upgrades) + um.RevokeUpgrade(self, u, this); + } + } + } +}