From ffc05d0bf17979b14a913a2a0e9393e564c1913b Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Fri, 26 Feb 2021 11:30:44 +0100 Subject: [PATCH] Core/Spells: implement helper to filter mechanic immunities in packets to reflect sniff behavior and removed pct heal effects from heal prediction Despite being able to send all mechanic immunities in spell_start and channel_start, sniffs confirm that only relevant immunities are being sent which in most cases are silence and interrupt immunities. Further sniff analysis may reveal even more possible interrupt flags --- src/server/game/Spells/Spell.cpp | 14 ++++++-------- src/server/game/Spells/SpellInfo.cpp | 19 +++++++++++++++++++ src/server/game/Spells/SpellInfo.h | 2 ++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 28b23fb6fbb..544a96c2e15 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4279,8 +4279,9 @@ void Spell::SendSpellStart() //TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id); uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY; - uint32 schoolImmunityMask = m_caster->GetSchoolImmunityMask(); - uint32 mechanicImmunityMask = m_caster->GetMechanicImmunityMask(); + uint32 schoolImmunityMask = m_casttime != 0 ? m_caster->GetSchoolImmunityMask() : 0; + uint32 mechanicImmunityMask = m_casttime != 0 ? m_spellInfo->GetMechanicImmunityMask(m_caster, false) : 0; + if (schoolImmunityMask || mechanicImmunityMask) castFlags |= CAST_FLAG_IMMUNITY; @@ -4298,8 +4299,7 @@ void Spell::SendSpellStart() if (m_spellInfo->RuneCostID && m_spellInfo->PowerType == POWER_RUNE) castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it - if ((m_casttime && m_spellInfo->HasEffect(SPELL_EFFECT_HEAL)) || m_spellInfo->HasEffect(SPELL_EFFECT_HEAL_PCT) || - m_spellInfo->HasAura(SPELL_AURA_PERIODIC_HEAL)) + if ((m_casttime && m_spellInfo->HasEffect(SPELL_EFFECT_HEAL)) || m_spellInfo->HasAura(SPELL_AURA_PERIODIC_HEAL)) castFlags |= CAST_FLAG_HEAL_PREDICTION; WorldPackets::Spells::SpellStart packet; @@ -4317,8 +4317,6 @@ void Spell::SendSpellStart() castData.CastFlagsEx = m_castFlagsEx; castData.CastTime = m_casttime; - //data << uint32(m_timer); // delay? - m_targets.Write(castData.Target); if (castFlags & CAST_FLAG_POWER_LEFT_SELF) @@ -4806,7 +4804,7 @@ void Spell::SendChannelStart(uint32 duration) uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY; uint32 schoolImmunityMask = m_caster->GetSchoolImmunityMask(); - uint32 mechanicImmunityMask = m_caster->GetMechanicImmunityMask(); + uint32 mechanicImmunityMask = m_spellInfo->GetMechanicImmunityMask(m_caster, true); if (schoolImmunityMask || mechanicImmunityMask) castFlags |= CAST_FLAG_IMMUNITY; @@ -4824,7 +4822,7 @@ void Spell::SendChannelStart(uint32 duration) for (uint8 j = 0; j < MAX_SPELL_EFFECTS; j++) { - if (spell->Effects[j].Effect == SPELL_EFFECT_HEAL || spell->Effects[j].Effect == SPELL_EFFECT_HEAL_PCT) + if (spell->Effects[j].Effect == SPELL_EFFECT_HEAL) { Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : m_caster; int32 heal = spell->Effects[j].CalcValue(m_caster); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 3444f103f75..f382b0802fd 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3253,6 +3253,25 @@ uint32 SpellInfo::GetAllowedMechanicMask() const return _allowedMechanicMask; } +uint32 SpellInfo::GetMechanicImmunityMask(Unit* caster, bool channeled) const +{ + uint32 casterMechanicImmunityMask = caster->GetMechanicImmunityMask(); + uint32 mechanicImmunityMask = 0; + uint32 flags = channeled ? ChannelInterruptFlags : InterruptFlags; + + // @todo: research other interrupt flags + if (flags & 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) const { if (!RangeEntry) diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 9bb59173a9d..5c768e7a0b1 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -593,6 +593,8 @@ class TC_GAME_API SpellInfo uint32 GetAllowedMechanicMask() const; + uint32 GetMechanicImmunityMask(Unit* caster, bool channeled) const; + private: // loading helpers void _InitializeExplicitTargetMask();