diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index f33073ff65..13d03e9bb6 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -901,11 +901,11 @@ void Aura::SetDuration(int32 duration, bool withMods) SetNeedClientUpdateForTargets(); } -void Aura::RefreshDuration() +void Aura::RefreshDuration(bool resetPeriodicTimer /*= true*/) { - SetDuration(GetMaxDuration()); + SetDuration(GetMaxDuration() + (resetPeriodicTimer ? 0 : CalcRolledOverDuration())); - if (m_spellInfo->ManaPerSecond) + if (resetPeriodicTimer && m_spellInfo->ManaPerSecond) m_timeCla = 1 * IN_MILLISECONDS; // also reset periodic counters @@ -916,25 +916,16 @@ void Aura::RefreshDuration() void Aura::RefreshTimers(bool resetPeriodicTimer) { + // Recalculate the maximum duration m_maxDuration = CalcMaxDuration(); + // Roll over remaining time until the next tick from previous aura timers if (!resetPeriodicTimer) - { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* aurEff = GetEffect(i)) - { - if (int32 period = aurEff->GetPeriod()) - { - m_rolledOverDuration = period - aurEff->GetPeriodicTimer(); - // For now we only check for a single periodic effect since we don't have enough data regarding multiple periodic effects - break; - } - } - } - } + m_rolledOverDuration = CalcRolledOverDuration(); + else + m_rolledOverDuration = 0; - RefreshDuration(); + RefreshDuration(resetPeriodicTimer); Unit* caster = GetCaster(); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -942,6 +933,16 @@ void Aura::RefreshTimers(bool resetPeriodicTimer) aurEff->CalculatePeriodic(caster, resetPeriodicTimer, false); } +int32 Aura::CalcRolledOverDuration() const +{ + // For now we only check for a single periodic effect since we don't have enough data regarding multiple periodic effects + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (AuraEffect const* aurEff = GetEffect(i)) + if (int32 period = aurEff->GetPeriod()) + return (period - aurEff->GetPeriodicTimer()); + return 0; +} + void Aura::SetCharges(uint8 charges) { if (m_procCharges == charges) diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index ee8b5703af..4c9ea10228 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -153,11 +153,14 @@ class TC_GAME_API Aura static int32 CalcMaxDuration(SpellInfo const* spellInfo, WorldObject* caster); int32 GetDuration() const { return m_duration; } void SetDuration(int32 duration, bool withMods = false); - void RefreshDuration(); + // Resets the duration and tick number of the aura and rolls over a remaining tick if specified. Use this method if a talent or spell is suposed to refresh an aura. + void RefreshDuration(bool resetPeriodicTimer = true); + // Used to refresh the entire aura duration and timers. Do NOT use this for refreshing durations via spells and talents. Use Aura::RefreshDuration instead. void RefreshTimers(bool resetPeriodicTimer); bool IsExpired() const { return !GetDuration() && !m_dropEvent; } bool IsPermanent() const { return GetMaxDuration() == -1; } int32 GetRolledOverDuration() const { return m_rolledOverDuration; } + int32 CalcRolledOverDuration() const; uint8 GetCharges() const { return m_procCharges; } void SetCharges(uint8 charges); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index d7988820d3..5e5b2160cc 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -699,9 +699,9 @@ void AuraScript::SetDuration(int32 duration, bool withMods) m_aura->SetDuration(duration, withMods); } -void AuraScript::RefreshDuration() +void AuraScript::RefreshDuration(bool resetPeriodicTimer /*= true*/) { - m_aura->RefreshDuration(); + m_aura->RefreshDuration(resetPeriodicTimer); } time_t AuraScript::GetApplyTime() const diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index ad846ca67e..ea3040d186 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -1059,7 +1059,7 @@ class TC_GAME_API AuraScript : public _SpellScript int32 GetDuration() const; void SetDuration(int32 duration, bool withMods = false); // sets duration to maxduration - void RefreshDuration(); + void RefreshDuration(bool resetPeriodicTimer = true); time_t GetApplyTime() const; int32 GetMaxDuration() const; void SetMaxDuration(int32 duration);