aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-04-28 18:31:26 +0200
committerShauren <shauren.trinity@gmail.com>2022-04-28 18:31:26 +0200
commitdda375b9868d6dbe2a4d58b386bb90ae41d25e0d (patch)
tree9a4a55dd37d787b1384ed55ba99be0cc92cfa2e2 /src/server/game/Entities/Unit
parentc88b602a2c7eda598a4205dd0ec9f562c31f21b0 (diff)
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
Diffstat (limited to 'src/server/game/Entities/Unit')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp99
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
2 files changed, 65 insertions, 36 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 332ac0e21f1..65e78d8cff9 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -759,10 +759,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);
if (!damage && damagetype != DOT && cleanDamage && cleanDamage->absorbed_damage)
if (victim != attacker && victim->GetTypeId() == TYPEID_PLAYER)
@@ -956,7 +956,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)
{
@@ -2950,7 +2950,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;
}
}
@@ -2958,7 +2958,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
@@ -3921,19 +3921,38 @@ void Unit::RemoveNotOwnSingleTargetAuras(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->CanCastSpellWhileMoving(spellInfo);
+ switch (flag)
+ {
+ case SpellAuraInterruptFlags::Moving:
+ return unit->CanCastSpellWhileMoving(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;
@@ -3944,8 +3963,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, AURA_REMOVE_BY_INTERRUPT);
@@ -3958,15 +3977,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);
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, flag128 const& familyFlag, ObjectGuid casterGUID)
{
@@ -7169,7 +7188,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())
@@ -7321,7 +7340,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo co
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);
@@ -9805,30 +9824,44 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg
{
TimePoint now = GameTime::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()))
+ {
+ 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()))
+ aurApp->GetBase()->AddProcCooldown(procEntry, now);
+ }
+ };
+
// use provided list of auras which can proc
if (procAuras)
{
for (AuraApplication* aurApp : *procAuras)
{
ASSERT(aurApp->GetTarget() == this);
- if (uint32 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 (uint32 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);
}
}
@@ -9878,12 +9911,8 @@ void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProc
if (disableProcs)
SetCantProc(true);
- for (auto const& aurAppProc : aurasTriggeringProc)
+ for (auto const& [procEffectMask, aurApp] : aurasTriggeringProc)
{
- AuraApplication* aurApp;
- uint32 procEffectMask;
- std::tie(procEffectMask, aurApp) = aurAppProc;
-
if (aurApp->GetRemoveMode())
continue;
@@ -11563,7 +11592,7 @@ Aura* Unit::AddAura(SpellInfo const* spellInfo, uint32 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))
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index b1dc82c6421..1a19d0d1fde 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1382,7 +1382,7 @@ class TC_GAME_API Unit : public WorldObject
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = nullptr, bool negative = true, bool positive = true);
void RemoveNotOwnSingleTargetAuras(bool onPhaseChange = false);
template <typename InterruptFlags>
- void RemoveAurasWithInterruptFlags(InterruptFlags flag, uint32 except = 0);
+ void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const* source = nullptr);
void RemoveAurasWithAttribute(uint32 flags);
void RemoveAurasWithFamily(SpellFamilyNames family, flag128 const& familyFlag, ObjectGuid casterGUID);
void RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode = AURA_REMOVE_BY_DEFAULT, uint32 except = 0);