From 6215cb4e0014fbe9df35a8c6b013e7801bd8ffec Mon Sep 17 00:00:00 2001 From: Ovah Date: Sun, 11 Apr 2021 12:51:58 +0200 Subject: [PATCH] Core/Spells: implement SpellInfo helper to filter for relevant mechanic immunities in spell_start packet (#26183) * Core/Spells: implement SpellInfo helper to filter for relevant mechanic immunities when sending SMSG_SPELL_START packets. According to sniff analysis Blizzard does not send all mechanic immunities of creatures but instead only the ones that are responsible for actual interrupts which are MECHANIC_INTERRUPT and MECHANIC_SILENCE. Additionally we no longer send immunities for instant cast spells as sniffs confirm that they are not sent for spells without a cast time. --- src/server/game/Spells/Spell.cpp | 4 ++-- src/server/game/Spells/SpellInfo.cpp | 18 ++++++++++++++++++ src/server/game/Spells/SpellInfo.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 1ff4cffe812..cd78f49cd84 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4176,8 +4176,8 @@ void Spell::SendSpellStart() uint32 mechanicImmunityMask = 0; if (Unit* unitCaster = m_caster->ToUnit()) { - schoolImmunityMask = unitCaster->GetSchoolImmunityMask(); - mechanicImmunityMask = unitCaster->GetMechanicImmunityMask(); + schoolImmunityMask = m_timer!= 0 ? unitCaster->GetSchoolImmunityMask() : 0; + mechanicImmunityMask = m_timer != 0 ? m_spellInfo->GetMechanicImmunityMask(unitCaster) : 0; } if (schoolImmunityMask || mechanicImmunityMask) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index f0d42133088..492ced10a64 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3038,6 +3038,24 @@ uint32 SpellInfo::GetAllowedMechanicMask() const return _allowedMechanicMask; } +uint32 SpellInfo::GetMechanicImmunityMask(Unit* caster) const +{ + uint32 casterMechanicImmunityMask = caster->GetMechanicImmunityMask(); + uint32 mechanicImmunityMask = 0; + + // @todo: research other interrupt flags + if (InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT) + { + if (casterMechanicImmunityMask & (1 << MECHANIC_SILENCE)) + mechanicImmunityMask |= (1 << MECHANIC_SILENCE); + + if (casterMechanicImmunityMask & (1 << MECHANIC_INTERRUPT)) + mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT); + } + + return mechanicImmunityMask; +} + float SpellInfo::GetMinRange(bool positive /*= false*/) const { if (!RangeEntry) diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 6f2e8588009..f1a501b0286 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -533,6 +533,8 @@ class TC_GAME_API SpellInfo uint32 GetAllowedMechanicMask() const; + uint32 GetMechanicImmunityMask(Unit* caster) const; + private: // loading helpers void _InitializeExplicitTargetMask();