diff options
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 28 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 13 |
7 files changed, 52 insertions, 25 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 7ca7718fe39..74297bc5fb4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7522,6 +7522,16 @@ uint64 Unit::GetMechanicImmunityMask() const return mask; } +EnumFlag<SpellOtherImmunity> Unit::GetSpellOtherImmunityMask() const +{ + SpellOtherImmunity mask = { }; + SpellImmuneContainer const& damageList = m_spellImmune[IMMUNITY_OTHER]; + for (auto itr = damageList.begin(); itr != damageList.end(); ++itr) + mask |= SpellOtherImmunity(itr->first); + + return mask; +} + bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster, bool requireImmunityPurgesEffectAttribute /*= false*/) const { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 7e177193a9b..558c750f04f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -102,6 +102,7 @@ enum MovementGeneratorType : uint8; enum ProcFlagsHit : uint32; enum ProcFlagsSpellPhase : uint32; enum ProcFlagsSpellType : uint32; +enum class SpellOtherImmunity : uint8; enum ZLiquidStatus : uint32; namespace Movement @@ -1611,6 +1612,7 @@ class TC_GAME_API Unit : public WorldObject uint32 GetSchoolImmunityMask() const; uint32 GetDamageImmunityMask() const; uint64 GetMechanicImmunityMask() const; + EnumFlag<SpellOtherImmunity> GetSpellOtherImmunityMask() const; bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const; bool IsImmunedToDamage(SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo = nullptr) const; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 2ff3a7c77b5..43663f3e0f5 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -2618,6 +2618,7 @@ enum SpellImmunity IMMUNITY_DISPEL = 4, // enum DispelType IMMUNITY_MECHANIC = 5, // enum Mechanics IMMUNITY_ID = 6, + IMMUNITY_OTHER = 7, // enum SpellOtherImmunity MAX_SPELL_IMMUNITY }; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 6bbea868124..2aed9e672b8 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -9217,24 +9217,20 @@ bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target) const if (!isInsideCylinder) return false; - if (Creature* creatureTarget = target->ToCreature()) + if (Unit* unitTarget = target->ToUnit()) { - if (CreatureImmunities const* immunities = SpellMgr::GetCreatureImmunities(creatureTarget->GetCreatureTemplate()->CreatureImmunitiesId)) + switch (_searchReason) { - switch (_searchReason) - { - case WorldObjectSpellAreaTargetSearchReason::Area: - if (immunities->ImmuneAoE) - return false; - break; - case WorldObjectSpellAreaTargetSearchReason::Chain: - if (immunities->ImmuneChain) - return false; - break; - default: - break; - } - + case WorldObjectSpellAreaTargetSearchReason::Area: + if (unitTarget->GetSpellOtherImmunityMask().HasFlag(SpellOtherImmunity::AoETarget)) + return false; + break; + case WorldObjectSpellAreaTargetSearchReason::Chain: + if (unitTarget->GetSpellOtherImmunityMask().HasFlag(SpellOtherImmunity::ChainTarget)) + return false; + break; + default: + break; } } } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 7a365207d4b..6f86e41ac45 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -233,6 +233,7 @@ struct SpellEffectInfo::ImmunityInfo uint64 MechanicImmuneMask = 0; uint32 DispelImmuneMask = 0; uint32 DamageSchoolMask = 0; + uint8 OtherImmuneMask = 0; Trinity::Containers::FlatSet<AuraType> AuraTypeImmune; Trinity::Containers::FlatSet<SpellEffectName> SpellEffectImmune; @@ -2250,6 +2251,10 @@ SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject co if (HasAttribute(SPELL_ATTR8_ONLY_TARGET_OWN_SUMMONS)) if (!unitTarget->IsSummon() || unitTarget->ToTempSummon()->GetSummonerGUID() != caster->GetGUID()) return SPELL_FAILED_BAD_TARGETS; + + if (HasAttribute(SPELL_ATTR3_NOT_ON_AOE_IMMUNE)) + if (unitTarget->GetSpellOtherImmunityMask().HasFlag(SpellOtherImmunity::AoETarget)) + return SPELL_FAILED_BAD_TARGETS; } // corpse specific target checks else if (Corpse const* corpseTarget = target->ToCorpse()) @@ -2275,11 +2280,6 @@ SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject co if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && unitTarget->IsControlledByPlayer()) return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED; - - if (HasAttribute(SPELL_ATTR3_NOT_ON_AOE_IMMUNE)) - if (CreatureImmunities const* immunities = SpellMgr::GetCreatureImmunities(unitTarget->ToCreature()->GetCreatureTemplate()->CreatureImmunitiesId)) - if (immunities->ImmuneAoE) - return SPELL_FAILED_BAD_TARGETS; } else if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER)) return SPELL_FAILED_TARGET_IS_PLAYER; @@ -3316,6 +3316,7 @@ void SpellInfo::_LoadImmunityInfo() uint64 mechanicImmunityMask = 0; uint32 dispelImmunityMask = 0; uint32 damageImmunityMask = 0; + uint8 otherImmunityMask = 0; int32 miscVal = effect.MiscValue; @@ -3330,6 +3331,7 @@ void SpellInfo::_LoadImmunityInfo() schoolImmunityMask |= creatureImmunities->School.to_ulong(); dispelImmunityMask |= creatureImmunities->DispelType.to_ulong(); mechanicImmunityMask |= creatureImmunities->Mechanic.to_ullong(); + otherImmunityMask |= creatureImmunities->Other.AsUnderlyingType(); for (SpellEffectName effectType : creatureImmunities->Effect) immuneInfo.SpellEffectImmune.insert(effectType); for (AuraType aura : creatureImmunities->Aura) @@ -3408,6 +3410,7 @@ void SpellInfo::_LoadImmunityInfo() immuneInfo.MechanicImmuneMask = mechanicImmunityMask; immuneInfo.DispelImmuneMask = dispelImmunityMask; immuneInfo.DamageSchoolMask = damageImmunityMask; + immuneInfo.OtherImmuneMask = otherImmunityMask; immuneInfo.AuraTypeImmune.shrink_to_fit(); immuneInfo.SpellEffectImmune.shrink_to_fit(); @@ -3417,6 +3420,7 @@ void SpellInfo::_LoadImmunityInfo() || immuneInfo.MechanicImmuneMask || immuneInfo.DispelImmuneMask || immuneInfo.DamageSchoolMask + || immuneInfo.OtherImmuneMask || !immuneInfo.AuraTypeImmune.empty() || !immuneInfo.SpellEffectImmune.empty()) { @@ -3597,6 +3601,9 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s for (SpellEffectName effectType : immuneInfo->SpellEffectImmune) target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply); + + if (uint8 otherImmuneMask = immuneInfo->OtherImmuneMask) + target->ApplySpellImmune(Id, IMMUNITY_OTHER, otherImmuneMask, apply); } bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInfo) const diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 16b010ba2eb..fe31c6e00ea 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4957,8 +4957,10 @@ void SpellMgr::LoadSpellInfoImmunities() immunities.School = school; immunities.DispelType = dispelType; immunities.Mechanic = mechanics; - immunities.ImmuneAoE = fields[6].GetBool(); - immunities.ImmuneChain = fields[7].GetBool(); + if (fields[6].GetBool()) + immunities.Other |= SpellOtherImmunity::AoETarget; + if (fields[7].GetBool()) + immunities.Other |= SpellOtherImmunity::ChainTarget; if (immunities.School.to_ullong() != school) TC_LOG_ERROR("sql.sql", "Invalid value in `SchoolMask` {} for creature immunities {}, truncated", school, id); diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 95f67f2cdaa..e9097afffd6 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -23,6 +23,7 @@ #include "Define.h" #include "DBCEnums.h" #include "Duration.h" +#include "EnumFlag.h" #include "Errors.h" #include "FlagsArray.h" #include "Hash.h" @@ -594,6 +595,15 @@ struct SpellLearnSpellNode bool AutoLearned; // This marks the spell as automatically learned from another source that - will only be used for unlearning }; +enum class SpellOtherImmunity : uint8 +{ + None = 0x0, + AoETarget = 0x1, + ChainTarget = 0x2 +}; + +DEFINE_ENUM_FLAG(SpellOtherImmunity) + struct CreatureImmunities { std::bitset<MAX_SPELL_SCHOOL> School; @@ -601,8 +611,7 @@ struct CreatureImmunities std::bitset<MAX_MECHANIC> Mechanic; std::vector<SpellEffectName> Effect; std::vector<AuraType> Aura; - bool ImmuneAoE = false; // NYI - bool ImmuneChain = false; // NYI + EnumFlag<SpellOtherImmunity> Other = SpellOtherImmunity::None; }; typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap; |