diff --git a/proto/shaman.proto b/proto/shaman.proto index 0fd1dc62dc..33a9f6da1f 100644 --- a/proto/shaman.proto +++ b/proto/shaman.proto @@ -138,6 +138,7 @@ enum EarthTotem { NoEarthTotem = 0; StrengthOfEarthTotem = 1; TremorTotem = 2; + StoneskinTotem = 3; } enum AirTotem { diff --git a/sim/priest/healing/TestDisc.results b/sim/priest/healing/TestDisc.results index 970d609d73..98e94f83b2 100644 --- a/sim/priest/healing/TestDisc.results +++ b/sim/priest/healing/TestDisc.results @@ -965,7 +965,7 @@ dps_results: { value: { dps: 46.29484 tps: 923.38559 - hps: 3815.47503 + hps: 3865.92202 } } dps_results: { @@ -973,7 +973,7 @@ dps_results: { value: { dps: 46.29484 tps: 46.16928 - hps: 3815.47503 + hps: 3865.92202 } } dps_results: { @@ -981,7 +981,7 @@ dps_results: { value: { dps: 231.47421 tps: 111.20851 - hps: 6223.79078 + hps: 6224.24357 } } dps_results: { diff --git a/sim/priest/healing/TestHoly.results b/sim/priest/healing/TestHoly.results index 99243b8e91..7c3398d8e9 100644 --- a/sim/priest/healing/TestHoly.results +++ b/sim/priest/healing/TestHoly.results @@ -918,25 +918,25 @@ dps_results: { dps_results: { key: "TestHoly-Settings-Undead-P1-Holy-NoBuffs-LongMultiTarget" value: { - dps: 48.47615 - tps: 442.41013 - hps: 2397.88991 + dps: 48.815 + tps: 445.41013 + hps: 2465.27937 } } dps_results: { key: "TestHoly-Settings-Undead-P1-Holy-NoBuffs-LongSingleTarget" value: { - dps: 48.47615 - tps: 22.12051 - hps: 2397.88991 + dps: 48.815 + tps: 22.27051 + hps: 2465.27937 } } dps_results: { key: "TestHoly-Settings-Undead-P1-Holy-NoBuffs-ShortSingleTarget" value: { - dps: 242.38076 - tps: 99.36047 - hps: 5855.88701 + dps: 244.07498 + tps: 98.28599 + hps: 5912.81696 } } dps_results: { diff --git a/sim/priest/priest.go b/sim/priest/priest.go index f8c1634bf7..20ac7b5b7e 100644 --- a/sim/priest/priest.go +++ b/sim/priest/priest.go @@ -111,6 +111,7 @@ func (priest *Priest) HasMinorGlyph(glyph proto.PriestMinorGlyph) bool { func (priest *Priest) AddRaidBuffs(raidBuffs *proto.RaidBuffs) { raidBuffs.ShadowProtection = true + raidBuffs.DivineSpirit = true raidBuffs.PowerWordFortitude = core.MaxTristate(raidBuffs.PowerWordFortitude, core.MakeTristateValue( true, diff --git a/sim/priest/shadow/TestShadow.results b/sim/priest/shadow/TestShadow.results index 0db3fad342..6102467360 100644 --- a/sim/priest/shadow/TestShadow.results +++ b/sim/priest/shadow/TestShadow.results @@ -810,22 +810,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-Draenei-P1-Basic-NoBuffs-LongMultiTarget" value: { - dps: 3179.48052 - tps: 4041.74966 + dps: 3295.82347 + tps: 4156.95718 } } dps_results: { key: "TestShadow-Settings-Draenei-P1-Basic-NoBuffs-LongSingleTarget" value: { - dps: 3179.48052 - tps: 3079.43259 + dps: 3295.82347 + tps: 3194.64011 } } dps_results: { key: "TestShadow-Settings-Draenei-P1-Basic-NoBuffs-ShortSingleTarget" value: { - dps: 3859.14133 - tps: 3670.19953 + dps: 3876.67502 + tps: 3688.20951 } } dps_results: { @@ -852,22 +852,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-Draenei-P1-Clipping-NoBuffs-LongMultiTarget" value: { - dps: 3074.10343 - tps: 3934.82197 + dps: 3156.1037 + tps: 4014.39406 } } dps_results: { key: "TestShadow-Settings-Draenei-P1-Clipping-NoBuffs-LongSingleTarget" value: { - dps: 3074.10343 - tps: 2972.5049 + dps: 3156.1037 + tps: 3052.07699 } } dps_results: { key: "TestShadow-Settings-Draenei-P1-Clipping-NoBuffs-ShortSingleTarget" value: { - dps: 3638.61531 - tps: 3449.81117 + dps: 3635.43134 + tps: 3446.08416 } } dps_results: { @@ -894,22 +894,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-Draenei-P1-Ideal-NoBuffs-LongMultiTarget" value: { - dps: 3143.95514 - tps: 4005.42227 + dps: 3218.71393 + tps: 4067.3837 } } dps_results: { key: "TestShadow-Settings-Draenei-P1-Ideal-NoBuffs-LongSingleTarget" value: { - dps: 3143.95514 - tps: 3043.10521 + dps: 3218.71393 + tps: 3118.49431 } } dps_results: { key: "TestShadow-Settings-Draenei-P1-Ideal-NoBuffs-ShortSingleTarget" value: { - dps: 3910.61632 - tps: 3722.63817 + dps: 3916.8271 + tps: 3728.01171 } } dps_results: { @@ -936,22 +936,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-NightElf-P1-Basic-NoBuffs-LongMultiTarget" value: { - dps: 3194.17874 - tps: 4055.5882 + dps: 3281.21516 + tps: 4141.79577 } } dps_results: { key: "TestShadow-Settings-NightElf-P1-Basic-NoBuffs-LongSingleTarget" value: { - dps: 3194.17874 - tps: 3094.08813 + dps: 3281.21516 + tps: 3180.2957 } } dps_results: { key: "TestShadow-Settings-NightElf-P1-Basic-NoBuffs-ShortSingleTarget" value: { - dps: 3852.68095 - tps: 3663.70773 + dps: 3871.36584 + tps: 3682.99577 } } dps_results: { @@ -978,22 +978,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-NightElf-P1-Clipping-NoBuffs-LongMultiTarget" value: { - dps: 3064.18956 - tps: 3924.83134 + dps: 3140.96752 + tps: 3997.9834 } } dps_results: { key: "TestShadow-Settings-NightElf-P1-Clipping-NoBuffs-LongSingleTarget" value: { - dps: 3064.18956 - tps: 2963.33127 + dps: 3140.96752 + tps: 3036.48333 } } dps_results: { key: "TestShadow-Settings-NightElf-P1-Clipping-NoBuffs-ShortSingleTarget" value: { - dps: 3634.10672 - tps: 3445.45277 + dps: 3631.16695 + tps: 3441.60764 } } dps_results: { @@ -1020,22 +1020,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-NightElf-P1-Ideal-NoBuffs-LongMultiTarget" value: { - dps: 3134.67202 - tps: 3996.05439 + dps: 3226.60756 + tps: 4089.61617 } } dps_results: { key: "TestShadow-Settings-NightElf-P1-Ideal-NoBuffs-LongSingleTarget" value: { - dps: 3134.67202 - tps: 3034.55432 + dps: 3226.60756 + tps: 3128.1161 } } dps_results: { key: "TestShadow-Settings-NightElf-P1-Ideal-NoBuffs-ShortSingleTarget" value: { - dps: 3911.09799 - tps: 3721.79945 + dps: 3910.78409 + tps: 3721.94365 } } dps_results: { @@ -1062,22 +1062,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-Undead-P1-Basic-NoBuffs-LongMultiTarget" value: { - dps: 3217.02585 - tps: 4076.37119 + dps: 3283.42212 + tps: 4142.58822 } } dps_results: { key: "TestShadow-Settings-Undead-P1-Basic-NoBuffs-LongSingleTarget" value: { - dps: 3217.02585 - tps: 3116.50512 + dps: 3283.42212 + tps: 3182.72215 } } dps_results: { key: "TestShadow-Settings-Undead-P1-Basic-NoBuffs-ShortSingleTarget" value: { - dps: 3853.81992 - tps: 3664.62764 + dps: 3872.50555 + tps: 3683.91747 } } dps_results: { @@ -1104,22 +1104,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-Undead-P1-Clipping-NoBuffs-LongMultiTarget" value: { - dps: 3072.59202 - tps: 3931.39176 + dps: 3145.27953 + tps: 4002.01556 } } dps_results: { key: "TestShadow-Settings-Undead-P1-Clipping-NoBuffs-LongSingleTarget" value: { - dps: 3072.59202 - tps: 2971.52569 + dps: 3145.27953 + tps: 3042.14949 } } dps_results: { key: "TestShadow-Settings-Undead-P1-Clipping-NoBuffs-ShortSingleTarget" value: { - dps: 3635.17371 - tps: 3446.30103 + dps: 3632.22753 + tps: 3442.44973 } } dps_results: { @@ -1146,22 +1146,22 @@ dps_results: { dps_results: { key: "TestShadow-Settings-Undead-P1-Ideal-NoBuffs-LongMultiTarget" value: { - dps: 3125.32682 - tps: 3985.37558 + dps: 3234.43345 + tps: 4095.17523 } } dps_results: { key: "TestShadow-Settings-Undead-P1-Ideal-NoBuffs-LongSingleTarget" value: { - dps: 3125.32682 - tps: 3025.50951 + dps: 3234.43345 + tps: 3135.30916 } } dps_results: { key: "TestShadow-Settings-Undead-P1-Ideal-NoBuffs-ShortSingleTarget" value: { - dps: 3913.92581 - tps: 3726.03737 + dps: 3911.9331 + tps: 3722.874 } } dps_results: { diff --git a/sim/priest/smite/TestSmite.results b/sim/priest/smite/TestSmite.results index 6a1e5405d8..fb6210d838 100644 --- a/sim/priest/smite/TestSmite.results +++ b/sim/priest/smite/TestSmite.results @@ -810,22 +810,22 @@ dps_results: { dps_results: { key: "TestSmite-Settings-Undead-P1-Basic-NoBuffs-LongMultiTarget" value: { - dps: 1063.9483 - tps: 1326.64675 + dps: 1116.06882 + tps: 1373.42671 } } dps_results: { key: "TestSmite-Settings-Undead-P1-Basic-NoBuffs-LongSingleTarget" value: { - dps: 1063.9483 - tps: 917.72126 + dps: 1116.06882 + tps: 964.50123 } } dps_results: { key: "TestSmite-Settings-Undead-P1-Basic-NoBuffs-ShortSingleTarget" value: { - dps: 2573.43723 - tps: 2076.36088 + dps: 2589.41624 + tps: 2086.69684 } } dps_results: { diff --git a/sim/shaman/chain_lightning.go b/sim/shaman/chain_lightning.go index 4d7c69ecf0..7b75968bb9 100644 --- a/sim/shaman/chain_lightning.go +++ b/sim/shaman/chain_lightning.go @@ -19,7 +19,7 @@ func (shaman *Shaman) registerChainLightningSpell() { func (shaman *Shaman) newChainLightningSpell(isLightningOverload bool) *core.Spell { spellConfig := shaman.newElectricSpellConfig( core.ActionID{SpellID: 49271}, - baseMana*0.26, + 0.26*shaman.BaseMana, time.Millisecond*2000, isLightningOverload) diff --git a/sim/shaman/elemental/TestElemental.results b/sim/shaman/elemental/TestElemental.results index 09a46ed2f6..7d653400fd 100644 --- a/sim/shaman/elemental/TestElemental.results +++ b/sim/shaman/elemental/TestElemental.results @@ -415,7 +415,7 @@ dps_results: { key: "TestElemental-AllItems-FrostWitch'sRegalia" value: { dps: 4609.89575 - tps: 2714.13196 + tps: 2714.50497 } } dps_results: { @@ -443,7 +443,7 @@ dps_results: { key: "TestElemental-AllItems-Gladiator'sEarthshaker" value: { dps: 3354.47482 - tps: 2016.86097 + tps: 2017.05078 } } dps_results: { @@ -730,7 +730,7 @@ dps_results: { key: "TestElemental-AllItems-SouloftheDead-40382" value: { dps: 4237.4174 - tps: 2534.0618 + tps: 2534.62444 } } dps_results: { @@ -961,7 +961,7 @@ dps_results: { key: "TestElemental-Average-Default" value: { dps: 4557.83064 - tps: 2703.10588 + tps: 2703.11008 } } dps_results: { diff --git a/sim/shaman/enhancement/TestEnhancement.results b/sim/shaman/enhancement/TestEnhancement.results index 8c2f1beeff..c02a4ef6ca 100644 --- a/sim/shaman/enhancement/TestEnhancement.results +++ b/sim/shaman/enhancement/TestEnhancement.results @@ -68,14 +68,14 @@ dps_results: { key: "TestEnhancement-AllItems-AustereEarthsiegeDiamond" value: { dps: 6623.43723 - tps: 3751.78128 + tps: 3751.79221 } } dps_results: { key: "TestEnhancement-AllItems-Bandit'sInsignia-40371" value: { dps: 6763.15268 - tps: 3834.0025 + tps: 3834.01344 } } dps_results: { @@ -131,14 +131,14 @@ dps_results: { key: "TestEnhancement-AllItems-BracingEarthsiegeDiamond" value: { dps: 6643.54056 - tps: 3660.15542 + tps: 3660.16636 } } dps_results: { key: "TestEnhancement-AllItems-ChaoticSkyflareDiamond" value: { dps: 6788.01497 - tps: 3844.55278 + tps: 3844.56371 } } dps_results: { @@ -188,7 +188,7 @@ dps_results: { key: "TestEnhancement-AllItems-DeadlyGladiator'sTotemofSurvival-42602" value: { dps: 6806.44782 - tps: 3861.36448 + tps: 3861.3648 } } dps_results: { @@ -230,14 +230,14 @@ dps_results: { key: "TestEnhancement-AllItems-DestructiveSkyflareDiamond" value: { dps: 6643.6889 - tps: 3761.04418 + tps: 3761.05512 } } dps_results: { key: "TestEnhancement-AllItems-DislodgedForeignObject-50348" value: { - dps: 6927.75795 - tps: 3934.30043 + dps: 6926.24875 + tps: 3933.23667 } } dps_results: { @@ -265,7 +265,7 @@ dps_results: { key: "TestEnhancement-AllItems-EffulgentSkyflareDiamond" value: { dps: 6623.43723 - tps: 3751.78128 + tps: 3751.79221 } } dps_results: { @@ -279,21 +279,21 @@ dps_results: { key: "TestEnhancement-AllItems-EnigmaticSkyflareDiamond" value: { dps: 6643.6017 - tps: 3761.13608 + tps: 3761.14701 } } dps_results: { key: "TestEnhancement-AllItems-EnigmaticStarflareDiamond" value: { dps: 6640.38947 - tps: 3759.33754 + tps: 3759.34848 } } dps_results: { key: "TestEnhancement-AllItems-EphemeralSnowflake-50260" value: { dps: 6731.60913 - tps: 3810.3569 + tps: 3810.36784 } } dps_results: { @@ -307,7 +307,7 @@ dps_results: { key: "TestEnhancement-AllItems-EternalEarthsiegeDiamond" value: { dps: 6623.43723 - tps: 3751.78128 + tps: 3751.79221 } } dps_results: { @@ -349,14 +349,14 @@ dps_results: { key: "TestEnhancement-AllItems-ForlornSkyflareDiamond" value: { dps: 6643.54056 - tps: 3764.41318 + tps: 3764.42412 } } dps_results: { key: "TestEnhancement-AllItems-ForlornStarflareDiamond" value: { dps: 6639.5199 - tps: 3761.8868 + tps: 3761.89774 } } dps_results: { @@ -377,7 +377,7 @@ dps_results: { key: "TestEnhancement-AllItems-FuriousGladiator'sTotemofSurvival-42603" value: { dps: 6817.76858 - tps: 3868.46699 + tps: 3868.46731 } } dps_results: { @@ -433,21 +433,21 @@ dps_results: { key: "TestEnhancement-AllItems-HatefulGladiator'sTotemofSurvival-42601" value: { dps: 6785.01888 - tps: 3847.37617 + tps: 3847.37648 } } dps_results: { key: "TestEnhancement-AllItems-Heartpierce-49982" value: { dps: 6794.17617 - tps: 3849.3003 + tps: 3849.31124 } } dps_results: { key: "TestEnhancement-AllItems-Heartpierce-50641" value: { dps: 6794.17617 - tps: 3849.3003 + tps: 3849.31124 } } dps_results: { @@ -461,14 +461,14 @@ dps_results: { key: "TestEnhancement-AllItems-ImpassiveSkyflareDiamond" value: { dps: 6643.6017 - tps: 3761.13608 + tps: 3761.14701 } } dps_results: { key: "TestEnhancement-AllItems-ImpassiveStarflareDiamond" value: { dps: 6640.38947 - tps: 3759.33754 + tps: 3759.34848 } } dps_results: { @@ -489,7 +489,7 @@ dps_results: { key: "TestEnhancement-AllItems-InvigoratingEarthsiegeDiamond" value: { dps: 6648.86251 - tps: 3765.86158 + tps: 3765.87251 hps: 10.80745 } } @@ -525,14 +525,14 @@ dps_results: { key: "TestEnhancement-AllItems-PersistentEarthshatterDiamond" value: { dps: 6644.0196 - tps: 3763.17962 + tps: 3763.19055 } } dps_results: { key: "TestEnhancement-AllItems-PersistentEarthsiegeDiamond" value: { dps: 6648.86251 - tps: 3765.86158 + tps: 3765.87251 } } dps_results: { @@ -553,14 +553,14 @@ dps_results: { key: "TestEnhancement-AllItems-PowerfulEarthshatterDiamond" value: { dps: 6623.43723 - tps: 3751.78128 + tps: 3751.79221 } } dps_results: { key: "TestEnhancement-AllItems-PowerfulEarthsiegeDiamond" value: { dps: 6623.43723 - tps: 3751.78128 + tps: 3751.79221 } } dps_results: { @@ -588,14 +588,14 @@ dps_results: { key: "TestEnhancement-AllItems-RelentlessEarthsiegeDiamond" value: { dps: 6794.17617 - tps: 3849.3003 + tps: 3849.31124 } } dps_results: { key: "TestEnhancement-AllItems-RelentlessGladiator'sTotemofSurvival-42604" value: { dps: 6831.51522 - tps: 3877.09147 + tps: 3877.09179 } } dps_results: { @@ -616,7 +616,7 @@ dps_results: { key: "TestEnhancement-AllItems-SavageGladiator'sTotemofSurvival-42594" value: { dps: 6779.34552 - tps: 3843.90451 + tps: 3843.90483 } } dps_results: { @@ -630,7 +630,7 @@ dps_results: { key: "TestEnhancement-AllItems-Shadowmourne-49623" value: { dps: 6794.17617 - tps: 3849.3003 + tps: 3849.31124 } } dps_results: { @@ -671,8 +671,8 @@ dps_results: { dps_results: { key: "TestEnhancement-AllItems-SliverofPureIce-50339" value: { - dps: 6716.86465 - tps: 3802.72722 + dps: 6717.15786 + tps: 3803.08146 } } dps_results: { @@ -714,7 +714,7 @@ dps_results: { key: "TestEnhancement-AllItems-Stonebreaker'sTotem-33507" value: { dps: 6781.41154 - tps: 3843.25865 + tps: 3843.25896 } } dps_results: { @@ -728,21 +728,21 @@ dps_results: { key: "TestEnhancement-AllItems-SwiftSkyflareDiamond" value: { dps: 6648.86251 - tps: 3765.86158 + tps: 3765.87251 } } dps_results: { key: "TestEnhancement-AllItems-SwiftStarflareDiamond" value: { dps: 6644.0196 - tps: 3763.17962 + tps: 3763.19055 } } dps_results: { key: "TestEnhancement-AllItems-SwiftWindfireDiamond" value: { dps: 6635.5445 - tps: 3758.48618 + tps: 3758.49712 } } dps_results: { @@ -791,7 +791,7 @@ dps_results: { key: "TestEnhancement-AllItems-ThunderingSkyflareDiamond" value: { dps: 6730.29301 - tps: 3813.33531 + tps: 3813.34625 } } dps_results: { @@ -805,7 +805,7 @@ dps_results: { key: "TestEnhancement-AllItems-TinyAbominationinaJar-50351" value: { dps: 6787.45718 - tps: 3847.01426 + tps: 3847.03613 } } dps_results: { @@ -819,14 +819,14 @@ dps_results: { key: "TestEnhancement-AllItems-TirelessSkyflareDiamond" value: { dps: 6643.54056 - tps: 3764.41318 + tps: 3764.42412 } } dps_results: { key: "TestEnhancement-AllItems-TirelessStarflareDiamond" value: { dps: 6639.5199 - tps: 3761.8868 + tps: 3761.89774 } } dps_results: { @@ -847,7 +847,7 @@ dps_results: { key: "TestEnhancement-AllItems-TotemoftheAvalanche-50463" value: { dps: 7009.81073 - tps: 3970.67203 + tps: 3970.68296 } } dps_results: { @@ -861,14 +861,14 @@ dps_results: { key: "TestEnhancement-AllItems-TrenchantEarthshatterDiamond" value: { dps: 6639.5199 - tps: 3761.8868 + tps: 3761.89774 } } dps_results: { key: "TestEnhancement-AllItems-TrenchantEarthsiegeDiamond" value: { dps: 6643.54056 - tps: 3764.41318 + tps: 3764.42412 } } dps_results: { @@ -882,7 +882,7 @@ dps_results: { key: "TestEnhancement-AllItems-Val'anyr,HammerofAncientKings-46017" value: { dps: 6869.79206 - tps: 3884.76918 + tps: 3884.78012 } } dps_results: { @@ -902,22 +902,22 @@ dps_results: { dps_results: { key: "TestEnhancement-AllItems-WorldbreakerGarb" value: { - dps: 6161.213 - tps: 3507.86358 + dps: 6160.63764 + tps: 3507.45287 } } dps_results: { key: "TestEnhancement-AllItems-WrathfulGladiator'sTotemofSurvival-51513" value: { dps: 6846.07049 - tps: 3886.22327 + tps: 3886.22359 } } dps_results: { key: "TestEnhancement-Average-Default" value: { - dps: 6799.41121 - tps: 3849.39068 + dps: 6799.38611 + tps: 3849.40146 } } dps_results: { @@ -951,8 +951,8 @@ dps_results: { dps_results: { key: "TestEnhancement-Settings-Orc-P1-Basic-NoBuffs-LongSingleTarget" value: { - dps: 3770.08617 - tps: 2134.60187 + dps: 3770.23621 + tps: 2134.7069 } } dps_results: { @@ -986,15 +986,15 @@ dps_results: { dps_results: { key: "TestEnhancement-Settings-Orc-P1-EnhFireElemental-NoBuffs-LongMultiTarget" value: { - dps: 13274.5514 - tps: 7909.42958 + dps: 13275.52041 + tps: 7911.23808 } } dps_results: { key: "TestEnhancement-Settings-Orc-P1-EnhFireElemental-NoBuffs-LongSingleTarget" value: { - dps: 3906.37835 - tps: 2013.88267 + dps: 3905.18557 + tps: 2013.0408 } } dps_results: { @@ -1015,7 +1015,7 @@ dps_results: { key: "TestEnhancement-Settings-Troll-P1-Basic-FullBuffs-LongSingleTarget" value: { dps: 6794.17617 - tps: 3849.3003 + tps: 3849.31124 } } dps_results: { @@ -1049,8 +1049,8 @@ dps_results: { dps_results: { key: "TestEnhancement-Settings-Troll-P1-EnhFireElemental-FullBuffs-LongMultiTarget" value: { - dps: 18225.38021 - tps: 10245.9404 + dps: 18216.08453 + tps: 10241.1522 } } dps_results: { diff --git a/sim/shaman/fire_totems.go b/sim/shaman/fire_totems.go index ee49f10449..ea0eeb2a9d 100644 --- a/sim/shaman/fire_totems.go +++ b/sim/shaman/fire_totems.go @@ -11,7 +11,7 @@ import ( func (shaman *Shaman) registerSearingTotemSpell() { actionID := core.ActionID{SpellID: 58704} - baseCost := baseMana * 0.07 + baseCost := 0.07 * shaman.BaseMana shaman.SearingTotem = shaman.RegisterSpell(core.SpellConfig{ ActionID: actionID, @@ -87,7 +87,7 @@ func (shaman *Shaman) registerSearingTotemSpell() { func (shaman *Shaman) registerMagmaTotemSpell() { actionID := core.ActionID{SpellID: 58734} - baseCost := baseMana * 0.27 + baseCost := 0.27 * shaman.BaseMana shaman.MagmaTotem = shaman.RegisterSpell(core.SpellConfig{ ActionID: actionID, diff --git a/sim/shaman/lavaburst.go b/sim/shaman/lavaburst.go index 24ef5efea9..fbd9afb82b 100644 --- a/sim/shaman/lavaburst.go +++ b/sim/shaman/lavaburst.go @@ -11,7 +11,7 @@ import ( func (shaman *Shaman) registerLavaBurstSpell() { actionID := core.ActionID{SpellID: 60043} - baseCost := baseMana * 0.1 + baseCost := 0.1 * shaman.BaseMana dmgBonus := core.TernaryFloat64(shaman.Equip[core.ItemSlotRanged].ID == VentureCoLightningRod, 121, 0) + core.TernaryFloat64(shaman.Equip[core.ItemSlotRanged].ID == ThunderfallTotem, 215, 0) spellCoeff := 0.5714 + diff --git a/sim/shaman/lightning_bolt.go b/sim/shaman/lightning_bolt.go index 482038c0d0..9ddc6a99ad 100644 --- a/sim/shaman/lightning_bolt.go +++ b/sim/shaman/lightning_bolt.go @@ -14,7 +14,7 @@ func (shaman *Shaman) registerLightningBoltSpell() { } func (shaman *Shaman) newLightningBoltSpell(isLightningOverload bool) *core.Spell { - baseCost := baseMana * 0.1 + baseCost := 0.1 * shaman.BaseMana if shaman.HasSetBonus(ItemSetEarthShatterGarb, 2) { baseCost -= baseCost * 0.05 } diff --git a/sim/shaman/shaman.go b/sim/shaman/shaman.go index 61bba63e1d..f18e5c2f95 100644 --- a/sim/shaman/shaman.go +++ b/sim/shaman/shaman.go @@ -8,8 +8,6 @@ import ( "github.com/wowsims/wotlk/sim/core/stats" ) -const baseMana = 4396.0 - // Start looking to refresh 5 minute totems at 4:55. const TotemRefreshTime5M = time.Second * 295 @@ -22,7 +20,7 @@ const ( func NewShaman(character core.Character, talents *proto.ShamanTalents, totems *proto.ShamanTotems, selfBuffs SelfBuffs, thunderstormRange bool) *Shaman { if totems.Fire == proto.FireTotem_TotemOfWrath && !talents.TotemOfWrath { - totems.Fire = proto.FireTotem_NoFireTotem + totems.Fire = proto.FireTotem_FlametongueTotem } shaman := &Shaman{ @@ -117,6 +115,7 @@ type Shaman struct { StrengthOfEarthTotem *core.Spell TotemOfWrath *core.Spell TremorTotem *core.Spell + StoneskinTotem *core.Spell WindfuryTotem *core.Spell WrathOfAirTotem *core.Spell FlametongueTotem *core.Spell @@ -185,6 +184,11 @@ func (shaman *Shaman) AddRaidBuffs(raidBuffs *proto.RaidBuffs) { totem = proto.TristateEffect_TristateEffectImproved } raidBuffs.StrengthOfEarthTotem = core.MaxTristate(raidBuffs.StrengthOfEarthTotem, totem) + case proto.EarthTotem_StoneskinTotem: + raidBuffs.StoneskinTotem = core.MaxTristate(raidBuffs.StoneskinTotem, core.MakeTristateValue( + true, + shaman.Talents.GuardianTotems == 2, + )) } if shaman.Talents.UnleashedRage > 0 { @@ -220,6 +224,7 @@ func (shaman *Shaman) Initialize() { shaman.registerTotemOfWrathSpell() shaman.registerFlametongueTotemSpell() shaman.registerTremorTotemSpell() + shaman.registerStoneskinTotemSpell() shaman.registerWindfuryTotemSpell() shaman.registerWrathOfAirTotemSpell() @@ -378,7 +383,7 @@ func init() { stats.Stamina: 135, stats.Intellect: 126, stats.Spirit: 145, - stats.Mana: baseMana, + stats.Mana: 4396, stats.SpellCrit: 2.2 * core.CritRatingPerCritChance, stats.AttackPower: 95, // TODO: confirm this. stats.MeleeCrit: 2.92 * core.CritRatingPerCritChance, @@ -390,7 +395,7 @@ func init() { stats.Stamina: 138, stats.Intellect: 122, stats.Spirit: 146, - stats.Mana: baseMana, + stats.Mana: 4396, stats.SpellCrit: 2.2 * core.CritRatingPerCritChance, stats.AttackPower: 95, // TODO: confirm this. stats.MeleeCrit: 2.92 * core.CritRatingPerCritChance, @@ -402,7 +407,7 @@ func init() { stats.Stamina: 138, stats.Intellect: 120, stats.Spirit: 145, - stats.Mana: baseMana, + stats.Mana: 4396, stats.SpellCrit: 2.2 * core.CritRatingPerCritChance, stats.AttackPower: 95, // TODO: confirm this. stats.MeleeCrit: 2.92 * core.CritRatingPerCritChance, @@ -414,7 +419,7 @@ func init() { stats.Stamina: 137, stats.Intellect: 122, stats.Spirit: 144, - stats.Mana: baseMana, + stats.Mana: 4396, stats.SpellCrit: 2.2 * core.CritRatingPerCritChance, stats.AttackPower: 95, // TODO: confirm this. stats.MeleeCrit: 2.92 * core.CritRatingPerCritChance, diff --git a/sim/shaman/shocks.go b/sim/shaman/shocks.go index 1a4e3ca41b..d06d031355 100644 --- a/sim/shaman/shocks.go +++ b/sim/shaman/shocks.go @@ -54,7 +54,7 @@ func (shaman *Shaman) newShockSpellConfig(spellID int32, spellSchool core.SpellS } func (shaman *Shaman) registerEarthShockSpell(shockTimer *core.Timer) { - config := shaman.newShockSpellConfig(49231, core.SpellSchoolNature, baseMana*0.18, shockTimer) + config := shaman.newShockSpellConfig(49231, core.SpellSchoolNature, 0.18*shaman.BaseMana, shockTimer) config.ApplyEffects = func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { baseDamage := sim.Roll(854, 900) + 0.386*spell.SpellPower() spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMagicHitAndCrit) @@ -67,7 +67,7 @@ const FlameshockID = 49233 func (shaman *Shaman) registerFlameShockSpell(shockTimer *core.Timer) { actionID := core.ActionID{SpellID: FlameshockID} - config := shaman.newShockSpellConfig(FlameshockID, core.SpellSchoolFire, baseMana*0.17, shockTimer) + config := shaman.newShockSpellConfig(FlameshockID, core.SpellSchoolFire, 0.17*shaman.BaseMana, shockTimer) config.Cast.CD.Duration -= time.Duration(shaman.Talents.BoomingEchoes) * time.Second config.CritMultiplier = shaman.ElementalCritMultiplier(core.TernaryFloat64(shaman.HasMajorGlyph(proto.ShamanMajorGlyph_GlyphOfFlameShock), 0.6, 0)) @@ -124,7 +124,7 @@ func (shaman *Shaman) registerFlameShockSpell(shockTimer *core.Timer) { } func (shaman *Shaman) registerFrostShockSpell(shockTimer *core.Timer) { - config := shaman.newShockSpellConfig(49236, core.SpellSchoolFrost, baseMana*0.18, shockTimer) + config := shaman.newShockSpellConfig(49236, core.SpellSchoolFrost, 0.18*shaman.BaseMana, shockTimer) config.Cast.CD.Duration -= time.Duration(shaman.Talents.BoomingEchoes) * time.Second config.DamageMultiplier += 0.1 * float64(shaman.Talents.BoomingEchoes) config.ThreatMultiplier *= 2 diff --git a/sim/shaman/stormstrike.go b/sim/shaman/stormstrike.go index a171eab131..cd0fe694b4 100644 --- a/sim/shaman/stormstrike.go +++ b/sim/shaman/stormstrike.go @@ -84,7 +84,7 @@ func (shaman *Shaman) registerStormstrikeSpell() { mhHit := shaman.newStormstrikeHitSpell(true) ohHit := shaman.newStormstrikeHitSpell(false) - baseCost := baseMana * 0.08 + baseCost := 0.08 * shaman.BaseMana if shaman.Equip[core.ItemSlotRanged].ID == StormfuryTotem { baseCost -= 22 } @@ -104,6 +104,7 @@ func (shaman *Shaman) registerStormstrikeSpell() { manaMetrics := shaman.NewManaMetrics(core.ActionID{SpellID: 51522}) cooldownTime := time.Duration(core.TernaryFloat64(shaman.HasSetBonus(ItemSetGladiatorsEarthshaker, 4), 6, 8)) + impSSChance := 0.5 * float64(shaman.Talents.ImprovedStormstrike) shaman.Stormstrike = shaman.RegisterSpell(core.SpellConfig{ ActionID: StormstrikeActionID, @@ -130,10 +131,8 @@ func (shaman *Shaman) registerStormstrikeSpell() { ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { result := spell.CalcOutcome(sim, target, spell.OutcomeMeleeSpecialHit) if result.Landed() { - if shaman.Talents.ImprovedStormstrike > 0 { - if sim.RandomFloat("Improved Stormstrike") < 0.5*float64(shaman.Talents.ImprovedStormstrike) { - shaman.AddMana(sim, baseMana*0.2, manaMetrics, true) - } + if impSSChance > 0 && sim.RandomFloat("Improved Stormstrike") < impSSChance { + shaman.AddMana(sim, 0.2*shaman.BaseMana, manaMetrics, true) } ssDebuffAura.Activate(sim) ssDebuffAura.SetStacks(sim, 4) diff --git a/sim/shaman/totems.go b/sim/shaman/totems.go index 56720ea0d4..c79bad5db4 100644 --- a/sim/shaman/totems.go +++ b/sim/shaman/totems.go @@ -29,7 +29,7 @@ func (shaman *Shaman) newTotemSpellConfig(baseCost float64, spellID int32) core. } func (shaman *Shaman) registerWrathOfAirTotemSpell() { - config := shaman.newTotemSpellConfig(320.0, 3738) + config := shaman.newTotemSpellConfig(0.11*shaman.BaseMana, 3738) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[AirTotem] = sim.CurrentTime + time.Second*300 } @@ -37,7 +37,7 @@ func (shaman *Shaman) registerWrathOfAirTotemSpell() { } func (shaman *Shaman) registerWindfuryTotemSpell() { - config := shaman.newTotemSpellConfig(baseMana*0.11, 8512) + config := shaman.newTotemSpellConfig(shaman.BaseMana*0.11, 8512) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[AirTotem] = sim.CurrentTime + time.Second*300 } @@ -45,7 +45,7 @@ func (shaman *Shaman) registerWindfuryTotemSpell() { } func (shaman *Shaman) registerManaSpringTotemSpell() { - config := shaman.newTotemSpellConfig(baseMana*0.04, 58774) + config := shaman.newTotemSpellConfig(shaman.BaseMana*0.04, 58774) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[WaterTotem] = sim.CurrentTime + time.Second*300 } @@ -53,7 +53,7 @@ func (shaman *Shaman) registerManaSpringTotemSpell() { } func (shaman *Shaman) registerTotemOfWrathSpell() { - config := shaman.newTotemSpellConfig(baseMana*0.05, 57722) + config := shaman.newTotemSpellConfig(shaman.BaseMana*0.05, 57722) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[FireTotem] = sim.CurrentTime + time.Second*300 shaman.applyToWDebuff(sim) @@ -69,7 +69,7 @@ func (shaman *Shaman) applyToWDebuff(sim *core.Simulation) { } func (shaman *Shaman) registerFlametongueTotemSpell() { - config := shaman.newTotemSpellConfig(baseMana*0.11, 58656) + config := shaman.newTotemSpellConfig(0.11*shaman.BaseMana, 58656) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[FireTotem] = sim.CurrentTime + time.Second*300 } @@ -77,7 +77,7 @@ func (shaman *Shaman) registerFlametongueTotemSpell() { } func (shaman *Shaman) registerStrengthOfEarthTotemSpell() { - config := shaman.newTotemSpellConfig(300, 25528) + config := shaman.newTotemSpellConfig(0.1*shaman.BaseMana, 58643) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[EarthTotem] = sim.CurrentTime + time.Second*300 } @@ -85,13 +85,21 @@ func (shaman *Shaman) registerStrengthOfEarthTotemSpell() { } func (shaman *Shaman) registerTremorTotemSpell() { - config := shaman.newTotemSpellConfig(60, 8143) + config := shaman.newTotemSpellConfig(0.02*shaman.BaseMana, 8143) config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { shaman.NextTotemDrops[EarthTotem] = sim.CurrentTime + time.Second*300 } shaman.TremorTotem = shaman.RegisterSpell(config) } +func (shaman *Shaman) registerStoneskinTotemSpell() { + config := shaman.newTotemSpellConfig(0.1*shaman.BaseMana, 58753) + config.ApplyEffects = func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { + shaman.NextTotemDrops[EarthTotem] = sim.CurrentTime + time.Second*300 + } + shaman.StoneskinTotem = shaman.RegisterSpell(config) +} + func (shaman *Shaman) NextTotemAt(_ *core.Simulation) time.Duration { nextTotemAt := core.MinDuration( shaman.NextTotemDrops[0], @@ -131,6 +139,8 @@ func (shaman *Shaman) TryDropTotems(sim *core.Simulation) bool { spell = shaman.StrengthOfEarthTotem case proto.EarthTotem_TremorTotem: spell = shaman.TremorTotem + case proto.EarthTotem_StoneskinTotem: + spell = shaman.StoneskinTotem } case FireTotem: diff --git a/ui/core/components/importers.ts b/ui/core/components/importers.ts index 7e65555da5..7ade26bea9 100644 --- a/ui/core/components/importers.ts +++ b/ui/core/components/importers.ts @@ -18,7 +18,7 @@ import { classGlyphsConfig, talentSpellIdsToTalentString } from '../talents/fact import { GlyphConfig } from '../talents/glyphs_picker'; export abstract class Importer extends Popup { - private readonly textElem: HTMLTextAreaElement; + protected readonly textElem: HTMLTextAreaElement; protected readonly descriptionElem: HTMLElement; protected readonly importButton: HTMLButtonElement; private readonly includeFile: boolean; diff --git a/ui/core/components/totem_inputs.ts b/ui/core/components/totem_inputs.ts index 29b7bfb6bd..210260f1a5 100644 --- a/ui/core/components/totem_inputs.ts +++ b/ui/core/components/totem_inputs.ts @@ -43,6 +43,7 @@ export function TotemsSection(parentElem: HTMLElement, simUI: IndividualSimUI a == b, diff --git a/ui/raid/import_export.ts b/ui/raid/import_export.ts index 99392c6b04..85cc76d3c2 100644 --- a/ui/raid/import_export.ts +++ b/ui/raid/import_export.ts @@ -70,6 +70,7 @@ export class RaidWCLImporter extends Importer { constructor(parent: HTMLElement, simUI: RaidSimUI) { super(parent, simUI, 'WCL Import', false); this.simUI = simUI; + this.textElem.classList.add('small-textarea'); this.descriptionElem.innerHTML = `

Imports the entire raid from a WCL report.
@@ -402,7 +403,6 @@ export class RaidWCLImporter extends Importer { }); wclPlayers - .filter(p => p.isPlayer) .forEach(player => { const positionInParty = player.raidIndex % 5; const partyIdx = (player.raidIndex - positionInParty) / 5; @@ -461,24 +461,17 @@ class WCLSimPlayer implements wclSimPlayer { } this.fullType = this.type + this.wclSpec; - this.spec = fullTypeToSpec[this.fullType] || null; - this.sortPriority = specSortPriority[this.fullType] ?? 99; - - console.log(`WCL spec: ${this.fullType}`); - if (this.spec != null) { + const foundSpec = fullTypeToSpec[this.fullType] ?? null; + if (foundSpec == null) { throw new Error('Player type not implemented: ' + this.fullType); } - } + this.spec = foundSpec; + this.sortPriority = specSortPriority[this.fullType] ?? 99; - public get isPlayer(): boolean { - return this.spec != null; + console.log(`WCL spec: ${this.fullType}`); } public getPlayer(): PlayerProto | undefined { - if (!this.isPlayer) { - return; - } - const matchingPreset = this.getMatchingPreset(); if (matchingPreset === undefined) { throw new Error('Could not find matching preset: ' + JSON.stringify({ diff --git a/ui/raid/raid_picker.ts b/ui/raid/raid_picker.ts index 041d387049..ab147584d9 100644 --- a/ui/raid/raid_picker.ts +++ b/ui/raid/raid_picker.ts @@ -249,7 +249,7 @@ export class PlayerPicker extends Component { this.referenceDeltaElem = this.rootElem.getElementsByClassName('player-results-reference-delta')[0] as HTMLElement; this.nameElem.addEventListener('input', event => { - if (this.player instanceof Player) { + if (this.player) { this.player.setName(TypedEvent.nextEventID(), this.nameElem.textContent || ''); } }); @@ -259,7 +259,7 @@ export class PlayerPicker extends Component { // 9 is tab, 13 is enter if (event.keyCode == 9 || event.keyCode == 13) { event.preventDefault(); - const realPlayerPickers = this.raidPicker.getPlayerPickers().filter(pp => pp.player instanceof Player); + const realPlayerPickers = this.raidPicker.getPlayerPickers().filter(pp => pp.player != null); const indexOfThis = realPlayerPickers.indexOf(this); if (indexOfThis != -1 && realPlayerPickers.length > indexOfThis + 1) { realPlayerPickers[indexOfThis + 1].nameElem.focus(); @@ -292,7 +292,7 @@ export class PlayerPicker extends Component { this.nameElem.addEventListener('focusout', event => { if (!this.nameElem.textContent) { this.nameElem.textContent = emptyName; - if (this.player instanceof Player) { + if (this.player) { this.player.setName(TypedEvent.nextEventID(), emptyName); } } @@ -310,7 +310,7 @@ export class PlayerPicker extends Component { const dragImage = new Image(); dragImage.src = iconSrc; event.dataTransfer!.setDragImage(dragImage, 30, 30); - if (this.player instanceof Player) { + if (this.player) { var playerDataProto = this.player.toProto(true); event.dataTransfer!.setData("text/plain", btoa(String.fromCharCode(...PlayerProto.toBinary(playerDataProto)))); } @@ -425,7 +425,7 @@ export class PlayerPicker extends Component { 'allowHTML': true, }); editElem.addEventListener('click', event => { - if (this.player instanceof Player) { + if (this.player) { new PlayerEditorModal(this.player); } }); diff --git a/ui/raid/raid_stats.ts b/ui/raid/raid_stats.ts index c962594cec..b15ffbda2d 100644 --- a/ui/raid/raid_stats.ts +++ b/ui/raid/raid_stats.ts @@ -266,17 +266,16 @@ const RAID_STATS_OPTIONS: RaidStatsOptions = {sections: [ actionId: ActionId.fromSpellId(48942), providedByPlayer: playerClassAndMissingTalent(Class.ClassPaladin, 'improvedDevotionAura', player => player.getSpecOptions().aura == PaladinAura.DevotionAura), }, - // TODO: Implement stoneskin totem - //{ - // label: 'Improved Stoneskin Totem', - // actionId: ActionId.fromSpellId(16293), - // providedByPlayer: playerClassAndTalent(Class.ClassShaman, 'guardianTotems', player => player.getRotation().totems?.earth == EarthTotem.StoneskinTotem), - //}, - //{ - // label: 'Stoneskin Totem', - // actionId: ActionId.fromSpellId(58753), - // providedByPlayer: playerClassAndMissingTalent(Class.ClassShaman, 'guardianTotems', player => player.getRotation().totems?.earth == EarthTotem.StoneskinTotem), - //}, + { + label: 'Improved Stoneskin Totem', + actionId: ActionId.fromSpellId(16293), + providedByPlayer: playerClassAndTalent(Class.ClassShaman, 'guardianTotems', player => player.getRotation().totems?.earth == EarthTotem.StoneskinTotem), + }, + { + label: 'Stoneskin Totem', + actionId: ActionId.fromSpellId(58753), + providedByPlayer: playerClassAndMissingTalent(Class.ClassShaman, 'guardianTotems', player => player.getRotation().totems?.earth == EarthTotem.StoneskinTotem), + }, { label: 'Scroll of Protection', actionId: ActionId.fromItemId(43468), @@ -342,7 +341,6 @@ const RAID_STATS_OPTIONS: RaidStatsOptions = {sections: [ actionId: ActionId.fromSpellId(43002), providedByPlayer: playerClass(Class.ClassMage), }, - // TODO: Double-check the talent { label: 'Improved Fel Intelligence', actionId: ActionId.fromSpellId(54038), @@ -363,13 +361,11 @@ const RAID_STATS_OPTIONS: RaidStatsOptions = {sections: [ { label: 'Spirit', effects: [ - // TODO: Implement divine spirit { label: 'Divine Spirit', actionId: ActionId.fromSpellId(48073), providedByPlayer: playerClass(Class.ClassPriest), }, - // TODO: Double-check the talent { label: 'Improved Fel Intelligence', actionId: ActionId.fromSpellId(54038), diff --git a/ui/scss/core/components/_importers.scss b/ui/scss/core/components/_importers.scss index 0b0ec4dfe1..488f16b98e 100644 --- a/ui/scss/core/components/_importers.scss +++ b/ui/scss/core/components/_importers.scss @@ -23,6 +23,9 @@ height: 40vh; resize: none; } +.importer-textarea.small-textarea { + height: 1rem; +} .importer-button { cursor: pointer; diff --git a/ui/scss/core/components/_popup.scss b/ui/scss/core/components/_popup.scss index 574cabca03..69918ffa08 100644 --- a/ui/scss/core/components/_popup.scss +++ b/ui/scss/core/components/_popup.scss @@ -3,6 +3,8 @@ .popup { @include vertical-horizontal-center; min-width: 50%; + max-height: 98vh; + overflow-y: scroll; padding: 1rem; background-color: #111218; border: 1px solid $primary;