From 2c4cc00df2ee7269fb0cbdc7184e46021fdbd634 Mon Sep 17 00:00:00 2001 From: sidsukana <> Date: Tue, 24 Jan 2017 21:41:10 +0000 Subject: [PATCH] Implemented school immunity for creature from database The code is checking the database value against 1 << spellInfo->School so it should match the spell schools defined in the code (SharedDefines.h). Or translated into bits and mask values you can use in the database: SPELL_SCHOOL_NORMAL = bit 0 (0x00000001) SPELL_SCHOOL_HOLY = bit 1 (0x00000002) SPELL_SCHOOL_FIRE = bit 2 (0x00000004) SPELL_SCHOOL_NATURE = bit 3 (0x00000008) SPELL_SCHOOL_FROST = bit 4 (0x00000010) SPELL_SCHOOL_SHADOW = bit 5 (0x00000020) SPELL_SCHOOL_ARCANE = bit 6 (0x00000040) --- src/game/Object/Creature.cpp | 18 ++++++++++++++++-- src/game/Object/Creature.h | 2 ++ src/game/Object/Player.cpp | 2 +- src/game/Object/Unit.cpp | 8 ++++---- src/game/Object/Unit.h | 2 +- src/game/Server/SQLStorages.cpp | 4 ++-- src/game/WorldHandlers/Spell.cpp | 2 +- src/game/WorldHandlers/SpellAuras.cpp | 8 ++++---- src/shared/revision.h | 4 ++-- 9 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/game/Object/Creature.cpp b/src/game/Object/Creature.cpp index 1de8e17d..74d4cb29 100644 --- a/src/game/Object/Creature.cpp +++ b/src/game/Object/Creature.cpp @@ -1750,12 +1750,26 @@ bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf) if (!spellInfo) { return false; } - if (!castOnSelf && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) - { return true; } + if (!castOnSelf) + { + if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) + { return true; } + + if (GetCreatureInfo()->SchoolImmuneMask & (1 << spellInfo->School)) + { return true; } + } return Unit::IsImmuneToSpell(spellInfo, castOnSelf); } +bool Creature::IsImmuneToDamage(SpellSchoolMask meleeSchoolMask) +{ + if (GetCreatureInfo()->SchoolImmuneMask & meleeSchoolMask) + { return true; } + + return Unit::IsImmuneToDamage(meleeSchoolMask); +} + bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const { if (!castOnSelf && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1))) diff --git a/src/game/Object/Creature.h b/src/game/Object/Creature.h index 321a8484..45990190 100644 --- a/src/game/Object/Creature.h +++ b/src/game/Object/Creature.h @@ -129,6 +129,7 @@ struct CreatureInfo uint32 SkinningLootId; uint32 KillCredit[MAX_KILL_CREDIT]; uint32 MechanicImmuneMask; + uint32 SchoolImmuneMask; int32 ResistanceHoly; int32 ResistanceFire; int32 ResistanceNature; @@ -546,6 +547,7 @@ class Creature : public Unit void FillGuidsListFromThreatList(GuidVector& guids, uint32 maxamount = 0); bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf) override; + bool IsImmuneToDamage(SpellSchoolMask meleeSchoolMask) override; bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const override; bool IsElite() const diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index eb793c20..1db4c31e 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -19362,7 +19362,7 @@ void Player::HandleFall(MovementInfo const& movementInfo) // 14.57 can be calculated by resolving damageperc formula below to 0 if (z_diff >= 14.57f && !IsDead() && !isGameMaster() && !HasMovementFlag(MOVEFLAG_ONTRANSPORT) && !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) && - !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL)) + !IsImmuneToDamage(SPELL_SCHOOL_MASK_NORMAL)) { // Safe fall, fall height reduction int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); diff --git a/src/game/Object/Unit.cpp b/src/game/Object/Unit.cpp index a25acc62..05951df0 100644 --- a/src/game/Object/Unit.cpp +++ b/src/game/Object/Unit.cpp @@ -1505,7 +1505,7 @@ void Unit::CalculateMeleeDamage(Unit* pVictim, CalcDamageInfo* damageInfo, Weapo } // Physical Immune check - if (damageInfo->target->IsImmunedToDamage(damageInfo->damageSchoolMask)) + if (damageInfo->target->IsImmuneToDamage(damageInfo->damageSchoolMask)) { damageInfo->HitInfo |= HITINFO_NORMALSWING; damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE; @@ -2719,7 +2719,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* pVictim, SpellEntry const* spell, bool { return SPELL_MISS_NONE; } // Check for immune (use charges) - if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell)) && !spell->HasAttribute(SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)) + if (pVictim->IsImmuneToDamage(GetSpellSchoolMask(spell)) && !spell->HasAttribute(SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)) { return SPELL_MISS_IMMUNE; } // Try victim reflect spell @@ -6050,7 +6050,7 @@ int32 Unit::SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) return AdvertisedBenefit; } -bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask) +bool Unit::IsImmuneToDamage(SpellSchoolMask shoolMask) { // If m_immuneToSchool type contain this school type, IMMUNE damage. SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; @@ -7312,7 +7312,7 @@ bool Unit::IsSecondChoiceTarget(Unit* pTarget, bool checkThreatArea) MANGOS_ASSERT(pTarget && GetTypeId() == TYPEID_UNIT); return - pTarget->IsImmunedToDamage(GetMeleeDamageSchoolMask()) || + pTarget->IsImmuneToDamage(GetMeleeDamageSchoolMask()) || pTarget->hasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_DAMAGE) || (checkThreatArea && ((Creature*)this)->IsOutOfThreatArea(pTarget)); } diff --git a/src/game/Object/Unit.h b/src/game/Object/Unit.h index 5c727ed4..e4767135 100644 --- a/src/game/Object/Unit.h +++ b/src/game/Object/Unit.h @@ -3597,7 +3597,7 @@ class Unit : public WorldObject void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); void ApplySpellDispelImmunity(const SpellEntry* spellProto, DispelType type, bool apply); virtual bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf); - bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask); + virtual bool IsImmuneToDamage(SpellSchoolMask meleeSchoolMask); virtual bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const; uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage); diff --git a/src/game/Server/SQLStorages.cpp b/src/game/Server/SQLStorages.cpp index d9e8a291..a4bf0809 100644 --- a/src/game/Server/SQLStorages.cpp +++ b/src/game/Server/SQLStorages.cpp @@ -43,8 +43,8 @@ // DBC_FF_LOGIC = 'l' // Logical (boolean) // }; // -const char CreatureInfosrcfmt[] = "issiiiiiiiifiiiiliiiiiffiiffffffiiiiffffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; -const char CreatureInfodstfmt[] = "issiiiiiiiifiiiiliiiiiffiiffffffiiiiffffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; +const char CreatureInfosrcfmt[] = "issiiiiiiiifiiiiliiiiiffiiffffffiiiiffffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; +const char CreatureInfodstfmt[] = "issiiiiiiiifiiiiliiiiiffiiffffffiiiiffffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; const char CreatureDataAddonInfofmt[] = "iiibbiis"; const char CreatureModelfmt[] = "iffbii"; const char CreatureInfoAddonInfofmt[] = "iiibbiis"; diff --git a/src/game/WorldHandlers/Spell.cpp b/src/game/WorldHandlers/Spell.cpp index 2eb80081..42e610b7 100644 --- a/src/game/WorldHandlers/Spell.cpp +++ b/src/game/WorldHandlers/Spell.cpp @@ -1131,7 +1131,7 @@ void Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool isReflected) // Recheck immune (only for delayed spells) float speed = m_spellInfo->speed == 0.0f && m_triggeredBySpellInfo ? m_triggeredBySpellInfo->speed : m_spellInfo->speed; if (speed && ( - unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo)) || + unit->IsImmuneToDamage(GetSpellSchoolMask(m_spellInfo)) || unit->IsImmuneToSpell(m_spellInfo, unit == realCaster))) { if (realCaster) diff --git a/src/game/WorldHandlers/SpellAuras.cpp b/src/game/WorldHandlers/SpellAuras.cpp index 016cc18b..a56a97fa 100644 --- a/src/game/WorldHandlers/SpellAuras.cpp +++ b/src/game/WorldHandlers/SpellAuras.cpp @@ -4343,7 +4343,7 @@ void Aura::PeriodicTick() { return; } // Check for immune (not use charges) - if (target->IsImmunedToDamage(GetSpellSchoolMask(spellProto))) + if (target->IsImmuneToDamage(GetSpellSchoolMask(spellProto))) { return; } uint32 absorb = 0; @@ -4434,7 +4434,7 @@ void Aura::PeriodicTick() { return; } // Check for immune - if (target->IsImmunedToDamage(GetSpellSchoolMask(spellProto))) + if (target->IsImmuneToDamage(GetSpellSchoolMask(spellProto))) { return; } uint32 absorb = 0; @@ -4591,7 +4591,7 @@ void Aura::PeriodicTick() { return; } // Check for immune (not use charges) - if (target->IsImmunedToDamage(GetSpellSchoolMask(spellProto))) + if (target->IsImmuneToDamage(GetSpellSchoolMask(spellProto))) { return; } // ignore non positive values (can be result apply spellmods to aura damage @@ -4704,7 +4704,7 @@ void Aura::PeriodicTick() { return; } // Check for immune (not use charges) - if (target->IsImmunedToDamage(GetSpellSchoolMask(spellProto))) + if (target->IsImmuneToDamage(GetSpellSchoolMask(spellProto))) { return; } int32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; diff --git a/src/shared/revision.h b/src/shared/revision.h index 7fff5bb1..cae4a708 100644 --- a/src/shared/revision.h +++ b/src/shared/revision.h @@ -37,7 +37,7 @@ #define CHAR_DB_UPDATE_DESCRIPTION "Remove field from dbDocs" #define WORLD_DB_VERSION_NR 21 - #define WORLD_DB_STRUCTURE_NR 12 + #define WORLD_DB_STRUCTURE_NR 13 #define WORLD_DB_CONTENT_NR 1 - #define WORLD_DB_UPDATE_DESCRIPTION "AutoBroadcast" + #define WORLD_DB_UPDATE_DESCRIPTION "SchoolImmuneMask" #endif // __REVISION_H__