diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index dcb2855629d..0121f2b594d 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -486,6 +486,7 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, UpdateMovementFlags(); LoadCreaturesAddon(); + LoadMechanicTemplateImmunity(); return true; } @@ -1832,17 +1833,35 @@ void Creature::DespawnOrUnsummon(uint32 msTimeToDespawn /*= 0*/, Seconds const& ForcedDespawn(msTimeToDespawn, forceRespawnTimer); } +void Creature::LoadMechanicTemplateImmunity() +{ + // uint32 max used for "spell id", the immunity system will not perform SpellInfo checks against invalid spells + // used so we know which immunities were loaded from template + static uint32 const placeholderSpellId = std::numeric_limits::max(); + + // unapply template immunities (in case we're updating entry) + for (uint32 i = MECHANIC_NONE + 1; i < MAX_MECHANIC; ++i) + ApplySpellImmune(placeholderSpellId, IMMUNITY_MECHANIC, i, false); + + // don't inherit immunities for hunter pets + if (GetOwnerGUID().IsPlayer() && IsHunterPet()) + return; + + if (uint32 mask = GetCreatureTemplate()->MechanicImmuneMask) + { + for (uint32 i = MECHANIC_NONE + 1; i < MAX_MECHANIC; ++i) + { + if (mask & (1 << (i - 1))) + ApplySpellImmune(placeholderSpellId, IMMUNITY_MECHANIC, i, true); + } + } +} + bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) const { if (!spellInfo) return false; - // Creature is immune to main mechanic of the spell - if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) - return true; - - // This check must be done instead of 'if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))' for not break - // the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data. bool immunedToAllEffects = true; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { @@ -1862,9 +1881,6 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) const bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const { - if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Effects[index].Mechanic - 1))) - return true; - if (GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && spellInfo->Effects[index].Effect == SPELL_EFFECT_HEAL) return true; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index b7d8f3c6b10..85cbe084f1a 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -481,6 +481,7 @@ class TC_GAME_API Creature : public Unit, public GridObject, public Ma bool isCanInteractWithBattleMaster(Player* player, bool msg) const; bool isCanTrainingAndResetTalentsOf(Player* player) const; bool CanCreatureAttack(Unit const* victim, bool force = true) const; + void LoadMechanicTemplateImmunity(); bool IsImmunedToSpell(SpellInfo const* spellInfo) const override; // override Unit::IsImmunedToSpell bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const override; // override Unit::IsImmunedToSpellEffect bool isElite() const;