diff options
author | Seyden <saiifii@live.de> | 2022-07-25 22:46:54 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-07-28 21:26:48 +0200 |
commit | f25aceab282f1c3828015dec6af0505a82130674 (patch) | |
tree | eece402c4e48eda33548965b2512c08545940996 | |
parent | 44236c70787eae0239fb636e217305dfa043bf71 (diff) |
Core/Spells: Refactor heal absorb code
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 31 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 3 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.h | 11 |
5 files changed, 49 insertions, 28 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2339aca1d2d..8a2fc56eeff 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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(); + } } } } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 3ad6cf25935..0a3e8bee84f 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2200,33 +2200,33 @@ void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication co } } -void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, HealInfo& healInfo, uint32& absorbAmount, bool& defaultPrevented) +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_ABSORB, aurApp); - auto effEndItr = (*scritr)->OnEffectAbsorbHeal.end(), effItr = (*scritr)->OnEffectAbsorbHeal.begin(); + (*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, healInfo, absorbAmount); + effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount); - if (!defaultPrevented) - defaultPrevented = (*scritr)->_IsDefaultActionPrevented(); (*scritr)->_FinishScriptCall(); } } -void Aura::CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo& dmgInfo, uint32& absorbAmount) +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) { - (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB, aurApp); - auto effEndItr = (*scritr)->AfterEffectAbsorb.end(), effItr = (*scritr)->AfterEffectAbsorb.begin(); + (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_ABSORB, aurApp); + auto effEndItr = (*scritr)->OnEffectAbsorbHeal.end(), effItr = (*scritr)->OnEffectAbsorbHeal.begin(); for (; effItr != effEndItr; ++effItr) + if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex())) - effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount); + effItr->Call(*scritr, aurEff, healInfo, absorbAmount); + if (!defaultPrevented) + defaultPrevented = (*scritr)->_IsDefaultActionPrevented(); (*scritr)->_FinishScriptCall(); } } diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 0ae0110b5d0..345b1683c24 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -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); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 772426ae5ed..d79b43211a7 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -1164,15 +1164,15 @@ AuraScript::EffectAbsorbHandler::EffectAbsorbHandler(EffectAbsorbHandler&& right AuraScript::EffectAbsorbHandler& AuraScript::EffectAbsorbHandler::operator=(EffectAbsorbHandler&& right) noexcept = default; AuraScript::EffectAbsorbHandler::~EffectAbsorbHandler() = default; -AuraScript::EffectAbsorbHealHandler::EffectAbsorbHealHandler(AuraEffectAbsorbHealFnType _pEffectHandlerScript, uint8 _effIndex) - : AuraScript::EffectBase(_effIndex, SPELL_AURA_SCHOOL_HEAL_ABSORB) +void AuraScript::EffectAbsorbHandler::Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) { - pEffectHandlerScript = _pEffectHandlerScript; + (auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount); } -void AuraScript::EffectAbsorbHandler::Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) +AuraScript::EffectAbsorbHealHandler::EffectAbsorbHealHandler(AuraEffectAbsorbHealFnType _pEffectHandlerScript, uint8 _effIndex) + : AuraScript::EffectBase(_effIndex, SPELL_AURA_SCHOOL_HEAL_ABSORB) { - (auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount); + pEffectHandlerScript = _pEffectHandlerScript; } void AuraScript::EffectAbsorbHealHandler::Call(AuraScript * auraScript, AuraEffect * aurEff, HealInfo & healInfo, uint32 & absorbAmount) diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 7deec060f01..dfd44b1bed3 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -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); |