aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-12-15 03:40:36 -0300
committerariel- <ariel-@users.noreply.github.com>2017-12-15 03:40:36 -0300
commit7dff0e3246f68c39e122e6ccb93b18c29f6df130 (patch)
tree116622e1b3855f425919d4158020d50507408c40
parent2d07d4f7b350035be50ccc39aba1ffdad09ad0b2 (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
-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
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp1
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp4
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp2
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp1
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp6
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp6
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp6
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp2
12 files changed, 77 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
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index decd33701db..fde570b8c6b 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -2414,6 +2414,7 @@ class spell_dk_unholy_blight : public SpellScriptLoader
if (AuraEffect const* glyph = caster->GetAuraEffect(SPELL_DK_GLYPH_OF_UNHOLY_BLIGHT, EFFECT_0, caster->GetGUID()))
AddPct(amount, glyph->GetAmount());
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to healing done
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index c4e7d96652c..6840cd02f27 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -566,6 +566,8 @@ class spell_dru_glyph_of_innervate : public SpellScriptLoader
Unit* caster = eventInfo.GetActor();
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DRUID_GLYPH_OF_INNERVATE_REGEN);
int32 amount = CalculatePct(static_cast<int32>(caster->GetCreatePowers(POWER_MANA)), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
caster->CastCustomSpell(SPELL_DRUID_GLYPH_OF_INNERVATE_REGEN, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff);
@@ -2098,6 +2100,8 @@ class spell_dru_t10_balance_4p_bonus : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DRUID_LANGUISH);
int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to damage done
amount += target->GetRemainingPeriodicAmount(caster->GetGUID(), SPELL_DRUID_LANGUISH, SPELL_AURA_PERIODIC_DAMAGE);
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index a96f9a4cd88..051e7d9c7c9 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -1477,6 +1477,8 @@ class spell_hun_thrill_of_the_hunt : public SpellScriptLoader
{
// due to Lock and Load SpellInfo::CalcPowerCost might return 0, so just calculate it manually
amount = CalculatePct(static_cast<int32>(CalculatePct(caster->GetCreateMana(), explosiveShot->GetSpellInfo()->ManaCostPercentage)), aurEff->GetAmount());
+
+ ASSERT(explosiveShot->GetSpellInfo()->GetMaxTicks() > 0);
amount /= explosiveShot->GetSpellInfo()->GetMaxTicks();
}
}
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index b5b12afae5e..8edb3e9cf03 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -986,6 +986,7 @@ class spell_mage_ignite : public SpellScriptLoader
SpellInfo const* igniteDot = sSpellMgr->AssertSpellInfo(SPELL_MAGE_IGNITE);
int32 pct = 8 * GetSpellInfo()->GetRank();
+ ASSERT(igniteDot->GetMaxTicks() > 0);
int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks());
amount += eventInfo.GetProcTarget()->GetRemainingPeriodicAmount(eventInfo.GetActor()->GetGUID(), SPELL_MAGE_IGNITE, SPELL_AURA_PERIODIC_DAMAGE);
GetTarget()->CastCustomSpell(SPELL_MAGE_IGNITE, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, nullptr, aurEff);
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index d3d1ed57ccf..29398c5dc35 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -1883,6 +1883,8 @@ class spell_pal_righteous_vengeance : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_RIGHTEOUS_VENGEANCE_DAMAGE);
int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to damage done
amount += target->GetRemainingPeriodicAmount(caster->GetGUID(), SPELL_PALADIN_RIGHTEOUS_VENGEANCE_DAMAGE, SPELL_AURA_PERIODIC_DAMAGE);
@@ -2248,6 +2250,8 @@ class spell_pal_sheath_of_light : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_SHEATH_OF_LIGHT_HEAL);
int32 amount = CalculatePct(static_cast<int32>(healInfo->GetEffectiveHeal()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to healing done
amount += target->GetRemainingPeriodicAmount(caster->GetGUID(), SPELL_PALADIN_SHEATH_OF_LIGHT_HEAL, SPELL_AURA_PERIODIC_HEAL);
@@ -2362,6 +2366,8 @@ class spell_pal_t8_2p_bonus : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_MENDING);
int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to healing done
amount += target->GetRemainingPeriodicAmount(caster->GetGUID(), SPELL_PALADIN_HOLY_MENDING, SPELL_AURA_PERIODIC_HEAL);
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 74c728a6cb0..ee7fc69b71c 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -173,6 +173,8 @@ public:
SpellInfo const* triggerInfo = sSpellMgr->AssertSpellInfo(triggerSpell);
int32 bp = CalculatePct(static_cast<int32>(dmgInfo->GetDamage()), aurEff->GetAmount());
+
+ ASSERT(triggerInfo->GetMaxTicks() > 0);
bp /= triggerInfo->GetMaxTicks();
bp += target->GetRemainingPeriodicAmount(target->GetGUID(), triggerSpell, SPELL_AURA_PERIODIC_HEAL);
target->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff);
@@ -443,6 +445,8 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader
return;
SpellInfo const* triggeredSpellInfo = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL);
+
+ ASSERT(triggeredSpellInfo->GetMaxTicks() > 0);
int32 heal = int32(CalculatePct(healInfo->GetHeal(), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks());
GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, nullptr, aurEff);
}
@@ -1408,6 +1412,8 @@ class spell_pri_t10_heal_2p_bonus : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_BLESSED_HEALING);
int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to healing done
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index c2ec92843ff..87d426d4df9 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -2044,6 +2044,8 @@ class spell_sha_t8_elemental_4p_bonus : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_ELECTRIFIED);
int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to damage done
@@ -2091,6 +2093,8 @@ class spell_sha_t9_elemental_4p_bonus : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE);
int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to damage done
@@ -2183,6 +2187,8 @@ class spell_sha_t10_restoration_4p_bonus : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_CHAINED_HEAL);
int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount());
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
amount /= spellInfo->GetMaxTicks();
// Add remaining ticks to healing done
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index 3d6791a0391..be7e0d0421d 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -286,6 +286,8 @@ class spell_warr_deep_wounds : public SpellScriptLoader
ApplyPct(damage, 16 * GetSpellInfo()->GetRank());
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC);
+
+ ASSERT(spellInfo->GetMaxTicks() > 0);
damage /= spellInfo->GetMaxTicks();
// Add remaining ticks to damage done