aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp29
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h6
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp28
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h1
5 files changed, 64 insertions, 1 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ad6ed3ec293..ed8c2bf0dae 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -7855,6 +7855,32 @@ int64 Unit::GetHealthGain(int64 dVal)
return gain;
}
+void Unit::TriggerOnHealthChangeAuras(uint64 oldVal, uint64 newVal)
+{
+ for (AuraEffect const* effect : GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT))
+ {
+ uint32 triggerHealthPct = effect->GetAmount();
+ uint32 triggerSpell = effect->GetSpellEffectInfo().TriggerSpell;
+ uint64 threshold = CountPctFromMaxHealth(triggerHealthPct);
+
+ switch (AuraTriggerOnHealthChangeDirection(effect->GetMiscValue()))
+ {
+ case AuraTriggerOnHealthChangeDirection::Above:
+ if (newVal < threshold || oldVal > threshold)
+ continue;
+ break;
+ case AuraTriggerOnHealthChangeDirection::Below:
+ if (newVal > threshold || oldVal < threshold)
+ continue;
+ break;
+ default:
+ break;
+ }
+
+ CastSpell(this, triggerSpell, effect);
+ }
+}
+
// returns negative amount on power reduction
int32 Unit::ModifyPower(Powers power, int32 dVal, bool withPowerUpdate /*= true*/)
{
@@ -8893,8 +8919,11 @@ void Unit::SetHealth(uint64 val)
val = maxHealth;
}
+ uint64 oldVal = GetHealth();
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::Health), val);
+ TriggerOnHealthChangeAuras(oldVal, val);
+
// group update
if (Player* player = ToPlayer())
{
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 05377acb549..668253fe6ca 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -900,6 +900,7 @@ class TC_GAME_API Unit : public WorldObject
inline void SetFullHealth() { SetHealth(GetMaxHealth()); }
int64 ModifyHealth(int64 val);
int64 GetHealthGain(int64 dVal);
+ void TriggerOnHealthChangeAuras(uint64 oldVal, uint64 newVal);
virtual float GetHealthMultiplierForTarget(WorldObject const* /*target*/) const { return 1.0f; }
virtual float GetDamageMultiplierForTarget(WorldObject const* /*target*/) const { return 1.0f; }
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index a56048669cc..24e2c2dbfc2 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -83,6 +83,12 @@ enum class AuraTriggerOnPowerChangeDirection : int32
Loss = 1
};
+enum class AuraTriggerOnHealthChangeDirection : int32
+{
+ Above = 0,
+ Below = 1,
+};
+
enum AuraType : uint32
{
SPELL_AURA_NONE = 0,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 28a0901b854..0e730fc83eb 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -536,7 +536,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //465 SPELL_AURA_MOD_BONUS_ARMOR
&AuraEffect::HandleNULL, //466 SPELL_AURA_MOD_BONUS_ARMOR_PCT
&AuraEffect::HandleModStatBonusPercent, //467 SPELL_AURA_MOD_STAT_BONUS_PCT
- &AuraEffect::HandleNULL, //468 SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT
+ &AuraEffect::HandleTriggerSpellOnHealthPercent, //468 SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT
&AuraEffect::HandleShowConfirmationPrompt, //469 SPELL_AURA_SHOW_CONFIRMATION_PROMPT_WITH_DIFFICULTY
&AuraEffect::HandleNULL, //470 SPELL_AURA_MOD_AURA_TIME_RATE_BY_SPELL_LABEL
&AuraEffect::HandleModVersatilityByPct, //471 SPELL_AURA_MOD_VERSATILITY
@@ -3887,6 +3887,32 @@ void AuraEffect::HandleAuraModMaxPowerPct(AuraApplication const* aurApp, uint8 m
target->ModifyPower(powerType, change);
}
+void AuraEffect::HandleTriggerSpellOnHealthPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL) || !apply)
+ return;
+
+ Unit* target = aurApp->GetTarget();
+ int32 thresholdPct = GetAmount();
+ uint32 triggerSpell = GetSpellEffectInfo().TriggerSpell;
+
+ switch (AuraTriggerOnHealthChangeDirection(GetMiscValue()))
+ {
+ case AuraTriggerOnHealthChangeDirection::Above:
+ if (!target->HealthAbovePct(thresholdPct))
+ return;
+ break;
+ case AuraTriggerOnHealthChangeDirection::Below:
+ if (!target->HealthBelowPct(thresholdPct))
+ return;
+ break;
+ default:
+ break;
+ }
+
+ target->CastSpell(target, triggerSpell, this);
+}
+
/********************************/
/*** FIGHT ***/
/********************************/
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 4678e36baf5..b63f50e8f67 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -254,6 +254,7 @@ class TC_GAME_API AuraEffect
void HandleAuraModPowerDisplay(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModOverridePowerDisplay(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModMaxPowerPct(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleTriggerSpellOnHealthPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// fight
void HandleAuraModParryPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModDodgePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;