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
This commit is contained in:
Ovahlord
2021-02-26 11:30:44 +01:00
parent 2439a741ff
commit ffc05d0bf1
3 changed files with 27 additions and 8 deletions

View File

@@ -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);

View File

@@ -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)

View File

@@ -593,6 +593,8 @@ class TC_GAME_API SpellInfo
uint32 GetAllowedMechanicMask() const;
uint32 GetMechanicImmunityMask(Unit* caster, bool channeled) const;
private:
// loading helpers
void _InitializeExplicitTargetMask();