aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-06-04 12:30:03 +0200
committerShauren <shauren.trinity@gmail.com>2023-06-04 12:30:03 +0200
commitb3590184c0c31d080609af8e6edd3db33ac4cb8e (patch)
tree092f6edda9d5bf270532ddb4e0988163a10d6f35 /src
parentcd10bf5052c1cb880125c159e97f1a295561774d (diff)
Core/Auras: Implemented helper function to estimate total damage/healing done by a periodic effect
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp73
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h5
2 files changed, 62 insertions, 16 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 93276151f8f..73dc1ee087a 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -711,25 +711,66 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
if (!GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack))
amount *= GetBase()->GetStackAmount();
- if (caster && GetBase()->GetType() == UNIT_AURA_TYPE)
- {
- uint32 stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
+ _estimatedAmount = CalculateEstimatedAmount(caster, amount);
- switch (GetAuraType())
- {
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- _estimatedAmount = caster->SpellDamageBonusDone(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, DOT, GetSpellEffectInfo(), stackAmountForBonuses);
- break;
- case SPELL_AURA_PERIODIC_HEAL:
- _estimatedAmount = caster->SpellHealingBonusDone(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, DOT, GetSpellEffectInfo(), stackAmountForBonuses);
- break;
- default:
- break;
- }
+ return amount;
+}
+
+Optional<float> AuraEffect::CalculateEstimatedAmount(Unit const* caster, Unit* target, SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo,
+ int32 amount, uint8 stack)
+{
+ uint32 stackAmountForBonuses = !spellEffectInfo.EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? stack : 1;
+
+ switch (spellEffectInfo.ApplyAuraName)
+ {
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_LEECH:
+ return caster->SpellDamageBonusDone(target, spellInfo, amount, DOT, spellEffectInfo, stackAmountForBonuses);
+ case SPELL_AURA_PERIODIC_HEAL:
+ return caster->SpellHealingBonusDone(target, spellInfo, amount, DOT, spellEffectInfo, stackAmountForBonuses);
+ default:
+ break;
}
- return amount;
+ return {};
+}
+
+Optional<float> AuraEffect::CalculateEstimatedAmount(Unit const* caster, int32 amount) const
+{
+ if (!caster || GetBase()->GetType() != UNIT_AURA_TYPE)
+ return {};
+
+ return CalculateEstimatedAmount(caster, GetBase()->GetUnitOwner(), GetSpellInfo(), GetSpellEffectInfo(), amount, GetBase()->GetStackAmount());
+}
+
+float AuraEffect::CalculateEstimatedfTotalPeriodicAmount(Unit* caster, Unit* target, SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo,
+ float amount, uint8 stack)
+{
+ int32 maxDuration = Aura::CalcMaxDuration(spellInfo, caster);
+ if (maxDuration <= 0)
+ return 0.0f;
+
+ int32 period = spellEffectInfo.ApplyAuraPeriod;
+ if (!period)
+ return 0.0f;
+
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(spellInfo, SpellModOp::Period, period);
+
+ // Haste modifies periodic time of channeled spells
+ if (spellInfo->IsChanneled())
+ caster->ModSpellDurationTime(spellInfo, period);
+ else if (spellInfo->HasAttribute(SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC))
+ period = int32(period * caster->m_unitData->ModCastingSpeed);
+
+ if (!period)
+ return 0.0f;
+
+ float totalTicks = float(maxDuration) / period;
+ if (spellInfo->HasAttribute(SPELL_ATTR5_EXTRA_INITIAL_PERIOD))
+ totalTicks += 1.0f;
+
+ return totalTicks * CalculateEstimatedAmount(caster, target, spellInfo, spellEffectInfo, amount, stack).value_or(amount);
}
uint32 AuraEffect::GetTotalTicks() const
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 9342c8956a1..032b8987ebd 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -22,6 +22,7 @@
class AuraEffect;
class Unit;
+class WorldObject;
typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uint8 mode, bool apply) const;
@@ -64,6 +65,9 @@ class TC_GAME_API AuraEffect
void SetPeriodicTimer(int32 periodicTimer) { _periodicTimer = periodicTimer; }
int32 CalculateAmount(Unit* caster);
+ static Optional<float> CalculateEstimatedAmount(Unit const* caster, Unit* target, SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, int32 amount, uint8 stack);
+ Optional<float> CalculateEstimatedAmount(Unit const* caster, int32 amount) const;
+ static float CalculateEstimatedfTotalPeriodicAmount(Unit* caster, Unit* target, SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, float amount, uint8 stack);
void CalculatePeriodic(Unit* caster, bool resetPeriodicTimer = true, bool load = false);
void CalculateSpellMod();
void ChangeAmount(int32 newAmount, bool mark = true, bool onStackOrReapply = false, AuraEffect const* triggeredBy = nullptr);
@@ -83,6 +87,7 @@ class TC_GAME_API AuraEffect
void ResetPeriodic(bool resetPeriodicTimer = false);
void ResetTicks() { _ticksDone = 0; }
+
bool IsPeriodic() const { return m_isPeriodic; }
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
bool IsAffectingSpell(SpellInfo const* spell) const;