diff --git a/sim/hunter/arcane_shot.go b/sim/hunter/arcane_shot.go index 2099105c07..efdfe92274 100644 --- a/sim/hunter/arcane_shot.go +++ b/sim/hunter/arcane_shot.go @@ -14,7 +14,8 @@ func (hunter *Hunter) registerArcaneShotSpell() { ProcMask: core.ProcMaskRangedSpecial, Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, MissileSpeed: 40, - + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 25 - float64(hunter.Talents.Efficiency), }, diff --git a/sim/hunter/aspects.go b/sim/hunter/aspects.go index 9715ff7cdf..868ebde4f0 100644 --- a/sim/hunter/aspects.go +++ b/sim/hunter/aspects.go @@ -35,11 +35,12 @@ func (hunter *Hunter) registerAspectOfTheHawkSpell() { } func (hunter *Hunter) registerAspectOfTheFoxSpell() { actionID := core.ActionID{SpellID: 82661} - // restoreFocus := 2 + restoreFocus := 2.0 + focusMetric := hunter.NewFocusMetrics(actionID) - // if hunter.Talents.OneWithNature > 0 { - // restoreFocus += 1 * float64(hunter.Talents.OneWithNature) - // } + if hunter.Talents.OneWithNature > 0 { + restoreFocus += 1 * float64(hunter.Talents.OneWithNature) + } foxMod := hunter.AddDynamicMod(core.SpellModConfig{ Kind: core.SpellMod_AllowCastWhileMoving, @@ -54,6 +55,11 @@ func (hunter *Hunter) registerAspectOfTheFoxSpell() { OnExpire: func(aura *core.Aura, sim *core.Simulation) { foxMod.Deactivate() }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if aura.IsActive() { + hunter.AddFocus(sim, restoreFocus, focusMetric) + } + }, })) hunter.applySharedAspectConfig(true, hunter.AspectOfTheFoxAura) @@ -68,8 +74,6 @@ func (hunter *Hunter) registerAspectOfTheFoxSpell() { }) } -// Todo: Implement Aspect of the Fox? - func (hunter *Hunter) applySharedAspectConfig(isHawk bool, aura *core.Aura) { aura.Duration = core.NeverExpires aura.NewExclusiveEffect("Aspect", true, core.ExclusiveEffect{}) diff --git a/sim/hunter/beast_mastery/TestBM.results b/sim/hunter/beast_mastery/TestBM.results index c7b38fc851..917270a624 100644 --- a/sim/hunter/beast_mastery/TestBM.results +++ b/sim/hunter/beast_mastery/TestBM.results @@ -39,1450 +39,1450 @@ character_stats_results: { dps_results: { key: "TestBM-AllItems-AgileShadowspiritDiamond" value: { - dps: 20388.57547 - tps: 17192.23514 + dps: 20858.65438 + tps: 17660.08244 } } dps_results: { key: "TestBM-AllItems-Ahn'KaharBloodHunter'sBattlegear" value: { - dps: 17610.74012 - tps: 14895.03915 + dps: 18095.1918 + tps: 15364.82414 } } dps_results: { key: "TestBM-AllItems-Althor'sAbacus-50366" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Anhuur'sHymnal-55889" value: { - dps: 19413.92508 - tps: 16388.2145 + dps: 19808.61178 + tps: 16761.31952 } } dps_results: { key: "TestBM-AllItems-Anhuur'sHymnal-56407" value: { - dps: 19518.4798 - tps: 16488.13309 + dps: 19912.5216 + tps: 16870.29698 } } dps_results: { key: "TestBM-AllItems-AustereShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16827.20374 + dps: 20421.4492 + tps: 17240.83564 } } dps_results: { key: "TestBM-AllItems-BaubleofTrueBlood-50726" value: { - dps: 18921.64725 - tps: 15968.60893 - hps: 97.03133 + dps: 19313.86464 + tps: 16310.35268 + hps: 97.21407 } } dps_results: { key: "TestBM-AllItems-BedrockTalisman-58182" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BellofEnragingResonance-59326" value: { - dps: 19204.37185 - tps: 16205.8019 + dps: 19586.13432 + tps: 16560.79395 } } dps_results: { key: "TestBM-AllItems-BellofEnragingResonance-65053" value: { - dps: 19271.59248 - tps: 16268.55688 + dps: 19634.31634 + tps: 16605.26803 } } dps_results: { key: "TestBM-AllItems-BindingPromise-67037" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BlackBruise-50692" value: { - dps: 19052.13993 - tps: 16104.48698 + dps: 19526.12494 + tps: 16556.06153 } } dps_results: { key: "TestBM-AllItems-Blood-SoakedAleMug-63843" value: { - dps: 19570.07148 - tps: 16457.73955 + dps: 20009.96051 + tps: 16867.0115 } } dps_results: { key: "TestBM-AllItems-BloodofIsiset-55995" value: { - dps: 19018.20791 - tps: 16009.65907 + dps: 19415.83106 + tps: 16355.6561 } } dps_results: { key: "TestBM-AllItems-BloodofIsiset-56414" value: { - dps: 19030.86768 - tps: 16015.03469 + dps: 19429.1728 + tps: 16361.58869 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sBadgeofConquest-64687" value: { - dps: 19987.73297 - tps: 16841.47752 + dps: 20497.29946 + tps: 17326.25128 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sBadgeofDominance-64688" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sBadgeofVictory-64689" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sEmblemofCruelty-64740" value: { - dps: 19209.47837 - tps: 16212.3982 + dps: 19539.18441 + tps: 16517.63266 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sEmblemofMeditation-64741" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sEmblemofTenacity-64742" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sInsigniaofConquest-64761" value: { - dps: 19619.7882 - tps: 16547.39426 + dps: 20111.29914 + tps: 16990.65536 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sInsigniaofDominance-64762" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sInsigniaofVictory-64763" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-BloodthirstyGladiator'sPursuit" value: { - dps: 18132.27776 - tps: 15236.13505 + dps: 18483.51157 + tps: 15561.76977 } } dps_results: { key: "TestBM-AllItems-BottledLightning-66879" value: { - dps: 19055.17024 - tps: 16085.83976 + dps: 19419.46165 + tps: 16418.75079 } } dps_results: { key: "TestBM-AllItems-BracingShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16490.65966 + dps: 20421.4492 + tps: 16896.01892 } } dps_results: { key: "TestBM-AllItems-Bryntroll,theBoneArbiter-50709" value: { - dps: 20444.70775 - tps: 17248.23811 + dps: 20916.36247 + tps: 17717.71028 } } dps_results: { key: "TestBM-AllItems-BurningShadowspiritDiamond" value: { - dps: 20219.93165 - tps: 17051.62956 + dps: 20665.47629 + tps: 17484.86273 } } dps_results: { key: "TestBM-AllItems-ChaoticShadowspiritDiamond" value: { - dps: 20286.85562 - tps: 17109.75524 + dps: 20745.46831 + tps: 17560.87005 } } dps_results: { key: "TestBM-AllItems-CoreofRipeness-58184" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-CorpseTongueCoin-50349" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-CrushingWeight-59506" value: { - dps: 19202.52233 - tps: 16193.42641 + dps: 19593.20191 + tps: 16573.30345 } } dps_results: { key: "TestBM-AllItems-CrushingWeight-65118" value: { - dps: 19141.46808 - tps: 16128.45332 + dps: 19579.0914 + tps: 16537.40623 } } dps_results: { key: "TestBM-AllItems-DarkmoonCard:Earthquake-62048" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-DarkmoonCard:Hurricane-62049" value: { - dps: 19407.15752 - tps: 16418.25647 + dps: 19857.73296 + tps: 16862.1941 } } dps_results: { key: "TestBM-AllItems-DarkmoonCard:Hurricane-62051" value: { - dps: 20226.11466 - tps: 17116.88625 + dps: 20656.11894 + tps: 17523.94263 } } dps_results: { key: "TestBM-AllItems-DarkmoonCard:Tsunami-62050" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-DarkmoonCard:Volcano-62047" value: { - dps: 19044.67834 - tps: 16020.89899 + dps: 19443.72744 + tps: 16368.06061 } } dps_results: { key: "TestBM-AllItems-Deathbringer'sWill-50363" value: { - dps: 19469.4001 - tps: 16433.54883 + dps: 19853.30955 + tps: 16796.4201 } } dps_results: { key: "TestBM-AllItems-DestructiveShadowspiritDiamond" value: { - dps: 20059.15389 - tps: 16882.05351 + dps: 20497.59522 + tps: 17312.99696 } } dps_results: { key: "TestBM-AllItems-DislodgedForeignObject-50348" value: { - dps: 19172.61866 - tps: 16152.50551 + dps: 19556.77036 + tps: 16523.91338 } } dps_results: { key: "TestBM-AllItems-EffulgentShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16827.20374 + dps: 20421.4492 + tps: 17240.83564 } } dps_results: { key: "TestBM-AllItems-ElectrosparkHeartstarter-67118" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-EmberShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16827.20374 + dps: 20421.4492 + tps: 17240.83564 } } dps_results: { key: "TestBM-AllItems-EnigmaticShadowspiritDiamond" value: { - dps: 20059.15389 - tps: 16882.05351 + dps: 20497.59522 + tps: 17312.99696 } } dps_results: { key: "TestBM-AllItems-EssenceoftheCyclone-59473" value: { - dps: 20089.15436 - tps: 16918.56505 + dps: 20449.35323 + tps: 17282.724 } } dps_results: { key: "TestBM-AllItems-EssenceoftheCyclone-65140" value: { - dps: 20233.60656 - tps: 17050.16069 + dps: 20722.68468 + tps: 17548.85406 } } dps_results: { key: "TestBM-AllItems-EternalShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16827.20374 + dps: 20421.4492 + tps: 17240.83564 } } dps_results: { key: "TestBM-AllItems-FallofMortality-59500" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-FallofMortality-65124" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Figurine-DemonPanther-52199" value: { - dps: 20527.78558 - tps: 17321.03445 + dps: 21018.53277 + tps: 17798.3518 } } dps_results: { key: "TestBM-AllItems-Figurine-DreamOwl-52354" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Figurine-EarthenGuardian-52352" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Figurine-JeweledSerpent-52353" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Figurine-KingofBoars-52351" value: { - dps: 19030.86768 - tps: 16015.03469 + dps: 19429.1728 + tps: 16361.58869 } } dps_results: { key: "TestBM-AllItems-FleetShadowspiritDiamond" value: { - dps: 20018.08401 - tps: 16836.99301 + dps: 20444.93079 + tps: 17251.47862 } } dps_results: { key: "TestBM-AllItems-FluidDeath-58181" value: { - dps: 20444.62753 - tps: 17232.88939 + dps: 20968.59429 + tps: 17746.38748 } } dps_results: { key: "TestBM-AllItems-ForlornShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16827.20374 + dps: 20421.4492 + tps: 17240.83564 } } dps_results: { key: "TestBM-AllItems-FuryofAngerforge-59461" value: { - dps: 19204.37185 - tps: 16205.8019 + dps: 19586.13432 + tps: 16560.79395 } } dps_results: { key: "TestBM-AllItems-GaleofShadows-56138" value: { - dps: 19179.72144 - tps: 16138.44791 + dps: 19566.97806 + tps: 16528.96005 } } dps_results: { key: "TestBM-AllItems-GaleofShadows-56462" value: { - dps: 19293.49332 - tps: 16274.52192 + dps: 19543.02512 + tps: 16539.4819 } } dps_results: { key: "TestBM-AllItems-GearDetector-61462" value: { - dps: 19578.71134 - tps: 16504.0418 + dps: 20016.36544 + tps: 16947.92095 } } dps_results: { key: "TestBM-AllItems-Gladiator'sPursuit" value: { - dps: 17933.6661 - tps: 15063.58251 + dps: 18340.60309 + tps: 15467.33277 } } dps_results: { key: "TestBM-AllItems-GlowingTwilightScale-54589" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-GraceoftheHerald-55266" value: { - dps: 19578.04788 - tps: 16517.39864 + dps: 19927.94804 + tps: 16843.26986 } } dps_results: { key: "TestBM-AllItems-GraceoftheHerald-56295" value: { - dps: 19793.64998 - tps: 16658.82121 + dps: 20260.74965 + tps: 17130.04995 } } dps_results: { key: "TestBM-AllItems-HarmlightToken-63839" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Harrison'sInsigniaofPanache-65803" value: { - dps: 18973.1766 - tps: 15988.88566 + dps: 19366.95452 + tps: 16331.85987 } } dps_results: { key: "TestBM-AllItems-HeartofIgnacious-59514" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-HeartofIgnacious-65110" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-HeartofRage-59224" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-HeartofRage-65072" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-HeartofSolace-55868" value: { - dps: 19179.72144 - tps: 16138.44791 + dps: 19566.97806 + tps: 16528.96005 } } dps_results: { key: "TestBM-AllItems-HeartofSolace-56393" value: { - dps: 19293.49332 - tps: 16274.52192 + dps: 19543.02512 + tps: 16539.4819 } } dps_results: { key: "TestBM-AllItems-HeartofThunder-55845" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-HeartofThunder-56370" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-HeartoftheVile-66969" value: { - dps: 19622.65105 - tps: 16563.47958 + dps: 20013.63063 + tps: 16916.90287 } } dps_results: { key: "TestBM-AllItems-Heartpierce-50641" value: { - dps: 20498.4937 - tps: 17285.72848 + dps: 20960.1014 + tps: 17740.74346 } } dps_results: { key: "TestBM-AllItems-ImpassiveShadowspiritDiamond" value: { - dps: 20059.15389 - tps: 16882.05351 + dps: 20497.59522 + tps: 17312.99696 } } dps_results: { key: "TestBM-AllItems-ImpatienceofYouth-62464" value: { - dps: 19044.67834 - tps: 16020.89899 + dps: 19443.72744 + tps: 16368.06061 } } dps_results: { key: "TestBM-AllItems-ImpatienceofYouth-62469" value: { - dps: 19044.67834 - tps: 16020.89899 + dps: 19443.72744 + tps: 16368.06061 } } dps_results: { key: "TestBM-AllItems-ImpetuousQuery-55881" value: { - dps: 19018.20791 - tps: 16009.65907 + dps: 19415.83106 + tps: 16355.6561 } } dps_results: { key: "TestBM-AllItems-ImpetuousQuery-56406" value: { - dps: 19030.86768 - tps: 16015.03469 + dps: 19429.1728 + tps: 16361.58869 } } dps_results: { key: "TestBM-AllItems-InsigniaofDiplomacy-61433" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-InsigniaoftheEarthenLord-61429" value: { - dps: 18995.9574 - tps: 16000.21102 + dps: 19392.38193 + tps: 16345.22913 } } dps_results: { key: "TestBM-AllItems-JarofAncientRemedies-59354" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-JarofAncientRemedies-65029" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-JujuofNimbleness-63840" value: { - dps: 19570.07148 - tps: 16457.73955 + dps: 20009.96051 + tps: 16867.0115 } } dps_results: { key: "TestBM-AllItems-KeytotheEndlessChamber-55795" value: { - dps: 20030.32189 - tps: 16880.5725 + dps: 20459.98842 + tps: 17305.04313 } } dps_results: { key: "TestBM-AllItems-KvaldirBattleStandard-59685" value: { - dps: 19198.56585 - tps: 16183.04991 + dps: 19587.1064 + tps: 16573.29529 } } dps_results: { key: "TestBM-AllItems-KvaldirBattleStandard-59689" value: { - dps: 19198.56585 - tps: 16183.04991 + dps: 19587.1064 + tps: 16573.29529 } } dps_results: { key: "TestBM-AllItems-LadyLa-La'sSingingShell-67152" value: { - dps: 19140.96276 - tps: 16160.86122 + dps: 19527.80885 + tps: 16538.03876 } } dps_results: { key: "TestBM-AllItems-LastWord-50708" value: { - dps: 20388.57547 - tps: 17192.23514 + dps: 20858.65438 + tps: 17660.08244 } } dps_results: { key: "TestBM-AllItems-LeadenDespair-55816" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-LeadenDespair-56347" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-LeftEyeofRajh-56102" value: { - dps: 19694.70955 - tps: 16606.11843 + dps: 20074.27139 + tps: 16946.84843 } } dps_results: { key: "TestBM-AllItems-LeftEyeofRajh-56427" value: { - dps: 19788.33081 - tps: 16666.49077 + dps: 20146.27214 + tps: 17000.90942 } } dps_results: { key: "TestBM-AllItems-LicensetoSlay-58180" value: { - dps: 19573.74729 - tps: 16521.12979 + dps: 19962.05039 + tps: 16888.27238 } } dps_results: { key: "TestBM-AllItems-Lightning-ChargedBattlegear" value: { - dps: 19723.03555 - tps: 16520.52391 + dps: 20127.99391 + tps: 16939.14803 } } dps_results: { key: "TestBM-AllItems-MagnetiteMirror-55814" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-MagnetiteMirror-56345" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-MandalaofStirringPatterns-62467" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-MandalaofStirringPatterns-62472" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-MarkofKhardros-56132" value: { - dps: 19035.50432 - tps: 16020.469 + dps: 19428.28455 + tps: 16360.62503 } } dps_results: { key: "TestBM-AllItems-MarkofKhardros-56458" value: { - dps: 19050.4291 - tps: 16027.2602 + dps: 19443.2571 + tps: 16367.20832 } } dps_results: { key: "TestBM-AllItems-MightoftheOcean-55251" value: { - dps: 19354.61059 - tps: 16316.00987 + dps: 19597.57981 + tps: 16575.47112 } } dps_results: { key: "TestBM-AllItems-MightoftheOcean-56285" value: { - dps: 19518.4798 - tps: 16488.13309 + dps: 19912.5216 + tps: 16870.29698 } } dps_results: { key: "TestBM-AllItems-MirrorofBrokenImages-62466" value: { - dps: 19044.67834 - tps: 16020.89899 + dps: 19443.72744 + tps: 16368.06061 } } dps_results: { key: "TestBM-AllItems-MirrorofBrokenImages-62471" value: { - dps: 19044.67834 - tps: 16020.89899 + dps: 19443.72744 + tps: 16368.06061 } } dps_results: { key: "TestBM-AllItems-MoonwellChalice-70142" value: { - dps: 19079.64115 - tps: 16038.71012 + dps: 19481.41434 + tps: 16387.46386 } } dps_results: { key: "TestBM-AllItems-Oremantle'sFavor-61448" value: { - dps: 19159.02529 - tps: 16170.29906 + dps: 19508.75772 + tps: 16500.26155 } } dps_results: { key: "TestBM-AllItems-PetrifiedTwilightScale-54591" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-PhylacteryoftheNamelessLich-50365" value: { - dps: 19091.97595 - tps: 16114.19373 + dps: 19506.59493 + tps: 16487.26598 } } dps_results: { key: "TestBM-AllItems-PorcelainCrab-55237" value: { - dps: 18968.31814 - tps: 15986.70487 + dps: 19361.58195 + tps: 16330.00158 } } dps_results: { key: "TestBM-AllItems-PorcelainCrab-56280" value: { - dps: 19004.27226 - tps: 16002.08457 + dps: 19396.8486 + tps: 16344.07876 } } dps_results: { key: "TestBM-AllItems-PowerfulShadowspiritDiamond" value: { - dps: 19995.50583 - tps: 16827.20374 + dps: 20421.4492 + tps: 17240.83564 } } dps_results: { key: "TestBM-AllItems-Prestor'sTalismanofMachination-59441" value: { - dps: 20139.70802 - tps: 16947.39125 + dps: 20575.62204 + tps: 17406.34825 } } dps_results: { key: "TestBM-AllItems-Prestor'sTalismanofMachination-65026" value: { - dps: 20081.50638 - tps: 16886.28318 + dps: 20499.47458 + tps: 17297.50642 } } dps_results: { key: "TestBM-AllItems-Rainsong-55854" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Rainsong-56377" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ReverberatingShadowspiritDiamond" value: { - dps: 20219.93165 - tps: 17051.62956 + dps: 20665.47629 + tps: 17484.86273 } } dps_results: { key: "TestBM-AllItems-RevitalizingShadowspiritDiamond" value: { - dps: 20219.93165 - tps: 17051.62956 + dps: 20665.47629 + tps: 17484.86273 } } dps_results: { key: "TestBM-AllItems-RightEyeofRajh-56100" value: { - dps: 19413.92508 - tps: 16388.2145 + dps: 19808.61178 + tps: 16761.31952 } } dps_results: { key: "TestBM-AllItems-RightEyeofRajh-56431" value: { - dps: 19518.4798 - tps: 16488.13309 + dps: 19912.5216 + tps: 16870.29698 } } dps_results: { key: "TestBM-AllItems-Schnottz'sMedallionofCommand-65805" value: { - dps: 19574.25728 - tps: 16490.05914 + dps: 19981.87994 + tps: 16855.75073 } } dps_results: { key: "TestBM-AllItems-SeaStar-55256" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-SeaStar-56290" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Shadowmourne-49623" value: { - dps: 20614.21585 - tps: 17376.41347 + dps: 20995.75288 + tps: 17761.6622 } } dps_results: { key: "TestBM-AllItems-ShardofWoe-60233" value: { - dps: 19287.24451 - tps: 16228.98719 + dps: 19746.81382 + tps: 16677.69756 } } dps_results: { key: "TestBM-AllItems-Shrine-CleansingPurifier-63838" value: { - dps: 19102.58915 - tps: 16110.85011 + dps: 19420.35518 + tps: 16409.26653 } } dps_results: { key: "TestBM-AllItems-Sindragosa'sFlawlessFang-50364" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Skardyn'sGrace-56115" value: { - dps: 19684.14999 - tps: 16558.34683 + dps: 20098.90397 + tps: 16928.92533 } } dps_results: { key: "TestBM-AllItems-Skardyn'sGrace-56440" value: { - dps: 19769.03503 - tps: 16616.59344 + dps: 20204.8082 + tps: 17009.87045 } } dps_results: { key: "TestBM-AllItems-Sorrowsong-55879" value: { - dps: 19018.20791 - tps: 16009.65907 + dps: 19415.83106 + tps: 16355.6561 } } dps_results: { key: "TestBM-AllItems-Sorrowsong-56400" value: { - dps: 19030.86768 - tps: 16015.03469 + dps: 19429.1728 + tps: 16361.58869 } } dps_results: { key: "TestBM-AllItems-Soul'sAnguish-66994" value: { - dps: 19413.92508 - tps: 16388.2145 + dps: 19808.61178 + tps: 16761.31952 } } dps_results: { key: "TestBM-AllItems-SoulCasket-58183" value: { - dps: 19044.67834 - tps: 16020.89899 + dps: 19443.72744 + tps: 16368.06061 } } dps_results: { key: "TestBM-AllItems-Stonemother'sKiss-61411" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-StumpofTime-62465" value: { - dps: 19573.74729 - tps: 16521.12979 + dps: 19962.05039 + tps: 16888.27238 } } dps_results: { key: "TestBM-AllItems-StumpofTime-62470" value: { - dps: 19573.74729 - tps: 16521.12979 + dps: 19962.05039 + tps: 16888.27238 } } dps_results: { key: "TestBM-AllItems-SymbioticWorm-59332" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-SymbioticWorm-65048" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-TalismanofSinisterOrder-65804" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Tank-CommanderInsignia-63841" value: { - dps: 19023.24089 - tps: 16025.22456 + dps: 19419.2705 + tps: 16407.64378 } } dps_results: { key: "TestBM-AllItems-TearofBlood-55819" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-TearofBlood-56351" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-TendrilsofBurrowingDark-55810" value: { - dps: 19004.01362 - tps: 16003.63187 + dps: 19400.87213 + tps: 16349.00441 } } dps_results: { key: "TestBM-AllItems-TendrilsofBurrowingDark-56339" value: { - dps: 19030.86768 - tps: 16015.03469 + dps: 19429.1728 + tps: 16361.58869 } } dps_results: { key: "TestBM-AllItems-Theralion'sMirror-59519" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Theralion'sMirror-65105" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Throngus'sFinger-56121" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Throngus'sFinger-56449" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-Tia'sGrace-55874" value: { - dps: 19757.88765 - tps: 16620.58631 + dps: 20199.81559 + tps: 17028.53534 } } dps_results: { key: "TestBM-AllItems-TinyAbominationinaJar-50706" value: { - dps: 19090.34766 - tps: 16095.97414 + dps: 19490.24174 + tps: 16486.75524 } } dps_results: { key: "TestBM-AllItems-Tyrande'sFavoriteDoll-64645" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-UnheededWarning-59520" value: { - dps: 19844.62269 - tps: 16729.07266 + dps: 20303.08525 + tps: 17152.65449 } } dps_results: { key: "TestBM-AllItems-UnquenchableFlame-67101" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-UnsolvableRiddle-62468" value: { - dps: 20000.53329 - tps: 16816.39744 + dps: 20398.57774 + tps: 17199.77026 } } dps_results: { key: "TestBM-AllItems-UnsolvableRiddle-68709" value: { - dps: 20000.53329 - tps: 16816.39744 + dps: 20398.57774 + tps: 17199.77026 } } dps_results: { key: "TestBM-AllItems-Val'anyr,HammerofAncientKings-46017" value: { - dps: 19124.73741 - tps: 16156.57498 + dps: 19533.69366 + tps: 16539.18835 } } dps_results: { key: "TestBM-AllItems-VialofStolenMemories-59515" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-VialofStolenMemories-65109" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sBadgeofConquest-61033" value: { - dps: 19869.60828 - tps: 16760.08501 + dps: 20263.10349 + tps: 17139.25238 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sBadgeofDominance-61035" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sBadgeofVictory-61034" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sEmblemofAccuracy-61027" value: { - dps: 19471.56702 - tps: 16426.28041 + dps: 19992.22295 + tps: 16915.57534 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sEmblemofAlacrity-61028" value: { - dps: 19353.1795 - tps: 16323.52074 + dps: 19666.58898 + tps: 16652.49801 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sEmblemofCruelty-61026" value: { - dps: 19254.38719 - tps: 16252.96664 + dps: 19628.59217 + tps: 16600.39096 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sEmblemofProficiency-61030" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sEmblemofProwess-61029" value: { - dps: 19051.9673 - tps: 16023.99404 + dps: 19451.40905 + tps: 16371.47635 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sEmblemofTenacity-61032" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sInsigniaofConquest-61047" value: { - dps: 19704.46268 - tps: 16620.67992 + dps: 20163.79311 + tps: 17043.50421 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sInsigniaofDominance-61045" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-ViciousGladiator'sInsigniaofVictory-61046" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-WitchingHourglass-55787" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-WitchingHourglass-56320" value: { - dps: 18921.53328 - tps: 15968.60893 + dps: 19313.94865 + tps: 16310.35268 } } dps_results: { key: "TestBM-AllItems-World-QuellerFocus-63842" value: { - dps: 19005.54813 - tps: 16004.28346 + dps: 19402.48932 + tps: 16349.72351 } } dps_results: { key: "TestBM-AllItems-Za'brox'sLuckyTooth-63742" value: { - dps: 19020.57954 - tps: 16013.6778 + dps: 19413.31199 + tps: 16354.04175 } } dps_results: { key: "TestBM-AllItems-Za'brox'sLuckyTooth-63745" value: { - dps: 19020.57954 - tps: 16013.6778 + dps: 19413.31199 + tps: 16354.04175 } } dps_results: { key: "TestBM-AllItems-Zod'sRepeatingLongbow-50638" value: { - dps: 18973.8388 - tps: 15854.3587 + dps: 19253.22375 + tps: 16107.00785 } } dps_results: { key: "TestBM-Average-Default" value: { - dps: 20232.30366 - tps: 17057.10704 + dps: 20680.87517 + tps: 17498.57841 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 20051.18028 - tps: 17036.98106 + dps: 20513.32322 + tps: 17497.47551 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 20051.18028 - tps: 17036.98106 + dps: 20513.32322 + tps: 17497.47551 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 24195.60015 - tps: 20436.13349 + dps: 24615.86886 + tps: 20857.52722 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 14149.28549 - tps: 12056.28058 + dps: 14412.86465 + tps: 12334.58921 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 14149.28549 - tps: 12056.28058 + dps: 14412.86465 + tps: 12334.58921 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 14929.16015 - tps: 12758.0027 + dps: 15188.89343 + tps: 13013.50466 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm_advanced-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 20051.18028 - tps: 17036.98106 + dps: 20513.32322 + tps: 17497.47551 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm_advanced-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 20051.18028 - tps: 17036.98106 + dps: 20513.32322 + tps: 17497.47551 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm_advanced-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 24195.60015 - tps: 20436.13349 + dps: 24615.86886 + tps: 20857.52722 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm_advanced-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 14149.28549 - tps: 12056.28058 + dps: 14412.86465 + tps: 12334.58921 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm_advanced-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 14149.28549 - tps: 12056.28058 + dps: 14412.86465 + tps: 12334.58921 } } dps_results: { key: "TestBM-Settings-Dwarf-preraid_bm-Basic-bm_advanced-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 14929.16015 - tps: 12758.0027 + dps: 15188.89343 + tps: 13013.50466 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 20388.57547 - tps: 17192.23514 + dps: 20858.65438 + tps: 17660.08244 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 20388.57547 - tps: 17192.23514 + dps: 20858.65438 + tps: 17660.08244 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 24770.49498 - tps: 20747.65386 + dps: 25198.77988 + tps: 21177.12015 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 14394.88528 - tps: 12175.3598 + dps: 14665.30191 + tps: 12460.66525 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 14394.88528 - tps: 12175.3598 + dps: 14665.30191 + tps: 12460.66525 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 15299.21123 - tps: 12975.00639 + dps: 15565.01429 + tps: 13236.36597 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm_advanced-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 20388.57547 - tps: 17192.23514 + dps: 20858.65438 + tps: 17660.08244 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm_advanced-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 20388.57547 - tps: 17192.23514 + dps: 20858.65438 + tps: 17660.08244 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm_advanced-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 24770.49498 - tps: 20747.65386 + dps: 25198.77988 + tps: 21177.12015 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm_advanced-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 14394.88528 - tps: 12175.3598 + dps: 14665.30191 + tps: 12460.66525 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm_advanced-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 14394.88528 - tps: 12175.3598 + dps: 14665.30191 + tps: 12460.66525 } } dps_results: { key: "TestBM-Settings-Orc-preraid_bm-Basic-bm_advanced-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 15299.21123 - tps: 12975.00639 + dps: 15565.01429 + tps: 13236.36597 } } dps_results: { key: "TestBM-SwitchInFrontOfTarget-Default" value: { - dps: 20110.62006 - tps: 16953.38257 + dps: 20575.26552 + tps: 17421.24228 } } diff --git a/sim/hunter/bm_talents.go b/sim/hunter/bm_talents.go new file mode 100644 index 0000000000..e07e28ba95 --- /dev/null +++ b/sim/hunter/bm_talents.go @@ -0,0 +1,382 @@ +package hunter + +import ( + "time" + + "github.com/wowsims/cata/sim/core" +) + +func (hunter *Hunter) ApplyBMTalents() { + if hunter.Talents.ImprovedKillCommand > 0 { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_BonusCrit_Rating, + ClassMask: HunterSpellKillCommand, + FloatValue: (float64(hunter.Talents.ImprovedKillCommand) * 5) * core.CritRatingPerCritChance, + }) + } + hunter.applyKillingStreak() + hunter.applyCobraStrikes() + hunter.applyInvigoration() + hunter.applyFocusFireCD() + hunter.applyFervorCD() + hunter.applySpiritBond() +} + +func (hunter *Hunter) applyCobraStrikes() { + if hunter.Talents.CobraStrikes == 0 || hunter.Pet == nil { + return + } + + actionID := core.ActionID{SpellID: 53260} + procChance := 0.05 * float64(hunter.Talents.CobraStrikes) + + hunter.Pet.CobraStrikesAura = hunter.Pet.RegisterAura(core.Aura{ + Label: "Cobra Strikes", + ActionID: actionID, + Duration: time.Second * 10, + MaxStacks: 2, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + hunter.Pet.focusDump.BonusCritRating += 100 * core.CritRatingPerCritChance + if hunter.Pet.specialAbility != nil { + hunter.Pet.specialAbility.BonusCritRating += 100 * core.CritRatingPerCritChance + } + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + hunter.Pet.focusDump.BonusCritRating -= 100 * core.CritRatingPerCritChance + if hunter.Pet.specialAbility != nil { + hunter.Pet.specialAbility.BonusCritRating -= 100 * core.CritRatingPerCritChance + } + }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.ProcMask.Matches(core.ProcMaskMeleeSpecial | core.ProcMaskSpellDamage) { + aura.RemoveStack(sim) + } + }, + }) + + hunter.RegisterAura(core.Aura{ + Label: "Cobra Strikes", + 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 != hunter.ArcaneShot { // Only arcane shot, but also can proc on non crits + return + } + + if sim.RandomFloat("Cobra Strikes") < procChance { + hunter.Pet.CobraStrikesAura.Activate(sim) + hunter.Pet.CobraStrikesAura.SetStacks(sim, 2) + } + }, + }) +} + +func (hunter *Hunter) applySpiritBond() { + if hunter.Talents.SpiritBond == 0 || hunter.Pet == nil { + return + } + + hunter.PseudoStats.HealingTakenMultiplier *= 1 + 0.05*float64(hunter.Talents.SpiritBond) + hunter.Pet.PseudoStats.HealingTakenMultiplier *= 1 + 0.05*float64(hunter.Talents.SpiritBond) + + actionID := core.ActionID{SpellID: 20895} + healthMultiplier := 0.01 * float64(hunter.Talents.SpiritBond) + healthMetrics := hunter.NewHealthMetrics(actionID) + petHealthMetrics := hunter.Pet.NewHealthMetrics(actionID) + + hunter.RegisterResetEffect(func(sim *core.Simulation) { + core.StartPeriodicAction(sim, core.PeriodicActionOptions{ + Period: time.Second * 10, + OnAction: func(sim *core.Simulation) { + hunter.GainHealth(sim, hunter.MaxHealth()*healthMultiplier, healthMetrics) + hunter.Pet.GainHealth(sim, hunter.Pet.MaxHealth()*healthMultiplier, petHealthMetrics) + }, + }) + }) +} + +func (hunter *Hunter) applyInvigoration() { + if hunter.Talents.Invigoration == 0 || hunter.Pet == nil { + return + } + + focusMetrics := hunter.NewFocusMetrics(core.ActionID{SpellID: 53253}) + + hunter.Pet.RegisterAura(core.Aura{ + Label: "Invigoration", + 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.ProcMask.Matches(core.ProcMaskMeleeSpecial | core.ProcMaskSpellDamage) { + return + } + + if !result.DidCrit() { + return + } + + hunter.AddFocus(sim, 3*float64(hunter.Talents.Invigoration), focusMetrics) + }, + }) +} + +func (hunter *Hunter) registerBestialWrathCD() { + if !hunter.Talents.BestialWrath { + return + } + if hunter.Talents.TheBeastWithin { + hunter.PseudoStats.DamageDealtMultiplier *= 1.1 + } + + actionID := core.ActionID{SpellID: 19574} + + bestialWrathPetAura := hunter.Pet.RegisterAura(core.Aura{ + Label: "Bestial Wrath Pet", + ActionID: actionID, + Duration: time.Second * 10, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.PseudoStats.DamageDealtMultiplier *= 1.2 + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.PseudoStats.DamageDealtMultiplier /= 1.2 + }, + }) + + bestialWrathAura := hunter.RegisterAura(core.Aura{ + Label: "Bestial Wrath", + ActionID: actionID, + Duration: time.Second * 10, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.PseudoStats.DamageDealtMultiplier *= 1.2 + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.PseudoStats.DamageDealtMultiplier /= 1.2 + }, + }) + core.RegisterPercentDamageModifierEffect(bestialWrathAura, 1.2) + + bwSpell := hunter.RegisterSpell(core.SpellConfig{ + ActionID: actionID, + ClassSpellMask: HunterSpellBestialWrath, + FocusCost: core.FocusCostOptions{ + Cost: 0, + }, + Cast: core.CastConfig{ + DefaultCast: core.Cast{ + GCD: 1, + }, + CD: core.Cooldown{ + Timer: hunter.NewTimer(), + Duration: hunter.applyLongevity(time.Minute * 2), + }, + }, + + ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { + bestialWrathPetAura.Activate(sim) + + if hunter.Talents.TheBeastWithin { + bestialWrathAura.Activate(sim) + } + }, + }) + + hunter.AddMajorCooldown(core.MajorCooldown{ + Spell: bwSpell, + Type: core.CooldownTypeDPS, + }) +} + +func (hunter *Hunter) applyFervorCD() { + if !hunter.Talents.Fervor { + return + } + + actionID := core.ActionID{SpellID: 82726} + focusMetrics := hunter.NewFocusMetrics(actionID) + fervorSpell := hunter.RegisterSpell(core.SpellConfig{ + ActionID: actionID, + + FocusCost: core.FocusCostOptions{ + Cost: 0, + }, + Cast: core.CastConfig{ + DefaultCast: core.Cast{ + GCD: 1, + }, + CD: core.Cooldown{ + Timer: hunter.NewTimer(), + Duration: time.Minute * 2, + }, + }, + + ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { + hunter.AddFocus(sim, 50, focusMetrics) + hunter.Pet.AddFocus(sim, 50, focusMetrics) + }, + }) + + hunter.AddMajorCooldown(core.MajorCooldown{ + Spell: fervorSpell, + Type: core.CooldownTypeDPS, + }) +} +func (hunter *Hunter) applyFocusFireCD() { + if !hunter.Talents.FocusFire || hunter.Pet == nil { + return + } + + actionID := core.ActionID{SpellID: 82692} + petFocusMetrics := hunter.Pet.NewFocusMetrics(actionID) + focusFireAura := hunter.RegisterAura(core.Aura{ + Label: "Focus Fire", + ActionID: actionID, + Duration: time.Second * 20, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + hunter.Pet.FrenzyStacksSnapshot = float64(hunter.Pet.FrenzyAura.GetStacks()) + if hunter.Pet.FrenzyStacksSnapshot >= 1 { + hunter.Pet.FrenzyAura.Deactivate(sim) + hunter.Pet.AddFocus(sim, 4, petFocusMetrics) + aura.Unit.MultiplyRangedSpeed(sim, 1+(float64(hunter.Pet.FrenzyStacksSnapshot)*0.03)) + if sim.Log != nil { + hunter.Pet.Log(sim, "Consumed %0f stacks of Frenzy for Focus Fire.", hunter.Pet.FrenzyStacksSnapshot) + } + } + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + if hunter.Pet.FrenzyStacksSnapshot > 0 { + aura.Unit.MultiplyRangedSpeed(sim, 1/(1+(float64(hunter.Pet.FrenzyStacksSnapshot)*0.03))) + } + }, + }) + + focusFireSpell := hunter.RegisterSpell(core.SpellConfig{ + ActionID: actionID, + + FocusCost: core.FocusCostOptions{ + Cost: 0, + }, + Cast: core.CastConfig{ + DefaultCast: core.Cast{ + GCD: 1, + }, + CD: core.Cooldown{ + Timer: hunter.NewTimer(), + Duration: time.Second * 15, + }, + }, + + ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { + if focusFireAura.IsActive() { + focusFireAura.Deactivate(sim) // Want to apply new one + } + focusFireAura.Activate(sim) + //focusFireAura.OnGain(focusFireAura, sim) + }, + }) + + hunter.AddMajorCooldown(core.MajorCooldown{ + Spell: focusFireSpell, + Type: core.CooldownTypeDPS, + }) + +} +func (hunter *Hunter) applyLongevity(dur time.Duration) time.Duration { + return time.Duration(float64(dur) * (1.0 - 0.1*float64(hunter.Talents.Longevity))) +} +func (hunter *Hunter) applyFrenzy() { + if hunter.Talents.Frenzy == 0 { + return + } + actionID := core.ActionID{SpellID: 19622} + hunter.Pet.FrenzyAura = hunter.Pet.RegisterAura(core.Aura{ + Label: "Frenzy", + Duration: time.Second * 10, + ActionID: actionID, + MaxStacks: 5, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.MultiplyMeleeSpeed(sim, 1+(float64(hunter.Talents.Frenzy)*0.02)) + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.MultiplyMeleeSpeed(sim, 1/(1+float64(hunter.Talents.Frenzy)*0.02)) + }, + }) + + hunter.Pet.RegisterAura(core.Aura{ + Label: "FrenzyHandler", + 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.ProcMask.Matches(core.ProcMaskMeleeSpecial | core.ProcMaskSpellDamage) { + return + } + if hunter.Pet.FrenzyAura.IsActive() { + if hunter.Pet.FrenzyAura.GetStacks() != 5 { + hunter.Pet.FrenzyAura.AddStack(sim) + hunter.Pet.FrenzyAura.Refresh(sim) + } + } else { + hunter.Pet.FrenzyAura.Activate(sim) + hunter.Pet.FrenzyAura.SetStacks(sim, 1) + } + }, + }) +} +func (hunter *Hunter) applyKillingStreak() { + if hunter.Talents.KillingStreak == 0 { + return + } + damageMod := hunter.AddDynamicMod(core.SpellModConfig{ + Kind: core.SpellMod_DamageDone_Pct, + ClassMask: HunterSpellKillCommand, + FloatValue: float64(hunter.Talents.KillingStreak) * 0.1, + }) + costMod := hunter.AddDynamicMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Flat, + ClassMask: HunterSpellKillCommand, + FloatValue: -(float64(hunter.Talents.KillingStreak) * 5), + }) + hunter.KillingStreakAura = hunter.RegisterAura(core.Aura{ + Label: "Killing Streak", + ActionID: core.ActionID{SpellID: 82748}, + Duration: core.NeverExpires, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + damageMod.Activate() + costMod.Activate() + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + damageMod.Deactivate() + costMod.Deactivate() + }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell == hunter.KillCommand { + aura.Deactivate(sim) + } + }, + }) + hunter.KillingStreakCounterAura = hunter.RegisterAura(core.Aura{ + Label: "Killing Streak (KC Crit)", + Duration: core.NeverExpires, + MaxStacks: 2, + 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 == hunter.KillCommand { + if aura.GetStacks() == 2 && result.DidCrit() { + hunter.KillingStreakAura.Activate(sim) + aura.SetStacks(sim, 1) + return + } + if result.DidCrit() { + aura.AddStack(sim) + } + } + }, + }) +} diff --git a/sim/hunter/cata_items.go b/sim/hunter/cata_items.go index 503214c14f..bf02a69ff2 100644 --- a/sim/hunter/cata_items.go +++ b/sim/hunter/cata_items.go @@ -12,9 +12,15 @@ var ItemSetLightningChargedBattleGear = core.NewItemSet(core.ItemSet{ Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { // 5% Crit on SS + agent.GetCharacter().AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_BonusCrit_Rating, + ClassMask: HunterSpellSerpentSting, + FloatValue: 5 * core.CritRatingPerCritChance, + }) }, 4: func(agent core.Agent) { // Cobra & Steady Shot < 0.2s cast time + // Cannot be spell modded for now }, }, }) @@ -39,7 +45,7 @@ var ItemSetBloodthirstyGladiatorsPursuit = core.NewItemSet(core.ItemSet{ func (hunter *Hunter) addBloodthirstyGloves() { switch hunter.Hands().ID { - case 64709: //Todo: Add more ids here when needed + case 64991, 64709, 60424, 65544, 70534, 70260, 70441, 72369, 73717, 73583: hunter.AddStaticMod(core.SpellModConfig{ ClassMask: HunterSpellExplosiveTrap | HunterSpellBlackArrow, Kind: core.SpellMod_Cooldown_Flat, diff --git a/sim/hunter/cobra_shot.go b/sim/hunter/cobra_shot.go index 83cdc87fe0..e53981a4c1 100644 --- a/sim/hunter/cobra_shot.go +++ b/sim/hunter/cobra_shot.go @@ -20,6 +20,8 @@ func (hunter *Hunter) registerCobraShotSpell() { Cost: 0, }, MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, Cast: core.CastConfig{ DefaultCast: core.Cast{ GCD: time.Second, diff --git a/sim/hunter/glyphs.go b/sim/hunter/glyphs.go index 4d3ebeccce..f2367222a0 100644 --- a/sim/hunter/glyphs.go +++ b/sim/hunter/glyphs.go @@ -1,11 +1,14 @@ package hunter import ( + "time" + "github.com/wowsims/cata/sim/core" "github.com/wowsims/cata/sim/core/proto" ) func (hunter *Hunter) ApplyGlyphs() { + // Prime Glyphs if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfArcaneShot) { hunter.AddStaticMod(core.SpellModConfig{ Kind: core.SpellMod_DamageDone_Flat, @@ -20,4 +23,61 @@ func (hunter *Hunter) ApplyGlyphs() { FloatValue: 6 * core.CritRatingPerCritChance, }) } + if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfSerpentSting) { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_BonusCrit_Rating, + ClassMask: HunterSpellSerpentSting, + FloatValue: 6 * core.CritRatingPerCritChance, + }) + } + if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfKillCommand) { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Flat, + ClassMask: HunterSpellKillCommand, + FloatValue: -3, + }) + } + if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfChimeraShot) { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_Cooldown_Flat, + ClassMask: HunterSpellChimeraShot, + TimeValue: -time.Second * 1, + }) + } + if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfAimedShot) { + focusMetrics := hunter.NewFocusMetrics(core.ActionID{SpellID: 42897}) + core.MakePermanent(hunter.RegisterAura(core.Aura{ + Label: "Glyph of Aimed Shot", + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell == hunter.AimedShot && result.DidCrit() { + hunter.AddFocus(sim, 5, focusMetrics) + } + }, + })) + } + if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfKillShot) { + icd := core.Cooldown{ + Timer: hunter.NewTimer(), + Duration: time.Second * 6, + } + core.MakePermanent(hunter.RegisterAura(core.Aura{ + Label: "Kill Shot Glyph", + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell == hunter.KillShot { + if icd.IsReady(sim) { + icd.Use(sim) + hunter.KillShot.CD.Reset() + } + } + }, + })) + } + // Major Glyphs + if hunter.HasMajorGlyph(proto.HunterMajorGlyph_GlyphOfBestialWrath) && hunter.Talents.BestialWrath { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_Cooldown_Flat, + ClassMask: HunterSpellBestialWrath, + TimeValue: -time.Second * 20, + }) + } } diff --git a/sim/hunter/hunter.go b/sim/hunter/hunter.go index 036ddd84fb..9c41b71b30 100644 --- a/sim/hunter/hunter.go +++ b/sim/hunter/hunter.go @@ -238,6 +238,10 @@ const ( HunterSpellBlackArrow HunterSpellMultiShot HunterSpellAimedShot + HunterSpellSerpentSting + HunterSpellKillShot + HunterSpellRapidFire + HunterSpellBestialWrath HunterPetFocusDump ) diff --git a/sim/hunter/kill_command.go b/sim/hunter/kill_command.go index dd973a6a92..459e450a5c 100644 --- a/sim/hunter/kill_command.go +++ b/sim/hunter/kill_command.go @@ -4,7 +4,6 @@ import ( "time" "github.com/wowsims/cata/sim/core" - "github.com/wowsims/cata/sim/core/proto" ) func (hunter *Hunter) registerKillCommandSpell() { @@ -22,7 +21,7 @@ func (hunter *Hunter) registerKillCommandSpell() { Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagAPL, FocusCost: core.FocusCostOptions{ - Cost: 40 - core.TernaryFloat64(hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfKillCommand), 3, 0), // Todo: Check if changed by other stuff + Cost: 40, }, Cast: core.CastConfig{ DefaultCast: core.Cast{ @@ -33,7 +32,6 @@ func (hunter *Hunter) registerKillCommandSpell() { Duration: time.Second * 6, }, }, - BonusCritRating: core.CritRatingPerCritChance * (float64(hunter.Talents.ImprovedKillCommand) * 0.05), DamageMultiplierAdditive: 1, CritMultiplier: hunter.CritMultiplier(false, false, false), ThreatMultiplier: 1, diff --git a/sim/hunter/kill_shot.go b/sim/hunter/kill_shot.go index a73414e272..5851bd046a 100644 --- a/sim/hunter/kill_shot.go +++ b/sim/hunter/kill_shot.go @@ -4,39 +4,18 @@ import ( "time" "github.com/wowsims/cata/sim/core" - "github.com/wowsims/cata/sim/core/proto" ) func (hunter *Hunter) registerKillShotSpell() { - if hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfKillShot) { - icd := core.Cooldown{ - Timer: hunter.NewTimer(), - Duration: time.Second * 6, - } - hunter.RegisterAura(core.Aura{ - Label: "Kill Shot Glyph", - 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 == hunter.KillShot { - if icd.IsReady(sim) { - icd.Use(sim) - hunter.KillShot.CD.Reset() - } - } - }, - }) - } - hunter.KillShot = hunter.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 53351}, - SpellSchool: core.SpellSchoolPhysical, - ProcMask: core.ProcMaskRangedSpecial, - Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, - MissileSpeed: 40, - + ActionID: core.ActionID{SpellID: 53351}, + SpellSchool: core.SpellSchoolPhysical, + ProcMask: core.ProcMaskRangedSpecial, + ClassSpellMask: HunterSpellKillShot, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, + MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 0, }, @@ -53,14 +32,10 @@ func (hunter *Hunter) registerKillShotSpell() { ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { return sim.IsExecutePhase20() }, - - BonusCritRating: 0 + 5*core.CritRatingPerCritChance*float64(hunter.Talents.SniperTraining), - DamageMultiplier: 1.5, // + DamageMultiplier: 1.5, CritMultiplier: hunter.CritMultiplier(true, true, false), ThreatMultiplier: 1, - // https://web.archive.org/web/20120207222124/http://elitistjerks.com/f74/t110306-hunter_faq_cataclysm_edition_read_before_asking_questions/ ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - // (100% weapon dmg + 45% RAP + 543) * 150% normalizedWeaponDamage := hunter.AutoAttacks.Ranged().CalculateNormalizedWeaponDamage(sim, spell.RangedAttackPower(target)) rapBonusDamage := spell.RangedAttackPower(target) * 0.45 flatBonus := 543.0 diff --git a/sim/hunter/marksmanship/TestMM.results b/sim/hunter/marksmanship/TestMM.results index f08a104a11..a12ada1c54 100644 --- a/sim/hunter/marksmanship/TestMM.results +++ b/sim/hunter/marksmanship/TestMM.results @@ -733,8 +733,8 @@ dps_results: { dps_results: { key: "TestMM-AllItems-Lightning-ChargedBattlegear" value: { - dps: 21929.8232 - tps: 19925.74169 + dps: 21945.33494 + tps: 19941.25342 } } dps_results: { diff --git a/sim/hunter/marksmanship/aimed_shot.go b/sim/hunter/marksmanship/aimed_shot.go index c619b8b0d1..a8a8228533 100644 --- a/sim/hunter/marksmanship/aimed_shot.go +++ b/sim/hunter/marksmanship/aimed_shot.go @@ -4,22 +4,11 @@ import ( "time" "github.com/wowsims/cata/sim/core" - "github.com/wowsims/cata/sim/core/proto" "github.com/wowsims/cata/sim/hunter" ) func (mmHunter *MarksmanshipHunter) registerAimedShotSpell() { - if mmHunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfAimedShot) { - focusMetrics := mmHunter.NewFocusMetrics(core.ActionID{SpellID: 42897}) - mmHunter.RegisterAura(core.Aura{ - Label: "Glyph of Aimed Shot", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell == mmHunter.AimedShot && result.DidCrit() { - mmHunter.AddFocus(sim, 5, focusMetrics) - } - }, - }) - } + mmHunter.AimedShot = mmHunter.RegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 19434}, SpellSchool: core.SpellSchoolPhysical, diff --git a/sim/hunter/marksmanship/chimera_shot.go b/sim/hunter/marksmanship/chimera_shot.go index 8ea85f1993..d43f3a658a 100644 --- a/sim/hunter/marksmanship/chimera_shot.go +++ b/sim/hunter/marksmanship/chimera_shot.go @@ -4,7 +4,6 @@ import ( "time" "github.com/wowsims/cata/sim/core" - "github.com/wowsims/cata/sim/core/proto" "github.com/wowsims/cata/sim/hunter" ) @@ -32,7 +31,7 @@ func (mmHunter *MarksmanshipHunter) registerChimeraShotSpell() { IgnoreHaste: true, CD: core.Cooldown{ Timer: mmHunter.NewTimer(), - Duration: time.Second*10 - core.TernaryDuration(mmHunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfChimeraShot), time.Second*1, 0), + Duration: time.Second * 10, }, }, diff --git a/sim/hunter/mm_talents.go b/sim/hunter/mm_talents.go new file mode 100644 index 0000000000..df032f9c6c --- /dev/null +++ b/sim/hunter/mm_talents.go @@ -0,0 +1,385 @@ +package hunter + +import ( + "time" + + "github.com/wowsims/cata/sim/core" +) + +func (hunter *Hunter) ApplyMMTalents() { + if hunter.Talents.Efficiency > 0 { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Flat, + ClassMask: HunterSpellArcaneShot, + FloatValue: -float64(hunter.Talents.Efficiency), + }) + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Flat, + ClassMask: HunterSpellExplosiveShot | HunterSpellChimeraShot, + FloatValue: -(float64(hunter.Talents.Efficiency) * 2), + }) + } + if hunter.Talents.CarefulAim > 0 { + caCritMod := hunter.AddDynamicMod(core.SpellModConfig{ + Kind: core.SpellMod_BonusCrit_Rating, + ClassMask: HunterSpellAimedShot | HunterSpellCobraShot | HunterSpellSteadyShot, + FloatValue: (30.0 * float64(hunter.Talents.CarefulAim)) * core.CritRatingPerCritChance, + }) + + hunter.RegisterResetEffect(func(sim *core.Simulation) { + caCritMod.Activate() + sim.RegisterExecutePhaseCallback(func(sim *core.Simulation, isExecute int32) { + caCritMod.Deactivate() + }) + }) + } + + if hunter.Talents.Posthaste > 0 { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_Cooldown_Flat, + ClassMask: HunterSpellRapidFire, + TimeValue: -(time.Minute * time.Duration(hunter.Talents.Posthaste)), + }) + } + hunter.registerSicEm() + hunter.applyPiercingShots() + hunter.applyGoForTheThroat() + hunter.applyImprovedSteadyShot() + hunter.registerReadinessCD() + hunter.applyMasterMarksman() + hunter.applyTermination() + hunter.applyBombardment() +} + +func (hunter *Hunter) applyTermination() { + if hunter.Talents.Termination == 0 { + return + } + + actionID := core.ActionID{SpellID: 83490} + + focusMetrics := hunter.NewFocusMetrics(actionID) + core.MakePermanent(hunter.RegisterAura(core.Aura{ + Label: "Termination", + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if sim.IsExecutePhase25() && spell == hunter.SteadyShot || spell == hunter.CobraShot { + hunter.AddFocus(sim, float64(hunter.Talents.Termination)*3, focusMetrics) + } + }, + })) +} +func (hunter *Hunter) applyBombardment() { + if hunter.Talents.Bombardment == 0 { + return + } + costMod := hunter.AddDynamicMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Pct, + ClassMask: HunterSpellMultiShot, + FloatValue: -(0.25 * float64(hunter.Talents.Bombardment)), + }) + + bombardmentAura := hunter.RegisterAura(core.Aura{ + Label: "Bombardment", + ActionID: core.ActionID{SpellID: 35110}, + Duration: time.Second * 5, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + costMod.Activate() + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + costMod.Deactivate() + }, + }) + + core.MakePermanent(hunter.RegisterAura(core.Aura{ + Label: "Bombardment Proc", + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell == hunter.MultiShot && result.DidCrit() { + bombardmentAura.Activate(sim) + } + }, + })) +} +func (hunter *Hunter) applyMasterMarksman() { + if hunter.Talents.MasterMarksman == 0 { + return + } + costMod := hunter.AddDynamicMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Pct, + ClassMask: HunterSpellAimedShot, + FloatValue: -1, + }) + procChance := float64(hunter.Talents.MasterMarksman) * 0.2 + hunter.MasterMarksmanAura = hunter.RegisterAura(core.Aura{ + Label: "Ready, Set, Aim...", + ActionID: core.ActionID{SpellID: 82925}, + Duration: time.Second * 8, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + if hunter.AimedShot != nil { + costMod.Activate() + hunter.AimedShot.DefaultCast.CastTime = 0 + } + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + if hunter.AimedShot != nil { + costMod.Deactivate() + hunter.AimedShot.DefaultCast.CastTime = time.Second * 3 + } + }, + OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { + if spell == hunter.AimedShot { + hunter.MasterMarksmanCounterAura.SetStacks(sim, 0) + hunter.MasterMarksmanCounterAura.Activate(sim) + aura.Deactivate(sim) // Consume effect + } + + }, + }) + hunter.MasterMarksmanCounterAura = hunter.RegisterAura(core.Aura{ + Label: "Master Marksman", + Duration: time.Second * 30, + ActionID: core.ActionID{SpellID: 34486}, + MaxStacks: 4, + OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { + if spell != hunter.SteadyShot { + return + } + if procChance == 1 || sim.Proc(procChance, "Master Marksman Proc") { + if aura.GetStacks() == 4 { + hunter.MasterMarksmanAura.Activate(sim) + } else { + aura.AddStack(sim) + } + } + }, + }) +} +func (hunter *Hunter) applyPiercingShots() { + if hunter.Talents.PiercingShots == 0 { + return + } + + psSpell := hunter.RegisterSpell(core.SpellConfig{ + ActionID: core.ActionID{SpellID: 53238}, + SpellSchool: core.SpellSchoolPhysical, + ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagIgnoreModifiers, + + DamageMultiplier: 1, + ThreatMultiplier: 1, + + Dot: core.DotConfig{ + Aura: core.Aura{ + Label: "PiercingShots", + Duration: time.Second * 8, + }, + NumberOfTicks: 8, + TickLength: time.Second * 1, + OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { + // Specifically account for bleed modifiers, since it still affects the spell, but we're ignoring all modifiers. + dot.SnapshotAttackerMultiplier = target.PseudoStats.PeriodicPhysicalDamageTakenMultiplier + dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeTick) + + }, + }, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + spell.Dot(target).ApplyOrReset(sim) + spell.CalcAndDealOutcome(sim, target, spell.OutcomeAlwaysHit) + + }, + }) + + hunter.RegisterAura(core.Aura{ + Label: "Piercing Shots Talent", + Duration: core.NeverExpires, + OnReset: func(aura *core.Aura, sim *core.Simulation) { + aura.Activate(sim) + }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if !result.DidCrit() { + return + } + if spell != hunter.AimedShot && spell != hunter.SteadyShot && spell != hunter.ChimeraShot { + return + } + + dot := psSpell.Dot(result.Target) + outstandingDamage := core.TernaryFloat64(dot.IsActive(), dot.SnapshotBaseDamage*float64(dot.NumberOfTicks-dot.TickCount), 0) + newDamage := result.Damage * 0.1 * float64(hunter.Talents.PiercingShots) + + dot.SnapshotBaseDamage = (outstandingDamage + newDamage) / float64(dot.NumberOfTicks) + psSpell.Cast(sim, result.Target) + }, + }) +} + +func (hunter *Hunter) applyGoForTheThroat() { + if hunter.Talents.GoForTheThroat == 0 { + return + } + if hunter.Pet == nil { + return + } + + focusMetrics := hunter.NewFocusMetrics(core.ActionID{SpellID: 34950}) + + amount := 5 * float64(hunter.Talents.GoForTheThroat) + + hunter.RegisterAura(core.Aura{ + Label: "Go for the Throat", + 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.ProcMask.Matches(core.ProcMaskRangedAuto) || !result.DidCrit() { + return + } + if !hunter.Pet.IsEnabled() { + return + } + hunter.Pet.AddFocus(sim, amount, focusMetrics) + }, + }) +} +func (hunter *Hunter) applyImprovedSteadyShot() { + if hunter.Talents.ImprovedSteadyShot == 0 { + return + } + + attackspeedMultiplier := 1 + (float64(hunter.Talents.ImprovedSteadyShot) * 0.05) + hunter.ImprovedSteadyShotAura = hunter.RegisterAura(core.Aura{ + Label: "Improved Steady Shot", + ActionID: core.ActionID{SpellID: 53221, Tag: 1}, + Duration: time.Second * 8, + MaxStacks: 1, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.MultiplyRangedSpeed(sim, attackspeedMultiplier) + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + aura.Unit.MultiplyRangedSpeed(sim, 1/attackspeedMultiplier) + }, + }) + hunter.ImprovedSteadyShotAuraCounter = core.MakePermanent(hunter.RegisterAura(core.Aura{ + Label: "Imp SS Counter", + ActionID: core.ActionID{SpellID: 53221, Tag: 2}, + MaxStacks: 2, + OnApplyEffects: func(aura *core.Aura, sim *core.Simulation, target *core.Unit, spell *core.Spell) { + if spell.ProcMask.Matches(core.ProcMaskRangedAuto) || spell.ActionID.SpellID == 0 || !spell.Flags.Matches(core.SpellFlagAPL) { + return + } + if spell != hunter.SteadyShot { + aura.SetStacks(sim, 1) + } else { + if aura.GetStacks() == 2 { + hunter.ImprovedSteadyShotAura.Activate(sim) + aura.SetStacks(sim, 1) + } else { + aura.SetStacks(sim, 2) + } + } + }, + })) +} +func (hunter *Hunter) registerSicEm() { + if hunter.Talents.SicEm == 0 || hunter.Pet == nil { + return + } + + actionId := core.ActionID{SpellID: 83356} + + sicEmMod := hunter.Pet.AddDynamicMod(core.SpellModConfig{ + Kind: core.SpellMod_PowerCost_Flat, + FloatValue: -(float64(hunter.Talents.SicEm) * 12.5), + ProcMask: core.ProcMaskMeleeMHSpecial, + }) + + sicEmAura := hunter.Pet.RegisterAura(core.Aura{ + ActionID: actionId, + Label: "Sic'Em", + Duration: time.Second * 12, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + sicEmMod.Activate() + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + sicEmMod.Deactivate() + }, + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell.ProcMask == core.ProcMaskMeleeMHSpecial { + aura.Deactivate(sim) + } + }, + }) + + core.MakePermanent(hunter.RegisterAura(core.Aura{ + Label: "Sic'Em Mod", + OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell == hunter.ArcaneShot || spell == hunter.AimedShot || spell == hunter.ExplosiveShot { + if result.DidCrit() { + sicEmAura.Activate(sim) + } + } + }, + OnPeriodicDamageDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + if spell == hunter.ExplosiveShot { + if result.DidCrit() { + sicEmAura.Activate(sim) + } + } + }, + })) +} +func (hunter *Hunter) registerReadinessCD() { + if !hunter.Talents.Readiness { + return + } + + actionID := core.ActionID{SpellID: 23989} + + readinessSpell := hunter.RegisterSpell(core.SpellConfig{ + ActionID: actionID, + + Cast: core.CastConfig{ + DefaultCast: core.Cast{ + GCD: time.Second * 1, + }, + IgnoreHaste: true, // Hunter GCD is locked + CD: core.Cooldown{ + Timer: hunter.NewTimer(), + Duration: time.Minute * 3, + }, + }, + ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { + // Don't use if there are no cooldowns to reset. + return !hunter.RapidFire.IsReady(sim) + }, + + ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { + hunter.RapidFire.CD.Reset() + hunter.KillShot.CD.Reset() + hunter.RaptorStrike.CD.Reset() + hunter.ExplosiveTrap.CD.Reset() + if hunter.KillCommand != nil { + hunter.KillCommand.CD.Reset() + } + if hunter.ChimeraShot != nil { + hunter.ChimeraShot.CD.Reset() + } + if hunter.BlackArrow != nil { + hunter.BlackArrow.CD.Reset() + } + }, + }) + + hunter.AddMajorCooldown(core.MajorCooldown{ + Spell: readinessSpell, + Type: core.CooldownTypeDPS, + ShouldActivate: func(sim *core.Simulation, character *core.Character) bool { + // If RF is about to become ready naturally, wait so we can get 2x usages. + if !hunter.RapidFire.IsReady(sim) && hunter.RapidFire.TimeToReady(sim) < time.Second*10 { + return false + } + return !hunter.RapidFireAura.IsActive() || hunter.RapidFireAura.RemainingDuration(sim) < time.Second*10 + }, + }) +} diff --git a/sim/hunter/multi_shot.go b/sim/hunter/multi_shot.go index 10b140f262..caaae88d04 100644 --- a/sim/hunter/multi_shot.go +++ b/sim/hunter/multi_shot.go @@ -14,7 +14,9 @@ func (hunter *Hunter) registerMultiShotSpell() { ProcMask: core.ProcMaskRangedSpecial, ClassSpellMask: HunterSpellMultiShot, Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, - + MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 40, }, diff --git a/sim/hunter/rapid_fire.go b/sim/hunter/rapid_fire.go index 8d1e5727d4..d409381a30 100644 --- a/sim/hunter/rapid_fire.go +++ b/sim/hunter/rapid_fire.go @@ -40,20 +40,20 @@ func (hunter *Hunter) registerRapidFireCD() { }) hunter.RapidFire = hunter.RegisterSpell(core.SpellConfig{ - ActionID: actionID, - + ActionID: actionID, + ClassSpellMask: HunterSpellRapidFire, FocusCost: core.FocusCostOptions{ Cost: 0, }, Cast: core.CastConfig{ - DefaultCast: core.Cast{ - GCD: 0, - }, CD: core.Cooldown{ Timer: hunter.NewTimer(), - Duration: time.Minute*5 - time.Minute*time.Duration(hunter.Talents.Posthaste), + Duration: time.Minute * 5, }, }, + ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { + return hunter.GCD.IsReady(sim) + }, ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { hunter.RapidFireAura.Activate(sim) }, diff --git a/sim/hunter/serpent_sting.go b/sim/hunter/serpent_sting.go index a442e67825..228b0600b9 100644 --- a/sim/hunter/serpent_sting.go +++ b/sim/hunter/serpent_sting.go @@ -4,22 +4,19 @@ import ( "time" "github.com/wowsims/cata/sim/core" - "github.com/wowsims/cata/sim/core/proto" ) func (hunter *Hunter) registerSerpentStingSpell() { noxiousStingsMultiplier := 1 + 0.05*float64(hunter.Talents.NoxiousStings) - impSSCritChance := float64(hunter.Talents.ImprovedSerpentSting) * 5 - impSSCritChance += core.TernaryFloat64(hunter.HasSetBonus(ItemSetLightningChargedBattleGear, 2), 5, 0) hunter.ImprovedSerpentSting = hunter.RegisterSpell(core.SpellConfig{ ActionID: core.ActionID{SpellID: 82834}, SpellSchool: core.SpellSchoolNature, ProcMask: core.ProcMaskDirect, + ClassSpellMask: HunterSpellSerpentSting, DamageMultiplier: 1, DamageMultiplierAdditive: 1, - BonusCritRating: impSSCritChance + core.TernaryFloat64(hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfSerpentSting), 6, 0)*core.CritRatingPerCritChance, - CritMultiplier: hunter.MeleeCritMultiplier(1, float64(hunter.Talents.Toxicology)*0.5), + CritMultiplier: hunter.MeleeCritMultiplier(1, 0), ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { baseDamage := (460 * 5) + 0.40*spell.RangedAttackPower(target) dmg := baseDamage * (float64(hunter.Talents.ImprovedSerpentSting) * 0.15) @@ -28,11 +25,14 @@ func (hunter *Hunter) registerSerpentStingSpell() { }) hunter.SerpentSting = hunter.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 1978}, - SpellSchool: core.SpellSchoolNature, - ProcMask: core.ProcMaskProc, - Flags: core.SpellFlagAPL, - MissileSpeed: 40, + ActionID: core.ActionID{SpellID: 1978}, + SpellSchool: core.SpellSchoolNature, + ProcMask: core.ProcMaskProc, + ClassSpellMask: HunterSpellSerpentSting, + Flags: core.SpellFlagAPL, + MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 25, }, @@ -42,11 +42,11 @@ func (hunter *Hunter) registerSerpentStingSpell() { }, IgnoreHaste: true, }, - BonusCritRating: impSSCritChance + core.TernaryFloat64(hunter.HasPrimeGlyph(proto.HunterPrimeGlyph_GlyphOfSerpentSting), 6, 0)*core.CritRatingPerCritChance, DamageMultiplierAdditive: 1, + // SS uses Spell Crit which is multiplied by toxicology - CritMultiplier: hunter.SpellCritMultiplier(1, float64(hunter.Talents.Toxicology)*0.5), + CritMultiplier: hunter.SpellCritMultiplier(1, 0), ThreatMultiplier: 1, Dot: core.DotConfig{ diff --git a/sim/hunter/silencing_shot.go b/sim/hunter/silencing_shot.go index 88c5149303..0ef4a54156 100644 --- a/sim/hunter/silencing_shot.go +++ b/sim/hunter/silencing_shot.go @@ -17,7 +17,8 @@ func (hunter *Hunter) registerSilencingShotSpell() { SpellSchool: core.SpellSchoolPhysical, ProcMask: core.ProcMaskRangedSpecial, Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, - + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 0, }, diff --git a/sim/hunter/steady_shot.go b/sim/hunter/steady_shot.go index 7b09d7319a..d59e2b0987 100644 --- a/sim/hunter/steady_shot.go +++ b/sim/hunter/steady_shot.go @@ -18,6 +18,8 @@ func (hunter *Hunter) registerSteadyShotSpell() { ProcMask: core.ProcMaskRangedSpecial, Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 0, diff --git a/sim/hunter/survival/TestSV.results b/sim/hunter/survival/TestSV.results index 5c7be8065c..1a88629aa5 100644 --- a/sim/hunter/survival/TestSV.results +++ b/sim/hunter/survival/TestSV.results @@ -39,1534 +39,1534 @@ character_stats_results: { dps_results: { key: "TestSV-AllItems-AgileShadowspiritDiamond" value: { - dps: 24782.99781 - tps: 22494.194 + dps: 24892.27653 + tps: 22597.11943 } } dps_results: { key: "TestSV-AllItems-Ahn'KaharBloodHunter'sBattlegear" value: { - dps: 20886.24519 - tps: 18952.85779 + dps: 20992.27638 + tps: 19055.33717 } } dps_results: { key: "TestSV-AllItems-Althor'sAbacus-50366" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Anhuur'sHymnal-55889" value: { - dps: 23489.89964 - tps: 21321.53612 + dps: 23606.35616 + tps: 21436.078 } } dps_results: { key: "TestSV-AllItems-Anhuur'sHymnal-56407" value: { - dps: 23570.10942 - tps: 21402.55091 + dps: 23682.32192 + tps: 21512.84875 } } dps_results: { key: "TestSV-AllItems-AustereShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21954.98679 + dps: 24324.05348 + tps: 22050.98782 } } dps_results: { key: "TestSV-AllItems-BaubleofTrueBlood-50726" value: { - dps: 22801.79832 - tps: 20668.37078 + dps: 22916.40304 + tps: 20781.06084 hps: 87.59714 } } dps_results: { key: "TestSV-AllItems-BedrockTalisman-58182" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BellofEnragingResonance-59326" value: { - dps: 23105.01856 - tps: 20939.65117 + dps: 23218.20151 + tps: 21048.9472 } } dps_results: { key: "TestSV-AllItems-BellofEnragingResonance-65053" value: { - dps: 23155.14118 - tps: 20987.15568 + dps: 23266.57918 + tps: 21094.70676 } } dps_results: { key: "TestSV-AllItems-BindingPromise-67037" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BlackBruise-50692" value: { - dps: 23083.11104 - tps: 20947.22195 + dps: 23194.90564 + tps: 21055.06748 } } dps_results: { key: "TestSV-AllItems-Blood-SoakedAleMug-63843" value: { - dps: 23752.89478 - tps: 21544.52014 + dps: 23872.23148 + tps: 21659.53419 } } dps_results: { key: "TestSV-AllItems-BloodofIsiset-55995" value: { - dps: 23008.1538 - tps: 20874.24052 + dps: 23124.16278 + tps: 20988.31139 } } dps_results: { key: "TestSV-AllItems-BloodofIsiset-56414" value: { - dps: 23035.14555 - tps: 20901.17172 + dps: 23151.33842 + tps: 21015.4234 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sBadgeofConquest-64687" value: { - dps: 24206.68828 - tps: 21941.91838 + dps: 24327.32455 + tps: 22058.1261 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sBadgeofDominance-64688" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sBadgeofVictory-64689" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sEmblemofCruelty-64740" value: { - dps: 23093.75458 - tps: 20929.90526 + dps: 23208.04973 + tps: 21040.31349 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sEmblemofMeditation-64741" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sEmblemofTenacity-64742" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sInsigniaofConquest-64761" value: { - dps: 23827.21903 - tps: 21579.30847 + dps: 23942.61374 + tps: 21690.73403 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sInsigniaofDominance-64762" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sInsigniaofVictory-64763" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-BloodthirstyGladiator'sPursuit" value: { - dps: 21961.99925 - tps: 19918.95102 + dps: 22069.48435 + tps: 20022.65117 } } dps_results: { key: "TestSV-AllItems-BottledLightning-66879" value: { - dps: 22911.54337 - tps: 20765.29294 + dps: 23026.21514 + tps: 20876.0778 } } dps_results: { key: "TestSV-AllItems-BracingShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21515.88705 + dps: 24324.05348 + tps: 21609.96807 } } dps_results: { key: "TestSV-AllItems-Bryntroll,theBoneArbiter-50709" value: { - dps: 24784.36946 - tps: 22495.61093 + dps: 24893.64818 + tps: 22598.53637 } } dps_results: { key: "TestSV-AllItems-BurningShadowspiritDiamond" value: { - dps: 24584.64626 - tps: 22316.49724 + dps: 24695.61182 + tps: 22421.13837 } } dps_results: { key: "TestSV-AllItems-ChaoticShadowspiritDiamond" value: { - dps: 24665.11581 - tps: 22387.7755 + dps: 24775.52037 + tps: 22491.85563 } } dps_results: { key: "TestSV-AllItems-CoreofRipeness-58184" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-CorpseTongueCoin-50349" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-CrushingWeight-59506" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-CrushingWeight-65118" value: { - dps: 22791.66274 - tps: 20663.72378 + dps: 22904.7188 + tps: 20774.86518 } } dps_results: { key: "TestSV-AllItems-DarkmoonCard:Earthquake-62048" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-DarkmoonCard:Hurricane-62049" value: { - dps: 23090.81399 - tps: 20946.79961 + dps: 23198.95064 + tps: 21053.02161 } } dps_results: { key: "TestSV-AllItems-DarkmoonCard:Hurricane-62051" value: { - dps: 24087.89191 - tps: 21842.51616 + dps: 24201.92301 + tps: 21952.54596 } } dps_results: { key: "TestSV-AllItems-DarkmoonCard:Tsunami-62050" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-DarkmoonCard:Volcano-62047" value: { - dps: 23070.67486 - tps: 20936.68363 + dps: 23187.06834 + tps: 21051.13257 } } dps_results: { key: "TestSV-AllItems-Deathbringer'sWill-50363" value: { - dps: 23403.89267 - tps: 21209.79015 + dps: 23516.88591 + tps: 21318.79565 } } dps_results: { key: "TestSV-AllItems-DestructiveShadowspiritDiamond" value: { - dps: 24298.47826 - tps: 22022.18776 + dps: 24399.93105 + tps: 22117.67412 } } dps_results: { key: "TestSV-AllItems-DislodgedForeignObject-50348" value: { - dps: 22838.6233 - tps: 20706.78115 + dps: 22955.22194 + tps: 20821.46515 } } dps_results: { key: "TestSV-AllItems-EffulgentShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21954.98679 + dps: 24324.05348 + tps: 22050.98782 } } dps_results: { key: "TestSV-AllItems-ElectrosparkHeartstarter-67118" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-EmberShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21954.98679 + dps: 24324.05348 + tps: 22050.98782 } } dps_results: { key: "TestSV-AllItems-EnigmaticShadowspiritDiamond" value: { - dps: 24298.47826 - tps: 22022.18776 + dps: 24399.93105 + tps: 22117.67412 } } dps_results: { key: "TestSV-AllItems-EssenceoftheCyclone-59473" value: { - dps: 24191.5051 - tps: 21916.31964 + dps: 24307.9339 + tps: 22028.74715 } } dps_results: { key: "TestSV-AllItems-EssenceoftheCyclone-65140" value: { - dps: 24337.70974 - tps: 22045.69339 + dps: 24468.06876 + tps: 22172.03614 } } dps_results: { key: "TestSV-AllItems-EternalShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21954.98679 + dps: 24324.05348 + tps: 22050.98782 } } dps_results: { key: "TestSV-AllItems-FallofMortality-59500" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-FallofMortality-65124" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Figurine-DemonPanther-52199" value: { - dps: 24941.37492 - tps: 22650.36038 + dps: 25059.93778 + tps: 22764.52855 } } dps_results: { key: "TestSV-AllItems-Figurine-DreamOwl-52354" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Figurine-EarthenGuardian-52352" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Figurine-JeweledSerpent-52353" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Figurine-KingofBoars-52351" value: { - dps: 23035.14555 - tps: 20901.17172 + dps: 23151.33842 + tps: 21015.4234 } } dps_results: { key: "TestSV-AllItems-FleetShadowspiritDiamond" value: { - dps: 24269.01496 - tps: 22001.81878 + dps: 24371.25017 + tps: 22098.07189 } } dps_results: { key: "TestSV-AllItems-FluidDeath-58181" value: { - dps: 24867.34702 - tps: 22578.28033 + dps: 24994.22295 + tps: 22701.28634 } } dps_results: { key: "TestSV-AllItems-ForlornShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21954.98679 + dps: 24324.05348 + tps: 22050.98782 } } dps_results: { key: "TestSV-AllItems-FuryofAngerforge-59461" value: { - dps: 23105.01856 - tps: 20939.65117 + dps: 23218.20151 + tps: 21048.9472 } } dps_results: { key: "TestSV-AllItems-GaleofShadows-56138" value: { - dps: 22965.40839 - tps: 20820.73448 + dps: 23085.81357 + tps: 20939.225 } } dps_results: { key: "TestSV-AllItems-GaleofShadows-56462" value: { - dps: 22997.08317 - tps: 20854.95998 + dps: 23105.66949 + tps: 20961.63165 } } dps_results: { key: "TestSV-AllItems-GearDetector-61462" value: { - dps: 23308.57443 - tps: 21117.25499 + dps: 23450.46073 + tps: 21264.71398 } } dps_results: { key: "TestSV-AllItems-Gladiator'sPursuit" value: { - dps: 21417.09087 - tps: 19410.40806 + dps: 21700.4344 + tps: 19683.25229 } } dps_results: { key: "TestSV-AllItems-GlowingTwilightScale-54589" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-GraceoftheHerald-55266" value: { - dps: 23534.10648 - tps: 21325.01427 + dps: 23656.28704 + tps: 21441.28636 } } dps_results: { key: "TestSV-AllItems-GraceoftheHerald-56295" value: { - dps: 23872.45514 - tps: 21628.97289 + dps: 23995.40311 + tps: 21745.96562 } } dps_results: { key: "TestSV-AllItems-HarmlightToken-63839" value: { - dps: 22808.88654 - tps: 20675.46785 + dps: 22923.49125 + tps: 20788.15791 } } dps_results: { key: "TestSV-AllItems-Harrison'sInsigniaofPanache-65803" value: { - dps: 22814.65766 - tps: 20681.20682 + dps: 22929.29188 + tps: 20793.9264 } } dps_results: { key: "TestSV-AllItems-HeartofIgnacious-59514" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-HeartofIgnacious-65110" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-HeartofRage-59224" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-HeartofRage-65072" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-HeartofSolace-55868" value: { - dps: 22965.40839 - tps: 20820.73448 + dps: 23085.81357 + tps: 20939.225 } } dps_results: { key: "TestSV-AllItems-HeartofSolace-56393" value: { - dps: 22997.08317 - tps: 20854.95998 + dps: 23105.66949 + tps: 20961.63165 } } dps_results: { key: "TestSV-AllItems-HeartofThunder-55845" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-HeartofThunder-56370" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-HeartoftheVile-66969" value: { - dps: 23650.24114 - tps: 21428.33732 + dps: 23771.21971 + tps: 21543.38925 } } dps_results: { key: "TestSV-AllItems-Heartpierce-50641" value: { - dps: 24942.97901 - tps: 22638.62103 + dps: 25053.26136 + tps: 22742.52443 } } dps_results: { key: "TestSV-AllItems-ImpassiveShadowspiritDiamond" value: { - dps: 24298.47826 - tps: 22022.18776 + dps: 24399.93105 + tps: 22117.67412 } } dps_results: { key: "TestSV-AllItems-ImpatienceofYouth-62464" value: { - dps: 23064.5911 - tps: 20930.5512 + dps: 23180.98457 + tps: 21045.00014 } } dps_results: { key: "TestSV-AllItems-ImpatienceofYouth-62469" value: { - dps: 23064.5911 - tps: 20930.5512 + dps: 23180.98457 + tps: 21045.00014 } } dps_results: { key: "TestSV-AllItems-ImpetuousQuery-55881" value: { - dps: 23008.1538 - tps: 20874.24052 + dps: 23124.16278 + tps: 20988.31139 } } dps_results: { key: "TestSV-AllItems-ImpetuousQuery-56406" value: { - dps: 23035.14555 - tps: 20901.17172 + dps: 23151.33842 + tps: 21015.4234 } } dps_results: { key: "TestSV-AllItems-InsigniaofDiplomacy-61433" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-InsigniaoftheEarthenLord-61429" value: { - dps: 22960.71375 - tps: 20826.90691 + dps: 23076.39953 + tps: 20940.65997 } } dps_results: { key: "TestSV-AllItems-JarofAncientRemedies-59354" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-JarofAncientRemedies-65029" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-JujuofNimbleness-63840" value: { - dps: 23752.89478 - tps: 21544.52014 + dps: 23872.23148 + tps: 21659.53419 } } dps_results: { key: "TestSV-AllItems-KeytotheEndlessChamber-55795" value: { - dps: 24252.5034 - tps: 22003.35538 + dps: 24382.32288 + tps: 22131.2602 } } dps_results: { key: "TestSV-AllItems-KvaldirBattleStandard-59685" value: { - dps: 22882.7263 - tps: 20754.00144 + dps: 23000.69041 + tps: 20870.0509 } } dps_results: { key: "TestSV-AllItems-KvaldirBattleStandard-59689" value: { - dps: 22882.7263 - tps: 20754.00144 + dps: 23000.69041 + tps: 20870.0509 } } dps_results: { key: "TestSV-AllItems-LadyLa-La'sSingingShell-67152" value: { - dps: 22913.14118 - tps: 20784.52671 + dps: 23022.66371 + tps: 20892.1346 } } dps_results: { key: "TestSV-AllItems-LastWord-50708" value: { - dps: 24782.99781 - tps: 22494.194 + dps: 24892.27653 + tps: 22597.11943 } } dps_results: { key: "TestSV-AllItems-LeadenDespair-55816" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-LeadenDespair-56347" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-LeftEyeofRajh-56102" value: { - dps: 23791.97695 - tps: 21563.38019 + dps: 23910.20993 + tps: 21677.51718 } } dps_results: { key: "TestSV-AllItems-LeftEyeofRajh-56427" value: { - dps: 23923.5773 - tps: 21684.80746 + dps: 24043.57979 + tps: 21798.00729 } } dps_results: { key: "TestSV-AllItems-LicensetoSlay-58180" value: { - dps: 23628.38217 - tps: 21457.56047 + dps: 23745.67277 + tps: 21572.93642 } } dps_results: { key: "TestSV-AllItems-Lightning-ChargedBattlegear" value: { - dps: 23964.62914 - tps: 21789.82998 + dps: 24123.27468 + tps: 21938.40749 } } dps_results: { key: "TestSV-AllItems-MagnetiteMirror-55814" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-MagnetiteMirror-56345" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-MandalaofStirringPatterns-62467" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-MandalaofStirringPatterns-62472" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-MarkofKhardros-56132" value: { - dps: 23028.4659 - tps: 20892.70285 + dps: 23144.21912 + tps: 21006.42412 } } dps_results: { key: "TestSV-AllItems-MarkofKhardros-56458" value: { - dps: 23058.11757 - tps: 20922.05173 + dps: 23174.02119 + tps: 21035.90804 } } dps_results: { key: "TestSV-AllItems-MightoftheOcean-55251" value: { - dps: 23334.73929 - tps: 21181.08547 + dps: 23452.73137 + tps: 21297.1629 } } dps_results: { key: "TestSV-AllItems-MightoftheOcean-56285" value: { - dps: 23570.10942 - tps: 21402.55091 + dps: 23682.32192 + tps: 21512.84875 } } dps_results: { key: "TestSV-AllItems-MirrorofBrokenImages-62466" value: { - dps: 23064.5911 - tps: 20930.5512 + dps: 23180.98457 + tps: 21045.00014 } } dps_results: { key: "TestSV-AllItems-MirrorofBrokenImages-62471" value: { - dps: 23064.5911 - tps: 20930.5512 + dps: 23180.98457 + tps: 21045.00014 } } dps_results: { key: "TestSV-AllItems-MoonwellChalice-70142" value: { - dps: 23133.90787 - tps: 20997.33738 + dps: 23250.86965 + tps: 21112.22625 } } dps_results: { key: "TestSV-AllItems-Oremantle'sFavor-61448" value: { - dps: 23010.676 - tps: 20855.88767 + dps: 23123.36107 + tps: 20964.68583 } } dps_results: { key: "TestSV-AllItems-PetrifiedTwilightScale-54591" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-PhylacteryoftheNamelessLich-50365" value: { - dps: 22959.86395 - tps: 20808.5736 + dps: 23075.14527 + tps: 20921.94028 } } dps_results: { key: "TestSV-AllItems-PorcelainCrab-55237" value: { - dps: 22806.07194 - tps: 20672.6211 + dps: 22920.70748 + tps: 20785.34199 } } dps_results: { key: "TestSV-AllItems-PorcelainCrab-56280" value: { - dps: 22809.32718 - tps: 20675.87634 + dps: 22923.9888 + tps: 20788.62332 } } dps_results: { key: "TestSV-AllItems-PowerfulShadowspiritDiamond" value: { - dps: 24222.086 - tps: 21954.98679 + dps: 24324.05348 + tps: 22050.98782 } } dps_results: { key: "TestSV-AllItems-Prestor'sTalismanofMachination-59441" value: { - dps: 23955.13447 - tps: 21694.45708 + dps: 24059.77721 + tps: 21797.07036 } } dps_results: { key: "TestSV-AllItems-Prestor'sTalismanofMachination-65026" value: { - dps: 24216.52057 - tps: 21936.86971 + dps: 24330.88995 + tps: 22047.22282 } } dps_results: { key: "TestSV-AllItems-Rainsong-55854" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Rainsong-56377" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ReverberatingShadowspiritDiamond" value: { - dps: 24584.64626 - tps: 22316.49724 + dps: 24695.61182 + tps: 22421.13837 } } dps_results: { key: "TestSV-AllItems-RevitalizingShadowspiritDiamond" value: { - dps: 24584.64626 - tps: 22316.49724 + dps: 24695.61182 + tps: 22421.13837 } } dps_results: { key: "TestSV-AllItems-RightEyeofRajh-56100" value: { - dps: 23489.89964 - tps: 21321.53612 + dps: 23606.35616 + tps: 21436.078 } } dps_results: { key: "TestSV-AllItems-RightEyeofRajh-56431" value: { - dps: 23570.10942 - tps: 21402.55091 + dps: 23682.32192 + tps: 21512.84875 } } dps_results: { key: "TestSV-AllItems-Schnottz'sMedallionofCommand-65805" value: { - dps: 23541.93677 - tps: 21332.66579 + dps: 23659.43057 + tps: 21448.20325 } } dps_results: { key: "TestSV-AllItems-SeaStar-55256" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-SeaStar-56290" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Shadowmourne-49623" value: { - dps: 24928.86672 - tps: 22621.69969 + dps: 25052.18452 + tps: 22738.66419 } } dps_results: { key: "TestSV-AllItems-ShardofWoe-60233" value: { - dps: 23010.01601 - tps: 20842.18194 + dps: 23120.83654 + tps: 20951.08782 } } dps_results: { key: "TestSV-AllItems-Shrine-CleansingPurifier-63838" value: { - dps: 22770.02791 - tps: 20631.36574 + dps: 22885.65581 + tps: 20745.07899 } } dps_results: { key: "TestSV-AllItems-Sindragosa'sFlawlessFang-50364" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Skardyn'sGrace-56115" value: { - dps: 23839.31059 - tps: 21622.06897 + dps: 23959.90303 + tps: 21740.58182 } } dps_results: { key: "TestSV-AllItems-Skardyn'sGrace-56440" value: { - dps: 23978.80045 - tps: 21749.53395 + dps: 24098.33054 + tps: 21866.96243 } } dps_results: { key: "TestSV-AllItems-Sorrowsong-55879" value: { - dps: 23008.1538 - tps: 20874.24052 + dps: 23124.16278 + tps: 20988.31139 } } dps_results: { key: "TestSV-AllItems-Sorrowsong-56400" value: { - dps: 23035.14555 - tps: 20901.17172 + dps: 23151.33842 + tps: 21015.4234 } } dps_results: { key: "TestSV-AllItems-Soul'sAnguish-66994" value: { - dps: 23489.89964 - tps: 21321.53612 + dps: 23606.35616 + tps: 21436.078 } } dps_results: { key: "TestSV-AllItems-SoulCasket-58183" value: { - dps: 23064.5911 - tps: 20930.5512 + dps: 23180.98457 + tps: 21045.00014 } } dps_results: { key: "TestSV-AllItems-Stonemother'sKiss-61411" value: { - dps: 22811.48306 - tps: 20676.71768 + dps: 22928.00243 + tps: 20789.40774 } } dps_results: { key: "TestSV-AllItems-StumpofTime-62465" value: { - dps: 23628.38217 - tps: 21457.56047 + dps: 23745.67277 + tps: 21572.93642 } } dps_results: { key: "TestSV-AllItems-StumpofTime-62470" value: { - dps: 23628.38217 - tps: 21457.56047 + dps: 23745.67277 + tps: 21572.93642 } } dps_results: { key: "TestSV-AllItems-SymbioticWorm-59332" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-SymbioticWorm-65048" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-TalismanofSinisterOrder-65804" value: { - dps: 22862.39893 - tps: 20728.782 + dps: 22977.35027 + tps: 20841.81869 } } dps_results: { key: "TestSV-AllItems-Tank-CommanderInsignia-63841" value: { - dps: 22843.18088 - tps: 20718.23515 + dps: 22925.69697 + tps: 20793.58983 } } dps_results: { key: "TestSV-AllItems-TearofBlood-55819" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-TearofBlood-56351" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-TendrilsofBurrowingDark-55810" value: { - dps: 22977.89032 - tps: 20844.04494 + dps: 23093.69312 + tps: 20957.91307 } } dps_results: { key: "TestSV-AllItems-TendrilsofBurrowingDark-56339" value: { - dps: 23035.14555 - tps: 20901.17172 + dps: 23151.33842 + tps: 21015.4234 } } dps_results: { key: "TestSV-AllItems-Theralion'sMirror-59519" value: { - dps: 22810.91476 - tps: 20677.46392 + dps: 22925.51947 + tps: 20790.15399 } } dps_results: { key: "TestSV-AllItems-Theralion'sMirror-65105" value: { - dps: 22842.15831 - tps: 20708.20012 + dps: 22957.19398 + tps: 20821.32114 } } dps_results: { key: "TestSV-AllItems-Throngus'sFinger-56121" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Throngus'sFinger-56449" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-Tia'sGrace-55874" value: { - dps: 23937.46938 - tps: 21710.19807 + dps: 24057.28591 + tps: 21826.10591 } } dps_results: { key: "TestSV-AllItems-TinyAbominationinaJar-50706" value: { - dps: 23059.0136 - tps: 20938.79718 + dps: 23174.47077 + tps: 21052.3397 } } dps_results: { key: "TestSV-AllItems-Tyrande'sFavoriteDoll-64645" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-UnheededWarning-59520" value: { - dps: 23838.14791 - tps: 21597.66568 + dps: 23958.0843 + tps: 21713.60078 } } dps_results: { key: "TestSV-AllItems-UnquenchableFlame-67101" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-UnsolvableRiddle-62468" value: { - dps: 24261.72349 - tps: 21992.87468 + dps: 24382.47453 + tps: 22106.86233 } } dps_results: { key: "TestSV-AllItems-UnsolvableRiddle-68709" value: { - dps: 24261.72349 - tps: 21992.87468 + dps: 24382.47453 + tps: 22106.86233 } } dps_results: { key: "TestSV-AllItems-Val'anyr,HammerofAncientKings-46017" value: { - dps: 23093.72227 - tps: 20948.39585 + dps: 23204.26881 + tps: 21055.00358 } } dps_results: { key: "TestSV-AllItems-VialofStolenMemories-59515" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-VialofStolenMemories-65109" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sBadgeofConquest-61033" value: { - dps: 23985.64859 - tps: 21717.51083 + dps: 24104.54389 + tps: 21829.7467 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sBadgeofDominance-61035" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sBadgeofVictory-61034" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sEmblemofAccuracy-61027" value: { - dps: 23637.74349 - tps: 21472.89987 + dps: 23754.78661 + tps: 21588.02833 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sEmblemofAlacrity-61028" value: { - dps: 23063.20929 - tps: 20896.90017 + dps: 23176.36122 + tps: 21008.13744 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sEmblemofCruelty-61026" value: { - dps: 23127.39741 - tps: 20960.98915 + dps: 23240.53741 + tps: 21070.24224 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sEmblemofProficiency-61030" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sEmblemofProwess-61029" value: { - dps: 23080.1318 - tps: 20946.05704 + dps: 23196.63116 + tps: 21060.61009 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sEmblemofTenacity-61032" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sInsigniaofConquest-61047" value: { - dps: 23894.65626 - tps: 21641.21528 + dps: 24012.06772 + tps: 21756.71208 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sInsigniaofDominance-61045" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-ViciousGladiator'sInsigniaofVictory-61046" value: { - dps: 22802.03497 - tps: 20668.58414 + dps: 22916.63969 + tps: 20781.2742 } } dps_results: { key: "TestSV-AllItems-WitchingHourglass-55787" value: { - dps: 22795.52479 - tps: 20663.57226 + dps: 22905.14682 + tps: 20771.27963 } } dps_results: { key: "TestSV-AllItems-WitchingHourglass-56320" value: { - dps: 22803.50657 - tps: 20674.35414 + dps: 22913.63506 + tps: 20782.56798 } } dps_results: { key: "TestSV-AllItems-World-QuellerFocus-63842" value: { - dps: 22981.16205 - tps: 20847.30933 + dps: 23096.98713 + tps: 20961.19937 } } dps_results: { key: "TestSV-AllItems-Za'brox'sLuckyTooth-63742" value: { - dps: 22998.81423 - tps: 20863.35397 + dps: 23114.41705 + tps: 20976.9402 } } dps_results: { key: "TestSV-AllItems-Za'brox'sLuckyTooth-63745" value: { - dps: 22998.81423 - tps: 20863.35397 + dps: 23114.41705 + tps: 20976.9402 } } dps_results: { key: "TestSV-AllItems-Zod'sRepeatingLongbow-50638" value: { - dps: 23349.72555 - tps: 21109.94244 + dps: 23474.59601 + tps: 21230.70495 } } dps_results: { key: "TestSV-Average-Default" value: { - dps: 24656.07263 - tps: 22368.65771 + dps: 24774.83184 + tps: 22483.14011 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-aoe-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 109636.09053 - tps: 80874.74185 + dps: 316652.57765 + tps: 170591.26108 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-aoe-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 18853.06342 - tps: 16538.81808 + dps: 20085.60348 + tps: 16474.66933 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-aoe-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 22876.30921 - tps: 19646.12255 + dps: 24161.70574 + tps: 19335.12398 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-aoe-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 73575.99293 - tps: 55107.49546 + dps: 222109.91944 + tps: 122468.19744 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-aoe-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 12708.00461 - tps: 11107.35933 + dps: 13655.73104 + tps: 11200.56435 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-aoe-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 13377.16372 - tps: 11542.61251 + dps: 14428.25623 + tps: 11621.64025 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 26839.75553 - tps: 24683.71216 + dps: 26947.12281 + tps: 24787.41887 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 24461.08326 - tps: 22302.16094 + dps: 24569.54717 + tps: 22404.52465 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 30186.01422 - tps: 27328.73884 + dps: 30316.23167 + tps: 27428.45532 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 18488.12367 - tps: 16941.67236 + dps: 18579.63047 + tps: 17029.23922 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 17138.28512 - tps: 15584.99975 + dps: 17219.71891 + tps: 15665.22578 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 18654.78653 - tps: 16878.42574 + dps: 18744.01246 + tps: 16961.61294 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv_advanced-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 26375.40831 - tps: 24234.86041 + dps: 26485.07829 + tps: 24340.93512 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv_advanced-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 24374.43019 - tps: 22236.80839 + dps: 24484.1896 + tps: 22343.03016 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv_advanced-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 29368.03407 - tps: 26674.51879 + dps: 29504.01151 + tps: 26792.80805 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv_advanced-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 18488.12367 - tps: 16941.67236 + dps: 18579.63047 + tps: 17029.23922 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv_advanced-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 17138.28512 - tps: 15584.99975 + dps: 17219.71891 + tps: 15665.22578 } } dps_results: { key: "TestSV-Settings-Dwarf-preraid_sv-Basic-sv_advanced-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 18654.78653 - tps: 16878.42574 + dps: 18744.01246 + tps: 16961.61294 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-aoe-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 110931.4278 - tps: 81756.98394 + dps: 319806.84816 + tps: 172199.4904 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-aoe-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 19154.02141 - tps: 16721.3298 + dps: 20402.52085 + tps: 16659.19925 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-aoe-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 23430.34062 - tps: 20015.25575 + dps: 24730.58767 + tps: 19694.18566 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-aoe-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 74517.96223 - tps: 55770.04047 + dps: 224570.27982 + tps: 123753.56265 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-aoe-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 12931.7897 - tps: 11246.67776 + dps: 13891.02486 + tps: 11341.57557 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-aoe-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 13744.98494 - tps: 11800.30345 + dps: 14814.71295 + tps: 11877.36465 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 27272.76844 - tps: 24986.65241 + dps: 27381.08247 + tps: 25091.13713 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 24782.99781 - tps: 22494.194 + dps: 24892.27653 + tps: 22597.11943 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 30762.16595 - tps: 27715.90288 + dps: 30894.40159 + tps: 27816.37208 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 18810.20635 - tps: 17168.80665 + dps: 18902.68578 + tps: 17257.13518 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 17379.60156 - tps: 15731.22479 + dps: 17461.65759 + tps: 15812.00413 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 19052.30986 - tps: 17153.54345 + dps: 19142.85707 + tps: 17237.70722 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv_advanced-FullBuffs-5.1yards-LongMultiTarget" value: { - dps: 26801.90427 - tps: 24531.91687 + dps: 26912.61024 + tps: 24638.8563 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv_advanced-FullBuffs-5.1yards-LongSingleTarget" value: { - dps: 24696.70871 - tps: 22430.29413 + dps: 24807.25584 + tps: 22537.1349 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv_advanced-FullBuffs-5.1yards-ShortSingleTarget" value: { - dps: 29922.03077 - tps: 27048.9018 + dps: 30059.89461 + tps: 27168.23381 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv_advanced-NoBuffs-5.1yards-LongMultiTarget" value: { - dps: 18810.20635 - tps: 17168.80665 + dps: 18902.68578 + tps: 17257.13518 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv_advanced-NoBuffs-5.1yards-LongSingleTarget" value: { - dps: 17379.60156 - tps: 15731.22479 + dps: 17461.65759 + tps: 15812.00413 } } dps_results: { key: "TestSV-Settings-Orc-preraid_sv-Basic-sv_advanced-NoBuffs-5.1yards-ShortSingleTarget" value: { - dps: 19052.30986 - tps: 17153.54345 + dps: 19142.85707 + tps: 17237.70722 } } dps_results: { key: "TestSV-SwitchInFrontOfTarget-Default" value: { - dps: 24429.80223 - tps: 22172.5622 + dps: 24539.08095 + tps: 22275.48764 } } diff --git a/sim/hunter/survival/black_arrow.go b/sim/hunter/survival/black_arrow.go index bc74e17a17..df4c60a4a7 100644 --- a/sim/hunter/survival/black_arrow.go +++ b/sim/hunter/survival/black_arrow.go @@ -24,6 +24,8 @@ func (svHunter *SurvivalHunter) registerBlackArrowSpell(timer *core.Timer) { Cost: 35, }, MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, Cast: core.CastConfig{ DefaultCast: core.Cast{ GCD: time.Second, @@ -53,7 +55,7 @@ func (svHunter *SurvivalHunter) registerBlackArrowSpell(timer *core.Timer) { rap := dot.Spell.RangedAttackPower(target) percentageOfRAP := 0.0665 dot.SnapshotBaseDamage = baseDamage + (percentageOfRAP * rap) - // SnapshotBaseDamage calculation for the DoT, divided by 10 to spread across all ticks + attackTable := dot.Spell.Unit.AttackTables[target.UnitIndex] dot.SnapshotCritChance = dot.Spell.PhysicalCritChance(attackTable) dot.SnapshotAttackerMultiplier = dot.Spell.AttackerDamageMultiplier(attackTable, true) diff --git a/sim/hunter/survival/explosive_shot.go b/sim/hunter/survival/explosive_shot.go index ec3785e893..270a975486 100644 --- a/sim/hunter/survival/explosive_shot.go +++ b/sim/hunter/survival/explosive_shot.go @@ -18,6 +18,8 @@ func (svHunter *SurvivalHunter) registerExplosiveShotSpell() { ProcMask: core.ProcMaskRangedSpecial, Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, MissileSpeed: 40, + MinRange: 5, + MaxRange: 40, FocusCost: core.FocusCostOptions{ Cost: 50, }, @@ -56,7 +58,7 @@ func (svHunter *SurvivalHunter) registerExplosiveShotSpell() { ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { result := spell.CalcOutcome(sim, target, spell.OutcomeRangedHit) - spell.WaitTravelTime(sim, func(sim *core.Simulation) { // Is this the right way of doing this? + spell.WaitTravelTime(sim, func(sim *core.Simulation) { if result.Landed() { spell.SpellMetrics[target.UnitIndex].Hits-- dot := spell.Dot(target) diff --git a/sim/hunter/survival_talents.go b/sim/hunter/survival_talents.go index ed9c636983..8211214e52 100644 --- a/sim/hunter/survival_talents.go +++ b/sim/hunter/survival_talents.go @@ -40,10 +40,17 @@ func (hunter *Hunter) ApplySurvivalTalents() { if hunter.Talents.Toxicology > 0 { hunter.AddStaticMod(core.SpellModConfig{ Kind: core.SpellMod_CritMultiplier_Pct, - ClassMask: HunterSpellBlackArrow, + ClassMask: HunterSpellBlackArrow | HunterSpellSerpentSting, FloatValue: float64(hunter.Talents.Toxicology) * 0.5, }) } + if hunter.Talents.ImprovedSerpentSting > 0 { + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_BonusCrit_Rating, + ClassMask: HunterSpellSerpentSting, + FloatValue: (float64(hunter.Talents.ImprovedSerpentSting) * 5) * core.CritRatingPerCritChance, + }) + } hunter.applyTNT() hunter.applySniperTraining() @@ -106,6 +113,12 @@ func (hunter *Hunter) applySniperTraining() { }) core.ApplyFixedUptimeAura(stAura, uptime, time.Second*15, 1) + + hunter.AddStaticMod(core.SpellModConfig{ + Kind: core.SpellMod_BonusCrit_Rating, + ClassMask: HunterSpellKillShot, + FloatValue: (5.0 * float64(hunter.Talents.SniperTraining)) * core.CritRatingPerCritChance, + }) } // Todo: Should we support precasting freezing/ice trap? diff --git a/sim/hunter/talents.go b/sim/hunter/talents.go index 5813843473..15fd95e636 100644 --- a/sim/hunter/talents.go +++ b/sim/hunter/talents.go @@ -1,9 +1,6 @@ package hunter import ( - "time" - - "github.com/wowsims/cata/sim/core" "github.com/wowsims/cata/sim/core/proto" "github.com/wowsims/cata/sim/core/stats" ) @@ -18,746 +15,12 @@ func (hunter *Hunter) ApplyTalents() { hunter.Pet.ApplyTalents() } - if hunter.Talents.KillingStreak > 0 { - hunter.applyKillingStreak() - } - - if hunter.Talents.Efficiency > 0 { - hunter.AddStaticMod(core.SpellModConfig{ - Kind: core.SpellMod_PowerCost_Flat, - ClassMask: HunterSpellArcaneShot, - FloatValue: -float64(hunter.Talents.Efficiency), - }) - hunter.AddStaticMod(core.SpellModConfig{ - Kind: core.SpellMod_PowerCost_Flat, - ClassMask: HunterSpellExplosiveShot | HunterSpellChimeraShot, - FloatValue: -(float64(hunter.Talents.Efficiency) * 2), - }) - } - if hunter.Talents.CarefulAim > 0 { - caCritMod := hunter.AddDynamicMod(core.SpellModConfig{ - Kind: core.SpellMod_BonusCrit_Rating, - ClassMask: HunterSpellAimedShot | HunterSpellCobraShot | HunterSpellSteadyShot, - FloatValue: (30.0 * float64(hunter.Talents.CarefulAim)) * core.CritRatingPerCritChance, - }) - - hunter.RegisterResetEffect(func(sim *core.Simulation) { - caCritMod.Activate() - sim.RegisterExecutePhaseCallback(func(sim *core.Simulation, isExecute int32) { - caCritMod.Deactivate() - }) - }) - } - //Apply Survival Talents hunter.ApplySurvivalTalents() - hunter.registerSicEm() - hunter.applyCobraStrikes() - hunter.applyPiercingShots() - hunter.applySpiritBond() - hunter.applyInvigoration() - hunter.applyGoForTheThroat() - hunter.applyImprovedSteadyShot() - hunter.applyFocusFireCD() - hunter.applyFervorCD() - hunter.registerReadinessCD() - hunter.applyMasterMarksman() - hunter.applyTermination() - hunter.applyBombardment() -} - -func (hunter *Hunter) applyBombardment() { - if hunter.Talents.Bombardment == 0 { - return - } - costMod := hunter.AddDynamicMod(core.SpellModConfig{ - Kind: core.SpellMod_PowerCost_Pct, - ClassMask: HunterSpellMultiShot, - FloatValue: -(0.25 * float64(hunter.Talents.Bombardment)), - }) - - bombardmentAura := hunter.RegisterAura(core.Aura{ - Label: "Bombardment", - ActionID: core.ActionID{SpellID: 35110}, - Duration: time.Second * 5, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - costMod.Activate() - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - costMod.Deactivate() - }, - }) - - core.MakePermanent(hunter.RegisterAura(core.Aura{ - Label: "Bombardment Proc", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell == hunter.MultiShot && result.DidCrit() { - bombardmentAura.Activate(sim) - } - }, - })) -} -func (hunter *Hunter) applyMasterMarksman() { - if hunter.Talents.MasterMarksman == 0 { - return - } - costMod := hunter.AddDynamicMod(core.SpellModConfig{ - Kind: core.SpellMod_PowerCost_Pct, - ClassMask: HunterSpellAimedShot, - FloatValue: -1, - }) - procChance := float64(hunter.Talents.MasterMarksman) * 0.2 - hunter.MasterMarksmanAura = hunter.RegisterAura(core.Aura{ - Label: "Ready, Set, Aim...", - ActionID: core.ActionID{SpellID: 82925}, - Duration: time.Second * 8, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - if hunter.AimedShot != nil { - costMod.Activate() - hunter.AimedShot.DefaultCast.CastTime = 0 - } - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - if hunter.AimedShot != nil { - costMod.Deactivate() - hunter.AimedShot.DefaultCast.CastTime = time.Second * 3 - } - }, - OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { - if spell == hunter.AimedShot { - hunter.MasterMarksmanCounterAura.SetStacks(sim, 0) - hunter.MasterMarksmanCounterAura.Activate(sim) - aura.Deactivate(sim) // Consume effect - } - - }, - }) - hunter.MasterMarksmanCounterAura = hunter.RegisterAura(core.Aura{ - Label: "Master Marksman", - Duration: time.Second * 30, - ActionID: core.ActionID{SpellID: 34486}, - MaxStacks: 4, - OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { - if spell != hunter.SteadyShot { - return - } - if procChance == 1 || sim.Proc(procChance, "Master Marksman Proc") { - if aura.GetStacks() == 4 { - hunter.MasterMarksmanAura.Activate(sim) - } else { - aura.AddStack(sim) - } - } - }, - }) -} - -func (hunter *Hunter) applySpiritBond() { - if hunter.Talents.SpiritBond == 0 || hunter.Pet == nil { - return - } - - hunter.PseudoStats.HealingTakenMultiplier *= 1 + 0.05*float64(hunter.Talents.SpiritBond) - hunter.Pet.PseudoStats.HealingTakenMultiplier *= 1 + 0.05*float64(hunter.Talents.SpiritBond) - - actionID := core.ActionID{SpellID: 20895} - healthMultiplier := 0.01 * float64(hunter.Talents.SpiritBond) - healthMetrics := hunter.NewHealthMetrics(actionID) - petHealthMetrics := hunter.Pet.NewHealthMetrics(actionID) - - hunter.RegisterResetEffect(func(sim *core.Simulation) { - core.StartPeriodicAction(sim, core.PeriodicActionOptions{ - Period: time.Second * 10, - OnAction: func(sim *core.Simulation) { - hunter.GainHealth(sim, hunter.MaxHealth()*healthMultiplier, healthMetrics) - hunter.Pet.GainHealth(sim, hunter.Pet.MaxHealth()*healthMultiplier, petHealthMetrics) - }, - }) - }) -} - -func (hunter *Hunter) applyInvigoration() { - if hunter.Talents.Invigoration == 0 || hunter.Pet == nil { - return - } - - focusMetrics := hunter.NewFocusMetrics(core.ActionID{SpellID: 53253}) - - hunter.Pet.RegisterAura(core.Aura{ - Label: "Invigoration", - 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.ProcMask.Matches(core.ProcMaskMeleeSpecial | core.ProcMaskSpellDamage) { - return - } - - if !result.DidCrit() { - return - } - - hunter.AddFocus(sim, 3*float64(hunter.Talents.Invigoration), focusMetrics) - }, - }) -} - -func (hunter *Hunter) applyCobraStrikes() { - if hunter.Talents.CobraStrikes == 0 || hunter.Pet == nil { - return - } - - actionID := core.ActionID{SpellID: 53260} - procChance := 0.05 * float64(hunter.Talents.CobraStrikes) - - hunter.Pet.CobraStrikesAura = hunter.Pet.RegisterAura(core.Aura{ - Label: "Cobra Strikes", - ActionID: actionID, - Duration: time.Second * 10, - MaxStacks: 2, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - hunter.Pet.focusDump.BonusCritRating += 100 * core.CritRatingPerCritChance - if hunter.Pet.specialAbility != nil { - hunter.Pet.specialAbility.BonusCritRating += 100 * core.CritRatingPerCritChance - } - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - hunter.Pet.focusDump.BonusCritRating -= 100 * core.CritRatingPerCritChance - if hunter.Pet.specialAbility != nil { - hunter.Pet.specialAbility.BonusCritRating -= 100 * core.CritRatingPerCritChance - } - }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell.ProcMask.Matches(core.ProcMaskMeleeSpecial | core.ProcMaskSpellDamage) { - aura.RemoveStack(sim) - } - }, - }) - - hunter.RegisterAura(core.Aura{ - Label: "Cobra Strikes", - 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 != hunter.ArcaneShot { // Only arcane shot, but also can proc on non crits - return - } - - if sim.RandomFloat("Cobra Strikes") < procChance { - hunter.Pet.CobraStrikesAura.Activate(sim) - hunter.Pet.CobraStrikesAura.SetStacks(sim, 2) - } - }, - }) -} -func (hunter *Hunter) applyTermination() { - if hunter.Talents.Termination == 0 { - return - } - - actionID := core.ActionID{SpellID: 83490} - - focusMetrics := hunter.NewFocusMetrics(actionID) - core.MakePermanent(hunter.RegisterAura(core.Aura{ - Label: "Termination", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if sim.IsExecutePhase25() && spell == hunter.SteadyShot || spell == hunter.CobraShot { - hunter.AddFocus(sim, float64(hunter.Talents.Termination)*3, focusMetrics) - } - }, - })) -} - -func (hunter *Hunter) applyPiercingShots() { - if hunter.Talents.PiercingShots == 0 { - return - } - - psSpell := hunter.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 53238}, - SpellSchool: core.SpellSchoolPhysical, - ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagIgnoreModifiers, - - DamageMultiplier: 1, - ThreatMultiplier: 1, - - Dot: core.DotConfig{ - Aura: core.Aura{ - Label: "PiercingShots", - Duration: time.Second * 8, - }, - NumberOfTicks: 8, - TickLength: time.Second * 1, - OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { - // Specifically account for bleed modifiers, since it still affects the spell, but we're ignoring all modifiers. - dot.SnapshotAttackerMultiplier = target.PseudoStats.PeriodicPhysicalDamageTakenMultiplier - dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeTick) - - }, - }, - - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - spell.Dot(target).ApplyOrReset(sim) - spell.CalcAndDealOutcome(sim, target, spell.OutcomeAlwaysHit) - - }, - }) - - hunter.RegisterAura(core.Aura{ - Label: "Piercing Shots Talent", - Duration: core.NeverExpires, - OnReset: func(aura *core.Aura, sim *core.Simulation) { - aura.Activate(sim) - }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if !result.DidCrit() { - return - } - if spell != hunter.AimedShot && spell != hunter.SteadyShot && spell != hunter.ChimeraShot { - return - } - - dot := psSpell.Dot(result.Target) - outstandingDamage := core.TernaryFloat64(dot.IsActive(), dot.SnapshotBaseDamage*float64(dot.NumberOfTicks-dot.TickCount), 0) - newDamage := result.Damage * 0.1 * float64(hunter.Talents.PiercingShots) - - dot.SnapshotBaseDamage = (outstandingDamage + newDamage) / float64(dot.NumberOfTicks) - psSpell.Cast(sim, result.Target) - }, - }) -} - -func (hunter *Hunter) applyImprovedSteadyShot() { - if hunter.Talents.ImprovedSteadyShot == 0 { - return - } - - attackspeedMultiplier := 1 + (float64(hunter.Talents.ImprovedSteadyShot) * 0.05) - hunter.ImprovedSteadyShotAura = hunter.RegisterAura(core.Aura{ - Label: "Improved Steady Shot", - ActionID: core.ActionID{SpellID: 53221, Tag: 1}, - Duration: time.Second * 8, - MaxStacks: 1, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.MultiplyRangedSpeed(sim, attackspeedMultiplier) - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.MultiplyRangedSpeed(sim, 1/attackspeedMultiplier) - }, - }) - hunter.ImprovedSteadyShotAuraCounter = core.MakePermanent(hunter.RegisterAura(core.Aura{ - Label: "Imp SS Counter", - ActionID: core.ActionID{SpellID: 53221, Tag: 2}, - MaxStacks: 2, - OnApplyEffects: func(aura *core.Aura, sim *core.Simulation, target *core.Unit, spell *core.Spell) { - if spell.ProcMask.Matches(core.ProcMaskRangedAuto) || spell.ActionID.SpellID == 0 || !spell.Flags.Matches(core.SpellFlagAPL) { - return - } - if spell != hunter.SteadyShot { - aura.SetStacks(sim, 1) - } else { - if aura.GetStacks() == 2 { - hunter.ImprovedSteadyShotAura.Activate(sim) - aura.SetStacks(sim, 1) - } else { - aura.SetStacks(sim, 2) - } - } - }, - })) -} -func (hunter *Hunter) applyKillingStreak() { - if hunter.Talents.KillingStreak == 0 { - return - } - damageMod := hunter.AddDynamicMod(core.SpellModConfig{ - Kind: core.SpellMod_DamageDone_Pct, - ClassMask: HunterSpellKillCommand, - FloatValue: float64(hunter.Talents.KillingStreak) * 0.1, - }) - costMod := hunter.AddDynamicMod(core.SpellModConfig{ - Kind: core.SpellMod_PowerCost_Flat, - ClassMask: HunterSpellKillCommand, - FloatValue: -(float64(hunter.Talents.KillingStreak) * 5), - }) - hunter.KillingStreakAura = hunter.RegisterAura(core.Aura{ - Label: "Killing Streak", - ActionID: core.ActionID{SpellID: 82748}, - Duration: core.NeverExpires, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - damageMod.Activate() - costMod.Activate() - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - damageMod.Deactivate() - costMod.Deactivate() - }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell == hunter.KillCommand { - aura.Deactivate(sim) - } - }, - }) - hunter.KillingStreakCounterAura = hunter.RegisterAura(core.Aura{ - Label: "Killing Streak (KC Crit)", - Duration: core.NeverExpires, - MaxStacks: 2, - 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 == hunter.KillCommand { - if aura.GetStacks() == 2 && result.DidCrit() { - hunter.KillingStreakAura.Activate(sim) - aura.SetStacks(sim, 1) - return - } - if result.DidCrit() { - aura.AddStack(sim) - } - } - }, - }) -} -func (hunter *Hunter) applyFrenzy() { - if hunter.Talents.Frenzy == 0 { - return - } - actionID := core.ActionID{SpellID: 19622} - hunter.Pet.FrenzyAura = hunter.Pet.RegisterAura(core.Aura{ - Label: "Frenzy", - Duration: time.Second * 10, - ActionID: actionID, - MaxStacks: 5, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.MultiplyMeleeSpeed(sim, 1+(float64(hunter.Talents.Frenzy)*0.02)) - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.MultiplyMeleeSpeed(sim, 1/(1+float64(hunter.Talents.Frenzy)*0.02)) - }, - }) - - hunter.Pet.RegisterAura(core.Aura{ - Label: "FrenzyHandler", - 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.ProcMask.Matches(core.ProcMaskMeleeSpecial | core.ProcMaskSpellDamage) { - return - } - if hunter.Pet.FrenzyAura.IsActive() { - if hunter.Pet.FrenzyAura.GetStacks() != 5 { - hunter.Pet.FrenzyAura.AddStack(sim) - hunter.Pet.FrenzyAura.Refresh(sim) - } - } else { - hunter.Pet.FrenzyAura.Activate(sim) - hunter.Pet.FrenzyAura.SetStacks(sim, 1) - } - }, - }) -} - -func (hunter *Hunter) applyLongevity(dur time.Duration) time.Duration { - return time.Duration(float64(dur) * (1.0 - 0.1*float64(hunter.Talents.Longevity))) -} - -func (hunter *Hunter) applyFocusFireCD() { - if !hunter.Talents.FocusFire || hunter.Pet == nil { - return - } - - actionID := core.ActionID{SpellID: 82692} - petFocusMetrics := hunter.Pet.NewFocusMetrics(actionID) - focusFireAura := hunter.RegisterAura(core.Aura{ - Label: "Focus Fire", - ActionID: actionID, - Duration: time.Second * 20, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - hunter.Pet.FrenzyStacksSnapshot = float64(hunter.Pet.FrenzyAura.GetStacks()) - if hunter.Pet.FrenzyStacksSnapshot >= 1 { - hunter.Pet.FrenzyAura.Deactivate(sim) - hunter.Pet.AddFocus(sim, 4, petFocusMetrics) - aura.Unit.MultiplyRangedSpeed(sim, 1+(float64(hunter.Pet.FrenzyStacksSnapshot)*0.03)) - if sim.Log != nil { - hunter.Pet.Log(sim, "Consumed %0f stacks of Frenzy for Focus Fire.", hunter.Pet.FrenzyStacksSnapshot) - } - } - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - if hunter.Pet.FrenzyStacksSnapshot > 0 { - aura.Unit.MultiplyRangedSpeed(sim, 1/(1+(float64(hunter.Pet.FrenzyStacksSnapshot)*0.03))) - } - }, - }) - - focusFireSpell := hunter.RegisterSpell(core.SpellConfig{ - ActionID: actionID, - - FocusCost: core.FocusCostOptions{ - Cost: 0, - }, - Cast: core.CastConfig{ - DefaultCast: core.Cast{ - GCD: 1, - }, - CD: core.Cooldown{ - Timer: hunter.NewTimer(), - Duration: time.Second * 15, - }, - }, - - ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { - if focusFireAura.IsActive() { - focusFireAura.Deactivate(sim) // Want to apply new one - } - focusFireAura.Activate(sim) - //focusFireAura.OnGain(focusFireAura, sim) - }, - }) - - hunter.AddMajorCooldown(core.MajorCooldown{ - Spell: focusFireSpell, - Type: core.CooldownTypeDPS, - }) - -} -func (hunter *Hunter) applyFervorCD() { - if !hunter.Talents.Fervor { - return - } - - actionID := core.ActionID{SpellID: 82726} - focusMetrics := hunter.NewFocusMetrics(actionID) - fervorSpell := hunter.RegisterSpell(core.SpellConfig{ - ActionID: actionID, - - FocusCost: core.FocusCostOptions{ - Cost: 0, - }, - Cast: core.CastConfig{ - DefaultCast: core.Cast{ - GCD: 1, - }, - CD: core.Cooldown{ - Timer: hunter.NewTimer(), - Duration: time.Minute * 2, - }, - }, - - ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { - hunter.AddFocus(sim, 50, focusMetrics) - hunter.Pet.AddFocus(sim, 50, focusMetrics) - }, - }) - - hunter.AddMajorCooldown(core.MajorCooldown{ - Spell: fervorSpell, - Type: core.CooldownTypeDPS, - }) -} -func (hunter *Hunter) registerBestialWrathCD() { - if !hunter.Talents.BestialWrath { - return - } - if hunter.Talents.TheBeastWithin { - hunter.PseudoStats.DamageDealtMultiplier *= 1.1 - } - - actionID := core.ActionID{SpellID: 19574} - - bestialWrathPetAura := hunter.Pet.RegisterAura(core.Aura{ - Label: "Bestial Wrath Pet", - ActionID: actionID, - Duration: time.Second * 10, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.PseudoStats.DamageDealtMultiplier *= 1.2 - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.PseudoStats.DamageDealtMultiplier /= 1.2 - }, - }) - - bestialWrathAura := hunter.RegisterAura(core.Aura{ - Label: "Bestial Wrath", - ActionID: actionID, - Duration: time.Second * 10, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.PseudoStats.DamageDealtMultiplier *= 1.2 - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - aura.Unit.PseudoStats.DamageDealtMultiplier /= 1.2 - }, - }) - core.RegisterPercentDamageModifierEffect(bestialWrathAura, 1.2) - - bwSpell := hunter.RegisterSpell(core.SpellConfig{ - ActionID: actionID, - - FocusCost: core.FocusCostOptions{ - Cost: 0, - }, - Cast: core.CastConfig{ - DefaultCast: core.Cast{ - GCD: 1, - }, - CD: core.Cooldown{ - Timer: hunter.NewTimer(), - Duration: hunter.applyLongevity(time.Minute*2 - core.TernaryDuration(hunter.HasMajorGlyph(proto.HunterMajorGlyph_GlyphOfBestialWrath), time.Second*20, 0)), - }, - }, - - ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { - bestialWrathPetAura.Activate(sim) - - if hunter.Talents.TheBeastWithin { - bestialWrathAura.Activate(sim) - } - }, - }) - - hunter.AddMajorCooldown(core.MajorCooldown{ - Spell: bwSpell, - Type: core.CooldownTypeDPS, - }) -} - -func (hunter *Hunter) applyGoForTheThroat() { - if hunter.Talents.GoForTheThroat == 0 { - return - } - if hunter.Pet == nil { - return - } - - focusMetrics := hunter.NewFocusMetrics(core.ActionID{SpellID: 34950}) - - amount := 5 * float64(hunter.Talents.GoForTheThroat) - - hunter.RegisterAura(core.Aura{ - Label: "Go for the Throat", - 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.ProcMask.Matches(core.ProcMaskRangedAuto) || !result.DidCrit() { - return - } - if !hunter.Pet.IsEnabled() { - return - } - hunter.Pet.AddFocus(sim, amount, focusMetrics) - }, - }) -} - -func (hunter *Hunter) registerSicEm() { - if hunter.Talents.SicEm == 0 || hunter.Pet == nil { - return - } - - actionId := core.ActionID{SpellID: 83356} - - sicEmMod := hunter.Pet.AddDynamicMod(core.SpellModConfig{ - Kind: core.SpellMod_PowerCost_Flat, - FloatValue: -(float64(hunter.Talents.SicEm) * 12.5), - ProcMask: core.ProcMaskMeleeMHSpecial, - }) - - sicEmAura := hunter.Pet.RegisterAura(core.Aura{ - ActionID: actionId, - Label: "Sic'Em", - Duration: time.Second * 12, - OnGain: func(aura *core.Aura, sim *core.Simulation) { - sicEmMod.Activate() - }, - OnExpire: func(aura *core.Aura, sim *core.Simulation) { - sicEmMod.Deactivate() - }, - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell.ProcMask == core.ProcMaskMeleeMHSpecial { - aura.Deactivate(sim) - } - }, - }) - - core.MakePermanent(hunter.RegisterAura(core.Aura{ - Label: "Sic'Em Mod", - OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell == hunter.ArcaneShot || spell == hunter.AimedShot || spell == hunter.ExplosiveShot { - if result.DidCrit() { - sicEmAura.Activate(sim) - } - } - }, - OnPeriodicDamageDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { - if spell == hunter.ExplosiveShot { - if result.DidCrit() { - sicEmAura.Activate(sim) - } - } - }, - })) -} -func (hunter *Hunter) registerReadinessCD() { - if !hunter.Talents.Readiness { - return - } - - actionID := core.ActionID{SpellID: 23989} - - readinessSpell := hunter.RegisterSpell(core.SpellConfig{ - ActionID: actionID, - - Cast: core.CastConfig{ - DefaultCast: core.Cast{ - GCD: time.Second * 1, - }, - IgnoreHaste: true, // Hunter GCD is locked - CD: core.Cooldown{ - Timer: hunter.NewTimer(), - Duration: time.Minute * 3, - }, - }, - ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { - // Don't use if there are no cooldowns to reset. - return !hunter.RapidFire.IsReady(sim) - }, - - ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) { - hunter.RapidFire.CD.Reset() - hunter.KillShot.CD.Reset() - hunter.RaptorStrike.CD.Reset() - hunter.ExplosiveTrap.CD.Reset() - if hunter.KillCommand != nil { - hunter.KillCommand.CD.Reset() - } - if hunter.ChimeraShot != nil { - hunter.ChimeraShot.CD.Reset() - } - if hunter.BlackArrow != nil { - hunter.BlackArrow.CD.Reset() - } - }, - }) + //Apply MM Talents + hunter.ApplyMMTalents() - hunter.AddMajorCooldown(core.MajorCooldown{ - Spell: readinessSpell, - Type: core.CooldownTypeDPS, - ShouldActivate: func(sim *core.Simulation, character *core.Character) bool { - // If RF is about to become ready naturally, wait so we can get 2x usages. - if !hunter.RapidFire.IsReady(sim) && hunter.RapidFire.TimeToReady(sim) < time.Second*10 { - return false - } - return !hunter.RapidFireAura.IsActive() || hunter.RapidFireAura.RemainingDuration(sim) < time.Second*10 - }, - }) + //Apply BM Talents + hunter.ApplyBMTalents() } diff --git a/ui/core/launched_sims.ts b/ui/core/launched_sims.ts index ccbbe1f148..279bb265df 100644 --- a/ui/core/launched_sims.ts +++ b/ui/core/launched_sims.ts @@ -57,15 +57,15 @@ export const simLaunchStatuses: Record = { // Hunter [Spec.SpecBeastMasteryHunter]: { phase: Phase.Phase1, - status: LaunchStatus.Alpha, + status: LaunchStatus.Beta, }, [Spec.SpecMarksmanshipHunter]: { phase: Phase.Phase1, - status: LaunchStatus.Alpha, + status: LaunchStatus.Beta, }, [Spec.SpecSurvivalHunter]: { phase: Phase.Phase1, - status: LaunchStatus.Alpha, + status: LaunchStatus.Beta, }, // Mage [Spec.SpecArcaneMage]: { diff --git a/ui/index.html b/ui/index.html index 15fb747a11..753079956d 100644 --- a/ui/index.html +++ b/ui/index.html @@ -278,7 +278,7 @@

Cataclysm

Hunter - Alpha + Beta
@@ -290,7 +290,7 @@

Cataclysm

Hunter Beast mastery - Alpha + Beta
@@ -302,7 +302,7 @@

Cataclysm

Hunter Marksmanship - Alpha + Beta
@@ -314,7 +314,7 @@

Cataclysm

Hunter Survival - Alpha + Beta