diff options
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 102 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 36 |
3 files changed, 103 insertions, 49 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index eb6ffc3012b..f420d1debd3 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3118,7 +3118,7 @@ void AuraEffect::HandleModMechanicImmunityMask(AuraApplication const* aurApp, ui return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); } void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -3127,7 +3127,7 @@ void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); } void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -3136,7 +3136,7 @@ void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const* aurApp, uint return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); // when removing flag aura, handle flag drop Player* player = target->ToPlayer(); @@ -3158,7 +3158,7 @@ void AuraEffect::HandleAuraModStateImmunity(AuraApplication const* aurApp, uint8 return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); } void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -3167,7 +3167,7 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); if (GetSpellInfo()->Mechanic == MECHANIC_BANISH) { @@ -3219,7 +3219,7 @@ void AuraEffect::HandleAuraModDmgImmunity(AuraApplication const* aurApp, uint8 m return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); if (apply) { @@ -3241,7 +3241,7 @@ void AuraEffect::HandleAuraModDispelImmunity(AuraApplication const* aurApp, uint return; Unit* target = aurApp->GetTarget(); - m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetEffIndex(), apply); + m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply); } /*********************************************************/ diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 38347a1bae5..dd3c8ede288 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -30,6 +30,7 @@ #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "Vehicle.h" +#include <boost/container/flat_set.hpp> uint32 GetTargetFlagMask(SpellTargetObjectTypes objType) { @@ -211,6 +212,26 @@ uint32 SpellImplicitTargetInfo::GetExplicitTargetMask(bool& srcSet, bool& dstSet return targetMask; } +struct SpellEffectInfo::ImmunityInfo +{ + ImmunityInfo() = default; + ~ImmunityInfo() = default; + + ImmunityInfo(ImmunityInfo const&) = delete; + ImmunityInfo(ImmunityInfo&&) noexcept = delete; + ImmunityInfo& operator=(ImmunityInfo const&) = delete; + ImmunityInfo& operator=(ImmunityInfo&&) noexcept = delete; + + uint32 SchoolImmuneMask = 0; + uint32 ApplyHarmfulAuraImmuneMask = 0; + uint32 MechanicImmuneMask = 0; + uint32 DispelImmune = 0; + uint32 DamageSchoolMask = 0; + + boost::container::flat_set<AuraType> AuraTypeImmune; + boost::container::flat_set<SpellEffects> SpellEffectImmune; +}; + std::array<SpellImplicitTargetInfo::StaticData, TOTAL_SPELL_TARGETS> SpellImplicitTargetInfo::_data = { { {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // @@ -326,6 +347,13 @@ std::array<SpellImplicitTargetInfo::StaticData, TOTAL_SPELL_TARGETS> SpellImplic {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 110 TARGET_UNIT_CONE_ENTRY_110 } }; +SpellEffectInfo::SpellEffectInfo() : _spellInfo(nullptr), EffectIndex(EFFECT_0), Effect(SPELL_EFFECT_NONE), ApplyAuraName(SPELL_AURA_NONE), + Amplitude(0), DieSides(0), RealPointsPerLevel(0), BasePoints(0), PointsPerComboPoint(0), ValueMultiplier(0), DamageMultiplier(0), + BonusMultiplier(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(nullptr), ChainTarget(0), ItemType(0), + TriggerSpell(0), ImplicitTargetConditions(nullptr), _immunityInfo(nullptr) +{ +} + SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex) { _spellInfo = spellInfo; @@ -351,6 +379,17 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* TriggerSpell = spellEntry->EffectTriggerSpell[effIndex]; SpellClassMask = spellEntry->EffectSpellClassMask[effIndex]; ImplicitTargetConditions = nullptr; + _immunityInfo = nullptr; +} + +SpellEffectInfo::SpellEffectInfo(SpellEffectInfo const&) = default; +SpellEffectInfo::SpellEffectInfo(SpellEffectInfo&&) noexcept = default; +SpellEffectInfo& SpellEffectInfo::operator=(SpellEffectInfo const&) = default; +SpellEffectInfo& SpellEffectInfo::operator=(SpellEffectInfo&&) noexcept = default; + +SpellEffectInfo::~SpellEffectInfo() +{ + delete _immunityInfo; } bool SpellEffectInfo::IsEffect() const @@ -2545,6 +2584,8 @@ int32 SpellInfo::GetDiminishingReturnsLimitDuration(bool triggered) const void SpellInfo::_LoadImmunityInfo() { + std::unique_ptr<SpellEffectInfo::ImmunityInfo> workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>(); + for (SpellEffectInfo& effect : _GetEffects()) { uint32 schoolImmunityMask = 0; @@ -2556,7 +2597,7 @@ void SpellInfo::_LoadImmunityInfo() int32 miscVal = effect.MiscValue; int32 amount = effect.CalcValue(); - ImmunityInfo& immuneInfo = _immunityInfo[effect.EffectIndex]; + SpellEffectInfo::ImmunityInfo& immuneInfo = *workBuffer; switch (effect.ApplyAuraName) { @@ -2736,7 +2777,7 @@ void SpellInfo::_LoadImmunityInfo() break; default: if (miscVal < 1) - continue; + break; mechanicImmunityMask |= 1 << miscVal; break; @@ -2786,6 +2827,18 @@ void SpellInfo::_LoadImmunityInfo() immuneInfo.AuraTypeImmune.shrink_to_fit(); immuneInfo.SpellEffectImmune.shrink_to_fit(); + if (immuneInfo.SchoolImmuneMask + || immuneInfo.ApplyHarmfulAuraImmuneMask + || immuneInfo.MechanicImmuneMask + || immuneInfo.DispelImmune + || immuneInfo.DamageSchoolMask + || !immuneInfo.AuraTypeImmune.empty() + || !immuneInfo.SpellEffectImmune.empty()) + { + effect._immunityInfo = workBuffer.release(); + workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>(); + } + _allowedMechanicMask |= immuneInfo.MechanicImmuneMask; } @@ -2827,11 +2880,13 @@ void SpellInfo::_LoadImmunityInfo() } } -void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool apply) const +void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const { - ImmunityInfo const& immuneInfo = _immunityInfo[effIndex]; + SpellEffectInfo::ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo(); + if (!immuneInfo) + return; - if (uint32 schoolImmunity = immuneInfo.SchoolImmuneMask) + if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask) { target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply); @@ -2849,7 +2904,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app } } - if (uint32 mechanicImmunity = immuneInfo.MechanicImmuneMask) + if (uint32 mechanicImmunity = immuneInfo->MechanicImmuneMask) { for (uint32 i = 0; i < MAX_MECHANIC; ++i) if (mechanicImmunity & (1 << i)) @@ -2878,7 +2933,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app } } - if (uint32 dispelImmunity = immuneInfo.DispelImmune) + if (uint32 dispelImmunity = immuneInfo->DispelImmune) { target->ApplySpellImmune(Id, IMMUNITY_DISPEL, dispelImmunity, apply); @@ -2895,10 +2950,10 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app } } - if (uint32 damageImmunity = immuneInfo.DamageSchoolMask) + if (uint32 damageImmunity = immuneInfo->DamageSchoolMask) target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply); - for (AuraType auraType : immuneInfo.AuraTypeImmune) + for (AuraType auraType : immuneInfo->AuraTypeImmune) { target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply); if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) @@ -2909,7 +2964,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app }); } - for (SpellEffects effectType : immuneInfo.SpellEffectImmune) + for (SpellEffects effectType : immuneInfo->SpellEffectImmune) target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply); } @@ -2918,20 +2973,27 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf if (!auraSpellInfo) return false; - for (ImmunityInfo const& immuneInfo : _immunityInfo) + for (SpellEffectInfo const& effectInfo : _effects) { + if (!effectInfo.IsEffect()) + continue; + + SpellEffectInfo::ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo(); + if (!immuneInfo) + continue; + if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) { - if (uint32 schoolImmunity = immuneInfo.SchoolImmuneMask) + if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask) if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0) return true; } - if (uint32 mechanicImmunity = immuneInfo.MechanicImmuneMask) + if (uint32 mechanicImmunity = immuneInfo->MechanicImmuneMask) if ((mechanicImmunity & (1 << auraSpellInfo->Mechanic)) != 0) return true; - if (uint32 dispelImmunity = immuneInfo.DispelImmune) + if (uint32 dispelImmunity = immuneInfo->DispelImmune) if (auraSpellInfo->Dispel == dispelImmunity) return true; @@ -2941,8 +3003,8 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf if (!auraSpellEffectInfo.IsEffect()) continue; - auto spellImmuneItr = immuneInfo.SpellEffectImmune.find(auraSpellEffectInfo.Effect); - if (spellImmuneItr == immuneInfo.SpellEffectImmune.cend()) + auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(auraSpellEffectInfo.Effect); + if (spellImmuneItr == immuneInfo->SpellEffectImmune.cend()) { immuneToAllEffects = false; break; @@ -2950,7 +3012,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf if (uint32 mechanic = auraSpellEffectInfo.Mechanic) { - if (!(immuneInfo.MechanicImmuneMask & (1 << mechanic))) + if (!(immuneInfo->MechanicImmuneMask & (1 << mechanic))) { immuneToAllEffects = false; break; @@ -2962,13 +3024,13 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName) { bool isImmuneToAuraEffectApply = false; - auto auraImmuneItr = immuneInfo.AuraTypeImmune.find(auraName); - if (auraImmuneItr != immuneInfo.AuraTypeImmune.cend()) + auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(auraName); + if (auraImmuneItr != immuneInfo->AuraTypeImmune.cend()) isImmuneToAuraEffectApply = true; if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) { - if (uint32 applyHarmfulAuraImmunityMask = immuneInfo.ApplyHarmfulAuraImmuneMask) + if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask) if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0) isImmuneToAuraEffectApply = true; } diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 51d34e2d443..426c067317a 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -24,8 +24,6 @@ #include "Object.h" #include "SpellAuraDefines.h" -#include <boost/container/flat_set.hpp> - class AuraEffect; class Item; class Player; @@ -208,6 +206,7 @@ private: class TC_GAME_API SpellEffectInfo { + friend class SpellInfo; SpellInfo const* _spellInfo; public: SpellEffIndex EffectIndex; @@ -233,11 +232,13 @@ public: flag96 SpellClassMask; std::vector<Condition*>* ImplicitTargetConditions; - SpellEffectInfo() : _spellInfo(nullptr), EffectIndex(EFFECT_0), Effect(SPELL_EFFECT_NONE), ApplyAuraName(SPELL_AURA_NONE), Amplitude(0), DieSides(0), - RealPointsPerLevel(0), BasePoints(0), PointsPerComboPoint(0), ValueMultiplier(0), DamageMultiplier(0), - BonusMultiplier(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(nullptr), ChainTarget(0), - ItemType(0), TriggerSpell(0), ImplicitTargetConditions(nullptr) {} - SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex); + SpellEffectInfo(); + explicit SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex); + SpellEffectInfo(SpellEffectInfo const&); + SpellEffectInfo(SpellEffectInfo&&) noexcept; + SpellEffectInfo& operator=(SpellEffectInfo const&); + SpellEffectInfo& operator=(SpellEffectInfo&&) noexcept; + ~SpellEffectInfo(); bool IsEffect() const; bool IsEffect(SpellEffects effectName) const; @@ -261,6 +262,9 @@ public: SpellEffectImplicitTargetTypes GetImplicitTargetType() const; SpellTargetObjectTypes GetUsedTargetObjectType() const; + struct ImmunityInfo; + ImmunityInfo const* GetImmunityInfo() const { return _immunityInfo; } + private: struct StaticData { @@ -268,6 +272,8 @@ private: SpellTargetObjectTypes UsedTargetObjectType; // defines valid target object type for spell effect }; static std::array<StaticData, TOTAL_SPELL_EFFECTS> _data; + + ImmunityInfo* _immunityInfo; }; struct TC_GAME_API SpellDiminishInfo @@ -278,18 +284,6 @@ struct TC_GAME_API SpellDiminishInfo int32 DiminishDurationLimit = 0; }; -struct TC_GAME_API ImmunityInfo -{ - uint32 SchoolImmuneMask = 0; - uint32 ApplyHarmfulAuraImmuneMask = 0; - uint32 MechanicImmuneMask = 0; - uint32 DispelImmune = 0; - uint32 DamageSchoolMask = 0; - - boost::container::flat_set<AuraType> AuraTypeImmune; - boost::container::flat_set<SpellEffects> SpellEffectImmune; -}; - class TC_GAME_API SpellInfo { friend class SpellMgr; @@ -498,7 +492,7 @@ class TC_GAME_API SpellInfo int32 GetDiminishingReturnsLimitDuration(bool triggered) const; // spell immunities - void ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool apply) const; + void ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const; bool CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInfo) const; bool SpellCancelsAuraEffect(AuraEffect const* aurEff) const; @@ -528,8 +522,6 @@ class TC_GAME_API SpellInfo SpellDiminishInfo _diminishInfoTriggered; uint32 _allowedMechanicMask; - - std::array<ImmunityInfo, MAX_SPELL_EFFECTS> _immunityInfo; }; #endif // _SPELLINFO_H |