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. (cherry picked from commit 6215cb4e0014fbe9df35a8c6b013e7801bd8ffec)
This commit is contained in:
@@ -4469,8 +4469,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)
|
||||
|
||||
@@ -1376,14 +1376,14 @@ bool SpellInfo::HasTargetType(::Targets target) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget) const
|
||||
bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget, bool ignoreImmunity /*= false*/) const
|
||||
{
|
||||
return HasAttribute(SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED)
|
||||
|| HasChannelInterruptFlag(SpellAuraInterruptFlags::Damage | SpellAuraInterruptFlags::EnteringCombat)
|
||||
|| (interruptTarget->IsPlayer() && InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancelsPlayerOnly))
|
||||
|| InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancels)
|
||||
|| (interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
|
||||
|| (!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT))
|
||||
|| (interruptCaster && interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
|
||||
|| ((!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT)) || ignoreImmunity)
|
||||
&& !interruptTarget->HasAuraTypeWithAffectMask(SPELL_AURA_PREVENT_INTERRUPT, this)
|
||||
&& PreventionType & SPELL_PREVENTION_TYPE_SILENCE);
|
||||
}
|
||||
@@ -3729,6 +3729,23 @@ uint32 SpellInfo::GetAllowedMechanicMask() const
|
||||
return _allowedMechanicMask;
|
||||
}
|
||||
|
||||
uint32 SpellInfo::GetMechanicImmunityMask(Unit const* caster) const
|
||||
{
|
||||
uint32 casterMechanicImmunityMask = caster->GetMechanicImmunityMask();
|
||||
uint32 mechanicImmunityMask = 0;
|
||||
|
||||
if (CanBeInterrupted(nullptr, caster, true))
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -476,7 +476,7 @@ class TC_GAME_API SpellInfo
|
||||
bool HasAttribute(SpellAttr14 attribute) const { return !!(AttributesEx14 & attribute); }
|
||||
bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
|
||||
|
||||
bool CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget) const;
|
||||
bool CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget, bool ignoreImmunity = false) const;
|
||||
|
||||
bool HasAnyAuraInterruptFlag() const;
|
||||
bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) const { return AuraInterruptFlags.HasFlag(flag); }
|
||||
@@ -605,6 +605,8 @@ class TC_GAME_API SpellInfo
|
||||
|
||||
uint32 GetAllowedMechanicMask() const;
|
||||
|
||||
uint32 GetMechanicImmunityMask(Unit const* caster) const;
|
||||
|
||||
// Player Condition
|
||||
bool MeetsFutureSpellPlayerCondition(Player const* player) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user