Skip to content

Commit

Permalink
[core] add specialized GetMeleeProcMaskForItem() and GetMeleeProcMask…
Browse files Browse the repository at this point in the history
…ForEnchant() methods, to simplify the typical use cases (GetWeaponHands() has been removed, and most usages of GetMeleeProcMaskForHands() outside of shaman imbues have been replaced)

[core] improve PPMManager to do less procMask matching
[all] related changes, including cleanup of PPMManager usages
[druid] OOC auto attack handling has been specialized, to prevent repetitive setup work for nearly every spell hit
  • Loading branch information
vigo2 committed Aug 25, 2023
1 parent 3fcac17 commit 0ea047f
Show file tree
Hide file tree
Showing 24 changed files with 267 additions and 369 deletions.
53 changes: 21 additions & 32 deletions sim/common/tbc/enchant_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,12 @@ func init() {
})

// ApplyCrusaderEffect will be applied twice if there is two weapons with this enchant.
// However it will automatically overwrite one of them so it should be ok.
// However, it will automatically overwrite one of them, so it should be ok.
// A single application of the aura will handle both mh and oh procs.
core.NewEnchantEffect(1900, func(agent core.Agent) {
character := agent.GetCharacter()
mh := character.Equip[proto.ItemSlot_ItemSlotMainHand].Enchant.EffectID == 1900
oh := character.Equip[proto.ItemSlot_ItemSlotOffHand].Enchant.EffectID == 1900
if !mh && !oh {
return
}
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForEnchant(1900)
ppmm := character.AutoAttacks.NewPPMManager(1.0, procMask)

// -4 str per level over 60
Expand All @@ -80,7 +76,7 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) {
if !result.Landed() {
return
}

Expand All @@ -102,13 +98,12 @@ func init() {
})

// ApplyMongooseEffect will be applied twice if there is two weapons with this enchant.
// However it will automatically overwrite one of them so it should be ok.
// However, it will automatically overwrite one of them, so it should be ok.
// A single application of the aura will handle both mh and oh procs.
core.NewEnchantEffect(2673, func(agent core.Agent) {
character := agent.GetCharacter()
mh := character.Equip[proto.ItemSlot_ItemSlotMainHand].Enchant.EffectID == 2673
oh := character.Equip[proto.ItemSlot_ItemSlotOffHand].Enchant.EffectID == 2673
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForEnchant(2673)
ppmm := character.AutoAttacks.NewPPMManager(0.73, procMask)

mhAura := character.NewTemporaryStatsAura("Lightning Speed MH", core.ActionID{SpellID: 28093, Tag: 1}, stats.Stats{stats.MeleeHaste: 30.0, stats.Agility: 120}, time.Second*15)
Expand All @@ -121,7 +116,7 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) {
if !result.Landed() {
return
}

Expand Down Expand Up @@ -155,12 +150,8 @@ func init() {

core.NewEnchantEffect(3225, func(agent core.Agent) {
character := agent.GetCharacter()
mh := character.Equip[proto.ItemSlot_ItemSlotMainHand].Enchant.EffectID == 3225
oh := character.Equip[proto.ItemSlot_ItemSlotOffHand].Enchant.EffectID == 3225
if !mh && !oh {
return
}
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForEnchant(3225)
ppmm := character.AutoAttacks.NewPPMManager(1.0, procMask)

procAura := character.NewTemporaryStatsAura("Executioner Proc", core.ActionID{SpellID: 42976}, stats.Stats{stats.ArmorPenetration: 120}, time.Second*15)
Expand All @@ -172,7 +163,7 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) {
if !result.Landed() {
return
}

Expand Down Expand Up @@ -212,16 +203,14 @@ func init() {
}

if spell.ProcMask.Matches(core.ProcMaskMelee) {
if !ppmm.Proc(sim, spell.ProcMask, "Deathfrost") {
return
if ppmm.Proc(sim, spell.ProcMask, "Deathfrost") {
procSpell.Cast(sim, result.Target)
}
procSpell.Cast(sim, result.Target)
} else if spell.ProcMask.Matches(core.ProcMaskSpellDamage) {
if !icd.IsReady(sim) || sim.RandomFloat("Deathfrost") > 0.5 {
return
if icd.IsReady(sim) && sim.RandomFloat("Deathfrost") < 0.5 {
icd.Use(sim)
procSpell.Cast(sim, result.Target)
}
icd.Use(sim)
procSpell.Cast(sim, result.Target)
}
},
})
Expand All @@ -230,9 +219,9 @@ func init() {
}
core.NewEnchantEffect(3273, func(agent core.Agent) {
character := agent.GetCharacter()
mh := character.Equip[proto.ItemSlot_ItemSlotMainHand].Enchant.EffectID == 3273
oh := character.Equip[proto.ItemSlot_ItemSlotOffHand].Enchant.EffectID == 3273
if !mh && !oh {

procMask := character.GetMeleeProcMaskForEnchant(3273)
if procMask == core.ProcMaskUnknown {
return
}

Expand Down Expand Up @@ -272,10 +261,10 @@ func init() {
},
})

if mh {
if procMask.Matches(core.ProcMaskMeleeMH) {
applyDeathfrostForWeapon(character, procSpell, true)
}
if oh {
if procMask.Matches(core.ProcMaskMeleeOH) {
applyDeathfrostForWeapon(character, procSpell, false)
}
})
Expand Down
77 changes: 36 additions & 41 deletions sim/common/tbc/melee_items.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func init() {

core.NewItemEffect(19019, func(agent core.Agent) {
character := agent.GetCharacter()
mh, oh := character.GetWeaponHands(19019)
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForItem(19019)
ppmm := character.AutoAttacks.NewPPMManager(6.0, procMask)

procActionID := core.ActionID{SpellID: 21992}
Expand Down Expand Up @@ -89,15 +89,14 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(procMask) {
return
}
if !ppmm.Proc(sim, spell.ProcMask, "Thunderfury") {
if !result.Landed() {
return
}

singleTargetSpell.Cast(sim, result.Target)
bounceSpell.Cast(sim, result.Target)
if ppmm.Proc(sim, spell.ProcMask, "Thunderfury") {
singleTargetSpell.Cast(sim, result.Target)
bounceSpell.Cast(sim, result.Target)
}
},
})
})
Expand Down Expand Up @@ -156,29 +155,28 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
// mask 340
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMeleeOrRanged) {
if !result.Landed() {
return
}

if !icd.IsReady(sim) {
return
}
if !ppmm.Proc(sim, spell.ProcMask, "Band of the Eternal Champion") {
return
}

icd.Use(sim)
procAura.Activate(sim)
if ppmm.Proc(sim, spell.ProcMask, "Band of the Eternal Champion") {
icd.Use(sim)
procAura.Activate(sim)
}
},
})
})

core.NewItemEffect(29996, func(agent core.Agent) {
character := agent.GetCharacter()
mh, oh := character.GetWeaponHands(29996)
procMask := core.GetMeleeProcMaskForHands(mh, oh)

const procChance = 2.7 / 60.0
procMask := character.GetMeleeProcMaskForItem(29996)
pppm := character.AutoAttacks.NewPPMManager(1.0, procMask)

actionID := core.ActionID{ItemID: 29996}

var resourceMetricsRage *core.ResourceMetrics
Expand All @@ -197,30 +195,26 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(procMask) {
if !result.Landed() {
return
}

cpb := spell.Unit.GetCurrentPowerBar()
if cpb == core.RageBar {
if sim.RandomFloat("Rod of the Sun King") > procChance {
return
}
spell.Unit.AddRage(sim, 5, resourceMetricsRage)
} else if cpb == core.EnergyBar {
if sim.RandomFloat("Rod of the Sun King") > procChance {
return
if pppm.Proc(sim, spell.ProcMask, "Rod of the Sun King") {
switch spell.Unit.GetCurrentPowerBar() {
case core.RageBar:
spell.Unit.AddRage(sim, 5, resourceMetricsRage)
case core.EnergyBar:
spell.Unit.AddEnergy(sim, 10, resourceMetricsEnergy)
}
spell.Unit.AddEnergy(sim, 10, resourceMetricsEnergy)
}
},
})
})

core.NewItemEffect(31193, func(agent core.Agent) {
character := agent.GetCharacter()
mh, oh := character.GetWeaponHands(31193)
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForItem(31193)

procSpell := character.GetOrRegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: 24585},
Expand Down Expand Up @@ -252,8 +246,8 @@ func init() {

core.NewItemEffect(32262, func(agent core.Agent) {
character := agent.GetCharacter()
mh, oh := character.GetWeaponHands(32262)
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForItem(32262)
ppmm := character.AutoAttacks.NewPPMManager(1.0, procMask)

procSpell := character.GetOrRegisterSpell(core.SpellConfig{
Expand Down Expand Up @@ -290,7 +284,7 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) {
if !result.Landed() {
return
}

Expand Down Expand Up @@ -358,25 +352,26 @@ func init() {

core.NewItemEffect(12590, func(agent core.Agent) {
character := agent.GetCharacter()
effectAura := character.NewTemporaryStatsAura("Felstriker Proc", core.ActionID{SpellID: 16551}, stats.Stats{stats.MeleeCrit: 100 * core.CritRatingPerCritChance}, time.Second*3)
mh, oh := character.GetWeaponHands(12590)
procMask := core.GetMeleeProcMaskForHands(mh, oh)

procMask := character.GetMeleeProcMaskForItem(12590)
ppmm := character.AutoAttacks.NewPPMManager(1.0, procMask)

effectAura := character.NewTemporaryStatsAura("Felstriker Proc", core.ActionID{SpellID: 16551}, stats.Stats{stats.MeleeCrit: 100 * core.CritRatingPerCritChance}, time.Second*3)

character.GetOrRegisterAura(core.Aura{
Label: "Felstriker",
Duration: core.NeverExpires,
OnReset: func(aura *core.Aura, sim *core.Simulation) {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(procMask) {
if !result.Landed() {
return
}
if !ppmm.Proc(sim, spell.ProcMask, "Felstriker") {
return

if ppmm.Proc(sim, spell.ProcMask, "Felstriker") {
effectAura.Activate(sim)
}
effectAura.Activate(sim)
},
})
})
Expand Down
23 changes: 8 additions & 15 deletions sim/common/tbc/melee_sets.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var ItemSetFistsOfFury = core.NewItemSet(core.ItemSet{
},
})

ppmm := character.AutoAttacks.NewPPMManager(2, core.ProcMaskMelee)
ppmm := character.AutoAttacks.NewPPMManager(2.0, core.ProcMaskMelee)

character.RegisterAura(core.Aura{
Label: "Fists of Fury",
Expand All @@ -39,14 +39,13 @@ var ItemSetFistsOfFury = core.NewItemSet(core.ItemSet{
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) {
return
}
if !ppmm.Proc(sim, spell.ProcMask, "The Fists of Fury") {
if !result.Landed() {
return
}

procSpell.Cast(sim, result.Target)
if ppmm.Proc(sim, spell.ProcMask, "The Fists of Fury") {
procSpell.Cast(sim, result.Target)
}
},
})
},
Expand Down Expand Up @@ -157,20 +156,14 @@ var ItemSetTwinBladesOfAzzinoth = core.NewItemSet(core.ItemSet{
return
}

// https://wotlk.wowhead.com/spell=41434/the-twin-blades-of-azzinoth, proc mask = 20.
if !spell.ProcMask.Matches(core.ProcMaskMelee) {
return
}

if !icd.IsReady(sim) {
return
}

if !ppmm.Proc(sim, spell.ProcMask, "Twin Blades of Azzinoth") {
return
if ppmm.Proc(sim, spell.ProcMask, "Twin Blades of Azzinoth") {
icd.Use(sim)
procAura.Activate(sim)
}
icd.Use(sim)
procAura.Activate(sim)
},
})
},
Expand Down
23 changes: 10 additions & 13 deletions sim/common/tbc/melee_trinkets.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,18 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
// mask: 340
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMeleeOrRanged) {
if !result.Landed() {
return
}

if !icd.IsReady(sim) {
return
}
if !ppmm.Proc(sim, spell.ProcMask, "dragonspine") {
return
}
icd.Use(sim)

procAura.Activate(sim)
if ppmm.Proc(sim, spell.ProcMask, "dragonspine") {
icd.Use(sim)
procAura.Activate(sim)
}
},
})
})
Expand Down Expand Up @@ -158,15 +157,13 @@ func init() {
aura.Activate(sim)
},
OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
// mask 340
if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMeleeOrRanged) {
return
}
if !ppmm.Proc(sim, spell.ProcMask, "Madness of the Betrayer") {
if !result.Landed() {
return
}

procAura.Activate(sim)
if ppmm.Proc(sim, spell.ProcMask, "Madness of the Betrayer") {
procAura.Activate(sim)
}
},
})
})
Expand Down
Loading

0 comments on commit 0ea047f

Please sign in to comment.