diff options
author | ariel- <ariel-@users.noreply.github.com> | 2018-03-12 02:31:17 -0300 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-09-06 20:05:37 +0200 |
commit | b2de3efb4b3e023874b6e28dd3a0a82b2c735ca8 (patch) | |
tree | 1da441d80ee8f876a3c4f15f1a4b6415c852e956 | |
parent | bb772416bfa7a6833931e1a0993523d49dc549b8 (diff) |
Core/Spells: Fix some issues with channeled spells and aura duration mods
Closes #21584
(cherry picked from commit ac976550632f17f5a3ec7eaae354f84faf2656e5)
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 87 |
3 files changed, 54 insertions, 47 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index a6959945d0d..bead326338d 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -842,23 +842,28 @@ void Aura::Update(uint32 diff, Unit* caster) int32 Aura::CalcMaxDuration(Unit* caster) const { + return Aura::CalcMaxDuration(GetSpellInfo(), caster); +} + +/*static*/ int32 Aura::CalcMaxDuration(SpellInfo const* spellInfo, WorldObject* caster) +{ Player* modOwner = nullptr; int32 maxDuration; if (caster) { modOwner = caster->GetSpellModOwner(); - maxDuration = caster->CalcSpellDuration(m_spellInfo); + maxDuration = caster->CalcSpellDuration(spellInfo); } else - maxDuration = m_spellInfo->GetDuration(); + maxDuration = spellInfo->GetDuration(); - if (IsPassive() && !m_spellInfo->DurationEntry) + if (spellInfo->IsPassive() && !spellInfo->DurationEntry) maxDuration = -1; // IsPermanent() checks max duration (which we are supposed to calculate here) if (maxDuration != -1 && modOwner) - modOwner->ApplySpellMod(GetSpellInfo(), SpellModOp::Duration, maxDuration); + modOwner->ApplySpellMod(spellInfo, SpellModOp::Duration, maxDuration); return maxDuration; } diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 189b65a7d1d..5a5fdc00544 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -168,6 +168,7 @@ class TC_GAME_API Aura void SetMaxDuration(int32 duration) { m_maxDuration = duration; } int32 CalcMaxDuration() const { return CalcMaxDuration(GetCaster()); } int32 CalcMaxDuration(Unit* caster) const; + static int32 CalcMaxDuration(SpellInfo const* spellInfo, WorldObject* caster); int32 GetDuration() const { return m_duration; } void SetDuration(int32 duration, bool withMods = false); void RefreshDuration(bool withMods = false); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index bc5f090bb38..a24bb14366d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2814,7 +2814,7 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, TargetInfo& hitInfo) } } - hitInfo.AuraDuration = m_spellInfo->GetMaxDuration(); + hitInfo.AuraDuration = Aura::CalcMaxDuration(m_spellInfo, origCaster); // unit is immune to aura if it was diminished to 0 duration if (!hitInfo.Positive && !unit->ApplyDiminishingToDuration(m_spellInfo, hitInfo.AuraDuration, origCaster, diminishLevel)) @@ -2852,54 +2852,53 @@ void Spell::DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo, .IsRefresh = &refresh; if (Aura* aura = Aura::TryRefreshStackOrCreate(createInfo)) - _spellAura = aura->ToUnitAura(); - } - else - _spellAura->AddStaticApplication(unit, aura_effmask); - - if (_spellAura) - { - // Set aura stack amount to desired value - if (m_spellValue->AuraStackAmount > 1) { - if (!refresh) - _spellAura->SetStackAmount(m_spellValue->AuraStackAmount); - else - _spellAura->ModStackAmount(m_spellValue->AuraStackAmount); - } + _spellAura = aura->ToUnitAura(); - _spellAura->SetDiminishGroup(hitInfo.DRGroup); + // Set aura stack amount to desired value + if (m_spellValue->AuraStackAmount > 1) + { + if (!refresh) + _spellAura->SetStackAmount(m_spellValue->AuraStackAmount); + else + _spellAura->ModStackAmount(m_spellValue->AuraStackAmount); + } - hitInfo.AuraDuration = caster->ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask()); + _spellAura->SetDiminishGroup(hitInfo.DRGroup); - if (hitInfo.AuraDuration > 0) - { - hitInfo.AuraDuration *= m_spellValue->DurationMul; + hitInfo.AuraDuration = caster->ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask()); - // Haste modifies duration of channeled spells - if (m_spellInfo->IsChanneled()) - caster->ModSpellDurationTime(m_spellInfo, hitInfo.AuraDuration, this); - else if (m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) + if (hitInfo.AuraDuration > 0) { - int32 origDuration = hitInfo.AuraDuration; - hitInfo.AuraDuration = 0; - for (AuraEffect const* auraEff : _spellAura->GetAuraEffects()) - if (auraEff) - if (int32 period = auraEff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED - hitInfo.AuraDuration = std::max(std::max(origDuration / period, 1) * period, hitInfo.AuraDuration); - - // if there is no periodic effect - if (!hitInfo.AuraDuration) - hitInfo.AuraDuration = int32(origDuration * m_originalCaster->m_unitData->ModCastingSpeed); + hitInfo.AuraDuration *= m_spellValue->DurationMul; + + // Haste modifies duration of channeled spells + if (m_spellInfo->IsChanneled()) + caster->ModSpellDurationTime(m_spellInfo, hitInfo.AuraDuration, this); + else if (m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) + { + int32 origDuration = hitInfo.AuraDuration; + hitInfo.AuraDuration = 0; + for (AuraEffect const* auraEff : _spellAura->GetAuraEffects()) + if (auraEff) + if (int32 period = auraEff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED + hitInfo.AuraDuration = std::max(std::max(origDuration / period, 1) * period, hitInfo.AuraDuration); + + // if there is no periodic effect + if (!hitInfo.AuraDuration) + hitInfo.AuraDuration = int32(origDuration * m_originalCaster->m_unitData->ModCastingSpeed); + } } - } - if (hitInfo.AuraDuration != _spellAura->GetMaxDuration()) - { - _spellAura->SetMaxDuration(hitInfo.AuraDuration); - _spellAura->SetDuration(hitInfo.AuraDuration); + if (hitInfo.AuraDuration != _spellAura->GetMaxDuration()) + { + _spellAura->SetMaxDuration(hitInfo.AuraDuration); + _spellAura->SetDuration(hitInfo.AuraDuration); + } } } + else + _spellAura->AddStaticApplication(unit, aura_effmask); } } @@ -3582,10 +3581,12 @@ void Spell::handle_immediate() else if (duration == -1) SendChannelStart(duration); - m_spellState = SPELL_STATE_CASTING; - - // GameObjects shouldn't cast channeled spells - ASSERT_NOTNULL(m_caster->ToUnit())->AddInterruptMask(m_spellInfo->ChannelInterruptFlags, m_spellInfo->ChannelInterruptFlags2); + if (duration != 0) + { + m_spellState = SPELL_STATE_CASTING; + // GameObjects shouldn't cast channeled spells + ASSERT_NOTNULL(m_caster->ToUnit())->AddInterruptMask(m_spellInfo->ChannelInterruptFlags, m_spellInfo->ChannelInterruptFlags2); + } } PrepareTargetProcessing(); |