mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Add hook on AuraScript called when an aura is dispelled
This commit is contained in:
@@ -3492,17 +3492,25 @@ void Unit::RemoveAuraFromStack(uint32 spellId, uint64 casterGUID, AuraRemoveMode
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved/*= 1*/)
|
||||
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved/*= 1*/)
|
||||
{
|
||||
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
||||
{
|
||||
Aura* aura = iter->second;
|
||||
if (aura->GetCasterGUID() == casterGUID)
|
||||
{
|
||||
DispelInfo dispelInfo(dispeller, dispellerSpellId, chargesRemoved);
|
||||
|
||||
// Call OnDispel hook on AuraScript
|
||||
aura->CallScriptDispel(&dispelInfo);
|
||||
|
||||
if (aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES)
|
||||
aura->ModCharges(-chargesRemoved, AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
aura->ModCharges(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
else
|
||||
aura->ModStackAmount(-chargesRemoved, AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
aura->ModStackAmount(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
|
||||
// Call AfterDispel hook on AuraScript
|
||||
aura->CallScriptAfterDispel(&dispelInfo);
|
||||
|
||||
switch (aura->GetSpellInfo()->SpellFamilyName)
|
||||
{
|
||||
@@ -3532,7 +3540,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit
|
||||
{
|
||||
// final heal
|
||||
int32 healAmount = aurEff->GetAmount();
|
||||
int32 stack = chargesRemoved;
|
||||
int32 stack = dispelInfo.GetRemovedCharges();
|
||||
CastCustomSpell(this, 33778, &healAmount, &stack, NULL, true, NULL, NULL, aura->GetCasterGUID());
|
||||
|
||||
// mana
|
||||
|
||||
@@ -788,6 +788,25 @@ enum MeleeHitOutcome
|
||||
MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL
|
||||
};
|
||||
|
||||
class DispelInfo
|
||||
{
|
||||
private:
|
||||
Unit* const m_dispeller;
|
||||
uint32 const m_dispellerSpellId;
|
||||
uint8 m_chargesRemoved;
|
||||
public:
|
||||
explicit DispelInfo(Unit* _dispeller, uint32 _dispellerSpellId, uint8 _chargesRemoved) :
|
||||
m_dispeller(_dispeller), m_dispellerSpellId(_dispellerSpellId), m_chargesRemoved(_chargesRemoved) {}
|
||||
|
||||
Unit* GetDispeller() { return m_dispeller; }
|
||||
uint32 GetDispellerSpellId() { return m_dispellerSpellId; }
|
||||
uint8 GetRemovedCharges() { return m_chargesRemoved; }
|
||||
void SetRemovedCharges(uint8 amount)
|
||||
{
|
||||
m_chargesRemoved = amount;
|
||||
}
|
||||
};
|
||||
|
||||
struct CleanDamage
|
||||
{
|
||||
CleanDamage(uint32 mitigated, uint32 absorbed, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) :
|
||||
@@ -1744,7 +1763,7 @@ class Unit : public WorldObject
|
||||
|
||||
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
||||
void RemoveAuraFromStack(uint32 spellId, uint64 casterGUID = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved = 1);
|
||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved = 1);
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit* stealer);
|
||||
void RemoveAurasDueToItemSpell(Item* castItem, uint32 spellId);
|
||||
void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura* except = NULL, bool negative = true, bool positive = true);
|
||||
|
||||
@@ -2075,6 +2075,30 @@ bool Aura::CallScriptCheckAreaTargetHandlers(Unit* target)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Aura::CallScriptDispel(DispelInfo* dispelInfo)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_DISPEL);
|
||||
std::list<AuraScript::AuraDispelHandler>::iterator hookItrEnd = (*scritr)->OnDispel.end(), hookItr = (*scritr)->OnDispel.begin();
|
||||
for (; hookItr != hookItrEnd ; ++hookItr)
|
||||
(*hookItr).Call(*scritr, dispelInfo);
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
void Aura::CallScriptAfterDispel(DispelInfo* dispelInfo)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_AFTER_DISPEL);
|
||||
std::list<AuraScript::AuraDispelHandler>::iterator hookItrEnd = (*scritr)->AfterDispel.end(), hookItr = (*scritr)->AfterDispel.begin();
|
||||
for (; hookItr != hookItrEnd ; ++hookItr)
|
||||
(*hookItr).Call(*scritr, dispelInfo);
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
bool Aura::CallScriptEffectApplyHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, AuraEffectHandleModes mode)
|
||||
{
|
||||
bool preventDefault = false;
|
||||
|
||||
@@ -198,6 +198,8 @@ class Aura
|
||||
// AuraScript
|
||||
void LoadScripts();
|
||||
bool CallScriptCheckAreaTargetHandlers(Unit* target);
|
||||
void CallScriptDispel(DispelInfo* dispelInfo);
|
||||
void CallScriptAfterDispel(DispelInfo* dispelInfo);
|
||||
bool CallScriptEffectApplyHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, AuraEffectHandleModes mode);
|
||||
bool CallScriptEffectRemoveHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, AuraEffectHandleModes mode);
|
||||
void CallScriptAfterEffectApplyHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, AuraEffectHandleModes mode);
|
||||
|
||||
@@ -3317,7 +3317,7 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
|
||||
// Send dispelled spell info
|
||||
dataSuccess << uint32(itr->first->GetId()); // Spell Id
|
||||
dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
|
||||
unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), itr->first->GetCasterGUID(), m_caster, itr->second);
|
||||
unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
|
||||
}
|
||||
m_caster->SendMessageToSet(&dataSuccess, true);
|
||||
|
||||
|
||||
@@ -542,6 +542,14 @@ bool AuraScript::_Validate(SpellInfo const* entry)
|
||||
if (!entry->HasAreaAuraEffect())
|
||||
sLog->outError("TSCR: Spell `%u` of script `%s` does not have area aura effect - handler bound to hook `DoCheckAreaTarget` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraDispelHandler>::iterator itr = OnDispel.begin(); itr != OnDispel.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError("TSCR: Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `OnDispel` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<AuraDispelHandler>::iterator itr = AfterDispel.begin(); itr != AfterDispel.end(); ++itr)
|
||||
if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect())
|
||||
sLog->outError("TSCR: Spell `%u` of script `%s` does not have apply aura effect - handler bound to hook `AfterDispel` of AuraScript won't be executed", entry->Id, m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectApplyHandler>::iterator itr = OnEffectApply.begin(); itr != OnEffectApply.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectApply` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
@@ -607,6 +615,16 @@ bool AuraScript::CheckAreaTargetHandler::Call(AuraScript* auraScript, Unit* _tar
|
||||
return (auraScript->*pHandlerScript)(_target);
|
||||
}
|
||||
|
||||
AuraScript::AuraDispelHandler::AuraDispelHandler(AuraDispelFnType _pHandlerScript)
|
||||
{
|
||||
pHandlerScript = _pHandlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::AuraDispelHandler::Call(AuraScript* auraScript, DispelInfo* _dispelInfo)
|
||||
{
|
||||
(auraScript->*pHandlerScript)(_dispelInfo);
|
||||
}
|
||||
|
||||
AuraScript::EffectBase::EffectBase(uint8 _effIndex, uint16 _effName)
|
||||
: _SpellScript::EffectAuraNameCheck(_effName), _SpellScript::EffectHook(_effIndex)
|
||||
{
|
||||
|
||||
@@ -385,6 +385,8 @@ enum AuraScriptHookType
|
||||
AURA_SCRIPT_HOOK_EFFECT_MANASHIELD,
|
||||
AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD,
|
||||
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET,
|
||||
AURA_SCRIPT_HOOK_DISPEL,
|
||||
AURA_SCRIPT_HOOK_AFTER_DISPEL,
|
||||
/*AURA_SCRIPT_HOOK_APPLY,
|
||||
AURA_SCRIPT_HOOK_REMOVE, */
|
||||
};
|
||||
@@ -400,6 +402,7 @@ class AuraScript : public _SpellScript
|
||||
|
||||
#define AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) \
|
||||
typedef bool(CLASSNAME::*AuraCheckAreaTargetFnType)(Unit* target); \
|
||||
typedef void(CLASSNAME::*AuraDispelFnType)(DispelInfo* dispelInfo); \
|
||||
typedef void(CLASSNAME::*AuraEffectApplicationModeFnType)(AuraEffect const*, AuraEffectHandleModes); \
|
||||
typedef void(CLASSNAME::*AuraEffectPeriodicFnType)(AuraEffect const*); \
|
||||
typedef void(CLASSNAME::*AuraEffectUpdatePeriodicFnType)(AuraEffect*); \
|
||||
@@ -418,6 +421,14 @@ class AuraScript : public _SpellScript
|
||||
private:
|
||||
AuraCheckAreaTargetFnType pHandlerScript;
|
||||
};
|
||||
class AuraDispelHandler
|
||||
{
|
||||
public:
|
||||
AuraDispelHandler(AuraDispelFnType pHandlerScript);
|
||||
void Call(AuraScript* auraScript, DispelInfo* dispelInfo);
|
||||
private:
|
||||
AuraDispelFnType pHandlerScript;
|
||||
};
|
||||
class EffectBase : public _SpellScript::EffectAuraNameCheck, public _SpellScript::EffectHook
|
||||
{
|
||||
public:
|
||||
@@ -493,6 +504,7 @@ class AuraScript : public _SpellScript
|
||||
|
||||
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
|
||||
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \
|
||||
class AuraDispelFunction : public AuraScript::AuraDispelHandler { public: AuraDispelFunction(AuraDispelFnType _pHandlerScript) : AuraScript::AuraDispelHandler((AuraScript::AuraDispelFnType)_pHandlerScript) {} }; \
|
||||
class EffectPeriodicHandlerFunction : public AuraScript::EffectPeriodicHandler { public: EffectPeriodicHandlerFunction(AuraEffectPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectPeriodicHandler((AuraScript::AuraEffectPeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
class EffectUpdatePeriodicHandlerFunction : public AuraScript::EffectUpdatePeriodicHandler { public: EffectUpdatePeriodicHandlerFunction(AuraEffectUpdatePeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectUpdatePeriodicHandler((AuraScript::AuraEffectUpdatePeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
class EffectCalcAmountHandlerFunction : public AuraScript::EffectCalcAmountHandler { public: EffectCalcAmountHandlerFunction(AuraEffectCalcAmountFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcAmountHandler((AuraScript::AuraEffectCalcAmountFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
@@ -540,6 +552,17 @@ class AuraScript : public _SpellScript
|
||||
// where function is: bool function (Unit* target);
|
||||
HookList<CheckAreaTargetHandler> DoCheckAreaTarget;
|
||||
#define AuraCheckAreaTargetFn(F) CheckAreaTargetFunction(&F)
|
||||
|
||||
// executed when aura is dispelled by a unit
|
||||
// example: OnDispel += AuraDispelFn(class::function);
|
||||
// where function is: void function (DispelInfo* dispelInfo);
|
||||
HookList<AuraDispelHandler> OnDispel;
|
||||
// executed after aura is dispelled by a unit
|
||||
// example: AfterDispel += AuraDispelFn(class::function);
|
||||
// where function is: void function (DispelInfo* dispelInfo);
|
||||
HookList<AuraDispelHandler> AfterDispel;
|
||||
#define AuraDispelFn(F) AuraDispelFunction(&F)
|
||||
|
||||
// executed when aura effect is applied with specified mode to target
|
||||
// should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
|
||||
// example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
|
||||
Reference in New Issue
Block a user