mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spells: Add SpellMissInfo argument to BeforeHit hooks and call them also when the spell doesn't hit. (#17613)
This commit is contained in:
@@ -2338,9 +2338,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
|
||||
}
|
||||
}
|
||||
|
||||
PrepareScriptHitHandlers();
|
||||
CallScriptBeforeHitHandlers(missInfo);
|
||||
|
||||
if (spellHitTarget)
|
||||
{
|
||||
SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
|
||||
|
||||
if (missInfo2 != SPELL_MISS_NONE)
|
||||
{
|
||||
if (missInfo2 != SPELL_MISS_MISS)
|
||||
@@ -2519,9 +2523,6 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
|
||||
if (!effectMask)
|
||||
return returnVal;
|
||||
|
||||
PrepareScriptHitHandlers();
|
||||
CallScriptBeforeHitHandlers();
|
||||
|
||||
if (Player* player = unit->ToPlayer())
|
||||
{
|
||||
player->StartCriteriaTimer(CRITERIA_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
|
||||
@@ -2782,7 +2783,7 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo* target)
|
||||
return;
|
||||
|
||||
PrepareScriptHitHandlers();
|
||||
CallScriptBeforeHitHandlers();
|
||||
CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
|
||||
|
||||
for (SpellEffectInfo const* effect : GetEffects())
|
||||
if (effect && (effectMask & (1 << effect->EffectIndex)))
|
||||
@@ -2799,7 +2800,7 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo* target)
|
||||
return;
|
||||
|
||||
PrepareScriptHitHandlers();
|
||||
CallScriptBeforeHitHandlers();
|
||||
CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
|
||||
|
||||
for (SpellEffectInfo const* effect : GetEffects())
|
||||
if (effect && (effectMask & (1 << effect->EffectIndex)))
|
||||
@@ -7190,14 +7191,14 @@ void Spell::CallScriptSuccessfulDispel(SpellEffIndex effIndex)
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::CallScriptBeforeHitHandlers()
|
||||
void Spell::CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
|
||||
{
|
||||
for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
|
||||
std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
|
||||
std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
|
||||
for (; hookItr != hookItrEnd; ++hookItr)
|
||||
(*hookItr).Call(*scritr);
|
||||
(*hookItr).Call(*scritr, missInfo);
|
||||
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
|
||||
@@ -801,7 +801,7 @@ class TC_GAME_API Spell
|
||||
void PrepareScriptHitHandlers();
|
||||
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode);
|
||||
void CallScriptSuccessfulDispel(SpellEffIndex effIndex);
|
||||
void CallScriptBeforeHitHandlers();
|
||||
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo);
|
||||
void CallScriptOnHitHandlers();
|
||||
void CallScriptAfterHitHandlers();
|
||||
void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
|
||||
|
||||
@@ -206,6 +206,16 @@ void SpellScript::EffectHandler::Call(SpellScript* spellScript, SpellEffIndex ef
|
||||
(spellScript->*pEffectHandlerScript)(effIndexToHandle);
|
||||
}
|
||||
|
||||
SpellScript::BeforeHitHandler::BeforeHitHandler(SpellBeforeHitFnType pBeforeHitHandlerScript)
|
||||
{
|
||||
_pBeforeHitHandlerScript = pBeforeHitHandlerScript;
|
||||
}
|
||||
|
||||
void SpellScript::BeforeHitHandler::Call(SpellScript* spellScript, SpellMissInfo missInfo)
|
||||
{
|
||||
(spellScript->*_pBeforeHitHandlerScript)(missInfo);
|
||||
}
|
||||
|
||||
SpellScript::HitHandler::HitHandler(SpellHitFnType _pHitHandlerScript)
|
||||
{
|
||||
pHitHandlerScript = _pHitHandlerScript;
|
||||
|
||||
@@ -168,6 +168,7 @@ class TC_GAME_API SpellScript : public _SpellScript
|
||||
#define SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) \
|
||||
typedef SpellCastResult(CLASSNAME::*SpellCheckCastFnType)(); \
|
||||
typedef void(CLASSNAME::*SpellEffectFnType)(SpellEffIndex); \
|
||||
typedef void(CLASSNAME::*SpellBeforeHitFnType)(SpellMissInfo missInfo); \
|
||||
typedef void(CLASSNAME::*SpellHitFnType)(); \
|
||||
typedef void(CLASSNAME::*SpellCastFnType)(); \
|
||||
typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \
|
||||
@@ -214,6 +215,15 @@ class TC_GAME_API SpellScript : public _SpellScript
|
||||
SpellHitFnType pHitHandlerScript;
|
||||
};
|
||||
|
||||
class TC_GAME_API BeforeHitHandler
|
||||
{
|
||||
public:
|
||||
BeforeHitHandler(SpellBeforeHitFnType pBeforeHitHandlerScript);
|
||||
void Call(SpellScript* spellScript, SpellMissInfo missInfo);
|
||||
private:
|
||||
SpellBeforeHitFnType _pBeforeHitHandlerScript;
|
||||
};
|
||||
|
||||
class TC_GAME_API TargetHook : public _SpellScript::EffectHook
|
||||
{
|
||||
public:
|
||||
@@ -259,6 +269,7 @@ class TC_GAME_API SpellScript : public _SpellScript
|
||||
class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) { } }; \
|
||||
class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) { } }; \
|
||||
class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) { } }; \
|
||||
class BeforeHitHandlerFunction : public SpellScript::BeforeHitHandler { public: BeforeHitHandlerFunction(SpellBeforeHitFnType pBeforeHitHandlerScript) : SpellScript::BeforeHitHandler((SpellScript::SpellBeforeHitFnType)pBeforeHitHandlerScript) { } }; \
|
||||
class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
|
||||
class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
|
||||
class DestinationTargetSelectHandlerFunction : public SpellScript::DestinationTargetSelectHandler { public: DestinationTargetSelectHandlerFunction(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::DestinationTargetSelectHandler((SpellScript::SpellDestinationTargetSelectFnType)_DestinationTargetSelectHandlerScript, _effIndex, _targetType) { } }
|
||||
@@ -307,8 +318,11 @@ class TC_GAME_API SpellScript : public _SpellScript
|
||||
HookList<EffectHandler> OnEffectSuccessfulDispel;
|
||||
#define SpellEffectFn(F, I, N) EffectHandlerFunction(&F, I, N)
|
||||
|
||||
// example: BeforeHit += SpellHitFn(class::function);
|
||||
HookList<HitHandler> BeforeHit;
|
||||
// example: BeforeHit += BeforeSpellHitFn(class::function);
|
||||
// where function is void function(SpellMissInfo missInfo)
|
||||
HookList<BeforeHitHandler> BeforeHit;
|
||||
#define BeforeSpellHitFn(F) BeforeHitHandlerFunction(&F)
|
||||
|
||||
// example: OnHit += SpellHitFn(class::function);
|
||||
HookList<HitHandler> OnHit;
|
||||
// example: AfterHit += SpellHitFn(class::function);
|
||||
|
||||
@@ -263,8 +263,11 @@ class spell_garfrost_permafrost : public SpellScriptLoader
|
||||
}
|
||||
|
||||
private:
|
||||
void PreventHitByLoS()
|
||||
void PreventHitByLoS(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
@@ -305,7 +308,7 @@ class spell_garfrost_permafrost : public SpellScriptLoader
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeHit += SpellHitFn(spell_garfrost_permafrost_SpellScript::PreventHitByLoS);
|
||||
BeforeHit += BeforeSpellHitFn(spell_garfrost_permafrost_SpellScript::PreventHitByLoS);
|
||||
AfterHit += SpellHitFn(spell_garfrost_permafrost_SpellScript::RestoreImmunity);
|
||||
}
|
||||
|
||||
|
||||
@@ -1555,15 +1555,18 @@ class spell_valanar_kinetic_bomb_knockback : public SpellScriptLoader
|
||||
{
|
||||
PrepareSpellScript(spell_valanar_kinetic_bomb_knockback_SpellScript);
|
||||
|
||||
void KnockIntoAir()
|
||||
void KnockIntoAir(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
if (Creature* target = GetHitCreature())
|
||||
target->AI()->DoAction(ACTION_KINETIC_BOMB_JUMP);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeHit += SpellHitFn(spell_valanar_kinetic_bomb_knockback_SpellScript::KnockIntoAir);
|
||||
BeforeHit += BeforeSpellHitFn(spell_valanar_kinetic_bomb_knockback_SpellScript::KnockIntoAir);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -551,9 +551,9 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
void OnCast()
|
||||
void OnCast(SpellMissInfo missInfo)
|
||||
{
|
||||
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
|
||||
if (GetCaster()->GetTypeId() != TYPEID_PLAYER || missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
GetCaster()->RemoveAura(SPELL_FRENZIED_BLOODTHIRST, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
@@ -585,7 +585,7 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_blood_queen_vampiric_bite_SpellScript::CheckTarget);
|
||||
BeforeHit += SpellHitFn(spell_blood_queen_vampiric_bite_SpellScript::OnCast);
|
||||
BeforeHit += BeforeSpellHitFn(spell_blood_queen_vampiric_bite_SpellScript::OnCast);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_blood_queen_vampiric_bite_SpellScript::HandlePresence, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2133,14 +2133,17 @@ class spell_igb_below_zero : public SpellScriptLoader
|
||||
{
|
||||
PrepareSpellScript(spell_igb_below_zero_SpellScript);
|
||||
|
||||
void RemovePassengers()
|
||||
void RemovePassengers(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeHit += SpellHitFn(spell_igb_below_zero_SpellScript::RemovePassengers);
|
||||
BeforeHit += BeforeSpellHitFn(spell_igb_below_zero_SpellScript::RemovePassengers);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2102,8 +2102,11 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
|
||||
targets.resize(1);
|
||||
}
|
||||
|
||||
void CheckAura()
|
||||
void CheckAura(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
if (GetHitUnit()->HasAura(GetSpellInfo()->Id))
|
||||
_hadAura = true;
|
||||
}
|
||||
@@ -2116,7 +2119,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::CheckAura);
|
||||
BeforeHit += BeforeSpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::CheckAura);
|
||||
OnHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::AddMissingStack);
|
||||
}
|
||||
|
||||
@@ -2926,8 +2929,11 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveAura()
|
||||
void RemoveAura(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->RemoveAurasDueToSpell(target->GetMap()->IsHeroic() ? SPELL_HARVEST_SOULS_TELEPORT : SPELL_HARVEST_SOUL_TELEPORT);
|
||||
}
|
||||
@@ -2935,7 +2941,7 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_the_lich_king_restore_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
||||
BeforeHit += SpellHitFn(spell_the_lich_king_restore_soul_SpellScript::RemoveAura);
|
||||
BeforeHit += BeforeSpellHitFn(spell_the_lich_king_restore_soul_SpellScript::RemoveAura);
|
||||
}
|
||||
|
||||
InstanceScript* _instance;
|
||||
|
||||
@@ -1517,8 +1517,11 @@ class spell_auto_repair : public SpellScriptLoader
|
||||
{
|
||||
PrepareSpellScript(spell_auto_repair_SpellScript);
|
||||
|
||||
void CheckCooldownForTarget()
|
||||
void CheckCooldownForTarget(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
if (GetHitUnit()->HasAuraEffect(SPELL_AUTO_REPAIR, EFFECT_2)) // Check presence of dummy aura indicating cooldown
|
||||
{
|
||||
PreventHitEffect(EFFECT_0);
|
||||
@@ -1559,7 +1562,7 @@ class spell_auto_repair : public SpellScriptLoader
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_auto_repair_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
BeforeHit += SpellHitFn(spell_auto_repair_SpellScript::CheckCooldownForTarget);
|
||||
BeforeHit += BeforeSpellHitFn(spell_auto_repair_SpellScript::CheckCooldownForTarget);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -281,8 +281,11 @@ class spell_rog_deadly_poison : public SpellScriptLoader
|
||||
return GetCaster()->GetTypeId() == TYPEID_PLAYER && GetCastItem();
|
||||
}
|
||||
|
||||
void HandleBeforeHit()
|
||||
void HandleBeforeHit(SpellMissInfo missInfo)
|
||||
{
|
||||
if (missInfo != SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
if (Unit* target = GetHitUnit())
|
||||
// Deadly Poison
|
||||
if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, flag128(0x10000, 0x80000, 0), GetCaster()->GetGUID()))
|
||||
@@ -345,7 +348,7 @@ class spell_rog_deadly_poison : public SpellScriptLoader
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeHit += SpellHitFn(spell_rog_deadly_poison_SpellScript::HandleBeforeHit);
|
||||
BeforeHit += BeforeSpellHitFn(spell_rog_deadly_poison_SpellScript::HandleBeforeHit);
|
||||
AfterHit += SpellHitFn(spell_rog_deadly_poison_SpellScript::HandleAfterHit);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,10 +148,11 @@ class spell_warl_banish : public SpellScriptLoader
|
||||
}
|
||||
|
||||
private:
|
||||
void HandleBanish()
|
||||
void HandleBanish(SpellMissInfo missInfo)
|
||||
{
|
||||
/// Casting Banish on a banished target will cancel the effect
|
||||
/// Check if the target already has Banish, if so, do nothing.
|
||||
if (missInfo != SPELL_MISS_IMMUNE)
|
||||
return;
|
||||
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
if (target->GetAuraEffect(SPELL_AURA_SCHOOL_IMMUNITY, SPELLFAMILY_WARLOCK, flag128(0, 0x08000000, 0)))
|
||||
@@ -173,7 +174,7 @@ class spell_warl_banish : public SpellScriptLoader
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeHit += SpellHitFn(spell_warl_banish_SpellScript::HandleBanish);
|
||||
BeforeHit += BeforeSpellHitFn(spell_warl_banish_SpellScript::HandleBanish);
|
||||
AfterHit += SpellHitFn(spell_warl_banish_SpellScript::RemoveAura);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user