Core/Spells: Refactor heal absorb code

This commit is contained in:
Seyden
2022-07-25 22:46:54 +02:00
committed by Shauren
parent 44236c7078
commit f25aceab28
5 changed files with 52 additions and 31 deletions

View File

@@ -1976,17 +1976,20 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
if (!healInfo.GetHeal())
return;
// Need remove expired auras after
bool existExpired = false;
// absorb without mana cost
AuraEffectList const& vHealAbsorb = healInfo.GetTarget()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB);
for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && healInfo.GetHeal() > 0; ++i)
{
AuraEffect * absorbAurEff = *i;
AuraEffect* absorbAurEff = *i;
// Check if aura was removed during iteration - we don't need to work on such auras
AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(healInfo.GetTarget()->GetGUID());
if (!aurApp)
continue;
if (!(absorbAurEff->GetMiscValue() & healInfo.GetSchoolMask()))
if (!(absorbAurEff->GetMiscValue() & healInfo.GetSpellInfo()->GetSchoolMask()))
continue;
// get amount which can be still absorbed by the aura
@@ -2006,6 +2009,7 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
continue;
// currentAbsorb - damage can be absorbed by shield
// If need absorb less damage
currentAbsorb = std::min<int32>(healInfo.GetHeal(), currentAbsorb);
healInfo.AbsorbHeal(currentAbsorb);
@@ -2013,16 +2017,31 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
tempAbsorb = currentAbsorb;
absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, healInfo, tempAbsorb);
// Reduce shield amount
absorbAurEff->ChangeAmount((*i)->GetAmount() - currentAbsorb);
// Check if our aura is using amount to count damage
// Check if our aura is using amount to count heal
if (absorbAurEff->GetAmount() >= 0)
{
// Reduce shield amount
absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb);
// Aura cannot absorb anything more - remove it
if (absorbAurEff->GetAmount() <= 0)
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
existExpired = true;
}
}
// Remove all expired absorb auras
if (existExpired)
{
for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end();)
{
AuraEffect* auraEff = *i;
++i;
if (auraEff->GetAmount() <= 0)
{
uint32 removedAuras = healInfo.GetTarget()->m_removedAurasCount;
auraEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
if (removedAuras + 1 < healInfo.GetTarget()->m_removedAurasCount)
i = vHealAbsorb.begin();
}
}
}
}

View File

@@ -2200,6 +2200,20 @@ void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication co
}
}
void Aura::CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount)
{
for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
{
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB, aurApp);
auto effEndItr = (*scritr)->AfterEffectAbsorb.end(), effItr = (*scritr)->AfterEffectAbsorb.begin();
for (; effItr != effEndItr; ++effItr)
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount);
(*scritr)->_FinishScriptCall();
}
}
void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, HealInfo& healInfo, uint32& absorbAmount, bool& defaultPrevented)
{
for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
@@ -2217,20 +2231,6 @@ void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication co
}
}
void Aura::CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount)
{
for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
{
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB, aurApp);
auto effEndItr = (*scritr)->AfterEffectAbsorb.end(), effItr = (*scritr)->AfterEffectAbsorb.begin();
for (; effItr != effEndItr; ++effItr)
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount);
(*scritr)->_FinishScriptCall();
}
}
void Aura::CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, HealInfo& healInfo, uint32& absorbAmount)
{
for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)

View File

@@ -44,6 +44,7 @@ class DispelInfo;
class DynObjAura;
class ChargeDropEvent;
class DynamicObject;
class HealInfo;
class ProcEventInfo;
class Unit;
class UnitAura;
@@ -277,8 +278,8 @@ class TC_GAME_API Aura
void CallScriptEffectCalcSpellModHandlers(AuraEffect const* aurEff, SpellModifier*& spellMod);
void CallScriptEffectCalcCritChanceHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, Unit const* victim, float& critChance);
void CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount, bool & defaultPrevented);
void CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, HealInfo& healInfo, uint32& absorbAmount, bool& defaultPrevented);
void CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount);
void CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, HealInfo& healInfo, uint32& absorbAmount, bool& defaultPrevented);
void CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, HealInfo& healInfo, uint32& absorbAmount);
void CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount, bool & defaultPrevented);
void CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount);

View File

@@ -1164,17 +1164,17 @@ AuraScript::EffectAbsorbHandler::EffectAbsorbHandler(EffectAbsorbHandler&& right
AuraScript::EffectAbsorbHandler& AuraScript::EffectAbsorbHandler::operator=(EffectAbsorbHandler&& right) noexcept = default;
AuraScript::EffectAbsorbHandler::~EffectAbsorbHandler() = default;
void AuraScript::EffectAbsorbHandler::Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
{
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount);
}
AuraScript::EffectAbsorbHealHandler::EffectAbsorbHealHandler(AuraEffectAbsorbHealFnType _pEffectHandlerScript, uint8 _effIndex)
: AuraScript::EffectBase(_effIndex, SPELL_AURA_SCHOOL_HEAL_ABSORB)
{
pEffectHandlerScript = _pEffectHandlerScript;
}
void AuraScript::EffectAbsorbHandler::Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
{
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount);
}
void AuraScript::EffectAbsorbHealHandler::Call(AuraScript * auraScript, AuraEffect * aurEff, HealInfo & healInfo, uint32 & absorbAmount)
{
(auraScript->*pEffectHandlerScript)(aurEff, healInfo, absorbAmount);

View File

@@ -37,6 +37,7 @@ class DamageInfo;
class DispelInfo;
class DynamicObject;
class GameObject;
class HealInfo;
class Item;
class ModuleReference;
class Player;
@@ -1077,17 +1078,17 @@ class TC_GAME_API AuraScript : public _SpellScript
#define AuraEffectAbsorbFn(F, I) EffectAbsorbFunction(&F, I)
#define AuraEffectAbsorbOverkillFn(F, I) EffectAbsorbFunction(&F, I, true)
// executed after absorb aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
// example: AfterEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
HookList<EffectAbsorbHandler> AfterEffectAbsorb;
// executed when absorb aura effect is going to reduce damage
// example: OnEffectAbsorbHeal += AuraEffectAbsorbHealFn(class::function, EffectIndexSpecifier);
// where function is: void function (AuraEffect const* aurEff, HealInfo& healInfo, uint32& absorbAmount);
HookList<EffectAbsorbHealHandler> OnEffectAbsorbHeal;
#define AuraEffectAbsorbHealFn(F, I) EffectAbsorbHealFunction(&F, I)
// executed after absorb aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
// example: AfterEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
HookList<EffectAbsorbHandler> AfterEffectAbsorb;
// executed after absorb aura effect reduced heal to target - absorbAmount is real amount absorbed by aura
// example: AfterEffectAbsorbHeal += AuraEffectAbsorbHealFn(class::function, EffectIndexSpecifier);
// where function is: void function (AuraEffect* aurEff, HealInfo& healInfo, uint32& absorbAmount);