From 621b5e4d4775682305c7556b84cc1fb39b26b565 Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Tue, 2 Sep 2025 16:17:10 -0500 Subject: [PATCH 1/7] Added helper function to CalculateExpectedTick Damage --- sim/core/dot.go | 54 +++++++++++++++++++ sim/druid/balance/sunfire.go | 18 +++---- sim/druid/moonfire.go | 18 +++---- sim/druid/rake.go | 29 +++++----- sim/druid/rip.go | 33 +++++++----- sim/druid/thrash.go | 17 +++--- sim/hunter/pet_abilities.go | 12 ++++- sim/mage/fire/combustion.go | 21 +++++--- sim/priest/_shadow_word_pain.go | 17 +++--- sim/priest/shadow/mind_flay.go | 11 +++- sim/priest/shadow/talents.go | 11 +++- sim/priest/shadow_word_pain.go | 18 +++---- sim/priest/vampiric_touch.go | 18 +++---- sim/warlock/affliction/agony.go | 25 +++++---- sim/warlock/affliction/unstable_affliction.go | 18 +++---- sim/warlock/corruption.go | 18 +++---- sim/warlock/demonology/doom.go | 18 +++---- sim/warlock/destruction/immolate.go | 18 +++---- sim/warrior/passives.go | 18 ++++--- 19 files changed, 246 insertions(+), 146 deletions(-) diff --git a/sim/core/dot.go b/sim/core/dot.go index a81391e6ec..f45cc20e54 100644 --- a/sim/core/dot.go +++ b/sim/core/dot.go @@ -493,3 +493,57 @@ func (dot *Dot) RestoreState(state DotState, sim *Simulation) { dot.tickAction = pa sim.AddPendingAction(dot.tickAction) } + +// CalcExpectedTickDamage computes the expected damage for a DoT tick, either +// from snapshot values or by calculating periodic damage. +// +// Parameters: +// - sim: the current simulation. +// - target: target of dot. +// - useSnapshot: if true, calculate from snapshot values; +// otherwise calculate each tick. +// - baseDmgFn: function to compute base damage when not snapshotting. +// - snapshotCrit: crit outcome type for snapshot damage. +// - normalCrit: crit outcome type for periodic damage. +// - skipTickDivision: skips division of ticks aka DeepWounds +// - modifyResult: optional hook to adjust the result (e.g. apply multipliers, add crit mods). +// +// This is a helper function for DoT calculations so that each spell only +// needs to provide its unique scaling and modifiers. +// +// TODO: if modifyResult needs the raw PerTick value you may need to adjust the order and do a modifyDamage func and postTickModify func +func (dot *Dot) CalcExpectedTickDamage( + sim *Simulation, + target *Unit, + useSnapshot bool, + baseDmgFn func(*Spell, *Unit) float64, // optional for non-snapshot + snapshotCrit OutcomeApplier, + normalCrit OutcomeApplier, + skipTickDivision bool, // flag to disable default tick division + modifyResult func(*SpellResult, *Dot), // optional final tweaks +) *SpellResult { + if useSnapshot { + result := dot.CalcSnapshotDamage(sim, target, snapshotCrit) + if !skipTickDivision { + result.Damage /= dot.TickPeriod().Seconds() + } + if modifyResult != nil { + modifyResult(result, dot) + } + return result + } + + baseDamage := 0.0 + if baseDmgFn != nil { + baseDamage = baseDmgFn(dot.Spell, target) + } + + result := dot.Spell.CalcPeriodicDamage(sim, target, baseDamage, normalCrit) + if !skipTickDivision { + result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() + } + if modifyResult != nil { + modifyResult(result, dot) + } + return result +} diff --git a/sim/druid/balance/sunfire.go b/sim/druid/balance/sunfire.go index 4dae04321c..7519663a6c 100644 --- a/sim/druid/balance/sunfire.go +++ b/sim/druid/balance/sunfire.go @@ -69,15 +69,15 @@ func (moonkin *BalanceDruid) registerSunfireDoTSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, moonkin.CalcScalingSpellDmg(SunfireDotCoeff), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return moonkin.CalcScalingSpellDmg(SunfireDotCoeff) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/druid/moonfire.go b/sim/druid/moonfire.go index b2c3803b7e..0a03f8b30e 100644 --- a/sim/druid/moonfire.go +++ b/sim/druid/moonfire.go @@ -68,15 +68,15 @@ func (druid *Druid) registerMoonfireDoTSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, druid.CalcScalingSpellDmg(MoonfireDotCoeff), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return druid.CalcScalingSpellDmg(MoonfireDotCoeff) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/druid/rake.go b/sim/druid/rake.go index 36549e0e19..e10fad9fb3 100644 --- a/sim/druid/rake.go +++ b/sim/druid/rake.go @@ -74,20 +74,21 @@ func (druid *Druid) registerRakeSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { - if useSnapshot { - dot := spell.Dot(target) - return dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - } else { - tickBase := flatBaseDamage + bonusCoefficientFromAP*spell.MeleeAttackPower() - ticks := spell.CalcPeriodicDamage(sim, target, tickBase, spell.OutcomeExpectedMagicAlwaysHit) - - attackTable := spell.Unit.AttackTables[target.UnitIndex] - critChance := spell.PhysicalCritChance(attackTable) - critMod := (critChance * (spell.CritMultiplier - 1)) - ticks.Damage *= 1 + critMod - - return ticks - } + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return flatBaseDamage + bonusCoefficientFromAP*spell.MeleeAttackPower() + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicAlwaysHit, + true, + func(sr *core.SpellResult, d *core.Dot) { + attackTable := spell.Unit.AttackTables[target.UnitIndex] + critChance := spell.PhysicalCritChance(attackTable) + critMod := (critChance * (spell.CritMultiplier - 1)) + sr.Damage *= 1 + critMod + }, + ) }, }) diff --git a/sim/druid/rip.go b/sim/druid/rip.go index d189ad5195..13abfe6842 100644 --- a/sim/druid/rip.go +++ b/sim/druid/rip.go @@ -83,20 +83,25 @@ func (druid *Druid) registerRipSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { - if useSnapshot { - dot := spell.Dot(target) - return dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - } else { - cp := 5.0 // Hard-code this so that snapshotting calculations can be performed at any CP value. - ap := spell.MeleeAttackPower() - baseTickDamage := baseDamage + comboPointCoeff*cp + attackPowerCoeff*cp*ap - result := spell.CalcPeriodicDamage(sim, target, baseTickDamage, spell.OutcomeExpectedMagicAlwaysHit) - attackTable := spell.Unit.AttackTables[target.UnitIndex] - critChance := spell.PhysicalCritChance(attackTable) - critMod := critChance * (spell.CritMultiplier - 1) - result.Damage *= 1 + critMod - return result - } + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + cp := 5.0 // Hard-code this so that snapshotting calculations can be performed at any CP value. + ap := spell.MeleeAttackPower() + return baseDamage + comboPointCoeff*cp + attackPowerCoeff*cp*ap + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicAlwaysHit, + true, + func(sr *core.SpellResult, d *core.Dot) { + if !useSnapshot { + attackTable := spell.Unit.AttackTables[target.UnitIndex] + critChance := spell.PhysicalCritChance(attackTable) + critMod := critChance * (spell.CritMultiplier - 1) + sr.Damage *= 1 + critMod + } + }, + ) }, }) diff --git a/sim/druid/thrash.go b/sim/druid/thrash.go index 3f8bc89adb..affa8a7fec 100644 --- a/sim/druid/thrash.go +++ b/sim/druid/thrash.go @@ -139,13 +139,16 @@ func (druid *Druid) registerThrashCatSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { - if useSnapshot { - dot := spell.Dot(target) - return dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - } else { - baseTickDamage := flatTickDamage + 0.141*spell.MeleeAttackPower() - return spell.CalcPeriodicDamage(sim, target, baseTickDamage, spell.OutcomeExpectedPhysicalCrit) - } + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return flatTickDamage + 0.141*spell.MeleeAttackPower() + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedPhysicalCrit, + true, + nil, + ) }, RelatedAuraArrays: druid.WeakenedBlowsAuras.ToMap(), diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go index ce2172afa7..3699cae067 100644 --- a/sim/hunter/pet_abilities.go +++ b/sim/hunter/pet_abilities.go @@ -349,8 +349,16 @@ func (hp *HunterPet) newFrostStormBreath() *core.Spell { } }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { - baseDamage := 206 + (spell.MeleeAttackPower() * 0.40) - return spell.CalcPeriodicDamage(sim, target, baseDamage, spell.OutcomeExpectedMagicCrit) + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, false, + func(s *core.Spell, u *core.Unit) float64 { + return 206 + (spell.MeleeAttackPower() * 0.40) + }, + nil, + spell.OutcomeExpectedMagicCrit, + true, + nil, + ) }, }) return hp.frostStormBreath diff --git a/sim/mage/fire/combustion.go b/sim/mage/fire/combustion.go index bf1d5a41a0..67a7f5d460 100644 --- a/sim/mage/fire/combustion.go +++ b/sim/mage/fire/combustion.go @@ -90,13 +90,20 @@ func (fire *FireMage) registerCombustionSpell() { }, }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { - tickBase := calculatedDotTick(sim, target) - result := spell.CalcPeriodicDamage(sim, target, tickBase, spell.OutcomeExpectedMagicAlwaysHit) - critChance := spell.SpellCritChance(target) - critMod := (critChance * (spell.CritMultiplier - 1)) - result.Damage *= 1 + critMod - - return result + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, false, + func(s *core.Spell, u *core.Unit) float64 { + return calculatedDotTick(sim, target) + }, + nil, + spell.OutcomeExpectedMagicAlwaysHit, + true, + func(sr *core.SpellResult, d *core.Dot) { + critChance := spell.SpellCritChance(target) + critMod := (critChance * (spell.CritMultiplier - 1)) + sr.Damage *= 1 + critMod + }, + ) }, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { spell.Dot(target).Apply(sim) diff --git a/sim/priest/_shadow_word_pain.go b/sim/priest/_shadow_word_pain.go index 73714233fb..1887ad9d46 100644 --- a/sim/priest/_shadow_word_pain.go +++ b/sim/priest/_shadow_word_pain.go @@ -63,13 +63,16 @@ func (priest *Priest) registerShadowWordPainSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { - if useSnapshot { - dot := spell.Dot(target) - return dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedMagicSnapshotCrit) - } else { - baseDamage := 194.709 - return spell.CalcPeriodicDamage(sim, target, baseDamage, spell.OutcomeExpectedMagicCrit) - } + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return priest.CalcScalingSpellDmg(SwpScaleCoeff) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/priest/shadow/mind_flay.go b/sim/priest/shadow/mind_flay.go index a90f12f12f..d8ab65b8df 100644 --- a/sim/priest/shadow/mind_flay.go +++ b/sim/priest/shadow/mind_flay.go @@ -55,7 +55,16 @@ func (shadow *ShadowPriest) registerMindFlaySpell() *core.Spell { } }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { - return spell.CalcPeriodicDamage(sim, target, shadow.CalcScalingSpellDmg(MfScale), spell.OutcomeExpectedMagicCrit) + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, false, + func(s *core.Spell, u *core.Unit) float64 { + return shadow.CalcScalingSpellDmg(MfScale) + }, + nil, + spell.OutcomeExpectedMagicCrit, + true, + nil, + ) }, }) } diff --git a/sim/priest/shadow/talents.go b/sim/priest/shadow/talents.go index 35401d2f6e..013d925a04 100644 --- a/sim/priest/shadow/talents.go +++ b/sim/priest/shadow/talents.go @@ -106,7 +106,16 @@ func (shadow *ShadowPriest) registerSolaceAndInstanity() { } }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { - return spell.CalcPeriodicDamage(sim, target, shadow.CalcScalingSpellDmg(MfScale), spell.OutcomeExpectedMagicCrit) + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, false, + func(s *core.Spell, u *core.Unit) float64 { + return shadow.CalcScalingSpellDmg(MfScale) + }, + nil, + spell.OutcomeExpectedMagicCrit, + true, + nil, + ) }, ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { return shadow.DevouringPlague.Dot(target).IsActive() diff --git a/sim/priest/shadow_word_pain.go b/sim/priest/shadow_word_pain.go index 9ad476e994..c09110c293 100644 --- a/sim/priest/shadow_word_pain.go +++ b/sim/priest/shadow_word_pain.go @@ -62,15 +62,15 @@ func (priest *Priest) registerShadowWordPainSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, priest.CalcScalingSpellDmg(SwpScaleCoeff), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return priest.CalcScalingSpellDmg(SwpScaleCoeff) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/priest/vampiric_touch.go b/sim/priest/vampiric_touch.go index b88472e237..bf57a92087 100644 --- a/sim/priest/vampiric_touch.go +++ b/sim/priest/vampiric_touch.go @@ -61,15 +61,15 @@ func (priest *Priest) registerVampiricTouchSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, priest.CalcScalingSpellDmg(VtScaleCoeff), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return priest.CalcScalingSpellDmg(VtScaleCoeff) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/warlock/affliction/agony.go b/sim/warlock/affliction/agony.go index 424804f2b1..d597fce3ac 100644 --- a/sim/warlock/affliction/agony.go +++ b/sim/warlock/affliction/agony.go @@ -72,19 +72,18 @@ func (affliction *AfflictionWarlock) registerAgony() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - - // Always compare fully stacked agony damage - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage *= 10 - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, affliction.CalcScalingSpellDmg(agonyScale), spell.OutcomeExpectedMagicCrit) - result.Damage *= 10 - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return affliction.CalcScalingSpellDmg(agonyScale) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + func(sr *core.SpellResult, d *core.Dot) { + // Always compare fully stacked agony damage + sr.Damage *= 10 + }, + ) }, }) } diff --git a/sim/warlock/affliction/unstable_affliction.go b/sim/warlock/affliction/unstable_affliction.go index ba096556af..32f5236770 100644 --- a/sim/warlock/affliction/unstable_affliction.go +++ b/sim/warlock/affliction/unstable_affliction.go @@ -55,15 +55,15 @@ func (affliction *AfflictionWarlock) registerUnstableAffliction() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, affliction.CalcScalingSpellDmg(uaScale), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return affliction.CalcScalingSpellDmg(uaScale) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/warlock/corruption.go b/sim/warlock/corruption.go index ab2dfda2ec..001850e457 100644 --- a/sim/warlock/corruption.go +++ b/sim/warlock/corruption.go @@ -57,15 +57,15 @@ func (warlock *Warlock) RegisterCorruption(callback WarlockSpellCastedCallback) }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, warlock.CalcScalingSpellDmg(corruptionScale), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return warlock.CalcScalingSpellDmg(corruptionScale) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) diff --git a/sim/warlock/demonology/doom.go b/sim/warlock/demonology/doom.go index 786fe70525..1758720765 100644 --- a/sim/warlock/demonology/doom.go +++ b/sim/warlock/demonology/doom.go @@ -56,15 +56,15 @@ func (demonology *DemonologyWarlock) registerDoom() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, demonology.CalcScalingSpellDmg(doomScale), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return demonology.CalcScalingSpellDmg(doomScale) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/warlock/destruction/immolate.go b/sim/warlock/destruction/immolate.go index d00b58c45d..60faefb723 100644 --- a/sim/warlock/destruction/immolate.go +++ b/sim/warlock/destruction/immolate.go @@ -100,15 +100,15 @@ func (destruction *DestructionWarlock) registerImmolate() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - result.Damage /= dot.TickPeriod().Seconds() - return result - } else { - result := spell.CalcPeriodicDamage(sim, target, destruction.CalcScalingSpellDmg(immolateCoeff), spell.OutcomeExpectedMagicCrit) - result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() - return result - } + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return destruction.CalcScalingSpellDmg(immolateCoeff) + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedMagicCrit, + false, + nil, + ) }, }) } diff --git a/sim/warrior/passives.go b/sim/warrior/passives.go index 7ba4c26cec..b9d978e25e 100644 --- a/sim/warrior/passives.go +++ b/sim/warrior/passives.go @@ -91,14 +91,16 @@ func (warrior *Warrior) registerDeepWounds() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { - if useSnapshot { - dot := spell.Dot(target) - return dot.CalcSnapshotDamage(sim, target, dot.OutcomeExpectedSnapshotCrit) - } else { - baseDamage := warrior.CalcScalingSpellDmg(deepWoundsCoeff) - baseDamage += deepWoundsBonusCoeff * spell.MeleeAttackPower() - return spell.CalcPeriodicDamage(sim, target, baseDamage, spell.OutcomeExpectedPhysicalCrit) - } + dot := spell.Dot(target) + return dot.CalcExpectedTickDamage(sim, target, useSnapshot, + func(s *core.Spell, u *core.Unit) float64 { + return warrior.CalcScalingSpellDmg(deepWoundsCoeff) + deepWoundsBonusCoeff*s.MeleeAttackPower() + }, + dot.OutcomeExpectedSnapshotCrit, + spell.OutcomeExpectedPhysicalCrit, + true, + nil, + ) }, }) From acb6ee5793d1009017f0fcb5c357c1d7f5771b83 Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Wed, 3 Sep 2025 09:02:01 -0500 Subject: [PATCH 2/7] change to cfg ExpectedTickConfig --- sim/core/dot.go | 62 +++++++------------ sim/druid/balance/sunfire.go | 17 ++--- sim/druid/moonfire.go | 17 ++--- sim/druid/rake.go | 17 ++--- sim/druid/rip.go | 17 ++--- sim/druid/thrash.go | 17 ++--- sim/hunter/pet_abilities.go | 17 ++--- sim/mage/fire/combustion.go | 17 ++--- sim/priest/_shadow_word_pain.go | 17 ++--- sim/priest/shadow/mind_flay.go | 17 ++--- sim/priest/shadow/talents.go | 17 ++--- sim/priest/shadow_word_pain.go | 17 ++--- sim/priest/vampiric_touch.go | 17 ++--- sim/warlock/affliction/agony.go | 17 ++--- sim/warlock/affliction/unstable_affliction.go | 17 ++--- sim/warlock/corruption.go | 17 ++--- sim/warlock/demonology/doom.go | 17 ++--- sim/warlock/destruction/immolate.go | 17 ++--- sim/warrior/passives.go | 17 ++--- 19 files changed, 203 insertions(+), 165 deletions(-) diff --git a/sim/core/dot.go b/sim/core/dot.go index f45cc20e54..058caf2b7d 100644 --- a/sim/core/dot.go +++ b/sim/core/dot.go @@ -494,56 +494,40 @@ func (dot *Dot) RestoreState(state DotState, sim *Simulation) { sim.AddPendingAction(dot.tickAction) } -// CalcExpectedTickDamage computes the expected damage for a DoT tick, either -// from snapshot values or by calculating periodic damage. -// -// Parameters: -// - sim: the current simulation. -// - target: target of dot. -// - useSnapshot: if true, calculate from snapshot values; -// otherwise calculate each tick. -// - baseDmgFn: function to compute base damage when not snapshotting. -// - snapshotCrit: crit outcome type for snapshot damage. -// - normalCrit: crit outcome type for periodic damage. -// - skipTickDivision: skips division of ticks aka DeepWounds -// - modifyResult: optional hook to adjust the result (e.g. apply multipliers, add crit mods). -// -// This is a helper function for DoT calculations so that each spell only -// needs to provide its unique scaling and modifiers. -// -// TODO: if modifyResult needs the raw PerTick value you may need to adjust the order and do a modifyDamage func and postTickModify func -func (dot *Dot) CalcExpectedTickDamage( - sim *Simulation, - target *Unit, - useSnapshot bool, - baseDmgFn func(*Spell, *Unit) float64, // optional for non-snapshot - snapshotCrit OutcomeApplier, - normalCrit OutcomeApplier, - skipTickDivision bool, // flag to disable default tick division - modifyResult func(*SpellResult, *Dot), // optional final tweaks -) *SpellResult { - if useSnapshot { - result := dot.CalcSnapshotDamage(sim, target, snapshotCrit) - if !skipTickDivision { +type ExpectedTickConfig struct { + Sim *Simulation + Target *Unit + UseSnapshot bool + BaseDmgFn func(*Spell, *Unit) float64 // for non-snapshot damage calc + SnapshotCrit OutcomeApplier + NormalCrit OutcomeApplier + SkipHasteNormalization bool // disables haste normalization + ModifyResult func(*SpellResult, *Dot) // optional final tweaks, apply multipliers, add crit mods +} + +func (dot *Dot) CalcExpectedTickDamage(cfg ExpectedTickConfig) *SpellResult { + if cfg.UseSnapshot { + result := dot.CalcSnapshotDamage(cfg.Sim, cfg.Target, cfg.SnapshotCrit) + if !cfg.SkipHasteNormalization { result.Damage /= dot.TickPeriod().Seconds() } - if modifyResult != nil { - modifyResult(result, dot) + if cfg.ModifyResult != nil { + cfg.ModifyResult(result, dot) } return result } baseDamage := 0.0 - if baseDmgFn != nil { - baseDamage = baseDmgFn(dot.Spell, target) + if cfg.BaseDmgFn != nil { + baseDamage = cfg.BaseDmgFn(dot.Spell, cfg.Target) } - result := dot.Spell.CalcPeriodicDamage(sim, target, baseDamage, normalCrit) - if !skipTickDivision { + result := dot.Spell.CalcPeriodicDamage(cfg.Sim, cfg.Target, baseDamage, cfg.NormalCrit) + if !cfg.SkipHasteNormalization { result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() } - if modifyResult != nil { - modifyResult(result, dot) + if cfg.ModifyResult != nil { + cfg.ModifyResult(result, dot) } return result } diff --git a/sim/druid/balance/sunfire.go b/sim/druid/balance/sunfire.go index 7519663a6c..23f8336834 100644 --- a/sim/druid/balance/sunfire.go +++ b/sim/druid/balance/sunfire.go @@ -69,15 +69,18 @@ func (moonkin *BalanceDruid) registerSunfireDoTSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return moonkin.CalcScalingSpellDmg(SunfireDotCoeff) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/druid/moonfire.go b/sim/druid/moonfire.go index 0a03f8b30e..7aab6a3592 100644 --- a/sim/druid/moonfire.go +++ b/sim/druid/moonfire.go @@ -68,15 +68,18 @@ func (druid *Druid) registerMoonfireDoTSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return druid.CalcScalingSpellDmg(MoonfireDotCoeff) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/druid/rake.go b/sim/druid/rake.go index e10fad9fb3..fd18d30e46 100644 --- a/sim/druid/rake.go +++ b/sim/druid/rake.go @@ -75,20 +75,23 @@ func (druid *Druid) registerRakeSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return flatBaseDamage + bonusCoefficientFromAP*spell.MeleeAttackPower() }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicAlwaysHit, - true, - func(sr *core.SpellResult, d *core.Dot) { + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicAlwaysHit, + SkipHasteNormalization: true, + ModifyResult: func(sr *core.SpellResult, d *core.Dot) { attackTable := spell.Unit.AttackTables[target.UnitIndex] critChance := spell.PhysicalCritChance(attackTable) critMod := (critChance * (spell.CritMultiplier - 1)) sr.Damage *= 1 + critMod }, - ) + }) }, }) diff --git a/sim/druid/rip.go b/sim/druid/rip.go index 13abfe6842..df7455da76 100644 --- a/sim/druid/rip.go +++ b/sim/druid/rip.go @@ -84,16 +84,19 @@ func (druid *Druid) registerRipSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { cp := 5.0 // Hard-code this so that snapshotting calculations can be performed at any CP value. ap := spell.MeleeAttackPower() return baseDamage + comboPointCoeff*cp + attackPowerCoeff*cp*ap }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicAlwaysHit, - true, - func(sr *core.SpellResult, d *core.Dot) { + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicAlwaysHit, + SkipHasteNormalization: true, + ModifyResult: func(sr *core.SpellResult, d *core.Dot) { if !useSnapshot { attackTable := spell.Unit.AttackTables[target.UnitIndex] critChance := spell.PhysicalCritChance(attackTable) @@ -101,7 +104,7 @@ func (druid *Druid) registerRipSpell() { sr.Damage *= 1 + critMod } }, - ) + }) }, }) diff --git a/sim/druid/thrash.go b/sim/druid/thrash.go index affa8a7fec..33072f7d63 100644 --- a/sim/druid/thrash.go +++ b/sim/druid/thrash.go @@ -140,15 +140,18 @@ func (druid *Druid) registerThrashCatSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return flatTickDamage + 0.141*spell.MeleeAttackPower() }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedPhysicalCrit, - true, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedPhysicalCrit, + SkipHasteNormalization: true, + ModifyResult: nil, + }) }, RelatedAuraArrays: druid.WeakenedBlowsAuras.ToMap(), diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go index 3699cae067..bbeaa1685a 100644 --- a/sim/hunter/pet_abilities.go +++ b/sim/hunter/pet_abilities.go @@ -350,15 +350,18 @@ func (hp *HunterPet) newFrostStormBreath() *core.Spell { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, false, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: false, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return 206 + (spell.MeleeAttackPower() * 0.40) }, - nil, - spell.OutcomeExpectedMagicCrit, - true, - nil, - ) + SnapshotCrit: nil, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: true, + ModifyResult: nil, + }) }, }) return hp.frostStormBreath diff --git a/sim/mage/fire/combustion.go b/sim/mage/fire/combustion.go index 67a7f5d460..8198a76bb6 100644 --- a/sim/mage/fire/combustion.go +++ b/sim/mage/fire/combustion.go @@ -91,19 +91,22 @@ func (fire *FireMage) registerCombustionSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, false, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: false, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return calculatedDotTick(sim, target) }, - nil, - spell.OutcomeExpectedMagicAlwaysHit, - true, - func(sr *core.SpellResult, d *core.Dot) { + SnapshotCrit: nil, + NormalCrit: spell.OutcomeExpectedMagicAlwaysHit, + SkipHasteNormalization: true, + ModifyResult: func(sr *core.SpellResult, d *core.Dot) { critChance := spell.SpellCritChance(target) critMod := (critChance * (spell.CritMultiplier - 1)) sr.Damage *= 1 + critMod }, - ) + }) }, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { spell.Dot(target).Apply(sim) diff --git a/sim/priest/_shadow_word_pain.go b/sim/priest/_shadow_word_pain.go index 1887ad9d46..16bb35a989 100644 --- a/sim/priest/_shadow_word_pain.go +++ b/sim/priest/_shadow_word_pain.go @@ -64,15 +64,18 @@ func (priest *Priest) registerShadowWordPainSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/priest/shadow/mind_flay.go b/sim/priest/shadow/mind_flay.go index d8ab65b8df..0536ea6ab3 100644 --- a/sim/priest/shadow/mind_flay.go +++ b/sim/priest/shadow/mind_flay.go @@ -56,15 +56,18 @@ func (shadow *ShadowPriest) registerMindFlaySpell() *core.Spell { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, false, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: false, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, - nil, - spell.OutcomeExpectedMagicCrit, - true, - nil, - ) + SnapshotCrit: nil, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: true, + ModifyResult: nil, + }) }, }) } diff --git a/sim/priest/shadow/talents.go b/sim/priest/shadow/talents.go index 013d925a04..4a7175008f 100644 --- a/sim/priest/shadow/talents.go +++ b/sim/priest/shadow/talents.go @@ -107,15 +107,18 @@ func (shadow *ShadowPriest) registerSolaceAndInstanity() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, false, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: false, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, - nil, - spell.OutcomeExpectedMagicCrit, - true, - nil, - ) + SnapshotCrit: nil, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: true, + ModifyResult: nil, + }) }, ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { return shadow.DevouringPlague.Dot(target).IsActive() diff --git a/sim/priest/shadow_word_pain.go b/sim/priest/shadow_word_pain.go index c09110c293..b3a5f6e17b 100644 --- a/sim/priest/shadow_word_pain.go +++ b/sim/priest/shadow_word_pain.go @@ -62,15 +62,18 @@ func (priest *Priest) registerShadowWordPainSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/priest/vampiric_touch.go b/sim/priest/vampiric_touch.go index bf57a92087..8ce91047b3 100644 --- a/sim/priest/vampiric_touch.go +++ b/sim/priest/vampiric_touch.go @@ -61,15 +61,18 @@ func (priest *Priest) registerVampiricTouchSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return priest.CalcScalingSpellDmg(VtScaleCoeff) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/warlock/affliction/agony.go b/sim/warlock/affliction/agony.go index d597fce3ac..b0c7cfbfdb 100644 --- a/sim/warlock/affliction/agony.go +++ b/sim/warlock/affliction/agony.go @@ -72,18 +72,21 @@ func (affliction *AfflictionWarlock) registerAgony() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return affliction.CalcScalingSpellDmg(agonyScale) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - func(sr *core.SpellResult, d *core.Dot) { + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: func(sr *core.SpellResult, d *core.Dot) { // Always compare fully stacked agony damage sr.Damage *= 10 }, - ) + }) }, }) } diff --git a/sim/warlock/affliction/unstable_affliction.go b/sim/warlock/affliction/unstable_affliction.go index 32f5236770..b09ce43c7b 100644 --- a/sim/warlock/affliction/unstable_affliction.go +++ b/sim/warlock/affliction/unstable_affliction.go @@ -55,15 +55,18 @@ func (affliction *AfflictionWarlock) registerUnstableAffliction() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return affliction.CalcScalingSpellDmg(uaScale) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/warlock/corruption.go b/sim/warlock/corruption.go index 001850e457..bceccf7508 100644 --- a/sim/warlock/corruption.go +++ b/sim/warlock/corruption.go @@ -57,15 +57,18 @@ func (warlock *Warlock) RegisterCorruption(callback WarlockSpellCastedCallback) }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return warlock.CalcScalingSpellDmg(corruptionScale) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) diff --git a/sim/warlock/demonology/doom.go b/sim/warlock/demonology/doom.go index 1758720765..3c89019b65 100644 --- a/sim/warlock/demonology/doom.go +++ b/sim/warlock/demonology/doom.go @@ -56,15 +56,18 @@ func (demonology *DemonologyWarlock) registerDoom() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return demonology.CalcScalingSpellDmg(doomScale) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/warlock/destruction/immolate.go b/sim/warlock/destruction/immolate.go index 60faefb723..eeebd47724 100644 --- a/sim/warlock/destruction/immolate.go +++ b/sim/warlock/destruction/immolate.go @@ -100,15 +100,18 @@ func (destruction *DestructionWarlock) registerImmolate() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return destruction.CalcScalingSpellDmg(immolateCoeff) }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedMagicCrit, - false, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedMagicCrit, + SkipHasteNormalization: false, + ModifyResult: nil, + }) }, }) } diff --git a/sim/warrior/passives.go b/sim/warrior/passives.go index b9d978e25e..334413a80e 100644 --- a/sim/warrior/passives.go +++ b/sim/warrior/passives.go @@ -92,15 +92,18 @@ func (warrior *Warrior) registerDeepWounds() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(sim, target, useSnapshot, - func(s *core.Spell, u *core.Unit) float64 { + return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + Sim: sim, + Target: target, + UseSnapshot: useSnapshot, + BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return warrior.CalcScalingSpellDmg(deepWoundsCoeff) + deepWoundsBonusCoeff*s.MeleeAttackPower() }, - dot.OutcomeExpectedSnapshotCrit, - spell.OutcomeExpectedPhysicalCrit, - true, - nil, - ) + SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, + NormalCrit: spell.OutcomeExpectedPhysicalCrit, + SkipHasteNormalization: true, + ModifyResult: nil, + }) }, }) From 1f2cb0d2226ceda4c975ae36aa7f46370cc5c599 Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Wed, 3 Sep 2025 10:03:10 -0500 Subject: [PATCH 3/7] Remove nil since swapped to cfg, remove dot from ModifyResult function from previous iteration, Add ModifyDamage that is called before Normalization, general cleanups --- sim/core/dot.go | 29 +++++++++++-------- sim/druid/balance/sunfire.go | 9 ++---- sim/druid/moonfire.go | 9 ++---- sim/druid/rake.go | 10 +++---- sim/druid/rip.go | 10 +++---- sim/druid/thrash.go | 9 ++---- sim/hunter/pet_abilities.go | 9 ++---- sim/mage/fire/combustion.go | 10 +++---- sim/priest/_shadow_word_pain.go | 7 ++--- sim/priest/shadow/mind_flay.go | 9 ++---- sim/priest/shadow/talents.go | 9 ++---- sim/priest/shadow_word_pain.go | 9 ++---- sim/priest/vampiric_touch.go | 9 ++---- sim/warlock/affliction/agony.go | 12 ++++---- sim/warlock/affliction/unstable_affliction.go | 9 ++---- sim/warlock/corruption.go | 9 ++---- sim/warlock/demonology/doom.go | 9 ++---- sim/warlock/destruction/immolate.go | 9 ++---- sim/warrior/passives.go | 9 ++---- 19 files changed, 76 insertions(+), 119 deletions(-) diff --git a/sim/core/dot.go b/sim/core/dot.go index 058caf2b7d..03d1579501 100644 --- a/sim/core/dot.go +++ b/sim/core/dot.go @@ -495,39 +495,44 @@ func (dot *Dot) RestoreState(state DotState, sim *Simulation) { } type ExpectedTickConfig struct { - Sim *Simulation - Target *Unit UseSnapshot bool BaseDmgFn func(*Spell, *Unit) float64 // for non-snapshot damage calc - SnapshotCrit OutcomeApplier - NormalCrit OutcomeApplier - SkipHasteNormalization bool // disables haste normalization - ModifyResult func(*SpellResult, *Dot) // optional final tweaks, apply multipliers, add crit mods + SnapshotOutcome OutcomeApplier + NormalOutcome OutcomeApplier + ModifyDamage func(*SpellResult) // Modifies Damage before hasteNormalization + SkipHasteNormalization bool // disables haste normalization + ModifyResult func(*SpellResult) // optional final tweaks, apply multipliers, add crit mods } -func (dot *Dot) CalcExpectedTickDamage(cfg ExpectedTickConfig) *SpellResult { +func (dot *Dot) CalcExpectedTickDamage(sim *Simulation, target *Unit, cfg ExpectedTickConfig) *SpellResult { if cfg.UseSnapshot { - result := dot.CalcSnapshotDamage(cfg.Sim, cfg.Target, cfg.SnapshotCrit) + result := dot.CalcSnapshotDamage(sim, target, cfg.SnapshotOutcome) + if cfg.ModifyDamage != nil { + cfg.ModifyDamage(result) + } if !cfg.SkipHasteNormalization { result.Damage /= dot.TickPeriod().Seconds() } if cfg.ModifyResult != nil { - cfg.ModifyResult(result, dot) + cfg.ModifyResult(result) } return result } baseDamage := 0.0 if cfg.BaseDmgFn != nil { - baseDamage = cfg.BaseDmgFn(dot.Spell, cfg.Target) + baseDamage = cfg.BaseDmgFn(dot.Spell, target) } - result := dot.Spell.CalcPeriodicDamage(cfg.Sim, cfg.Target, baseDamage, cfg.NormalCrit) + result := dot.Spell.CalcPeriodicDamage(sim, target, baseDamage, cfg.NormalOutcome) + if cfg.ModifyDamage != nil { + cfg.ModifyDamage(result) + } if !cfg.SkipHasteNormalization { result.Damage /= dot.CalcTickPeriod().Round(time.Millisecond).Seconds() } if cfg.ModifyResult != nil { - cfg.ModifyResult(result, dot) + cfg.ModifyResult(result) } return result } diff --git a/sim/druid/balance/sunfire.go b/sim/druid/balance/sunfire.go index 23f8336834..74a0d68601 100644 --- a/sim/druid/balance/sunfire.go +++ b/sim/druid/balance/sunfire.go @@ -69,17 +69,14 @@ func (moonkin *BalanceDruid) registerSunfireDoTSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return moonkin.CalcScalingSpellDmg(SunfireDotCoeff) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/druid/moonfire.go b/sim/druid/moonfire.go index 7aab6a3592..8357302751 100644 --- a/sim/druid/moonfire.go +++ b/sim/druid/moonfire.go @@ -68,17 +68,14 @@ func (druid *Druid) registerMoonfireDoTSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return druid.CalcScalingSpellDmg(MoonfireDotCoeff) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/druid/rake.go b/sim/druid/rake.go index fd18d30e46..6b9c0d9628 100644 --- a/sim/druid/rake.go +++ b/sim/druid/rake.go @@ -75,17 +75,15 @@ func (druid *Druid) registerRakeSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return flatBaseDamage + bonusCoefficientFromAP*spell.MeleeAttackPower() }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicAlwaysHit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicAlwaysHit, SkipHasteNormalization: true, - ModifyResult: func(sr *core.SpellResult, d *core.Dot) { + ModifyResult: func(sr *core.SpellResult) { attackTable := spell.Unit.AttackTables[target.UnitIndex] critChance := spell.PhysicalCritChance(attackTable) critMod := (critChance * (spell.CritMultiplier - 1)) diff --git a/sim/druid/rip.go b/sim/druid/rip.go index df7455da76..9b49219d1c 100644 --- a/sim/druid/rip.go +++ b/sim/druid/rip.go @@ -84,19 +84,17 @@ func (druid *Druid) registerRipSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { cp := 5.0 // Hard-code this so that snapshotting calculations can be performed at any CP value. ap := spell.MeleeAttackPower() return baseDamage + comboPointCoeff*cp + attackPowerCoeff*cp*ap }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicAlwaysHit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicAlwaysHit, SkipHasteNormalization: true, - ModifyResult: func(sr *core.SpellResult, d *core.Dot) { + ModifyResult: func(sr *core.SpellResult) { if !useSnapshot { attackTable := spell.Unit.AttackTables[target.UnitIndex] critChance := spell.PhysicalCritChance(attackTable) diff --git a/sim/druid/thrash.go b/sim/druid/thrash.go index 33072f7d63..80868c525f 100644 --- a/sim/druid/thrash.go +++ b/sim/druid/thrash.go @@ -140,17 +140,14 @@ func (druid *Druid) registerThrashCatSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return flatTickDamage + 0.141*spell.MeleeAttackPower() }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedPhysicalCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedPhysicalCrit, SkipHasteNormalization: true, - ModifyResult: nil, }) }, diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go index bbeaa1685a..2e8f46e514 100644 --- a/sim/hunter/pet_abilities.go +++ b/sim/hunter/pet_abilities.go @@ -350,17 +350,14 @@ func (hp *HunterPet) newFrostStormBreath() *core.Spell { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return 206 + (spell.MeleeAttackPower() * 0.40) }, - SnapshotCrit: nil, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: nil, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: true, - ModifyResult: nil, }) }, }) diff --git a/sim/mage/fire/combustion.go b/sim/mage/fire/combustion.go index 8198a76bb6..fa393f1901 100644 --- a/sim/mage/fire/combustion.go +++ b/sim/mage/fire/combustion.go @@ -91,17 +91,15 @@ func (fire *FireMage) registerCombustionSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return calculatedDotTick(sim, target) }, - SnapshotCrit: nil, - NormalCrit: spell.OutcomeExpectedMagicAlwaysHit, + SnapshotOutcome: nil, + NormalOutcome: spell.OutcomeExpectedMagicAlwaysHit, SkipHasteNormalization: true, - ModifyResult: func(sr *core.SpellResult, d *core.Dot) { + ModifyResult: func(sr *core.SpellResult) { critChance := spell.SpellCritChance(target) critMod := (critChance * (spell.CritMultiplier - 1)) sr.Damage *= 1 + critMod diff --git a/sim/priest/_shadow_word_pain.go b/sim/priest/_shadow_word_pain.go index 16bb35a989..f235f5e86e 100644 --- a/sim/priest/_shadow_word_pain.go +++ b/sim/priest/_shadow_word_pain.go @@ -64,17 +64,16 @@ func (priest *Priest) registerShadowWordPainSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ Sim: sim, Target: target, UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/priest/shadow/mind_flay.go b/sim/priest/shadow/mind_flay.go index 0536ea6ab3..f2511fc79c 100644 --- a/sim/priest/shadow/mind_flay.go +++ b/sim/priest/shadow/mind_flay.go @@ -56,17 +56,14 @@ func (shadow *ShadowPriest) registerMindFlaySpell() *core.Spell { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, - SnapshotCrit: nil, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: nil, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: true, - ModifyResult: nil, }) }, }) diff --git a/sim/priest/shadow/talents.go b/sim/priest/shadow/talents.go index 4a7175008f..607f8d57fa 100644 --- a/sim/priest/shadow/talents.go +++ b/sim/priest/shadow/talents.go @@ -107,17 +107,14 @@ func (shadow *ShadowPriest) registerSolaceAndInstanity() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, - SnapshotCrit: nil, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: nil, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: true, - ModifyResult: nil, }) }, ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { diff --git a/sim/priest/shadow_word_pain.go b/sim/priest/shadow_word_pain.go index b3a5f6e17b..7039808e44 100644 --- a/sim/priest/shadow_word_pain.go +++ b/sim/priest/shadow_word_pain.go @@ -62,17 +62,14 @@ func (priest *Priest) registerShadowWordPainSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/priest/vampiric_touch.go b/sim/priest/vampiric_touch.go index 8ce91047b3..54ec68fb0a 100644 --- a/sim/priest/vampiric_touch.go +++ b/sim/priest/vampiric_touch.go @@ -61,17 +61,14 @@ func (priest *Priest) registerVampiricTouchSpell() { }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return priest.CalcScalingSpellDmg(VtScaleCoeff) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/warlock/affliction/agony.go b/sim/warlock/affliction/agony.go index b0c7cfbfdb..345d648070 100644 --- a/sim/warlock/affliction/agony.go +++ b/sim/warlock/affliction/agony.go @@ -72,20 +72,18 @@ func (affliction *AfflictionWarlock) registerAgony() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return affliction.CalcScalingSpellDmg(agonyScale) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, - ModifyResult: func(sr *core.SpellResult, d *core.Dot) { + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, + ModifyDamage: func(sr *core.SpellResult) { // Always compare fully stacked agony damage sr.Damage *= 10 }, + SkipHasteNormalization: false, }) }, }) diff --git a/sim/warlock/affliction/unstable_affliction.go b/sim/warlock/affliction/unstable_affliction.go index b09ce43c7b..664c84f98a 100644 --- a/sim/warlock/affliction/unstable_affliction.go +++ b/sim/warlock/affliction/unstable_affliction.go @@ -55,17 +55,14 @@ func (affliction *AfflictionWarlock) registerUnstableAffliction() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return affliction.CalcScalingSpellDmg(uaScale) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/warlock/corruption.go b/sim/warlock/corruption.go index bceccf7508..f11d2acd47 100644 --- a/sim/warlock/corruption.go +++ b/sim/warlock/corruption.go @@ -57,17 +57,14 @@ func (warlock *Warlock) RegisterCorruption(callback WarlockSpellCastedCallback) }, ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return warlock.CalcScalingSpellDmg(corruptionScale) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/warlock/demonology/doom.go b/sim/warlock/demonology/doom.go index 3c89019b65..361d7f2307 100644 --- a/sim/warlock/demonology/doom.go +++ b/sim/warlock/demonology/doom.go @@ -56,17 +56,14 @@ func (demonology *DemonologyWarlock) registerDoom() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return demonology.CalcScalingSpellDmg(doomScale) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/warlock/destruction/immolate.go b/sim/warlock/destruction/immolate.go index eeebd47724..e5eb97da16 100644 --- a/sim/warlock/destruction/immolate.go +++ b/sim/warlock/destruction/immolate.go @@ -100,17 +100,14 @@ func (destruction *DestructionWarlock) registerImmolate() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return destruction.CalcScalingSpellDmg(immolateCoeff) }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedMagicCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: false, - ModifyResult: nil, }) }, }) diff --git a/sim/warrior/passives.go b/sim/warrior/passives.go index 334413a80e..bc7261af4c 100644 --- a/sim/warrior/passives.go +++ b/sim/warrior/passives.go @@ -92,17 +92,14 @@ func (warrior *Warrior) registerDeepWounds() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) - return dot.CalcExpectedTickDamage(core.ExpectedTickConfig{ - Sim: sim, - Target: target, + return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { return warrior.CalcScalingSpellDmg(deepWoundsCoeff) + deepWoundsBonusCoeff*s.MeleeAttackPower() }, - SnapshotCrit: dot.OutcomeExpectedSnapshotCrit, - NormalCrit: spell.OutcomeExpectedPhysicalCrit, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedPhysicalCrit, SkipHasteNormalization: true, - ModifyResult: nil, }) }, }) From 69058beb9b1623edc0758c55d6f3f69518879d0a Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Wed, 3 Sep 2025 10:14:08 -0500 Subject: [PATCH 4/7] Remove *unit since target is already available in function --- sim/core/dot.go | 4 ++-- sim/druid/balance/sunfire.go | 2 +- sim/druid/moonfire.go | 2 +- sim/druid/rake.go | 2 +- sim/druid/rip.go | 2 +- sim/druid/thrash.go | 2 +- sim/hunter/pet_abilities.go | 2 +- sim/mage/fire/combustion.go | 2 +- sim/priest/_shadow_word_pain.go | 2 +- sim/priest/shadow/mind_flay.go | 2 +- sim/priest/shadow/talents.go | 2 +- sim/priest/shadow_word_pain.go | 2 +- sim/priest/vampiric_touch.go | 2 +- sim/warlock/affliction/agony.go | 2 +- sim/warlock/affliction/unstable_affliction.go | 2 +- sim/warlock/corruption.go | 2 +- sim/warlock/demonology/doom.go | 2 +- sim/warlock/destruction/immolate.go | 2 +- sim/warrior/passives.go | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/sim/core/dot.go b/sim/core/dot.go index e0ff519b17..afd3f81693 100644 --- a/sim/core/dot.go +++ b/sim/core/dot.go @@ -497,7 +497,7 @@ func (dot *Dot) RestoreState(state DotState, sim *Simulation) { type ExpectedTickConfig struct { UseSnapshot bool - BaseDmgFn func(*Spell, *Unit) float64 // for non-snapshot damage calc + BaseDmgFn func(*Spell) float64 // for non-snapshot damage calc SnapshotOutcome OutcomeApplier NormalOutcome OutcomeApplier ModifyDamage func(*SpellResult) // Modifies Damage before hasteNormalization @@ -522,7 +522,7 @@ func (dot *Dot) CalcExpectedTickDamage(sim *Simulation, target *Unit, cfg Expect baseDamage := 0.0 if cfg.BaseDmgFn != nil { - baseDamage = cfg.BaseDmgFn(dot.Spell, target) + baseDamage = cfg.BaseDmgFn(dot.Spell) } result := dot.Spell.CalcPeriodicDamage(sim, target, baseDamage, cfg.NormalOutcome) diff --git a/sim/druid/balance/sunfire.go b/sim/druid/balance/sunfire.go index 74a0d68601..1ad05707e9 100644 --- a/sim/druid/balance/sunfire.go +++ b/sim/druid/balance/sunfire.go @@ -71,7 +71,7 @@ func (moonkin *BalanceDruid) registerSunfireDoTSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return moonkin.CalcScalingSpellDmg(SunfireDotCoeff) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/druid/moonfire.go b/sim/druid/moonfire.go index 8357302751..e7fb431211 100644 --- a/sim/druid/moonfire.go +++ b/sim/druid/moonfire.go @@ -70,7 +70,7 @@ func (druid *Druid) registerMoonfireDoTSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return druid.CalcScalingSpellDmg(MoonfireDotCoeff) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/druid/rake.go b/sim/druid/rake.go index 6b9c0d9628..c9dbbaca40 100644 --- a/sim/druid/rake.go +++ b/sim/druid/rake.go @@ -77,7 +77,7 @@ func (druid *Druid) registerRakeSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return flatBaseDamage + bonusCoefficientFromAP*spell.MeleeAttackPower() }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/druid/rip.go b/sim/druid/rip.go index 9b49219d1c..c3a94ec5d7 100644 --- a/sim/druid/rip.go +++ b/sim/druid/rip.go @@ -86,7 +86,7 @@ func (druid *Druid) registerRipSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { cp := 5.0 // Hard-code this so that snapshotting calculations can be performed at any CP value. ap := spell.MeleeAttackPower() return baseDamage + comboPointCoeff*cp + attackPowerCoeff*cp*ap diff --git a/sim/druid/thrash.go b/sim/druid/thrash.go index 80868c525f..bd76c52554 100644 --- a/sim/druid/thrash.go +++ b/sim/druid/thrash.go @@ -142,7 +142,7 @@ func (druid *Druid) registerThrashCatSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return flatTickDamage + 0.141*spell.MeleeAttackPower() }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go index 2e8f46e514..23fc168989 100644 --- a/sim/hunter/pet_abilities.go +++ b/sim/hunter/pet_abilities.go @@ -352,7 +352,7 @@ func (hp *HunterPet) newFrostStormBreath() *core.Spell { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return 206 + (spell.MeleeAttackPower() * 0.40) }, SnapshotOutcome: nil, diff --git a/sim/mage/fire/combustion.go b/sim/mage/fire/combustion.go index fa393f1901..e699fa01aa 100644 --- a/sim/mage/fire/combustion.go +++ b/sim/mage/fire/combustion.go @@ -93,7 +93,7 @@ func (fire *FireMage) registerCombustionSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return calculatedDotTick(sim, target) }, SnapshotOutcome: nil, diff --git a/sim/priest/_shadow_word_pain.go b/sim/priest/_shadow_word_pain.go index f235f5e86e..b5a382cc56 100644 --- a/sim/priest/_shadow_word_pain.go +++ b/sim/priest/_shadow_word_pain.go @@ -68,7 +68,7 @@ func (priest *Priest) registerShadowWordPainSpell() { Sim: sim, Target: target, UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/priest/shadow/mind_flay.go b/sim/priest/shadow/mind_flay.go index f2511fc79c..5553f4774f 100644 --- a/sim/priest/shadow/mind_flay.go +++ b/sim/priest/shadow/mind_flay.go @@ -58,7 +58,7 @@ func (shadow *ShadowPriest) registerMindFlaySpell() *core.Spell { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, SnapshotOutcome: nil, diff --git a/sim/priest/shadow/talents.go b/sim/priest/shadow/talents.go index 607f8d57fa..85d4c47ba4 100644 --- a/sim/priest/shadow/talents.go +++ b/sim/priest/shadow/talents.go @@ -109,7 +109,7 @@ func (shadow *ShadowPriest) registerSolaceAndInstanity() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: false, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, SnapshotOutcome: nil, diff --git a/sim/priest/shadow_word_pain.go b/sim/priest/shadow_word_pain.go index 7039808e44..2dbd5a3064 100644 --- a/sim/priest/shadow_word_pain.go +++ b/sim/priest/shadow_word_pain.go @@ -64,7 +64,7 @@ func (priest *Priest) registerShadowWordPainSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/priest/vampiric_touch.go b/sim/priest/vampiric_touch.go index 54ec68fb0a..e11bc4d3ff 100644 --- a/sim/priest/vampiric_touch.go +++ b/sim/priest/vampiric_touch.go @@ -63,7 +63,7 @@ func (priest *Priest) registerVampiricTouchSpell() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(VtScaleCoeff) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/warlock/affliction/agony.go b/sim/warlock/affliction/agony.go index 345d648070..16e248299d 100644 --- a/sim/warlock/affliction/agony.go +++ b/sim/warlock/affliction/agony.go @@ -74,7 +74,7 @@ func (affliction *AfflictionWarlock) registerAgony() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return affliction.CalcScalingSpellDmg(agonyScale) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/warlock/affliction/unstable_affliction.go b/sim/warlock/affliction/unstable_affliction.go index 664c84f98a..501785c6e4 100644 --- a/sim/warlock/affliction/unstable_affliction.go +++ b/sim/warlock/affliction/unstable_affliction.go @@ -57,7 +57,7 @@ func (affliction *AfflictionWarlock) registerUnstableAffliction() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return affliction.CalcScalingSpellDmg(uaScale) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/warlock/corruption.go b/sim/warlock/corruption.go index f11d2acd47..f75c69db59 100644 --- a/sim/warlock/corruption.go +++ b/sim/warlock/corruption.go @@ -59,7 +59,7 @@ func (warlock *Warlock) RegisterCorruption(callback WarlockSpellCastedCallback) dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return warlock.CalcScalingSpellDmg(corruptionScale) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/warlock/demonology/doom.go b/sim/warlock/demonology/doom.go index 361d7f2307..5faba85d2c 100644 --- a/sim/warlock/demonology/doom.go +++ b/sim/warlock/demonology/doom.go @@ -58,7 +58,7 @@ func (demonology *DemonologyWarlock) registerDoom() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return demonology.CalcScalingSpellDmg(doomScale) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/warlock/destruction/immolate.go b/sim/warlock/destruction/immolate.go index e5eb97da16..ab9197d8ff 100644 --- a/sim/warlock/destruction/immolate.go +++ b/sim/warlock/destruction/immolate.go @@ -102,7 +102,7 @@ func (destruction *DestructionWarlock) registerImmolate() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return destruction.CalcScalingSpellDmg(immolateCoeff) }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, diff --git a/sim/warrior/passives.go b/sim/warrior/passives.go index bc7261af4c..b465f44fea 100644 --- a/sim/warrior/passives.go +++ b/sim/warrior/passives.go @@ -94,7 +94,7 @@ func (warrior *Warrior) registerDeepWounds() { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ UseSnapshot: useSnapshot, - BaseDmgFn: func(s *core.Spell, u *core.Unit) float64 { + BaseDmgFn: func(s *core.Spell) float64 { return warrior.CalcScalingSpellDmg(deepWoundsCoeff) + deepWoundsBonusCoeff*s.MeleeAttackPower() }, SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, From 52fdaf539a3eaf56e20c05179ec0d07bff26c818 Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Wed, 3 Sep 2025 11:32:25 -0500 Subject: [PATCH 5/7] more cleanups --- sim/druid/balance/sunfire.go | 5 ++--- sim/druid/moonfire.go | 5 ++--- sim/hunter/pet_abilities.go | 1 - sim/mage/fire/combustion.go | 1 - sim/priest/_shadow_word_pain.go | 5 ++--- sim/priest/shadow/mind_flay.go | 1 - sim/priest/shadow/talents.go | 1 - sim/priest/shadow_word_pain.go | 5 ++--- sim/priest/vampiric_touch.go | 5 ++--- sim/warlock/affliction/agony.go | 1 - sim/warlock/affliction/unstable_affliction.go | 5 ++--- sim/warlock/corruption.go | 5 ++--- sim/warlock/demonology/doom.go | 5 ++--- sim/warlock/destruction/immolate.go | 5 ++--- 14 files changed, 18 insertions(+), 32 deletions(-) diff --git a/sim/druid/balance/sunfire.go b/sim/druid/balance/sunfire.go index 1ad05707e9..0b8ca0a911 100644 --- a/sim/druid/balance/sunfire.go +++ b/sim/druid/balance/sunfire.go @@ -74,9 +74,8 @@ func (moonkin *BalanceDruid) registerSunfireDoTSpell() { BaseDmgFn: func(s *core.Spell) float64 { return moonkin.CalcScalingSpellDmg(SunfireDotCoeff) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/druid/moonfire.go b/sim/druid/moonfire.go index e7fb431211..c8b4c3cbec 100644 --- a/sim/druid/moonfire.go +++ b/sim/druid/moonfire.go @@ -73,9 +73,8 @@ func (druid *Druid) registerMoonfireDoTSpell() { BaseDmgFn: func(s *core.Spell) float64 { return druid.CalcScalingSpellDmg(MoonfireDotCoeff) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go index 23fc168989..322f3d4515 100644 --- a/sim/hunter/pet_abilities.go +++ b/sim/hunter/pet_abilities.go @@ -355,7 +355,6 @@ func (hp *HunterPet) newFrostStormBreath() *core.Spell { BaseDmgFn: func(s *core.Spell) float64 { return 206 + (spell.MeleeAttackPower() * 0.40) }, - SnapshotOutcome: nil, NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: true, }) diff --git a/sim/mage/fire/combustion.go b/sim/mage/fire/combustion.go index e699fa01aa..c523f7c62e 100644 --- a/sim/mage/fire/combustion.go +++ b/sim/mage/fire/combustion.go @@ -96,7 +96,6 @@ func (fire *FireMage) registerCombustionSpell() { BaseDmgFn: func(s *core.Spell) float64 { return calculatedDotTick(sim, target) }, - SnapshotOutcome: nil, NormalOutcome: spell.OutcomeExpectedMagicAlwaysHit, SkipHasteNormalization: true, ModifyResult: func(sr *core.SpellResult) { diff --git a/sim/priest/_shadow_word_pain.go b/sim/priest/_shadow_word_pain.go index b5a382cc56..b3fdb2a7ae 100644 --- a/sim/priest/_shadow_word_pain.go +++ b/sim/priest/_shadow_word_pain.go @@ -71,9 +71,8 @@ func (priest *Priest) registerShadowWordPainSpell() { BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/priest/shadow/mind_flay.go b/sim/priest/shadow/mind_flay.go index 5553f4774f..8f262c4579 100644 --- a/sim/priest/shadow/mind_flay.go +++ b/sim/priest/shadow/mind_flay.go @@ -61,7 +61,6 @@ func (shadow *ShadowPriest) registerMindFlaySpell() *core.Spell { BaseDmgFn: func(s *core.Spell) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, - SnapshotOutcome: nil, NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: true, }) diff --git a/sim/priest/shadow/talents.go b/sim/priest/shadow/talents.go index 85d4c47ba4..4e562f0134 100644 --- a/sim/priest/shadow/talents.go +++ b/sim/priest/shadow/talents.go @@ -112,7 +112,6 @@ func (shadow *ShadowPriest) registerSolaceAndInstanity() { BaseDmgFn: func(s *core.Spell) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, - SnapshotOutcome: nil, NormalOutcome: spell.OutcomeExpectedMagicCrit, SkipHasteNormalization: true, }) diff --git a/sim/priest/shadow_word_pain.go b/sim/priest/shadow_word_pain.go index 2dbd5a3064..db19973f31 100644 --- a/sim/priest/shadow_word_pain.go +++ b/sim/priest/shadow_word_pain.go @@ -67,9 +67,8 @@ func (priest *Priest) registerShadowWordPainSpell() { BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/priest/vampiric_touch.go b/sim/priest/vampiric_touch.go index e11bc4d3ff..d39312ab6b 100644 --- a/sim/priest/vampiric_touch.go +++ b/sim/priest/vampiric_touch.go @@ -66,9 +66,8 @@ func (priest *Priest) registerVampiricTouchSpell() { BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(VtScaleCoeff) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/warlock/affliction/agony.go b/sim/warlock/affliction/agony.go index 16e248299d..9c40f2a4a1 100644 --- a/sim/warlock/affliction/agony.go +++ b/sim/warlock/affliction/agony.go @@ -83,7 +83,6 @@ func (affliction *AfflictionWarlock) registerAgony() { // Always compare fully stacked agony damage sr.Damage *= 10 }, - SkipHasteNormalization: false, }) }, }) diff --git a/sim/warlock/affliction/unstable_affliction.go b/sim/warlock/affliction/unstable_affliction.go index 501785c6e4..94e30f0460 100644 --- a/sim/warlock/affliction/unstable_affliction.go +++ b/sim/warlock/affliction/unstable_affliction.go @@ -60,9 +60,8 @@ func (affliction *AfflictionWarlock) registerUnstableAffliction() { BaseDmgFn: func(s *core.Spell) float64 { return affliction.CalcScalingSpellDmg(uaScale) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/warlock/corruption.go b/sim/warlock/corruption.go index f75c69db59..0469a09a5a 100644 --- a/sim/warlock/corruption.go +++ b/sim/warlock/corruption.go @@ -62,9 +62,8 @@ func (warlock *Warlock) RegisterCorruption(callback WarlockSpellCastedCallback) BaseDmgFn: func(s *core.Spell) float64 { return warlock.CalcScalingSpellDmg(corruptionScale) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/warlock/demonology/doom.go b/sim/warlock/demonology/doom.go index 5faba85d2c..e37eb18c5c 100644 --- a/sim/warlock/demonology/doom.go +++ b/sim/warlock/demonology/doom.go @@ -61,9 +61,8 @@ func (demonology *DemonologyWarlock) registerDoom() { BaseDmgFn: func(s *core.Spell) float64 { return demonology.CalcScalingSpellDmg(doomScale) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) diff --git a/sim/warlock/destruction/immolate.go b/sim/warlock/destruction/immolate.go index ab9197d8ff..49f65b716e 100644 --- a/sim/warlock/destruction/immolate.go +++ b/sim/warlock/destruction/immolate.go @@ -105,9 +105,8 @@ func (destruction *DestructionWarlock) registerImmolate() { BaseDmgFn: func(s *core.Spell) float64 { return destruction.CalcScalingSpellDmg(immolateCoeff) }, - SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, - NormalOutcome: spell.OutcomeExpectedMagicCrit, - SkipHasteNormalization: false, + SnapshotOutcome: dot.OutcomeExpectedSnapshotCrit, + NormalOutcome: spell.OutcomeExpectedMagicCrit, }) }, }) From 25d84dc25ebd1c8f1530c7e7dc7b75437f2253d6 Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Wed, 3 Sep 2025 11:38:52 -0500 Subject: [PATCH 6/7] removed setting to default values since...they are default values --- sim/hunter/pet_abilities.go | 1 - sim/mage/fire/combustion.go | 1 - sim/priest/shadow/mind_flay.go | 1 - sim/priest/shadow/talents.go | 1 - 4 files changed, 4 deletions(-) diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go index 322f3d4515..b8cc8dcb75 100644 --- a/sim/hunter/pet_abilities.go +++ b/sim/hunter/pet_abilities.go @@ -351,7 +351,6 @@ func (hp *HunterPet) newFrostStormBreath() *core.Spell { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ - UseSnapshot: false, BaseDmgFn: func(s *core.Spell) float64 { return 206 + (spell.MeleeAttackPower() * 0.40) }, diff --git a/sim/mage/fire/combustion.go b/sim/mage/fire/combustion.go index c523f7c62e..fc979bb5d1 100644 --- a/sim/mage/fire/combustion.go +++ b/sim/mage/fire/combustion.go @@ -92,7 +92,6 @@ func (fire *FireMage) registerCombustionSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ - UseSnapshot: false, BaseDmgFn: func(s *core.Spell) float64 { return calculatedDotTick(sim, target) }, diff --git a/sim/priest/shadow/mind_flay.go b/sim/priest/shadow/mind_flay.go index 8f262c4579..a84491de6a 100644 --- a/sim/priest/shadow/mind_flay.go +++ b/sim/priest/shadow/mind_flay.go @@ -57,7 +57,6 @@ func (shadow *ShadowPriest) registerMindFlaySpell() *core.Spell { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ - UseSnapshot: false, BaseDmgFn: func(s *core.Spell) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, diff --git a/sim/priest/shadow/talents.go b/sim/priest/shadow/talents.go index 4e562f0134..a6868f223a 100644 --- a/sim/priest/shadow/talents.go +++ b/sim/priest/shadow/talents.go @@ -108,7 +108,6 @@ func (shadow *ShadowPriest) registerSolaceAndInstanity() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ - UseSnapshot: false, BaseDmgFn: func(s *core.Spell) float64 { return shadow.CalcScalingSpellDmg(MfScale) }, From babcd11dd217435eb2fc4f5001a8d67f565b1d82 Mon Sep 17 00:00:00 2001 From: MR-Valdez Date: Wed, 3 Sep 2025 11:42:15 -0500 Subject: [PATCH 7/7] keep _swp inline with regular file --- sim/priest/_shadow_word_pain.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/sim/priest/_shadow_word_pain.go b/sim/priest/_shadow_word_pain.go index b3fdb2a7ae..145d9d2ea5 100644 --- a/sim/priest/_shadow_word_pain.go +++ b/sim/priest/_shadow_word_pain.go @@ -65,8 +65,6 @@ func (priest *Priest) registerShadowWordPainSpell() { ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { dot := spell.Dot(target) return dot.CalcExpectedTickDamage(sim, target, core.ExpectedTickConfig{ - Sim: sim, - Target: target, UseSnapshot: useSnapshot, BaseDmgFn: func(s *core.Spell) float64 { return priest.CalcScalingSpellDmg(SwpScaleCoeff)