From d54e4395e5611b646387b8a505329d45b69263cd Mon Sep 17 00:00:00 2001 From: Mustafa Alperen Seki Date: Thu, 21 Feb 2019 10:43:36 +0300 Subject: [PATCH] Add GrantConditionOnHealth --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Conditions/GrantConditionOnHealth.cs | 100 ++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnHealth.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 8e22ea5b4f..6d430e9415 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -121,6 +121,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnHealth.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnHealth.cs new file mode 100644 index 0000000000..2de9ad2afb --- /dev/null +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnHealth.cs @@ -0,0 +1,100 @@ +#region Copyright & License Information +/* + * Copyright 2007-2019 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 a condition to the actor at when its health is between 2 specific values.")] + public class GrantConditionOnHealthInfo : ITraitInfo, IRulesetLoaded, Requires + { + [FieldLoader.Require] + [GrantedConditionReference] + [Desc("Condition to grant.")] + public readonly string Condition = null; + + [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("Minimum level of health at which to grant the condition.")] + public readonly int MinHP = 0; + + [Desc("Maximum level of health at which to grant the condition.", + "Non-positive values will make it use Health.HP.")] + public readonly int MaxHP = 0; + + [Desc("Is the condition irrevokable once it has been granted?")] + public readonly bool GrantPermanently = false; + + public object Create(ActorInitializer init) { return new GrantConditionOnHealth(init.Self, this); } + + public void RulesetLoaded(Ruleset rules, ActorInfo ai) + { + var health = ai.TraitInfo(); + if (health.MaxHP < MinHP) + throw new YamlException("Minimum HP ({0}) for GrantConditionOnHealth can't be more than actor's Maximum HP ({1})".F(MinHP, health.MaxHP)); + } + } + + public class GrantConditionOnHealth : INotifyCreated, INotifyDamage + { + readonly GrantConditionOnHealthInfo info; + readonly IHealth health; + readonly int maxHP; + + ConditionManager conditionManager; + int conditionToken = ConditionManager.InvalidConditionToken; + + public GrantConditionOnHealth(Actor self, GrantConditionOnHealthInfo info) + { + this.info = info; + health = self.Trait(); + maxHP = info.MaxHP > 0 ? info.MaxHP : health.MaxHP; + } + + void INotifyCreated.Created(Actor self) + { + conditionManager = self.Trait(); + GrantConditionOnValidHealth(self, health.HP); + } + + void GrantConditionOnValidHealth(Actor self, int hp) + { + if (info.MinHP > hp || maxHP < hp || conditionToken != ConditionManager.InvalidConditionToken) + return; + + conditionToken = conditionManager.GrantCondition(self, info.Condition); + + var sound = info.EnabledSounds.RandomOrDefault(Game.CosmeticRandom); + Game.Sound.Play(SoundType.World, sound, self.CenterPosition); + } + + void INotifyDamage.Damaged(Actor self, AttackInfo e) + { + var granted = conditionToken != ConditionManager.InvalidConditionToken; + if (granted && info.GrantPermanently) + return; + + if (!granted) + GrantConditionOnValidHealth(self, health.HP); + else if (granted && (info.MinHP > health.HP || maxHP < health.HP)) + { + conditionToken = conditionManager.RevokeCondition(self, conditionToken); + + var sound = info.DisabledSounds.RandomOrDefault(Game.CosmeticRandom); + Game.Sound.Play(SoundType.World, sound, self.CenterPosition); + } + } + } +}