fix(Core/Unit): partial immunity for mixed spells (#25219)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
parent
9d9f9bdc58
commit
aac930864a
2 changed files with 58 additions and 3 deletions
|
|
@ -910,15 +910,34 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, uint32 effectMask, Unit
|
|||
if (!spellInfo)
|
||||
return false;
|
||||
|
||||
bool immuneToAllEffects = true;
|
||||
bool hasCheckedEffect = false;
|
||||
|
||||
for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (!(effectMask & (1u << i)))
|
||||
continue;
|
||||
|
||||
if (!spellInfo->Effects[i].IsEffect())
|
||||
continue;
|
||||
|
||||
hasCheckedEffect = true;
|
||||
|
||||
if (IsImmunedToSpellEffect(spellInfo, i, caster))
|
||||
return true;
|
||||
{
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR4_NO_PARTIAL_IMMUNITY))
|
||||
return true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
immuneToAllEffects = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasCheckedEffect && immuneToAllEffects)
|
||||
return true;
|
||||
|
||||
if (!spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
|
||||
{
|
||||
if (IsImmunedToSchool(spellInfo))
|
||||
|
|
|
|||
|
|
@ -105,6 +105,31 @@ namespace
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IsEffectBlockedByStunImmunity(EffectDesc const& effect, bool immuneToStun)
|
||||
{
|
||||
if (!immuneToStun)
|
||||
return false;
|
||||
|
||||
return effect.effect == EFFECT_APPLY_AURA && effect.aura == AURA_MOD_STUN;
|
||||
}
|
||||
|
||||
bool IsFullyImmunedByStunImmunity(SpellDesc const& spell, bool immuneToStun)
|
||||
{
|
||||
bool hasAnyEffect = false;
|
||||
|
||||
for (EffectDesc const& effect : spell.effects)
|
||||
{
|
||||
if (effect.effect == EFFECT_NONE)
|
||||
continue;
|
||||
|
||||
hasAnyEffect = true;
|
||||
if (!IsEffectBlockedByStunImmunity(effect, immuneToStun))
|
||||
return false;
|
||||
}
|
||||
|
||||
return hasAnyEffect;
|
||||
}
|
||||
|
||||
// The last parameter defaults to false to avoid updating existing tests
|
||||
// that don't care about mechanic immunities. Bladestorm grants a
|
||||
// specific mechanic immunity (including stun) that should block
|
||||
|
|
@ -114,12 +139,12 @@ namespace
|
|||
{
|
||||
// Mirrors current core ordering:
|
||||
// 1) full spell immunity check
|
||||
// 2) mechanic immunity check (e.g. bladestorm vs stun)
|
||||
// 2) full immunity from mechanic immunity (all effects blocked)
|
||||
// 3) damage immunity only for damage-only spells
|
||||
if (isImmunedToSpell)
|
||||
return SPELL_MISS_IMMUNE;
|
||||
|
||||
if (immuneToStun && IsStunSpell(spell))
|
||||
if (IsFullyImmunedByStunImmunity(spell, immuneToStun))
|
||||
return SPELL_MISS_IMMUNE;
|
||||
|
||||
if (HasOnlyDamageEffects(spell) && isImmunedToDamage)
|
||||
|
|
@ -328,3 +353,14 @@ TEST(SpellImmunityTest, Bladestorm_ImmuneToStun)
|
|||
// with a bladestorm‑style stun immunity it is blocked
|
||||
EXPECT_EQ(ComputeSpellHitResult(false, false, stunSpell, true), SPELL_MISS_IMMUNE);
|
||||
}
|
||||
|
||||
TEST(SpellImmunityTest, StunImmunity_DoesNotFullyBlockMixedSpell)
|
||||
{
|
||||
SpellDesc mixedSpell;
|
||||
mixedSpell.effects[0] = { EFFECT_SCHOOL_DAMAGE, AURA_NONE };
|
||||
mixedSpell.effects[1] = { EFFECT_APPLY_AURA, AURA_MOD_STUN };
|
||||
|
||||
// This models partial immunity: stun effect is blocked, damage still hits.
|
||||
EXPECT_TRUE(IsStunSpell(mixedSpell));
|
||||
EXPECT_EQ(ComputeSpellHitResult(false, false, mixedSpell, true), SPELL_MISS_NONE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue