fix(Core/Immunities): ignore school immunity from friendly caster (#25408)

This commit is contained in:
sogladev
2026-04-10 11:55:47 +02:00
committed by GitHub
parent dbae4648ba
commit b5c8b99ad6
3 changed files with 80 additions and 28 deletions

View File

@@ -74,6 +74,7 @@
#include "WorldPacket.h"
#include <algorithm>
#include <cmath>
#include <limits>
float baseMoveSpeed[MAX_MOVE_TYPE] =
{
@@ -910,6 +911,9 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, uint32 effectMask, Unit
if (!spellInfo)
return false;
if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && !HasSpiritOfRedemptionAura())
return false;
bool immuneToAllEffects = true;
bool hasCheckedEffect = false;
@@ -940,8 +944,28 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, uint32 effectMask, Unit
if (!spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
{
if (IsImmunedToSchool(spellInfo))
return true;
if (spellInfo->Id == 42292 || spellInfo->Id == 59752 || spellInfo->Id == 19574 || spellInfo->Id == 34471)
return false;
SpellSchoolMask schoolMask = spellInfo->GetSchoolMask();
if (schoolMask != SPELL_SCHOOL_MASK_NONE)
{
SpellImmuneContainer const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for (auto const& [immunitySchoolMask, immunityAuraId] : schoolList)
{
SpellInfo const* immuneSpellInfo = sSpellMgr->GetSpellInfo(immunityAuraId);
if ((immunitySchoolMask & schoolMask) != schoolMask)
continue;
if (IgnoresSchoolImmunityFromFriendlyCaster(caster, immunityAuraId, immuneSpellInfo))
continue;
if (spellInfo->CanPierceImmuneAura(immuneSpellInfo))
continue;
return true;
}
}
}
return false;
@@ -9810,6 +9834,18 @@ uint32 Unit::GetDamageImmunityMask() const
return mask;
}
bool Unit::IgnoresSchoolImmunityFromFriendlyCaster(Unit const* caster, uint32 immunityAuraId, SpellInfo const* immunitySpellInfo) const
{
if (!caster || !caster->IsFriendlyTo(this))
return false;
if (immunitySpellInfo)
return !immunitySpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS);
// Creature template immunities are loaded with a placeholder spell id.
return immunityAuraId == std::numeric_limits<uint32>::max();
}
bool Unit::IsImmunedToDamage(SpellSchoolMask schoolMask) const
{
if (schoolMask == SPELL_SCHOOL_MASK_NONE)
@@ -9847,7 +9883,7 @@ bool Unit::IsImmunedToDamage(Unit const* caster, SpellInfo const* spellInfo) con
for (auto const& [immunitySchoolMask, immunityAuraId] : container)
{
SpellInfo const* immuneAuraInfo = sSpellMgr->GetSpellInfo(immunityAuraId);
if (immuneAuraInfo && !immuneAuraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && caster && caster->IsFriendlyTo(this))
if (IgnoresSchoolImmunityFromFriendlyCaster(caster, immunityAuraId, immuneAuraInfo))
continue;
if (immuneAuraInfo && spellInfo->CanPierceImmuneAura(immuneAuraInfo))
@@ -9928,7 +9964,10 @@ bool Unit::IsImmunedToSchool(Spell const* spell) const
SpellImmuneContainer const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for (auto itr = schoolList.begin(); itr != schoolList.end(); ++itr)
{
if ((itr->first & schoolMask) == schoolMask && !spellInfo->CanPierceImmuneAura(sSpellMgr->GetSpellInfo(itr->second)))
SpellInfo const* immuneSpellInfo = sSpellMgr->GetSpellInfo(itr->second);
if ((itr->first & schoolMask) == schoolMask
&& !IgnoresSchoolImmunityFromFriendlyCaster(spell->GetCaster(), itr->second, immuneSpellInfo)
&& !spellInfo->CanPierceImmuneAura(immuneSpellInfo))
{
return true;
}
@@ -9966,7 +10005,7 @@ bool Unit::IsImmunedToAuraPeriodicTick(Unit const* caster, SpellInfo const* spel
for (auto const& [immunitySchoolMask, immunityAuraId] : container)
{
SpellInfo const* immuneAuraInfo = sSpellMgr->GetSpellInfo(immunityAuraId);
if (immuneAuraInfo && !immuneAuraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && caster && caster->IsFriendlyTo(this))
if (IgnoresSchoolImmunityFromFriendlyCaster(caster, immunityAuraId, immuneAuraInfo))
continue;
schoolImmunityMask |= immunitySchoolMask;
@@ -10045,6 +10084,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell)
if (!spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
{
SpellSchoolMask spellSchoolMask = spellInfo->GetSchoolMask();
Unit const* spellCaster = spell ? spell->GetCaster() : nullptr;
if (spell)
{
spellSchoolMask = spell->GetSpellSchoolMask();
@@ -10059,12 +10099,8 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell)
if (!(itr->first & spellSchoolMask))
continue;
if (immuneSpellInfo && !immuneSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
{
Unit const* spellCaster = spell ? spell->GetCaster() : nullptr;
if (spellCaster && spellCaster->IsFriendlyTo(this))
continue;
}
if (IgnoresSchoolImmunityFromFriendlyCaster(spellCaster, itr->second, immuneSpellInfo))
continue;
if (spellInfo->CanPierceImmuneAura(immuneSpellInfo))
continue;
@@ -15109,7 +15145,7 @@ Aura* Unit::AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target)
if (!spellInfo)
return nullptr;
if (target->IsImmunedToSpell(spellInfo))
if (target->IsImmunedToSpell(spellInfo, effMask, this))
return nullptr;
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)