mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-29 13:22:48 +01:00
Core/Spells: Fix some issues with channeled spells and aura duration mods
Closes #21584
(cherry picked from commit ac97655063)
This commit is contained in:
@@ -841,6 +841,11 @@ 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;
|
||||
@@ -848,17 +853,17 @@ int32 Aura::CalcMaxDuration(Unit* caster) const
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
// 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->SetDiminishGroup(hitInfo.DRGroup);
|
||||
|
||||
hitInfo.AuraDuration = caster->ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask());
|
||||
|
||||
if (hitInfo.AuraDuration > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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->SetDiminishGroup(hitInfo.DRGroup);
|
||||
|
||||
hitInfo.AuraDuration = caster->ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask());
|
||||
|
||||
if (hitInfo.AuraDuration > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user