mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-21 07:22:02 -04:00
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
(cherry picked from commit c968dedfee)
This commit is contained in:
@@ -2676,7 +2676,7 @@ SpellMissInfo WorldObject::SpellHitResult(Unit* victim, SpellInfo const* spellIn
|
||||
|
||||
// Damage immunity is only checked if the spell has damage effects, this immunity must not prevent aura apply
|
||||
// returns SPELL_MISS_IMMUNE in that case, for other spells, the SMSG_SPELL_GO must show hit
|
||||
if (spellInfo->HasOnlyDamageEffects() && victim->IsImmunedToDamage(spellInfo))
|
||||
if (spellInfo->HasOnlyDamageEffects() && victim->IsImmunedToDamage(this, spellInfo))
|
||||
return SPELL_MISS_IMMUNE;
|
||||
|
||||
// All positive spells can`t miss
|
||||
|
||||
@@ -1585,7 +1585,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
||||
}
|
||||
|
||||
// ...or immuned
|
||||
if (IsImmunedToDamage(spellInfo))
|
||||
if (IsImmunedToDamage(this, spellInfo))
|
||||
{
|
||||
victim->SendSpellDamageImmune(this, spellInfo->Id, false);
|
||||
continue;
|
||||
@@ -7391,61 +7391,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)
|
||||
@@ -7523,11 +7468,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;
|
||||
@@ -7576,6 +7523,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
|
||||
{
|
||||
@@ -7628,17 +7637,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)
|
||||
|
||||
@@ -268,7 +268,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
|
||||
@@ -288,7 +288,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,
|
||||
@@ -1617,9 +1617,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);
|
||||
|
||||
@@ -482,7 +482,7 @@ enum SpellAttr1 : uint32
|
||||
SPELL_ATTR1_TOGGLE_FAR_SIGHT = 0x00002000, // TITLE Toggle Far Sight (client only)
|
||||
SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL = 0x00004000, // TITLE Track Target in Channel DESCRIPTION While channeling, adjust facing to face target
|
||||
SPELL_ATTR1_IMMUNITY_PURGES_EFFECT = 0x00008000, // TITLE Immunity Purges Effect DESCRIPTION For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied
|
||||
SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS = 0x00010000, /*WRONG IMPL*/ // TITLE Immunity to Hostile & Friendly Effects DESCRIPTION Will not pierce Divine Shield, Ice Block and other full invulnerabilities
|
||||
SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS = 0x00010000, // TITLE Immunity to Hostile & Friendly Effects DESCRIPTION Immunity applied by this aura will also be checked for friendly spells (school immunity only) - used by Cyclone for example to cause friendly spells and healing over time to be immuned
|
||||
SPELL_ATTR1_NO_AUTOCAST_AI = 0x00020000, // TITLE No AutoCast (AI)
|
||||
SPELL_ATTR1_PREVENTS_ANIM = 0x00040000, /*NYI*/ // TITLE Prevents Anim DESCRIPTION Auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT
|
||||
SPELL_ATTR1_EXCLUDE_CASTER = 0x00080000, // TITLE Exclude Caster
|
||||
@@ -2567,7 +2567,7 @@ enum AuraStateType
|
||||
AURA_STATE_MARKED = 5, // C t| NYI
|
||||
AURA_STATE_WOUNDED_25_PERCENT = 6, // T |
|
||||
AURA_STATE_DEFENSIVE_2 = 7, // Cc | NYI
|
||||
AURA_STATE_BANISHED = 8, // c | NYI
|
||||
AURA_STATE_BANISHED = 8, // c |
|
||||
AURA_STATE_DAZED = 9, // t|
|
||||
AURA_STATE_VICTORIOUS = 10, // C |
|
||||
AURA_STATE_RAMPAGE = 11, // | NYI
|
||||
|
||||
@@ -422,7 +422,7 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr1>::ToString(SpellAttr1 value)
|
||||
case SPELL_ATTR1_TOGGLE_FAR_SIGHT: return { "SPELL_ATTR1_TOGGLE_FAR_SIGHT", "Toggle Far Sight (client only)", "" };
|
||||
case SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL: return { "SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL", "Track Target in Channel", "While channeling, adjust facing to face target" };
|
||||
case SPELL_ATTR1_IMMUNITY_PURGES_EFFECT: return { "SPELL_ATTR1_IMMUNITY_PURGES_EFFECT", "Immunity Purges Effect", "For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied" };
|
||||
case SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS: return { "SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS", "Immunity to Hostile & Friendly Effects", "Will not pierce Divine Shield, Ice Block and other full invulnerabilities" };
|
||||
case SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS: return { "SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS", "Immunity to Hostile & Friendly Effects", "Immunity applied by this aura will also be checked for friendly spells (school immunity only) - used by Cyclone for example to cause friendly spells and healing over time to be immuned" };
|
||||
case SPELL_ATTR1_NO_AUTOCAST_AI: return { "SPELL_ATTR1_NO_AUTOCAST_AI", "No AutoCast (AI)", "" };
|
||||
case SPELL_ATTR1_PREVENTS_ANIM: return { "SPELL_ATTR1_PREVENTS_ANIM", "Prevents Anim", "Auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT" };
|
||||
case SPELL_ATTR1_EXCLUDE_CASTER: return { "SPELL_ATTR1_EXCLUDE_CASTER", "Exclude Caster", "" };
|
||||
@@ -3219,7 +3219,7 @@ TC_API_EXPORT EnumText EnumUtils<AuraStateType>::ToString(AuraStateType value)
|
||||
case AURA_STATE_MARKED: return { "AURA_STATE_MARKED", "AURA_STATE_MARKED", "C t| NYI" };
|
||||
case AURA_STATE_WOUNDED_25_PERCENT: return { "AURA_STATE_WOUNDED_25_PERCENT", "AURA_STATE_WOUNDED_25_PERCENT", "T |" };
|
||||
case AURA_STATE_DEFENSIVE_2: return { "AURA_STATE_DEFENSIVE_2", "AURA_STATE_DEFENSIVE_2", "Cc | NYI" };
|
||||
case AURA_STATE_BANISHED: return { "AURA_STATE_BANISHED", "AURA_STATE_BANISHED", "c | NYI" };
|
||||
case AURA_STATE_BANISHED: return { "AURA_STATE_BANISHED", "AURA_STATE_BANISHED", "c |" };
|
||||
case AURA_STATE_DAZED: return { "AURA_STATE_DAZED", "AURA_STATE_DAZED", "t|" };
|
||||
case AURA_STATE_VICTORIOUS: return { "AURA_STATE_VICTORIOUS", "AURA_STATE_VICTORIOUS", "C |" };
|
||||
case AURA_STATE_RAMPAGE: return { "AURA_STATE_RAMPAGE", "AURA_STATE_RAMPAGE", "| NYI" };
|
||||
|
||||
@@ -3447,28 +3447,6 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint
|
||||
Unit* target = aurApp->GetTarget();
|
||||
m_spellInfo->ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
|
||||
if (GetSpellInfo()->Mechanic == MECHANIC_BANISH)
|
||||
{
|
||||
if (apply)
|
||||
target->AddUnitState(UNIT_STATE_ISOLATED);
|
||||
else
|
||||
{
|
||||
bool banishFound = false;
|
||||
Unit::AuraEffectList const& banishAuras = target->GetAuraEffectsByType(GetAuraType());
|
||||
for (AuraEffect const* aurEff : banishAuras)
|
||||
{
|
||||
if (aurEff->GetSpellInfo()->Mechanic == MECHANIC_BANISH)
|
||||
{
|
||||
banishFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!banishFound)
|
||||
target->ClearUnitState(UNIT_STATE_ISOLATED);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: should be changed to a proc script on flag spell (they have "Taken positive" proc flags in db2)
|
||||
{
|
||||
if (apply && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
|
||||
@@ -5501,7 +5479,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
|
||||
if (!target->IsAlive())
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
if (target->IsImmunedToDamage(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5636,7 +5614,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
|
||||
if (!target->IsAlive())
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
if (target->IsImmunedToDamage(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5735,7 +5713,7 @@ void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster)
|
||||
if (!caster || !caster->IsAlive() || !target->IsAlive())
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
if (target->IsImmunedToAuraPeriodicTick(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5765,7 +5743,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
|
||||
if (!target->IsAlive())
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
if (target->IsImmunedToAuraPeriodicTick(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5825,7 +5803,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
|
||||
if (!caster || !caster->IsAlive() || !target->IsAlive() || target->GetPowerType() != powerType)
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
if (target->IsImmunedToAuraPeriodicTick(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5888,7 +5866,7 @@ void AuraEffect::HandleObsModPowerAuraTick(Unit* target, Unit* caster) const
|
||||
if (!target->IsAlive() || !target->GetMaxPower(powerType))
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
if (target->IsImmunedToAuraPeriodicTick(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5918,7 +5896,7 @@ void AuraEffect::HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) cons
|
||||
if (!target->IsAlive() || !target->GetMaxPower(powerType))
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
if (target->IsImmunedToAuraPeriodicTick(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -5950,7 +5928,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
|
||||
if (!caster || !target->IsAlive() || target->GetPowerType() != powerType)
|
||||
return;
|
||||
|
||||
if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
if (target->IsImmunedToDamage(caster, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(target, caster);
|
||||
return;
|
||||
@@ -6078,7 +6056,7 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv
|
||||
{
|
||||
Unit* target = aurApp->GetTarget();
|
||||
Unit* triggerTarget = eventInfo.GetProcTarget();
|
||||
if (triggerTarget->HasUnitState(UNIT_STATE_ISOLATED) || triggerTarget->IsImmunedToDamage(GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
if (triggerTarget->IsImmunedToDamage(target, GetSpellInfo(), &GetSpellEffectInfo()))
|
||||
{
|
||||
SendTickImmune(triggerTarget, target);
|
||||
return;
|
||||
|
||||
@@ -2542,7 +2542,7 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
|
||||
if (!GetUnitOwner()->IsInWorld())
|
||||
continue;
|
||||
|
||||
if (GetUnitOwner()->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
if (GetUnitOwner()->HasAuraState(AURA_STATE_BANISHED, GetSpellInfo(), caster))
|
||||
continue;
|
||||
|
||||
std::vector<WorldObject*> units;
|
||||
|
||||
@@ -2917,7 +2917,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
|
||||
// Fill base damage struct (unitTarget - is real spell target)
|
||||
SpellNonMeleeDamage damageInfo(caster, spell->unitTarget, spell->m_spellInfo, spell->m_SpellVisual, spell->m_spellSchoolMask, spell->m_castId);
|
||||
// Check damage immunity
|
||||
if (spell->unitTarget->IsImmunedToDamage(spell->m_spellInfo))
|
||||
if (spell->unitTarget->IsImmunedToDamage(caster, spell->m_spellInfo))
|
||||
{
|
||||
hitMask = PROC_HIT_IMMUNE;
|
||||
spell->m_damage = 0;
|
||||
|
||||
@@ -1821,24 +1821,6 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const
|
||||
|
||||
bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
|
||||
{
|
||||
// aura can't be pierced
|
||||
if (!auraSpellInfo || auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
return false;
|
||||
|
||||
// these spells pierce all available spells (Resurrection Sickness for example)
|
||||
if (HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
return true;
|
||||
|
||||
// these spells (Cyclone for example) can pierce all...
|
||||
if (HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
|
||||
{
|
||||
// ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
|
||||
if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD &&
|
||||
auraSpellInfo->Mechanic != MECHANIC_INVULNERABILITY &&
|
||||
(auraSpellInfo->Mechanic != MECHANIC_BANISH || (IsRankOf(auraSpellInfo) && auraSpellInfo->Dispel != DISPEL_NONE))) // Banish shouldn't be immune to itself, but Cyclone should
|
||||
return true;
|
||||
}
|
||||
|
||||
// Dispels other auras on immunity, check if this spell makes the unit immune to aura
|
||||
if (HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT) && CanSpellProvideImmunityAgainstAura(auraSpellInfo))
|
||||
return true;
|
||||
@@ -1852,15 +1834,6 @@ bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const
|
||||
if (auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
return false;
|
||||
|
||||
// These spells (like Mass Dispel) can dispel all auras
|
||||
if (HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
return true;
|
||||
|
||||
// These auras (Cyclone for example) are not dispelable
|
||||
if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && auraSpellInfo->Mechanic != MECHANIC_NONE)
|
||||
|| auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3494,14 +3467,24 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s
|
||||
|
||||
if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
{
|
||||
target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
|
||||
target->RemoveAppliedAuras([this, target, schoolImmunity](AuraApplication const* aurApp) -> bool
|
||||
{
|
||||
SpellInfo const* auraSpellInfo = aurApp->GetBase()->GetSpellInfo();
|
||||
return ((auraSpellInfo->GetSchoolMask() & schoolImmunity) != 0 && // Check for school mask
|
||||
CanDispelAura(auraSpellInfo) &&
|
||||
(IsPositive() != aurApp->IsPositive()) && // Check spell vs aura possitivity
|
||||
!auraSpellInfo->IsPassive() && // Don't remove passive auras
|
||||
auraSpellInfo->Id != Id); // Don't remove self
|
||||
if (auraSpellInfo->Id == Id) // Don't remove self
|
||||
return false;
|
||||
if (auraSpellInfo->IsPassive()) // Don't remove passive auras
|
||||
return false;
|
||||
if (!(auraSpellInfo->GetSchoolMask() & schoolImmunity)) // Check for school mask
|
||||
return false;
|
||||
if (!CanDispelAura(auraSpellInfo))
|
||||
return false;
|
||||
if (!HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
|
||||
{
|
||||
WorldObject const* existingAuraCaster = aurApp->GetBase()->GetWorldObjectCaster();
|
||||
if (existingAuraCaster && existingAuraCaster->IsFriendlyTo(target)) // Check spell vs aura possitivity
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3570,10 +3553,9 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s
|
||||
{
|
||||
target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
|
||||
if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
target->RemoveAurasByType(auraType, [](AuraApplication const* aurApp) -> bool
|
||||
target->RemoveAurasByType(auraType, [this](AuraApplication const* aurApp) -> bool
|
||||
{
|
||||
// if the aura has SPELL_ATTR0_NO_IMMUNITIES, then it cannot be removed by immunity
|
||||
return !aurApp->GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES);
|
||||
return CanDispelAura(aurApp->GetBase()->GetSpellInfo());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3598,7 +3580,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
|
||||
if (!immuneInfo)
|
||||
continue;
|
||||
|
||||
if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
|
||||
if (!auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
|
||||
{
|
||||
if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
|
||||
if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
|
||||
|
||||
@@ -1048,7 +1048,7 @@ class spell_sindragosa_s_fury : public SpellScript
|
||||
if (!GetHitUnit()->IsAlive() || !_targetCount)
|
||||
return;
|
||||
|
||||
if (GetHitUnit()->IsImmunedToDamage(GetSpellInfo(), &GetEffectInfo()))
|
||||
if (GetHitUnit()->IsImmunedToDamage(GetCaster(), GetSpellInfo(), &GetEffectInfo()))
|
||||
{
|
||||
GetCaster()->SendSpellDamageImmune(GetHitUnit(), GetSpellInfo()->Id, false);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user