Core/Spells: Rename SpellAttr2 to use official attribute names

* Corrected implementation of SPELL_ATTR1_ALLOW_WHILE_STEALTHED
* Implemented SPELL_ATTR2_RETAIN_ITEM_CAST
* Implemented SPELL_ATTR2_ALLOW_WHILE_INVISIBLE
* Implemented SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE
* Implemented SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE
* Implemented SPELL_ATTR2_NO_TARGET_PER_SECOND_COSTS
* Implemented SPELL_ATTR2_DO_NOT_REPORT_SPELL_FAILURE
* Implemented SPELL_ATTR1_REQUIRE_ALL_TARGETS
* Implemented SPELL_ATTR2_CHAIN_FROM_CASTER
* Implemented SPELL_ATTR2_NO_ACTIVE_PETS
* Implemented SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY
This commit is contained in:
Shauren authored and Ovahlord committed 2022-09-13 14:36:32 +02:00
1 parent 6224558c8c
commit ea4bc6c02a
15 files changed
+282 -175

No files matched your search

+64 -36
View File
@@ -786,10 +786,10 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
if (spellProto)
{
if (!spellProto->HasAttribute(SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS))
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Damage, spellProto->Id);
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Damage, spellProto);
}
else
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Damage, 0);
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Damage);
// We're going to call functions which can modify content of the list during iteration over it's elements
// Let's copy the list so we can prevent iterator invalidation
@@ -923,7 +923,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
victim->ModifyHealth(-(int32)damage);
if (damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::NonPeriodicDamage, spellProto ? spellProto->Id : 0);
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::NonPeriodicDamage, spellProto);
if (victim->GetTypeId() != TYPEID_PLAYER)
{
@@ -2880,7 +2880,7 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu
{
if (!skipInstant || m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime())
{
if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)))
if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)))
return true;
}
}
@@ -2888,7 +2888,7 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu
if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
(m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED))
{
if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS)))
if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)))
return true;
}
// autorepeat spells may be finished or delayed, but they are still considered cast
@@ -3829,19 +3829,37 @@ void Unit::RemoveNotOwnLimitedTargetAuras(bool onPhaseChange /*= false*/)
}
template<typename InterruptFlag>
bool IsInterruptFlagIgnoredForSpell(InterruptFlag /*flag*/, Unit const* /*unit*/, SpellInfo const* /*spellInfo*/)
bool IsInterruptFlagIgnoredForSpell(InterruptFlag /*flag*/, Unit const* /*unit*/, SpellInfo const* /*auraSpellInfo*/, SpellInfo const* /*interruptSource*/)
{
return false;
}
template<>
bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit const* unit, SpellInfo const* spellInfo)
bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit const* unit, SpellInfo const* auraSpellInfo, SpellInfo const* interruptSource)
{
return flag == SpellAuraInterruptFlags::Moving && unit->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, spellInfo);
switch (flag)
{
case SpellAuraInterruptFlags::Moving:
return unit->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, auraSpellInfo);
case SpellAuraInterruptFlags::Action:
case SpellAuraInterruptFlags::ActionDelayed:
if (interruptSource)
{
if (interruptSource->HasAttribute(SPELL_ATTR1_ALLOW_WHILE_STEALTHED) && auraSpellInfo->HasAura(SPELL_AURA_MOD_STEALTH))
return true;
if (interruptSource->HasAttribute(SPELL_ATTR2_ALLOW_WHILE_INVISIBLE) && auraSpellInfo->HasAura(SPELL_AURA_MOD_INVISIBILITY))
return true;
}
break;
default:
break;
}
return false;
}
template <typename InterruptFlags>
void Unit::RemoveAurasWithInterruptFlags(InterruptFlags flag, uint32 except)
void Unit::RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const* source)
{
if (!HasInterruptFlag(flag))
return;
@@ -3852,8 +3870,8 @@ void Unit::RemoveAurasWithInterruptFlags(InterruptFlags flag, uint32 except)
Aura* aura = (*iter)->GetBase();
++iter;
if (aura->GetSpellInfo()->HasAuraInterruptFlag(flag)
&& (!except || aura->GetId() != except)
&& !IsInterruptFlagIgnoredForSpell(flag, this, aura->GetSpellInfo()))
&& (!source || aura->GetId() != source->Id)
&& !IsInterruptFlagIgnoredForSpell(flag, this, aura->GetSpellInfo(), source))
{
uint32 removedAuras = m_removedAurasCount;
RemoveAura(aura);
@@ -3866,15 +3884,15 @@ void Unit::RemoveAurasWithInterruptFlags(InterruptFlags flag, uint32 except)
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() == SPELL_STATE_CASTING
&& spell->GetSpellInfo()->HasChannelInterruptFlag(flag)
&& spell->GetSpellInfo()->Id != except
&& !IsInterruptFlagIgnoredForSpell(flag, this, spell->GetSpellInfo()))
&& (!source || spell->GetSpellInfo()->Id != source->Id)
&& !IsInterruptFlagIgnoredForSpell(flag, this, spell->GetSpellInfo(), source))
InterruptNonMeleeSpells(false, 0, true);
UpdateInterruptMask();
}
template TC_GAME_API void Unit::RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags flag, uint32 except);
template TC_GAME_API void Unit::RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2 flag, uint32 except);
template TC_GAME_API void Unit::RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags flag, SpellInfo const* source);
template TC_GAME_API void Unit::RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2 flag, SpellInfo const* source);
void Unit::RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID)
{
@@ -7324,7 +7342,7 @@ bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) const
if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT))
return false;
if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || spellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || spellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
return false;
if (uint32 schoolMask = spellInfo->GetSchoolMask())
@@ -7478,7 +7496,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Worl
if (list.count(aura) > 0)
return true;
if (!spellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
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);
@@ -10099,30 +10117,44 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg
{
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
auto processAuraApplication = [&](AuraApplication* aurApp)
{
if (uint32 procEffectMask = aurApp->GetBase()->GetProcEffectMask(aurApp, eventInfo, now))
{
aurApp->GetBase()->PrepareProcToTrigger(aurApp, eventInfo, now);
aurasTriggeringProc.emplace_back(procEffectMask, aurApp);
}
else
{
if (aurApp->GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE))
{
if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(aurApp->GetBase()->GetSpellInfo()->Id))
{
aurApp->GetBase()->PrepareProcChargeDrop(procEntry, eventInfo);
aurApp->GetBase()->ConsumeProcCharges(procEntry);
}
}
if (aurApp->GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR2_PROC_COOLDOWN_ON_FAILURE))
if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(aurApp->GetBase()->GetSpellInfo()->Id))
aurApp->GetBase()->AddProcCooldown(procEntry, now);
}
};
// use provided list of auras which can proc
if (procAuras)
{
for (AuraApplication* aurApp : *procAuras)
{
ASSERT(aurApp->GetTarget() == this);
if (uint8 procEffectMask = aurApp->GetBase()->GetProcEffectMask(aurApp, eventInfo, now))
{
aurApp->GetBase()->PrepareProcToTrigger(aurApp, eventInfo, now);
aurasTriggeringProc.emplace_back(procEffectMask, aurApp);
}
processAuraApplication(aurApp);
}
}
// or generate one on our own
else
{
for (AuraApplicationMap::iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr)
{
if (uint8 procEffectMask = itr->second->GetBase()->GetProcEffectMask(itr->second, eventInfo, now))
{
itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo, now);
aurasTriggeringProc.emplace_back(procEffectMask, itr->second);
}
}
processAuraApplication(itr->second);
}
}
@@ -10169,12 +10201,8 @@ void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProc
if (disableProcs)
SetCantProc(true);
for (auto const& aurAppProc : aurasTriggeringProc)
for (auto const& [procEffectMask, aurApp] : aurasTriggeringProc)
{
AuraApplication* aurApp;
uint8 procEffectMask;
std::tie(procEffectMask, aurApp) = aurAppProc;
if (aurApp->GetRemoveMode().HasAnyFlag())
continue;
@@ -11934,7 +11962,7 @@ Aura* Unit::AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target)
if (!spellInfo)
return nullptr;
if (!target->IsAlive() && !spellInfo->IsPassive() && !spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD))
if (!target->IsAlive() && !spellInfo->IsPassive() && !spellInfo->HasAttribute(SPELL_ATTR2_ALLOW_DEAD_TARGET))
return nullptr;
if (target->IsImmunedToSpell(spellInfo, this))