diff options
| author | Shauren <shauren.trinity@gmail.com> | 2022-04-28 18:31:26 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-04-28 18:31:26 +0200 |
| commit | dda375b9868d6dbe2a4d58b386bb90ae41d25e0d (patch) | |
| tree | 9a4a55dd37d787b1384ed55ba99be0cc92cfa2e2 /src/server/game/Entities/Unit | |
| parent | c88b602a2c7eda598a4205dd0ec9f562c31f21b0 (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.cpp | 99 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 |
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); |
