diff --git a/sim/core/aura.go b/sim/core/aura.go index 0f1cddbc60..f20b4c0446 100644 --- a/sim/core/aura.go +++ b/sim/core/aura.go @@ -213,6 +213,9 @@ func (aura *Aura) SetStacks(sim *Simulation, newStacks int32) { func (aura *Aura) AddStack(sim *Simulation) { aura.SetStacks(sim, aura.stacks+1) } +func (aura *Aura) AddStacks(sim *Simulation, numStacks int32) { + aura.SetStacks(sim, aura.stacks+numStacks) +} func (aura *Aura) RemoveStack(sim *Simulation) { aura.SetStacks(sim, aura.stacks-1) } diff --git a/sim/druid/balance/TestBalance.results b/sim/druid/balance/TestBalance.results index d78936c454..3f42b9c887 100644 --- a/sim/druid/balance/TestBalance.results +++ b/sim/druid/balance/TestBalance.results @@ -114,8 +114,8 @@ dps_results: { dps_results: { key: "TestBalance-Average-Default" value: { - dps: 55.49145 - tps: 56.41221 + dps: 55.39244 + tps: 56.3132 } } dps_results: { @@ -135,29 +135,29 @@ dps_results: { dps_results: { key: "TestBalance-Settings-Tauren-25-phase_1-Default-phase_1-FullBuffs-Full Consumes-ShortSingleTarget" value: { - dps: 60.14399 - tps: 64.74619 + dps: 58.03327 + tps: 62.63547 } } dps_results: { key: "TestBalance-Settings-Tauren-25-phase_1-Default-phase_1-NoBuffs-Full Consumes-LongMultiTarget" value: { - dps: 52.66508 - tps: 52.66508 + dps: 52.58487 + tps: 52.58487 } } dps_results: { key: "TestBalance-Settings-Tauren-25-phase_1-Default-phase_1-NoBuffs-Full Consumes-LongSingleTarget" value: { - dps: 52.66508 - tps: 52.66508 + dps: 52.58487 + tps: 52.58487 } } dps_results: { key: "TestBalance-Settings-Tauren-25-phase_1-Default-phase_1-NoBuffs-Full Consumes-ShortSingleTarget" value: { - dps: 58.82808 - tps: 58.82808 + dps: 56.75419 + tps: 56.75419 } } dps_results: { diff --git a/sim/druid/runes.go b/sim/druid/runes.go index f8ab268430..cbdb64c090 100644 --- a/sim/druid/runes.go +++ b/sim/druid/runes.go @@ -1,6 +1,7 @@ package druid import ( + "slices" "time" "github.com/wowsims/sod/sim/core" @@ -41,31 +42,33 @@ func (druid *Druid) applyEclipse() { solarCritBonus := 30.0 lunarCastTimeReduction := time.Second * 1 + var affectedSolarSpells []*DruidSpell + var affectedLunarSpells []*DruidSpell + // Solar druid.SolarEclipseProcAura = druid.RegisterAura(core.Aura{ Label: "Solar Eclipse proc", Duration: time.Second * 15, MaxStacks: 4, ActionID: core.ActionID{SpellID: 408250}, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - core.Each( - core.FilterSlice(druid.Wrath, func(spell *DruidSpell) bool { return spell != nil }), - func(spell *DruidSpell) { - spell.BonusCritRating += solarCritBonus - }, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + affectedSolarSpells = core.FilterSlice( + core.Flatten([][]*DruidSpell{druid.Wrath, {druid.Starsurge}}), + func(spell *DruidSpell) bool { return spell != nil }, ) }, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + core.Each(affectedSolarSpells, func(spell *DruidSpell) { + spell.BonusCritRating += solarCritBonus + }) + }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { - core.Each( - core.FilterSlice(druid.Wrath, func(spell *DruidSpell) bool { return spell != nil }), - func(spell *DruidSpell) { - spell.BonusCritRating -= solarCritBonus - }, - ) + core.Each(affectedSolarSpells, func(spell *DruidSpell) { + spell.BonusCritRating -= solarCritBonus + }) }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - // Assert we are casting wrath - if !result.Landed() || spell.SpellCode != SpellCode_DruidWrath { + OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { + if spell.SpellCode != SpellCode_DruidWrath && spell.SpellCode != SpellCode_DruidStarsurge { return } @@ -79,25 +82,24 @@ func (druid *Druid) applyEclipse() { Duration: time.Second * 15, MaxStacks: 4, ActionID: core.ActionID{SpellID: 408255}, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - core.Each( - core.FilterSlice(druid.Starfire, func(spell *DruidSpell) bool { return spell != nil }), - func(spell *DruidSpell) { - spell.DefaultCast.CastTime -= lunarCastTimeReduction - }, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + affectedLunarSpells = core.FilterSlice( + core.Flatten([][]*DruidSpell{druid.Starfire}), + func(spell *DruidSpell) bool { return spell != nil }, ) }, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + core.Each(affectedLunarSpells, func(spell *DruidSpell) { + spell.DefaultCast.CastTime -= lunarCastTimeReduction + }) + }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { - core.Each( - core.FilterSlice(druid.Starfire, func(spell *DruidSpell) bool { return spell != nil }), - func(spell *DruidSpell) { - spell.DefaultCast.CastTime += lunarCastTimeReduction - }, - ) + core.Each(affectedLunarSpells, func(spell *DruidSpell) { + spell.DefaultCast.CastTime += lunarCastTimeReduction + }) }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - // Assert we are casting Starfire - if !result.Landed() || spell.SpellCode != SpellCode_DruidStarfire { + OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { + if spell.SpellCode != SpellCode_DruidStarfire { return } @@ -113,20 +115,20 @@ func (druid *Druid) applyEclipse() { aura.Activate(sim) }, OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - switch spell.SpellCode { - case SpellCode_DruidWrath: - // Proc Lunar + if !slices.Contains([]int32{SpellCode_DruidWrath, SpellCode_DruidStarfire, SpellCode_DruidStarsurge}, spell.SpellCode) || !result.Landed() { + return + } + + if spell.SpellCode == SpellCode_DruidWrath || spell.SpellCode == SpellCode_DruidStarsurge { druid.LunarEclipseProcAura.Activate(sim) - // Wrath gives 1 stack of starfire bonus + // Solar gives 1 stack of lunar bonus druid.LunarEclipseProcAura.AddStack(sim) - case SpellCode_DruidStarfire: - // Proc Solar + } + + if spell.SpellCode == SpellCode_DruidStarfire || spell.SpellCode == SpellCode_DruidStarsurge { druid.SolarEclipseProcAura.Activate(sim) - // Starfire gives 2 staacks of wrath bonus - druid.SolarEclipseProcAura.AddStack(sim) - druid.SolarEclipseProcAura.AddStack(sim) - default: - return + // Lunar gives 2 staacks of solar bonus + druid.SolarEclipseProcAura.AddStacks(sim, 2) } }, }) @@ -214,6 +216,8 @@ func (druid *Druid) applyStarsurge() { ProcMask: core.ProcMaskSpellDamage, Flags: core.SpellFlagAPL | core.SpellFlagResetAttackSwing, + MissileSpeed: 24, + ManaCost: core.ManaCostOptions{ BaseCost: 0.01 * (1 - 0.03*float64(druid.Talents.Moonglow)), }, @@ -234,7 +238,11 @@ func (druid *Druid) applyStarsurge() { ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { baseDamage := sim.Roll(baseLowDamage, baseHighDamage)*druid.MoonfuryDamageMultiplier() + spell.SpellDamage() - spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMagicHitAndCrit) + result := spell.CalcDamage(sim, target, baseDamage, spell.OutcomeMagicHitAndCrit) + + spell.WaitTravelTime(sim, func(sim *core.Simulation) { + spell.DealDamage(sim, result) + }) }, }) }