diff --git a/sim/common/vanilla/item_effects.go b/sim/common/vanilla/item_effects.go index 9a326598b..49157dba4 100644 --- a/sim/common/vanilla/item_effects.go +++ b/sim/common/vanilla/item_effects.go @@ -17,6 +17,7 @@ const ( Bloodrazor = 809 HammerOfTheNorthernWind = 810 FlurryAxe = 871 + ManualCrowdPummeler = 9449 SkullflameShield = 1168 Nightblade = 1982 Shadowblade = 2163 @@ -125,6 +126,8 @@ func init() { // ! Please keep items ordered alphabetically within a given category ! + // Many referenced from Classic WoW Armaments - https://discord.gg/w95B2hXfBF + /////////////////////////////////////////////////////////////////////////// // Weapons /////////////////////////////////////////////////////////////////////////// @@ -417,8 +420,10 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=9511/bloodletter-scalpel itemhelpers.CreateWeaponCoHProcDamage(BloodletterScalpel, "Bloodletter Scalpel", 1.0, 18081, core.SpellSchoolPhysical, 60, 10, 0, core.DefenseTypeMelee) + // https://www.wowhead.com/classic/item=809/bloodrazor itemhelpers.CreateWeaponProcSpell(Bloodrazor, "Bloodrazor", 1.0, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 17504}, @@ -474,6 +479,8 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=2825/bow-of-searing-arrows + // Equip: Chance to strike your ranged target with a Searing Arrow for 18 to 26 Fire damage. itemhelpers.CreateWeaponProcSpell(BowOfSearingArrows, "Bow of Searing Arrows", 3.35, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 29638}, @@ -548,7 +555,6 @@ func init() { // https://www.wowhead.com/classic/item=17112/empyrean-demolisher // Chance on hit: Increases your attack speed by 20% for 10 sec. - // Original proc rate 1.0 lowered to 0.6 in SoD phase 5 itemhelpers.CreateWeaponProcAura(EmpyreanDemolisher, "Empyrean Demolisher", 1.0, func(character *core.Character) *core.Aura { return character.GetOrRegisterAura(core.Aura{ Label: "Empyrean Demolisher Haste Aura", @@ -601,7 +607,6 @@ func init() { // https://www.wowhead.com/classic/item=18203/eskhandars-right-claw // Chance on hit: Increases your attack speed by 30% for 5 sec. - // Original proc rate 1.0 lowered to 0.6 in SoD phase 5 itemhelpers.CreateWeaponProcAura(EskhandarsRightClaw, "Eskhandar's Right Claw", 1.0, func(character *core.Character) *core.Aura { return character.GetOrRegisterAura(core.Aura{ Label: "Eskhandar's Rage", @@ -648,7 +653,6 @@ func init() { // https://www.wowhead.com/classic/item=12590/felstriker // Chance on hit: All attacks are guaranteed to land and will be critical strikes for the next 3 sec. - // Original proc rate 1.0 lowered to 0.6 in SoD phase 5 core.NewItemEffect(Felstriker, func(agent core.Agent) { character := agent.GetCharacter() @@ -660,13 +664,14 @@ func init() { Outcome: core.OutcomeLanded, ProcMask: procMask, SpellFlagsExclude: core.SpellFlagSuppressWeaponProcs, - PPM: 0.6, + PPM: 1, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { effectAura.Activate(sim) }, }) }) + // https://www.wowhead.com/classic/item=18310/fiendish-machete core.NewItemEffect(FiendishMachete, func(agent core.Agent) { character := agent.GetCharacter() @@ -675,6 +680,7 @@ func init() { } }) + // https://www.wowhead.com/classic/item=870/fiery-war-axe itemhelpers.CreateWeaponProcSpell(FieryWarAxe, "Fiery War Axe", 1.0, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 18796}, @@ -974,6 +980,7 @@ func init() { } }) + // https://www.wowhead.com/classic/item=9651/gryphon-riders-stormhammer itemhelpers.CreateWeaponCoHProcDamage(GryphonRidersStormhammer, "Gryphon Rider's Stormhammer", 1.0, 18081, core.SpellSchoolNature, 91, 34, 0, core.DefenseTypeMagic) // https://www.wowhead.com/classic/item=17071/gutgore-ripper @@ -1020,7 +1027,8 @@ func init() { }, }) }) - + + // https://www.wowhead.com/classic/item=5616/gutwrencher itemhelpers.CreateWeaponProcSpell(Gutwrencher, "Gutwrencher", 1.0, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 16406}, @@ -1052,12 +1060,14 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=2164/gut-ripper itemhelpers.CreateWeaponCoHProcDamage(GutRipper, "Gut Ripper", 1.0, 18107, core.SpellSchoolPhysical, 95, 26, 0, core.DefenseTypeMelee) // https://www.wowhead.com/classic/item=19874/halberd-of-smiting // Equip: Chance to decapitate the target on a melee swing, causing 452 to 676 damage. itemhelpers.CreateWeaponEquipProcDamage(HalberdOfSmiting, "Halberd of Smiting", 2.1, 467819, core.SpellSchoolPhysical, 452, 224, 0.0, core.DefenseTypeMelee) // Works as phantom strike + // https://www.wowhead.com/classic/item=810/hammer-of-the-northern-wind itemhelpers.CreateWeaponCoHProcDamage(HammerOfTheNorthernWind, "Hammer of the Northern Wind", 3.5, 13439, core.SpellSchoolFrost, 20, 10, 0, core.DefenseTypeMagic) // https://www.wowhead.com/classic/item=2243/hand-of-edward-the-odd @@ -1079,6 +1089,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=8190/hanzo-sword itemhelpers.CreateWeaponCoHProcDamage(HanzoSword, "Hanzo Sword", 1.0, 16405, core.SpellSchoolPhysical, 75, 0, 0, core.DefenseTypeMelee) // https://www.wowhead.com/classic/item=13937/headmasters-charge @@ -1121,6 +1132,7 @@ func init() { }) }) */ + // https://www.wowhead.com/classic/item=11635/hookfang-shanker itemhelpers.CreateWeaponProcSpell(HookfangShanker, "Hookfang Shanker", 1.0, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 13526}, @@ -1176,10 +1188,13 @@ func init() { // Original proc rate 4.0 lowered to 1.5 in SoD phase 5 itemhelpers.CreateWeaponCoHProcDamage(JekliksCrusher, "Jeklik's Crusher", 4.0, 467642, core.SpellSchoolPhysical, 200, 20, 0.0, core.DefenseTypeMelee) + // https://www.wowhead.com/classic/item=17054/joonhos-mercy itemhelpers.CreateWeaponCoHProcDamage(JoonhosMercy, "Joonho's Mercy", 1.0, 20883, core.SpellSchoolArcane, 70, 0, 0, core.DefenseTypeMagic) + // https://www.wowhead.com/classic/item=21679/kalimdors-revenge itemhelpers.CreateWeaponCoHProcDamage(KalimdorsRevenge, "Kalimdor's Revenge", 1.25, 26415, core.SpellSchoolNature, 239, 38, 0, core.DefenseTypeMagic) // TODO Update PPM/scaling from PTR + // https://www.wowhead.com/classic/item=11902/linkens-sword-of-mastery itemhelpers.CreateWeaponCoHProcDamage(LinkensSwordOfMastery, "Linken's Sword of Mastery", 1.0, 18089, core.SpellSchoolNature, 45, 30, 0, core.DefenseTypeMagic) // https://www.wowhead.com/classic/item=11817/lord-generals-sword @@ -1205,6 +1220,44 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=9449/manual-crowd-pummeler + + core.NewItemEffect(ManualCrowdPummeler, func(agent core.Agent) { + character := agent.GetCharacter() + actionID := core.ActionID{SpellID: 13494} + duration := time.Second * 30 + + mcpAura := character.GetOrRegisterAura(core.Aura{ + Label: "Haste", + ActionID: actionID, + Duration: duration, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + character.MultiplyAttackSpeed(sim, 1.5) + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + character.MultiplyAttackSpeed(sim, 1.0/1.5) + }, + }) + + spell := character.RegisterSpell(core.SpellConfig{ + ActionID: actionID, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, + Cast: core.CastConfig{ + CD: core.Cooldown{ + Timer: character.NewTimer(), + Duration: time.Second * 30, + }, + }, + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + mcpAura.Activate(sim) + }, + }) + character.AddMajorCooldown(core.MajorCooldown{ + Type: core.CooldownTypeDPS, + Spell: spell, + }) + }) + // https://www.wowhead.com/classic/item=12794/masterwork-stormhammer // Chance on hit: Blasts up to 3 targets for 105 to 145 Nature damage. // Estimated based on data from WoW Armaments Discord @@ -1226,6 +1279,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=1982/nightblade itemhelpers.CreateWeaponCoHProcDamage(Nightblade, "Nightblade", 1.0, 18211, core.SpellSchoolShadow, 125, 150, 0, core.DefenseTypeMagic) // https://www.wowhead.com/classic/item=19169/nightfall @@ -1233,8 +1287,10 @@ func init() { makeNightfallProc(agent.GetCharacter(), "Nightfall") }) + // https://www.wowhead.com/classic/item=9425/pendulum-of-doom itemhelpers.CreateWeaponCoHProcDamage(PendulumOfDoom, "Pendulum of Doom", 0.5, 10373, core.SpellSchoolPhysical, 250, 100, 0, core.DefenseTypeMelee) + // https://www.wowhead.com/classic/item=12709/pips-skinner core.NewItemEffect(PipsSkinner, func(agent core.Agent) { character := agent.GetCharacter() @@ -1279,9 +1335,11 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=7717/ravager itemhelpers.CreateWeaponProcAura(Ravager, "Ravager", 1.0, func(character *core.Character) *core.Aura { tickActionID := core.ActionID{SpellID: 9633} procActionID := core.ActionID{SpellID: 9632} + //Used as part of a canceling ravager APL auraActionID := core.ActionID{SpellID: 433801} ravegerBladestormTickSpell := character.GetOrRegisterSpell(core.SpellConfig{ @@ -1360,6 +1418,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=17752/satyrs-lash itemhelpers.CreateWeaponCoHProcDamage(SatyrsLash, "Satyr's Lash", 1.0, 18205, core.SpellSchoolShadow, 55, 30, 0, core.DefenseTypeMagic) // TODO Searing Needle adds an "Apply Aura: Mod Damage Done (Fire): 10" aura to the /target/, buffing it; not currently modelled @@ -1423,6 +1482,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=13035/serpent-slicer itemhelpers.CreateWeaponProcSpell(SerpentSlicer, "Serpent Slicer", 1.0, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 17511}, @@ -1454,6 +1514,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=2163/shadowblade itemhelpers.CreateWeaponCoHProcDamage(Shadowblade, "Shadowblade", 1.0, 18138, core.SpellSchoolShadow, 110, 30, 0, core.DefenseTypeMagic) // https://www.wowhead.com/classic/item=17074/shadowstrike @@ -1477,6 +1538,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=754/shortsword-of-vengeance itemhelpers.CreateWeaponCoHProcDamage(ShortswordOfVengeance, "Shortsword of Vengeance", 1.0, 13519, core.SpellSchoolHoly, 30, 0, 0, core.DefenseTypeMagic) // https://www.wowhead.com/classic/item=13361/skullforge-reaver @@ -1644,6 +1706,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=9639/the-hand-of-antusul itemhelpers.CreateWeaponProcSpell(TheHandOfAntusul, "The Hand of Antu'sul", 1.0, func(character *core.Character) *core.Spell { debuffAuras := character.NewEnemyAuraArray(func(unit *core.Unit, _ int32) *core.Aura { aura := unit.GetOrRegisterAura(core.Aura{ @@ -1679,6 +1742,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=9423/the-jackhammer itemhelpers.CreateWeaponProcAura(TheJackhammer, "The Jackhammer", 1.0, func(character *core.Character) *core.Aura { return character.GetOrRegisterAura(core.Aura{ Label: "The Jackhammer Haste Aura", @@ -1693,6 +1757,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=13060/the-needler itemhelpers.CreateWeaponCoHProcDamage(TheNeedler, "The Needler", 3.0, 13060, core.SpellSchoolPhysical, 75, 0, 0, core.DefenseTypeMelee) // https://www.wowhead.com/classic/item=19334/the-untamed-blade @@ -1713,6 +1778,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=17705/thrash-blade itemhelpers.CreateWeaponProcSpell(ThrashBlade, "Thrash Blade", 1.0, func(character *core.Character) *core.Spell { return character.GetOrRegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 21919}, @@ -1878,8 +1944,10 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=11603/vilerend-slicer itemhelpers.CreateWeaponCoHProcDamage(VilerendSlicer, "Vilerend Slicer", 1.0, 16405, core.SpellSchoolPhysical, 75, 0, 0, core.DefenseTypeMelee) + // https://www.wowhead.com/classic/item=17075/viskag-the-bloodletter itemhelpers.CreateWeaponCoHProcDamage(ViskagTheBloodletter, "Vis'kag the Bloodletter", 0.6, 21140, core.SpellSchoolPhysical, 240, 0, 0, core.DefenseTypeMelee) // https://www.wowhead.com/classic/item=11920/wraith-scythe @@ -1923,14 +1991,14 @@ func init() { OnGain: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range aura.Unit.Spellbook { if spell.Cost != nil && spell.Cost.CostType() == core.CostTypeMana { - spell.Cost.Multiplier -= 100 + spell.Cost.FlatModifier -= 100 } } }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range aura.Unit.Spellbook { if spell.Cost != nil && spell.Cost.CostType() == core.CostTypeMana { - spell.Cost.Multiplier += 100 + spell.Cost.FlatModifier += 100 } } }, @@ -1968,7 +2036,7 @@ func init() { core.NewItemEffect(DarkmoonCardBlueDragon, func(agent core.Agent) { character := agent.GetCharacter() - actionID := core.ActionID{SpellID: 1213421} + actionID := core.ActionID{SpellID: 23688} procAura := character.GetOrRegisterAura(core.Aura{ Label: "Aura of the Blue Dragon", @@ -2029,7 +2097,7 @@ func init() { core.NewItemEffect(DarkmoonCardMaelstrom, func(agent core.Agent) { character := agent.GetCharacter() - actionID := core.ActionID{SpellID: 1213417} + actionID := core.ActionID{SpellID: 23686} procSpell := character.GetOrRegisterSpell(core.SpellConfig{ ActionID: actionID, @@ -2160,7 +2228,7 @@ func init() { // Use: Increases attack power by 65 and an additional 65 every 2 sec. Lasts 20 sec. (2 Min Cooldown) core.NewItemEffect(JomGabbar, func(agent core.Agent) { character := agent.GetCharacter() - actionID := core.ActionID{SpellID: 1213366} + actionID := core.ActionID{SpellID: 29602} duration := time.Second * 20 bonusPerStack := stats.Stats{ stats.AttackPower: 65, @@ -2226,6 +2294,7 @@ func init() { } }) */ + // https://www.wowhead.com/classic/item=17774/mark-of-the-chosen core.NewItemEffect(MarkOfTheChosen, func(agent core.Agent) { character := agent.GetCharacter() statIncrease := float64(25) @@ -2281,6 +2350,7 @@ func init() { } }) + // https://www.wowhead.com/classic/item=21625/scarab-brooch core.NewItemEffect(ScarabBrooch, func(agent core.Agent) { character := agent.GetCharacter() actionID := core.ActionID{ItemID: ScarabBrooch} @@ -2536,6 +2606,7 @@ func init() { }) }) + // https://www.wowhead.com/classic/item=19949/zandalarian-hero-medallion core.NewItemEffect(ZandalariHeroMedallion, func(agent core.Agent) { character := agent.GetCharacter() diff --git a/sim/common/vanilla/item_sets/crafted.go b/sim/common/vanilla/item_sets/crafted.go index 2c7806d86..fc611c820 100644 --- a/sim/common/vanilla/item_sets/crafted.go +++ b/sim/common/vanilla/item_sets/crafted.go @@ -48,6 +48,7 @@ var ItemSetBlueDragonMail = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=443/bloodsoul-embrace var ItemSetBloodsoulEmbrace = core.NewItemSet(core.ItemSet{ Name: "Bloodsoul Embrace", Bonuses: map[int32]core.ApplyEffect{ @@ -59,6 +60,7 @@ var ItemSetBloodsoulEmbrace = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=421/bloodvine-garb var ItemSetBloodvineGarb = core.NewItemSet(core.ItemSet{ Name: "Bloodvine Garb", Bonuses: map[int32]core.ApplyEffect{ @@ -70,6 +72,7 @@ var ItemSetBloodvineGarb = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=442/blood-tiger-harness var ItemSetBloodTigerHarness = core.NewItemSet(core.ItemSet{ Name: "Blood Tiger Harness", Bonuses: map[int32]core.ApplyEffect{ @@ -96,6 +99,7 @@ var ItemSetDevilsaurArmor = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=490/green-dragon-mail var ItemSetGreenDragonMail = core.NewItemSet(core.ItemSet{ Name: "Green Dragon Mail", ID: 490, @@ -113,6 +117,7 @@ var ItemSetGreenDragonMail = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=321/imperial-plate var ItemSetImperialPlate = core.NewItemSet(core.ItemSet{ Name: "Imperial Plate", Bonuses: map[int32]core.ApplyEffect{ @@ -135,6 +140,7 @@ var ItemSetImperialPlate = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=144/ironfeather-armor var ItemSetIronfeatherArmor = core.NewItemSet(core.ItemSet{ Name: "Ironfeather Armor", Bonuses: map[int32]core.ApplyEffect{ @@ -146,6 +152,7 @@ var ItemSetIronfeatherArmor = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=142/stormshroud-armor var ItemSetStormshroudArmor = core.NewItemSet(core.ItemSet{ Name: "Stormshroud Armor", Bonuses: map[int32]core.ApplyEffect{ @@ -166,7 +173,7 @@ var ItemSetStormshroudArmor = core.NewItemSet(core.ItemSet{ }, }) char.RegisterAura(core.Aura{ - Label: "Stormshround Armor 2pc", + Label: "Lightning", ActionID: core.ActionID{SpellID: 18979}, Duration: core.NeverExpires, OnReset: func(aura *core.Aura, sim *core.Simulation) { @@ -176,7 +183,7 @@ var ItemSetStormshroudArmor = core.NewItemSet(core.ItemSet{ if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) { return } - if sim.RandomFloat("Stormshroud Armor 2pc") < 0.05 { + if sim.RandomFloat("Lightning") < 0.05 { proc.Cast(sim, result.Target) } }, @@ -197,7 +204,7 @@ var ItemSetStormshroudArmor = core.NewItemSet(core.ItemSet{ }, }) char.RegisterAura(core.Aura{ - Label: "Stormshround Armor 3pc", + Label: "Revitalize", ActionID: core.ActionID{SpellID: 18979}, Duration: core.NeverExpires, OnReset: func(aura *core.Aura, sim *core.Simulation) { @@ -207,7 +214,7 @@ var ItemSetStormshroudArmor = core.NewItemSet(core.ItemSet{ if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMelee) { return } - if sim.RandomFloat("Stormshroud Armor 3pc") < 0.02 { + if sim.RandomFloat("Revitalize") < 0.02 { proc.Cast(sim, result.Target) } }, @@ -222,6 +229,7 @@ var ItemSetStormshroudArmor = core.NewItemSet(core.ItemSet{ }, }) +// https://www.wowhead.com/classic/item-set=444/the-darksoul var ItemSetTheDarksoul = core.NewItemSet(core.ItemSet{ Name: "The Darksoul", Bonuses: map[int32]core.ApplyEffect{ diff --git a/sim/common/sod/items_sets/dungeon_set_1.go b/sim/common/vanilla/item_sets/dungeon_set_1.go similarity index 58% rename from sim/common/sod/items_sets/dungeon_set_1.go rename to sim/common/vanilla/item_sets/dungeon_set_1.go index f8bac6d9f..66fd5a9e7 100644 --- a/sim/common/sod/items_sets/dungeon_set_1.go +++ b/sim/common/vanilla/item_sets/dungeon_set_1.go @@ -7,6 +7,8 @@ import ( "github.com/wowsims/classic/sim/core/stats" ) +//We can place these in the class items_sets_pve.go if wanted. + var ItemSetWildheartRaiment = core.NewItemSet(core.ItemSet{ Name: "Wildheart Raiment", Bonuses: map[int32]core.ApplyEffect{ @@ -15,56 +17,37 @@ var ItemSetWildheartRaiment = core.NewItemSet(core.ItemSet{ c := agent.GetCharacter() c.AddStat(stats.Armor, 200) }, - // +40 Attack Power, up to 23 increased damage from spells, and up to 44 increased healing from spells. + // +26 Attack Power,increases damage and healing done by magical spells and effects by up to 15. 4: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ - stats.AttackPower: 40, - stats.RangedAttackPower: 40, - stats.SpellDamage: 23, - stats.HealingPower: 44, + stats.AttackPower: 26, + stats.RangedAttackPower: 26, + stats.SpellDamage: 15, + stats.HealingPower: 15, }) }, - // 2% chance on spellcast to energize you for 300 mana, 6% chance on dealing a melee autoattack to energize you for 40 Energy, and 3% chance on being hit by a melee attack to energize you for 10 Rage. + // When struck in combat has a chance of returning 300 mana, 10 rage, or 40 energy to the wearer. 6: func(agent core.Agent) { c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450608} + actionID := core.ActionID{SpellID: 27781} manaMetrics := c.NewManaMetrics(actionID) energyMetrics := c.NewEnergyMetrics(actionID) rageMetrics := c.NewRageMetrics(actionID) core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ ActionID: actionID, - Name: "S03 - Druid Energize Trigger - Wildheart Raiment (Mana)", - Callback: core.CallbackOnCastComplete, - ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, + Name: "Nature's Bounty", + Callback: core.CallbackOnSpellHitTaken, + ProcMask: core.ProcMaskMelee, ProcChance: 0.02, Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { if c.HasManaBar() { c.AddMana(sim, 300, manaMetrics) } - }, - }) - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "S03 - Druid Energize Trigger - Wildheart Raiment (Energy)", - Callback: core.CallbackOnSpellHitDealt, - Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskMeleeWhiteHit, - ProcChance: 0.06, - Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { if c.HasEnergyBar() { c.AddEnergy(sim, 40, energyMetrics) } - }, - }) - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "S03 - Druid Energize Trigger - Wildheart Raiment (Rage)", - Callback: core.CallbackOnSpellHitTaken, - ProcMask: core.ProcMaskMelee, - ProcChance: 0.03, - Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { if c.HasRageBar() { c.AddRage(sim, 10, rageMetrics) } @@ -95,22 +78,22 @@ var ItemSetBeaststalkerArmor = core.NewItemSet(core.ItemSet{ stats.RangedAttackPower: 40, }) }, - // Your melee and ranged autoattacks have a 6% chance to energize you for 300 mana. + // Your normal ranged attacks have a 4% chance of restoring 200 mana. 6: func(agent core.Agent) { c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450577} + actionID := core.ActionID{SpellID: 27785} manaMetrics := c.NewManaMetrics(actionID) core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ ActionID: actionID, - Name: "S03 - Mana Proc on Cast - Beaststalker Armor", + Name: "Hunter Armor Energize", Callback: core.CallbackOnSpellHitDealt, Outcome: core.OutcomeLanded, ProcMask: core.ProcMaskWhiteHit, - ProcChance: 0.06, + ProcChance: 0.04, Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { if c.HasManaBar() { - c.AddMana(sim, 300, manaMetrics) + c.AddMana(sim, 200, manaMetrics) } }, }) @@ -136,25 +119,9 @@ var ItemSetMagistersRegalia = core.NewItemSet(core.ItemSet{ c := agent.GetCharacter() c.AddStat(stats.SpellPower, 23) }, - // Your spellcasts have a 6% chance to energize you for 300 mana. + // When struck in combat has a chance of freezing the attacker in place for 3 sec. 6: func(agent core.Agent) { - c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450527} - manaMetrics := c.NewManaMetrics(actionID) - - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "S03 - Mana Proc on Cast - Magister's Regalia", - Callback: core.CallbackOnSpellHitDealt, - Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, - ProcChance: 0.06, - Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { - if c.HasManaBar() { - c.AddMana(sim, 300, manaMetrics) - } - }, - }) + //Not implemented due to raid boss immunity }, // +8 All Resistances. 8: func(agent core.Agent) { @@ -172,40 +139,31 @@ var ItemSetLightforgeArmor = core.NewItemSet(core.ItemSet{ c := agent.GetCharacter() c.AddStat(stats.Armor, 200) }, - // +40 Attack Power and up to 40 increased healing from spells. + // +40 Attack Power 4: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ stats.AttackPower: 40, stats.RangedAttackPower: 40, - stats.HealingPower: 40, }) }, - // 6% chance on melee autoattack and 4% chance on spellcast to increase your damage and healing done by magical spells and effects by up to 95 for 10 sec. + // Chance on melee attack to increase your damage and healing done by magical spells and effects by up to 95 for 10 sec. 6: func(agent core.Agent) { c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450625} + actionID := core.ActionID{SpellID: 27498} - procAura := c.NewTemporaryStatsAura("Crusader's Wrath", core.ActionID{SpellID: 27499}, stats.Stats{stats.SpellPower: 95}, time.Second*10) + procAura := c.NewTemporaryStatsAura("Crusader's Wrath", core.ActionID{SpellID: 27498}, stats.Stats{stats.SpellPower: 95}, time.Second*10) handler := func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { procAura.Activate(sim) } core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ ActionID: actionID, - Name: "Item - Crusader's Wrath Proc - Lightforge Armor (Melee Auto)", + Name: "Item - Crusader's Wrath Proc - Lightforge Armor", Callback: core.CallbackOnSpellHitDealt, Outcome: core.OutcomeLanded, ProcMask: core.ProcMaskMeleeWhiteHit, - ProcChance: 0.06, - Handler: handler, - }) - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "Item - Crusader's Wrath Proc - Lightforge Armor (Spell Cast)", - Callback: core.CallbackOnCastComplete, - ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, - ProcChance: 0.04, + ProcChance: 0.06, //Unsure if this is the classic or SoD proc rate. Handler: handler, }) }, @@ -230,24 +188,9 @@ var ItemSetVestmentsOfTheDevout = core.NewItemSet(core.ItemSet{ c := agent.GetCharacter() c.AddStat(stats.SpellPower, 23) }, - // Your spellcasts have a 6% chance to energize you for 300 mana. + // 6 pieces: When struck in combat has a chance of shielding the wearer in a protective shield which will absorb 350 damage. 6: func(agent core.Agent) { - c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450576} - manaMetrics := c.NewManaMetrics(actionID) - - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "S03 - Mana Proc on Cast - Vestments of the Devout", - Callback: core.CallbackOnCastComplete, - ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, - ProcChance: 0.06, - Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { - if c.HasManaBar() { - c.AddMana(sim, 300, manaMetrics) - } - }, - }) + //No use case in Classic Sim }, // +8 All Resistances. 8: func(agent core.Agent) { @@ -309,45 +252,33 @@ var ItemSetTheElements = core.NewItemSet(core.ItemSet{ c := agent.GetCharacter() c.AddStat(stats.Armor, 200) }, - // +40 Attack Power, up to 23 increased damage from spells, and up to 44 increased healing from spells. + // Increases damage and healing done by magical spells and effects by up to 23. 4: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ - stats.AttackPower: 40, - stats.RangedAttackPower: 40, stats.SpellDamage: 23, - stats.HealingPower: 44, + stats.HealingPower: 23, }) }, - // 6% chance on mainhand autoattack and 4% chance on spellcast to increase your damage and healing done by magical spells and effects by up to 95 for 10 sec. + // Chance on spell cast to increase your damage and healing by up to 95 for 10 sec. 6: func(agent core.Agent) { c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450626} + actionID := core.ActionID{SpellID: 27774} - procAura := c.NewTemporaryStatsAura("The Furious Storm", core.ActionID{SpellID: 27775}, stats.Stats{stats.SpellPower: 95}, time.Second*10) + procAura := c.NewTemporaryStatsAura("The Furious Storm", core.ActionID{SpellID: 27774}, stats.Stats{stats.SpellPower: 95}, time.Second*10) handler := func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { procAura.Activate(sim) } core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ ActionID: actionID, - Name: "Item - The Furious Storm Proc (MH Auto)", - Callback: core.CallbackOnSpellHitDealt, - Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskMeleeMHAuto, - ProcChance: 0.06, - Handler: handler, - }) - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "Item - The Furious Storm Proc (Spell Cast)", + Name: "Item - The Furious Storm Proc", Callback: core.CallbackOnCastComplete, ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, ProcChance: 0.04, Handler: handler, }) }, - // +8 All Resistances. 8: func(agent core.Agent) { c := agent.GetCharacter() @@ -369,33 +300,9 @@ var ItemSetDreadmistRaiment = core.NewItemSet(core.ItemSet{ c := agent.GetCharacter() c.AddStat(stats.SpellPower, 23) }, - // Your melee autoattacks and spellcasts have a 6% chance to heal you for 270 to 330 health. + // When struck in combat has a chance of causing the attacker to flee in terror for 2 seconds. 6: func(agent core.Agent) { - c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450585} - healthMetrics := c.NewHealthMetrics(core.ActionID{SpellID: 450583}) - - handler := func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { - c.GainHealth(sim, sim.Roll(270, 300), healthMetrics) - } - - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "S03 - Heal Proc on Cast - Dreadmist Raiment (Melee Auto)", - Callback: core.CallbackOnSpellHitDealt, - Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskWhiteHit, - ProcChance: 0.06, - Handler: handler, - }) - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "S03 - Heal Proc on Cast - Dreadmist Raiment (Spell Cast)", - Callback: core.CallbackOnCastComplete, - ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, - ProcChance: 0.06, - Handler: handler, - }) + //No use case in Classic Sim }, // +8 All Resistances. 8: func(agent core.Agent) { @@ -421,25 +328,21 @@ var ItemSetBattlegearOfValor = core.NewItemSet(core.ItemSet{ stats.RangedAttackPower: 40, }) }, - // Chance on melee attack to heal you for 88 to 132 and energize you for 10 Rage + // Chance on melee attack to heal you for 88 to 132 6: func(agent core.Agent) { c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 450587} - healthMetrics := c.NewHealthMetrics(core.ActionID{SpellID: 450589}) - rageMetrics := c.NewRageMetrics(core.ActionID{SpellID: 450589}) + actionID := core.ActionID{SpellID: 27419} + healthMetrics := c.NewHealthMetrics(core.ActionID{SpellID: 27419}) core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ ActionID: actionID, - Name: "S03 - Warrior Armor Heal Trigger - Battlegear of Valor", + Name: "Warrior's Resolve", Callback: core.CallbackOnSpellHitDealt, Outcome: core.OutcomeLanded, ProcMask: core.ProcMaskMelee, PPM: 1, Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { c.GainHealth(sim, sim.Roll(88, 132), healthMetrics) - if c.HasRageBar() { - c.AddRage(sim, 10, rageMetrics) - } }, }) }, diff --git a/sim/rogue/_items.go b/sim/rogue/_items.go deleted file mode 100644 index 584f16065..000000000 --- a/sim/rogue/_items.go +++ /dev/null @@ -1,201 +0,0 @@ -package rogue - -import ( - "time" - - "github.com/wowsims/classic/sim/core" - "github.com/wowsims/classic/sim/core/proto" - "github.com/wowsims/classic/sim/core/stats" -) - -const ( - BloodSpatteredStilletto = 216522 - ShadowflameSword = 228143 - DreamEater = 224122 - VenomousTotem = 230250 - RenatakisCharmofTrickery = 231287 - ZandalarianShadowMasteryTalisman = 231336 -) - -func init() { - core.AddEffectsToTest = false - - core.NewItemEffect(BloodSpatteredStilletto, func(agent core.Agent) { - character := agent.GetCharacter() - - spell := character.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 436477}, - SpellSchool: core.SpellSchoolPhysical | core.SpellSchoolShadow, - DefenseType: core.DefenseTypeMagic, - ProcMask: core.ProcMaskSpellDamage, - Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, - - Cast: core.CastConfig{ - CD: core.Cooldown{ - Timer: character.NewTimer(), - Duration: time.Minute * 3, - }, - }, - - DamageMultiplier: 1, - - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - for _, aoeTarget := range sim.Encounter.TargetUnits { - //Confirmed always hits through logs - spell.CalcAndDealDamage(sim, aoeTarget, 140, spell.OutcomeAlwaysHit) - } - }, - }) - - character.AddMajorCooldown(core.MajorCooldown{ - Spell: spell, - Priority: core.CooldownPriorityLow, - Type: core.CooldownTypeDPS, - }) - }) - - // https://www.wowhead.com/classic/item=228143/shadowflame-sword - core.NewItemEffect(ShadowflameSword, func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - - if !rogue.Talents.BladeFlurry { - return - } - - // TODO: This is treated as a buff, NOT a debuff in-game - // We don't have the ability to remove resistances for only one agent at a time right now - procAura := rogue.RegisterAura(core.Aura{ - ActionID: core.ActionID{SpellID: 461252}, - Label: "Shadowflame Fury", - OnGain: func(aura *core.Aura, sim *core.Simulation) { - for _, target := range sim.Encounter.TargetUnits { - target.AddStatDynamic(sim, stats.Armor, -2000) - } - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - for _, target := range sim.Encounter.TargetUnits { - target.AddStatDynamic(sim, stats.Armor, 2000) - } - }, - }) - - core.MakePermanent(rogue.RegisterAura(core.Aura{ - Label: "Shadowflame Fury Trigger", - OnCastComplete: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell) { - if spell.SpellCode == SpellCode_RogueBladeFlurry { - procAura.Duration = rogue.BladeFlurryAura.Duration - procAura.Activate(sim) - } - }, - })) - }) - - // https://www.wowhead.com/classic/item=224122/dream-eater - // Damaging finishing moves have a 20% chance per combo point to restore 10 energy. - core.NewItemEffect(DreamEater, func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - - cpMetrics := rogue.NewEnergyMetrics(core.ActionID{SpellID: 451439}) - rogue.OnComboPointsSpent(func(sim *core.Simulation, spell *core.Spell, comboPoints int32) { - if spell.SpellCode == SpellCode_RogueBetweentheEyes || spell.SpellCode == SpellCode_RogueCrimsonTempest || spell.SpellCode == SpellCode_RogueEnvenom || spell.SpellCode == SpellCode_RogueEviscerate || spell.SpellCode == SpellCode_RogueRupture { - if sim.Proc(0.2*float64(comboPoints), "Dream Eater") { - rogue.AddEnergy(sim, 10, cpMetrics) - } - } - }) - }) - - // https://www.wowhead.com/classic/item=231287/renatakis-charm-of-trickery - // Use: Instantly increases your energy by 60. If Cutthroat is engraved, gain an activation of Cutthroat's Ambush effect. (2 Min Cooldown) - core.NewItemEffect(RenatakisCharmofTrickery, func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - cpMetrics := rogue.NewEnergyMetrics(core.ActionID{SpellID: 468458}) - hasCutthroatRune := rogue.HasRune(proto.RogueRune_RuneCutthroat) - - spell := rogue.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{ItemID: RenatakisCharmofTrickery}, - ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, - - Cast: core.CastConfig{ - CD: core.Cooldown{ - Timer: rogue.NewTimer(), - Duration: time.Second * 120, - }, - SharedCD: core.Cooldown{ - Timer: rogue.GetOffensiveTrinketCD(), - Duration: time.Second * 10, - }, - }, - - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - rogue.AddEnergy(sim, 60, cpMetrics) - if hasCutthroatRune { - rogue.CutthroatProcAura.Activate(sim) - } - }, - }) - - rogue.AddMajorCooldown(core.MajorCooldown{ - Type: core.CooldownTypeDPS, - Spell: spell, - ShouldActivate: func(sim *core.Simulation, character *core.Character) bool { - // Make sure we have plenty of room so we dont energy cap right after using. - return rogue.CurrentEnergy() <= 40 - }, - }) - - }) - - // https://www.wowhead.com/classic/item=230250/venomous-totem - core.NewItemEffect(VenomousTotem, func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - - aura := rogue.GetOrRegisterAura(core.Aura{ - ActionID: core.ActionID{SpellID: 467511}, - Label: "Venomous Totem", - Duration: time.Second * 20, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - rogue.additivePoisonBonusChance += 0.3 - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - rogue.additivePoisonBonusChance -= 0.3 - }, - }) - - spell := rogue.GetOrRegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{ItemID: VenomousTotem}, - ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, - - Cast: core.CastConfig{ - CD: core.Cooldown{ - Timer: rogue.NewTimer(), - Duration: time.Minute * 2, - }, - SharedCD: core.Cooldown{ - Timer: rogue.GetOffensiveTrinketCD(), - Duration: time.Second * 20, - }, - }, - - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - aura.Activate(sim) - }, - }) - - rogue.AddMajorCooldown(core.MajorCooldown{ - Type: core.CooldownTypeDPS, - Spell: spell, - }) - }) - - // https://www.wowhead.com/classic/item=231336/zandalarian-shadow-mastery-talisman - // Increases the chance Cutthroat's Ambush effect is triggered by 5%. - core.NewItemEffect(ZandalarianShadowMasteryTalisman, func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - rogue.cutthroatBonusChance += 0.05 - }) - - core.AddEffectsToTest = true -} diff --git a/sim/rogue/_items_sets_pve.go b/sim/rogue/_items_sets_pve.go deleted file mode 100644 index eeb307bd5..000000000 --- a/sim/rogue/_items_sets_pve.go +++ /dev/null @@ -1,548 +0,0 @@ -package rogue - -import ( - "time" - - "github.com/wowsims/classic/sim/core" - "github.com/wowsims/classic/sim/core/proto" - "github.com/wowsims/classic/sim/core/stats" -) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 3 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var _ = core.NewItemSet(core.ItemSet{ - Name: "Blood Corrupted Leathers", - Bonuses: map[int32]core.ApplyEffect{ - 2: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddStat(stats.MeleeHit, 1) - c.AddStat(stats.SpellHit, 1) - }, - 3: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - - procAuras := rogue.NewEnemyAuraArray(func(target *core.Unit, _ int32) *core.Aura { - return target.RegisterAura(core.Aura{ - Label: "Blood Corruption", - ActionID: core.ActionID{SpellID: 449927}, - Duration: time.Second * 15, - MaxStacks: 30, - - OnGain: func(aura *core.Aura, sim *core.Simulation) { - for si := stats.SchoolIndexPhysical; si < stats.SchoolLen; si++ { - aura.Unit.PseudoStats.SchoolBonusDamageTaken[si] += 7 - } - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - for si := stats.SchoolIndexPhysical; si < stats.SchoolLen; si++ { - aura.Unit.PseudoStats.SchoolBonusDamageTaken[si] -= 7 - } - }, - OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.Landed() && spell.ProcMask.Matches(core.ProcMaskDirect) { - aura.RemoveStack(sim) - } - }, - }) - }) - - core.MakePermanent(rogue.RegisterAura(core.Aura{ - Label: "Blood Corrupting" + rogue.Label, - ActionID: core.ActionID{SpellID: 449928}, - OnSpellHitDealt: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMeleeOrRangedSpecial) { - return - } - - switch spell { - case rogue.Backstab, rogue.Mutilate, rogue.SinisterStrike, rogue.SaberSlash, rogue.Shiv, rogue.PoisonedKnife, rogue.MainGauche, rogue.QuickDraw: - aura := procAuras.Get(result.Target) - aura.Activate(sim) - aura.SetStacks(sim, aura.MaxStacks) - } - }, - })) - }, - }, -}) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 4 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var ItemSetDarkmantleArmor = core.NewItemSet(core.ItemSet{ - Name: "Darkmantle Armor", - Bonuses: map[int32]core.ApplyEffect{ - // +40 Attack Power. - 2: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddStats(stats.Stats{ - stats.AttackPower: 40, - stats.RangedAttackPower: 40, - }) - }, - // Chance on melee attack to restore 35 energy. - 4: func(agent core.Agent) { - c := agent.GetCharacter() - actionID := core.ActionID{SpellID: 27787} - energyMetrics := c.NewEnergyMetrics(actionID) - - core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ - ActionID: actionID, - Name: "Rogue Armor Energize", - Callback: core.CallbackOnSpellHitDealt, - Outcome: core.OutcomeLanded, - ProcMask: core.ProcMaskMeleeWhiteHit, - PPM: 1, - Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { - if c.HasEnergyBar() { - c.AddEnergy(sim, 35, energyMetrics) - } - }, - }) - }, - // +8 All Resistances. - 6: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddResistances(8) - }, - // +200 Armor. - 8: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddStat(stats.Armor, 200) - }, - }, -}) - -var ItemSetNightSlayerThrill = core.NewItemSet(core.ItemSet{ - Name: "Nightslayer Thrill", - Bonuses: map[int32]core.ApplyEffect{ - // Feint also grants Avoidance for 6 sec, reducing all damage taken from area of effect attacks from non-players by 50% - 2: func(agent core.Agent) { - // Not yet implemented - }, - // Increases the critical strike damage bonus of your Poisons by 100%. - 4: func(agent core.Agent) { - rogue := agent.GetCharacter() - rogue.OnSpellRegistered(func(spell *core.Spell) { - if spell.Flags.Matches(SpellFlagRoguePoison) { - spell.CritDamageBonus += 1 - } - }) - }, - // Your finishing moves have a 5% chance per combo point to make your next ability cost no energy. - //https://www.wowhead.com/classic/spell=457342/clearcasting - 6: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - - var affectedSpells []*core.Spell - - aura := rogue.RegisterAura(core.Aura{ - Label: "Clearcasting (S03 - Item - T1 - Rogue - Damage 6P Bonus)", - ActionID: core.ActionID{SpellID: 457342}, - Duration: time.Second * 15, - OnInit: func(aura *core.Aura, sim *core.Simulation) { - affectedSpells = core.FilterSlice( - rogue.Spellbook, - func(spell *core.Spell) bool { - return spell != nil && spell.Cost != nil && spell.Cost.CostType() == core.CostTypeEnergy - }, - ) - }, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - core.Each(affectedSpells, func(spell *core.Spell) { spell.Cost.Multiplier -= 100 }) - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - core.Each(affectedSpells, func(spell *core.Spell) { spell.Cost.Multiplier += 100 }) - }, - OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { - if aura.RemainingDuration(sim) == aura.Duration || spell.DefaultCast.Cost == 0 { - return - } - aura.Deactivate(sim) - }, - }) - rogue.OnComboPointsSpent(func(sim *core.Simulation, spell *core.Spell, comboPoints int32) { - if sim.Proc(.05*float64(comboPoints), "Clearcasting (S03 - Item - T1 - Rogue - Damage 6P Bonus)") { - aura.Activate(sim) - } - }) - }, - }, -}) - -var ItemSetNightSlayerBattlearmor = core.NewItemSet(core.ItemSet{ - Name: "Nightslayer Battlearmor", - Bonuses: map[int32]core.ApplyEffect{ - // While Just a Flesh Wound and Blade Dance are active, Crimson Tempest, Blunderbuss, and Fan of Knives cost 20 less Energy and generate 100% increased threat. - 2: func(agent core.Agent) { - // Implemented in individual rune sections - }, - // Vanish now reduces all Magic damage you take by 50% for its duration, but it no longer grants Stealth or breaks movement impairing effects. - 457437 - 4: func(agent core.Agent) { - // Implemented in Vanish.go - }, - // Your finishing moves have a 20% chance per combo point to make you take 50% less Physical damage from the next melee attack that hits you within 10 sec. - 6: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - damageTaken := 0.5 - - aura := rogue.RegisterAura(core.Aura{ - Label: "Resilient (S03 - Item - T1 - Rogue - Tank 6P Bonus)", - ActionID: core.ActionID{SpellID: 457469}, - Duration: time.Second * 10, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - rogue.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexPhysical] *= damageTaken - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - rogue.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexPhysical] /= damageTaken - }, - OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell.ProcMask.Matches(core.ProcMaskMelee) && result.Outcome.Matches(core.OutcomeLanded) { - aura.Deactivate(sim) - } - }, - }) - - rogue.OnComboPointsSpent(func(sim *core.Simulation, spell *core.Spell, comboPoints int32) { - if sim.Proc(0.2*float64(comboPoints), "Resilient (S03 - Item - T1 - Rogue - Tank 6P Bonus)") { - aura.Activate(sim) - } - }) - }, - }, -}) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 5 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var ItemSetBloodfangThrill = core.NewItemSet(core.ItemSet{ - Name: "Bloodfang Thrill", - Bonuses: map[int32]core.ApplyEffect{ - // Your opening moves have a 100% chance to make your next ability cost no energy. - 2: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - - var affectedSpells []*core.Spell - - aura := rogue.RegisterAura(core.Aura{ - Label: "Clearcasting (S03 - Item - T2 - Rogue - Damage 2P Bonus)", - ActionID: core.ActionID{SpellID: 467735}, - Duration: time.Second * 15, - OnInit: func(aura *core.Aura, sim *core.Simulation) { - affectedSpells = core.FilterSlice( - rogue.Spellbook, - func(spell *core.Spell) bool { - return spell != nil && spell.Cost != nil && spell.Cost.CostType() == core.CostTypeEnergy - }, - ) - }, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - core.Each(affectedSpells, func(spell *core.Spell) { spell.Cost.Multiplier -= 100 }) - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - core.Each(affectedSpells, func(spell *core.Spell) { spell.Cost.Multiplier += 100 }) - }, - OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { - if aura.RemainingDuration(sim) == aura.Duration || spell.DefaultCast.Cost == 0 { - return - } - aura.Deactivate(sim) - }, - }) - - core.MakePermanent(rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Rogue - Damage 2P Bonus", - OnSpellHitDealt: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskMeleeOrRangedSpecial) { - return - } - if spell.SpellCode == SpellCode_RogueAmbush || spell.SpellCode == SpellCode_RogueGarrote { - aura.Activate(sim) - } - }, - })) - }, - // Increases damage dealt by your main hand weapon from combo-generating abilities by 20% - 4: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - rogue.OnSpellRegistered(func(spell *core.Spell) { - //Currently not working as intended. The below are tested to have worked. MG and PK are subspells of Sinister Strike even though they are offhand attacks. SSL DoT confirmed to get the bonus as well. - if spell.SpellCode == SpellCode_RogueAmbush || spell.SpellCode == SpellCode_RogueBackstab || spell.SpellCode == SpellCode_RogueGhostlyStrike || spell.SpellCode == SpellCode_RogueHemorrhage || spell.SpellCode == SpellCode_RogueMainGauche || spell.SpellCode == SpellCode_RoguePoisonedKnife || spell.SpellCode == SpellCode_RogueSaberSlash || spell.SpellCode == SpellCode_RogueSaberSlashDoT || spell.SpellCode == SpellCode_RogueShadowStrike || spell.SpellCode == SpellCode_RogueSinisterStrike || (spell.SpellCode == SpellCode_RogueMutilate && spell.ActionID.Tag == 1) { - spell.DamageMultiplier *= 1.20 - } - }) - }, - // Reduces cooldown on vanish to 1 minute - 6: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Rogue - Damage 6P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - //Applied after talents in sim so does not stack with elusiveness when active. - rogue.Vanish.CD.Duration = time.Second * 60 - }, - }) - }, - }, -}) - -var ItemSetBloodfangBattlearmor = core.NewItemSet(core.ItemSet{ - Name: "Bloodfang Battlearmor", - Bonuses: map[int32]core.ApplyEffect{ - // Your Rolling with the Punches now also activates every time you gain a combo point. - 2: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - if !rogue.HasRune(proto.RogueRune_RuneRollingWithThePunches) { - return - } - rogue.OnComboPointsGained(func(sim *core.Simulation) { - rogue.RollingWithThePunchesProcAura.Activate(sim) - rogue.RollingWithThePunchesProcAura.AddStack(sim) - }) - }, - // Your Rolling with the Punches also grants you 20% increased Armor from items per stack. - 4: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - if !rogue.HasRune(proto.RogueRune_RuneRollingWithThePunches) { - return - } - initarmor := rogue.BaseEquipStats()[stats.Armor] - - rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Rogue - Tank 4P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - oldOnStacksChange := rogue.RollingWithThePunchesProcAura.OnStacksChange - rogue.RollingWithThePunchesProcAura.OnStacksChange = func(aura *core.Aura, sim *core.Simulation, oldStacks int32, newStacks int32) { - oldOnStacksChange(aura, sim, oldStacks, newStacks) - rogue.AddStatDynamic(sim, stats.Armor, float64(0.2*initarmor*float64(newStacks-oldStacks))) - } - }, - }) - }, - // The cooldown on your Main Gauche resets every time your target Dodges or Parries. - 6: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - if !rogue.HasRune(proto.RogueRune_RuneMainGauche) { - return - } - - core.MakePermanent(rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Rogue - Tank 6P Bonus", - OnSpellHitDealt: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.DidDodge() || result.DidParry() { - rogue.MainGauche.CD.Reset() - } - }, - })) - }, - }, -}) - -var ItemSetMadCapsOutfit = core.NewItemSet(core.ItemSet{ - Name: "Madcap's Outfit", - Bonuses: map[int32]core.ApplyEffect{ - // +20 Attack Power - 2: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddStats(stats.Stats{ - stats.AttackPower: 20, - stats.RangedAttackPower: 20, - }) - }, - // Increases your chance to get a critical strike with Daggers by 5%. - 3: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - switch rogue.GetProcMaskForTypes(proto.WeaponType_WeaponTypeDagger) { - case core.ProcMaskMelee: - rogue.AddStat(stats.MeleeCrit, core.CritRatingPerCritChance*float64(5)) - case core.ProcMaskMeleeMH: - // the default character pane displays critical strike chance for main hand only - rogue.AddStat(stats.MeleeCrit, core.CritRatingPerCritChance*float64(5)) - rogue.OnSpellRegistered(func(spell *core.Spell) { - if spell.ProcMask.Matches(core.ProcMaskMeleeOH) { - spell.BonusCritRating -= core.CritRatingPerCritChance * float64(5) - } - }) - case core.ProcMaskMeleeOH: - rogue.OnSpellRegistered(func(spell *core.Spell) { - if spell.ProcMask.Matches(core.ProcMaskMeleeOH) { - spell.BonusCritRating += core.CritRatingPerCritChance * float64(5) - } - }) - } - }, - // Increases the critical strike chance of your Ambush ability by 30%. - 5: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - rogue.OnSpellRegistered(func(spell *core.Spell) { - if spell.SpellCode == SpellCode_RogueAmbush { - spell.BonusCritRating += 30 * core.CritRatingPerCritChance - } - }) - }, - }, -}) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 6 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var ItemSetEmblemsofVeiledShadows = core.NewItemSet(core.ItemSet{ - Name: "Emblems of Veiled Shadows", - Bonuses: map[int32]core.ApplyEffect{ - // 3 pieces: Your finishing moves cost 50% less Energy. - 3: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - RAQ - Rogue - Damage 3P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - for _, finisher := range rogue.Finishers { - finisher.Cost.Multiplier -= 50 - } - }, - }) - }, - }, -}) - -var ItemSetDeathdealersThrill = core.NewItemSet(core.ItemSet{ - Name: "Deathdealer's Thrill", - Bonuses: map[int32]core.ApplyEffect{ - // Increases Saber Slash damage by 20% - 2: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - if !rogue.HasRune(proto.RogueRune_RuneSaberSlash) { - return - } - rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Rogue - Damage 2P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - rogue.SaberSlash.DamageMultiplier *= 1.20 - rogue.saberSlashTick.DamageMultiplier *= 1.20 - }, - }) - }, - // Reduces the cooldown on Adrenaline Rush by 4 minutes. - 4: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - if !rogue.Talents.AdrenalineRush { - return - } - rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Rogue - Damage 4P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - rogue.AdrenalineRush.CD.Duration -= time.Second * 240 - }, - }) - }, - }, -}) - -var ItemSetDeathdealersBattlearmor = core.NewItemSet(core.ItemSet{ - Name: "Deathdealer's Battlearmor", - Bonuses: map[int32]core.ApplyEffect{ - // Your Main Gauche now strikes 1 additional nearby target and also causes your Sinister Strike to strike 1 additional nearby target. - // These additional strikes are not duplicated by Blade Flurry. - 2: func(agent core.Agent) { - rogue := agent.(RogueAgent).GetRogue() - if !rogue.HasRune(proto.RogueRune_RuneMainGauche) { - return - } - - if rogue.Env.GetNumTargets() == 1 { - return - } - - var curDmg float64 - - cleaveHit := rogue.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 1213754}, - SpellSchool: core.SpellSchoolPhysical, - ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagMeleeMetrics | core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell, - - DamageMultiplier: 1, - ThreatMultiplier: 1, - - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - spell.CalcAndDealDamage(sim, target, curDmg, spell.OutcomeAlwaysHit) - }, - }) - - cleaveAura := rogue.RegisterAura(core.Aura{ - Label: "2P Cleave Buff", - Duration: time.Second * 10, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.Landed() && (spell.SpellCode == SpellCode_RogueSinisterStrike) { - curDmg = result.Damage / result.ResistanceMultiplier - cleaveHit.Cast(sim, rogue.Env.NextTargetUnit(result.Target)) - cleaveHit.SpellMetrics[result.Target.UnitIndex].Casts-- - } - }, - }) - - core.MakePermanent(rogue.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Rogue - Tank 2P Bonus", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.Landed() && spell.SpellCode == SpellCode_RogueMainGauche { - cleaveAura.Activate(sim) - curDmg = result.Damage / result.ResistanceMultiplier - cleaveHit.Cast(sim, rogue.Env.NextTargetUnit(result.Target)) - cleaveHit.SpellMetrics[result.Target.UnitIndex].Casts-- - } - }, - })) - - }, - // While active, your Main Gauche also causes you to heal for 10% of all damage done by Sinister Strike. - // Any excess healing becomes a Blood Barrier, absorbing damage up to 20% of your maximum health. - // Shield appear to not be fully implemented in SoD commenting out until fixed - 4: func(agent core.Agent) { -// rogue := agent.(RogueAgent).GetRogue() -// if !rogue.HasRune(proto.RogueRune_RuneMainGauche) { -// return -// } -// shieldSpell := rogue.GetOrRegisterSpell(core.SpellConfig{ -// ActionID: core.ActionID{SpellID: 1213761}, -// SpellSchool: core.SpellSchoolPhysical, -// ProcMask: core.ProcMaskSpellHealing, -// Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell | core.SpellFlagHelpful, -// -// DamageMultiplier: 1, -// ThreatMultiplier: 1, -// -// Shield: core.ShieldConfig{ -// Aura: core.Aura{ -// Label: "Blood Barrier", -// Duration: time.Second * 15, -// }, -// }, -// }) -// -// activeAura := core.MakeProcTriggerAura(&rogue.Unit, core.ProcTrigger{ -// Name: "Main Gauche - Blood Barrier", -// ActionID: core.ActionID{SpellID: 1213762}, -// Callback: core.CallbackOnSpellHitDealt, -// Duration: time.Second * 15, -// Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { -// if result.Landed() && spell.SpellCode == SpellCode_RogueSinisterStrike{ -// shieldSpell.Shield(&rogue.Unit).Apply(sim, result.Damage*0.10) -// } -// }, -// }) -// -// core.MakePermanent(rogue.RegisterAura(core.Aura{ -// Label: "S03 - Item - TAQ - Rogue - Tank 4P Bonus", -// OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { -// if result.Landed() && spell.SpellCode == SpellCode_RogueMainGauche { -// activeAura.Activate(sim) -// } -// }, -// })) - }, - }, -}) diff --git a/sim/rogue/items.go b/sim/rogue/items.go new file mode 100644 index 000000000..3e74b62f4 --- /dev/null +++ b/sim/rogue/items.go @@ -0,0 +1,100 @@ +package rogue + +import ( + "time" + + "github.com/wowsims/classic/sim/core" +) + +const ( + VenomousTotem = 19342 + RenatakisCharmofTrickery = 19954 +) + +func init() { + core.AddEffectsToTest = false + + // https://www.wowhead.com/classic/item=19954/renatakis-charm-of-trickery + // Use: Instantly increases your energy by 60. (3 Min Cooldown) + core.NewItemEffect(RenatakisCharmofTrickery, func(agent core.Agent) { + rogue := agent.(RogueAgent).GetRogue() + energyMetrics := rogue.NewEnergyMetrics(core.ActionID{SpellID: 24532}) + + spell := rogue.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{ItemID: RenatakisCharmofTrickery}, + ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, + + Cast: core.CastConfig{ + CD: core.Cooldown{ + Timer: rogue.NewTimer(), + Duration: time.Second * 180, + }, + SharedCD: core.Cooldown{ + Timer: rogue.GetOffensiveTrinketCD(), + Duration: time.Second * 10, + }, + }, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + rogue.AddEnergy(sim, 60, energyMetrics) + }, + }) + + rogue.AddMajorCooldown(core.MajorCooldown{ + Type: core.CooldownTypeDPS, + Spell: spell, + ShouldActivate: func(sim *core.Simulation, character *core.Character) bool { + // Make sure we have plenty of room so we dont energy cap right after using. + return rogue.CurrentEnergy() <= 40 + }, + }) + + }) + + // https://www.wowhead.com/classic/item=230250/venomous-totem + // Increases the chance to apply Rogue poisons to your target by 30% for 20 sec. (5 Min Cooldown) + core.NewItemEffect(VenomousTotem, func(agent core.Agent) { + rogue := agent.(RogueAgent).GetRogue() + + aura := rogue.GetOrRegisterAura(core.Aura{ + ActionID: core.ActionID{SpellID: 23726}, + Label: "Venomous Totem", + Duration: time.Second * 20, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + rogue.additivePoisonBonusChance += 0.3 + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + rogue.additivePoisonBonusChance -= 0.3 + }, + }) + + spell := rogue.GetOrRegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{ItemID: VenomousTotem}, + ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, + + Cast: core.CastConfig{ + CD: core.Cooldown{ + Timer: rogue.NewTimer(), + Duration: time.Minute * 5, + }, + SharedCD: core.Cooldown{ + Timer: rogue.GetOffensiveTrinketCD(), + Duration: time.Second * 20, + }, + }, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + aura.Activate(sim) + }, + }) + + rogue.AddMajorCooldown(core.MajorCooldown{ + Type: core.CooldownTypeDPS, + Spell: spell, + }) + }) + + core.AddEffectsToTest = true +} diff --git a/sim/rogue/items_sets_pve.go b/sim/rogue/items_sets_pve.go new file mode 100644 index 000000000..52e29f668 --- /dev/null +++ b/sim/rogue/items_sets_pve.go @@ -0,0 +1,342 @@ +package rogue + +import ( + "time" + + "github.com/wowsims/classic/sim/core" + "github.com/wowsims/classic/sim/core/stats" +) + +/////////////////////////////////////////////////////////////////////////// +// Phase 1 Item Sets - Molten Core +/////////////////////////////////////////////////////////////////////////// + +var ItemSetNightslayerArmor = core.NewItemSet(core.ItemSet{ + Name: "Nightslayer Armor", + Bonuses: map[int32]core.ApplyEffect{ + // Reduces the cooldown of your Vanish ability by 30 sec. + 3: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + c.RegisterAura(core.Aura{ + Label: "Improved Vanish", + OnInit: func(aura *core.Aura, sim *core.Simulation) { + c.Vanish.CD.Duration -= time.Second * 30 + }, + }) + }, + // Increases your maximum Energy by 10. + 5: func(agent core.Agent) { + c := agent.GetCharacter() + if c.HasEnergyBar() { + c.EnableEnergyBar(c.MaxEnergy() + 10) + } + }, + // Heals the rogue for 500 when Vanish is performed. + 8: func(agent core.Agent) { + c := agent.GetCharacter() + healthMetrics := c.NewHealthMetrics(core.ActionID{SpellID: 23582}) + + core.MakePermanent(c.RegisterAura(core.Aura{ + Label: "Clean Escape", + OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { + if spell.SpellCode == SpellCode_RogueVanish { + c.GainHealth(sim, 500, healthMetrics) + } + }, + })) + }, + }, +}) + + +/////////////////////////////////////////////////////////////////////////// +// Phase 2 Item Sets - Dire Maul +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// Phase 3 Item Sets - BWL +/////////////////////////////////////////////////////////////////////////// + +var ItemSetBloodfangArmor = core.NewItemSet(core.ItemSet{ + Name: "Bloodfang Armor", + Bonuses: map[int32]core.ApplyEffect{ + // Increases the chance to apply poisons to your target by 5%. + 3: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + c.RegisterAura(core.Aura{ + Label: "Improved Poisons", + OnInit: func(aura *core.Aura, sim *core.Simulation) { + c.additivePoisonBonusChance += .05 + }, + }) + }, + // Improves the threat reduction of Feint by 25%. + 5: func(agent core.Agent) { + // Feint threat reduction not currently implemented in feint.go + }, + // Gives the Rogue a chance to inflict 283 to 317 damage on the target and heal the Rogue for 50 health every 1 sec. for 6 sec. on a melee hit. + 8: func(agent core.Agent) { + c := agent.GetCharacter() + + bloodfangHeal := c.GetOrRegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 23580}, + SpellSchool: core.SpellSchoolPhysical, + DefenseType: core.DefenseTypeMelee, + ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell, + Hot: core.DotConfig{ + Aura: core.Aura{ + Label: "Bloodfang", + }, + NumberOfTicks: 6, + TickLength: time.Second, + OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, _ bool) { + dot.SnapshotBaseDamage = 50 + }, + OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { + dot.CalcAndDealPeriodicSnapshotHealing(sim, target, dot.OutcomeTick) + }, + }, + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + spell.Hot(&c.Unit).Apply(sim) + }, + }) + + procSpell := c.GetOrRegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 23581}, + SpellSchool: core.SpellSchoolPhysical, + DefenseType: core.DefenseTypeMelee, + ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell, + + DamageMultiplier: 1, + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + spell.CalcAndDealDamage(sim, target, sim.Roll(283,317), spell.OutcomeMagicCrit) + }, + }) + + core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ + Name: "Bloodfang", + Callback: core.CallbackOnSpellHitDealt, + Outcome: core.OutcomeLanded, + ProcMask: core.ProcMaskMelee, + SpellFlagsExclude: core.SpellFlagSuppressWeaponProcs, + PPM: 1, + Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + procSpell.Cast(sim, result.Target) + bloodfangHeal.Cast(sim, result.Target) + }, + }) + }, + }, +}) + +var ItemSetMadcapsOutfit = core.NewItemSet(core.ItemSet{ + Name: "Madcap's Outfit", + Bonuses: map[int32]core.ApplyEffect{ + // +20 Attack Power. + 2: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + c.AddStats(stats.Stats{ + stats.AttackPower: 20, + stats.RangedAttackPower: 20, + }) + }, + // Decreases the cooldown of Blind by 20 sec. + 3: func(agent core.Agent) { + // Blind not implemented in sim + }, + // Decrease the energy cost of Eviscerate and Rupture by 5. + 5: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + + core.MakePermanent(c.RegisterAura(core.Aura{ + Label: "Improved Eviscerate and Rupture", + OnInit: func(aura *core.Aura, sim *core.Simulation) { + c.Eviscerate.Cost.FlatModifier -= 5 + c.Rupture.Cost.FlatModifier -= 5 + }, + })) + }, + }, +}) + +/////////////////////////////////////////////////////////////////////////// +// Phase 4 Item Sets - AQ +/////////////////////////////////////////////////////////////////////////// + +// https://www.wowhead.com/classic/item-set=512/darkmantle-armor +var ItemSetDarkmantleArmor = core.NewItemSet(core.ItemSet{ + Name: "Darkmantle Armor", + Bonuses: map[int32]core.ApplyEffect{ + // +8 All Resistances. + 2: func(agent core.Agent) { + c := agent.GetCharacter() + c.AddResistances(8) + }, + // Chance on melee attack to restore 35 energy. + 4: func(agent core.Agent) { + c := agent.GetCharacter() + actionID := core.ActionID{SpellID: 27787} + energyMetrics := c.NewEnergyMetrics(actionID) + + core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ + ActionID: actionID, + Name: "Rogue Armor Energize", + Callback: core.CallbackOnSpellHitDealt, + Outcome: core.OutcomeLanded, + ProcMask: core.ProcMaskMeleeWhiteHit, + PPM: 1, + Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { + if c.HasEnergyBar() { + c.AddEnergy(sim, 35, energyMetrics) + } + }, + }) + }, + // +40 Attack Power. + 6: func(agent core.Agent) { + c := agent.GetCharacter() + c.AddStats(stats.Stats{ + stats.AttackPower: 40, + stats.RangedAttackPower: 40, + }) + }, + // +200 Armor. + 8: func(agent core.Agent) { + c := agent.GetCharacter() + c.AddStat(stats.Armor, 200) + }, + }, +}) + +// https://www.wowhead.com/classic/item-set=497/deathdealers-embrace +var ItemSetDeathdealersEmbrace = core.NewItemSet(core.ItemSet{ + Name: "Deathdealer's Embrace", + Bonuses: map[int32]core.ApplyEffect{ + // Reduces the cooldown of your Evasion ability by -1 min. + 3: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + c.RegisterAura(core.Aura{ + Label: "Deathdealer Evasion Bonus", + OnInit: func(aura *core.Aura, sim *core.Simulation) { + c.Evasion.CD.Duration -= time.Second * 60 + }, + }) + }, + // 15% increased damage to your Eviscerate ability. + 5: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + c.RegisterAura(core.Aura{ + Label: "Deathdealer Eviscerate Bonus", + OnInit: func(aura *core.Aura, sim *core.Simulation) { + c.Eviscerate.DamageMultiplier *= 1.15 + }, + }) + }, + }, +}) + +/////////////////////////////////////////////////////////////////////////// +// Phase 5 Item Sets - Naxx +/////////////////////////////////////////////////////////////////////////// + +// https://www.wowhead.com/classic/item-set=524/bonescythe-armor +var ItemSetBonescytheArmor = core.NewItemSet(core.ItemSet{ + Name: "Bonescythe Armor", + Bonuses: map[int32]core.ApplyEffect{ + // Your normal melee swings have a chance to Invigorate you, healing you for 90 to 110. + 2: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + actionID := core.ActionID{SpellID: 28817} + healthMetrics := c.NewHealthMetrics(actionID) + + core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ + ActionID: actionID, + Name: "Invigorate", + Callback: core.CallbackOnSpellHitDealt, + Outcome: core.OutcomeLanded, + ProcMask: core.ProcMaskMelee, + PPM: 1, + Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { + c.GainHealth(sim, sim.Roll(90,110), healthMetrics) + }, + }) + }, + // Your Backstab, Sinister Strike, and Hemorrhage critical hits cause you to regain 5 energy. + 4: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + actionID := core.ActionID{SpellID: 28813} + energyMetrics := c.NewEnergyMetrics(actionID) + + c.RegisterAura(core.Aura{ + Label: "Head Rush", + 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 (spell.SpellCode == SpellCode_RogueBackstab || spell.SpellCode == SpellCode_RogueSinisterStrike || spell.SpellCode == SpellCode_RogueHemorrhage) && result.DidCrit() { + c.AddEnergy(sim, 5, energyMetrics) + } + }, + }) + }, + // Reduces the threat from your Backstab, Sinister Strike, Hemorrhage, and Eviscerate abilities. + 6: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + c.RegisterAura(core.Aura{ + Label: "Reduced Threat", + OnInit: func(aura *core.Aura, sim *core.Simulation) { + c.Backstab.ThreatMultiplier /= 1.08 + c.SinisterStrike.ThreatMultiplier /= 1.08 + if c.Talents.Hemorrhage { + c.Hemorrhage.ThreatMultiplier /= 1.08 + } + c.Eviscerate.ThreatMultiplier /= 1.08 + }, + }) + }, + // Your Eviscerate has a chance per combo point to reveal a flaw in your opponent's armor, granting a 100% critical hit chance for your next Backstab, Sinister Strike, or Hemorrhage. + 8: func(agent core.Agent) { + c := agent.(RogueAgent).GetRogue() + actionID := core.ActionID{SpellID: 28815} + + aura := c.RegisterAura(core.Aura{ + Label: "Revealed Flaw", + ActionID: actionID, + Duration: core.NeverExpires, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + c.Backstab.BonusCritRating += 100 * core.CritRatingPerCritChance + c.SinisterStrike.BonusCritRating += 100 * core.CritRatingPerCritChance + if c.Talents.Hemorrhage { + c.Hemorrhage.BonusCritRating += 100 * core.CritRatingPerCritChance + } + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + c.Backstab.BonusCritRating -= 100 * core.CritRatingPerCritChance + c.SinisterStrike.BonusCritRating -= 100 * core.CritRatingPerCritChance + if c.Talents.Hemorrhage { + c.Hemorrhage.BonusCritRating -= 100 * core.CritRatingPerCritChance + } + }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.SpellCode == SpellCode_RogueBackstab || spell.SpellCode == SpellCode_RogueSinisterStrike || spell.SpellCode == SpellCode_RogueHemorrhage { + aura.Deactivate(sim) + } + }, + }) + + c.OnComboPointsSpent(func(sim *core.Simulation, spell *core.Spell, comboPoints int32) { + if spell.SpellCode == SpellCode_RogueEviscerate { + // Proc rate from Simonize Era sheet + if sim.Proc(0.05*float64(comboPoints), "Revealed Flaw") { + aura.Activate(sim) + } + } + }) + }, + }, +}) \ No newline at end of file diff --git a/sim/rogue/poisons.go b/sim/rogue/poisons.go index 2ca2251be..9fb49c18d 100644 --- a/sim/rogue/poisons.go +++ b/sim/rogue/poisons.go @@ -36,7 +36,7 @@ const ( ) func (rogue *Rogue) GetInstantPoisonProcChance() float64 { - return (0.2 + rogue.improvedPoisons()) * (1 + rogue.instantPoisonProcChanceBonus) + rogue.additivePoisonBonusChance + return 0.2 + rogue.improvedPoisons() + rogue.additivePoisonBonusChance } func (rogue *Rogue) GetDeadlyPoisonProcChance() float64 { diff --git a/sim/rogue/rogue.go b/sim/rogue/rogue.go index 6b948ae5b..26ea5d9e1 100644 --- a/sim/rogue/rogue.go +++ b/sim/rogue/rogue.go @@ -32,6 +32,7 @@ const ( SpellCode_RogueRupture SpellCode_RogueSinisterStrike SpellCode_RogueSliceandDice + SpellCode_RogueVanish ) var TalentTreeSizes = [3]int{15, 19, 17} @@ -72,7 +73,6 @@ type Rogue struct { InstantPoison *core.Spell WoundPoison *core.Spell - instantPoisonProcChanceBonus float64 additivePoisonBonusChance float64 AdrenalineRushAura *core.Aura diff --git a/sim/rogue/vanish.go b/sim/rogue/vanish.go index d70108cc5..04dd2e503 100644 --- a/sim/rogue/vanish.go +++ b/sim/rogue/vanish.go @@ -18,6 +18,7 @@ func (rogue *Rogue) registerVanishSpell() { }) rogue.Vanish = rogue.RegisterSpell(core.SpellConfig{ + SpellCode: SpellCode_RogueVanish, ActionID: core.ActionID{SpellID: 1856}, SpellSchool: core.SpellSchoolPhysical, Flags: core.SpellFlagAPL,