diff options
author | Shauren <shauren.trinity@gmail.com> | 2021-06-13 00:54:03 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-06-13 00:59:15 +0200 |
commit | bda948fc5c3bd3675edb98f6807d8481bca50fb0 (patch) | |
tree | bcaf118354ffae19b31da8b0ddd589a9d710eb7d | |
parent | 31ef525ecd4a97e887e7d471cf071530e38c6128 (diff) |
Core/Auras: Implemented EstimatedPoints for SMSG_AURA_UPDATE
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 3 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 13 |
3 files changed, 48 insertions, 11 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 6373a39c3b4..7a1b1028041 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -668,6 +668,25 @@ int32 AuraEffect::CalculateAmount(Unit* caster) GetBase()->CallScriptEffectCalcAmountHandlers(this, amount, m_canBeRecalculated); if (!GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack)) amount *= GetBase()->GetStackAmount(); + + if (caster) + { + uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1; + + 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; } @@ -5161,6 +5180,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL); + uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1; + // ignore negative values (can be result apply spellmods to aura damage uint32 damage = std::max(GetAmount(), 0); @@ -5172,8 +5193,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const case SPELL_AURA_PERIODIC_DAMAGE: { if (caster) - damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); - damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); // There is a Chance to make a Soul Shard when Drain soul does damage if (caster && GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)) @@ -5213,7 +5234,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: // ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner damage = uint32(ceil(CalculatePct<float, float>(target->GetMaxHealth(), damage))); - damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); break; default: break; @@ -5301,12 +5322,14 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL); + uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1; + // ignore negative values (can be result apply spellmods to aura damage uint32 damage = std::max(GetAmount(), 0); if (caster) - damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); - damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); bool crit = roll_chance_f(GetCritChanceFor(caster, target)); if (crit) @@ -5367,8 +5390,8 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster); - uint32 heal = caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); - heal = caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); + uint32 heal = caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetSpellEffectInfo(), stackAmountForBonuses); + heal = caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetSpellEffectInfo(), stackAmountForBonuses); HealInfo healInfo(caster, caster, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask()); caster->HealBySpell(healInfo); @@ -5431,15 +5454,17 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const if (GetBase()->IsPermanent() && target->IsFullHealth()) return; + uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1; + // ignore negative values (can be result apply spellmods to aura damage uint32 damage = std::max(GetAmount(), 0); if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH) damage = uint32(target->CountPctFromMaxHealth(damage)); else if (caster) - damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); + damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); - damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); + damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), stackAmountForBonuses); bool crit = roll_chance_f(GetCritChanceFor(caster, target)); if (crit) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 51e8d738cff..6891d27b7fe 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -57,6 +57,8 @@ class TC_GAME_API AuraEffect int32 GetAmount() const { return _amount; } void SetAmount(int32 amount) { _amount = amount; m_canBeRecalculated = false; } + Optional<float> GetEstimatedAmount() const { return _estimatedAmount; } + int32 GetPeriodicTimer() const { return _periodicTimer; } void SetPeriodicTimer(int32 periodicTimer) { _periodicTimer = periodicTimer; } @@ -110,6 +112,7 @@ class TC_GAME_API AuraEffect int32 const m_baseAmount; int32 _amount; + Optional<float> _estimatedAmount; // for periodic damage and healing auras this will include damage done bonuses // periodic stuff int32 _periodicTimer; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index fe1ed0caefe..89c5b832600 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -203,10 +203,19 @@ void AuraApplication::BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo if (auraData.Flags & AFLAG_SCALABLE) { - auraData.Points.resize(aura->GetAuraEffects().size(), 0.0f); + auraData.Points.reserve(aura->GetAuraEffects().size()); + auraData.EstimatedPoints.reserve(aura->GetAuraEffects().size()); for (AuraEffect const* effect : GetBase()->GetAuraEffects()) + { if (effect && HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target - auraData.Points[effect->GetEffIndex()] = float(effect->GetAmount()); + { + Trinity::Containers::EnsureWritableVectorIndex(auraData.Points, effect->GetEffIndex()) = float(effect->GetAmount()); + if (effect->GetEstimatedAmount()) + Trinity::Containers::EnsureWritableVectorIndex(auraData.EstimatedPoints, effect->GetEffIndex()) = *effect->GetEstimatedAmount(); + } + } + if (!auraData.EstimatedPoints.empty()) + auraData.EstimatedPoints.resize(auraData.Points.size()); // pad to equal sizes } } |