fix(Core/Spells): Fix channeled CAST→HIT proc ordering and hasted DynObject duration (#24948)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com> Co-authored-by: TrinityCore <TrinityCore@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
-- Arcane Blast debuff: spell_proc override to consume at CAST phase via family masks (AM/AE/ABarr only)
|
||||||
|
UPDATE `spell_proc` SET `ProcFlags`=69632, `SpellFamilyMask0`=6144, `SpellFamilyMask1`=32768, `SpellFamilyMask2`=0, `SpellPhaseMask`=1, `Charges`=1 WHERE `SpellId`=36032;
|
||||||
@@ -2354,7 +2354,20 @@ void Aura::ConsumeProcCharges(SpellProcEntry const* procEntry)
|
|||||||
else if (IsUsingCharges())
|
else if (IsUsingCharges())
|
||||||
{
|
{
|
||||||
if (!GetCharges())
|
if (!GetCharges())
|
||||||
|
{
|
||||||
|
// Defer removal while spell mods are being consumed,
|
||||||
|
// cleaned up in Spell::_cast() after handle_immediate()
|
||||||
|
if (GetType() == UNIT_AURA_TYPE
|
||||||
|
&& (HasEffectType(SPELL_AURA_ADD_FLAT_MODIFIER)
|
||||||
|
|| HasEffectType(SPELL_AURA_ADD_PCT_MODIFIER)))
|
||||||
|
{
|
||||||
|
if (Player* player = GetUnitOwner()->ToPlayer())
|
||||||
|
if (player->m_spellModTakingSpell)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Remove();
|
Remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3956,11 +3956,8 @@ void Spell::_cast(bool skipCheck)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// CAST phase procs for non-channeled immediate spells
|
// CAST phase procs for immediate spells (including channeled)
|
||||||
// (channeled spells handle this below to preserve spell mods)
|
if (m_originalCaster)
|
||||||
// Note: triggered spells are allowed here; per-aura filtering via
|
|
||||||
// PROC_ATTR_TRIGGERED_CAN_PROC in SpellAuras.cpp handles rejection.
|
|
||||||
if (!m_spellInfo->IsChanneled() && m_originalCaster)
|
|
||||||
{
|
{
|
||||||
uint32 procAttacker = m_procAttacker;
|
uint32 procAttacker = m_procAttacker;
|
||||||
if (!procAttacker)
|
if (!procAttacker)
|
||||||
@@ -3996,6 +3993,31 @@ void Spell::_cast(bool skipCheck)
|
|||||||
|
|
||||||
// Immediate spell, no big deal
|
// Immediate spell, no big deal
|
||||||
handle_immediate();
|
handle_immediate();
|
||||||
|
|
||||||
|
// Clean up deferred 0-charge spell modifier auras
|
||||||
|
for (Aura* aura : m_appliedMods)
|
||||||
|
{
|
||||||
|
if (!aura->IsRemoved() && aura->IsUsingCharges()
|
||||||
|
&& !aura->GetCharges())
|
||||||
|
aura->Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also clean up deferred modifier auras not in m_appliedMods
|
||||||
|
if (Unit* caster = m_caster)
|
||||||
|
{
|
||||||
|
std::vector<Aura*> deferred;
|
||||||
|
for (auto const& [id, aura] : caster->GetOwnedAuras())
|
||||||
|
{
|
||||||
|
if (!aura->IsRemoved() && aura->IsUsingCharges()
|
||||||
|
&& !aura->GetCharges()
|
||||||
|
&& (aura->HasEffectType(SPELL_AURA_ADD_FLAT_MODIFIER)
|
||||||
|
|| aura->HasEffectType(SPELL_AURA_ADD_PCT_MODIFIER)))
|
||||||
|
deferred.push_back(aura);
|
||||||
|
}
|
||||||
|
for (Aura* aura : deferred)
|
||||||
|
if (!aura->IsRemoved())
|
||||||
|
aura->Remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resetAttackTimers)
|
if (resetAttackTimers)
|
||||||
@@ -4023,10 +4045,8 @@ void Spell::_cast(bool skipCheck)
|
|||||||
if (modOwner)
|
if (modOwner)
|
||||||
modOwner->SetSpellModTakingSpell(this, false);
|
modOwner->SetSpellModTakingSpell(this, false);
|
||||||
|
|
||||||
// CAST phase procs for delayed and channeled spells
|
// CAST phase procs for delayed spells
|
||||||
// Note: triggered spells are allowed here; per-aura filtering via
|
if (m_spellState == SPELL_STATE_DELAYED
|
||||||
// PROC_ATTR_TRIGGERED_CAN_PROC in SpellAuras.cpp handles rejection.
|
|
||||||
if ((m_spellState == SPELL_STATE_DELAYED || m_spellInfo->IsChanneled())
|
|
||||||
&& m_originalCaster)
|
&& m_originalCaster)
|
||||||
{
|
{
|
||||||
uint32 procAttacker = m_procAttacker;
|
uint32 procAttacker = m_procAttacker;
|
||||||
@@ -4138,6 +4158,14 @@ void Spell::handle_immediate()
|
|||||||
// process immediate effects (items, ground, etc.) also initialize some variables
|
// process immediate effects (items, ground, etc.) also initialize some variables
|
||||||
_handle_immediate_phase();
|
_handle_immediate_phase();
|
||||||
|
|
||||||
|
// Sync persistent area aura duration with hasted channel duration
|
||||||
|
if (m_spellInfo->IsChanneled() && m_spellAura && m_channeledDuration > 0
|
||||||
|
&& m_spellAura->GetType() == DYNOBJ_AURA_TYPE)
|
||||||
|
{
|
||||||
|
m_spellAura->SetMaxDuration(m_channeledDuration);
|
||||||
|
m_spellAura->SetDuration(m_channeledDuration);
|
||||||
|
}
|
||||||
|
|
||||||
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||||
DoAllEffectOnTarget(&(*ihit));
|
DoAllEffectOnTarget(&(*ihit));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user