diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-06-04 12:30:03 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-06-04 12:30:03 +0200 |
commit | b3590184c0c31d080609af8e6edd3db33ac4cb8e (patch) | |
tree | 092f6edda9d5bf270532ddb4e0988163a10d6f35 | |
parent | cd10bf5052c1cb880125c159e97f1a295561774d (diff) |
Core/Auras: Implemented helper function to estimate total damage/healing done by a periodic effect
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 73 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 5 |
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; |