From 72e48ef8b3f0115dfa509c5e9a14d7738cb85b59 Mon Sep 17 00:00:00 2001 From: Giuseppe Montesanto Date: Wed, 14 Dec 2011 16:13:10 +0100 Subject: Fix immunity system for many spells. --- src/server/game/Entities/Creature/Creature.cpp | 15 ++++++++++++++- src/server/game/Entities/Unit/Unit.cpp | 16 +++++++++++----- src/server/game/Spells/Spell.cpp | 2 +- src/server/game/Spells/SpellInfo.cpp | 8 ++++++++ src/server/game/Spells/SpellInfo.h | 1 + 5 files changed, 35 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 3238d9873a9..32fe7021acf 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1643,7 +1643,20 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) if (!spellInfo) return false; - if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) + // Spells that don't have effectMechanics. + if (!spellInfo->HasAnyEffectMechanic() && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) + return true; + + // This check must be done instead of 'if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))' for not break + // the check of mechanic immunity on DB (tested) because GetCreatureInfo()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data. + bool immunedToAllEffects = true; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (!IsImmunedToSpellEffect(spellInfo, i)) + { + immunedToAllEffects = false; + break; + } + if (immunedToAllEffects) return true; return Unit::IsImmunedToSpell(spellInfo); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2e2f5591a5d..8997fad9d0d 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11448,7 +11448,8 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) return true; } - if (spellInfo->Mechanic) + // Spells that don't have effectMechanics. + if (!spellInfo->HasAnyEffectMechanic() && spellInfo->Mechanic) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -11456,14 +11457,19 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) return true; } - for (int i = 0; i < MAX_SPELL_EFFECTS; ++i) + bool immuneToAllEffects = true; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { // State/effect immunities applied by aura expect full spell immunity // Ignore effects with mechanic, they are supposed to be checked separately - if (!spellInfo->Effects[i].Mechanic) - if (IsImmunedToSpellEffect(spellInfo, i)) - return true; + if (spellInfo->Effects[i].Mechanic || !IsImmunedToSpellEffect(spellInfo, i)) + { + immuneToAllEffects = false; + break; + } } + if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects. + return true; if (spellInfo->Id != 42292 && spellInfo->Id !=59752) { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8a4c0a768d8..1edc3573e0a 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1562,7 +1562,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, const uint32 effectMask, bool } for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber)) + if (effectMask & (1 << effectNumber) && !unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) //Handle effect only if the target isn't immune. HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); return SPELL_MISS_NONE; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 972276c7d26..dae1b462880 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1755,6 +1755,14 @@ Mechanics SpellInfo::GetEffectMechanic(uint8 effIndex) const return MECHANIC_NONE; } +bool SpellInfo::HasAnyEffectMechanic() const +{ + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (Effects[i].Mechanic) + return true; + return false; +} + uint32 SpellInfo::GetDispelMask() const { return GetDispelMask(DispelType(Dispel)); diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 7faf0de890d..b38c1e0568e 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -446,6 +446,7 @@ public: uint32 GetEffectMechanicMask(uint8 effIndex) const; uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const; Mechanics GetEffectMechanic(uint8 effIndex) const; + bool HasAnyEffectMechanic() const; uint32 GetDispelMask() const; static uint32 GetDispelMask(DispelType type); uint32 GetExplicitTargetMask() const; -- cgit v1.2.3