aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp51
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.cpp22
4 files changed, 49 insertions, 30 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index ac51952c4aa..84f7ace72e1 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -498,15 +498,28 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
return amount;
}
+uint32 AuraEffect::GetTotalTicks() const
+{
+ uint32 totalTicks = 0;
+ if (_amplitude && !GetBase()->IsPermanent())
+ {
+ totalTicks = static_cast<uint32>(GetBase()->GetMaxDuration() / _amplitude);
+ if (m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
+ ++totalTicks;
+ }
+
+ return totalTicks;
+}
+
void AuraEffect::ResetPeriodic(bool resetPeriodicTimer /*= false*/)
{
_ticksDone = 0;
if (resetPeriodicTimer)
{
- _periodicTimer = _amplitude;
+ _periodicTimer = 0;
// Start periodic on next tick or at aura apply
- if (!m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
- _periodicTimer = 0;
+ if (m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
+ _periodicTimer = _amplitude;
}
}
@@ -759,27 +772,29 @@ void AuraEffect::ApplySpellMod(Unit* target, bool apply)
void AuraEffect::Update(uint32 diff, Unit* caster)
{
- if (m_isPeriodic && (GetBase()->GetDuration() >= 0 || GetBase()->IsPassive() || GetBase()->IsPermanent()))
+ if (!m_isPeriodic || (GetBase()->GetDuration() < 0 && !GetBase()->IsPassive() && !GetBase()->IsPermanent()))
+ return;
+
+ uint32 totalTicks = GetTotalTicks();
+
+ _periodicTimer += diff;
+ while (_periodicTimer >= _amplitude)
{
- _periodicTimer += diff;
- while (_periodicTimer >= _amplitude)
- {
- _periodicTimer -= _amplitude;
+ _periodicTimer -= _amplitude;
- if (!GetBase()->IsPermanent() && (_ticksDone + 1) > GetTotalTicks())
- break;
+ if (!GetBase()->IsPermanent() && (_ticksDone + 1) > totalTicks)
+ break;
- ++_ticksDone;
+ ++_ticksDone;
- GetBase()->CallScriptEffectUpdatePeriodicHandlers(this);
+ GetBase()->CallScriptEffectUpdatePeriodicHandlers(this);
- std::vector<AuraApplication*> effectApplications;
- GetApplicationList(effectApplications);
+ std::vector<AuraApplication*> effectApplications;
+ GetApplicationList(effectApplications);
- // tick on targets of effects
- for (AuraApplication* aurApp : effectApplications)
- PeriodicTick(aurApp, caster);
- }
+ // tick on targets of effects
+ for (AuraApplication* aurApp : effectApplications)
+ PeriodicTick(aurApp, caster);
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index d18ac2d0919..b79cbdfc66f 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -82,11 +82,11 @@ class TC_GAME_API AuraEffect
void Update(uint32 diff, Unit* caster);
- void ResetTicks() { _ticksDone = 0; }
uint32 GetTickNumber() const { return _ticksDone; }
uint32 GetRemainingTicks() const { return GetTotalTicks() - _ticksDone; }
- uint32 GetTotalTicks() const { return (_amplitude && !GetBase()->IsPermanent()) ? uint32(GetBase()->GetMaxDuration() / _amplitude) : uint32(0); }
+ uint32 GetTotalTicks() const;
void ResetPeriodic(bool resetPeriodicTimer = false);
+ void ResetTicks() { _ticksDone = 0; }
bool IsPeriodic() const { return m_isPeriodic; }
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 052d4e466c6..007e30b7714 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -444,6 +444,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
int32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_2);
int32 const dotBasePoints = CalculatePct(pdamage, pct_dot);
+
+ ASSERT(m_spellInfo->GetMaxTicks() > 0);
m_spellValue->EffectBasePoints[EFFECT_1] = dotBasePoints / m_spellInfo->GetMaxTicks();
apply_direct_bonus = false;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index e2946dbb45e..1f4cc10b4fd 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -3100,17 +3100,13 @@ uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const
uint32 SpellInfo::GetMaxTicks() const
{
+ uint32 totalTicks = 0;
int32 DotDuration = GetDuration();
- if (DotDuration == 0)
- return 1;
-
- // 200% limit
- if (DotDuration > 30000)
- DotDuration = 30000;
- for (uint8 x = 0; x < MAX_SPELL_EFFECTS; x++)
+ for (uint8 x = 0; x < MAX_SPELL_EFFECTS; ++x)
{
if (Effects[x].Effect == SPELL_EFFECT_APPLY_AURA)
+ {
switch (Effects[x].ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
@@ -3127,13 +3123,19 @@ uint32 SpellInfo::GetMaxTicks() const
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
- if (Effects[x].Amplitude != 0)
- return DotDuration / Effects[x].Amplitude;
+ // skip infinite periodics
+ if (Effects[x].Amplitude > 0 && DotDuration > 0)
+ {
+ totalTicks = static_cast<uint32>(DotDuration) / Effects[x].Amplitude;
+ if (HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
+ ++totalTicks;
+ }
break;
}
+ }
}
- return 6;
+ return totalTicks;
}
uint32 SpellInfo::GetRecoveryTime() const