Core/Auras: Implemented SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT (#27455)

This commit is contained in:
Antonio Martín Berti
2021-12-25 13:01:17 -03:00
committed by GitHub
parent 34ae77ca86
commit b221f4b372
5 changed files with 64 additions and 1 deletions

View File

@@ -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())
{

View File

@@ -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; }

View File

@@ -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,

View File

@@ -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 ***/
/********************************/

View File

@@ -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;