Skip to content

Commit

Permalink
find mind-sear channel clipping in APL
Browse files Browse the repository at this point in the history
  • Loading branch information
lime-green committed Oct 22, 2023
1 parent da78d1c commit f08cb11
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 71 deletions.
4 changes: 0 additions & 4 deletions sim/core/apl.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,6 @@ func (apl *APLRotation) getNextAction(sim *Simulation) *APLAction {

func (apl *APLRotation) shouldInterruptChannel(sim *Simulation) bool {
channeledDot := apl.unit.ChanneledDot
if channeledDot == nil {
// Cast was started by a different APL action (not Channel) so is non-interruptible.
return false
}

if channeledDot.MaxTicksRemaining() == 0 {
// Channel has ended, but apl.unit.ChanneledDot hasn't been cleared yet meaning the aura is still active.
Expand Down
1 change: 0 additions & 1 deletion sim/core/apl_actions_casting.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package core

import (
"fmt"

"github.com/wowsims/wotlk/sim/core/proto"
)

Expand Down
1 change: 0 additions & 1 deletion sim/priest/mind_flay.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ func (priest *Priest) getMindFlayTickSpell(numTicks int32) *core.Spell {
ActionID: core.ActionID{SpellID: 58381}.WithTag(numTicks),
SpellSchool: core.SpellSchoolShadow,
ProcMask: core.ProcMaskProc | core.ProcMaskNotInSpellbook,
Flags: core.SpellFlagNoLogs,
BonusHitRating: float64(priest.Talents.ShadowFocus) * 1 * core.SpellHitRatingPerHitChance,
BonusCritRating: 0 +
float64(priest.Talents.MindMelt)*2*core.CritRatingPerCritChance +
Expand Down
137 changes: 72 additions & 65 deletions sim/priest/mind_sear.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,43 @@ import (
"github.com/wowsims/wotlk/sim/core/proto"
)

// TODO see Mind Flay: Mind Sear (53023) now "periodically triggers" Mind Sear (53022).
// Since Mind Flay no longer is a binary spell, Mind Sear likely isn't, either.
func (priest *Priest) getMindSearMiseryCoefficient() float64 {
return 0.2861 * (1 + 0.05*float64(priest.Talents.Misery))
}

func (priest *Priest) getMindSearBaseConfig() core.SpellConfig {
return core.SpellConfig{
SpellSchool: core.SpellSchoolShadow,
ProcMask: core.ProcMaskProc,
BonusHitRating: float64(priest.Talents.ShadowFocus) * 1 * core.SpellHitRatingPerHitChance,
BonusCritRating: float64(priest.Talents.MindMelt) * 2 * core.CritRatingPerCritChance,
DamageMultiplier: 1 +
0.02*float64(priest.Talents.Darkness) +
0.01*float64(priest.Talents.TwinDisciplines),
ThreatMultiplier: 1 - 0.08*float64(priest.Talents.ShadowAffinity),
CritMultiplier: priest.DefaultSpellCritMultiplier(),
}
}

func (priest *Priest) getMindSearTickSpell(numTicks int32) *core.Spell {
hasGlyphOfShadow := priest.HasGlyph(int32(proto.PriestMajorGlyph_GlyphOfShadow))
miseryCoeff := priest.getMindSearMiseryCoefficient()

config := priest.getMindSearBaseConfig()
config.ActionID = core.ActionID{SpellID: 49821}.WithTag(numTicks)
config.ApplyEffects = func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
damage := sim.Roll(212, 228) + miseryCoeff*spell.SpellPower()
result := spell.CalcAndDealDamage(sim, target, damage, spell.OutcomeMagicHitAndCrit)

if result.Landed() {
priest.AddShadowWeavingStack(sim)
}
if result.DidCrit() && hasGlyphOfShadow {
priest.ShadowyInsightAura.Activate(sim)
}
}
return priest.GetOrRegisterSpell(config)
}

func (priest *Priest) newMindSearSpell(numTicksIdx int32) *core.Spell {
numTicks := numTicksIdx
Expand All @@ -20,74 +55,46 @@ func (priest *Priest) newMindSearSpell(numTicksIdx int32) *core.Spell {
}

channelTime := time.Second * time.Duration(numTicks)
miseryCoeff := 0.2861 * (1 + 0.05*float64(priest.Talents.Misery))
hasGlyphOfShadow := priest.HasGlyph(int32(proto.PriestMajorGlyph_GlyphOfShadow))
miseryCoeff := priest.getMindSearMiseryCoefficient()
mindSearTickSpell := priest.getMindSearTickSpell(numTicksIdx)

return priest.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: 53023, Tag: numTicksIdx},
SpellSchool: core.SpellSchoolShadow,
ProcMask: core.ProcMaskSpellDamage,
Flags: flags,

ManaCost: core.ManaCostOptions{
BaseCost: 0.28,
Multiplier: 1 - 0.05*float64(priest.Talents.FocusedMind),
},
Cast: core.CastConfig{
DefaultCast: core.Cast{
GCD: core.GCDDefault,
ChannelTime: channelTime,
},
config := priest.getMindSearBaseConfig()
config.ActionID = core.ActionID{SpellID: 53023}.WithTag(numTicksIdx)
config.Flags = flags
config.ManaCost = core.ManaCostOptions{
BaseCost: 0.28,
Multiplier: 1 - 0.05*float64(priest.Talents.FocusedMind),
}
config.Cast = core.CastConfig{
DefaultCast: core.Cast{
GCD: core.GCDDefault,
ChannelTime: channelTime,
},

BonusHitRating: float64(priest.Talents.ShadowFocus) * 1 * core.SpellHitRatingPerHitChance,
BonusCritRating: float64(priest.Talents.MindMelt) * 2 * core.CritRatingPerCritChance,
DamageMultiplier: 1 +
0.02*float64(priest.Talents.Darkness) +
0.01*float64(priest.Talents.TwinDisciplines),
ThreatMultiplier: 1 - 0.08*float64(priest.Talents.ShadowAffinity),
CritMultiplier: priest.DefaultSpellCritMultiplier(),
Dot: core.DotConfig{
Aura: core.Aura{
Label: "MindSear-" + strconv.Itoa(int(numTicksIdx)),
},
NumberOfTicks: numTicks,
TickLength: time.Second,
AffectedByCastSpeed: true,

OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, _ bool) {
dot.SnapshotBaseDamage = sim.Roll(212, 228) + miseryCoeff*dot.Spell.SpellPower()
dot.SnapshotCritChance = dot.Spell.SpellCritChance(target)
dot.SnapshotAttackerMultiplier = dot.Spell.AttackerDamageMultiplier(dot.Spell.Unit.AttackTables[target.UnitIndex])
},
OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) {
result := dot.CalcSnapshotDamage(sim, target, dot.OutcomeMagicHitAndSnapshotCrit)
dot.Spell.DealDamage(sim, result)

if result.Landed() {
priest.AddShadowWeavingStack(sim)
}
if result.DidCrit() && hasGlyphOfShadow {
priest.ShadowyInsightAura.Activate(sim)
}
},
}
config.Dot = core.DotConfig{
Aura: core.Aura{
Label: "MindSear-" + strconv.Itoa(int(numTicksIdx)),
},
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
NumberOfTicks: numTicks,
TickLength: time.Second,
AffectedByCastSpeed: true,
OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) {
for _, aoeTarget := range sim.Encounter.TargetUnits {
if aoeTarget != sim.Encounter.TargetUnits[0] {

result := spell.CalcOutcome(sim, aoeTarget, spell.OutcomeMagicHit)
if result.Landed() {
spell.SpellMetrics[aoeTarget.UnitIndex].Hits--
spell.Dot(aoeTarget).Apply(sim)
}
spell.DealOutcome(sim, result)
if aoeTarget != target {
mindSearTickSpell.Cast(sim, aoeTarget)
}
}
},
ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult {
baseDamage := sim.Roll(212, 228) + miseryCoeff*spell.SpellPower()
return spell.CalcPeriodicDamage(sim, target, baseDamage, spell.OutcomeExpectedMagicCrit)
},
})
}
config.ApplyEffects = func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
result := spell.CalcAndDealOutcome(sim, target, spell.OutcomeMagicHit)
if result.Landed() {
spell.Dot(target).Apply(sim)
}
}
config.ExpectedTickDamage = func(sim *core.Simulation, target *core.Unit, spell *core.Spell, _ bool) *core.SpellResult {
baseDamage := sim.Roll(212, 228) + miseryCoeff*spell.SpellPower()
return spell.CalcPeriodicDamage(sim, target, baseDamage, spell.OutcomeExpectedMagicCrit)
}
return priest.GetOrRegisterSpell(config)
}

0 comments on commit f08cb11

Please sign in to comment.