diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 29 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 6 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 28 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 1 |
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; |