diff --git a/assets/database/db.bin b/assets/database/db.bin index 93c7a127ad..6578a92c15 100644 Binary files a/assets/database/db.bin and b/assets/database/db.bin differ diff --git a/assets/database/db.json b/assets/database/db.json index 33b8ac614e..6f83a5b020 100644 --- a/assets/database/db.json +++ b/assets/database/db.json @@ -10594,8 +10594,8 @@ {"effectId":63,"spellId":13538,"name":"Enchant Chest - Lesser Absorption","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":66,"spellId":7457,"name":"Enchant Bracer - Minor Stamina","type":6,"stats":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":66,"spellId":7863,"name":"Enchant Boots - Minor Stamina","type":10,"stats":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, -{"effectId":241,"spellId":7745,"name":"Enchant 2H Weapon - Minor Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":241,"spellId":13503,"name":"Enchant Weapon - Lesser Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, +{"effectId":241,"spellId":7745,"name":"Enchant 2H Weapon - Minor Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":242,"spellId":7748,"name":"Enchant Chest - Lesser Health","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":243,"spellId":7766,"name":"Enchant Bracer - Minor Spirit","type":6,"stats":[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":246,"spellId":7776,"name":"Enchant Chest - Lesser Mana","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, @@ -10670,8 +10670,8 @@ {"effectId":929,"itemId":16217,"spellId":20069,"name":"Enchant Shield - Greater Stamina","type":13,"enchantType":2,"stats":[0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":930,"spellId":13947,"name":"Enchant Gloves - Riding Skill","type":7,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":931,"spellId":13948,"name":"Enchant Gloves - Minor Haste","type":7,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, -{"effectId":943,"spellId":13693,"name":"Enchant Weapon - Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":943,"spellId":13529,"name":"Enchant 2H Weapon - Lesser Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, +{"effectId":943,"spellId":13693,"name":"Enchant Weapon - Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":963,"spellId":13937,"name":"Enchant 2H Weapon - Greater Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":1483,"itemId":11622,"spellId":15340,"name":"Lesser Arcanum of Rumination","type":1,"extraTypes":[9],"enchantType":3,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":1503,"itemId":11642,"spellId":15389,"name":"Lesser Arcanum of Constitution","type":1,"extraTypes":[9],"enchantType":3,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0],"quality":2}, @@ -10697,8 +10697,8 @@ {"effectId":1893,"spellId":20028,"name":"Enchant Chest - Major Mana","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":1894,"spellId":20029,"name":"Enchant Weapon - Icy Chill","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":1896,"spellId":20030,"name":"Enchant 2H Weapon - Superior Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, -{"effectId":1897,"spellId":13695,"name":"Enchant 2H Weapon - Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":1897,"spellId":20031,"name":"Enchant Weapon - Superior Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, +{"effectId":1897,"spellId":13695,"name":"Enchant 2H Weapon - Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":1898,"spellId":20032,"name":"Enchant Weapon - Lifestealing","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":3}, {"effectId":1899,"spellId":20033,"name":"Enchant Weapon - Unholy Weapon","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":1900,"spellId":20034,"name":"Enchant Weapon - Crusader","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, @@ -11017,31 +11017,64 @@ {"id":440870,"name":"Engrave Boots - Decimation","icon":"spell_fire_fireball02","type":10,"classAllowlist":[8]}, {"id":440882,"name":"Engrave Cloak - Infernal Armor","icon":"achievement_boss_kiljaedan","type":4,"classAllowlist":[8]}, {"id":440892,"name":"Engrave Cloak - Mark of Chaos","icon":"spell_shadow_unstableaffliction_1","type":4,"classAllowlist":[8]}, -{"id":442813,"name":"Engrave Ring - Sword Specialization","icon":"ability_meleedamage","type":11,"classAllowlist":[0,9,4,2,6,3,8]}, -{"id":442876,"name":"Engrave Ring - Axe Specialization","icon":"inv_axe_03","type":11,"classAllowlist":[0,9,4,2,7]}, -{"id":442881,"name":"Engrave Ring - Mace Specialization","icon":"inv_hammer_01","type":11,"classAllowlist":[0,9,4,6,5,7,1]}, -{"id":442887,"name":"Engrave Ring - Dagger Specialization","icon":"inv_weapon_shortblade_05","type":11,"classAllowlist":[0,9,2,6,5,7,3,8,1]}, -{"id":442890,"name":"Engrave Ring - Fist Weapon Specialization","icon":"inv_misc_desecrated_plategloves","type":11,"classAllowlist":[0,9,2,6,7,1]}, -{"id":442891,"name":"Engrave Ring - Ranged Weapon Specialization","icon":"inv_weapon_bow_02","type":11,"classAllowlist":[0,9,2,6]}, -{"id":442892,"name":"Engrave Ring - Pole Weapon Specialization","icon":"inv_staff_08","type":11,"classAllowlist":[0,9,4,2,5,7,3,8,1]}, -{"id":442893,"name":"Engrave Ring - Arcane Specialization","icon":"inv_elemental_primal_mana","type":11,"classAllowlist":[0,1,3,2]}, -{"id":442894,"name":"Engrave Ring - Fire Specialization","icon":"inv_elemental_primal_fire","type":11,"classAllowlist":[0,7,3,8,2,5]}, -{"id":442895,"name":"Engrave Ring - Frost Specialization","icon":"inv_elemental_primal_water","type":11,"classAllowlist":[0,7,3]}, -{"id":442896,"name":"Engrave Ring - Nature Specialization","icon":"inv_elemental_primal_life","type":11,"classAllowlist":[0,6,7,1]}, -{"id":442897,"name":"Engrave Ring - Shadow Specialization","icon":"inv_elemental_primal_shadow","type":11,"classAllowlist":[0,5,8]}, -{"id":442898,"name":"Engrave Ring - Holy Specialization","icon":"spell_holy_aspiration","type":11,"classAllowlist":[0,4,5]}, +{"id":442813,"name":"Engrave Ring - Sword Specialization","icon":"ability_meleedamage","type":11,"classAllowlist":[9,4,2,6,3,8]}, +{"id":442876,"name":"Engrave Ring - Axe Specialization","icon":"inv_axe_03","type":11,"classAllowlist":[9,4,2,7]}, +{"id":442881,"name":"Engrave Ring - Mace Specialization","icon":"inv_hammer_01","type":11,"classAllowlist":[9,4,6,5,7,1]}, +{"id":442887,"name":"Engrave Ring - Dagger Specialization","icon":"inv_weapon_shortblade_05","type":11,"classAllowlist":[9,2,6,5,7,3,8,1]}, +{"id":442890,"name":"Engrave Ring - Fist Weapon Specialization","icon":"inv_misc_desecrated_plategloves","type":11,"classAllowlist":[9,2,6,7,1]}, +{"id":442891,"name":"Engrave Ring - Ranged Weapon Specialization","icon":"inv_weapon_bow_02","type":11,"classAllowlist":[9,2,6]}, +{"id":442892,"name":"Engrave Ring - Pole Weapon Specialization","icon":"inv_staff_08","type":11,"classAllowlist":[9,4,2,5,7,3,8,1]}, +{"id":442893,"name":"Engrave Ring - Arcane Specialization","icon":"inv_elemental_primal_mana","type":11,"classAllowlist":[1,3,2]}, +{"id":442894,"name":"Engrave Ring - Fire Specialization","icon":"inv_elemental_primal_fire","type":11,"classAllowlist":[7,3,8,2,5]}, +{"id":442895,"name":"Engrave Ring - Frost Specialization","icon":"inv_elemental_primal_water","type":11,"classAllowlist":[7,3]}, +{"id":442896,"name":"Engrave Ring - Nature Specialization","icon":"inv_elemental_primal_life","type":11,"classAllowlist":[6,7,1]}, +{"id":442897,"name":"Engrave Ring - Shadow Specialization","icon":"inv_elemental_primal_shadow","type":11,"classAllowlist":[5,8]}, +{"id":442898,"name":"Engrave Ring - Holy Specialization","icon":"spell_holy_aspiration","type":11,"classAllowlist":[4,5]}, {"id":453622,"name":"Engrave Ring - Feral Combat Specialization","icon":"ability_druid_catformattack","type":11,"classAllowlist":[1]}, {"id":458287,"name":"Engrave Chest - Hallowed Ground","icon":"spell_holy_crusade","type":5,"classAllowlist":[4]}, {"id":458318,"name":"Engrave Belt - Malleable Protection","icon":"spell_holy_restoration","type":8,"classAllowlist":[4]}, {"id":458393,"name":"Engrave Gloves - Cobra Slayer","icon":"spell_nature_guardianward","type":7,"classAllowlist":[2]}, {"id":458479,"name":"Engrave Boots - Wyvern Strike","icon":"inv_spear_02","type":10,"classAllowlist":[2]}, {"id":458856,"name":"Engrave Cloak - Divine Light","icon":"spell_holy_surgeoflight","type":4,"classAllowlist":[4]}, -{"id":459312,"name":"Engrave Ring - Defense Specialization","icon":"inv_shield_06","type":11,"classAllowlist":[0,9,4,6,7,8,1]}, +{"id":459312,"name":"Engrave Ring - Defense Specialization","icon":"inv_shield_06","type":11,"classAllowlist":[9,4,6,7,8,1]}, {"id":462708,"name":"Engrave Gloves - Cutthroat","icon":"ability_rogue_slaughterfromtheshadows","type":7,"classAllowlist":[6]}, {"id":462834,"name":"Engrave Cloak - Shock and Awe","icon":"ability_vehicle_sonicshockwave","type":4,"classAllowlist":[4]}, {"id":462853,"name":"Engrave Pants - Hand of Sacrifice","icon":"spell_holy_sealofsacrifice","type":9,"classAllowlist":[4]}, -{"id":468758,"name":"Engrave Ring - Healing Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[0,1,3,4,5,7]}, -{"id":468762,"name":"Engrave Ring - Meditation Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[0,1,2,3,4,5,7,8]} +{"id":468758,"name":"Engrave Ring - Healing Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[1,3,4,5,7]}, +{"id":468762,"name":"Engrave Ring - Meditation Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[1,2,3,4,5,7,8]}, +{"id":1220034,"name":"Soul of the Refined","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220232,"name":"Soul of the Windwalker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220234,"name":"Soul of the Shield Master","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220236,"name":"Soul of the Totemic Protector","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220238,"name":"Soul of the Shock-Absorber","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220240,"name":"Soul of the Spiritual Bulwark","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220242,"name":"Soul of the Maelstrombringer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220244,"name":"Soul of the Lavawalker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220246,"name":"Soul of the True Alpha","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220248,"name":"Soul of the Totemkeeper","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220250,"name":"Soul of the Ancestors","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220252,"name":"Soul of the Spiritweaver","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220254,"name":"Soul of the Waterwalker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220256,"name":"Soul of the Stormtender","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220258,"name":"Soul of the Elemental Seer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220260,"name":"Soul of the Vitalist","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220262,"name":"Soul of the Spirithealer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220266,"name":"Soul of the Chieftain","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220268,"name":"Soul of the Furycharged","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220270,"name":"Soul of the Stormbreaker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220272,"name":"Soul of the Tempest","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220274,"name":"Soul of the Seismic Smasher","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220276,"name":"Soul of the Flamebringer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220278,"name":"Soul of the Volcano","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220279,"name":"Soul of the Raging Flame","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220282,"name":"Soul of the Elemental Master","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220284,"name":"Soul of the Tribesman","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220286,"name":"Soul of the Spirit Guide","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220288,"name":"Soul of the Elder","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220291,"name":"Soul of the Elements","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220293,"name":"Soul of the Lava Sage","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220295,"name":"Soul of the Ancestral Warden","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220297,"name":"Soul of the Corrupt","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]} ], "zones":[ {"id":209,"name":"Shadowfang Keep","expansion":1}, @@ -15538,7 +15571,6 @@ {"id":453696,"name":"Engrave Ring - Fire Specialization","icon":"inv_jewelry_ring_31","requiresLevel":1}, {"id":453697,"name":"Engrave Ring - Frost Specialization","icon":"inv_jewelry_ring_31","requiresLevel":1}, {"id":457437,"name":"Vanish","icon":"ability_vanish","requiresLevel":1,"hasBuff":true}, -{"id":457544,"name":"S03 - Item - T1 - Shaman - Tank 6P Bonus","icon":"ability_ghoulfrenzy","requiresLevel":1}, {"id":458436,"name":"Wyvern Strike","icon":"inv_spear_02","requiresLevel":1,"hasBuff":true}, {"id":458481,"name":"Wyvern Strike","icon":"inv_spear_02","requiresLevel":1,"hasBuff":true}, {"id":458482,"name":"Wyvern Strike","icon":"inv_spear_02","requiresLevel":1,"hasBuff":true}, diff --git a/assets/database/leftover_db.bin b/assets/database/leftover_db.bin index e8e708bdbc..38ed5a452e 100644 Binary files a/assets/database/leftover_db.bin and b/assets/database/leftover_db.bin differ diff --git a/assets/database/leftover_db.json b/assets/database/leftover_db.json index 04baf7c889..1bbb831ebd 100644 --- a/assets/database/leftover_db.json +++ b/assets/database/leftover_db.json @@ -1482,8 +1482,8 @@ {"effectId":63,"spellId":13538,"name":"Enchant Chest - Lesser Absorption","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":66,"spellId":7457,"name":"Enchant Bracer - Minor Stamina","type":6,"stats":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":66,"spellId":7863,"name":"Enchant Boots - Minor Stamina","type":10,"stats":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, -{"effectId":241,"spellId":13503,"name":"Enchant Weapon - Lesser Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":241,"spellId":7745,"name":"Enchant 2H Weapon - Minor Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, +{"effectId":241,"spellId":13503,"name":"Enchant Weapon - Lesser Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":242,"spellId":7748,"name":"Enchant Chest - Lesser Health","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":243,"spellId":7766,"name":"Enchant Bracer - Minor Spirit","type":6,"stats":[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":246,"spellId":7776,"name":"Enchant Chest - Lesser Mana","type":5,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, @@ -1558,8 +1558,8 @@ {"effectId":929,"itemId":16217,"spellId":20069,"name":"Enchant Shield - Greater Stamina","type":13,"enchantType":2,"stats":[0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":930,"spellId":13947,"name":"Enchant Gloves - Riding Skill","type":7,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":931,"spellId":13948,"name":"Enchant Gloves - Minor Haste","type":7,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, -{"effectId":943,"spellId":13529,"name":"Enchant 2H Weapon - Lesser Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":943,"spellId":13693,"name":"Enchant Weapon - Striking","type":13,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, +{"effectId":943,"spellId":13529,"name":"Enchant 2H Weapon - Lesser Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":963,"spellId":13937,"name":"Enchant 2H Weapon - Greater Impact","type":13,"enchantType":1,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":1}, {"effectId":1483,"itemId":11622,"spellId":15340,"name":"Lesser Arcanum of Rumination","type":1,"extraTypes":[9],"enchantType":3,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"quality":2}, {"effectId":1503,"itemId":11642,"spellId":15389,"name":"Lesser Arcanum of Constitution","type":1,"extraTypes":[9],"enchantType":3,"stats":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0],"quality":2}, @@ -1905,31 +1905,64 @@ {"id":440870,"name":"Engrave Boots - Decimation","icon":"spell_fire_fireball02","type":10,"classAllowlist":[8]}, {"id":440882,"name":"Engrave Cloak - Infernal Armor","icon":"achievement_boss_kiljaedan","type":4,"classAllowlist":[8]}, {"id":440892,"name":"Engrave Cloak - Mark of Chaos","icon":"spell_shadow_unstableaffliction_1","type":4,"classAllowlist":[8]}, -{"id":442813,"name":"Engrave Ring - Sword Specialization","icon":"ability_meleedamage","type":11,"classAllowlist":[0,9,4,2,6,3,8]}, -{"id":442876,"name":"Engrave Ring - Axe Specialization","icon":"inv_axe_03","type":11,"classAllowlist":[0,9,4,2,7]}, -{"id":442881,"name":"Engrave Ring - Mace Specialization","icon":"inv_hammer_01","type":11,"classAllowlist":[0,9,4,6,5,7,1]}, -{"id":442887,"name":"Engrave Ring - Dagger Specialization","icon":"inv_weapon_shortblade_05","type":11,"classAllowlist":[0,9,2,6,5,7,3,8,1]}, -{"id":442890,"name":"Engrave Ring - Fist Weapon Specialization","icon":"inv_misc_desecrated_plategloves","type":11,"classAllowlist":[0,9,2,6,7,1]}, -{"id":442891,"name":"Engrave Ring - Ranged Weapon Specialization","icon":"inv_weapon_bow_02","type":11,"classAllowlist":[0,9,2,6]}, -{"id":442892,"name":"Engrave Ring - Pole Weapon Specialization","icon":"inv_staff_08","type":11,"classAllowlist":[0,9,4,2,5,7,3,8,1]}, -{"id":442893,"name":"Engrave Ring - Arcane Specialization","icon":"inv_elemental_primal_mana","type":11,"classAllowlist":[0,1,3,2]}, -{"id":442894,"name":"Engrave Ring - Fire Specialization","icon":"inv_elemental_primal_fire","type":11,"classAllowlist":[0,7,3,8,2,5]}, -{"id":442895,"name":"Engrave Ring - Frost Specialization","icon":"inv_elemental_primal_water","type":11,"classAllowlist":[0,7,3]}, -{"id":442896,"name":"Engrave Ring - Nature Specialization","icon":"inv_elemental_primal_life","type":11,"classAllowlist":[0,6,7,1]}, -{"id":442897,"name":"Engrave Ring - Shadow Specialization","icon":"inv_elemental_primal_shadow","type":11,"classAllowlist":[0,5,8]}, -{"id":442898,"name":"Engrave Ring - Holy Specialization","icon":"spell_holy_aspiration","type":11,"classAllowlist":[0,4,5]}, +{"id":442813,"name":"Engrave Ring - Sword Specialization","icon":"ability_meleedamage","type":11,"classAllowlist":[9,4,2,6,3,8]}, +{"id":442876,"name":"Engrave Ring - Axe Specialization","icon":"inv_axe_03","type":11,"classAllowlist":[9,4,2,7]}, +{"id":442881,"name":"Engrave Ring - Mace Specialization","icon":"inv_hammer_01","type":11,"classAllowlist":[9,4,6,5,7,1]}, +{"id":442887,"name":"Engrave Ring - Dagger Specialization","icon":"inv_weapon_shortblade_05","type":11,"classAllowlist":[9,2,6,5,7,3,8,1]}, +{"id":442890,"name":"Engrave Ring - Fist Weapon Specialization","icon":"inv_misc_desecrated_plategloves","type":11,"classAllowlist":[9,2,6,7,1]}, +{"id":442891,"name":"Engrave Ring - Ranged Weapon Specialization","icon":"inv_weapon_bow_02","type":11,"classAllowlist":[9,2,6]}, +{"id":442892,"name":"Engrave Ring - Pole Weapon Specialization","icon":"inv_staff_08","type":11,"classAllowlist":[9,4,2,5,7,3,8,1]}, +{"id":442893,"name":"Engrave Ring - Arcane Specialization","icon":"inv_elemental_primal_mana","type":11,"classAllowlist":[1,3,2]}, +{"id":442894,"name":"Engrave Ring - Fire Specialization","icon":"inv_elemental_primal_fire","type":11,"classAllowlist":[7,3,8,2,5]}, +{"id":442895,"name":"Engrave Ring - Frost Specialization","icon":"inv_elemental_primal_water","type":11,"classAllowlist":[7,3]}, +{"id":442896,"name":"Engrave Ring - Nature Specialization","icon":"inv_elemental_primal_life","type":11,"classAllowlist":[6,7,1]}, +{"id":442897,"name":"Engrave Ring - Shadow Specialization","icon":"inv_elemental_primal_shadow","type":11,"classAllowlist":[5,8]}, +{"id":442898,"name":"Engrave Ring - Holy Specialization","icon":"spell_holy_aspiration","type":11,"classAllowlist":[4,5]}, {"id":453622,"name":"Engrave Ring - Feral Combat Specialization","icon":"ability_druid_catformattack","type":11,"classAllowlist":[1]}, {"id":458287,"name":"Engrave Chest - Hallowed Ground","icon":"spell_holy_crusade","type":5,"classAllowlist":[4]}, {"id":458318,"name":"Engrave Belt - Malleable Protection","icon":"spell_holy_restoration","type":8,"classAllowlist":[4]}, {"id":458393,"name":"Engrave Gloves - Cobra Slayer","icon":"spell_nature_guardianward","type":7,"classAllowlist":[2]}, {"id":458479,"name":"Engrave Boots - Wyvern Strike","icon":"inv_spear_02","type":10,"classAllowlist":[2]}, {"id":458856,"name":"Engrave Cloak - Divine Light","icon":"spell_holy_surgeoflight","type":4,"classAllowlist":[4]}, -{"id":459312,"name":"Engrave Ring - Defense Specialization","icon":"inv_shield_06","type":11,"classAllowlist":[0,9,4,6,7,8,1]}, +{"id":459312,"name":"Engrave Ring - Defense Specialization","icon":"inv_shield_06","type":11,"classAllowlist":[9,4,6,7,8,1]}, {"id":462708,"name":"Engrave Gloves - Cutthroat","icon":"ability_rogue_slaughterfromtheshadows","type":7,"classAllowlist":[6]}, {"id":462834,"name":"Engrave Cloak - Shock and Awe","icon":"ability_vehicle_sonicshockwave","type":4,"classAllowlist":[4]}, {"id":462853,"name":"Engrave Pants - Hand of Sacrifice","icon":"spell_holy_sealofsacrifice","type":9,"classAllowlist":[4]}, -{"id":468758,"name":"Engrave Ring - Healing Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[0,1,3,4,5,7]}, -{"id":468762,"name":"Engrave Ring - Meditation Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[0,1,2,3,4,5,7,8]} +{"id":468758,"name":"Engrave Ring - Healing Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[1,3,4,5,7]}, +{"id":468762,"name":"Engrave Ring - Meditation Specialization","icon":"spell_holy_greaterheal","type":11,"classAllowlist":[1,2,3,4,5,7,8]}, +{"id":1220034,"name":"Soul of the Refined","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220232,"name":"Soul of the Windwalker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220234,"name":"Soul of the Shield Master","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220236,"name":"Soul of the Totemic Protector","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220238,"name":"Soul of the Shock-Absorber","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220240,"name":"Soul of the Spiritual Bulwark","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220242,"name":"Soul of the Maelstrombringer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220244,"name":"Soul of the Lavawalker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220246,"name":"Soul of the True Alpha","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220248,"name":"Soul of the Totemkeeper","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220250,"name":"Soul of the Ancestors","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220252,"name":"Soul of the Spiritweaver","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220254,"name":"Soul of the Waterwalker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220256,"name":"Soul of the Stormtender","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220258,"name":"Soul of the Elemental Seer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220260,"name":"Soul of the Vitalist","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220262,"name":"Soul of the Spirithealer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220266,"name":"Soul of the Chieftain","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220268,"name":"Soul of the Furycharged","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220270,"name":"Soul of the Stormbreaker","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220272,"name":"Soul of the Tempest","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220274,"name":"Soul of the Seismic Smasher","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220276,"name":"Soul of the Flamebringer","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220278,"name":"Soul of the Volcano","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220279,"name":"Soul of the Raging Flame","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220282,"name":"Soul of the Elemental Master","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220284,"name":"Soul of the Tribesman","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220286,"name":"Soul of the Spirit Guide","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220288,"name":"Soul of the Elder","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220291,"name":"Soul of the Elements","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220293,"name":"Soul of the Lava Sage","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220295,"name":"Soul of the Ancestral Warden","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]}, +{"id":1220297,"name":"Soul of the Corrupt","icon":"spell_holy_divinespirit","type":3,"classAllowlist":[7]} ], "zones":[ ], diff --git a/assets/db_inputs/wowhead_shoulder_rune_tooltips.csv b/assets/db_inputs/wowhead_shoulder_rune_tooltips.csv new file mode 100644 index 0000000000..5d4291b591 --- /dev/null +++ b/assets/db_inputs/wowhead_shoulder_rune_tooltips.csv @@ -0,0 +1,206 @@ +1220142,{"name":"Soul of the Reverberant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Reverberant
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Reverberant:

Your Temporal Beacons last 20% longer.

","spells":[]} +1220050,{"name":"Soul of the Demonlord","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Demonlord
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Demonlord:

Increases the benefits of your Master Demonologist talent by 50%.

","spells":[]} +1220350,{"name":"Soul of the Lunatic","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lunatic
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lunatic:

Increases your chance to hit with spells and attacks by 3%.

","spells":[]} +1220042,{"name":"Soul of the Shadowmancer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shadowmancer
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shadowmancer:

Shadowbolt deals 10 + (5 * ComboPoints)% increased damage for each of your effects afflicting the target, up to a maximum of 30 + (5 * ComboPoints)%.

","spells":[]} +1220364,{"name":"Soul of the Cometcaller","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Cometcaller
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Cometcaller:

Reduces the cast time and global cooldown of Starfire by 0.5 sec.

","spells":[]} +1220307,{"name":"Soul of the Beast","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Beast
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Beast:

Your Mangle(Bear), Swipe(Bear), Maul, and Lacerate abilities gain 5% increased critical strike chance against targets afflicted by your Lacerate.

","spells":[]} +1220328,{"name":"Soul of the Benevolet Seer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Benevolet Seer
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Benevolet Seer:

Reduces the cooldown of your Rebirth and Innervate spells by 65%.

","spells":[]} +1219956,{"name":"Soul of the Tactician","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Tactician
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Tactician:

After changing stances, your next offensive ability's rage cost is reduced by 10.

","spells":[]} +1219964,{"name":"Soul of the Titan","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Titan
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Titan:

Your Heroic Strike, Slam, and Overpower abilities deal 25 + (5 * ComboPoints)% more damage.

","spells":[]} +1219976,{"name":"Soul of Enmity","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Enmity
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior, Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Enmity:

Increases all threat you generate in Defensive Stance by an additional 10% and increases all damage you deal in Gladiator Stance by 4%.

","spells":[]} +1220072,{"name":"Soul of the Preyseeker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Preyseeker
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Preyseeker:

While tracking a creature type, you deal 3% increased damage to that creature type.

","spells":[]} +1219960,{"name":"Soul of the Battle Forecaster","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Battle Forecaster
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Battle Forecaster:

For the first 15 sec after activating a stance, you can gain an additional benefit:

Battle Stance/Gladiator Stance: 10% increased damage done.

Berserker Stance: 10% increased critical strike chance.

Defensive Stance: 10% reduced Physical damage taken.

","spells":[]} +1220305,{"name":"Soul of the Territorial","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Territorial
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Territorial:

Swipe(Bear) also causes your Maul to hit 1 additional target for the next 6 sec.

","spells":[]} +1220090,{"name":"Soul of the Alpha Tamer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Alpha Tamer
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Alpha Tamer:

Increases the Focus regeneration of your pets by 100%.

","spells":[]} +1220102,{"name":"Soul of the Strategist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Strategist
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Strategist:

Increases Wyvern Strike damage over time by 50% and increases your pet's maximum focus by 50.

","spells":[]} +1220040,{"name":"Soul of the Malevolent","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Malevolent
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Malevolent:

Periodic damage from your Shadowflame, Unstable Affliction, and Curse of Agony spells and damage done by your Felguard have a 4% chance to grant the Shadow Trance effect.

","spells":[]} +1220232,{"name":"Soul of the Windwalker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Windwalker
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Windwalker:

Increases your attack speed by 30% for your next 3 swings after you parry, dodge, or block.

","spells":[]} +1219992,{"name":"Soul of the Aftershock","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Aftershock
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Aftershock:

Reduces the cooldown on Shockwave by 50%.

","spells":[]} +1220299,{"name":"Soul of the Gentle Paw","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Gentle Paw
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Gentle Paw:

You may cast Rebirth and Innervate while in Bear Form or Dire Bear Form.

","spells":[]} +1220214,{"name":"Soul of the Sealbearer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Sealbearer
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Sealbearer:

Your Seal of Command, Seal of Righteousness, and Seal of Martyrdom now persist for 6 seconds after you cast another Seal, or until you cast a third Seal. Your Judgements can now trigger multiple Seals if active.

","spells":[]} +1220088,{"name":"Soul of the Hound Master","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Hound Master
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Hound Master:

Increases the Focus regeneration of your Beast pet by 20%.

","spells":[]} +1220150,{"name":"Soul of the Arcanist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Arcanist
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Arcanist:

Arcane Blast gains a 10% additional chance to trigger Missile Barrage, and Missile Barrage now affects Regeneration the same way it affects Arcane Missiles.

","spells":[]} +1220354,{"name":"Soul of the Night","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Night
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Night:

Increases the damage done and damage radius of Starfall's stars and Hurricane by 25%.

","spells":[]} +1220208,{"name":"Soul of the Vindicator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Vindicator
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Vindicator:

Reduces the cooldown on Divine Light by 25%.

","spells":[]} +1220060,{"name":"Soul of the Abyssal","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Abyssal
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Abyssal:

While Metamorphosis is active, your offensive abilities and Demon summons cost no Soul Shards. In addition, you heal for 15% of your maximum health when you damage a target with Shadowburn.

","spells":[]} +1220234,{"name":"Soul of the Shield Master","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shield Master
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shield Master:

Your parries and dodges also activate your Shield Mastery rune ability.

","spells":[]} +1220340,{"name":"Soul of the Prideful","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Prideful
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Prideful:

Your critical strike chance is increased by 15% while Tiger's Fury is active.

","spells":[]} +1220362,{"name":"Soul of the Astral Ascendant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Astral Ascendant
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Astral Ascendant:

Increases the critical strike damage bonus of your Starfire, Starsurge, and Wrath by 60%.

","spells":[]} +1220358,{"name":"Soul of the Wrathful","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Wrathful
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Wrathful:

Your Wrath critical strikes have a 50% chance to make your next Starfire deal 10% increased damage, stacking up to 3 times.

","spells":[]} +1220035,{"name":"Soul of the Decimator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Decimator
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Decimator:

Your Nightfall talent has a 4% increased chance to trigger. Your Incinerate has a 4% chance to trigger your Decimation regardless of the target's health.

","spells":[]} +1220274,{"name":"Soul of the Seismic Smasher","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Seismic Smasher
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Seismic Smasher:

Increases Stormstrike and Lava Lash damage by 50%. This effect is increased to 100% if using a two-handed weapon.

","spells":[]} +1220318,{"name":"Soul of the Nurturer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Nurturer
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Nurturer:

Casting your Healing Touch or Nourish spells gives you a 25% chance to gain Mana equal to 35% of the base cost of the spell.

","spells":[]} +1220034,{"name":"Soul of the Refined","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Refined
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Refined:

Increases your critical strike chance with spells and attacks by 2%.

","spells":[]} +1220336,{"name":"Soul of the Ripper","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ripper
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ripper:

Your Rip and Ferocious Bite have a 20% chance per combo point spent to refresh the duration of Savage Roar back to its initial value.

","spells":[]} +1220346,{"name":"Soul of the Exsanguinator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Exsanguinator
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Exsanguinator:

Your Mangle, Shred, and Ferocious Bite critical strikes cause your target to Bleed for 30% of the damage done over the next 4 sec sec.

","spells":[]} +1220366,{"name":"Soul of the Forest","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Forest
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Forest:

Increases the critical strike chance of Wrath by 10%.

","spells":[]} +1219966,{"name":"Soul of the Destroyer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Destroyer
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Destroyer:

Your Slam hits reset the remaining cooldown on your Mortal Strike, Bloodthirst, and Shield Slam abilities.

","spells":[]} +1219972,{"name":"Soul of the Pristine Blocker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Pristine Blocker
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Pristine Blocker:

Increases the block value of your shield by 30.

","spells":[]} +1220080,{"name":"Soul of the Toxinologist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Toxinologist
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Toxinologist:

Your Serpent Sting damage is increased by 25% of your Attack Power over its normal duration.

","spells":[]} +1220182,{"name":"Soul of the Lightwarden","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lightwarden
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lightwarden:

Heal for 189 to 211 when you Block. Can only heal once every few seconds.

","spells":[]} +1219970,{"name":"Soul of the Sanguinist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Sanguinist
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Sanguinist:

You deal 10% increased damage while any nearby enemy is afflicted with both your Rend and your Deep Wounds.

","spells":[]} +1219988,{"name":"Soul of the Southpaw","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Southpaw
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Southpaw:

Reduces the cooldown on your Shield Slam ability by 2 sec.

","spells":[]} +1220004,{"name":"Soul of the Phantom","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Phantom
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Phantom:

Reduces the cooldown on Vanish to 1 min. Cannot be combined with Elusiveness.

","spells":[]} +1220048,{"name":"Soul of the Infernal Shepherd","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Infernal Shepherd
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Infernal Shepherd:

Increases the Attack Power and Spell Damage your Demon pet gains from your attributes by 20%.

","spells":[]} +1220240,{"name":"Soul of the Spiritual Bulwark","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Spiritual Bulwark
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Spiritual Bulwark:

Each time you Block, your Block amount is increased by 10% of your Spell Damage for 6 sec, stacking up to 3 times.

","spells":[]} +1220244,{"name":"Soul of the Lavawalker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lavawalker
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lavawalker:

Damaging a target with Stormstrike, Lava Burst, or Molten Blast also reduces all damage you take by 10% for 10 sec.

","spells":[]} +1220140,{"name":"Soul of the Plaguebringer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Plaguebringer
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Plaguebringer:

Your Pain and Suffering rune can now refresh the duration of Devouring Plague.

","spells":[]} +1220160,{"name":"Soul of the Cryomancer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Cryomancer
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Cryomancer:

Increases damage done by your Frostbolt and Spellfrost Bolt spells by 65%.

","spells":[]} +1219980,{"name":"Soul of the Revenger","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Revenger
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Revenger:

Revenge also grants you Flurry, increasing your attack speed by 30% for the next 3 swings.

","spells":[]} +1220056,{"name":"Soul of the Flamewraith","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Flamewraith
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Flamewraith:

Your Shadow Cleave hits have a 20% chance to grant you a Soul Shard, reset the cooldown on Soul Fire, and make your next Soul Fire within 10 sec instant.

","spells":[]} +1220070,{"name":"Soul of the Misleader","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Misleader
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Misleader:

You generate 100% more threat for 8 sec after using Distracting Shot.

","spells":[]} +1220132,{"name":"Soul of the Spirit Font","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Spirit Font
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Spirit Font:

Your Shadow Word: Pain has a 2.0% chance per talent point in Spirit Tap to trigger your Spirit Tap talent when it deals damage, or a 20% chance per talent point when a target dies with your Shadow Word: Pain active. Inner Focus also has a 20% chance per talent point to trigger Spirit Tap.

","spells":[]} +1220268,{"name":"Soul of the Furycharged","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Furycharged
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Furycharged:

Your chance to trigger Static Shock is increased by 12% (6% while dual - wielding).

","spells":[]} +1220270,{"name":"Soul of the Stormbreaker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Stormbreaker
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Stormbreaker:

Increases the main hand damage done by your Stormstrike by 50%.

","spells":[]} +1220316,{"name":"Soul of the Innervator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Innervator
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Innervator:

When you cast Innervate on another player, it is also cast on you.

","spells":[]} +1219958,{"name":"Soul of the War Veteran","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the War Veteran
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the War Veteran:

For 15 sec after leaving a stance, you can use abilities requiring that stance as if you were still in that stance.

","spells":[]} +1219986,{"name":"Soul of the Sentinel","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Sentinel
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Sentinel:

Your Shield Slam deals 100% increased threat and its cooldown is reset if it is Dodged, Parried, or Blocked.

","spells":[]} +1220064,{"name":"Soul of the Umbral Blade","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Umbral Blade
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Umbral Blade:

Reduces the cooldown on your Shadow Cleave by 1.5 sec.

","spells":[]} +1220078,{"name":"Soul of the Alternator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Alternator
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Alternator:

Your damaging Shot abilities deal 10% increased damage if the previous damaging Shot used was different than the current one.

","spells":[]} +1220138,{"name":"Soul of the Contemnor","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Contemnor
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Contemnor:

Your Mind Spike is now instant, deals 10% more damage, and can be cast while channeling another spell.

","spells":[]} +1220184,{"name":"Soul of the Radiant Defender","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Radiant Defender
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Radiant Defender:

Holy Shield no longer has charges and instead always lasts its full duration. In addition, its damage is increased by 80% of your shield block value.

","spells":[]} +1220186,{"name":"Soul of the Shieldbearer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shieldbearer
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shieldbearer:

Increases the bonus chance to Block from Holy Shield by 10%.

","spells":[]} +1220200,{"name":"Soul of the Exemplar","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Exemplar
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Exemplar:

Whenever your Flash of Light, Holy Light, or Beacon of Light heals a target to full health, you also heal all members of their party for 189 to 211 health.

","spells":[]} +1219982,{"name":"Soul of the Incessant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Incessant
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Incessant:

When your target Parries an attack, you instantly Retaliate for 200% weapon damage to that target. Retaliate cannot be Dodged, Blocked, or Parried, but can only occur once every 30 sec per target.

","spells":[]} +1220076,{"name":"Soul of the Hazard Harrier","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Hazard Harrier
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Hazard Harrier:

Your Aimed Shot deals 20% more damage to targets afflicted by one of your trap effects.

","spells":[]} +1220192,{"name":"Soul of the Ironclad","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ironclad
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ironclad:

Your Blessing of Sanctuary also grants 10% increase to all stats when cast on yourself.

","spells":[]} +1220194,{"name":"Soul of the Guardian","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Guardian
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Guardian:

Shield of the Righteous causes your next Holy Light to be instant cast. If cast on self, it will refund 100% of its mana cost and be unaffected by Guarded by the Light.

","spells":[]} +1220202,{"name":"Soul of the Inquisitor","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Inquisitor
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Inquisitor:

Increases the critical strike chance of Holy Shock by 5%.

","spells":[]} +1220218,{"name":"Soul of the Judicator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Judicator
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Judicator:

Reduces the cooldown on your Judgement ability by 5 sec.

","spells":[]} +1220228,{"name":"Soul of the Exile","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Exile
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Exile:

Reduces the cooldown of your Exorcism spell by 3 sec and increases its damage done by 50%.

","spells":[]} +1220312,{"name":"Soul of the Furious","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Furious
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Furious:

Each time you Dodge while in Dire Bear Form, you gain 10% increased damage on your next Mangle or Swipe, stacking up to 5 times.

","spells":[]} +1220338,{"name":"Soul of the Claw","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Claw
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Claw:

Increases the duration of Rake by 6 sec and its periodic damage by 50%.

","spells":[]} +1220104,{"name":"Soul of the Deadly Striker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Deadly Striker
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Deadly Striker:

Increases the impact damage of Mongoose Bite and all Strikes by 15%.

","spells":[]} +1220166,{"name":"Soul of the Magical Armorer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Magical Armorer
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Magical Armorer:

Mage Armor increases your mana regeneration while casting by an additional 15%. Molten Armor increases your spell damage and healing by 18. Ice Armor grants 20% increased chance to trigger Fingers of Frost.

","spells":[]} +1220230,{"name":"Soul of the Templar","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Templar
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Templar:

Crusader Strike now unleashes the Judgement effect of your Seals, but does not consume the Seal.

","spells":[]} +1220291,{"name":"Soul of the Elements","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Elements
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Elements:

Increases the critical strike damage bonus of your Fire, Frost, and Nature spells by 60%.

","spells":[]} +1220314,{"name":"Soul of the Mangler","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Mangler
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Mangler:

Reduces the cooldown on Mangle (Bear) by 1.5 sec.

","spells":[]} +1220124,{"name":"Soul of the Soul Warder","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Soul Warder
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Soul Warder:

Increases the damage absorbed by your Power Word: Shield spell by 10%.

","spells":[]} +1220126,{"name":"Soul of the Twilight Walker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Twilight Walker
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Twilight Walker:

You may cast Flash Heal while in Shadowform.

","spells":[]} +1220236,{"name":"Soul of the Totemic Protector","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Totemic Protector
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Totemic Protector:

Your Stoneskin Totem also reduces Physical damage taken by 5% and your Windwall Totem also reduces Magical damage taken by 5%.

","spells":[]} +1220008,{"name":"Soul of the Thrill Seeker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Thrill Seeker
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Thrill Seeker:

Reduces the cooldown on Adrenaline Rush by 4 min.

","spells":[]} +1220054,{"name":"Soul of the Pained","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Pained
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Pained:

Each time you take damage, you and your pet gain mana equal to the damage taken, up to a maximum of 420 mana per event. Can only occur once every few seconds.

","spells":[]} +1220226,{"name":"Soul of the Lightbringer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lightbringer
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lightbringer:

Increases damage done by your Holy Shock spell by 50%.

","spells":[]} +1220266,{"name":"Soul of the Chieftain","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Chieftain
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Chieftain:

Your Flurry talent grants an additional 10% increase to your attack speed.

","spells":[]} +1220272,{"name":"Soul of the Tempest","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Tempest
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Tempest:

While Static Shock is engraved, your Lightning Shield now gains a charge each time you hit a target with Lightning Bolt or Chain Lightning, up to a maximum of 9 charges. In addition, while Static Shock is engraved, your Lightning Shield can now deal critical damage.

","spells":[]} +1220332,{"name":"Soul of the Illuminator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Illuminator
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Illuminator:

Your Faerie Fire (Feral) also increases the chance for all attacks to hit that target by 1% for 40 sec.

","spells":[]} +1220360,{"name":"Soul of the Graceful","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Graceful
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Graceful:

Your Nature's Grace talent gains 1 additional charge each time it triggers.

","spells":[]} +1219962,{"name":"Soul of the Bloodseeker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Bloodseeker
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Bloodseeker:

Overpower critical strikes refresh the duration of Rend on your target back to its maximum duration.

","spells":[]} +1220094,{"name":"Soul of the Retaliator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Retaliator
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Retaliator:

Mongoose Bite also activates for 5 sec whenever your target Parries or Blocks or when your melee attack misses.

","spells":[]} +1220120,{"name":"Soul of the Archbishop","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Archbishop
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Archbishop:

Your Circle of Healing now heals the most injured member of the target party for 100% more.

","spells":[]} +1220176,{"name":"Soul of the Igniter","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Igniter
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Igniter:

Increases the damage done by your Ignite talent by 10%.

","spells":[]} +1220242,{"name":"Soul of the Maelstrombringer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Maelstrombringer
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Maelstrombringer:

Each time you Block an attack, you have a 50% chance to trigger your Maelstrom Weapon rune.

","spells":[]} +1220330,{"name":"Soul of the Lifeweaver","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lifeweaver
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lifeweaver:

Your critical heals with Healing Touch, Regrowth, and Nourish instantly heal the target for another 50% of the healing they dealt.

","spells":[]} +1220344,{"name":"Soul of the Frenetic","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Frenetic
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Frenetic:

Your Shred no longer has a positional requirement, but deals 15% more damage if you are behind the target.

","spells":[]} +1220348,{"name":"Soul of the Thornkeeper","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Thornkeeper
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Thornkeeper:

Damage dealt by Thorns increased by 100% and duration increased by 200%.

","spells":[]} +1220052,{"name":"Soul of the Demonic Exorcist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Demonic Exorcist
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Demonic Exorcist:

Banish is now instant cast, and can be cast on yourself while you are a Demon. You cannot Banish yourself while you have Forbearance, and doing so will give you Forbearance for 1 min.

","spells":[]} +1220092,{"name":"Soul of the Huntsman","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Huntsman
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Huntsman:

Your Mongoose Bite also reduces its target's chance to Dodge by 1% and increases your chance to hit by 1% for 30 sec.

","spells":[]} +1220110,{"name":"Soul of the Celebrant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Celebrant
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Celebrant:

Increases your critical strike chance with Prayer of Healing and Circle of Healing by 25%.

","spells":[]} +1220136,{"name":"Soul of the Unwavering Defiler","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Unwavering Defiler
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Unwavering Defiler:

Your Mind Flay no longer loses duration from taking damage and launches a free Mind Spike at the target on cast.

","spells":[]} +1220172,{"name":"Soul of the Perpetual Blaze","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Perpetual Blaze
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Perpetual Blaze:

Your Fireball's periodic effect gains increased damage over its duration equal to 100% of its impact damage.

","spells":[]} +1219968,{"name":"Soul of the Deathbound","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Deathbound
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Deathbound:

Reduces the cooldown on your Death Wish by 50%.

","spells":[]} +1219974,{"name":"Soul of the Savage","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Savage
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Savage:

You gain 1 extra Rage every time you take any damage or deal auto attack damage.

","spells":[]} +1220066,{"name":"Soul of the Ritualist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ritualist
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ritualist:

The effects of your Demonic Sacrifice now persist while you have a Demon pet active, as long as you do not resummon the sacrificed pet. You may have only one Demonic Sacrifice effect active at a time.

","spells":[]} +1220112,{"name":"Soul of the Faithful","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Faithful
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Faithful:

Allows 15% of your Mana regeneration to continue while casting.

","spells":[]} +1219996,{"name":"Soul of the Toxicologist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Toxicologist
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Toxicologist:

Increases the critical strike damage bonus of your Poisons by 100%.

","spells":[]} +1220038,{"name":"Soul of the Rotbringer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Rotbringer
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Rotbringer:

Increases the damage of your periodic spells and Felguard pet by 10 + (5 * ComboPoints)%.

","spells":[]} +1220128,{"name":"Soul of the Mind Breaker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Mind Breaker
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Mind Breaker:

Mind Blast critical strikes reduce the duration of your next Mind Flay by 50% while increasing its total damage by 50%.

","spells":[]} +1220152,{"name":"Soul of the Eternal Caretaker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Eternal Caretaker
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Eternal Caretaker:

Your Temporal Beacons caused by Mass Regeneration now last 21 sec.

","spells":[]} +1220216,{"name":"Soul of the Justicar","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Justicar
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Justicar:

Increases damage done by your damaging Judgements by 20% and your Judgements no longer consume your Seals on the target.

","spells":[]} +1220238,{"name":"Soul of the Shock-Absorber","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shock-Absorber
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shock-Absorber:

Your Flame Shock also grants 30% increased chance to Block for 5 sec or until you Block an attack.

","spells":[]} +1220032,{"name":"Soul of the Transfusionist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Transfusionist
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Transfusionist:

Lifetap generates 50% more mana and 100% less threat.

","spells":[]} +1220144,{"name":"Soul of the Chronohealer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Chronohealer
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Chronohealer:

Increases all chronomantic healing you deal by 10%.

","spells":[]} +1220220,{"name":"Soul of the Ascendant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ascendant
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ascendant:

Your Judgement grants 1% increased Holy damage for 8 sec, stacking up to 5 times.

","spells":[]} +1220224,{"name":"Soul of the Excommunicator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Excommunicator
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Excommunicator:

Your basic attacks increase the damage of your next Exorcism cast within 20 sec by 40%.  Stacking up to 3 times.

","spells":[]} +1220368,{"name":"Soul of Animalistic Expertise","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Animalistic Expertise
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Animalistic Expertise:

Your melee attacks have 5% less chance to be Dodged or Parried.

","spells":[]} +1219990,{"name":"Soul of the Gladiator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Gladiator
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Gladiator:

Reduces the cooldown on your Bloodrage ability by 30 sec while you are in Gladiator Stance.

","spells":[]} +1220014,{"name":"Soul of the Efficient","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Efficient
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Efficient:

Your finishing moves cost 50% less Energy.

","spells":[]} +1220022,{"name":"Soul of the Poised Brawler","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Poised Brawler
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Poised Brawler:

Your Rolling with the Punches now also activates every time you gain a combo point.

","spells":[]} +1220058,{"name":"Soul of the Fleshfeaster","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Fleshfeaster
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Fleshfeaster:

While you are targeting an enemy within 30 yards, Life Tap grants you mana at the expense of your target's health but deals 50 + (5 * ComboPoints)% reduced damage to them. Mana gained remains unchanged.

","spells":[]} +1220034,{"name":"Soul of the Refined","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Refined
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Refined:

Increases your critical strike chance with spells and attacks by 2%.

","spells":[]} +1220118,{"name":"Soul of the Devotee","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Devotee
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Devotee:

Your Prayer of Mending gains 2 additional charges.

","spells":[]} +1220122,{"name":"Soul of the Penitent","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Penitent
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Penitent:

Reduces the cooldown of your Penance spell by 6 sec.

","spells":[]} +1220134,{"name":"Soul of the Zealot","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Zealot
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Zealot:

While Spirit Tap is active, you deal 25% more Shadow damage.

","spells":[]} +1220276,{"name":"Soul of the Flamebringer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Flamebringer
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Flamebringer:

Your Stormstrike, Lava Lash and Lava Burst critical strikes cause your target to burn for 30% of the damage done over 4 sec.

","spells":[]} +1220326,{"name":"Soul of the Feathered Sage","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Feathered Sage
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Feathered Sage:

Increases healing from Wild Growth by 10%. In addition, Wild Growth can now be used in Moonkin Form, and its healing is increased by an additional 50% in that form.

","spells":[]} +1220098,{"name":"Soul of the Lethal Lasher","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lethal Lasher
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lethal Lasher:

Increases damage dealt by your main hand weapon with Raptor Strike and Wyvern Strike by 20%.

","spells":[]} +1220106,{"name":"Soul of the Hastened Healer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Hastened Healer
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Hastened Healer:

-0.1 sec to the casting time of Flash Heal and -0.1 sec to the casting time of Greater Heal.

","spells":[]} +1220114,{"name":"Soul of the Serendipitous","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Serendipitous
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Serendipitous:

Your periodic healing has a 2% chance to make your next spell with a casting time less than 10 seconds an instant cast spell.

","spells":[]} +1220297,{"name":"Soul of the Corrupt","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Corrupt
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Corrupt:

Increases the chance to trigger your Power Surge rune by an additional 5%.

","spells":[]} +1220324,{"name":"Soul of the Grove Tender","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Grove Tender
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Grove Tender:

Your non-periodic spell critical strikes reduce the casting time of your next Healing Touch, Regrowth, or Nourish spell by 0.5 sec.

","spells":[]} +1220334,{"name":"Soul of Predatory Instincts","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Predatory Instincts
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Predatory Instincts:

Periodic damage from your Rake and Rip can now be critical strikes.

","spells":[]} +1219998,{"name":"Soul of the Executioner","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Executioner
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Executioner:

Your finishing moves have a 5% chance per combo point to make your next ability cost no energy.

","spells":[]} +1220016,{"name":"Soul of the Knife Juggler","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Knife Juggler
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Knife Juggler:

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.

","spells":[]} +1220030,{"name":"Soul of the Bloodthirsty","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Bloodthirsty
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Bloodthirsty:

While active, your Main Gauche also causes you to heal for 15% of all damage done by Sinister Strike. Any excess healing becomes a Blood Barrier, absorbing damage up to 20% of your maximum health.

","spells":[]} +1220062,{"name":"Soul of the Voidborne","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Voidborne
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Voidborne:

Any excess healing you deal to yourself  is converted into a shield that absorbs damage. This shield can absorb up to 30 + (5 * ComboPoints)% of your maximum health, and stacks from multiple heals.

","spells":[]} +1220100,{"name":"Soul of the Kineticist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Kineticist
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Kineticist:

Your periodic damage has a 5% chance to reset the cooldown on one of your Strike abilities. The Strike with the longest remaining cooldown is always chosen.

","spells":[]} +1220158,{"name":"Soul of Winter's Grasp","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Winter's Grasp
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Winter's Grasp:

Increases the chance to trigger your Fingers of Frost rune by an additional 15%.

","spells":[]} +1220162,{"name":"Soul of the Evoker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Evoker
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Evoker:

You are immune to all damage while channeling Evocation.

","spells":[]} +1220190,{"name":"Soul of the Reckoner","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Reckoner
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Reckoner:

Your Reckoning talent now has a 20% chance per talent point to trigger when you Block.

","spells":[]} +1220002,{"name":"Soul of the Butcher","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Butcher
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Butcher:

Increases damage dealt by your main hand weapon from combo-generating abilities by 20%.

","spells":[]} +1220026,{"name":"Soul of the Fencer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Fencer
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Fencer:

The cooldown on your Main Gauche resets every time your target Dodges or Parries.

","spells":[]} +1220044,{"name":"Soul of the Chaos Harbinger","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Chaos Harbinger
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Chaos Harbinger:

Reduces the cooldown on your Chaos Bolt by 50% and increases Chaos Bolt and Shadow Bolt damage done by 10%. In addition, Chaos Bolt can now trigger your Improved Shadow Bolt talent.

","spells":[]} +1220046,{"name":"Soul of the Arsonist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Arsonist
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Arsonist:

Each time you hit a target with Conflagrate, you gain 5% increased Fire damage for 20 sec, stacking up to 2 times.

","spells":[]} +1220074,{"name":"Soul of the Sharpshooter","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Sharpshooter
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Sharpshooter:

Your next Shot ability within 12 sec after Aimed Shot deals 20% more damage.

","spells":[]} +1220130,{"name":"Soul of the Deathdealer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Deathdealer
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Deathdealer:

Reduces the cooldown of your Shadow Word: Death spell by 6 sec.

","spells":[]} +1219972,{"name":"Soul of the Pristine Blocker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Pristine Blocker
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Pristine Blocker:

Increases the block value of your shield by 30.

","spells":[]} +1220000,{"name":"Soul of the Opportunist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Opportunist
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Opportunist:

Your opening moves have a 100% chance to make your next ability cost no energy.

","spells":[]} +1220010,{"name":"Soul of the Shiv Savant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shiv Savant
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shiv Savant:

Increases your chance to get a critical strike with Daggers by 5%.

","spells":[]} +1220020,{"name":"Soul of the Equilibrist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Equilibrist
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Equilibrist:

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.

","spells":[]} +1220084,{"name":"Soul of the Trick Shooter","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Trick Shooter
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Trick Shooter:

Kill Shot's cooldown is reduced by 50%.  While Rapid Fire is active with Rapid Killing engraved, Kill Shot has no cooldown and fires 3 additional Kill Shots at 30% damage, with a minimum range.

","spells":[]} +1220116,{"name":"Soul of the Resonant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Resonant
Item Level 55

Binds when picked up
Unique (20)
Classes: Priest
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Resonant:

Circle of Healing and Penance also place a heal over time effect on their targets that heals for 25% as much over 15 sec.

","spells":[]} +1220164,{"name":"Soul of the Elementalist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Elementalist
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Elementalist:

You gain 1% increased damage for 15 sec each time you cast a spell from a different school of magic.

","spells":[]} +1220174,{"name":"Soul of the Pyromaniac","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Pyromaniac
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Pyromaniac:

Your Fire Blast now also causes your next Fire spell to gain 50% increased critical strike chance for 10 sec.

","spells":[]} +1220034,{"name":"Soul of the Refined","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Refined
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Refined:

Increases your critical strike chance with spells and attacks by 2%.

","spells":[]} +1220204,{"name":"Soul of the Sovereign","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Sovereign
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Sovereign:

Increases the damage done by your Consecration by 50%.

","spells":[]} +1220250,{"name":"Soul of the Ancestors","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ancestors
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ancestors:

After casting your Healing Wave, Lesser Healing Wave, or Riptide spell, gives you a 25% chance to gain Mana equal to 35% of the base cost of the spell.

","spells":[]} +1220342,{"name":"Soul of the Barbaric","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Barbaric
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Barbaric:

Your Shred, Ferocious Bite, and Mangle(Cat) abilities deal 10% increased damage per your Bleed effect on the target, up to a maximum of 20% increase.

","spells":[]} +1220352,{"name":"Soul of the Starcaller","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Starcaller
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Starcaller:

Reduces the cooldown on Starfall by 50%.

","spells":[]} +1219994,{"name":"Soul of the Avoidant","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Avoidant
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Avoidant:

Feint also grants Avoidance for 6 sec, reducing all damage taken from area of effect attacks from non-players by 50%.

","spells":[]} +1220006,{"name":"Soul of the Scoundrel","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Scoundrel
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Scoundrel:

Increases Mutilate and Saber Slash damage by 20%.

","spells":[]} +1220023,{"name":"Soul of the Black Belt","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Black Belt
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Black Belt:

Your Rolling with the Punches also grants you 20% increased Armor from items per stack.

","spells":[]} +1220178,{"name":"Soul of the Torcher","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Torcher
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Torcher:

Your Fireball, Frostfire Bolt, and Balefire Bolt spells gain 3% increased damage for each of your Fire effects on your target, up to a maximum increased of 9%.

","spells":[]} +1220248,{"name":"Soul of the Totemkeeper","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Totemkeeper
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Totemkeeper:

The radius of your totems that affect friendly targets is increased to 40 yd.

","spells":[]} +1220258,{"name":"Soul of the Elemental Seer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Elemental Seer
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Elemental Seer:

Increases the healing of Chain Heal and the damage of Chain Lightning by 20%.

","spells":[]} +1220286,{"name":"Soul of the Spirit Guide","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Spirit Guide
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Spirit Guide:

While Clearcasting is active, you deal 15 + (5 * ComboPoints)% more non-Physical damage.

","spells":[]} +1220288,{"name":"Soul of the Elder","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Elder
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Elder:

You have a 70% chance to avoid interruption caused by damage while casting Lightning Bolt, Chain Lightning, or Lava Burst, and a 10% increased chance to trigger your Elemental Focus talent.

","spells":[]} +1220303,{"name":"Soul of the Shifter","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shifter
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shifter:

Bear Form and Dire Bear Form increase all threat you generate by an additional 20%, and Cower now removes all your threat against the target but has a 20 sec longer cooldown.

","spells":[]} +1220086,{"name":"Soul of the Beast Tender","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Beast Tender
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Beast Tender:

Increases the Attack Power your Beast pet gains from your attributes by 20%.

","spells":[]} +1220210,{"name":"Soul of the Altruist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Altruist
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Altruist:

Your heals on your Beacon of Light target also heal the nearest friendly injured target for 90% as much.

","spells":[]} +1220278,{"name":"Soul of the Volcano","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Volcano
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Volcano:

Your Lightning Bolt critical strikes have a 35% chance to reset the cooldown on Lava Burst and Chain Lightning and make the next Lava Burst, Chain Heal, or Chain Lightning within 10 sec instant.

","spells":[]} +1220279,{"name":"Soul of the Raging Flame","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Raging Flame
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Raging Flame:

Lava Burst now also refreshes the duration of Flame Shock on your target back to 12 sec.

","spells":[]} +1220320,{"name":"Soul of the Tranquil","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Tranquil
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Tranquil:

Reduces the cooldown on Tranquility by 100% and increases its healing by 100%.

","spells":[]} +1220322,{"name":"Soul of the Dreamwalker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Dreamwalker
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Dreamwalker:

Your healing spell critical strikes trigger the Dreamstate effect, granting you 50% of your mana regeneration while casting for 8 sec.

","spells":[]} +1219978,{"name":"Soul of the Deflective","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Deflective
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Deflective:

You gain 10 Rage every time you Parry or one of your attacks is Parried.

","spells":[]} +1219984,{"name":"Soul of the Thunderbringer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Thunderbringer
Item Level 55

Binds when picked up
Unique (20)
Classes: Warrior
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Thunderbringer:

Reduces the cooldown on Thunder Clap by 100%.

","spells":[]} +1220146,{"name":"Soul of Temporal Longing","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Temporal Longing
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Temporal Longing:

Each time you heal a target with Regeneration, the remaining cooldown on Rewind Time is reduced by 1 sec.

","spells":[]} +1220156,{"name":"Soul of the Wardshaper","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Wardshaper
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Wardshaper:

Your Mana Shield, Fire Ward, and Frost Ward absorb 50% more damage and also place a Temporal Beacon on the target for 30 sec.

","spells":[]} +1220188,{"name":"Soul of the Bastion","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Bastion
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Bastion:

You take 10% reduced damage while Holy Shield is active.

","spells":[]} +1220196,{"name":"Soul of the Peacekeeper","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Peacekeeper
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Peacekeeper:

Increases the chance for allies to trigger your Judgement of Light or Judgement of Wisdom to 70%.

","spells":[]} +1220212,{"name":"Soul of the Arbiter","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Arbiter
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Arbiter:

Your Judgement of Light and Judgement of Wisdom also grant the effects of Judgement of the Crusader.

","spells":[]} +1220284,{"name":"Soul of the Tribesman","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Tribesman
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Tribesman:

Loyal Beta from your Spirit of the Alpha ability now also increases Fire, Frost, and Nature damage by 5 + (5 * ComboPoints)%.

","spells":[]} +1220012,{"name":"Soul of the Stalker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Stalker
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Stalker:

Increases the critical strike chance of your Ambush ability by 30%.

","spells":[]} +1220028,{"name":"Soul of the Swashbuckler","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Swashbuckler
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Swashbuckler:

Your Main Gauche now strikes 1 additional nearby target and also causes your Sinister Strike to strike 1 additional nearby target for 10 sec. These additional strikes are not duplicated by Blade Flurry.

","spells":[]} +1220148,{"name":"Soul of the Precognitive","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Precognitive
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Precognitive:

Your Arcane Missiles refunds 10% of its base mana cost each time it deals damage.

","spells":[]} +1220154,{"name":"Soul of the Spellbider","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Spellbider
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Spellbider:

Your Arcane Blast increases damage and healing done by an additional 10% per stack.

","spells":[]} +1220206,{"name":"Soul of the Dominus","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Dominus
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Dominus:

While you are not your Beacon of Light target, your Beacon of Light target is also healed by 75% of the damage you deal with Consecration, Exorcism, Holy Shock, Holy Wrath, and Hammer of Wrath.

","spells":[]} +1220295,{"name":"Soul of the Ancestral Warden","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ancestral Warden
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ancestral Warden:

Increases your chance to block attacks with a shield by 10%.

","spells":[]} +1220356,{"name":"Soul of the Keepers","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Keepers
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Keepers:

Your Wrath casts have a 10% chance to summon a stand of 3 Treants to attack your target for 15 sec.

","spells":[]} +1220018,{"name":"Soul of the Shadow Master","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Shadow Master
Item Level 55

Binds when picked up
Unique (20)
Classes: Rogue
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Shadow Master:

Vanish now reduces all Magic damage you take by 50% for its duration, but it no longer grants Stealth or breaks movement impairing effects.

","spells":[]} +1220082,{"name":"Soul of the Bounty Hunter","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Bounty Hunter
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Bounty Hunter:

Increases Kill Shot's damage against non-player controlled targets by 20%.

","spells":[]} +1220168,{"name":"Soul of the Kindler","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Kindler
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Kindler:

Decreases the threat generated by your Fire spells by 20%.

","spells":[]} +1220222,{"name":"Soul of the Retributor","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Retributor
Item Level 55

Binds when picked up
Unique (20)
Classes: Paladin
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Retributor:

Increases Crusader Strike damage by 50%.

","spells":[]} +1220246,{"name":"Soul of the True Alpha","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the True Alpha
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the True Alpha:

When your Spirit of the Alpha is cast on yourself, it also increases your health by 10%, your threat generated by 20%, and all damage you deal by 10%.

","spells":[]} +1220256,{"name":"Soul of the Stormtender","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Stormtender
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Stormtender:

Your Chain Lightning now also heals the target of your most recent Earth Shield for 100% of the damage done.

","spells":[]} +1220262,{"name":"Soul of the Spirithealer","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Spirithealer
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Spirithealer:

Reduces the cast time of Chain Heal by 0.5 sec.

","spells":[]} +1220034,{"name":"Soul of the Refined","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Refined
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Refined:

Increases your critical strike chance with spells and attacks by 2%.

","spells":[]} +1220282,{"name":"Soul of the Elemental Master","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Elemental Master
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Elemental Master:

Your spell critical strikes now have a 100% chance trigger your Elemental Focus talent.

","spells":[]} +1220301,{"name":"Soul of the Ferocious","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Ferocious
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Ferocious:

Reduces the cooldown of Enrage by 30 sec and it no longer reduces your armor.

","spells":[]} +1220301,{"name":"Soul of Echoes","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Echoes
Item Level 55

Binds when picked up
Unique (20)
Classes: Hunter
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Echoes:

Raptor Strike increases the damage done by your next other melee ability (excluding Wing Clip) within 5 sec by 20%.

","spells":[]} +1220170,{"name":"Soul of Fiery Convergence","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of Fiery Convergence
Item Level 55

Binds when picked up
Unique (20)
Classes: Mage
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of Fiery Convergence:

Your Pyroblast deals 20% increased damage to targets afflicted with your Fireball's periodic effect.

","spells":[]} +1220068,{"name":"Soul of the Pain Spreader","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Pain Spreader
Item Level 55

Binds when picked up
Unique (20)
Classes: Warlock
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Pain Spreader:

For 6 sec after using Shadowcleave, your Searing Pain strikes 1 additional target within melee range.

","spells":[]} +1220260,{"name":"Soul of the Vitalist","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Vitalist
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Vitalist:

Your Riptide increases the amount healed by Chain Heal by an additional 25%.

","spells":[]} +1220310,{"name":"Soul of the Lacerator","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lacerator
Item Level 55

Binds when picked up
Unique (20)
Classes: Druid
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lacerator:

Your Swipe now spreads your Lacerate from your primary target to other targets it strikes.

","spells":[]} +1220252,{"name":"Soul of the Spiritweaver","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Spiritweaver
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Spiritweaver:

Your Healing Wave will now jump to additional nearby targets. Each jump reduces the effectiveness of the heal by 60%, and the spell will jump to up to 2 additional targets.

","spells":[]} +1220254,{"name":"Soul of the Waterwalker","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Waterwalker
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Waterwalker:

Your non-periodic damaging and healing critical strikes now have a 100% chance to trigger your Water Shield, but do not consume a charge or trigger its cooldown.

","spells":[]} +1220293,{"name":"Soul of the Lava Sage","quality":3,"icon":"spell_holy_divinespirit","tooltip":"
Soul of the Lava Sage
Item Level 55

Binds when picked up
Unique (20)
Classes: Shaman
Requires Level 55
Use: Permanently imbue your shoulders with the Soul of the Lava Sage:

Your Lava burst damage is increased by a percentage equal to your spell critical strike chance.

","spells":[]} \ No newline at end of file diff --git a/proto/shaman.proto b/proto/shaman.proto index 0892e4fb35..09c2136869 100644 --- a/proto/shaman.proto +++ b/proto/shaman.proto @@ -4,211 +4,240 @@ package proto; option go_package = "./proto"; message ShamanTalents { - // Elemental - int32 convection = 1; - int32 concussion = 2; - int32 earths_grasp = 3; - int32 elemental_warding = 4; - int32 call_of_flame = 5; - bool elemental_focus = 6; - int32 reverberation = 7; - int32 call_of_thunder = 8; - int32 improved_fire_totems = 9; - int32 eye_of_the_storm = 10; - int32 elemental_devastation = 11; - int32 storm_reach = 12; - bool elemental_fury = 13; - int32 lightning_mastery = 14; - bool elemental_mastery = 15; - - // Enhancement - int32 ancestral_knowledge = 16; - int32 shield_specialization = 17; - int32 guardian_totems = 18; - int32 thundering_strikes = 19; - int32 improved_ghost_wolf = 20; - int32 improved_lightning_shield = 21; - int32 enhancing_totems = 22; - bool two_handed_axes_and_maces = 23; - int32 anticipation = 24; - int32 flurry = 25; - int32 toughness = 26; - int32 improved_weapon_totems = 27; - int32 elemental_weapons = 28; - bool parry = 29; - int32 weapon_mastery = 30; - bool stormstrike = 31; - - // Restoration - int32 improved_healing_wave = 32; - int32 tidal_focus = 33; - int32 improved_reincarnation = 34; - int32 ancestral_healing = 35; - int32 totemic_focus = 36; - int32 natures_guidance = 37; - int32 healing_focus = 38; - bool totemic_mastery = 39; - int32 healing_grace = 40; - int32 restorative_totems = 41; - int32 tidal_mastery = 42; - int32 healing_way = 43; - bool natures_swiftness = 44; - int32 purification = 45; - bool mana_tide_totem = 46; + // Elemental + int32 convection = 1; + int32 concussion = 2; + int32 earths_grasp = 3; + int32 elemental_warding = 4; + int32 call_of_flame = 5; + bool elemental_focus = 6; + int32 reverberation = 7; + int32 call_of_thunder = 8; + int32 improved_fire_totems = 9; + int32 eye_of_the_storm = 10; + int32 elemental_devastation = 11; + int32 storm_reach = 12; + bool elemental_fury = 13; + int32 lightning_mastery = 14; + bool elemental_mastery = 15; + + // Enhancement + int32 ancestral_knowledge = 16; + int32 shield_specialization = 17; + int32 guardian_totems = 18; + int32 thundering_strikes = 19; + int32 improved_ghost_wolf = 20; + int32 improved_lightning_shield = 21; + int32 enhancing_totems = 22; + bool two_handed_axes_and_maces = 23; + int32 anticipation = 24; + int32 flurry = 25; + int32 toughness = 26; + int32 improved_weapon_totems = 27; + int32 elemental_weapons = 28; + bool parry = 29; + int32 weapon_mastery = 30; + bool stormstrike = 31; + + // Restoration + int32 improved_healing_wave = 32; + int32 tidal_focus = 33; + int32 improved_reincarnation = 34; + int32 ancestral_healing = 35; + int32 totemic_focus = 36; + int32 natures_guidance = 37; + int32 healing_focus = 38; + bool totemic_mastery = 39; + int32 healing_grace = 40; + int32 restorative_totems = 41; + int32 tidal_mastery = 42; + int32 healing_way = 43; + bool natures_swiftness = 44; + int32 purification = 45; + bool mana_tide_totem = 46; } enum ShamanRune { - RuneNone = 0; - - RuneHelmBurn = 415231; - RuneHelmMentalDexterity = 415140; - RuneHelmTidalWaves = 432042; - - RuneCloakCoherence = 415096; - RuneCloakStormEarthAndFire = 440569; - RuneCloakFeralSpirit = 440580; - - RuneChestDualWieldSpec = 408496; - RuneChestHealingRain = 415236; - RuneChestOverload = 408438; - RuneChestShieldMastery = 408524; - RuneChestTwoHandedMastery = 436364; - - RuneBracersOvercharged = 432140; - RuneBracersRiptide = 408521; - RuneBracersRollingThunder = 432056; - RuneBracersStaticShock = 432134; - - RuneHandsLavaBurst = 408490; - RuneHandsLavaLash = 408507; - RuneHandsMoltenBlast = 425339; - RuneHandsWaterShield = 408510; - - RuneWaistFireNova = 408339; - RuneWaistMaelstromWeapon = 408498; - RuneWaistPowerSurge = 415100; - - RuneLegsAncestralGuidance = 409324; - RuneLegsEarthShield = 408514; - RuneLegsWayOfEarth = 408531; - RuneLegsGreaterGhostWolf = 415813; - - RuneFeetAncestralAwakening = 425858; - RuneFeetDecoyTotem = 425874; - RuneFeetSpiritOfTheAlpha = 408696; + RuneNone = 0; + + RuneHelmBurn = 415231; + RuneHelmMentalDexterity = 415140; + RuneHelmTidalWaves = 432042; + + RuneShouldersAncestralWarden = 1220295; + RuneShouldersChieftain = 1220266; + RuneShouldersCorrupt = 1220297; + RuneShouldersElder = 1220288; + RuneShouldersElementalMaster = 1220282; + RuneShouldersElementalSeer = 1220258; + RuneShouldersElements = 1220291; + RuneShouldersFlamebringer = 1220276; + RuneShouldersFurycharged = 1220268; + RuneShouldersLavaSage = 1220293; + RuneShouldersLavaWalker = 1220244; + RuneShouldersMaelstrombringer = 1220242; + RuneShouldersRagingFlame = 1220279; + RuneShouldersRefined = 1220034; + RuneShouldersSeismicSmasher = 1220274; + RuneShouldersShieldMaster = 1220234; + RuneShouldersShockAbsorber = 1220238; + RuneShouldersSpiritualBulwark = 1220240; + RuneShouldersSpiritGuide = 1220286; + RuneShouldersStormbreaker = 1220270; + RuneShouldersStormtender = 1220256; + RuneShouldersTempest = 1220272; + RuneShouldersTotemicProtector = 1220236; + RuneShouldersTribesman = 1220284; + RuneShouldersTrueAlpha = 1220246; + RuneShouldersVolcano = 1220278; + RuneShouldersWaterWalker = 1220254; + RuneShouldersWindwalker = 1220232; + + RuneCloakCoherence = 415096; + RuneCloakStormEarthAndFire = 440569; + RuneCloakFeralSpirit = 440580; + + RuneChestDualWieldSpec = 408496; + RuneChestHealingRain = 415236; + RuneChestOverload = 408438; + RuneChestShieldMastery = 408524; + RuneChestTwoHandedMastery = 436364; + + RuneBracersOvercharged = 432140; + RuneBracersRiptide = 408521; + RuneBracersRollingThunder = 432056; + RuneBracersStaticShock = 432134; + + RuneHandsLavaBurst = 408490; + RuneHandsLavaLash = 408507; + RuneHandsMoltenBlast = 425339; + RuneHandsWaterShield = 408510; + + RuneWaistFireNova = 408339; + RuneWaistMaelstromWeapon = 408498; + RuneWaistPowerSurge = 415100; + + RuneLegsAncestralGuidance = 409324; + RuneLegsEarthShield = 408514; + RuneLegsWayOfEarth = 408531; + RuneLegsGreaterGhostWolf = 415813; + + RuneFeetAncestralAwakening = 425858; + RuneFeetDecoyTotem = 425874; + RuneFeetSpiritOfTheAlpha = 408696; } enum EarthTotem { - NoEarthTotem = 0; - StrengthOfEarthTotem = 1; - TremorTotem = 2; - StoneskinTotem = 3; + NoEarthTotem = 0; + StrengthOfEarthTotem = 1; + TremorTotem = 2; + StoneskinTotem = 3; } enum AirTotem { - NoAirTotem = 0; - WindfuryTotem = 1; - GraceOfAirTotem = 2; + NoAirTotem = 0; + WindfuryTotem = 1; + GraceOfAirTotem = 2; } enum FireTotem { - NoFireTotem = 0; - MagmaTotem = 1; - SearingTotem = 2; - FireNovaTotem = 3; + NoFireTotem = 0; + MagmaTotem = 1; + SearingTotem = 2; + FireNovaTotem = 3; } enum WaterTotem { - NoWaterTotem = 0; - ManaSpringTotem = 1; - HealingStreamTotem = 2; + NoWaterTotem = 0; + ManaSpringTotem = 1; + HealingStreamTotem = 2; } // Deprecated on 2024-02-08. Use APL totems instead message ShamanTotems { - // Not used here, but used by APL - enum TotemType { - TypeUnknown = 0; - Earth = 1; - Air = 2; - Fire = 3; - Water = 4; - } - - EarthTotem earth = 1; - AirTotem air = 2; - FireTotem fire = 3; - WaterTotem water = 4; - - // If set, will use mana tide when appropriate. - bool use_mana_tide = 5; - - // If set, any time a 2-minute totem is about to expire, will recall and - // replace all totems. - bool recall_totems = 8; - - // If set will use fire totems as an MCD instead of manually controlling when to place them. - bool use_fire_mcd = 9; - - // Bonus spell power for fire elemental snapshotting. - int32 bonus_spellpower = 10; - - // Snapshot fire elemental using Tier 10 4 set bonus. - bool enh_tier_ten_bonus = 11; + // Not used here, but used by APL + enum TotemType { + TypeUnknown = 0; + Earth = 1; + Air = 2; + Fire = 3; + Water = 4; + } + + EarthTotem earth = 1; + AirTotem air = 2; + FireTotem fire = 3; + WaterTotem water = 4; + + // If set, will use mana tide when appropriate. + bool use_mana_tide = 5; + + // If set, any time a 2-minute totem is about to expire, will recall and + // replace all totems. + bool recall_totems = 8; + + // If set will use fire totems as an MCD instead of manually controlling when to place them. + bool use_fire_mcd = 9; + + // Bonus spell power for fire elemental snapshotting. + int32 bonus_spellpower = 10; + + // Snapshot fire elemental using Tier 10 4 set bonus. + bool enh_tier_ten_bonus = 11; } enum ShamanSyncType { NoSync = 0; SyncMainhandOffhandSwings = 1; DelayOffhandSwings = 2; - Auto = 3; + Auto = 3; } message ElementalShaman { - message Rotation { - } + message Rotation { + } - // NextIndex: 6 - message Options { - } - Options options = 3; + // NextIndex: 6 + message Options { + } + Options options = 3; } message EnhancementShaman { - message Rotation { - } - - // NextIndex: 7 - message Options { - ShamanSyncType sync_type = 3; - } - Options options = 3; + message Rotation { + } + + // NextIndex: 7 + message Options { + ShamanSyncType sync_type = 3; + } + Options options = 3; } enum ShamanHealSpell { - AutoHeal = 0; - HealingWave = 1; - LesserHealingWave = 2; - ChainHeal = 3; + AutoHeal = 0; + HealingWave = 1; + LesserHealingWave = 2; + ChainHeal = 3; } message RestorationShaman { - message Rotation { - } - - // NextIndex: 8 - message Options { - int32 earth_shield_p_p_m = 5; - ShamanTotems totems = 6 [deprecated=true]; - } - Options options = 3; + message Rotation { + } + + // NextIndex: 8 + message Options { + int32 earth_shield_p_p_m = 5; + ShamanTotems totems = 6 [deprecated=true]; + } + Options options = 3; } message WardenShaman { - message Rotation { - } + message Rotation { + } - message Options { - } - Options options = 1; + message Options { + } + Options options = 1; } diff --git a/sim/core/aura.go b/sim/core/aura.go index 7ffb003c2c..93c0c17ce7 100644 --- a/sim/core/aura.go +++ b/sim/core/aura.go @@ -18,6 +18,7 @@ type OnInit func(aura *Aura, sim *Simulation) type OnReset func(aura *Aura, sim *Simulation) type OnDoneIteration func(aura *Aura, sim *Simulation) type OnGain func(aura *Aura, sim *Simulation) +type OnRefresh func(aura *Aura, sim *Simulation) type OnExpire func(aura *Aura, sim *Simulation) type OnStacksChange func(aura *Aura, sim *Simulation, oldStacks int32, newStacks int32) type OnStatsChange func(aura *Aura, sim *Simulation, oldStats stats.Stats, newStats stats.Stats) @@ -89,6 +90,7 @@ type Aura struct { OnReset OnReset OnDoneIteration OnDoneIteration OnGain OnGain + OnRefresh OnRefresh OnExpire OnExpire OnStacksChange OnStacksChange // Invoked when the number of stacks of this aura changes. OnStatsChange OnStatsChange // Invoked when the stats of this aura owner changes. @@ -179,6 +181,10 @@ func (aura *Aura) Refresh(sim *Simulation) { if sim.Log != nil && aura.IsActive() && !aura.ActionID.IsEmptyAction() { aura.Unit.Log(sim, "Aura refreshed: %s", aura.ActionID) } + + if aura.OnRefresh != nil { + aura.OnRefresh(aura, sim) + } } func (aura *Aura) GetStacks() int32 { @@ -276,6 +282,19 @@ func (aura *Aura) ApplyOnGain(newOnGain OnGain) { } } +// Adds a handler to be called OnRefresh, in addition to any current handlers. +func (aura *Aura) ApplyOnRefresh(newOnRefresh OnRefresh) { + oldOnRefresh := aura.OnRefresh + if oldOnRefresh == nil { + aura.OnRefresh = newOnRefresh + } else { + aura.OnRefresh = func(aura *Aura, sim *Simulation) { + oldOnRefresh(aura, sim) + newOnRefresh(aura, sim) + } + } +} + // Adds a handler to be called OnExpire, in addition to any current handlers. func (aura *Aura) ApplyOnExpire(newOnExpire OnExpire) { oldOnExpire := aura.OnExpire diff --git a/sim/core/database.go b/sim/core/database.go index 5c20b4156d..319af4020c 100644 --- a/sim/core/database.go +++ b/sim/core/database.go @@ -175,6 +175,10 @@ func (equipment *Equipment) Head() *Item { return &equipment[proto.ItemSlot_ItemSlotHead] } +func (equipment *Equipment) Shoulders() *Item { + return &equipment[proto.ItemSlot_ItemSlotShoulder] +} + func (equipment *Equipment) Hands() *Item { return &equipment[proto.ItemSlot_ItemSlotHands] } diff --git a/sim/shaman/air_totems.go b/sim/shaman/air_totems.go index 3fe8ea07fb..24189dd741 100644 --- a/sim/shaman/air_totems.go +++ b/sim/shaman/air_totems.go @@ -127,16 +127,12 @@ func (shaman *Shaman) registerWindwallTotemSpell() { } func (shaman *Shaman) newWindwallTotemSpellConfig(rank int) core.SpellConfig { - has6PEarthfuryResolve := shaman.HasSetBonus(ItemSetEarthfuryResolve, 6) - spellId := WindwallTotemSpellId[rank] manaCost := WindwallTotemManaCost[rank] level := WindwallTotemLevel[rank] duration := time.Second * 120 - windwallTotemAura := core.ImprovedWindwallTotemAura(&shaman.Unit) - spell := shaman.newTotemSpellConfig(manaCost, spellId) spell.RequiredLevel = level spell.Rank = rank @@ -147,9 +143,6 @@ func (shaman *Shaman) newWindwallTotemSpellConfig(rank int) core.SpellConfig { // We don't have a separation of Melee vs Ranged bonus physical damage at the moment // but it's probably fine because bosses generally don't have ranged physical attacks. // core.WindwallTotemAura(&shaman.Unit, shaman.Level, shaman.Talents.GuardianTotems).Activate(sim) - if has6PEarthfuryResolve { - windwallTotemAura.Activate(sim) - } } return spell } diff --git a/sim/shaman/earth_totems.go b/sim/shaman/earth_totems.go index 9ddd1be9a2..e2e4ae7802 100644 --- a/sim/shaman/earth_totems.go +++ b/sim/shaman/earth_totems.go @@ -83,8 +83,6 @@ func (shaman *Shaman) registerStoneskinTotemSpell() { } func (shaman *Shaman) newStoneskinTotemSpellConfig(rank int) core.SpellConfig { - has6PEarthfuryResolve := shaman.HasSetBonus(ItemSetEarthfuryResolve, 6) - spellId := StoneskinTotemSpellId[rank] manaCost := StoneskinTotemManaCost[rank] level := StoneskinTotemLevel[rank] @@ -99,9 +97,6 @@ func (shaman *Shaman) newStoneskinTotemSpellConfig(rank int) core.SpellConfig { shaman.ActiveTotems[EarthTotem] = spell core.StoneskinTotemAura(&shaman.Unit, shaman.Talents.GuardianTotems).Activate(sim) - if has6PEarthfuryResolve { - core.ImprovedStoneskinTotemAura(&shaman.Unit).Activate(sim) - } } return spell } diff --git a/sim/shaman/item_sets_pve.go b/sim/shaman/item_sets_pve.go index ec45fc2e57..12ba0e3fd1 100644 --- a/sim/shaman/item_sets_pve.go +++ b/sim/shaman/item_sets_pve.go @@ -1,11 +1,9 @@ package shaman import ( - "slices" "time" "github.com/wowsims/sod/sim/core" - "github.com/wowsims/sod/sim/core/proto" "github.com/wowsims/sod/sim/core/stats" ) @@ -113,698 +111,3 @@ var ItemSetEmeraldLadenChain = core.NewItemSet(core.ItemSet{ }, }, }) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 4 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var ItemSetTheFiveThunders = core.NewItemSet(core.ItemSet{ - Name: "The Five Thunders", - Bonuses: map[int32]core.ApplyEffect{ - // +40 Attack Power, up to 23 increased damage from spells, and up to 44 increased healing from spells. - 2: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddStats(stats.Stats{ - stats.AttackPower: 40, - stats.RangedAttackPower: 40, - stats.SpellDamage: 23, - stats.HealingPower: 44, - }) - }, - // 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. - 4: func(agent core.Agent) { - c := agent.GetCharacter() - - procAura := c.NewTemporaryStatsAura("The Furious Storm", core.ActionID{SpellID: 27775}, 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{ - 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{ - Name: "Item - The Furious Storm Proc (Spell Cast)", - Callback: core.CallbackOnCastComplete, - ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, - ProcChance: 0.04, - Handler: handler, - }) - }, - // +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 ItemSetEarthfuryEruption = core.NewItemSet(core.ItemSet{ - Name: "Earthfury Eruption", - Bonuses: map[int32]core.ApplyEffect{ - // The radius of your totems that affect friendly targets is increased to 40 yd. - 2: func(agent core.Agent) { - // Nothing to do - }, - // Your Lightning Bolt critical strikes have a 35% chance to reset the cooldown on Lava Burst and Chain Lightning and make the next Lava Burst, Chain Heal, or Chain Lightning within 10 sec instant. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.GetOrRegisterAura(core.Aura{ - Label: "S03 - Item - T1 - Shaman - Elemental 4P Bonus", - 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_ShamanLightningBolt && spell.ProcMask.Matches(core.ProcMaskSpellDamage) && result.DidCrit() && sim.Proc(.35, "Power Surge") { - shaman.PowerSurgeDamageAura.Activate(sim) - } - }, - }) - }, - // Lava Burst now also refreshes the duration of Flame Shock on your target back to 12 sec. - 6: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - core.MakePermanent(shaman.GetOrRegisterAura(core.Aura{ - Label: "S03 - Item - T1 - Shaman - Elemental 6P Bonus", - OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { - if spell.SpellCode == SpellCode_ShamanLavaBurst { - for _, spell := range shaman.FlameShock { - if spell == nil { - continue - } - - if dot := spell.Dot(shaman.CurrentTarget); dot.IsActive() { - dot.NumberOfTicks = dot.OriginalNumberOfTicks - dot.Rollover(sim) - } - } - } - }, - })) - }, - }, -}) - -var ItemSetEarthfuryRelief = core.NewItemSet(core.ItemSet{ - Name: "Earthfury Relief", - Bonuses: map[int32]core.ApplyEffect{ - // The radius of your totems that affect friendly targets is increased to 40 yd. - 2: func(agent core.Agent) { - // Nothing to do - }, - // After casting your Healing Wave, Lesser Healing Wave, or Riptide spell, gives you a 25% chance to gain Mana equal to 35% of the base cost of the spell. - 4: func(agent core.Agent) { - // Not implementing for now - }, - // Your Healing Wave will now jump to additional nearby targets. Each jump reduces the effectiveness of the heal by 80%, and the spell will jump to up to 2 additional targets. - 6: func(agent core.Agent) { - // Not implementing for now - }, - }, -}) - -var ItemSetEarthfuryImpact = core.NewItemSet(core.ItemSet{ - Name: "Earthfury Impact", - Bonuses: map[int32]core.ApplyEffect{ - // The radius of your totems that affect friendly targets is increased to 40 yd. - 2: func(agent core.Agent) { - // Nothing to do - }, - // Increases your critical strike chance with spells and attacks by 2%. - 4: func(agent core.Agent) { - c := agent.GetCharacter() - c.AddStats(stats.Stats{ - stats.MeleeCrit: 2 * core.CritRatingPerCritChance, - stats.SpellCrit: 2 * core.CritRatingPerCritChance, - }) - }, - // Your Flurry talent grants an additional 10% increase to your attack speed. - 6: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T1 - Shaman - Enhancement 6P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - shaman.bonusFlurrySpeed += .10 - }, - }) - }, - }, -}) - -var ItemSetEarthfuryResolve = core.NewItemSet(core.ItemSet{ - Name: "Earthfury Resolve", - Bonuses: map[int32]core.ApplyEffect{ - // Increases your attack speed by 30% for your next 3 swings after you parry, dodge, or block. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - flurryAura := shaman.makeFlurryAura(5) - // The consumption trigger may not exist if the Shaman doesn't talent into Flurry - shaman.makeFlurryConsumptionTrigger(flurryAura) - - core.MakePermanent(shaman.GetOrRegisterAura(core.Aura{ - Label: "S03 - Item - T1 - Shaman - Tank 2P Bonus", - OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.DidParry() || result.DidDodge() || result.DidBlock() { - flurryAura.Activate(sim) - flurryAura.SetStacks(sim, 3) - } - }, - })) - }, - // Your parries and dodges also activate your Shield Mastery rune ability. - 4: func(agent core.Agent) { - // Implemented in runes.go - }, - // Your Stoneskin Totem also reduces Physical damage taken by 5% and your Windwall Totem also reduces Magical damage taken by 5%. - 6: func(agent core.Agent) { - // Debuffs implemented in core/buffs.go, activated with a raid buff setting or in earth_totems.go and air_totems.go - }, - }, -}) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 5 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var ItemSetEruptionOfTheTenStorms = core.NewItemSet(core.ItemSet{ - Name: "Eruption of the Ten Storms", - Bonuses: map[int32]core.ApplyEffect{ - // Your spell critical strikes now have a 100% chance trigger your Elemental Focus talent. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.Talents.ElementalFocus { - return - } - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Elemental 2P Bonus", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if shaman.isShamanDamagingSpell(spell) && result.DidCrit() { - shaman.ClearcastingAura.Activate(sim) - shaman.ClearcastingAura.SetStacks(sim, shaman.ClearcastingAura.MaxStacks) - } - }, - })) - }, - // Loyal Beta from your Spirit of the Alpha ability now also increases Fire, Frost, and Nature damage by 5%. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneFeetSpiritOfTheAlpha) { - return - } - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Elemental 4P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - oldOnGain := shaman.LoyalBetaAura.OnGain - shaman.LoyalBetaAura.OnGain = func(aura *core.Aura, sim *core.Simulation) { - oldOnGain(aura, sim) - shaman.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFrost] *= 1.05 - shaman.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFire] *= 1.05 - shaman.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexNature] *= 1.05 - } - }, - })) - }, - // While Clearcasting is active, you deal 15% more non-Physical damage. - 6: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.Talents.ElementalFocus { - return - } - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Elemental 6P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - oldOnGain := shaman.ClearcastingAura.OnGain - shaman.ClearcastingAura.OnGain = func(aura *core.Aura, sim *core.Simulation) { - oldOnGain(aura, sim) - shaman.PseudoStats.SchoolDamageDealtMultiplier.MultiplyMagicSchools(1.15) - } - - oldOnExpire := shaman.ClearcastingAura.OnExpire - shaman.ClearcastingAura.OnExpire = func(aura *core.Aura, sim *core.Simulation) { - oldOnExpire(aura, sim) - shaman.PseudoStats.SchoolDamageDealtMultiplier.MultiplyMagicSchools(1 / 1.15) - } - }, - })) - }, - }, -}) - -var ItemSetResolveOfTheTenStorms = core.NewItemSet(core.ItemSet{ - Name: "Resolve of the Ten Storms", - Bonuses: map[int32]core.ApplyEffect{ - // Your Flame Shock also grants 30% increased chance to Block for 5 sec or until you Block an attack. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - shieldBlockAura := shaman.RegisterAura(core.Aura{ - ActionID: core.ActionID{SpellID: 467891}, - Label: "Shield Block", - Duration: time.Second * 5, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - shaman.AddStatDynamic(sim, stats.Block, 30*core.BlockRatingPerBlockChance) - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - shaman.AddStatDynamic(sim, stats.Block, -30*core.BlockRatingPerBlockChance) - }, - OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, _ *core.Spell, result *core.SpellResult) { - if result.DidBlock() { - aura.Deactivate(sim) - } - }, - }) - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Tank 2P Bonus", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell.SpellCode == SpellCode_ShamanFlameShock { - shieldBlockAura.Activate(sim) - } - }, - })) - }, - // Each time you Block, your Block amount is increased by 10% of your Spell Damage for 6 sec, stacking up to 3 times. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - statDeps := []*stats.StatDependency{ - nil, - shaman.NewDynamicMultiplyStat(stats.BlockValue, 1.10), - shaman.NewDynamicMultiplyStat(stats.BlockValue, 1.20), - shaman.NewDynamicMultiplyStat(stats.BlockValue, 1.30), - } - - // Couldn't find a separate spell for this - blockAura := shaman.RegisterAura(core.Aura{ - ActionID: core.ActionID{SpellID: 467909}, - Label: "S03 - Item - T2 - Shaman - Tank 4P Bonus", - Duration: time.Second * 6, - MaxStacks: 3, - OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) { - if oldStacks != 0 { - shaman.DisableDynamicStatDep(sim, statDeps[oldStacks]) - } - if newStacks != 0 { - shaman.EnableDynamicStatDep(sim, statDeps[newStacks]) - } - }, - }) - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Tank 4P Bonus Trigger", - OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.DidBlock() { - blockAura.Activate(sim) - blockAura.AddStack(sim) - } - }, - })) - }, - // Each time you Block an attack, you have a 50% chance to trigger your Maelstrom Weapon rune. - 6: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneWaistMaelstromWeapon) { - return - } - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Tank 6P Bonus", - OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.DidBlock() && sim.Proc(0.50, "T2 6P Proc Maelstrom Weapon") { - shaman.MaelstromWeaponAura.Activate(sim) - shaman.MaelstromWeaponAura.AddStack(sim) - } - }, - })) - }, - }, -}) - -var ItemSetImpactOfTheTenStorms = core.NewItemSet(core.ItemSet{ - Name: "Impact of the Ten Storms", - Bonuses: map[int32]core.ApplyEffect{ - // Your chance to trigger Static Shock is increased by 12% (6% while dual-wielding) - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneBracersStaticShock) { - return - } - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Enhancement 2P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - shaman.staticSHocksProcChance += 0.06 - }, - })) - }, - // Main-hand Stormstrike now deals 50% more damage. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.Talents.Stormstrike { - return - } - - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Enhancement 4P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - shaman.StormstrikeMH.DamageMultiplier += 0.50 - }, - }) - }, - // Your Lightning Shield now gains a charge each time you hit a target with Lightning Bolt or Chain Lightning, up to a maximum of 9 charges. - // In addition, your Lightning Shield can now deal critical damage. - // Note: Only works with Static Shock - 6: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneBracersStaticShock) { - return - } - - affectedSpellCodes := []int32{SpellCode_ShamanLightningBolt, SpellCode_ShamanChainLightning} - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Enhancement 6P Bonus", - OnInit: func(t26pAura *core.Aura, sim *core.Simulation) { - for _, aura := range shaman.LightningShieldAuras { - if aura == nil { - continue - } - - oldOnGain := aura.OnGain - aura.OnGain = func(aura *core.Aura, sim *core.Simulation) { - oldOnGain(aura, sim) - t26pAura.Activate(sim) - } - - oldOnExpire := aura.OnExpire - aura.OnExpire = func(aura *core.Aura, sim *core.Simulation) { - oldOnExpire(aura, sim) - t26pAura.Deactivate(sim) - } - } - - shaman.lightningShieldCanCrit = true - }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - // Tested and it doesn't proc from overloads - if slices.Contains(affectedSpellCodes, spell.SpellCode) && spell.ActionID.Tag != CastTagOverload && result.Landed() { - shaman.ActiveShieldAura.AddStack(sim) - } - }, - })) - }, - }, -}) - -var ItemSetReliefOfTheTenStorms = core.NewItemSet(core.ItemSet{ - Name: "Relief of the Ten Storms", - Bonuses: map[int32]core.ApplyEffect{ - // Your damaging and healing critical strikes now have a 100% chance to trigger your Water Shield, but do not consume a charge or trigger its cooldown. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneHandsWaterShield) { - return - } - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Restoration 2P Bonus", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell.ProcMask.Matches(core.ProcMaskSpellDamage) && result.DidCrit() { - shaman.WaterShieldRestore.Cast(sim, aura.Unit) - } - }, - })) - }, - // Your Chain Lightning now also heals the target of your Earth Shield for 100% of the damage done. - 4: func(agent core.Agent) { - // TODO: Implement Earth Shield - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneLegsEarthShield) { - return - } - - // core.MakePermanent(shaman.RegisterAura()) - }, - // Increases the healing of Chain Heal and the damage of Chain Lightning by 20%. - 6: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - T2 - Shaman - Restoration 6P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - spells := core.FilterSlice( - core.Flatten([][]*core.Spell{ - shaman.ChainHeal, - shaman.ChainHealOverload, - shaman.ChainLightning, - shaman.ChainLightningOverload, - }), func(spell *core.Spell) bool { return spell != nil }, - ) - - for _, spell := range spells { - spell.DamageMultiplierAdditive += 0.20 - } - }, - }) - }, - }, -}) - -var ItemSetAugursRegalia = core.NewItemSet(core.ItemSet{ - Name: "Augur's Regalia", - Bonuses: map[int32]core.ApplyEffect{ - // Increased Defense +7. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.AddStat(stats.Defense, 7) - }, - // Increases your chance to block attacks with a shield by 10%. - 3: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.AddStat(stats.Block, 10*core.BlockRatingPerBlockChance) - }, - // Increases the chance to trigger your Power Surge rune by an additional 5%. - 5: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - if !shaman.HasRune(proto.ShamanRune_RuneWaistPowerSurge) { - return - } - - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - ZG - Shaman - Tank 5P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - shaman.powerSurgeProcChance += .05 - }, - }) - }, - }, -}) - -/////////////////////////////////////////////////////////////////////////// -// SoD Phase 6 Item Sets -/////////////////////////////////////////////////////////////////////////// - -var ItemSetStormcallersEruption = core.NewItemSet(core.ItemSet{ - Name: "Stormcaller's Eruption", - Bonuses: map[int32]core.ApplyEffect{ - // You have a 70% chance to avoid interruption caused by damage while casting Lightning Bolt, Chain Lightning, or Lava Burst, and a 10% increased chance to trigger your Elemental Focus talent. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Shaman - Elemental 2P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - affectedPushbackSpells := core.FilterSlice( - core.Flatten( - [][]*core.Spell{ - shaman.LightningBolt, - shaman.ChainLightning, - {shaman.LavaBurst}, - }, - ), - func(spell *core.Spell) bool { return spell != nil }, - ) - - for _, spell := range affectedPushbackSpells { - spell.PushbackReduction += .70 - } - - shaman.elementalFocusProcChance += .10 - }, - }) - }, - // Increases the critical strike damage bonus of your Fire, Frost, and Nature spells by 60%. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.OnSpellRegistered(func(spell *core.Spell) { - if (spell.Flags.Matches(SpellFlagShaman) || spell.Flags.Matches(SpellFlagTotem)) && spell.DefenseType == core.DefenseTypeMagic { - spell.CritDamageBonus += 0.60 - } - }) - }, - }, -}) - -var ItemSetStormcallersResolve = core.NewItemSet(core.ItemSet{ - Name: "Stormcaller's Resolve", - Bonuses: map[int32]core.ApplyEffect{ - // Damaging a target with Stormstrike, Lava Burst, or Molten Blast also reduces all damage you take by 10% for 10 sec. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - affectedSpellCodess := []int32{SpellCode_ShamanStormstrike, SpellCode_ShamanLavaBurst, SpellCode_ShamanMoltenBlast} - - buffAura := shaman.RegisterAura(core.Aura{ - ActionID: core.ActionID{SpellID: 1213934}, - Label: "Stormbraced", - Duration: time.Second * 10, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.PseudoStats.DamageTakenMultiplier *= 0.90 - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.PseudoStats.DamageTakenMultiplier /= 0.90 - }, - }) - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Shaman - Elemental 2P Bonus", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.Landed() && slices.Contains(affectedSpellCodess, spell.SpellCode) { - buffAura.Activate(sim) - } - }, - })) - }, - // Your Spirit of the Alpha also increases your health by 10%, threat by 20%, and damage by 10% when cast on self. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - // Do a simple multiply stat because we assume that a tank shaman is using Alpha on theirself - if shaman.HasRune(proto.ShamanRune_RuneFeetSpiritOfTheAlpha) && shaman.IsTanking() { - shaman.PseudoStats.DamageDealtMultiplier *= 1.10 - shaman.PseudoStats.ThreatMultiplier *= 1.20 - shaman.MultiplyStat(stats.Health, 1.10) - } - }, - }, -}) - -var ItemSetStormcallersRelief = core.NewItemSet(core.ItemSet{ - Name: "Stormcaller's Relief", - Bonuses: map[int32]core.ApplyEffect{ - // Your Riptide increases the amount healed by Chain Heal by an additional 25%. - 2: func(agent core.Agent) { - }, - // Reduces the cast time of Chain Heal by 0.5 sec. - 4: func(agent core.Agent) { - }, - }, -}) - -var ItemSetStormcallersImpact = core.NewItemSet(core.ItemSet{ - Name: "Stormcaller's Impact", - Bonuses: map[int32]core.ApplyEffect{ - // Increases Stormstrike and Lava Lash damage by 50%. Stormstrike's damage is increased by an additional 50% when using a Two-handed weapon. - 2: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Shaman - Enhancement 2P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - if shaman.StormstrikeMH != nil { - shaman.StormstrikeMH.DamageMultiplierAdditive += core.TernaryFloat64(shaman.HasRune(proto.ShamanRune_RuneChestTwoHandedMastery), 1.00, 0.50) - } - - if shaman.StormstrikeOH != nil { - shaman.StormstrikeOH.DamageMultiplierAdditive += 0.50 - } - - if shaman.LavaLash != nil { - shaman.LavaLash.DamageMultiplierAdditive += 0.50 - } - }, - }) - }, - // Your Stormstrike, Lava Lash, and Lava Burst critical strikes cause your target to burn for 30% of the damage done over 4 sec. - 4: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - - // This is the spell used for the burn proc. - // https://www.wowhead.com/classic/spell=1213915/burning - burnSpell := shaman.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 1213915}, - SpellSchool: core.SpellSchoolFire, - DefenseType: core.DefenseTypeMagic, - ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell, - - DamageMultiplier: 1, - ThreatMultiplier: 1, - BonusCoefficient: 1, - - Dot: core.DotConfig{ - Aura: core.Aura{ - Label: "Burning", - }, - NumberOfTicks: 2, - TickLength: time.Second * 2, - OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { - dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeTick) - }, - }, - - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - spell.Dot(target).ApplyOrRefresh(sim) - spell.CalcAndDealOutcome(sim, target, spell.OutcomeAlwaysHitNoHitCounter) - }, - }) - - core.MakePermanent(shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - TAQ - Shaman - Enhancement 4P Bonus", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if !result.Outcome.Matches(core.OutcomeCrit) || !(spell == shaman.StormstrikeMH || spell == shaman.StormstrikeOH || spell == shaman.LavaLash || spell == shaman.LavaBurst) { - return - } - - dot := burnSpell.Dot(result.Target) - dotDamage := result.Damage * 0.3 - if dot.IsActive() { - dotDamage += dot.SnapshotBaseDamage * float64(dot.MaxTicksRemaining()) - } - dot.SnapshotBaseDamage = dotDamage / float64(dot.NumberOfTicks) - dot.SnapshotAttackerMultiplier = 1 - - burnSpell.Cast(sim, result.Target) - }, - })) - }, - }, -}) - -var ItemSetGiftOfTheGatheringStorm = core.NewItemSet(core.ItemSet{ - Name: "Gift of the Gathering Storm", - Bonuses: map[int32]core.ApplyEffect{ - // Your Lava Burst deals increased damage equal to its critical strike chance. - 3: func(agent core.Agent) { - shaman := agent.(ShamanAgent).GetShaman() - shaman.RegisterAura(core.Aura{ - Label: "S03 - Item - RAQ - Shaman - Elemental 3P Bonus", - OnInit: func(aura *core.Aura, sim *core.Simulation) { - shaman.useLavaBurstCritScaling = true - }, - }) - }, - }, -}) diff --git a/sim/shaman/item_sets_pve_phase_4.go b/sim/shaman/item_sets_pve_phase_4.go new file mode 100644 index 0000000000..dfec53ae82 --- /dev/null +++ b/sim/shaman/item_sets_pve_phase_4.go @@ -0,0 +1,307 @@ +package shaman + +import ( + "fmt" + "time" + + "github.com/wowsims/sod/sim/core" + "github.com/wowsims/sod/sim/core/stats" +) + +var ItemSetTheFiveThunders = core.NewItemSet(core.ItemSet{ + Name: "The Five Thunders", + Bonuses: map[int32]core.ApplyEffect{ + // +40 Attack Power, up to 23 increased damage from spells, and up to 44 increased healing from spells. + 2: func(agent core.Agent) { + c := agent.GetCharacter() + c.AddStats(stats.Stats{ + stats.AttackPower: 40, + stats.RangedAttackPower: 40, + stats.SpellDamage: 23, + stats.HealingPower: 44, + }) + }, + // 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. + 4: func(agent core.Agent) { + c := agent.GetCharacter() + + procAura := c.NewTemporaryStatsAura("The Furious Storm", core.ActionID{SpellID: 27775}, 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{ + 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{ + Name: "Item - The Furious Storm Proc (Spell Cast)", + Callback: core.CallbackOnCastComplete, + ProcMask: core.ProcMaskSpellDamage | core.ProcMaskSpellHealing, + ProcChance: 0.04, + Handler: handler, + }) + }, + // +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 ItemSetEarthfuryEruption = core.NewItemSet(core.ItemSet{ + Name: "Earthfury Eruption", + Bonuses: map[int32]core.ApplyEffect{ + // The radius of your totems that affect friendly targets is increased to 40 yd. + 2: func(agent core.Agent) { + // Nothing to do + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Elemental4PBonus() + }, + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Elemental6PBonus() + }, + }, +}) + +// Your Lightning Bolt critical strikes have a 35% chance to reset the cooldown on Lava Burst and Chain Lightning and make the next Lava Burst, Chain Heal, or Chain Lightning within 10 sec instant. +func (shaman *Shaman) applyT1Elemental4PBonus() { + label := "S03 - Item - T1 - Shaman - Elemental 4P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.SpellCode == SpellCode_ShamanLightningBolt && spell.ProcMask.Matches(core.ProcMaskSpellDamage) && result.DidCrit() && sim.Proc(.35, "Power Surge") { + shaman.PowerSurgeDamageAura.Activate(sim) + } + }, + })) +} + +// Lava Burst now also refreshes the duration of Flame Shock on your target back to 12 sec. +func (shaman *Shaman) applyT1Elemental6PBonus() { + label := "S03 - Item - T1 - Shaman - Elemental 6P Bonus" + if shaman.HasAura(label) { + return + } + + var flameShockSpells []*core.Spell + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + flameShockSpells = core.FilterSlice(shaman.FlameShock, func(spell *core.Spell) bool { return spell != nil }) + }, + OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { + if spell.SpellCode != SpellCode_ShamanLavaBurst { + return + } + + for _, spell := range flameShockSpells { + if dot := spell.Dot(shaman.CurrentTarget); dot.IsActive() { + dot.NumberOfTicks = dot.OriginalNumberOfTicks + dot.Rollover(sim) + } + } + }, + })) +} + +var ItemSetEarthfuryRelief = core.NewItemSet(core.ItemSet{ + Name: "Earthfury Relief", + Bonuses: map[int32]core.ApplyEffect{ + // The radius of your totems that affect friendly targets is increased to 40 yd. + 2: func(agent core.Agent) { + // Nothing to do + }, + // After casting your Healing Wave, Lesser Healing Wave, or Riptide spell, gives you a 25% chance to gain Mana equal to 35% of the base cost of the spell. + 4: func(agent core.Agent) { + // Not implementing for now + }, + // Your Healing Wave will now jump to additional nearby targets. Each jump reduces the effectiveness of the heal by 80%, and the spell will jump to up to 2 additional targets. + 6: func(agent core.Agent) { + // Not implementing for now + }, + }, +}) + +var ItemSetEarthfuryImpact = core.NewItemSet(core.ItemSet{ + Name: "Earthfury Impact", + Bonuses: map[int32]core.ApplyEffect{ + // The radius of your totems that affect friendly targets is increased to 40 yd. + 2: func(agent core.Agent) { + // Nothing to do + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Enhancement4PBonus() + }, + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Enhancement6PBonus() + }, + }, +}) + +// Increases your critical strike chance with spells and attacks by 2%. +func (shaman *Shaman) applyT1Enhancement4PBonus() { + label := "S03 - Item - T1 - Shaman - Enhancement 4P Bonus" + if shaman.HasAura(label) { + return + } + + bonusStats := stats.Stats{ + stats.MeleeCrit: 2 * core.CritRatingPerCritChance, + stats.SpellCrit: 2 * core.CritRatingPerCritChance, + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + BuildPhase: core.CharacterBuildPhaseBuffs, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized { + aura.Unit.AddStats(bonusStats) + } else { + aura.Unit.AddStatsDynamic(sim, bonusStats) + } + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized { + aura.Unit.AddStats(bonusStats.Invert()) + } else { + aura.Unit.AddStatsDynamic(sim, bonusStats.Invert()) + } + }, + })) +} + +// Your Flurry talent grants an additional 10% increase to your attack speed. +func (shaman *Shaman) applyT1Enhancement6PBonus() { + label := "S03 - Item - T1 - Shaman - Enhancement 6P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + shaman.bonusFlurrySpeed += .10 + }, + }) +} + +var ItemSetEarthfuryResolve = core.NewItemSet(core.ItemSet{ + Name: "Earthfury Resolve", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Tank2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Tank4PBonus() + }, + + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT1Tank6PBonus() + }, + }, +}) + +// Increases your attack speed by 30% for your next 3 swings after you parry, dodge, or block. +func (shaman *Shaman) applyT1Tank2PBonus() { + label := "S03 - Item - T1 - Shaman - Tank 2P Bonus" + if shaman.HasAura(label) { + return + } + + flurryAura := shaman.makeFlurryAura(5) + // The consumption trigger may not exist if the Shaman doesn't talent into Flurry + shaman.makeFlurryConsumptionTrigger(flurryAura) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if result.DidParry() || result.DidDodge() || result.DidBlock() { + flurryAura.Activate(sim) + flurryAura.SetStacks(sim, 3) + } + }, + })) +} + +// Your parries and dodges also activate your Shield Mastery rune ability. +func (shaman *Shaman) applyT1Tank4PBonus() { + label := "S03 - Item - T1 - Shaman - Tank 4P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if result.DidParry() || result.DidDodge() { + fmt.Println("good") + shaman.ShieldMasteryAura.Activate(sim) + shaman.ShieldMasteryAura.AddStack(sim) + } + }, + })) +} + +// Your Stoneskin Totem also reduces Physical damage taken by 5% and your Windwall Totem also reduces Magical damage taken by 5%. +func (shaman *Shaman) applyT1Tank6PBonus() { + label := "S03 - Item - T1 - Shaman - Tank 6P Bonus" + if shaman.HasAura(label) { + return + } + + improvedStoneskinAura := core.ImprovedStoneskinTotemAura(&shaman.Unit) + improvedWindwallAura := core.ImprovedWindwallTotemAura(&shaman.Unit) + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + for _, spell := range shaman.StoneskinTotem { + if spell == nil { + continue + } + + oldApplyEffects := spell.ApplyEffects + spell.ApplyEffects = func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + oldApplyEffects(sim, target, spell) + improvedStoneskinAura.Activate(sim) + } + } + + for _, spell := range shaman.WindwallTotem { + if spell == nil { + continue + } + + oldApplyEffects := spell.ApplyEffects + spell.ApplyEffects = func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + oldApplyEffects(sim, target, spell) + improvedWindwallAura.Activate(sim) + } + } + }, + }) +} diff --git a/sim/shaman/item_sets_pve_phase_5.go b/sim/shaman/item_sets_pve_phase_5.go new file mode 100644 index 0000000000..20512204f4 --- /dev/null +++ b/sim/shaman/item_sets_pve_phase_5.go @@ -0,0 +1,486 @@ +package shaman + +import ( + "slices" + "time" + + "github.com/wowsims/sod/sim/core" + "github.com/wowsims/sod/sim/core/proto" + "github.com/wowsims/sod/sim/core/stats" +) + +/////////////////////////////////////////////////////////////////////////// +// SoD Phase 5 Item Sets +/////////////////////////////////////////////////////////////////////////// + +var ItemSetEruptionOfTheTenStorms = core.NewItemSet(core.ItemSet{ + Name: "Eruption of the Ten Storms", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Elemental2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Elemental4PBonus() + }, + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Elemental6PBonus() + }, + }, +}) + +// Your spell critical strikes now have a 100% chance trigger your Elemental Focus talent. +func (shaman *Shaman) applyT2Elemental2PBonus() { + if !shaman.Talents.ElementalFocus { + return + } + + label := "S03 - Item - T2 - Shaman - Elemental 2P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if shaman.isShamanDamagingSpell(spell) && result.DidCrit() { + shaman.ClearcastingAura.Activate(sim) + shaman.ClearcastingAura.SetStacks(sim, shaman.ClearcastingAura.MaxStacks) + } + }, + })) +} + +// Loyal Beta from your Spirit of the Alpha ability now also increases Fire, Frost, and Nature damage by 5%. +func (shaman *Shaman) applyT2Elemental4PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneFeetSpiritOfTheAlpha) || shaman.IsTanking() { + return + } + + label := "S03 - Item - T2 - Shaman - Elemental 4P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + oldOnGain := shaman.LoyalBetaAura.OnGain + shaman.LoyalBetaAura.OnGain = func(aura *core.Aura, sim *core.Simulation) { + oldOnGain(aura, sim) + shaman.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFrost] *= 1.05 + shaman.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFire] *= 1.05 + shaman.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexNature] *= 1.05 + } + }, + })) +} + +// While Clearcasting is active, you deal 15% more non-Physical damage. +func (shaman *Shaman) applyT2Elemental6PBonus() { + if !shaman.Talents.ElementalFocus { + return + } + + label := "S03 - Item - T2 - Shaman - Elemental 6P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + oldOnGain := shaman.ClearcastingAura.OnGain + shaman.ClearcastingAura.OnGain = func(aura *core.Aura, sim *core.Simulation) { + oldOnGain(aura, sim) + shaman.PseudoStats.SchoolDamageDealtMultiplier.MultiplyMagicSchools(1.15) + } + + oldOnExpire := shaman.ClearcastingAura.OnExpire + shaman.ClearcastingAura.OnExpire = func(aura *core.Aura, sim *core.Simulation) { + oldOnExpire(aura, sim) + shaman.PseudoStats.SchoolDamageDealtMultiplier.MultiplyMagicSchools(1 / 1.15) + } + }, + })) +} + +var ItemSetResolveOfTheTenStorms = core.NewItemSet(core.ItemSet{ + Name: "Resolve of the Ten Storms", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Tank2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Tank4PBonus() + }, + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Tank6PBonus() + }, + }, +}) + +// Your Flame Shock also grants 30% increased chance to Block for 5 sec or until you Block an attack. +func (shaman *Shaman) applyT2Tank2PBonus() { + label := "S03 - Item - T2 - Shaman - Tank 2P Bonus" + if shaman.HasAura(label) { + return + } + + shieldBlockAura := shaman.RegisterAura(core.Aura{ + ActionID: core.ActionID{SpellID: 467891}, + Label: "Shield Block", + Duration: time.Second * 5, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + shaman.AddStatDynamic(sim, stats.Block, 30*core.BlockRatingPerBlockChance) + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + shaman.AddStatDynamic(sim, stats.Block, -30*core.BlockRatingPerBlockChance) + }, + OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, _ *core.Spell, result *core.SpellResult) { + if result.DidBlock() { + aura.Deactivate(sim) + } + }, + }) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.SpellCode == SpellCode_ShamanFlameShock { + shieldBlockAura.Activate(sim) + } + }, + })) +} + +// Each time you Block, your Block amount is increased by 10% of your Spell Damage for 6 sec, stacking up to 3 times. +func (shaman *Shaman) applyT2Tank4PBonus() { + label := "S03 - Item - T2 - Shaman - Tank 4P Bonus" + if shaman.HasAura(label) { + return + } + + statDeps := []*stats.StatDependency{ + nil, + shaman.NewDynamicMultiplyStat(stats.BlockValue, 1.10), + shaman.NewDynamicMultiplyStat(stats.BlockValue, 1.20), + shaman.NewDynamicMultiplyStat(stats.BlockValue, 1.30), + } + + // Couldn't find a separate spell for this + blockAura := shaman.RegisterAura(core.Aura{ + ActionID: core.ActionID{SpellID: 467909}, + Label: "S03 - Item - T2 - Shaman - Tank 4P Bonus Proc", + Duration: time.Second * 6, + MaxStacks: 3, + OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) { + if oldStacks != 0 { + shaman.DisableDynamicStatDep(sim, statDeps[oldStacks]) + } + if newStacks != 0 { + shaman.EnableDynamicStatDep(sim, statDeps[newStacks]) + } + }, + }) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if result.DidBlock() { + blockAura.Activate(sim) + blockAura.AddStack(sim) + } + }, + })) +} + +// Each time you Block an attack, you have a 50% chance to trigger your Maelstrom Weapon rune. +func (shaman *Shaman) applyT2Tank6PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneWaistMaelstromWeapon) { + return + } + + label := "S03 - Item - T2 - Shaman - Tank 6P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if result.DidBlock() && sim.Proc(0.50, "T2 6P Proc Maelstrom Weapon") { + shaman.MaelstromWeaponAura.Activate(sim) + shaman.MaelstromWeaponAura.AddStack(sim) + } + }, + })) +} + +var ItemSetImpactOfTheTenStorms = core.NewItemSet(core.ItemSet{ + Name: "Impact of the Ten Storms", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Enhancement2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Enhancement4PBonus() + }, + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Enhancement6PBonus() + }, + }, +}) + +// Your chance to trigger Static Shock is increased by 12% (6% while dual-wielding) +func (shaman *Shaman) applyT2Enhancement2PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneBracersStaticShock) { + return + } + + label := "S03 - Item - T2 - Shaman - Enhancement 2P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + shaman.staticSHocksProcChance += 0.06 + }, + })) +} + +// Main-hand Stormstrike now deals 50% more damage. +func (shaman *Shaman) applyT2Enhancement4PBonus() { + if !shaman.Talents.Stormstrike { + return + } + + label := "S03 - Item - T2 - Shaman - Enhancement 4P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + shaman.StormstrikeMH.DamageMultiplier += 0.50 + }, + }) +} + +// While Static Shock is engraved, your Lightning Shield now gains a charge each time you hit a target with Lightning Bolt or Chain Lightning, up to a maximum of 9 charges. +// In addition, while Static Shock is engraved, your Lightning Shield can now deal critical damage. +func (shaman *Shaman) applyT2Enhancement6PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneBracersStaticShock) { + return + } + + label := "S03 - Item - T2 - Shaman - Enhancement 6P Bonus" + if shaman.HasAura(label) { + return + } + + affectedSpellCodes := []int32{SpellCode_ShamanLightningBolt, SpellCode_ShamanChainLightning} + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(t26pAura *core.Aura, sim *core.Simulation) { + for _, aura := range shaman.LightningShieldAuras { + if aura == nil { + continue + } + + oldOnGain := aura.OnGain + aura.OnGain = func(aura *core.Aura, sim *core.Simulation) { + oldOnGain(aura, sim) + t26pAura.Activate(sim) + } + + oldOnExpire := aura.OnExpire + aura.OnExpire = func(aura *core.Aura, sim *core.Simulation) { + oldOnExpire(aura, sim) + t26pAura.Deactivate(sim) + } + } + + shaman.lightningShieldCanCrit = true + }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + // Tested and it doesn't proc from overloads + if slices.Contains(affectedSpellCodes, spell.SpellCode) && spell.ActionID.Tag != CastTagOverload && result.Landed() { + shaman.ActiveShieldAura.AddStack(sim) + } + }, + })) +} + +var ItemSetReliefOfTheTenStorms = core.NewItemSet(core.ItemSet{ + Name: "Relief of the Ten Storms", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Restoration2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Restoration4PBonus() + }, + 6: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyT2Restoration6PBonus() + }, + }, +}) + +// Your damaging and healing critical strikes now have a 100% chance to trigger your Water Shield, but do not consume a charge or trigger its cooldown. +func (shaman *Shaman) applyT2Restoration2PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneHandsWaterShield) { + return + } + + label := "S03 - Item - T2 - Shaman - Restoration 2P Bonus" + if shaman.HasAura(label) { + return + } + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.ProcMask.Matches(core.ProcMaskSpellDamage) && result.DidCrit() { + shaman.WaterShieldRestore.Cast(sim, aura.Unit) + } + }, + })) +} + +// Your Chain Lightning now also heals the target of your Earth Shield for 100% of the damage done. +func (shaman *Shaman) applyT2Restoration4PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneHandsWaterShield) { + return + } + + label := "S03 - Item - T2 - Shaman - Restoration 4P Bonus" + if shaman.HasAura(label) { + return + } + + healthMetrics := shaman.NewHealthMetrics(core.ActionID{SpellID: 467809}) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.SpellCode == SpellCode_ShamanChainLightning { + shaman.GainHealth(sim, result.Damage, healthMetrics) + } + }, + })) +} + +// Increases the healing of Chain Heal and the damage of Chain Lightning by 20%. +func (shaman *Shaman) applyT2Restoration6PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneHandsWaterShield) { + return + } + + label := "S03 - Item - T2 - Shaman - Restoration 6P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + spells := core.FilterSlice( + core.Flatten([][]*core.Spell{ + shaman.ChainHeal, + shaman.ChainHealOverload, + shaman.ChainLightning, + shaman.ChainLightningOverload, + }), func(spell *core.Spell) bool { return spell != nil }, + ) + + for _, spell := range spells { + spell.DamageMultiplierAdditive += 0.20 + } + }, + }) +} + +var ItemSetAugursRegalia = core.NewItemSet(core.ItemSet{ + Name: "Augur's Regalia", + Bonuses: map[int32]core.ApplyEffect{ + // Increased Defense +7. + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + // No corresponding Soul found so leaving this simple + shaman.AddStat(stats.Defense, 7) + }, + + 3: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyZGTank3PBonus() + }, + + 5: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyZGTank5PBonus() + }, + }, +}) + +// Increases your chance to block attacks with a shield by 10%. +func (shaman *Shaman) applyZGTank3PBonus() { + label := "S03 - Item - ZG - Shaman - Tank 3P Bonus" + if shaman.HasAura(label) { + return + } + + bonusStats := stats.Stats{stats.Block: 10 * core.BlockRatingPerBlockChance} + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + BuildPhase: core.CharacterBuildPhaseBuffs, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized { + aura.Unit.AddStats(bonusStats) + } else { + aura.Unit.AddStatsDynamic(sim, bonusStats) + } + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized { + aura.Unit.AddStats(bonusStats.Invert()) + } else { + aura.Unit.AddStatsDynamic(sim, bonusStats.Invert()) + } + }, + })) +} + +// Increases the chance to trigger your Power Surge rune by an additional 5%. +func (shaman *Shaman) applyZGTank5PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneWaistPowerSurge) { + return + } + + label := "S03 - Item - ZG - Shaman - Tank 5P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + shaman.powerSurgeProcChance += .05 + }, + }) +} diff --git a/sim/shaman/item_sets_pve_phase_6.go b/sim/shaman/item_sets_pve_phase_6.go new file mode 100644 index 0000000000..2cd7a983a9 --- /dev/null +++ b/sim/shaman/item_sets_pve_phase_6.go @@ -0,0 +1,311 @@ +package shaman + +import ( + "slices" + "time" + + "github.com/wowsims/sod/sim/core" + "github.com/wowsims/sod/sim/core/proto" + "github.com/wowsims/sod/sim/core/stats" +) + +/////////////////////////////////////////////////////////////////////////// +// SoD Phase 6 Item Sets +/////////////////////////////////////////////////////////////////////////// + +var ItemSetStormcallersEruption = core.NewItemSet(core.ItemSet{ + Name: "Stormcaller's Eruption", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyTAQElemental2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyTAQElemental4PBonus() + }, + }, +}) + +// You have a 70% chance to avoid interruption caused by damage while casting Lightning Bolt, Chain Lightning, or Lava Burst, and a 10% increased chance to trigger your Elemental Focus talent. +func (shaman *Shaman) applyTAQElemental2PBonus() { + label := "S03 - Item - TAQ - Shaman - Elemental 2P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + affectedPushbackSpells := core.FilterSlice( + core.Flatten( + [][]*core.Spell{ + shaman.LightningBolt, + shaman.ChainLightning, + {shaman.LavaBurst}, + }, + ), + func(spell *core.Spell) bool { return spell != nil }, + ) + + for _, spell := range affectedPushbackSpells { + spell.PushbackReduction += .70 + } + + if shaman.Talents.ElementalFocus { + shaman.elementalFocusProcChance += .10 + } + }, + }) +} + +// Increases the critical strike damage bonus of your Fire, Frost, and Nature spells by 60%. +func (shaman *Shaman) applyTAQElemental4PBonus() { + label := "S03 - Item - TAQ - Shaman - Elemental 4P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + for _, spell := range shaman.Spellbook { + if spell.Flags.Matches(SpellFlagShaman) && spell.DefenseType == core.DefenseTypeMagic { + spell.CritDamageBonus += 0.60 + } + } + }, + }) +} + +var ItemSetStormcallersResolve = core.NewItemSet(core.ItemSet{ + Name: "Stormcaller's Resolve", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyTAQTank2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyTAQTank4PBonus() + }, + }, +}) + +// Damaging a target with Stormstrike, Lava Burst, or Molten Blast also reduces all damage you take by 10% for 10 sec. +func (shaman *Shaman) applyTAQTank2PBonus() { + if !shaman.Talents.Stormstrike && !shaman.HasRune(proto.ShamanRune_RuneHandsLavaBurst) && !shaman.HasRune(proto.ShamanRune_RuneHandsMoltenBlast) { + return + } + + label := "S03 - Item - TAQ - Shaman - Tank 2P Bonus" + if shaman.HasAura(label) { + return + } + + affectedSpellCodess := []int32{SpellCode_ShamanStormstrike, SpellCode_ShamanLavaBurst, SpellCode_ShamanMoltenBlast} + + buffAura := shaman.RegisterAura(core.Aura{ + ActionID: core.ActionID{SpellID: 1213934}, + Label: "Stormbraced", + Duration: time.Second * 10, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.PseudoStats.DamageTakenMultiplier *= 0.90 + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.PseudoStats.DamageTakenMultiplier /= 0.90 + }, + }) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if result.Landed() && slices.Contains(affectedSpellCodess, spell.SpellCode) { + buffAura.Activate(sim) + } + }, + })) +} + +// Your Spirit of the Alpha also increases your health by 10%, threat by 20%, and damage by 10% when cast on self. +func (shaman *Shaman) applyTAQTank4PBonus() { + if !shaman.HasRune(proto.ShamanRune_RuneFeetSpiritOfTheAlpha) || !shaman.IsTanking() { + return + } + + label := "S03 - Item - TAQ - Shaman - Tank 4P Bonus" + if shaman.HasAura(label) { + return + } + + damageMultiplier := 1.10 + threatMultiplier := 1.20 + healthMultiplier := 1.10 + statDep := shaman.NewDynamicMultiplyStat(stats.Health, healthMultiplier) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + BuildPhase: core.CharacterBuildPhaseBuffs, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized { + aura.Unit.MultiplyStat(stats.Health, healthMultiplier) + } else { + aura.Unit.EnableDynamicStatDep(sim, statDep) + } + + shaman.PseudoStats.DamageDealtMultiplier *= damageMultiplier + shaman.PseudoStats.ThreatMultiplier *= threatMultiplier + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized { + aura.Unit.MultiplyStat(stats.Health, 1/healthMultiplier) + } else { + aura.Unit.DisableDynamicStatDep(sim, statDep) + } + + shaman.PseudoStats.DamageDealtMultiplier /= damageMultiplier + shaman.PseudoStats.ThreatMultiplier /= threatMultiplier + }, + })) +} + +var ItemSetStormcallersRelief = core.NewItemSet(core.ItemSet{ + Name: "Stormcaller's Relief", + Bonuses: map[int32]core.ApplyEffect{ + // Your Riptide increases the amount healed by Chain Heal by an additional 25%. + 2: func(agent core.Agent) { + }, + // Reduces the cast time of Chain Heal by 0.5 sec. + 4: func(agent core.Agent) { + }, + }, +}) + +var ItemSetStormcallersImpact = core.NewItemSet(core.ItemSet{ + Name: "Stormcaller's Impact", + Bonuses: map[int32]core.ApplyEffect{ + 2: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyTAQEnhancement2PBonus() + }, + 4: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyTAQEnhancement4PBonus() + }, + }, +}) + +// Increases Stormstrike and Lava Lash damage by 50%. Stormstrike's damage is increased by an additional 50% when using a Two-handed weapon. +func (shaman *Shaman) applyTAQEnhancement2PBonus() { + if !shaman.Talents.Stormstrike && !shaman.HasRune(proto.ShamanRune_RuneHandsLavaLash) { + return + } + + label := "S03 - Item - TAQ - Shaman - Enhancement 2P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + if shaman.StormstrikeMH != nil { + shaman.StormstrikeMH.DamageMultiplierAdditive += core.TernaryFloat64(shaman.HasRune(proto.ShamanRune_RuneChestTwoHandedMastery), 1.00, 0.50) + } + + if shaman.StormstrikeOH != nil { + shaman.StormstrikeOH.DamageMultiplierAdditive += 0.50 + } + + if shaman.LavaLash != nil { + shaman.LavaLash.DamageMultiplierAdditive += 0.50 + } + }, + }) +} + +// Your Stormstrike, Lava Lash, and Lava Burst critical strikes cause your target to burn for 30% of the damage done over 4 sec. +func (shaman *Shaman) applyTAQEnhancement4PBonus() { + if !shaman.Talents.Stormstrike && !shaman.HasRune(proto.ShamanRune_RuneHandsLavaLash) && !shaman.HasRune(proto.ShamanRune_RuneHandsLavaBurst) { + return + } + + label := "S03 - Item - TAQ - Shaman - Enhancement 4P Bonus" + if shaman.HasAura(label) { + return + } + + // This is the spell used for the burn proc. + // https://www.wowhead.com/classic/spell=1213915/burning + burnSpell := shaman.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 1213915}, + SpellSchool: core.SpellSchoolFire, + DefenseType: core.DefenseTypeMagic, + ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell, + + DamageMultiplier: 1, + ThreatMultiplier: 1, + BonusCoefficient: 1, + + Dot: core.DotConfig{ + Aura: core.Aura{ + Label: "Burning", + }, + NumberOfTicks: 2, + TickLength: time.Second * 2, + OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { + dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeTick) + }, + }, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + spell.Dot(target).ApplyOrRefresh(sim) + spell.CalcAndDealOutcome(sim, target, spell.OutcomeAlwaysHitNoHitCounter) + }, + }) + + core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if !result.Outcome.Matches(core.OutcomeCrit) || !(spell == shaman.StormstrikeMH || spell == shaman.StormstrikeOH || spell == shaman.LavaLash || spell == shaman.LavaBurst) { + return + } + + dot := burnSpell.Dot(result.Target) + dotDamage := result.Damage * 0.3 + if dot.IsActive() { + dotDamage += dot.SnapshotBaseDamage * float64(dot.MaxTicksRemaining()) + } + dot.SnapshotBaseDamage = dotDamage / float64(dot.NumberOfTicks) + dot.SnapshotAttackerMultiplier = 1 + + burnSpell.Cast(sim, result.Target) + }, + })) +} + +var ItemSetGiftOfTheGatheringStorm = core.NewItemSet(core.ItemSet{ + Name: "Gift of the Gathering Storm", + Bonuses: map[int32]core.ApplyEffect{ + 3: func(agent core.Agent) { + shaman := agent.(ShamanAgent).GetShaman() + shaman.applyRAQElemental3PBonus() + }, + }, +}) + +// Your Lava Burst deals increased damage equal to its critical strike chance. +func (shaman *Shaman) applyRAQElemental3PBonus() { + label := "S03 - Item - RAQ - Shaman - Elemental 3P Bonus" + if shaman.HasAura(label) { + return + } + + shaman.RegisterAura(core.Aura{ + Label: label, + OnInit: func(aura *core.Aura, sim *core.Simulation) { + shaman.useLavaBurstCritScaling = true + }, + }) +} diff --git a/sim/shaman/runes.go b/sim/shaman/runes.go index f21f86b8d4..2c1ec97550 100644 --- a/sim/shaman/runes.go +++ b/sim/shaman/runes.go @@ -14,6 +14,9 @@ func (shaman *Shaman) ApplyRunes() { shaman.applyBurn() shaman.applyMentalDexterity() + // Shoulder + shaman.applyShoulderRuneEffect() + // Cloak shaman.registerFeralSpiritCD() @@ -48,6 +51,78 @@ func (shaman *Shaman) ApplyRunes() { shaman.applySpiritOfTheAlpha() } +func (shaman *Shaman) applyShoulderRuneEffect() { + if shaman.Equipment.Shoulders().Rune == int32(proto.ShamanRune_RuneNone) { + return + } + + switch shaman.Equipment.Shoulders().Rune { + // Elemental + case int32(proto.ShamanRune_RuneShouldersVolcano): + shaman.applyT1Elemental4PBonus() + case int32(proto.ShamanRune_RuneShouldersRagingFlame): + shaman.applyT1Elemental6PBonus() + case int32(proto.ShamanRune_RuneShouldersElementalMaster): + shaman.applyT2Elemental2PBonus() + case int32(proto.ShamanRune_RuneShouldersTribesman): + shaman.applyT2Elemental4PBonus() + case int32(proto.ShamanRune_RuneShouldersSpiritGuide): + shaman.applyT2Elemental6PBonus() + case int32(proto.ShamanRune_RuneShouldersElder): + shaman.applyTAQElemental2PBonus() + case int32(proto.ShamanRune_RuneShouldersElements): + shaman.applyTAQElemental4PBonus() + case int32(proto.ShamanRune_RuneShouldersLavaSage): + shaman.applyRAQElemental3PBonus() + + // Enhancement + case int32(proto.ShamanRune_RuneShouldersRefined): + shaman.applyT1Enhancement4PBonus() + case int32(proto.ShamanRune_RuneShouldersChieftain): + shaman.applyT1Enhancement6PBonus() + case int32(proto.ShamanRune_RuneShouldersFurycharged): + shaman.applyT2Enhancement2PBonus() + case int32(proto.ShamanRune_RuneShouldersStormbreaker): + shaman.applyT2Enhancement4PBonus() + case int32(proto.ShamanRune_RuneShouldersTempest): + shaman.applyT2Enhancement6PBonus() + case int32(proto.ShamanRune_RuneShouldersSeismicSmasher): + shaman.applyTAQEnhancement2PBonus() + case int32(proto.ShamanRune_RuneShouldersFlamebringer): + shaman.applyTAQEnhancement4PBonus() + + // Restoration + case int32(proto.ShamanRune_RuneShouldersWaterWalker): + shaman.applyT2Restoration2PBonus() + case int32(proto.ShamanRune_RuneShouldersStormtender): + shaman.applyT2Restoration4PBonus() + case int32(proto.ShamanRune_RuneShouldersElementalSeer): + shaman.applyT2Restoration6PBonus() + + // Tank + case int32(proto.ShamanRune_RuneShouldersWindwalker): + shaman.applyT1Tank2PBonus() + case int32(proto.ShamanRune_RuneShouldersShieldMaster): + shaman.applyT1Tank4PBonus() + case int32(proto.ShamanRune_RuneShouldersTotemicProtector): + shaman.applyT1Tank6PBonus() + case int32(proto.ShamanRune_RuneShouldersShockAbsorber): + shaman.applyT2Tank2PBonus() + case int32(proto.ShamanRune_RuneShouldersSpiritualBulwark): + shaman.applyT2Tank4PBonus() + case int32(proto.ShamanRune_RuneShouldersMaelstrombringer): + shaman.applyT2Tank6PBonus() + case int32(proto.ShamanRune_RuneShouldersAncestralWarden): + shaman.applyZGTank3PBonus() + case int32(proto.ShamanRune_RuneShouldersCorrupt): + shaman.applyZGTank5PBonus() + case int32(proto.ShamanRune_RuneShouldersLavaWalker): + shaman.applyTAQTank2PBonus() + case int32(proto.ShamanRune_RuneShouldersTrueAlpha): + shaman.applyTAQTank4PBonus() + } +} + var BurnFlameShockTargetCount = int32(5) var BurnFlameShockDamageBonus = 1.0 var BurnFlameShockBonusTicks = int32(2) @@ -159,8 +234,6 @@ func (shaman *Shaman) applyShieldMastery() { defendersResolveAura := core.DefendersResolveSpellDamage(shaman.GetCharacter(), 4) - has4PEarthfuryResolve := shaman.HasSetBonus(ItemSetEarthfuryResolve, 4) - shaman.AddStat(stats.Block, 10) shaman.PseudoStats.BlockValueMultiplier = 1.15 @@ -169,11 +242,14 @@ func (shaman *Shaman) applyShieldMastery() { procManaReturn := 0.08 armorPerStack := shaman.Equipment.OffHand().Stats[stats.Armor] * 0.3 - blockProcAura := shaman.RegisterAura(core.Aura{ + shaman.ShieldMasteryAura = shaman.RegisterAura(core.Aura{ Label: "Shield Mastery Block", ActionID: core.ActionID{SpellID: 408525}, Duration: time.Second * 15, MaxStacks: 5, + OnRefresh: func(aura *core.Aura, sim *core.Simulation) { + shaman.AddMana(sim, shaman.MaxMana()*procManaReturn, manaMetrics) + }, OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) { shaman.AddStatDynamic(sim, stats.Armor, armorPerStack*float64(newStacks-oldStacks)) }, @@ -183,10 +259,9 @@ func (shaman *Shaman) applyShieldMastery() { core.MakePermanent(shaman.RegisterAura(core.Aura{ Label: "Shield Mastery Trigger", OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if result.DidBlock() || (has4PEarthfuryResolve && (result.DidParry() || result.DidDodge())) { - shaman.AddMana(sim, shaman.MaxMana()*procManaReturn, manaMetrics) - blockProcAura.Activate(sim) - blockProcAura.AddStack(sim) + if result.DidBlock() { + shaman.ShieldMasteryAura.Activate(sim) + shaman.ShieldMasteryAura.AddStack(sim) } }, OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { diff --git a/sim/shaman/shaman.go b/sim/shaman/shaman.go index ae37c9d470..b23a4fda97 100644 --- a/sim/shaman/shaman.go +++ b/sim/shaman/shaman.go @@ -150,6 +150,7 @@ type Shaman struct { MaelstromWeaponAura *core.Aura PowerSurgeDamageAura *core.Aura PowerSurgeHealAura *core.Aura + ShieldMasteryAura *core.Aura SpiritOfTheAlphaAura *core.Aura WaterShieldAura *core.Aura diff --git a/sim/shaman/talents.go b/sim/shaman/talents.go index d59471edd7..e681976aed 100644 --- a/sim/shaman/talents.go +++ b/sim/shaman/talents.go @@ -401,9 +401,14 @@ func (shaman *Shaman) makeFlurryAura(points int32) *core.Aura { spellID := []int32{16257, 16277, 16278, 16279, 16280}[points-1] attackSpeed := []float64{1.1, 1.15, 1.2, 1.25, 1.3}[points-1] + label := fmt.Sprintf("Flurry Proc (%d)", spellID) - aura := shaman.GetOrRegisterAura(core.Aura{ - Label: fmt.Sprintf("Flurry Proc (%d)", spellID), + if aura := shaman.GetAura(label); aura != nil { + return aura + } + + aura := shaman.RegisterAura(core.Aura{ + Label: label, ActionID: core.ActionID{SpellID: spellID}, Duration: core.NeverExpires, MaxStacks: 3, @@ -425,12 +430,18 @@ func (shaman *Shaman) makeFlurryAura(points int32) *core.Aura { // With the Warden T1 2pc it's possible to have 2 different Flurry auras if using less than 5/5 points in Flurry. // The two different buffs don't stack whatsoever. Instead the stronger aura takes precedence and each one is only refreshed by the corresponding triggers. func (shaman *Shaman) makeFlurryConsumptionTrigger(flurryAura *core.Aura) *core.Aura { + label := fmt.Sprintf("Flurry Consume Trigger - %d", flurryAura.ActionID.SpellID) + if aura := shaman.GetAura(label); aura != nil { + return aura + } + icd := core.Cooldown{ Timer: shaman.NewTimer(), Duration: time.Millisecond * 500, } - return core.MakePermanent(shaman.GetOrRegisterAura(core.Aura{ - Label: fmt.Sprintf("Flurry Consume Trigger - %d", flurryAura.ActionID.SpellID), + + return core.MakePermanent(shaman.RegisterAura(core.Aura{ + Label: label, OnSpellHitDealt: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { // Remove a stack. if flurryAura.IsActive() && spell.ProcMask.Matches(core.ProcMaskMeleeWhiteHit) && icd.IsReady(sim) { diff --git a/tools/database/database.go b/tools/database/database.go index b7a918110b..1abe0191ac 100644 --- a/tools/database/database.go +++ b/tools/database/database.go @@ -191,11 +191,28 @@ func (db *WowDatabase) AddRune(id int32, tooltip WowheadItemResponse) { Id: id, Name: tooltip.GetName(), Icon: tooltip.GetIcon(), - ClassAllowlist: []proto.Class{tooltip.GetRequiredClass()}, + ClassAllowlist: tooltip.GetRequiredClasses(), Type: tooltip.GetRequiredItemSlot(), } } +func (db *WowDatabase) AddShoulderRune(id int32, tooltip WowheadItemResponse) { + if tooltip.GetName() == "" || tooltip.GetIcon() == "" { + return + } + if runeOverrideNames[tooltip.GetName()] != nil { + return + } + + db.Runes[id] = &proto.UIRune{ + Id: id, + Name: tooltip.GetName(), + Icon: tooltip.GetIcon(), + ClassAllowlist: tooltip.GetRequiredClasses(), + Type: proto.ItemType_ItemTypeShoulder, + } +} + func (db *WowDatabase) AddItemIcon(id int32, tooltips map[int32]WowheadItemResponse) { if tooltip, ok := tooltips[id]; ok { if tooltip.GetName() == "" || tooltip.GetIcon() == "" { diff --git a/tools/database/gen_db/main.go b/tools/database/gen_db/main.go index 5ec7b38631..aa1177adb6 100644 --- a/tools/database/gen_db/main.go +++ b/tools/database/gen_db/main.go @@ -26,6 +26,7 @@ import ( // go run ./tools/database/gen_db -outDir=assets -gen=wowhead-gearplannerdb // go run ./tools/database/gen_db -outDir=assets -gen=wago-db2-items // python3 tools/scrape_runes.py assets/db_inputs/wowhead_rune_tooltips.csv +// python3 tools/scrape_shoulder_runes.py assets/db_inputs/wowhead_shoulder_rune_tooltips.csv // Lastly run the following to generate db.json (ensure to delete cached versions and/or rebuild for copying of assets during local development) // Note: This does not make network requests, only regenerates core db binary and json files from existing inputs @@ -75,6 +76,7 @@ func main() { itemTooltips := database.NewWowheadItemTooltipManager(fmt.Sprintf("%s/wowhead_item_tooltips.csv", inputsDir)).Read() spellTooltips := database.NewWowheadSpellTooltipManager(fmt.Sprintf("%s/wowhead_spell_tooltips.csv", inputsDir)).Read() runeTooltips := database.NewWowheadSpellTooltipManager(fmt.Sprintf("%s/wowhead_rune_tooltips.csv", inputsDir)).Read() + shoulderRuneTooltips := database.NewWowheadSpellTooltipManager(fmt.Sprintf("%s/wowhead_shoulder_rune_tooltips.csv", inputsDir)).Read() wowheadDB := database.ParseWowheadDB(tools.ReadFile(fmt.Sprintf("%s/wowhead_gearplannerdb.txt", inputsDir))) atlaslootDB := database.ReadDatabaseFromJson(tools.ReadFile(fmt.Sprintf("%s/atlasloot_db.json", inputsDir))) wagoItems := database.ParseWagoDB(tools.ReadFile(fmt.Sprintf("%s/wago_db2_items.csv", inputsDir))) @@ -164,6 +166,12 @@ func main() { db.AddRune(id, rune) } + for id, rune := range shoulderRuneTooltips { + if database.ShoulderRuneClassAllowlist[rune.GetRequiredClasses()[0]] { + db.AddShoulderRune(id, rune) + } + } + db.MergeItems(database.ItemOverrides) db.MergeEnchants(database.EnchantOverrides) db.MergeRunes(database.RuneOverrides) diff --git a/tools/database/rune_overrides.go b/tools/database/rune_overrides.go index 8cb2a46da6..782e2103ea 100644 --- a/tools/database/rune_overrides.go +++ b/tools/database/rune_overrides.go @@ -45,33 +45,9 @@ var RuneOverrides = []*proto.UIRune{ // Hunter // As of 2024-06-13 Cobra Slayer is being missed by the scraper because the rune engraving ability is missing "Engrave Rune" in the name {Id: 458393, Name: "Engrave Gloves - Cobra Slayer", Icon: "spell_nature_guardianward", Type: proto.ItemType_ItemTypeHands, ClassAllowlist: []proto.Class{proto.Class_ClassHunter}}, +} - // Special should pseudo-runes - - // Druid - - // Hunter - - // Mage - // {Id: 1220158, Name: "Soul of Winter's Grasp", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassMage}}, - - // Paladin - - // Priest - // {Id: 1220134, Name: "Soul of the Zealot", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassPriest}}, - - // Rogue - - // Shaman - // {Id: 1220232, Name: "Soul of the Windwalker", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - // {Id: 1220234, Name: "Soul of the Shield Master", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - // {Id: 1220236, Name: "Soul of the Totemic Protector", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - // {Id: 1220238, Name: "Soul of the Shock-Absorber", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - // {Id: 1220240, Name: "Soul of the Spiritual Bulwark", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - // {Id: 1220242, Name: "Soul of the Maelstrombringer", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - // {Id: 1220244, Name: "Soul of the Lavawalker", Icon: "spell_holy_divinespirit", Type: proto.ItemType_ItemTypeShoulder, ClassAllowlist: []proto.Class{proto.Class_ClassShaman}}, - - // Warlock - - // Warrior +// Classes that have shoulder rune implementations completed to not confuse users +var ShoulderRuneClassAllowlist = map[proto.Class]bool{ + proto.Class_ClassShaman: true, } diff --git a/tools/database/wowhead_tooltips.go b/tools/database/wowhead_tooltips.go index 45535f0724..c0bc1a6e6f 100644 --- a/tools/database/wowhead_tooltips.go +++ b/tools/database/wowhead_tooltips.go @@ -334,17 +334,26 @@ func (item WowheadItemResponse) GetRequiresLevel() int { return level } -var reqClassRegex = regexp.MustCompile(`Requires (Druid|Hunter|Mage|Paladin|Priest|Rogue|Shaman|Warlock|Warrior)`) - -func (item WowheadItemResponse) GetRequiredClass() proto.Class { - class := item.GetTooltipRegexString(reqClassRegex, 1) +var allClassesRegex = regexp.MustCompile(`(Druid|Hunter|Mage|Paladin|Priest|Rogue|Shaman|Warlock|Warrior)`) +var reqClassRegex = regexp.MustCompile(`Requires\s(Druid|Hunter|Mage|Paladin|Priest|Rogue|Shaman|Warlock|Warrior)`) +var reqClassesRegex = regexp.MustCompile(`Classes:\s((?:.+?(Druid|Hunter|Mage|Paladin|Priest|Rogue|Shaman|Warlock|Warrior)<\/a>(?:,\s)?)+)`) + +func (item WowheadItemResponse) GetRequiredClasses() []proto.Class { + if singleClass := item.GetTooltipRegexString(reqClassRegex, 1); singleClass != "" { + className := "Class" + singleClass + return []proto.Class{proto.Class(proto.Class_value[className])} + } - if class == "" { - return proto.Class_ClassUnknown + if multiClasses := item.GetTooltipRegexString(reqClassesRegex, 1); multiClasses != "" { + classes := []proto.Class{} + for _, classMatch := range allClassesRegex.FindAllStringSubmatch(item.TooltipWithoutSetBonus(), -1) { + className := classMatch[1] + classes = append(classes, proto.Class(proto.Class_value["Class"+className])) + } + return classes } - className := "Class" + class - return proto.Class(proto.Class_value[className]) + return []proto.Class{} } var reqSlotRegex = regexp.MustCompile(`Requires (Back|Belt|Bracer|Chest|Cloak|Boots|Feet|Gloves|Hands|Head|Helm|Legs|Pants|Ring|Shoulder|Trinket|Waist|Wrist)`) diff --git a/tools/scrape_shoulder_runes.py b/tools/scrape_shoulder_runes.py new file mode 100644 index 0000000000..8134e668df --- /dev/null +++ b/tools/scrape_shoulder_runes.py @@ -0,0 +1,121 @@ +#!/usr/bin/python + +# This tool generates the classic SoD runes data + +import sys +import requests +import math +import re + +from typing import List + +from selenium import webdriver +from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.chrome.service import Service +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.by import By +from webdriver_manager.chrome import ChromeDriverManager +from selenium.webdriver.chrome.options import Options + +if len(sys.argv) < 2: + raise Exception("Missing arguments, expected output_file_path") + +output_file_path = sys.argv[1] + +# Added these options so that chrome would run in a docker container +chrome_options = Options() +chrome_options.add_argument("--headless") +chrome_options.add_argument("--no-sandbox") +chrome_options.add_argument("--disable-dev-shm-usage") + +driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) +wait = WebDriverWait(driver, 10) +element_locator = (By.ID, "data-tree-switcher") + +def _get_id_from_link(link): + return int(link.split("/")[-2].split("=")[-1]) + + +def get_item_ids() -> List[int]: + driver.get(f"https://www.wowhead.com/classic/items/name:%22Soul+of+the%22?filter=82:142;2:0;11506:spell_holy_divinespirit") + wait.until(EC.presence_of_element_located(element_locator)) + + listview = driver.find_element(By.ID, "lv-items") + pages = int(listview.find_element(By.CLASS_NAME, "listview-nav").find_element(By.CSS_SELECTOR, 'b:last-child').text)/50 + pages = math.ceil(pages) + all_ids = [] + + for page in range(pages): + print(f'Loading page {page} for runes...') + driver.get(f"https://www.wowhead.com/classic/items/name:%22Soul+of+the%22?filter=82:142;2:0;11506:spell_holy_divinespirit#{page*50}") + driver.refresh() + wait.until(EC.presence_of_element_located(element_locator)) + listview = driver.find_element(By.ID, "lv-items") + rows = listview.find_elements(By.CLASS_NAME, "listview-row") + all_ids.extend([_get_id_from_link(row.find_element(By.CLASS_NAME, "listview-cleartext").get_attribute("href")) + for row in rows]) + + return all_ids + +def get_tooltips_response(id): + # Get the underlying item ID from the engraving ID + url = f"https://nether.wowhead.com/classic/tooltip/item/{id}" + result = requests.get(url) + + if result.status_code == 200: + response_json = result.text + return response_json + else: + print(f"Request for id {id} failed with status code: {result.status_code}") + return None + + +# id, tooltip_json +to_export = [] + +item_ids = get_item_ids() + +print(f"Export Count ({len(item_ids)}) {item_ids}") + +to_export = [] + +# This sole spell is missing a related spell to reference +mismatchedIds = { + "1219819": 1220096 +} + +for id in item_ids: + item_response = get_tooltips_response(id) + spell_ids = re.findall(r'\/spell=(\d+)', item_response) + + if len(spell_ids) >= 2: + # The base spell is different from what we typically use but the spell we actually want appears as the first related spell in the "See also" tab + enchant_spell_id = spell_ids[0] + try: + driver.get(f"https://www.wowhead.com/classic/spell={enchant_spell_id}#see-also-other") + driver.refresh() + wait.until(EC.presence_of_element_located(element_locator)) + + see_also_tab = driver.find_element(By.ID, "tab-see-also-other") + rows = see_also_tab.find_elements(By.CLASS_NAME, "listview-row") + + if len(rows) > 0: + actual_spell_id = _get_id_from_link(rows[0].find_element(By.CLASS_NAME, "listview-cleartext").get_attribute("href")) + # Use the Spell ID of the effect but keep the item tooltip for class matching and display + to_export.append([actual_spell_id, item_response]) + else: + print(f"No related spell IDs found for spell ID {enchant_spell_id}") + except NoSuchElementException: + if mismatchedIds[enchant_spell_id]: + to_export.append([actual_spell_id, item_response]) + else: + print(f"No related spell IDs found for spell ID {enchant_spell_id}") + else: + print(f"Less than 2 spell IDs found for item ID {id}") + +driver.quit() +output_string = '\n'.join([str(','.join([str(inner_elem) for inner_elem in elem])) for elem in to_export]) + +with open(output_file_path, "w") as outfile: + outfile.write(output_string)