aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-03-12 02:31:17 -0300
committerShauren <shauren.trinity@gmail.com>2021-09-06 20:05:37 +0200
commitb2de3efb4b3e023874b6e28dd3a0a82b2c735ca8 (patch)
tree1da441d80ee8f876a3c4f15f1a4b6415c852e956
parentbb772416bfa7a6833931e1a0993523d49dc549b8 (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.cpp13
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h1
-rw-r--r--src/server/game/Spells/Spell.cpp87
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();