aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeyden <saiifii@live.de>2022-07-25 22:46:54 +0200
committerShauren <shauren.trinity@gmail.com>2022-07-28 21:26:48 +0200
commitf25aceab282f1c3828015dec6af0505a82130674 (patch)
treeeece402c4e48eda33548965b2512c08545940996
parent44236c70787eae0239fb636e217305dfa043bf71 (diff)
Core/Spells: Refactor heal absorb code
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp31
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp22
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h3
-rw-r--r--src/server/game/Spells/SpellScript.cpp10
-rw-r--r--src/server/game/Spells/SpellScript.h11
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);