diff options
author | ariel- <ariel-@users.noreply.github.com> | 2017-12-15 03:40:36 -0300 |
---|---|---|
committer | ariel- <ariel-@users.noreply.github.com> | 2017-12-15 03:40:36 -0300 |
commit | 7dff0e3246f68c39e122e6ccb93b18c29f6df130 (patch) | |
tree | 116622e1b3855f425919d4158020d50507408c40 | |
parent | 2d07d4f7b350035be50ccc39aba1ffdad09ad0b2 (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.cpp | 51 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 22 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_dk.cpp | 1 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_druid.cpp | 4 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_hunter.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_mage.cpp | 1 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 6 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 6 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_shaman.cpp | 6 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_warrior.cpp | 2 |
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 |