diff --git a/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp b/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp index 642f5b3fe..2a6dda237 100644 --- a/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/GlobalScript.cpp @@ -17,6 +17,7 @@ #include "ScriptMgr.h" #include "ScriptMgrMacros.h" +#include "Player.h" void ScriptMgr::OnGlobalItemDelFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid) { @@ -122,3 +123,18 @@ void ScriptMgr::OnBeforeWorldObjectSetPhaseMask(WorldObject const* worldObject, script->OnBeforeWorldObjectSetPhaseMask(worldObject, oldPhaseMask, newPhaseMask, useCombinedPhases, update); }); } + +bool ScriptMgr::OnIsAffectedBySpellModCheck(SpellInfo const* affectSpell, SpellInfo const* checkSpell, SpellModifier const* mod) +{ + auto ret = IsValidBoolScript([&](GlobalScript* script) + { + return !script->OnIsAffectedBySpellModCheck(affectSpell, checkSpell, mod); + }); + + if (ret && *ret) + { + return true; + } + + return false; +} diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 6aa23bee7..2637b7da9 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -82,6 +82,7 @@ struct GroupQueueInfo; struct ItemTemplate; struct OutdoorPvPData; struct TargetInfo; +struct SpellModifier; namespace Acore::ChatCommands { @@ -1517,6 +1518,9 @@ public: // Called before the phase for a WorldObject is set virtual void OnBeforeWorldObjectSetPhaseMask(WorldObject const* /*worldObject*/, uint32& /*oldPhaseMask*/, uint32& /*newPhaseMask*/, bool& /*useCombinedPhases*/, bool& /*update*/) { } + + // Called when checking if a spell is affected by a mod + virtual bool OnIsAffectedBySpellModCheck(SpellInfo const* /*affectSpell*/, SpellInfo const* /*checkSpell*/, SpellModifier const* /*mod*/) { return true; }; }; class BGScript : public ScriptObject @@ -2333,6 +2337,7 @@ public: /* GlobalScript */ void OnAfterInitializeLockedDungeons(Player* player); void OnAfterUpdateEncounterState(Map* map, EncounterCreditType type, uint32 creditEntry, Unit* source, Difficulty difficulty_fixed, DungeonEncounterList const* encounters, uint32 dungeonCompleted, bool updated); void OnBeforeWorldObjectSetPhaseMask(WorldObject const* worldObject, uint32& oldPhaseMask, uint32& newPhaseMask, bool& useCombinedPhases, bool& update); + bool OnIsAffectedBySpellModCheck(SpellInfo const* affectSpell, SpellInfo const* checkSpell, SpellModifier const* mod); public: /* Scheduled scripts */ uint32 IncreaseScheduledScriptsCount() { return ++_scheduledScripts; } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 1d31fbf91..8a9dd4698 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1280,8 +1280,19 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const return false; SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId); + + if (!affectSpell) + { + return false; + } + + if (!sScriptMgr->OnIsAffectedBySpellModCheck(affectSpell, this, mod)) + { + return true; + } + // False if affect_spell == nullptr or spellFamily not equal - if (!affectSpell || affectSpell->SpellFamilyName != SpellFamilyName) + if (affectSpell->SpellFamilyName != SpellFamilyName) return false; // true