aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-12-15 03:40:36 -0300
committerfunjoker <funjoker109@gmail.com>2021-03-15 20:17:31 +0100
commit794a3e43887d3fea4bb9b1ec77a98ab596eea0be (patch)
tree76b72a5ee856e1508ef7e8a28b7eb2229ab22fa0 /src/server/game
parent8eb3e6c243d910658076cba55fb2c4b32612b877 (diff)
Core/Auras: fixed off by one error in counting SPELL_ATTR5_START_PERIODIC_AT_APPLY ticks
- Made SpellInfo::GetMaxTicks and AuraEffect::GetTotalTicks return the same number without mods (dumped arbitrary default return value of 6 and arbitrary 30 sec limit) - They should be streamlined whenever SPELL_AURA_48 is implemented (cherry picked from commit 7dff0e3246f68c39e122e6ccb93b18c29f6df130)
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/SpellInfo.cpp16
3 files changed, 46 insertions, 25 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 8132912170a..797c0ce72bf 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -672,15 +672,28 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
return amount;
}
+uint32 AuraEffect::GetTotalTicks() const
+{
+ uint32 totalTicks = 0;
+ if (_period && !GetBase()->IsPermanent())
+ {
+ totalTicks = static_cast<uint32>(GetBase()->GetMaxDuration() / _period);
+ if (m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
+ ++totalTicks;
+ }
+
+ return totalTicks;
+}
+
void AuraEffect::ResetPeriodic(bool resetPeriodicTimer /*= false*/)
{
_ticksDone = 0;
if (resetPeriodicTimer)
{
- _periodicTimer = _period;
+ _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 = _period;
}
}
@@ -947,27 +960,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 >= _period)
{
- _periodicTimer += diff;
- while (_periodicTimer >= _period)
- {
- _periodicTimer -= _period;
+ _periodicTimer -= _period;
- 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 c2e5ae24759..6503878de89 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -81,11 +81,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 (_period && !GetBase()->IsPermanent()) ? uint32(GetBase()->GetMaxDuration() / _period) : 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/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 53a732c1390..38ec721e822 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -3722,13 +3722,13 @@ uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const
uint32 SpellInfo::GetMaxTicks() const
{
+ uint32 totalTicks = 0;
int32 DotDuration = GetDuration();
- if (DotDuration == 0)
- return 1;
for (SpellEffectInfo const* effect : _effects)
{
if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ {
switch (effect->ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
@@ -3745,13 +3745,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 (effect->ApplyAuraPeriod != 0)
- return DotDuration / effect->ApplyAuraPeriod;
+ // skip infinite periodics
+ if (effect->ApplyAuraPeriod > 0 && DotDuration > 0)
+ {
+ totalTicks = static_cast<uint32>(DotDuration) / effect->ApplyAuraPeriod;
+ if (HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
+ ++totalTicks;
+ }
break;
}
+ }
}
- return 6;
+ return totalTicks;
}
uint32 SpellInfo::GetRecoveryTime() const