aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-06-19 20:14:53 +0200
committerShauren <shauren.trinity@gmail.com>2024-06-19 20:14:53 +0200
commitc968dedfee59db53fc912ac166309f3d87470821 (patch)
tree040b523a5bed5e38c7447dadbad8b314ea6c6463 /src/server/game/Entities/Unit
parente54e3ed2040d0c21c3b05433269044568572cb7a (diff)
Core/Spells: Fixed implementation of SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS and removed banish special cases that were neccessary because that attribute wasn't correctly supported
Diffstat (limited to 'src/server/game/Entities/Unit')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp179
-rw-r--r--src/server/game/Entities/Unit/Unit.h8
2 files changed, 119 insertions, 68 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 7ffa74abba4..b02c7a5f130 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1584,7 +1584,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
}
// ...or immuned
- if (IsImmunedToDamage(spellInfo))
+ if (IsImmunedToDamage(this, spellInfo))
{
victim->SendSpellDamageImmune(this, spellInfo->Id, false);
continue;
@@ -7420,61 +7420,6 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
return advertisedBenefit;
}
-bool Unit::IsImmunedToDamage(SpellSchoolMask schoolMask) const
-{
- if (schoolMask == SPELL_SCHOOL_MASK_NONE)
- return false;
-
- // If m_immuneToSchool type contain this school type, IMMUNE damage.
- uint32 schoolImmunityMask = GetSchoolImmunityMask();
- if ((schoolImmunityMask & schoolMask) == schoolMask) // We need to be immune to all types
- return true;
-
- // If m_immuneToDamage type contain magic, IMMUNE damage.
- uint32 damageImmunityMask = GetDamageImmunityMask();
- if ((damageImmunityMask & schoolMask) == schoolMask) // We need to be immune to all types
- return true;
-
- return false;
-}
-
-bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo /*= nullptr*/) const
-{
- if (!spellInfo)
- return false;
-
- // for example 40175
- if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
- return false;
-
- if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
- return false;
-
- if (spellEffectInfo && spellEffectInfo->EffectAttributes.HasFlag(SpellEffectAttributes::NoImmunity))
- return false;
-
- if (uint32 schoolMask = spellInfo->GetSchoolMask())
- {
- // If m_immuneToSchool type contain this school type, IMMUNE damage.
- uint32 schoolImmunityMask = 0;
- SpellImmuneContainer const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
- for (auto itr = schoolList.begin(); itr != schoolList.end(); ++itr)
- if ((itr->first & schoolMask) && !spellInfo->CanPierceImmuneAura(sSpellMgr->GetSpellInfo(itr->second, GetMap()->GetDifficultyID())))
- schoolImmunityMask |= itr->first;
-
- // // We need to be immune to all types
- if ((schoolImmunityMask & schoolMask) == schoolMask)
- return true;
-
- // If m_immuneToDamage type contain magic, IMMUNE damage.
- uint32 damageImmunityMask = GetDamageImmunityMask();
- if ((damageImmunityMask & schoolMask) == schoolMask) // We need to be immune to all types
- return true;
- }
-
- return false;
-}
-
bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caster, bool requireImmunityPurgesEffectAttribute /*= false*/) const
{
if (!spellInfo)
@@ -7552,11 +7497,13 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caste
if (!immuneSpellInfo || !immuneSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
continue;
- // Consider the school immune if any of these conditions are not satisfied.
- // In case of no immuneSpellInfo, ignore that condition and check only the other conditions
- if ((immuneSpellInfo && !immuneSpellInfo->IsPositive()) || !spellInfo->IsPositive() || !caster || !IsFriendlyTo(caster))
- if (!spellInfo->CanPierceImmuneAura(immuneSpellInfo))
- schoolImmunityMask |= itr->first;
+ if (immuneSpellInfo && !immuneSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && caster && !caster->IsFriendlyTo(this))
+ continue;
+
+ if (spellInfo->CanPierceImmuneAura(immuneSpellInfo))
+ continue;
+
+ schoolImmunityMask |= itr->first;
}
if ((schoolImmunityMask & schoolMask) == schoolMask)
return true;
@@ -7605,6 +7552,68 @@ EnumFlag<SpellOtherImmunity> Unit::GetSpellOtherImmunityMask() const
return mask;
}
+bool Unit::IsImmunedToDamage(SpellSchoolMask schoolMask) const
+{
+ if (schoolMask == SPELL_SCHOOL_MASK_NONE)
+ return false;
+
+ // If m_immuneToSchool type contain this school type, IMMUNE damage.
+ uint32 schoolImmunityMask = GetSchoolImmunityMask();
+ if ((schoolImmunityMask & schoolMask) == schoolMask) // We need to be immune to all types
+ return true;
+
+ // If m_immuneToDamage type contain magic, IMMUNE damage.
+ uint32 damageImmunityMask = GetDamageImmunityMask();
+ if ((damageImmunityMask & schoolMask) == schoolMask) // We need to be immune to all types
+ return true;
+
+ return false;
+}
+
+bool Unit::IsImmunedToDamage(WorldObject const* caster, SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo /*= nullptr*/) const
+{
+ if (!spellInfo)
+ return false;
+
+ if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) || spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
+ return false;
+
+ if (spellEffectInfo && spellEffectInfo->EffectAttributes.HasFlag(SpellEffectAttributes::NoImmunity))
+ return false;
+
+ if (uint32 schoolMask = spellInfo->GetSchoolMask())
+ {
+ auto hasImmunity = [&](SpellImmuneContainer const& container)
+ {
+ uint32 schoolImmunityMask = 0;
+ for (auto&& [immunitySchoolMask, immunityAuraId] : container)
+ {
+ SpellInfo const* immuneAuraInfo = sSpellMgr->GetSpellInfo(immunityAuraId, GetMap()->GetDifficultyID());
+ if (immuneAuraInfo && !immuneAuraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && caster && caster->IsFriendlyTo(this))
+ continue;
+
+ if (immuneAuraInfo && spellInfo->CanPierceImmuneAura(immuneAuraInfo))
+ continue;
+
+ schoolImmunityMask |= immunitySchoolMask;
+ }
+
+ // // We need to be immune to all types
+ return (schoolImmunityMask & schoolMask) == schoolMask;
+ };
+
+ // If m_immuneToSchool type contain this school type, IMMUNE damage.
+ if (hasImmunity(m_spellImmune[IMMUNITY_SCHOOL]))
+ return true;
+
+ // If m_immuneToDamage type contain magic, IMMUNE damage.
+ if (hasImmunity(m_spellImmune[IMMUNITY_DAMAGE]))
+ return true;
+ }
+
+ return false;
+}
+
bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster,
bool requireImmunityPurgesEffectAttribute /*= false*/) const
{
@@ -7657,17 +7666,57 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo co
if (!spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
{
// Check for immune to application of harmful magical effects
- AuraEffectList const& immuneAuraApply = GetAuraEffectsByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
- for (AuraEffectList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
- if (((*iter)->GetMiscValue() & spellInfo->GetSchoolMask()) && // Check school
- ((caster && !IsFriendlyTo(caster)) || !spellInfo->IsPositiveEffect(spellEffectInfo.EffectIndex))) // Harmful
+ for (AuraEffect const* immuneAuraApply : GetAuraEffectsByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL))
+ {
+ if (!(immuneAuraApply->GetMiscValue() & spellInfo->GetSchoolMask())) // Check school
+ continue;
+
+ if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || (caster && !IsFriendlyTo(caster))) // Harmful
return true;
+ }
}
}
return false;
}
+bool Unit::IsImmunedToAuraPeriodicTick(WorldObject const* caster, SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo) const
+{
+ if (!spellInfo)
+ return false;
+
+ if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) || spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES) /*only school immunities are checked in this function*/)
+ return false;
+
+ if (spellEffectInfo && spellEffectInfo->EffectAttributes.HasFlag(SpellEffectAttributes::NoImmunity))
+ return false;
+
+ if (uint32 schoolMask = spellInfo->GetSchoolMask())
+ {
+ auto hasImmunity = [&](SpellImmuneContainer const& container)
+ {
+ uint32 schoolImmunityMask = 0;
+ for (auto&& [immunitySchoolMask, immunityAuraId] : container)
+ {
+ SpellInfo const* immuneAuraInfo = sSpellMgr->GetSpellInfo(immunityAuraId, GetMap()->GetDifficultyID());
+ if (immuneAuraInfo && !immuneAuraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && caster && caster->IsFriendlyTo(this))
+ continue;
+
+ schoolImmunityMask |= immunitySchoolMask;
+ }
+
+ // // We need to be immune to all types
+ return (schoolImmunityMask & schoolMask) == schoolMask;
+ };
+
+ // If m_immuneToSchool type contain this school type, IMMUNE damage.
+ if (hasImmunity(m_spellImmune[IMMUNITY_SCHOOL]))
+ return true;
+ }
+
+ return false;
+}
+
int32 Unit::MeleeDamageBonusDone(Unit* pVictim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, Mechanics mechanic /*= nullptr*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/)
{
if (!pVictim || damage == 0)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index a8c9c110a5e..c2ecd8d7c7d 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -266,7 +266,7 @@ enum UnitState : uint32
UNIT_STATE_ROOT = 0x00000400,
UNIT_STATE_CONFUSED = 0x00000800,
UNIT_STATE_DISTRACTED = 0x00001000,
- UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players
+ UNIT_STATE_ISOLATED_DEPRECATED = 0x00002000, // REUSE
UNIT_STATE_ATTACK_PLAYER = 0x00004000,
UNIT_STATE_CASTING = 0x00008000,
UNIT_STATE_POSSESSED = 0x00010000, // being possessed by another unit
@@ -286,7 +286,7 @@ enum UnitState : uint32
UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_CHARMED | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE
| UNIT_STATE_FOCUSING | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED
- | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING
+ | UNIT_STATE_DISTRACTED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING
| UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING
| UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE
| UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_FOLLOW_FORMATION_MOVE,
@@ -1638,9 +1638,11 @@ class TC_GAME_API Unit : public WorldObject
EnumFlag<SpellOtherImmunity> GetSpellOtherImmunityMask() const;
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const;
- bool IsImmunedToDamage(SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo = nullptr) const;
+ bool IsImmunedToDamage(WorldObject const* caster, SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo = nullptr) const;
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster, bool requireImmunityPurgesEffectAttribute = false) const;
+ bool IsImmunedToAuraPeriodicTick(WorldObject const* caster, SpellInfo const* spellInfo, SpellEffectInfo const* spellEffectInfo = nullptr) const;
+
static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr);
static uint32 CalcArmorReducedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK, uint8 attackerLevel = 0);
static uint32 CalcSpellResistedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo);