diff options
| author | ForesterDev <11771800+ForesterDev@users.noreply.github.com> | 2019-08-23 21:24:56 +0400 |
|---|---|---|
| committer | Giacomo Pozzoni <giacomopoz@gmail.com> | 2019-08-23 19:24:56 +0200 |
| commit | 448facc5e794bde5068533825ebfd55435effb57 (patch) | |
| tree | 9df1c5ea6f2cb7f9b2e49d00fbaf0d66fc48cfc2 /src/server/game | |
| parent | 10f6e3818578410246750c6fce53d189ad05bee4 (diff) | |
Core/Spells: Fixed warlock's Banish cancel if target was already banished (#23697)
* Core/Spells: Add SpellMissInfo argument to BeforeHit hooks and call them also when the spell doesn't hit. (#17613)
(cherry picked from commit 8ff5b35be1256d03b85438b130dcec7cd4cae6e1)
# Conflicts:
# src/server/game/Spells/Spell.cpp
# src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
# src/server/scripts/Spells/spell_warlock.cpp
* Core/Spells: Fixed warlock's Banish cancel if target was already banished (#17614)
(cherry picked from commit 4587b5d88082d2c6416fafaa2f5b9f5f15038520)
# Conflicts:
# src/server/scripts/Spells/spell_warlock.cpp
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 12 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 10 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellScript.h | 18 |
5 files changed, 34 insertions, 10 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 5e05fd2f911..740f7afdfab 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2284,6 +2284,8 @@ void Spell::TargetInfo::PreprocessTarget(Spell* spell) if ((MissCondition == SPELL_MISS_IMMUNE || MissCondition == SPELL_MISS_IMMUNE2) && spell->m_caster->GetTypeId() == TYPEID_PLAYER && unit->GetTypeId() == TYPEID_PLAYER && spell->m_caster->IsValidAttackTarget(unit, spell->GetSpellInfo())) unit->SetInCombatWith(spell->m_caster->ToPlayer()); + spell->CallScriptBeforeHitHandlers(MissCondition); + _enablePVP = false; // need to check PvP state before spell effects, but act on it afterwards if (_spellHitTarget) { @@ -2592,7 +2594,7 @@ void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex) if (!go) return; - spell->CallScriptBeforeHitHandlers(); + spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE); spell->HandleEffects(nullptr, nullptr, go, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); @@ -2616,7 +2618,7 @@ void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex) void Spell::ItemTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex) { - spell->CallScriptBeforeHitHandlers(); + spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE); spell->HandleEffects(nullptr, TargetItem, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); @@ -2638,8 +2640,6 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, bool scaleAura, TargetInfo& if (m_spellInfo->Speed && unit->IsImmunedToSpell(m_spellInfo, m_caster)) return SPELL_MISS_IMMUNE; - CallScriptBeforeHitHandlers(); - if (Player* player = unit->ToPlayer()) { player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id); @@ -7826,7 +7826,7 @@ void Spell::CallScriptSuccessfulDispel(SpellEffIndex effIndex) } } -void Spell::CallScriptBeforeHitHandlers() +void Spell::CallScriptBeforeHitHandlers(SpellMissInfo missInfo) { for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) { @@ -7834,7 +7834,7 @@ void Spell::CallScriptBeforeHitHandlers() (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT); auto hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin(); for (; hookItr != hookItrEnd; ++hookItr) - (*hookItr).Call(*scritr); + (*hookItr).Call(*scritr, missInfo); (*scritr)->_FinishScriptCall(); } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 13d15773e3d..b8ddb3895b1 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -740,7 +740,7 @@ class TC_GAME_API Spell SpellCastResult CallScriptCheckCastHandlers(); 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); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index f5c6f1d9f25..fcff4b49a36 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1346,7 +1346,7 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const // ...but not these (Divine shield, Ice block, Cyclone and Banish for example) if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD && auraSpellInfo->Mechanic != MECHANIC_INVULNERABILITY && - (auraSpellInfo->Mechanic != MECHANIC_BANISH || (IsRankOf(auraSpellInfo) && auraSpellInfo->Dispel != DISPEL_NONE))) // Banish shouldn't be immune to itself, but Cyclone should + auraSpellInfo->Mechanic != MECHANIC_BANISH) return true; } diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 3a777643933..784b009b3c2 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -220,6 +220,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; diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index d2cf973c9a0..e455398c2db 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -189,6 +189,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*>&); \ @@ -235,6 +236,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: @@ -280,6 +290,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) { } } @@ -329,8 +340,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); |
