From d39e81e257b5de68c947bff5e8304fdc9b6bcb5d Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 2 Sep 2024 10:40:50 +0200 Subject: Core/Spells: Fixed spell target selection not being shared by multiple effects when there are targeting scripts that have the same script function (cherry picked from commit b1d8061a0f848241fe70ab0d718e829836cb5601) --- src/server/game/Spells/Spell.cpp | 40 ++++++++++++++++++++++++------------ src/server/game/Spells/SpellScript.h | 8 ++++++++ 2 files changed, 35 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a91768186a3..7f0dbe517dc 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -8099,23 +8099,37 @@ void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target, bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck) { - // Skip if there are not any script - if (m_loadedScripts.empty()) + auto allEffectTargetScriptsAreShared = [](HookList& hooks, SpellInfo const* spellInfo, uint32 effIndex, uint32 effIndexToCheck) + { + for (HookType& hook : hooks) + { + if (!hook.IsEffectAffected(spellInfo, effIndex)) + continue; + + bool otherEffectHasSameTargetFunction = std::ranges::any_of(hooks, [&](HookType& other) + { + return other.IsEffectAffected(spellInfo, effIndexToCheck) && hook.HasSameTargetFunctionAs(other); + }); + if (!otherEffectHasSameTargetFunction) + return false; + } + return true; + }; - for (auto itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr) + for (SpellScript* script : m_loadedScripts) { - auto targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin(); - for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr) - if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) || - (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck))) - return false; + if (!allEffectTargetScriptsAreShared(script->OnObjectTargetSelect, m_spellInfo, effIndex, effIndexToCheck)) + return false; - auto areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin(); - for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr) - if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) || - (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck))) - return false; + if (!allEffectTargetScriptsAreShared(script->OnObjectTargetSelect, m_spellInfo, effIndexToCheck, effIndex)) + return false; + + if (!allEffectTargetScriptsAreShared(script->OnObjectAreaTargetSelect, m_spellInfo, effIndex, effIndexToCheck)) + return false; + + if (!allEffectTargetScriptsAreShared(script->OnObjectAreaTargetSelect, m_spellInfo, effIndexToCheck, effIndex)) + return false; } return true; } diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 91eb9cf5c3b..5f623e22218 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -281,6 +281,10 @@ class TC_GAME_API SpellScript : public _SpellScript public: ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); void Call(SpellScript* spellScript, std::list& targets); + bool HasSameTargetFunctionAs(ObjectAreaTargetSelectHandler const& other) const + { + return pObjectAreaTargetSelectHandlerScript == other.pObjectAreaTargetSelectHandlerScript; + } private: SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript; }; @@ -290,6 +294,10 @@ class TC_GAME_API SpellScript : public _SpellScript public: ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); void Call(SpellScript* spellScript, WorldObject*& target); + bool HasSameTargetFunctionAs(ObjectTargetSelectHandler const& other) const + { + return pObjectTargetSelectHandlerScript == other.pObjectTargetSelectHandlerScript; + } private: SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript; }; -- cgit v1.2.3