aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp10
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h1
-rw-r--r--src/server/game/Spells/Spell.cpp28
-rw-r--r--src/server/game/Spells/SpellInfo.cpp17
-rw-r--r--src/server/game/Spells/SpellMgr.cpp6
-rw-r--r--src/server/game/Spells/SpellMgr.h13
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;