Core/Auras: Implemented EstimatedPoints for SMSG_AURA_UPDATE

Port From (https://github.com/TrinityCore/TrinityCore/commit/bda948fc5c3bd3675edb98f6807d8481bca50fb0)
This commit is contained in:
hondacrx
2021-06-22 17:55:12 -04:00
parent e98e45cf8b
commit 046cd9f917
3 changed files with 52 additions and 18 deletions
@@ -1409,7 +1409,7 @@ namespace Game.Networking.Packets
data.WriteBit(Duration.HasValue); data.WriteBit(Duration.HasValue);
data.WriteBit(Remaining.HasValue); data.WriteBit(Remaining.HasValue);
data.WriteBit(TimeMod.HasValue); data.WriteBit(TimeMod.HasValue);
data.WriteBits(Points.Length, 6); data.WriteBits(Points.Count, 6);
data.WriteBits(EstimatedPoints.Count, 6); data.WriteBits(EstimatedPoints.Count, 6);
data.WriteBit(ContentTuning.HasValue); data.WriteBit(ContentTuning.HasValue);
@@ -1448,7 +1448,7 @@ namespace Game.Networking.Packets
public Optional<int> Duration; public Optional<int> Duration;
public Optional<int> Remaining; public Optional<int> Remaining;
Optional<float> TimeMod; Optional<float> TimeMod;
public float[] Points = Array.Empty<float>(); public List<float> Points = new();
public List<float> EstimatedPoints = new(); public List<float> EstimatedPoints = new();
} }
+14 -5
View File
@@ -45,6 +45,7 @@ namespace Game.Spells
Death Death
} }
[Flags]
public enum AuraFlags public enum AuraFlags
{ {
None = 0x00, None = 0x00,
@@ -226,21 +227,29 @@ namespace Game.Spells
// send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges
// stack amount has priority over charges (checked on retail with spell 50262) // stack amount has priority over charges (checked on retail with spell 50262)
auraData.Applications = aura.IsUsingStacks() ? aura.GetStackAmount() : aura.GetCharges(); auraData.Applications = aura.IsUsingStacks() ? aura.GetStackAmount() : aura.GetCharges();
if (!auraData.Flags.HasAnyFlag(AuraFlags.NoCaster)) if (!auraData.Flags.HasFlag(AuraFlags.NoCaster))
auraData.CastUnit.Set(aura.GetCasterGUID()); auraData.CastUnit.Set(aura.GetCasterGUID());
if (auraData.Flags.HasAnyFlag(AuraFlags.Duration)) if (auraData.Flags.HasFlag(AuraFlags.Duration))
{ {
auraData.Duration.Set(aura.GetMaxDuration()); auraData.Duration.Set(aura.GetMaxDuration());
auraData.Remaining.Set(aura.GetDuration()); auraData.Remaining.Set(aura.GetDuration());
} }
if (auraData.Flags.HasAnyFlag(AuraFlags.Scalable)) if (auraData.Flags.HasFlag(AuraFlags.Scalable))
{ {
auraData.Points = new float[GetBase().GetAuraEffects().Length];
foreach (AuraEffect effect in GetBase().GetAuraEffects()) foreach (AuraEffect effect in GetBase().GetAuraEffects())
{
if (effect != null && HasEffect(effect.GetEffIndex())) // Not all of aura's effects have to be applied on every target if (effect != null && HasEffect(effect.GetEffIndex())) // Not all of aura's effects have to be applied on every target
auraData.Points[effect.GetEffIndex()] = effect.GetAmount(); {
auraData.Points.Add(effect.GetAmount());
if (effect.GetEstimatedAmount().HasValue)
auraData.EstimatedPoints.Add(effect.GetEstimatedAmount().Value);
}
}
if (!auraData.EstimatedPoints.Empty())
auraData.EstimatedPoints.Resize((uint)auraData.Points.Count); // pad to equal sizes
} }
} }
+36 -11
View File
@@ -123,6 +123,24 @@ namespace Game.Spells
GetBase().CallScriptEffectCalcAmountHandlers(this, ref amount, ref m_canBeRecalculated); GetBase().CallScriptEffectCalcAmountHandlers(this, ref amount, ref m_canBeRecalculated);
if (!GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack)) if (!GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack))
amount *= GetBase().GetStackAmount(); amount *= GetBase().GetStackAmount();
if (caster)
{
uint stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack) ? GetBase().GetStackAmount() : 1u;
switch (GetAuraType())
{
case AuraType.PeriodicDamage:
case AuraType.PeriodicLeech:
_estimatedAmount = caster.SpellDamageBonusDone(GetBase().GetUnitOwner(), GetSpellInfo(), (uint)amount, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
break;
case AuraType.PeriodicHeal:
_estimatedAmount = caster.SpellHealingBonusDone(GetBase().GetUnitOwner(), GetSpellInfo(), (uint)amount, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
break;
default:
break;
}
}
return amount; return amount;
} }
@@ -774,6 +792,8 @@ namespace Game.Spells
public bool HasAmount() { return _amount != 0; } public bool HasAmount() { return _amount != 0; }
public void SetAmount(int amount) { _amount = amount; m_canBeRecalculated = false; } public void SetAmount(int amount) { _amount = amount; m_canBeRecalculated = false; }
public float? GetEstimatedAmount() { return _estimatedAmount; }
public int GetPeriodicTimer() { return _periodicTimer; } public int GetPeriodicTimer() { return _periodicTimer; }
public void SetPeriodicTimer(int periodicTimer) { _periodicTimer = periodicTimer; } public void SetPeriodicTimer(int periodicTimer) { _periodicTimer = periodicTimer; }
@@ -820,6 +840,7 @@ namespace Game.Spells
public int m_baseAmount; public int m_baseAmount;
int _amount; int _amount;
float? _estimatedAmount; // for periodic damage and healing auras this will include damage done bonuses
// periodic stuff // periodic stuff
int _periodicTimer; int _periodicTimer;
@@ -4893,6 +4914,8 @@ namespace Game.Spells
CleanDamage cleanDamage = new(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal); CleanDamage cleanDamage = new(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
uint stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack) ? GetBase().GetStackAmount() : 1u;
// ignore non positive values (can be result apply spellmods to aura damage // ignore non positive values (can be result apply spellmods to aura damage
uint damage = (uint)Math.Max(GetAmount(), 0); uint damage = (uint)Math.Max(GetAmount(), 0);
@@ -4904,9 +4927,9 @@ namespace Game.Spells
case AuraType.PeriodicDamage: case AuraType.PeriodicDamage:
{ {
if (caster != null) if (caster != null)
damage = (uint)caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
// There is a Chance to make a Soul Shard when Drain soul does damage // There is a Chance to make a Soul Shard when Drain soul does damage
if (caster != null && GetSpellInfo().SpellFamilyName == SpellFamilyNames.Warlock && GetSpellInfo().SpellFamilyFlags[0].HasAnyFlag(0x00004000u)) if (caster != null && GetSpellInfo().SpellFamilyName == SpellFamilyNames.Warlock && GetSpellInfo().SpellFamilyFlags[0].HasAnyFlag(0x00004000u))
@@ -4946,7 +4969,7 @@ namespace Game.Spells
case AuraType.PeriodicDamagePercent: case AuraType.PeriodicDamagePercent:
// ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner // ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner
damage = (uint)Math.Ceiling(MathFunctions.CalculatePct((float)target.GetMaxHealth(), (float)damage)); damage = (uint)Math.Ceiling(MathFunctions.CalculatePct((float)target.GetMaxHealth(), (float)damage));
damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
break; break;
default: default:
break; break;
@@ -5026,13 +5049,15 @@ namespace Game.Spells
CleanDamage cleanDamage = new(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal); CleanDamage cleanDamage = new(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
uint stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack) ? GetBase().GetStackAmount() : 1u;
// ignore negative values (can be result apply spellmods to aura damage // ignore negative values (can be result apply spellmods to aura damage
uint damage = (uint)Math.Max(GetAmount(), 0); uint damage = (uint)Math.Max(GetAmount(), 0);
if (caster) if (caster)
damage = caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
bool crit = RandomHelper.randChance(GetCritChanceFor(caster, target)); bool crit = RandomHelper.randChance(GetCritChanceFor(caster, target));
if (crit) if (crit)
@@ -5093,8 +5118,8 @@ namespace Game.Spells
float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster); float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
uint heal = (caster.SpellHealingBonusDone(caster, GetSpellInfo(), (uint)(new_damage * gainMultiplier), DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount())); uint heal = caster.SpellHealingBonusDone(caster, GetSpellInfo(), (uint)(new_damage * gainMultiplier), DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
heal = caster.SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); heal = caster.SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
HealInfo healInfo = new(caster, caster, heal, GetSpellInfo(), GetSpellInfo().GetSchoolMask()); HealInfo healInfo = new(caster, caster, heal, GetSpellInfo(), GetSpellInfo().GetSchoolMask());
caster.HealBySpell(healInfo); caster.HealBySpell(healInfo);
@@ -5157,17 +5182,17 @@ namespace Game.Spells
if (GetBase().IsPermanent() && target.IsFullHealth()) if (GetBase().IsPermanent() && target.IsFullHealth())
return; return;
uint stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack) ? GetBase().GetStackAmount() : 1u;
// ignore negative values (can be result apply spellmods to aura damage // ignore negative values (can be result apply spellmods to aura damage
uint damage = (uint)Math.Max(GetAmount(), 0); uint damage = (uint)Math.Max(GetAmount(), 0);
if (GetAuraType() == AuraType.ObsModHealth) if (GetAuraType() == AuraType.ObsModHealth)
{
damage = (uint)target.CountPctFromMaxHealth((int)damage); damage = (uint)target.CountPctFromMaxHealth((int)damage);
}
else if (caster != null) else if (caster != null)
damage = caster.SpellHealingBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = caster.SpellHealingBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
damage = target.SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); damage = target.SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
bool crit = RandomHelper.randChance(GetCritChanceFor(caster, target)); bool crit = RandomHelper.randChance(GetCritChanceFor(caster, target));
if (crit) if (crit)