diff --git a/sim/common/sod/item_effects/phase_8.go b/sim/common/sod/item_effects/phase_8.go index 795639e20c..57550d98df 100644 --- a/sim/common/sod/item_effects/phase_8.go +++ b/sim/common/sod/item_effects/phase_8.go @@ -245,21 +245,53 @@ func init() { core.NewItemEffect(Deception, func(agent core.Agent) { character := agent.GetCharacter() + isMH := character.GetMHWeapon().ID == Deception + procMaskAura := core.Ternary(isMH, core.ProcMaskMeleeMH, core.ProcMaskMeleeOH) + + spellProc := character.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 1231552}, + SpellSchool: core.SpellSchoolPhysical, + DefenseType: core.DefenseTypeMelee, + ProcMask: core.ProcMaskMeleeMHAuto, // Normal Melee Attack Flag + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell | core.SpellFlagSuppressWeaponProcs, // Cannot proc Oil, Poisons, and presumably Weapon Enchants or Procs(Chance on Hit) + CastType: proto.CastType_CastTypeMainHand, + + DamageMultiplier: 1.0, + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + baseDamage := spell.Unit.MHWeaponDamage(sim, spell.MeleeAttackPower()) + spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit) + }, + }) + + character.NewRageMetrics(spellProc.ActionID) + spellProc.ResourceMetrics = character.NewRageMetrics(spellProc.ActionID) + // Use a dummy to set a flag for the set bonus that doubles the extra attacks var setAura *core.Aura triggerAura := core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ - Name: "Deception Trigger", + ActionID: core.ActionID{SpellID: 1231553}, + Name: "Deception Proc", Callback: core.CallbackOnSpellHitDealt, Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskMelee, - SpellFlagsExclude: core.SpellFlagSuppressWeaponProcs, + ProcMask: procMaskAura, + SpellFlagsExclude: core.SpellFlagSuppressEquipProcs, ProcChance: 0.02, ICD: time.Millisecond * 100, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - spell.Unit.AutoAttacks.ExtraMHAttackProc(sim, core.TernaryInt32(setAura != nil && setAura.IsActive(), 2, 1), core.ActionID{SpellID: 1231555}, spell) + if (setAura != nil && setAura.IsActive()) { + return + } else { + spellProc.Cast(sim, result.Target) + } }, }).ApplyOnGain(func(aura *core.Aura, sim *core.Simulation) { setAura = character.GetAura("Tools of the Nathrezim") + + if setAura != nil { + procMaskAura = core.ProcMaskMelee + } }) character.ItemSwap.RegisterProc(Deception, triggerAura) @@ -270,18 +302,46 @@ func init() { core.NewItemEffect(Duplicity, func(agent core.Agent) { character := agent.GetCharacter() + isMH := character.GetMHWeapon().ID == Duplicity + procMaskAura := core.Ternary(isMH, core.ProcMaskMeleeMH, core.ProcMaskMeleeOH) + + spellProc := character.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 1231555}, + SpellSchool: core.SpellSchoolPhysical, + DefenseType: core.DefenseTypeMelee, + ProcMask: core.ProcMaskMeleeMHAuto, // Normal Melee Attack Flag + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell | core.SpellFlagSuppressWeaponProcs, // Cannot proc Oil, Poisons, and presumably Weapon Enchants or Procs(Chance on Hit) + CastType: proto.CastType_CastTypeMainHand, + + DamageMultiplier: 1, + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + baseDamage := spell.Unit.MHWeaponDamage(sim, spell.MeleeAttackPower()) + spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit) + }, + }) + + character.NewRageMetrics(spellProc.ActionID) + spellProc.ResourceMetrics = character.NewRageMetrics(spellProc.ActionID) + // Use a dummy to set a flag for the set bonus that doubles the extra attacks var setAura *core.Aura triggerAura := core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ - Name: "Duplicity Trigger", + ActionID: core.ActionID{SpellID: 1231554}, + Name: "Duplicity Proc", Callback: core.CallbackOnSpellHitDealt, Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskMelee, - SpellFlagsExclude: core.SpellFlagSuppressWeaponProcs, + ProcMask: procMaskAura, + SpellFlagsExclude: core.SpellFlagSuppressEquipProcs, ProcChance: 0.02, ICD: time.Millisecond * 100, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - spell.Unit.AutoAttacks.ExtraMHAttackProc(sim, core.TernaryInt32(setAura != nil && setAura.IsActive(), 2, 1), core.ActionID{SpellID: 1231555}, spell) + if (setAura != nil && setAura.IsActive()) { + return + } else { + spellProc.Cast(sim, result.Target) + } }, }).ApplyOnGain(func(aura *core.Aura, sim *core.Simulation) { setAura = character.GetAura("Tools of the Nathrezim") diff --git a/sim/common/sod/items_sets/phase_8.go b/sim/common/sod/items_sets/phase_8.go index 79d5016b54..d86718156f 100644 --- a/sim/common/sod/items_sets/phase_8.go +++ b/sim/common/sod/items_sets/phase_8.go @@ -1,6 +1,8 @@ package item_sets import ( + "time" + "github.com/wowsims/sod/sim/core" "github.com/wowsims/sod/sim/core/proto" "github.com/wowsims/sod/sim/hunter" @@ -61,6 +63,11 @@ var ItemSetHackAndSmash = core.NewItemSet(core.ItemSet{ }, }) +const ( + Deception = 240922 + Duplicity = 240923 +) + // https://www.wowhead.com/classic/item-set=1956/tools-of-the-nathrezim var ItemSetToolsOfTheNathrezim = core.NewItemSet(core.ItemSet{ Name: "Tools of the Nathrezim", @@ -72,6 +79,78 @@ var ItemSetToolsOfTheNathrezim = core.NewItemSet(core.ItemSet{ ActionID: core.ActionID{SpellID: 1231556}, Label: "Tools of the Nathrezim", })) + + // Duplicity + spellProcSetDuplicity := character.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 1231557}, + SpellSchool: core.SpellSchoolPhysical, + DefenseType: core.DefenseTypeMelee, + ProcMask: core.ProcMaskMeleeMHAuto, // Normal Melee Attack Flag + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell | core.SpellFlagSuppressWeaponProcs, // Cannot proc Oil, Poisons, and presumably Weapon Enchants or Procs(Chance on Hit) + CastType: proto.CastType_CastTypeMainHand, + + DamageMultiplier: 1, + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + baseDamage := spell.Unit.MHWeaponDamage(sim, spell.MeleeAttackPower()) + spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit) + }, + }) + + character.NewRageMetrics(spellProcSetDuplicity.ActionID) + spellProcSetDuplicity.ResourceMetrics = character.NewRageMetrics(spellProcSetDuplicity.ActionID) + + core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ + ActionID: core.ActionID{SpellID: 1231556}, + Name: "Tools of the Nathrezim (Duplicity)", + Callback: core.CallbackOnSpellHitDealt, + Outcome: core.OutcomeLanded, + ProcMask: core.ProcMaskMelee, // Can proc the Deception Proc + SpellFlagsExclude: core.SpellFlagSuppressEquipProcs, + ProcChance: 0.02, + ICD: time.Millisecond * 100, + Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + spellProcSetDuplicity.Cast(sim, result.Target) + spellProcSetDuplicity.Cast(sim, result.Target) + }, + }) + + // Deception + spellProcSetDeception := character.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 1231558}, + SpellSchool: core.SpellSchoolPhysical, + DefenseType: core.DefenseTypeMelee, + ProcMask: core.ProcMaskMeleeMHAuto, // Normal Melee Attack Flag + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell | core.SpellFlagSuppressWeaponProcs, // Cannot proc Oil, Poisons, and presumably Weapon Enchants or Procs(Chance on Hit) + CastType: proto.CastType_CastTypeMainHand, + + DamageMultiplier: 1, + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + baseDamage := spell.Unit.MHWeaponDamage(sim, spell.MeleeAttackPower()) + spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit) + }, + }) + + character.NewRageMetrics(spellProcSetDeception.ActionID) + spellProcSetDeception.ResourceMetrics = character.NewRageMetrics(spellProcSetDeception.ActionID) + + core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ + ActionID: core.ActionID{SpellID: 1231556}, + Name: "Tools of the Nathrezim (Deception)", + Callback: core.CallbackOnSpellHitDealt, + Outcome: core.OutcomeLanded, + ProcMask: core.ProcMaskMelee, // Can proc the Duplicity Proc + SpellFlagsExclude: core.SpellFlagSuppressEquipProcs, + ProcChance: 0.02, + ICD: time.Millisecond * 100, + Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + spellProcSetDeception.Cast(sim, result.Target) + spellProcSetDeception.Cast(sim, result.Target) + }, + }) }, }, }) diff --git a/sim/warrior/slam.go b/sim/warrior/slam.go index 876fdb5716..e8e6707a40 100644 --- a/sim/warrior/slam.go +++ b/sim/warrior/slam.go @@ -119,7 +119,7 @@ func (warrior *Warrior) newSlamHitSpell(isMH bool) *WarriorSpell { CritDamageBonus: warrior.impale(), FlatThreatBonus: 1 * requiredLevel, - DamageMultiplier: 1, + DamageMultiplier: core.Ternary(isMH, 1.0, warrior.AutoAttacks.OHConfig().DamageMultiplier), ThreatMultiplier: 1, BonusCoefficient: 1, diff --git a/sim/warrior/talents.go b/sim/warrior/talents.go index f2ac5c9330..8ec09b94cd 100644 --- a/sim/warrior/talents.go +++ b/sim/warrior/talents.go @@ -193,11 +193,8 @@ func (warrior *Warrior) applyDualWieldSpecialization() { } multiplier := 1 + 0.05*float64(warrior.Talents.DualWieldSpecialization) - warrior.OnSpellRegistered(func(spell *core.Spell) { - if spell.ProcMask.Matches(core.ProcMaskMeleeOH) && spell.BonusCoefficient > 0 { - spell.ApplyMultiplicativeDamageBonus(multiplier) - } - }) + + warrior.AutoAttacks.OHConfig().DamageMultiplier *= multiplier } func (warrior *Warrior) applyEnrage() { diff --git a/sim/warrior/whirlwind.go b/sim/warrior/whirlwind.go index 9fcbc5d20e..6a16881bbd 100644 --- a/sim/warrior/whirlwind.go +++ b/sim/warrior/whirlwind.go @@ -70,7 +70,7 @@ func (warrior *Warrior) newWhirlwindHitSpell(isMH bool) *WarriorSpell { CritDamageBonus: warrior.impale(), - DamageMultiplier: 1, + DamageMultiplier: core.Ternary(isMH, 1.0, warrior.AutoAttacks.OHConfig().DamageMultiplier), ThreatMultiplier: 1.25, BonusCoefficient: 1,