Core/Spells: Fixed spells with SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS ignoring permanently rooted creatures (with static flags)
Signed-off-by: luis <[email protected]>
This commit is contained in:
@@ -769,26 +769,32 @@ bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag
|
|||||||
|
|
||||||
bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const
|
bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const
|
||||||
{
|
{
|
||||||
AuraEffectList const& auras = GetAuraEffectsByType(type);
|
for (AuraEffect const* aura : GetAuraEffectsByType(type))
|
||||||
for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
if ((!excludeAura || excludeAura != aura->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
|
||||||
if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
|
aura->GetSpellInfo()->HasAuraInterruptFlag(SpellAuraInterruptFlags::AnyDamageMask))
|
||||||
(*itr)->GetSpellInfo()->HasAuraInterruptFlag(SpellAuraInterruptFlags::Damage))
|
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) const
|
bool Unit::HasBreakableByDamageCrowdControlAura(Unit const* excludeCasterChannel) const
|
||||||
{
|
{
|
||||||
uint32 excludeAura = 0;
|
if (!HasInterruptFlag(SpellAuraInterruptFlags::AnyDamageMask))
|
||||||
if (Spell* currentChanneledSpell = excludeCasterChannel ? excludeCasterChannel->GetCurrentSpell(CURRENT_CHANNELED_SPELL) : nullptr)
|
return false;
|
||||||
excludeAura = currentChanneledSpell->GetSpellInfo()->Id; //Avoid self interrupt of channeled Crowd Control spells like Seduction
|
|
||||||
|
|
||||||
return ( HasBreakableByDamageAuraType(SPELL_AURA_MOD_CONFUSE, excludeAura)
|
uint32 excludeAura = 0;
|
||||||
|| HasBreakableByDamageAuraType(SPELL_AURA_MOD_FEAR, excludeAura)
|
if (excludeCasterChannel)
|
||||||
|| HasBreakableByDamageAuraType(SPELL_AURA_MOD_STUN, excludeAura)
|
if (Spell const* currentChanneledSpell = excludeCasterChannel->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||||
|| HasBreakableByDamageAuraType(SPELL_AURA_MOD_ROOT, excludeAura)
|
excludeAura = currentChanneledSpell->GetSpellInfo()->Id; //Avoid self interrupt of channeled Crowd Control spells like Seduction
|
||||||
|| HasBreakableByDamageAuraType(SPELL_AURA_MOD_ROOT_2, excludeAura)
|
|
||||||
|| HasBreakableByDamageAuraType(SPELL_AURA_TRANSFORM, excludeAura));
|
// This function is named after spell attribute it is meant for - SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS
|
||||||
|
// Not checking aura type is not a mistake here
|
||||||
|
for (AuraApplication const* aurApp : m_interruptableAuras)
|
||||||
|
if (!aurApp->IsPositive()
|
||||||
|
&& (!excludeAura || excludeAura != aurApp->GetBase()->GetId())
|
||||||
|
&& aurApp->GetBase()->GetSpellInfo()->HasAuraInterruptFlag(SpellAuraInterruptFlags::AnyDamageMask))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void Unit::DealDamageMods(Unit const* attacker, Unit const* victim, uint32& damage, uint32* absorb)
|
/*static*/ void Unit::DealDamageMods(Unit const* attacker, Unit const* victim, uint32& damage, uint32* absorb)
|
||||||
|
|||||||
@@ -1084,7 +1084,7 @@ class TC_GAME_API Unit : public WorldObject
|
|||||||
bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag128 familyFlags) const;
|
bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag128 familyFlags) const;
|
||||||
bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
|
bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
|
||||||
bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura = 0) const;
|
bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura = 0) const;
|
||||||
bool HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel = nullptr) const;
|
bool HasBreakableByDamageCrowdControlAura(Unit const* excludeCasterChannel = nullptr) const;
|
||||||
|
|
||||||
bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
|
bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
|
||||||
bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); }
|
bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); }
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ enum class SpellAuraInterruptFlags : uint32
|
|||||||
Summon = 0x40000000,
|
Summon = 0x40000000,
|
||||||
LeavingCombat = 0x80000000,
|
LeavingCombat = 0x80000000,
|
||||||
|
|
||||||
NOT_VICTIM = (HostileActionReceived | Damage | NonPeriodicDamage)
|
NOT_VICTIM = HostileActionReceived | Damage | NonPeriodicDamage,
|
||||||
|
AnyDamageMask = Damage | NonPeriodicDamage | DamageCancelsScript
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_ENUM_FLAG(SpellAuraInterruptFlags);
|
DEFINE_ENUM_FLAG(SpellAuraInterruptFlags);
|
||||||
|
|||||||
@@ -2418,7 +2418,7 @@ SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject co
|
|||||||
return SPELL_FAILED_TARGETS_DEAD;
|
return SPELL_FAILED_TARGETS_DEAD;
|
||||||
|
|
||||||
// check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
|
// check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
|
||||||
if (implicit && HasAttribute(SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS) && !unitTarget->CanFreeMove())
|
if (implicit && HasAttribute(SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS) && unitTarget->HasBreakableByDamageCrowdControlAura())
|
||||||
return SPELL_FAILED_BAD_TARGETS;
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
|
||||||
// checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
|
// checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
|
||||||
|
|||||||
Reference in New Issue
Block a user