diff --git a/proto/api.proto b/proto/api.proto index 1be1bf8877..df2d9d3019 100644 --- a/proto/api.proto +++ b/proto/api.proto @@ -316,6 +316,7 @@ message SpellStats { bool has_shield = 6; // Whether this spell applies a shield effect. bool prepull_only = 5; // Whether this spell may only be cast during prepull. bool encounter_only = 8; // Whether this spell may only be cast during the encounter (not prepull). + bool has_cast_time = 9; // Whether this spell has a cast time or not. } message APLActionStats { repeated string warnings = 1; diff --git a/proto/apl.proto b/proto/apl.proto index d17be22e16..9c2f4087e8 100644 --- a/proto/apl.proto +++ b/proto/apl.proto @@ -76,7 +76,7 @@ message APLAction { } } -// NextIndex: 64 +// NextIndex: 66 message APLValue { oneof value { // Operators @@ -97,6 +97,10 @@ message APLValue { APLValueIsExecutePhase is_execute_phase = 41; APLValueNumberTargets number_targets = 28; + // Boss values + APLValueBossSpellTimeToReady boss_spell_time_to_ready = 64; + APLValueBossSpellIsCasting boss_spell_is_casting = 65; + // Resource values APLValueCurrentHealth current_health = 26; APLValueCurrentHealthPercent current_health_percent = 27; @@ -321,6 +325,16 @@ message APLValueIsExecutePhase { ExecutePhaseThreshold threshold = 1; } +message APLValueBossSpellTimeToReady { + UnitReference target_unit = 1; + ActionID spell_id = 2; +} + +message APLValueBossSpellIsCasting { + UnitReference target_unit = 1; + ActionID spell_id = 2; +} + message APLValueCurrentHealth { UnitReference source_unit = 1; } diff --git a/sim/core/apl_helpers.go b/sim/core/apl_helpers.go index fd3bf3f36e..faff038232 100644 --- a/sim/core/apl_helpers.go +++ b/sim/core/apl_helpers.go @@ -157,6 +157,17 @@ func (rot *APLRotation) GetAPLSpell(spellId *proto.ActionID) *Spell { return spell } +func (rot *APLRotation) GetTargetAPLSpell(spellId *proto.ActionID, targetUnit UnitReference) *Spell { + actionID := ProtoToActionID(spellId) + target := targetUnit.Get() + spell := target.GetSpell(actionID) + + if spell == nil { + rot.ValidationWarning("%s does not know spell %s", target.Label, actionID) + } + return spell +} + func (rot *APLRotation) GetAPLDot(targetUnit UnitReference, spellId *proto.ActionID) *Dot { spell := rot.GetAPLSpell(spellId) diff --git a/sim/core/apl_value.go b/sim/core/apl_value.go index 7d0646f499..25381b1f78 100644 --- a/sim/core/apl_value.go +++ b/sim/core/apl_value.go @@ -94,6 +94,12 @@ func (rot *APLRotation) newAPLValue(config *proto.APLValue) APLValue { case *proto.APLValue_NumberTargets: return rot.newValueNumberTargets(config.GetNumberTargets()) + // Boss + case *proto.APLValue_BossSpellIsCasting: + return rot.newValueBossSpellIsCasting(config.GetBossSpellIsCasting()) + case *proto.APLValue_BossSpellTimeToReady: + return rot.newValueBossSpellTimeToReady(config.GetBossSpellTimeToReady()) + // Resources case *proto.APLValue_CurrentHealth: return rot.newValueCurrentHealth(config.GetCurrentHealth()) diff --git a/sim/core/apl_values_boss.go b/sim/core/apl_values_boss.go new file mode 100644 index 0000000000..e44227aa88 --- /dev/null +++ b/sim/core/apl_values_boss.go @@ -0,0 +1,56 @@ +package core + +import ( + "fmt" + "time" + + "github.com/wowsims/wotlk/sim/core/proto" +) + +type APLValueBossSpellIsCasting struct { + DefaultAPLValueImpl + spell *Spell +} + +func (rot *APLRotation) newValueBossSpellIsCasting(config *proto.APLValueBossSpellIsCasting) APLValue { + spell := rot.GetTargetAPLSpell(config.SpellId, rot.GetTargetUnit(config.TargetUnit)) + if spell == nil { + return nil + } + return &APLValueBossSpellIsCasting{ + spell: spell, + } +} +func (value *APLValueBossSpellIsCasting) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeBool +} +func (value *APLValueBossSpellIsCasting) GetBool(sim *Simulation) bool { + return value.spell.Unit.Hardcast.ActionID == value.spell.ActionID && value.spell.Unit.Hardcast.Expires > sim.CurrentTime +} +func (value *APLValueBossSpellIsCasting) String() string { + return fmt.Sprintf("Boss is Casting(%s)", value.spell.ActionID) +} + +type APLValueBossSpellTimeToReady struct { + DefaultAPLValueImpl + spell *Spell +} + +func (rot *APLRotation) newValueBossSpellTimeToReady(config *proto.APLValueBossSpellTimeToReady) APLValue { + spell := rot.GetTargetAPLSpell(config.SpellId, rot.GetTargetUnit(config.TargetUnit)) + if spell == nil { + return nil + } + return &APLValueBossSpellTimeToReady{ + spell: spell, + } +} +func (value *APLValueBossSpellTimeToReady) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeDuration +} +func (value *APLValueBossSpellTimeToReady) GetDuration(sim *Simulation) time.Duration { + return value.spell.TimeToReady(sim) +} +func (value *APLValueBossSpellTimeToReady) String() string { + return fmt.Sprintf("Boss Spell Time to Ready(%s)", value.spell.ActionID) +} diff --git a/sim/core/character.go b/sim/core/character.go index 4e76833981..8c5e848bcc 100644 --- a/sim/core/character.go +++ b/sim/core/character.go @@ -467,6 +467,14 @@ func (character *Character) Finalize() { character.Unit.finalize() + // For now, restrict this optimization to rogues only. Ferals will require + // some extra logic to handle their ExcessEnergy() calc. + if character.Class == proto.Class_ClassRogue { + character.Env.RegisterPostFinalizeEffect(func() { + character.energyBar.setupEnergyThresholds() + }) + } + character.majorCooldownManager.finalize() character.ItemSwap.finalize() } diff --git a/sim/core/unit.go b/sim/core/unit.go index 54f327445b..cdec1ee4a1 100644 --- a/sim/core/unit.go +++ b/sim/core/unit.go @@ -443,15 +443,6 @@ func (unit *Unit) finalize() { for _, spell := range unit.Spellbook { spell.finalize() } - - // For now, restrict this optimization to rogues only. Ferals will require - // some extra logic to handle their ExcessEnergy() calc. - agent := unit.Env.Raid.GetPlayerFromUnit(unit) - if agent != nil && agent.GetCharacter().Class == proto.Class_ClassRogue { - unit.Env.RegisterPostFinalizeEffect(func() { - unit.energyBar.setupEnergyThresholds() - }) - } } func (unit *Unit) reset(sim *Simulation, _ Agent) { @@ -545,6 +536,7 @@ func (unit *Unit) GetMetadata() *proto.UnitMetadata { HasShield: spell.shields != nil || spell.selfShield != nil, PrepullOnly: spell.Flags.Matches(SpellFlagPrepullOnly), EncounterOnly: spell.Flags.Matches(SpellFlagEncounterOnly), + HasCastTime: spell.DefaultCast.CastTime > 0, } }) @@ -563,7 +555,7 @@ func (unit *Unit) GetMetadata() *proto.UnitMetadata { return metadata } -func (unit *Unit) StartAPLLoop(sim *Simulation) { +func (unit *Unit) StartAPLLoop(_ *Simulation) { if unit.HasManaBar() { unit.ManaRequired = 0 } diff --git a/sim/druid/feral/TestFeralApl.results b/sim/druid/feral/TestFeralApl.results new file mode 100644 index 0000000000..40bdfbed07 --- /dev/null +++ b/sim/druid/feral/TestFeralApl.results @@ -0,0 +1,1001 @@ +character_stats_results: { + key: "TestFeralApl-CharacterStats-Default" + value: { + final_stats: 491.18916 + final_stats: 2188.3488 + final_stats: 2143.7493 + final_stats: 385.33968 + final_stats: 394.85424 + final_stats: 500 + final_stats: 125 + final_stats: 230 + final_stats: 1315.66126 + final_stats: 469 + final_stats: 0 + final_stats: 12469.20382 + final_stats: 230 + final_stats: 3152.25975 + final_stats: 469 + final_stats: 605 + final_stats: 220.97496 + final_stats: 8996.0952 + final_stats: 0 + final_stats: 0 + final_stats: 11142.1976 + final_stats: 3330.8 + final_stats: 0 + final_stats: 0 + final_stats: 0 + final_stats: 2069.58472 + final_stats: 0 + final_stats: 0 + final_stats: 29045.343 + final_stats: 75 + final_stats: 75 + final_stats: 75 + final_stats: 75 + final_stats: 130 + final_stats: 0 + final_stats: 0 + final_stats: 0 + final_stats: 0 + final_stats: 0 + final_stats: 0 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Althor'sAbacus-50359" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Althor'sAbacus-50366" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-AshtongueTalismanofEquilibrium-32486" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-AustereEarthsiegeDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Bandit'sInsignia-40371" + value: { + dps: 11053.54068 + tps: 7908.21715 + } +} +dps_results: { + key: "TestFeralApl-AllItems-BaubleofTrueBlood-50354" + value: { + dps: 10853.70661 + tps: 7766.6341 + hps: 91.80479 + } +} +dps_results: { + key: "TestFeralApl-AllItems-BaubleofTrueBlood-50726" + value: { + dps: 10853.70661 + tps: 7766.6341 + hps: 91.80479 + } +} +dps_results: { + key: "TestFeralApl-AllItems-BeamingEarthsiegeDiamond" + value: { + dps: 11169.92198 + tps: 7991.2218 + } +} +dps_results: { + key: "TestFeralApl-AllItems-BlessedRegaliaofUndeadCleansing" + value: { + dps: 8367.89573 + tps: 5999.83872 + } +} +dps_results: { + key: "TestFeralApl-AllItems-BracingEarthsiegeDiamond" + value: { + dps: 11134.55244 + tps: 7806.86053 + } +} +dps_results: { + key: "TestFeralApl-AllItems-BrutalGladiator'sIdolofResolve-35019" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ChaoticSkyflareDiamond" + value: { + dps: 11442.28988 + tps: 8184.60302 + } +} +dps_results: { + key: "TestFeralApl-AllItems-CorpseTongueCoin-50349" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-CorpseTongueCoin-50352" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-CorrodedSkeletonKey-50356" + value: { + dps: 10853.70661 + tps: 7766.6341 + hps: 64 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DarkmoonCard:Berserker!-42989" + value: { + dps: 11018.16099 + tps: 7883.4715 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DarkmoonCard:Death-42990" + value: { + dps: 11048.11396 + tps: 7904.88768 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DarkmoonCard:Greatness-44255" + value: { + dps: 11078.34064 + tps: 7926.12427 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DeadlyGladiator'sIdolofResolve-42588" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Death'sChoice-47464" + value: { + dps: 11450.1305 + tps: 8190.16986 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DeathKnight'sAnguish-38212" + value: { + dps: 10970.57227 + tps: 7849.68351 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Deathbringer'sWill-50362" + value: { + dps: 11488.98044 + tps: 8217.8281 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Deathbringer'sWill-50363" + value: { + dps: 11588.31383 + tps: 8288.28002 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Defender'sCode-40257" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DestructiveSkyflareDiamond" + value: { + dps: 11174.71865 + tps: 7994.62744 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DislodgedForeignObject-50348" + value: { + dps: 11096.66221 + tps: 7939.0578 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DislodgedForeignObject-50353" + value: { + dps: 11066.03055 + tps: 7917.30931 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DreamwalkerBattlegear" + value: { + dps: 9190.2289 + tps: 6583.39612 + } +} +dps_results: { + key: "TestFeralApl-AllItems-DreamwalkerGarb" + value: { + dps: 7917.98149 + tps: 5682.79278 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EffulgentSkyflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EmberSkyflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EnigmaticSkyflareDiamond" + value: { + dps: 11169.92198 + tps: 7991.2218 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EnigmaticStarflareDiamond" + value: { + dps: 11167.23974 + tps: 7989.31742 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EphemeralSnowflake-50260" + value: { + dps: 10998.21993 + tps: 7869.53771 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EssenceofGossamer-37220" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EternalEarthsiegeDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ExtractofNecromanticPower-40373" + value: { + dps: 11048.28537 + tps: 7904.78503 + } +} +dps_results: { + key: "TestFeralApl-AllItems-EyeoftheBroodmother-45308" + value: { + dps: 10999.13015 + tps: 7869.9596 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Figurine-SapphireOwl-42413" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ForethoughtTalisman-40258" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ForgeEmber-37660" + value: { + dps: 10965.1328 + tps: 7845.82149 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ForlornSkyflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ForlornStarflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-FuriousGladiator'sIdolofResolve-42589" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-FuryoftheFiveFlights-40431" + value: { + dps: 11098.77661 + tps: 7940.63381 + } +} +dps_results: { + key: "TestFeralApl-AllItems-FuturesightRune-38763" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Gladiator'sSanctuary" + value: { + dps: 9708.33043 + tps: 6951.77172 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Gladiator'sWildhide" + value: { + dps: 7937.76831 + tps: 5694.44825 + } +} +dps_results: { + key: "TestFeralApl-AllItems-GlowingTwilightScale-54573" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-GlowingTwilightScale-54589" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-GnomishLightningGenerator-41121" + value: { + dps: 11025.55515 + tps: 7888.57178 + } +} +dps_results: { + key: "TestFeralApl-AllItems-HatefulGladiator'sIdolofResolve-42587" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Heartpierce-49982" + value: { + dps: 11684.47467 + tps: 8356.10549 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Heartpierce-50641" + value: { + dps: 11752.75713 + tps: 8405.03476 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdolofLunarFury-47670" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdoloftheCorruptor-45509" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdoloftheCryingMoon-50456" + value: { + dps: 11464.02712 + tps: 8199.96167 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdoloftheLunarEclipse-50457" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdoloftheRavenGoddess-32387" + value: { + dps: 11159.39707 + tps: 7983.8239 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdoloftheUnseenMoon-33510" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IdoloftheWhiteStag-32257" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IllustrationoftheDragonSoul-40432" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ImpassiveSkyflareDiamond" + value: { + dps: 11169.92198 + tps: 7991.2218 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ImpassiveStarflareDiamond" + value: { + dps: 11167.23974 + tps: 7989.31742 + } +} +dps_results: { + key: "TestFeralApl-AllItems-IncisorFragment-37723" + value: { + dps: 11081.69201 + tps: 7928.50374 + } +} +dps_results: { + key: "TestFeralApl-AllItems-InsightfulEarthsiegeDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-InvigoratingEarthsiegeDiamond" + value: { + dps: 11166.84764 + tps: 7989.11381 + hps: 15.15199 + } +} +dps_results: { + key: "TestFeralApl-AllItems-LasherweaveBattlegear" + value: { + dps: 11834.21272 + tps: 8460.69942 + } +} +dps_results: { + key: "TestFeralApl-AllItems-LasherweaveRegalia" + value: { + dps: 8591.80379 + tps: 6163.07628 + } +} +dps_results: { + key: "TestFeralApl-AllItems-LastWord-50179" + value: { + dps: 11640.63516 + tps: 8325.42816 + } +} +dps_results: { + key: "TestFeralApl-AllItems-LastWord-50708" + value: { + dps: 11668.66557 + tps: 8345.32975 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Lavanthor'sTalisman-37872" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-MajesticDragonFigurine-40430" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Malfurion'sBattlegear" + value: { + dps: 9762.5458 + tps: 6992.80737 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Malfurion'sRegalia" + value: { + dps: 7969.39515 + tps: 5720.56785 + } +} +dps_results: { + key: "TestFeralApl-AllItems-MeteoriteWhetstone-37390" + value: { + dps: 11179.86722 + tps: 7998.20814 + } +} +dps_results: { + key: "TestFeralApl-AllItems-NevermeltingIceCrystal-50259" + value: { + dps: 11035.14962 + tps: 7895.60822 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Nibelung-49992" + value: { + dps: 11453.32526 + tps: 8192.43814 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Nibelung-50648" + value: { + dps: 11453.32526 + tps: 8192.43814 + } +} +dps_results: { + key: "TestFeralApl-AllItems-NightsongBattlegear" + value: { + dps: 9740.57618 + tps: 6975.26449 + } +} +dps_results: { + key: "TestFeralApl-AllItems-NightsongGarb" + value: { + dps: 7845.4538 + tps: 5633.39215 + } +} +dps_results: { + key: "TestFeralApl-AllItems-OfferingofSacrifice-37638" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PersistentEarthshatterDiamond" + value: { + dps: 11160.69617 + tps: 7984.74627 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PersistentEarthsiegeDiamond" + value: { + dps: 11166.84764 + tps: 7989.11381 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PetrifiedScarab-21685" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PetrifiedTwilightScale-54571" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PetrifiedTwilightScale-54591" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PowerfulEarthshatterDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PowerfulEarthsiegeDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-PurifiedShardoftheGods" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ReignoftheDead-47316" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ReignoftheDead-47477" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-RelentlessEarthsiegeDiamond" + value: { + dps: 11453.32526 + tps: 8192.43814 + } +} +dps_results: { + key: "TestFeralApl-AllItems-RelentlessGladiator'sIdolofResolve-42591" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-RevitalizingSkyflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-RuneofRepulsion-40372" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SavageGladiator'sIdolofResolve-42574" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SealofthePantheon-36993" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ShinyShardoftheGods" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Sindragosa'sFlawlessFang-50361" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SliverofPureIce-50339" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SliverofPureIce-50346" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SoulPreserver-37111" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SouloftheDead-40382" + value: { + dps: 11006.02456 + tps: 7874.85464 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SparkofLife-37657" + value: { + dps: 11012.9848 + tps: 7879.64683 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SphereofRedDragon'sBlood-37166" + value: { + dps: 11069.73947 + tps: 7921.28881 + } +} +dps_results: { + key: "TestFeralApl-AllItems-StormshroudArmor" + value: { + dps: 8601.68001 + tps: 6166.49863 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SwiftSkyflareDiamond" + value: { + dps: 11166.84764 + tps: 7989.11381 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SwiftStarflareDiamond" + value: { + dps: 11160.69617 + tps: 7984.74627 + } +} +dps_results: { + key: "TestFeralApl-AllItems-SwiftWindfireDiamond" + value: { + dps: 11149.9311 + tps: 7977.10307 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TalismanofTrollDivinity-37734" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TearsoftheVanquished-47215" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TheGeneral'sHeart-45507" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ThunderheartHarness" + value: { + dps: 7484.346 + tps: 5369.67652 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ThunderheartRegalia" + value: { + dps: 6578.93302 + tps: 4727.58116 + } +} +dps_results: { + key: "TestFeralApl-AllItems-ThunderingSkyflareDiamond" + value: { + dps: 11229.91029 + tps: 8033.88829 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TinyAbominationinaJar-50351" + value: { + dps: 11058.12293 + tps: 7914.31244 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TinyAbominationinaJar-50706" + value: { + dps: 11143.20624 + tps: 7974.57202 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TirelessSkyflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TirelessStarflareDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TomeofArcanePhenomena-36972" + value: { + dps: 10994.71822 + tps: 7866.90192 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TrenchantEarthshatterDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-TrenchantEarthsiegeDiamond" + value: { + dps: 11134.55244 + tps: 7966.18422 + } +} +dps_results: { + key: "TestFeralApl-AllItems-UndeadSlayer'sBlessedArmor" + value: { + dps: 8740.20174 + tps: 6264.32555 + } +} +dps_results: { + key: "TestFeralApl-AllItems-Val'anyr,HammerofAncientKings-46017" + value: { + dps: 8600.30629 + tps: 6166.94424 + } +} +dps_results: { + key: "TestFeralApl-AllItems-VengefulGladiator'sIdolofResolve-33947" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-AllItems-WingedTalisman-37844" + value: { + dps: 10853.70661 + tps: 7766.6341 + } +} +dps_results: { + key: "TestFeralApl-AllItems-WrathfulGladiator'sIdolofResolve-51429" + value: { + dps: 11107.39591 + tps: 7946.90308 + } +} +dps_results: { + key: "TestFeralApl-Average-Default" + value: { + dps: 11456.57961 + tps: 8194.76951 + } +} +dps_results: { + key: "TestFeralApl-Settings-Tauren-p3-Default-default-FullBuffs-LongMultiTarget" + value: { + dps: 11453.32526 + tps: 8192.43814 + } +} +dps_results: { + key: "TestFeralApl-Settings-Tauren-p3-Default-default-FullBuffs-LongSingleTarget" + value: { + dps: 11453.32526 + tps: 8192.43814 + } +} +dps_results: { + key: "TestFeralApl-Settings-Tauren-p3-Default-default-FullBuffs-ShortSingleTarget" + value: { + dps: 13050.93286 + tps: 9315.14759 + } +} +dps_results: { + key: "TestFeralApl-Settings-Tauren-p3-Default-default-NoBuffs-LongMultiTarget" + value: { + dps: 7083.67635 + tps: 5088.49168 + } +} +dps_results: { + key: "TestFeralApl-Settings-Tauren-p3-Default-default-NoBuffs-LongSingleTarget" + value: { + dps: 7083.67635 + tps: 5088.49168 + } +} +dps_results: { + key: "TestFeralApl-Settings-Tauren-p3-Default-default-NoBuffs-ShortSingleTarget" + value: { + dps: 7578.66914 + tps: 5429.46642 + } +} +dps_results: { + key: "TestFeralApl-SwitchInFrontOfTarget-Default" + value: { + dps: 3096.09321 + tps: 2210.11726 + } +} diff --git a/sim/druid/feral/apl_values.go b/sim/druid/feral/apl_values.go index 0846b1afda..c23c9dcc60 100644 --- a/sim/druid/feral/apl_values.go +++ b/sim/druid/feral/apl_values.go @@ -23,7 +23,7 @@ type APLValueCatExcessEnergy struct { cat *FeralDruid } -func (cat *FeralDruid) newValueCatExcessEnergy(rot *core.APLRotation, config *proto.APLValueCatExcessEnergy) core.APLValue { +func (cat *FeralDruid) newValueCatExcessEnergy(_ *core.APLRotation, _ *proto.APLValueCatExcessEnergy) core.APLValue { return &APLValueCatExcessEnergy{ cat: cat, } @@ -36,23 +36,17 @@ func (value *APLValueCatExcessEnergy) GetFloat(sim *core.Simulation) float64 { pendingPool := PoolingActions{} pendingPool.create(4) - curCp := cat.ComboPoints() simTimeRemain := sim.GetRemainingDuration() - rakeDot := cat.Rake.CurDot() - ripDot := cat.Rip.CurDot() - mangleRefreshPending := cat.bleedAura.IsActive() && cat.bleedAura.RemainingDuration(sim) < (simTimeRemain-time.Second) - endThresh := time.Second * 10 - - if ripDot.IsActive() && (ripDot.RemainingDuration(sim) < simTimeRemain-endThresh) && curCp == 5 { + if ripDot := cat.Rip.CurDot(); ripDot.IsActive() && ripDot.RemainingDuration(sim) < simTimeRemain-time.Second*10 && cat.ComboPoints() == 5 { ripCost := core.Ternary(cat.berserkExpectedAt(sim, ripDot.ExpiresAt()), cat.Rip.DefaultCast.Cost*0.5, cat.Rip.DefaultCast.Cost) pendingPool.addAction(ripDot.ExpiresAt(), ripCost) cat.ripRefreshPending = true } - if rakeDot.IsActive() && (rakeDot.RemainingDuration(sim) < simTimeRemain-rakeDot.Duration) { + if rakeDot := cat.Rake.CurDot(); rakeDot.IsActive() && rakeDot.RemainingDuration(sim) < simTimeRemain-rakeDot.Duration { rakeCost := core.Ternary(cat.berserkExpectedAt(sim, rakeDot.ExpiresAt()), cat.Rake.DefaultCast.Cost*0.5, cat.Rake.DefaultCast.Cost) pendingPool.addAction(rakeDot.ExpiresAt(), rakeCost) } - if mangleRefreshPending { + if cat.bleedAura.IsActive() && cat.bleedAura.RemainingDuration(sim) < simTimeRemain-time.Second { mangleCost := core.Ternary(cat.berserkExpectedAt(sim, cat.bleedAura.ExpiresAt()), cat.MangleCat.DefaultCast.Cost*0.5, cat.MangleCat.DefaultCast.Cost) pendingPool.addAction(cat.bleedAura.ExpiresAt(), mangleCost) } @@ -75,7 +69,7 @@ type APLValueCatNewSavageRoarDuration struct { cat *FeralDruid } -func (cat *FeralDruid) newValueCatNewSavageRoarDuration(rot *core.APLRotation, config *proto.APLValueCatNewSavageRoarDuration) core.APLValue { +func (cat *FeralDruid) newValueCatNewSavageRoarDuration(_ *core.APLRotation, _ *proto.APLValueCatNewSavageRoarDuration) core.APLValue { return &APLValueCatNewSavageRoarDuration{ cat: cat, } @@ -83,7 +77,7 @@ func (cat *FeralDruid) newValueCatNewSavageRoarDuration(rot *core.APLRotation, c func (value *APLValueCatNewSavageRoarDuration) Type() proto.APLValueType { return proto.APLValueType_ValueTypeDuration } -func (value *APLValueCatNewSavageRoarDuration) GetDuration(sim *core.Simulation) time.Duration { +func (value *APLValueCatNewSavageRoarDuration) GetDuration(_ *core.Simulation) time.Duration { cat := value.cat return cat.SavageRoarDurationTable[cat.ComboPoints()] } diff --git a/sim/druid/feral/feral_test.go b/sim/druid/feral/feral_test.go index 40de6e30bd..587a8fa0c2 100644 --- a/sim/druid/feral/feral_test.go +++ b/sim/druid/feral/feral_test.go @@ -44,6 +44,21 @@ func TestFeral(t *testing.T) { })) } +func TestFeralApl(t *testing.T) { + core.RunTestSuite(t, t.Name(), core.FullCharacterTestSuiteGenerator(core.CharacterSuiteConfig{ + Class: proto.Class_ClassDruid, + Race: proto.Race_RaceTauren, + + GearSet: core.GetGearSet("../../../ui/feral_druid/gear_sets", "p3"), + Talents: StandardTalents, + Glyphs: StandardGlyphs, + Consumes: FullConsumes, + SpecOptions: core.SpecOptionsCombo{Label: "Default", SpecOptions: PlayerOptionsMonoCat}, + Rotation: core.GetAplRotation("../../../ui/feral_druid/apls", "default"), + ItemFilter: FeralItemFilter, + })) +} + func TestFeralDoubleArmorPenTrinketsNoDesync(t *testing.T) { core.RunTestSuite(t, t.Name(), core.FullCharacterTestSuiteGenerator(core.CharacterSuiteConfig{ Class: proto.Class_ClassDruid, diff --git a/sim/encounters/icc/lichking25h_ai.go b/sim/encounters/icc/lichking25h_ai.go index 59e10ebb41..945f8aa81f 100644 --- a/sim/encounters/icc/lichking25h_ai.go +++ b/sim/encounters/icc/lichking25h_ai.go @@ -61,6 +61,7 @@ func (ai *LichKing25HAI) Initialize(target *core.Target, _ *proto.Target) { } func (ai *LichKing25HAI) Reset(*core.Simulation) { + ai.SoulReaper.CD.Set(ai.SoulReaper.CD.Duration) } func (ai *LichKing25HAI) registerSoulReaperSpell(target *core.Target) { @@ -80,7 +81,7 @@ func (ai *LichKing25HAI) registerSoulReaperSpell(target *core.Target) { ActionID: core.ActionID{SpellID: 69409}, SpellSchool: core.SpellSchoolShadow, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagNone, + Flags: core.SpellFlagAPL, Cast: core.CastConfig{ CD: core.Cooldown{ @@ -135,7 +136,7 @@ func (ai *LichKing25HAI) registerSoulReaperSpell(target *core.Target) { func (ai *LichKing25HAI) DoAction(sim *core.Simulation) { if ai.Target.GCD.IsReady(sim) { if ai.Target.CurrentTarget != nil { - if ai.SoulReaper.IsReady(sim) && sim.CurrentTime >= ai.SoulReaper.CD.Duration { + if ai.SoulReaper.IsReady(sim) { // Based on log analysis, Soul Reaper appears to have a ~75% chance to "proc" on every 1.62 second server tick once it is off cooldown. // Note that analysis based only on the cast intervals supported a ~40% proc chance fit. However, many of the apparent delays in Soul Reaper casts are // due to Defile and Infest casts that take priority when the cooldowns overlap. Once these CD conflicts are corrected for, the variance in Soul Reaper diff --git a/sim/encounters/icc/sindragosa25h_ai.go b/sim/encounters/icc/sindragosa25h_ai.go index 01f9ac8f5b..bae19b56bd 100644 --- a/sim/encounters/icc/sindragosa25h_ai.go +++ b/sim/encounters/icc/sindragosa25h_ai.go @@ -50,7 +50,6 @@ type Sindragosa25HAI struct { FrostAura *core.Spell FrostBreath *core.Spell FrostBreathDebuff *core.Aura - FirstBreath time.Duration IncludeMysticBuffet bool MysticBuffetAuras []*core.Aura @@ -88,7 +87,9 @@ func (ai *Sindragosa25HAI) Reset(sim *core.Simulation) { breathPeriod := time.Millisecond * 22680 maxBreathsPossible := (sim.Duration - time.Millisecond*1500) / breathPeriod latestAllowedBreath := sim.Duration - time.Millisecond*1500 - breathPeriod*maxBreathsPossible - time.Millisecond*1620 - ai.FirstBreath = core.DurationFromSeconds(sim.RandomFloat("Frost Breath Timing") * latestAllowedBreath.Seconds()) + firstBreath := core.DurationFromSeconds(sim.RandomFloat("Frost Breath Timing") * latestAllowedBreath.Seconds()) + + ai.FrostBreath.CD.Set(firstBreath) } func (ai *Sindragosa25HAI) registerPermeatingChillAura(target *core.Target) { @@ -290,7 +291,7 @@ func (ai *Sindragosa25HAI) registerFrostBreathSpell(target *core.Target) { ActionID: actionID, SpellSchool: core.SpellSchoolFrost, ProcMask: core.ProcMaskSpellDamage, - Flags: core.SpellFlagNone, + Flags: core.SpellFlagAPL, Cast: core.CastConfig{ CD: core.Cooldown{ @@ -324,7 +325,7 @@ func (ai *Sindragosa25HAI) DoAction(sim *core.Simulation) { } if ai.Target.CurrentTarget != nil { - if ai.FrostBreath.IsReady(sim) && sim.CurrentTime >= ai.FirstBreath { + if ai.FrostBreath.IsReady(sim) { ai.Target.Unit.AutoAttacks.StopMeleeUntil(sim, sim.CurrentTime+time.Millisecond*1500, false) ai.FrostBreath.Cast(sim, ai.Target.CurrentTarget) return diff --git a/sim/priest/shadow/rotation.go b/sim/priest/shadow/rotation.go index 4b7a8963bd..3e92894cac 100644 --- a/sim/priest/shadow/rotation.go +++ b/sim/priest/shadow/rotation.go @@ -643,6 +643,10 @@ func (spriest *ShadowPriest) chooseSpellIdeal(sim *core.Simulation) (*core.Spell numTicks = spriest.IdealMindflayRotation(sim, gcd, tickLength, currentWait, mfDamage, mbDamage, dpDamage, vtDamage, swdDamage, overwriteDPS) //enter the mf optimizaiton routine to optimze mf clips and for next optimal spell } + if numTicks == 3 && spriest.ShadowWordPain.CurDot().IsActive() && spriest.ShadowWordPain.CurDot().RemainingDuration(sim).Seconds() < tickLength.Seconds()*12 && float64(tickLength.Seconds()*3) >= gcd.Seconds() { + numTicks = 2 + } + if numTicks == 0 { // Means we'd rather wait for next CD (swp, vt, etc) than start a MF cast. nextCD := core.NeverExpires diff --git a/sim/shaman/elemental/TestElemental.results b/sim/shaman/elemental/TestElemental.results index 55e522bc22..cdeaa2cb09 100644 --- a/sim/shaman/elemental/TestElemental.results +++ b/sim/shaman/elemental/TestElemental.results @@ -1029,43 +1029,43 @@ dps_results: { dps_results: { key: "TestElemental-Settings-Orc-p1-Adaptive-advanced-FullBuffs-LongMultiTarget" value: { - dps: 8993.67995 - tps: 4016.89247 + dps: 9840.69885 + tps: 4752.84315 } } dps_results: { key: "TestElemental-Settings-Orc-p1-Adaptive-advanced-FullBuffs-LongSingleTarget" value: { - dps: 6322.84125 - tps: 3490.3117 + dps: 7458.6682 + tps: 4125.47809 } } dps_results: { key: "TestElemental-Settings-Orc-p1-Adaptive-advanced-FullBuffs-ShortSingleTarget" value: { - dps: 9331.908 - tps: 4971.78415 + dps: 8955.74736 + tps: 4674.30922 } } dps_results: { key: "TestElemental-Settings-Orc-p1-Adaptive-advanced-NoBuffs-LongMultiTarget" value: { - dps: 5070.48894 - tps: 1770.31215 + dps: 5624.96049 + tps: 2381.13178 } } dps_results: { key: "TestElemental-Settings-Orc-p1-Adaptive-advanced-NoBuffs-LongSingleTarget" value: { - dps: 2977.50744 - tps: 1503.49874 + dps: 3878.88818 + tps: 2052.11172 } } dps_results: { key: "TestElemental-Settings-Orc-p1-Adaptive-advanced-NoBuffs-ShortSingleTarget" value: { - dps: 6049.10665 - tps: 3183.46629 + dps: 6509.36129 + tps: 3357.28864 } } dps_results: { @@ -1113,43 +1113,43 @@ dps_results: { dps_results: { key: "TestElemental-Settings-Orc-p1-EleFireElemental-advanced-FullBuffs-LongMultiTarget" value: { - dps: 8993.67995 - tps: 4016.89247 + dps: 9840.69885 + tps: 4752.84315 } } dps_results: { key: "TestElemental-Settings-Orc-p1-EleFireElemental-advanced-FullBuffs-LongSingleTarget" value: { - dps: 6322.84125 - tps: 3490.3117 + dps: 7458.6682 + tps: 4125.47809 } } dps_results: { key: "TestElemental-Settings-Orc-p1-EleFireElemental-advanced-FullBuffs-ShortSingleTarget" value: { - dps: 9331.908 - tps: 4971.78415 + dps: 8955.74736 + tps: 4674.30922 } } dps_results: { key: "TestElemental-Settings-Orc-p1-EleFireElemental-advanced-NoBuffs-LongMultiTarget" value: { - dps: 5070.48894 - tps: 1770.31215 + dps: 5624.96049 + tps: 2381.13178 } } dps_results: { key: "TestElemental-Settings-Orc-p1-EleFireElemental-advanced-NoBuffs-LongSingleTarget" value: { - dps: 2977.50744 - tps: 1503.49874 + dps: 3878.88818 + tps: 2052.11172 } } dps_results: { key: "TestElemental-Settings-Orc-p1-EleFireElemental-advanced-NoBuffs-ShortSingleTarget" value: { - dps: 6049.10665 - tps: 3183.46629 + dps: 6509.36129 + tps: 3357.28864 } } dps_results: { @@ -1197,43 +1197,43 @@ dps_results: { dps_results: { key: "TestElemental-Settings-Troll-p1-Adaptive-advanced-FullBuffs-LongMultiTarget" value: { - dps: 8765.33632 - tps: 4002.05751 + dps: 9546.15132 + tps: 4680.47017 } } dps_results: { key: "TestElemental-Settings-Troll-p1-Adaptive-advanced-FullBuffs-LongSingleTarget" value: { - dps: 6224.1282 - tps: 3466.37714 + dps: 7396.36835 + tps: 4126.68301 } } dps_results: { key: "TestElemental-Settings-Troll-p1-Adaptive-advanced-FullBuffs-ShortSingleTarget" value: { - dps: 9150.21717 - tps: 4927.2039 + dps: 9159.66165 + tps: 4943.86712 } } dps_results: { key: "TestElemental-Settings-Troll-p1-Adaptive-advanced-NoBuffs-LongMultiTarget" value: { - dps: 4856.26349 - tps: 1732.5399 + dps: 5462.52243 + tps: 2391.51442 } } dps_results: { key: "TestElemental-Settings-Troll-p1-Adaptive-advanced-NoBuffs-LongSingleTarget" value: { - dps: 2931.3259 - tps: 1500.98827 + dps: 3805.33866 + tps: 2029.18744 } } dps_results: { key: "TestElemental-Settings-Troll-p1-Adaptive-advanced-NoBuffs-ShortSingleTarget" value: { - dps: 5914.071 - tps: 3153.70901 + dps: 6557.0291 + tps: 3454.07046 } } dps_results: { @@ -1281,43 +1281,43 @@ dps_results: { dps_results: { key: "TestElemental-Settings-Troll-p1-EleFireElemental-advanced-FullBuffs-LongMultiTarget" value: { - dps: 8765.33632 - tps: 4002.05751 + dps: 9546.15132 + tps: 4680.47017 } } dps_results: { key: "TestElemental-Settings-Troll-p1-EleFireElemental-advanced-FullBuffs-LongSingleTarget" value: { - dps: 6224.1282 - tps: 3466.37714 + dps: 7396.36835 + tps: 4126.68301 } } dps_results: { key: "TestElemental-Settings-Troll-p1-EleFireElemental-advanced-FullBuffs-ShortSingleTarget" value: { - dps: 9150.21717 - tps: 4927.2039 + dps: 9159.66165 + tps: 4943.86712 } } dps_results: { key: "TestElemental-Settings-Troll-p1-EleFireElemental-advanced-NoBuffs-LongMultiTarget" value: { - dps: 4856.26349 - tps: 1732.5399 + dps: 5462.52243 + tps: 2391.51442 } } dps_results: { key: "TestElemental-Settings-Troll-p1-EleFireElemental-advanced-NoBuffs-LongSingleTarget" value: { - dps: 2931.3259 - tps: 1500.98827 + dps: 3805.33866 + tps: 2029.18744 } } dps_results: { key: "TestElemental-Settings-Troll-p1-EleFireElemental-advanced-NoBuffs-ShortSingleTarget" value: { - dps: 5914.071 - tps: 3153.70901 + dps: 6557.0291 + tps: 3454.07046 } } dps_results: { diff --git a/sim/shaman/enhancement/TestEnhancement.results b/sim/shaman/enhancement/TestEnhancement.results index b140845faa..27984a6646 100644 --- a/sim/shaman/enhancement/TestEnhancement.results +++ b/sim/shaman/enhancement/TestEnhancement.results @@ -6,13 +6,13 @@ character_stats_results: { final_stats: 1355.75 final_stats: 833.976 final_stats: 320.1 - final_stats: 3148.17956 + final_stats: 3148.20708 final_stats: 109 final_stats: 374 final_stats: 1632.42984 final_stats: 360 final_stats: 0 - final_stats: 5425.63186 + final_stats: 5425.7236 final_stats: 570.73993 final_stats: 1851.49064 final_stats: 360 @@ -46,1453 +46,1453 @@ character_stats_results: { dps_results: { key: "TestEnhancement-AllItems-Althor'sAbacus-50359" value: { - dps: 7551.16901 - tps: 4145.99422 + dps: 7551.22288 + tps: 4506.40045 } } dps_results: { key: "TestEnhancement-AllItems-Althor'sAbacus-50366" value: { - dps: 7571.27822 - tps: 4157.59638 + dps: 7571.33209 + tps: 4518.00261 } } dps_results: { key: "TestEnhancement-AllItems-AustereEarthsiegeDiamond" value: { - dps: 7432.23831 - tps: 4078.54216 + dps: 7432.29269 + tps: 4444.65886 } } dps_results: { key: "TestEnhancement-AllItems-Bandit'sInsignia-40371" value: { - dps: 7555.94818 - tps: 4150.52766 + dps: 7556.00198 + tps: 4520.15467 } } dps_results: { key: "TestEnhancement-AllItems-BaubleofTrueBlood-50354" value: { - dps: 7387.68838 - tps: 4051.67144 + dps: 7387.74225 + tps: 4412.07767 hps: 95.40076 } } dps_results: { key: "TestEnhancement-AllItems-BaubleofTrueBlood-50726" value: { - dps: 7387.68838 - tps: 4051.67144 + dps: 7387.74225 + tps: 4412.07767 hps: 95.40076 } } dps_results: { key: "TestEnhancement-AllItems-BeamingEarthsiegeDiamond" value: { - dps: 7429.26312 - tps: 4075.43524 + dps: 7429.31748 + tps: 4440.68518 } } dps_results: { key: "TestEnhancement-AllItems-Beast-tamer'sShoulders-30892" value: { - dps: 7214.01285 - tps: 3942.19381 + dps: 7214.06309 + tps: 4286.53216 } } dps_results: { key: "TestEnhancement-AllItems-Bizuri'sTotemofShatteredIce-50458" value: { - dps: 7855.43706 - tps: 4335.39386 + dps: 7855.49458 + tps: 4732.00351 } } dps_results: { key: "TestEnhancement-AllItems-BlackBruise-50035" value: { - dps: 7434.01596 - tps: 4070.24045 + dps: 7434.06846 + tps: 4494.04002 } } dps_results: { key: "TestEnhancement-AllItems-BlackBruise-50692" value: { - dps: 7493.56364 - tps: 4104.5592 + dps: 7493.61626 + tps: 4538.18907 } } dps_results: { key: "TestEnhancement-AllItems-BlessedGarboftheUndeadSlayer" value: { - dps: 6100.63866 - tps: 3319.88219 + dps: 6100.6793 + tps: 3598.15706 } } dps_results: { key: "TestEnhancement-AllItems-BlessedRegaliaofUndeadCleansing" value: { - dps: 6043.32824 - tps: 3290.49684 + dps: 6043.36963 + tps: 3550.84828 } } dps_results: { key: "TestEnhancement-AllItems-BracingEarthsiegeDiamond" value: { - dps: 7455.23833 - tps: 3978.79032 + dps: 7455.2927 + tps: 4371.49279 } } dps_results: { key: "TestEnhancement-AllItems-Bryntroll,theBoneArbiter-50415" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-Bryntroll,theBoneArbiter-50709" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-ChaoticSkyflareDiamond" value: { - dps: 7599.80498 - tps: 4178.21406 + dps: 7599.8606 + tps: 4553.33149 } } dps_results: { key: "TestEnhancement-AllItems-CorpseTongueCoin-50349" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-CorpseTongueCoin-50352" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-CorrodedSkeletonKey-50356" value: { - dps: 7387.5548 - tps: 4051.59484 + dps: 7387.60867 + tps: 4412.00106 hps: 64 } } dps_results: { key: "TestEnhancement-AllItems-DarkmoonCard:Berserker!-42989" value: { - dps: 7516.61315 - tps: 4129.03208 + dps: 7516.66801 + tps: 4496.98339 } } dps_results: { key: "TestEnhancement-AllItems-DarkmoonCard:Death-42990" value: { - dps: 7498.29351 - tps: 4129.32449 + dps: 7498.34779 + tps: 4493.1962 } } dps_results: { key: "TestEnhancement-AllItems-DarkmoonCard:Greatness-44255" value: { - dps: 7582.17139 - tps: 4156.15619 + dps: 7582.2326 + tps: 4532.36101 } } dps_results: { key: "TestEnhancement-AllItems-DeadlyGladiator'sTotemofSurvival-42602" value: { - dps: 7639.65012 - tps: 4203.01798 + dps: 7639.70535 + tps: 4574.28307 } } dps_results: { key: "TestEnhancement-AllItems-Death'sChoice-47464" value: { - dps: 7750.33425 - tps: 4241.37277 + dps: 7750.38852 + tps: 4633.04638 } } dps_results: { key: "TestEnhancement-AllItems-DeathKnight'sAnguish-38212" value: { - dps: 7477.2425 - tps: 4108.69773 + dps: 7477.29706 + tps: 4473.82938 } } dps_results: { key: "TestEnhancement-AllItems-Deathbringer'sWill-50362" value: { - dps: 7711.14094 - tps: 4214.51392 + dps: 7711.19648 + tps: 4608.47643 } } dps_results: { key: "TestEnhancement-AllItems-Deathbringer'sWill-50363" value: { - dps: 7759.15821 - tps: 4234.05411 + dps: 7759.21397 + tps: 4633.58657 } } dps_results: { key: "TestEnhancement-AllItems-Defender'sCode-40257" value: { - dps: 7387.5548 - tps: 4051.59484 + dps: 7387.60867 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-DestructiveSkyflareDiamond" value: { - dps: 7448.37586 - tps: 4086.02344 + dps: 7448.43038 + tps: 4453.5828 } } dps_results: { key: "TestEnhancement-AllItems-DislodgedForeignObject-50348" value: { - dps: 7836.65987 - tps: 4317.80124 + dps: 7836.71565 + tps: 4697.61157 } } dps_results: { key: "TestEnhancement-AllItems-DislodgedForeignObject-50353" value: { - dps: 7734.13808 - tps: 4251.83454 + dps: 7734.19336 + tps: 4627.63907 } } dps_results: { key: "TestEnhancement-AllItems-EarthshatterBattlegear" value: { - dps: 6836.4093 - tps: 3727.55867 + dps: 6836.45896 + tps: 4053.45224 } } dps_results: { key: "TestEnhancement-AllItems-EarthshatterGarb" value: { - dps: 6473.86219 - tps: 3534.12652 + dps: 6473.91636 + tps: 3791.67426 } } dps_results: { key: "TestEnhancement-AllItems-EffulgentSkyflareDiamond" value: { - dps: 7432.23831 - tps: 4078.54216 + dps: 7432.29269 + tps: 4444.65886 } } dps_results: { key: "TestEnhancement-AllItems-EmberSkyflareDiamond" value: { - dps: 7481.61457 - tps: 4110.41916 + dps: 7481.6702 + tps: 4478.88948 } } dps_results: { key: "TestEnhancement-AllItems-EnigmaticSkyflareDiamond" value: { - dps: 7445.66397 - tps: 4084.70162 + dps: 7445.71848 + tps: 4451.98829 } } dps_results: { key: "TestEnhancement-AllItems-EnigmaticStarflareDiamond" value: { - dps: 7441.4449 - tps: 4082.31954 + dps: 7441.49939 + tps: 4449.81179 } } dps_results: { key: "TestEnhancement-AllItems-EphemeralSnowflake-50260" value: { - dps: 7498.25245 - tps: 4114.93945 + dps: 7498.30721 + tps: 4485.1773 } } dps_results: { key: "TestEnhancement-AllItems-EssenceofGossamer-37220" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-EternalEarthsiegeDiamond" value: { - dps: 7432.23831 - tps: 4078.54216 + dps: 7432.29269 + tps: 4444.65886 } } dps_results: { key: "TestEnhancement-AllItems-ExtractofNecromanticPower-40373" value: { - dps: 7514.45903 - tps: 4134.18979 + dps: 7514.51365 + tps: 4499.46303 } } dps_results: { key: "TestEnhancement-AllItems-EyeoftheBroodmother-45308" value: { - dps: 7629.31578 - tps: 4195.50309 + dps: 7629.37055 + tps: 4562.45131 } } dps_results: { key: "TestEnhancement-AllItems-Figurine-SapphireOwl-42413" value: { - dps: 7404.80421 - tps: 4059.43863 + dps: 7404.86112 + tps: 4420.8207 } } dps_results: { key: "TestEnhancement-AllItems-ForethoughtTalisman-40258" value: { - dps: 7489.01329 - tps: 4110.133 + dps: 7489.06715 + tps: 4470.53923 } } dps_results: { key: "TestEnhancement-AllItems-ForgeEmber-37660" value: { - dps: 7567.71283 - tps: 4142.40543 + dps: 7567.76737 + tps: 4507.73844 } } dps_results: { key: "TestEnhancement-AllItems-ForlornSkyflareDiamond" value: { - dps: 7455.23833 - tps: 4091.81732 + dps: 7455.2927 + tps: 4457.93402 } } dps_results: { key: "TestEnhancement-AllItems-ForlornStarflareDiamond" value: { - dps: 7450.63833 - tps: 4089.16229 + dps: 7450.6927 + tps: 4455.27899 } } dps_results: { key: "TestEnhancement-AllItems-FrostWitch'sBattlegear" value: { - dps: 8347.24991 - tps: 4544.28828 + dps: 8347.3227 + tps: 4991.94144 } } dps_results: { key: "TestEnhancement-AllItems-FrostWitch'sRegalia" value: { - dps: 7882.13696 - tps: 4357.13911 + dps: 7882.22063 + tps: 4675.1757 } } dps_results: { key: "TestEnhancement-AllItems-FuriousGladiator'sTotemofSurvival-42603" value: { - dps: 7652.59374 - tps: 4210.48826 + dps: 7652.64897 + tps: 4581.75335 } } dps_results: { key: "TestEnhancement-AllItems-FuryoftheFiveFlights-40431" value: { - dps: 7593.75263 - tps: 4162.01841 + dps: 7593.80657 + tps: 4540.18261 } } dps_results: { key: "TestEnhancement-AllItems-FuturesightRune-38763" value: { - dps: 7444.22754 - tps: 4084.29183 + dps: 7444.28141 + tps: 4444.69806 } } dps_results: { key: "TestEnhancement-AllItems-Gladiator'sEarthshaker" value: { - dps: 7083.21273 - tps: 3829.83659 + dps: 7083.27204 + tps: 4181.34774 } } dps_results: { key: "TestEnhancement-AllItems-Gladiator'sWartide" value: { - dps: 6252.86217 - tps: 3384.95856 + dps: 6252.12636 + tps: 3615.20928 } } dps_results: { key: "TestEnhancement-AllItems-GlowingTwilightScale-54573" value: { - dps: 7561.22656 - tps: 4151.7953 + dps: 7561.28043 + tps: 4512.20153 } } dps_results: { key: "TestEnhancement-AllItems-GlowingTwilightScale-54589" value: { - dps: 7584.07793 - tps: 4164.97957 + dps: 7584.1318 + tps: 4525.3858 } } dps_results: { key: "TestEnhancement-AllItems-GnomishLightningGenerator-41121" value: { - dps: 7527.69764 - tps: 4140.09312 + dps: 7527.75223 + tps: 4504.38512 } } dps_results: { key: "TestEnhancement-AllItems-HatefulGladiator'sTotemofSurvival-42601" value: { - dps: 7614.97003 - tps: 4187.99004 + dps: 7615.02525 + tps: 4559.25513 } } dps_results: { key: "TestEnhancement-AllItems-Heartpierce-49982" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-Heartpierce-50641" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-IllustrationoftheDragonSoul-40432" value: { - dps: 7557.94099 - tps: 4152.85467 + dps: 7557.99486 + tps: 4513.2609 } } dps_results: { key: "TestEnhancement-AllItems-ImpassiveSkyflareDiamond" value: { - dps: 7445.66397 - tps: 4084.70162 + dps: 7445.71848 + tps: 4451.98829 } } dps_results: { key: "TestEnhancement-AllItems-ImpassiveStarflareDiamond" value: { - dps: 7441.4449 - tps: 4082.31954 + dps: 7441.49939 + tps: 4449.81179 } } dps_results: { key: "TestEnhancement-AllItems-IncisorFragment-37723" value: { - dps: 7520.44049 - tps: 4124.63502 + dps: 7520.4948 + tps: 4499.46817 } } dps_results: { key: "TestEnhancement-AllItems-InsightfulEarthsiegeDiamond" value: { - dps: 7442.89617 - tps: 4082.04185 + dps: 7442.95212 + tps: 4448.58814 } } dps_results: { key: "TestEnhancement-AllItems-InvigoratingEarthsiegeDiamond" value: { - dps: 7468.81688 - tps: 4099.03431 + dps: 7468.87131 + tps: 4467.55597 hps: 11.01615 } } dps_results: { key: "TestEnhancement-AllItems-LastWord-50179" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-LastWord-50708" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-Lavanthor'sTalisman-37872" value: { - dps: 7387.5548 - tps: 4051.59484 + dps: 7387.60867 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-MajesticDragonFigurine-40430" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-NevermeltingIceCrystal-50259" value: { - dps: 7509.67841 - tps: 4123.778 + dps: 7509.7324 + tps: 4485.03396 } } dps_results: { key: "TestEnhancement-AllItems-Nibelung-49992" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-Nibelung-50648" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-OfferingofSacrifice-37638" value: { - dps: 7387.55641 - tps: 4051.59484 + dps: 7387.61028 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-PersistentEarthshatterDiamond" value: { - dps: 7463.11582 - tps: 4095.89149 + dps: 7463.17025 + tps: 4464.03199 } } dps_results: { key: "TestEnhancement-AllItems-PersistentEarthsiegeDiamond" value: { - dps: 7468.81688 - tps: 4099.03431 + dps: 7468.87131 + tps: 4467.55597 } } dps_results: { key: "TestEnhancement-AllItems-PetrifiedScarab-21685" value: { - dps: 7387.54744 - tps: 4051.59484 + dps: 7387.60131 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-PetrifiedTwilightScale-54571" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-PetrifiedTwilightScale-54591" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-PowerfulEarthshatterDiamond" value: { - dps: 7432.23831 - tps: 4078.54216 + dps: 7432.29269 + tps: 4444.65886 } } dps_results: { key: "TestEnhancement-AllItems-PowerfulEarthsiegeDiamond" value: { - dps: 7432.23831 - tps: 4078.54216 + dps: 7432.29269 + tps: 4444.65886 } } dps_results: { key: "TestEnhancement-AllItems-PurifiedShardoftheGods" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-ReignoftheDead-47316" value: { - dps: 7805.58413 - tps: 4331.80401 + dps: 7805.63806 + tps: 4692.81942 } } dps_results: { key: "TestEnhancement-AllItems-ReignoftheDead-47477" value: { - dps: 7856.10276 - tps: 4365.15377 + dps: 7856.15669 + tps: 4726.16917 } } dps_results: { key: "TestEnhancement-AllItems-RelentlessEarthsiegeDiamond" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-RelentlessGladiator'sTotemofSurvival-42604" value: { - dps: 7668.311 - tps: 4219.55931 + dps: 7668.36622 + tps: 4590.8244 } } dps_results: { key: "TestEnhancement-AllItems-RevitalizingSkyflareDiamond" value: { - dps: 7443.61067 - tps: 4087.68193 + dps: 7443.66514 + tps: 4454.84215 } } dps_results: { key: "TestEnhancement-AllItems-RuneofRepulsion-40372" value: { - dps: 7387.5548 - tps: 4051.59484 + dps: 7387.60867 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-SavageGladiator'sTotemofSurvival-42594" value: { - dps: 7608.51228 - tps: 4184.38949 + dps: 7608.56751 + tps: 4555.65457 } } dps_results: { key: "TestEnhancement-AllItems-SealofthePantheon-36993" value: { - dps: 7387.5548 - tps: 4051.59484 + dps: 7387.60867 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-Shadowmourne-49623" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-AllItems-ShinyShardoftheGods" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-Sindragosa'sFlawlessFang-50361" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-SkycallTotem-33506" value: { - dps: 7590.74877 - tps: 4173.75299 + dps: 7590.80412 + tps: 4545.36982 } } dps_results: { key: "TestEnhancement-AllItems-SkyshatterHarness" value: { - dps: 5432.76204 - tps: 2938.51089 + dps: 5432.79459 + tps: 3161.54669 } } dps_results: { key: "TestEnhancement-AllItems-SkyshatterRegalia" value: { - dps: 5374.20033 - tps: 2923.77735 + dps: 5377.09601 + tps: 3118.69452 } } dps_results: { key: "TestEnhancement-AllItems-SliverofPureIce-50339" value: { - dps: 7512.41168 - tps: 4128.43315 + dps: 7512.4654 + tps: 4488.57543 } } dps_results: { key: "TestEnhancement-AllItems-SliverofPureIce-50346" value: { - dps: 7520.95394 - tps: 4131.05833 + dps: 7521.00756 + tps: 4489.39857 } } dps_results: { key: "TestEnhancement-AllItems-SoulPreserver-37111" value: { - dps: 7456.10731 - tps: 4091.14765 + dps: 7456.16118 + tps: 4451.55388 } } dps_results: { key: "TestEnhancement-AllItems-SouloftheDead-40382" value: { - dps: 7494.43499 - tps: 4114.73053 + dps: 7494.4897 + tps: 4481.48869 } } dps_results: { key: "TestEnhancement-AllItems-SparkofLife-37657" value: { - dps: 7479.22023 - tps: 4111.36677 + dps: 7479.2748 + tps: 4477.40587 } } dps_results: { key: "TestEnhancement-AllItems-SphereofRedDragon'sBlood-37166" value: { - dps: 7531.39642 - tps: 4118.75467 + dps: 7531.45062 + tps: 4490.66454 } } dps_results: { key: "TestEnhancement-AllItems-Stonebreaker'sTotem-33507" value: { - dps: 7609.33504 - tps: 4182.0575 + dps: 7609.39027 + tps: 4556.01682 } } dps_results: { key: "TestEnhancement-AllItems-StormshroudArmor" value: { - dps: 5696.10627 - tps: 3089.25307 + dps: 5696.13947 + tps: 3335.04843 } } dps_results: { key: "TestEnhancement-AllItems-SwiftSkyflareDiamond" value: { - dps: 7468.81688 - tps: 4099.03431 + dps: 7468.87131 + tps: 4467.55597 } } dps_results: { key: "TestEnhancement-AllItems-SwiftStarflareDiamond" value: { - dps: 7463.11582 - tps: 4095.89149 + dps: 7463.17025 + tps: 4464.03199 } } dps_results: { key: "TestEnhancement-AllItems-SwiftWindfireDiamond" value: { - dps: 7447.23233 - tps: 4086.99989 + dps: 7447.28673 + tps: 4454.4222 } } dps_results: { key: "TestEnhancement-AllItems-TalismanofTrollDivinity-37734" value: { - dps: 7387.55614 - tps: 4051.59484 + dps: 7387.61001 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-TearsoftheVanquished-47215" value: { - dps: 7443.49382 - tps: 4081.9271 + dps: 7443.55399 + tps: 4446.18613 } } dps_results: { key: "TestEnhancement-AllItems-TheFistsofFury" value: { - dps: 6562.78556 - tps: 3562.77847 + dps: 6562.83479 + tps: 3898.66725 } } dps_results: { key: "TestEnhancement-AllItems-TheGeneral'sHeart-45507" value: { - dps: 7387.5532 - tps: 4051.59484 + dps: 7387.60707 + tps: 4412.00106 } } dps_results: { key: "TestEnhancement-AllItems-Thrall'sBattlegear" value: { - dps: 7334.50007 - tps: 4035.19032 + dps: 7334.55667 + tps: 4373.00373 } } dps_results: { key: "TestEnhancement-AllItems-Thrall'sRegalia" value: { - dps: 6982.0956 - tps: 3849.32295 + dps: 6982.15847 + tps: 4129.68966 } } dps_results: { key: "TestEnhancement-AllItems-ThunderingSkyflareDiamond" value: { - dps: 7504.97661 - tps: 4126.89033 + dps: 7505.03167 + tps: 4502.91649 } } dps_results: { key: "TestEnhancement-AllItems-TidefuryRaiment" value: { - dps: 5396.11419 - tps: 2916.3189 + dps: 5394.0838 + tps: 3130.8434 } } dps_results: { key: "TestEnhancement-AllItems-TinyAbominationinaJar-50351" value: { - dps: 7577.0477 - tps: 4163.04058 + dps: 7577.10317 + tps: 4544.7385 } } dps_results: { key: "TestEnhancement-AllItems-TinyAbominationinaJar-50706" value: { - dps: 7601.99423 - tps: 4180.1133 + dps: 7602.04996 + tps: 4563.33704 } } dps_results: { key: "TestEnhancement-AllItems-TirelessSkyflareDiamond" value: { - dps: 7455.23833 - tps: 4091.81732 + dps: 7455.2927 + tps: 4457.93402 } } dps_results: { key: "TestEnhancement-AllItems-TirelessStarflareDiamond" value: { - dps: 7450.63833 - tps: 4089.16229 + dps: 7450.6927 + tps: 4455.27899 } } dps_results: { key: "TestEnhancement-AllItems-TomeofArcanePhenomena-36972" value: { - dps: 7527.16315 - tps: 4131.33883 + dps: 7527.21765 + tps: 4498.50208 } } dps_results: { key: "TestEnhancement-AllItems-TotemofElectrifyingWind-47666" value: { - dps: 7821.19259 - tps: 4313.61703 + dps: 7821.24986 + tps: 4705.96131 } } dps_results: { key: "TestEnhancement-AllItems-TotemofQuakingEarth-47667" value: { - dps: 7721.56943 - tps: 4241.60004 + dps: 7721.62464 + tps: 4625.52252 } } dps_results: { key: "TestEnhancement-AllItems-TotemoftheAvalanche-50463" value: { - dps: 7857.39474 - tps: 4311.55975 + dps: 7857.44993 + tps: 4706.15674 } } dps_results: { key: "TestEnhancement-AllItems-TotemoftheElementalPlane-40708" value: { - dps: 7590.21305 - tps: 4178.2754 + dps: 7590.26847 + tps: 4551.83695 } } dps_results: { key: "TestEnhancement-AllItems-TrenchantEarthshatterDiamond" value: { - dps: 7450.63833 - tps: 4089.16229 + dps: 7450.6927 + tps: 4455.27899 } } dps_results: { key: "TestEnhancement-AllItems-TrenchantEarthsiegeDiamond" value: { - dps: 7455.23833 - tps: 4091.81732 + dps: 7455.2927 + tps: 4457.93402 } } dps_results: { key: "TestEnhancement-AllItems-UndeadSlayer'sBlessedArmor" value: { - dps: 6043.88295 - tps: 3285.16169 + dps: 6043.91705 + tps: 3559.43808 } } dps_results: { key: "TestEnhancement-AllItems-Val'anyr,HammerofAncientKings-46017" value: { - dps: 7794.97152 - tps: 4283.14429 + dps: 7795.02818 + tps: 4669.09218 } } dps_results: { key: "TestEnhancement-AllItems-WingedTalisman-37844" value: { - dps: 7487.11256 - tps: 4091.68423 + dps: 7487.16643 + tps: 4452.09045 } } dps_results: { key: "TestEnhancement-AllItems-WorldbreakerBattlegear" value: { - dps: 7298.40397 - tps: 4011.40106 + dps: 7298.45886 + tps: 4357.65686 } } dps_results: { key: "TestEnhancement-AllItems-WorldbreakerGarb" value: { - dps: 7001.1038 - tps: 3863.90387 + dps: 7001.16635 + tps: 4140.84415 } } dps_results: { key: "TestEnhancement-AllItems-WrathfulGladiator'sTotemofSurvival-51513" value: { - dps: 7684.9528 - tps: 4229.16396 + dps: 7685.00802 + tps: 4600.42904 } } dps_results: { key: "TestEnhancement-Average-Default" value: { - dps: 7620.23338 - tps: 4189.58851 + dps: 7620.26411 + tps: 4565.62899 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_ft-FullBuffs-LongMultiTarget" value: { - dps: 26249.60367 - tps: 15742.56368 + dps: 26249.72731 + tps: 16118.60862 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_ft-FullBuffs-LongSingleTarget" value: { - dps: 7699.28044 - tps: 4191.54959 + dps: 7699.33608 + tps: 4565.63209 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_ft-FullBuffs-ShortSingleTarget" value: { - dps: 9594.52738 - tps: 4589.07833 + dps: 9594.59562 + tps: 5020.09434 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_ft-NoBuffs-LongMultiTarget" value: { - dps: 13757.65417 - tps: 8878.03048 + dps: 13763.46534 + tps: 9089.71623 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_ft-NoBuffs-LongSingleTarget" value: { - dps: 4017.85506 - tps: 2137.41962 + dps: 4015.91067 + tps: 2346.86625 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_ft-NoBuffs-ShortSingleTarget" value: { - dps: 5212.25755 - tps: 2446.17435 + dps: 5212.29144 + tps: 2660.48211 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_wf-FullBuffs-LongMultiTarget" value: { - dps: 25721.96031 - tps: 15476.15133 + dps: 25722.08226 + tps: 15850.30265 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_wf-FullBuffs-LongSingleTarget" value: { - dps: 7766.49597 - tps: 4240.93173 + dps: 7766.55218 + tps: 4614.97344 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_wf-FullBuffs-ShortSingleTarget" value: { - dps: 9624.58938 - tps: 4617.23092 + dps: 9624.65799 + tps: 5045.77593 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_wf-NoBuffs-LongMultiTarget" value: { - dps: 13174.37953 - tps: 8428.77325 + dps: 13163.13171 + tps: 8633.56542 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_wf-NoBuffs-LongSingleTarget" value: { - dps: 4060.00792 - tps: 2165.3211 + dps: 4059.72286 + tps: 2376.09695 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-default_wf-NoBuffs-ShortSingleTarget" value: { - dps: 5326.50631 - tps: 2516.33238 + dps: 5326.54097 + tps: 2735.10182 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-phase_3-FullBuffs-LongMultiTarget" value: { - dps: 26091.51726 - tps: 15708.87515 + dps: 26091.64018 + tps: 16081.41792 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-phase_3-FullBuffs-LongSingleTarget" value: { - dps: 7666.34338 - tps: 4175.88237 + dps: 7666.39868 + tps: 4546.66377 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-phase_3-FullBuffs-ShortSingleTarget" value: { - dps: 9555.6372 - tps: 4561.71596 + dps: 9555.70497 + tps: 4989.89658 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-phase_3-NoBuffs-LongMultiTarget" value: { - dps: 13560.54839 - tps: 8686.55786 + dps: 13559.77145 + tps: 8900.36759 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-phase_3-NoBuffs-LongSingleTarget" value: { - dps: 3993.21052 - tps: 2117.37687 + dps: 3992.93883 + tps: 2325.64352 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-FT-phase_3-NoBuffs-ShortSingleTarget" value: { - dps: 5223.4731 - tps: 2458.82795 + dps: 5223.50686 + tps: 2672.65427 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_ft-FullBuffs-LongMultiTarget" value: { - dps: 21768.03231 - tps: 13251.18925 + dps: 21768.14853 + tps: 13630.82366 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_ft-FullBuffs-LongSingleTarget" value: { - dps: 6549.52793 - tps: 3502.42615 + dps: 6549.58353 + tps: 3880.18754 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_ft-FullBuffs-ShortSingleTarget" value: { - dps: 8493.19042 - tps: 3913.3226 + dps: 8493.26029 + tps: 4354.11574 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_ft-NoBuffs-LongMultiTarget" value: { - dps: 10679.7829 - tps: 7426.73635 + dps: 10679.68338 + tps: 7595.27798 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_ft-NoBuffs-LongSingleTarget" value: { - dps: 2993.07639 - tps: 1630.34376 + dps: 2996.21675 + tps: 1794.37111 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_ft-NoBuffs-ShortSingleTarget" value: { - dps: 4015.50326 - tps: 1886.07417 + dps: 4015.53509 + tps: 2052.20641 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_wf-FullBuffs-LongMultiTarget" value: { - dps: 20979.12553 - tps: 12736.51577 + dps: 20979.23936 + tps: 13117.35913 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_wf-FullBuffs-LongSingleTarget" value: { - dps: 6639.63523 - tps: 3568.23371 + dps: 6639.69163 + tps: 3946.78008 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_wf-FullBuffs-ShortSingleTarget" value: { - dps: 8619.46862 - tps: 4003.93719 + dps: 8619.5394 + tps: 4445.01481 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_wf-NoBuffs-LongMultiTarget" value: { - dps: 9927.93938 - tps: 6911.53506 + dps: 9926.88955 + tps: 7086.87277 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_wf-NoBuffs-LongSingleTarget" value: { - dps: 3042.35975 - tps: 1663.03992 + dps: 3044.1999 + tps: 1828.15167 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-default_wf-NoBuffs-ShortSingleTarget" value: { - dps: 4086.67052 - tps: 1937.48807 + dps: 4086.70298 + tps: 2104.42225 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-phase_3-FullBuffs-LongMultiTarget" value: { - dps: 21334.49142 - tps: 12921.37943 + dps: 21334.60591 + tps: 13299.13823 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-phase_3-FullBuffs-LongSingleTarget" value: { - dps: 6516.21269 - tps: 3486.84939 + dps: 6516.26788 + tps: 3860.91745 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-phase_3-FullBuffs-ShortSingleTarget" value: { - dps: 8435.06146 - tps: 3889.97406 + dps: 8435.13083 + tps: 4325.33426 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-phase_3-NoBuffs-LongMultiTarget" value: { - dps: 10411.97261 - tps: 7210.32116 + dps: 10414.33237 + tps: 7380.13889 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-phase_3-NoBuffs-LongSingleTarget" value: { - dps: 2984.25684 - tps: 1620.45335 + dps: 2986.01548 + tps: 1784.0936 } } dps_results: { key: "TestEnhancement-Settings-Orc-p1-WF-phase_3-NoBuffs-ShortSingleTarget" value: { - dps: 4062.06457 - tps: 1927.93793 + dps: 4062.09662 + tps: 2094.26622 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_ft-FullBuffs-LongMultiTarget" value: { - dps: 25997.44452 - tps: 15825.85704 + dps: 25997.56786 + tps: 16202.46462 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_ft-FullBuffs-LongSingleTarget" value: { - dps: 7599.31041 - tps: 4179.40126 + dps: 7599.36593 + tps: 4554.96973 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_ft-FullBuffs-ShortSingleTarget" value: { - dps: 9595.81365 - tps: 4696.34995 + dps: 9595.8833 + tps: 5146.67199 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_ft-NoBuffs-LongMultiTarget" value: { - dps: 13325.24085 - tps: 8665.19533 + dps: 13310.12383 + tps: 8871.98313 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_ft-NoBuffs-LongSingleTarget" value: { - dps: 3978.60659 - tps: 2141.40901 + dps: 3974.18198 + tps: 2352.45029 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_ft-NoBuffs-ShortSingleTarget" value: { - dps: 5164.14909 - tps: 2505.77375 + dps: 5164.18366 + tps: 2730.35194 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_wf-FullBuffs-LongMultiTarget" value: { - dps: 25348.82592 - tps: 15322.82423 + dps: 25348.94745 + tps: 15701.96251 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_wf-FullBuffs-LongSingleTarget" value: { - dps: 7674.98308 - tps: 4232.62599 + dps: 7675.03918 + tps: 4607.29109 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_wf-FullBuffs-ShortSingleTarget" value: { - dps: 9613.88549 - tps: 4718.42972 + dps: 9613.95526 + tps: 5168.68323 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_wf-NoBuffs-LongMultiTarget" value: { - dps: 12965.11429 - tps: 8435.1971 + dps: 12953.03505 + tps: 8646.67606 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_wf-NoBuffs-LongSingleTarget" value: { - dps: 4038.6084 - tps: 2184.45165 + dps: 4038.64877 + tps: 2397.35028 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-default_wf-NoBuffs-ShortSingleTarget" value: { - dps: 5238.98494 - tps: 2547.45399 + dps: 5239.02002 + tps: 2774.64476 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-phase_3-FullBuffs-LongMultiTarget" value: { - dps: 25686.13096 - tps: 15536.37253 + dps: 25686.2533 + tps: 15914.46641 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-phase_3-FullBuffs-LongSingleTarget" value: { - dps: 7631.1628 - tps: 4205.88127 + dps: 7631.21841 + tps: 4582.12617 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-phase_3-FullBuffs-ShortSingleTarget" value: { - dps: 9502.01038 - tps: 4655.77643 + dps: 9502.07918 + tps: 5098.96327 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-phase_3-NoBuffs-LongMultiTarget" value: { - dps: 13362.97349 - tps: 8674.49828 + dps: 13363.28434 + tps: 8894.11584 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-phase_3-NoBuffs-LongSingleTarget" value: { - dps: 3937.59259 - tps: 2118.11034 + dps: 3940.4125 + tps: 2331.10205 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-FT-phase_3-NoBuffs-ShortSingleTarget" value: { - dps: 5145.52344 - tps: 2485.04316 + dps: 5145.55745 + tps: 2701.72676 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_ft-FullBuffs-LongMultiTarget" value: { - dps: 21508.47681 - tps: 13148.64825 + dps: 21508.59245 + tps: 13528.58401 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_ft-FullBuffs-LongSingleTarget" value: { - dps: 6494.30745 - tps: 3492.82616 + dps: 6494.3631 + tps: 3872.94901 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_ft-FullBuffs-ShortSingleTarget" value: { - dps: 8395.79942 - tps: 3915.29181 + dps: 8395.86974 + tps: 4368.40094 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_ft-NoBuffs-LongMultiTarget" value: { - dps: 10516.84746 - tps: 7347.45431 + dps: 10519.26364 + tps: 7518.86815 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_ft-NoBuffs-LongSingleTarget" value: { - dps: 2969.44202 - tps: 1628.10401 + dps: 2969.46751 + tps: 1791.78993 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_ft-NoBuffs-ShortSingleTarget" value: { - dps: 3968.80449 - tps: 1897.27885 + dps: 3968.83643 + tps: 2068.36286 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_wf-FullBuffs-LongMultiTarget" value: { - dps: 21058.37728 - tps: 12907.98965 + dps: 21058.4915 + tps: 13292.74186 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_wf-FullBuffs-LongSingleTarget" value: { - dps: 6562.69585 - tps: 3550.39829 + dps: 6562.75204 + tps: 3928.68293 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_wf-FullBuffs-ShortSingleTarget" value: { - dps: 8475.83432 - tps: 3978.75402 + dps: 8475.90527 + tps: 4431.08666 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_wf-NoBuffs-LongMultiTarget" value: { - dps: 9894.60901 - tps: 6972.19506 + dps: 9901.12513 + tps: 7151.10988 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_wf-NoBuffs-LongSingleTarget" value: { - dps: 3031.30887 - tps: 1671.98393 + dps: 3030.88243 + tps: 1836.21597 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-default_wf-NoBuffs-ShortSingleTarget" value: { - dps: 4042.5674 - tps: 1947.16305 + dps: 4042.59997 + tps: 2118.5086 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-phase_3-FullBuffs-LongMultiTarget" value: { - dps: 21387.2867 - tps: 13085.27147 + dps: 21387.40171 + tps: 13467.73833 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-phase_3-FullBuffs-LongSingleTarget" value: { - dps: 6495.16588 - tps: 3495.71092 + dps: 6495.22137 + tps: 3875.74041 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-phase_3-FullBuffs-ShortSingleTarget" value: { - dps: 8429.4497 - tps: 3953.50633 + dps: 8429.51999 + tps: 4410.77629 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-phase_3-NoBuffs-LongMultiTarget" value: { - dps: 10330.30617 - tps: 7176.61741 + dps: 10322.63124 + tps: 7347.65055 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-phase_3-NoBuffs-LongSingleTarget" value: { - dps: 2936.54919 - tps: 1604.65442 + dps: 2936.57426 + tps: 1768.19472 } } dps_results: { key: "TestEnhancement-Settings-Troll-p1-WF-phase_3-NoBuffs-ShortSingleTarget" value: { - dps: 4030.64483 - tps: 1946.11958 + dps: 4030.67707 + tps: 2119.91451 } } dps_results: { key: "TestEnhancement-SwitchInFrontOfTarget-Default" value: { - dps: 7261.95773 - tps: 3971.59846 + dps: 7262.01053 + tps: 4325.07316 } } diff --git a/sim/shaman/enhancement/enhancement.go b/sim/shaman/enhancement/enhancement.go index 8ac1b78112..70502026ef 100644 --- a/sim/shaman/enhancement/enhancement.go +++ b/sim/shaman/enhancement/enhancement.go @@ -136,12 +136,15 @@ func (enh *EnhancementShaman) Initialize() { }) } enh.DelayDPSCooldowns(3 * time.Second) + enh.RegisterPrepullAction(-time.Second, func(sim *core.Simulation) { + enh.ItemSwap.SwapItems(sim, []proto.ItemSlot{proto.ItemSlot_ItemSlotMainHand, proto.ItemSlot_ItemSlotOffHand}, false) + }) } func (enh *EnhancementShaman) Reset(sim *core.Simulation) { enh.previousSwingAt = 0 enh.Shaman.Reset(sim) - enh.ItemSwap.SwapItems(sim, []proto.ItemSlot{proto.ItemSlot_ItemSlotMainHand, proto.ItemSlot_ItemSlotOffHand}, false) + } func (enh *EnhancementShaman) AutoSyncWeapons() proto.ShamanSyncType { diff --git a/sim/shaman/shaman.go b/sim/shaman/shaman.go index 25ee1f5ea6..ba053aaea1 100644 --- a/sim/shaman/shaman.go +++ b/sim/shaman/shaman.go @@ -262,10 +262,6 @@ func (shaman *Shaman) Initialize() { shaman.setupProcTrackers() } - if shaman.Talents.SpiritWeapons { - shaman.PseudoStats.ThreatMultiplier -= 0.3 - } - // Healing stream totem applies a HoT (aura) and so needs to be handled as a pre-pull action // instead of during init/reset. if shaman.Totems.Water == proto.WaterTotem_HealingStreamTotem { diff --git a/sim/shaman/talents.go b/sim/shaman/talents.go index 76b7675b18..0ea408dbbd 100644 --- a/sim/shaman/talents.go +++ b/sim/shaman/talents.go @@ -39,16 +39,15 @@ func (shaman *Shaman) ApplyTalents() { shaman.AddStatDependency(stats.AttackPower, stats.SpellPower, 0.1*float64(shaman.Talents.MentalQuickness)) } if shaman.Talents.MentalDexterity > 0 { - shaman.AddStatDependency(stats.Intellect, stats.AttackPower, 0.3333*float64(shaman.Talents.MentalDexterity)) + shaman.AddStatDependency(stats.Intellect, stats.AttackPower, []float64{0, 0.33, 0.66, 1}[shaman.Talents.MentalDexterity]) } if shaman.Talents.NaturesBlessing > 0 { shaman.AddStatDependency(stats.Intellect, stats.SpellPower, 0.1*float64(shaman.Talents.NaturesBlessing)) } if shaman.Talents.SpiritWeapons { + shaman.PseudoStats.ThreatMultiplier *= 0.7 shaman.PseudoStats.CanParry = true - shaman.AutoAttacks.MHConfig().ThreatMultiplier *= 0.7 // TODO this looks fishy - shaman.AutoAttacks.OHConfig().ThreatMultiplier *= 0.7 } shaman.applyElementalFocus() diff --git a/ui/core/components/exporters.ts b/ui/core/components/exporters.ts index 59c03a3b55..31a0229ca6 100644 --- a/ui/core/components/exporters.ts +++ b/ui/core/components/exporters.ts @@ -199,7 +199,7 @@ export class IndividualWowheadGearPlannerExporter extends slotId = slotId | 0b10000000; } bytes.push(slotId); - bytes.push(item.curGems(isBlacksmithing).length << 5); + bytes.push(item.curEquippedGems(isBlacksmithing).length << 5); bytes = bytes.concat(to2Bytes(item.item.id)); if (item.enchant) { diff --git a/ui/core/components/individual_sim_ui/apl_helpers.ts b/ui/core/components/individual_sim_ui/apl_helpers.ts index 0664a21a38..fbed95b667 100644 --- a/ui/core/components/individual_sim_ui/apl_helpers.ts +++ b/ui/core/components/individual_sim_ui/apl_helpers.ts @@ -12,7 +12,7 @@ import { ActionID } from '../../proto/common.js'; import { BooleanPicker } from '../boolean_picker.js'; import { APLValueRuneSlot, APLValueRuneType } from '../../proto/apl.js'; -export type ACTION_ID_SET = 'auras' | 'stackable_auras' | 'icd_auras' | 'exclusive_effect_auras' | 'castable_spells' | 'channel_spells' | 'dot_spells' | 'shield_spells'; +export type ACTION_ID_SET = 'auras' | 'stackable_auras' | 'icd_auras' | 'exclusive_effect_auras' | 'spells' | 'castable_spells' | 'channel_spells' | 'dot_spells' | 'shield_spells' | 'non_instant_spells'; const actionIdSets: Record { + return metadata.getSpells().filter(spell => spell.data.isCastable).map(actionId => { + return { + value: actionId.id, + }; + }); + }, + }, 'castable_spells': { defaultLabel: 'Spell', getActionIDs: async (metadata) => { @@ -74,10 +85,12 @@ const actionIdSets: Record { return { value: actionId.id, + submenu: ['Spells'], extraCssClasses: (actionId.data.prepullOnly ? ['apl-prepull-actions-only'] : (actionId.data.encounterOnly @@ -88,10 +101,12 @@ const actionIdSets: Record { return { value: actionId.id, + submenu: ['Cooldowns'], extraCssClasses: (actionId.data.prepullOnly ? ['apl-prepull-actions-only'] : (actionId.data.encounterOnly @@ -102,16 +117,28 @@ const actionIdSets: Record { return { value: actionId, + submenu: ['Placeholders'], tooltip: 'The Prepull Potion if CurrentTime < 0, or the Combat Potion if combat has started.', }; }), ].flat(); }, }, + 'non_instant_spells': { + defaultLabel: 'Non-instant Spell', + getActionIDs: async (metadata) => { + return metadata.getSpells().filter(spell => spell.data.isCastable && spell.data.hasCastTime).map(actionId => { + return { + value: actionId.id, + }; + }); + }, + }, 'channel_spells': { defaultLabel: 'Channeled Spell', getActionIDs: async (metadata) => { diff --git a/ui/core/components/individual_sim_ui/apl_values.ts b/ui/core/components/individual_sim_ui/apl_values.ts index 1143277884..a74c7a6aca 100644 --- a/ui/core/components/individual_sim_ui/apl_values.ts +++ b/ui/core/components/individual_sim_ui/apl_values.ts @@ -75,6 +75,8 @@ import { APLValueWarlockShouldRecastDrainSoul, APLValueWarlockShouldRefreshCorruption, APLValueCatNewSavageRoarDuration, + APLValueBossSpellTimeToReady, + APLValueBossSpellIsCasting, } from '../../proto/apl.js'; import { EventID } from '../../typed_event.js'; @@ -554,6 +556,28 @@ const valueKindFactories: {[f in NonNullable]: ValueKindConfig { - return (this._gems.filter(g => g != null) as Array).slice(0, this.numSockets(isBlacksmithing)); + curGems(isBlacksmithing: boolean): Array { + return this._gems.slice(0, this.numSockets(isBlacksmithing)); + } + curEquippedGems(isBlacksmithing: boolean): Array { + return this.curGems(isBlacksmithing).filter(g => g != null) as Array; } getProfessionRequirements(): Array { diff --git a/ui/core/proto_utils/gear.ts b/ui/core/proto_utils/gear.ts index a242fdfefe..bc5cb807e7 100644 --- a/ui/core/proto_utils/gear.ts +++ b/ui/core/proto_utils/gear.ts @@ -170,7 +170,7 @@ export class Gear extends BaseGear { getAllGems(isBlacksmithing: boolean): Array { return this.asArray() - .map(ei => ei == null ? [] : ei.curGems(isBlacksmithing)) + .map(ei => ei == null ? [] : ei.curEquippedGems(isBlacksmithing)) .flat(); } @@ -377,7 +377,7 @@ export class ItemSwapGear extends BaseGear { return SimDatabase.create({ items: distinct(equippedItems.map(ei => ItemSwapGear.itemToDB(ei.item))), enchants: distinct(equippedItems.filter(ei => ei.enchant).map(ei => ItemSwapGear.enchantToDB(ei.enchant!))), - gems: distinct(equippedItems.map(ei => ei.curGems(true).map(gem => ItemSwapGear.gemToDB(gem))).flat()), + gems: distinct(equippedItems.map(ei => ei.curEquippedGems(true).map(gem => ItemSwapGear.gemToDB(gem))).flat()), }); } } diff --git a/ui/elemental_shaman/apls/advanced.apl.json b/ui/elemental_shaman/apls/advanced.apl.json index 5c378faff0..3240d5bc13 100644 --- a/ui/elemental_shaman/apls/advanced.apl.json +++ b/ui/elemental_shaman/apls/advanced.apl.json @@ -2,25 +2,27 @@ "enabled": true, "type": "TypeAPL", "prepullActions": [ - {"action":{"castSpell":{"spellId":{"spellId":59159}}},"doAtValue":{"const":{"val":"-5s"}}}, - {"action":{"castSpell":{"spellId":{"otherId":"OtherActionPotion"}}},"doAtValue":{"const":{"val":"-1s"}}}, - {"action":{"castSpell":{"spellId":{"spellId":49238}}},"doAtValue":{"const":{"val":"-1.00s"}}} + {"action":{"castSpell":{"spellId":{"spellId":59159}}},"doAtValue":{"const":{"val":"-5"}}}, + {"action":{"castSpell":{"spellId":{"spellId":49238}}},"doAtValue":{"const":{"val":"-3.5"}}}, + {"action":{"castSpell":{"spellId":{"spellId":49271}}},"doAtValue":{"const":{"val":"-1.5"}}} ], "priorityList": [ - {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"0s"}}}},{"spellIsReady":{"spellId":{"spellId":2825,"tag":-1}}}]}},"castSpell":{"spellId":{"spellId":2825,"tag":-1}}}}, - {"hide":true,"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"2s"}}}},{"spellIsReady":{"spellId":{"spellId":2825}}}]}},"castSpell":{"spellId":{"spellId":2825}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"spellId":16166}}},{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49238}}},"rhs":{"const":{"val":"1.0s"}}}}]}},"castSpell":{"spellId":{"spellId":16166}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"spellId":54758}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}}}},{"cmp":{"op":"OpGe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"41s"}}}}]}},"castSpell":{"spellId":{"spellId":54758}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"spellId":2894}}},{"or":{"vals":[{"auraIsActive":{"auraId":{"spellId":60494}}},{"auraIsActive":{"auraId":{"spellId":60064}}},{"auraIsActive":{"auraId":{"itemId":37660}}},{"auraIsActive":{"auraId":{"spellId":64713}}},{"auraIsActive":{"auraId":{"spellId":75466}}},{"auraIsActive":{"auraId":{"spellId":75473}}},{"auraIsActive":{"auraId":{"itemId":47213}}},{"auraIsActive":{"auraId":{"itemId":45490}}},{"auraIsActive":{"auraId":{"spellId":71605}}},{"auraIsActive":{"auraId":{"spellId":71636}}},{"auraIsActive":{"auraId":{"spellId":71570}}},{"auraIsActive":{"auraId":{"spellId":71572}}},{"auraIsActive":{"auraId":{"spellId":72416}}},{"cmp":{"op":"OpEq","lhs":{"auraNumStacks":{"auraId":{"itemId":50353}}},"rhs":{"const":{"val":"9"}}}},{"cmp":{"op":"OpEq","lhs":{"auraNumStacks":{"auraId":{"itemId":50348}}},"rhs":{"const":{"val":"9"}}}},{"cmp":{"op":"OpEq","lhs":{"auraNumStacks":{"auraId":{"spellId":60486}}},"rhs":{"const":{"val":"10"}}}}]}}]}},"strictSequence":{"actions":[{"castSpell":{"spellId":{"spellId":33697}}},{"castSpell":{"spellId":{"itemId":40212}}},{"castSpell":{"spellId":{"itemId":37873}}},{"castSpell":{"spellId":{"itemId":45148}}},{"castSpell":{"spellId":{"itemId":48724}}},{"castSpell":{"spellId":{"itemId":50357}}},{"castSpell":{"spellId":{"spellId":2894}}}]}}}, - {"action":{"condition":{"and":{"vals":[{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2894}}}}},{"not":{"val":{"dotIsActive":{"spellId":{"spellId":58704}}}}},{"cmp":{"op":"OpGe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"120"}}}},{"cmp":{"op":"OpGe","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"20s"}}}}]}},"castSpell":{"spellId":{"spellId":58704}}}}, - {"action":{"condition":{"and":{"vals":[{"not":{"val":{"dotIsActive":{"spellId":{"spellId":49233}}}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"3s"}}}}]}},"multidot":{"spellId":{"spellId":49233},"maxDots":3,"maxOverlap":{"const":{"val":"10ms"}}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"spellId":49271}}},{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49271}}},"rhs":{"const":{"val":".92s"}}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":".98s"}}}},{"not":{"val":{"spellIsReady":{"spellId":{"spellId":60043}}}}}]}},"castSpell":{"spellId":{"spellId":49271}}}}, - {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGt","lhs":{"dotRemainingTime":{"spellId":{"spellId":49233}}},"rhs":{"const":{"val":".98s"}}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":".98s"}}}},{"spellIsReady":{"spellId":{"spellId":60043}}}]}},"castSpell":{"spellId":{"spellId":60043}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"itemId":40211}}},{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49238}}},"rhs":{"const":{"val":"1.00s"}}}}]}},"castSpell":{"spellId":{"itemId":40211}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"spellId":33697}}},{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"60s"}}}}]}},"castSpell":{"spellId":{"spellId":33697}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"itemId":42641}}}]}},"castSpell":{"spellId":{"itemId":42641}}}}, - {"action":{"condition":{"and":{"vals":[{"spellIsReady":{"spellId":{"itemId":41119}}},{"not":{"val":{"spellIsReady":{"spellId":{"itemId":42641}}}}}]}},"castSpell":{"spellId":{"itemId":41119}}}}, - {"action":{"condition":{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"1.25s"}}}},"castSpell":{"spellId":{"spellId":49238}}}}, - {"action":{"condition":{"cmp":{"op":"OpLe","lhs":{"remainingTime":{}},"rhs":{"const":{"val":".97s"}}}},"castSpell":{"spellId":{"spellId":49236}}}} + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"0s"}}}}]}},"castSpell":{"spellId":{"spellId":2825,"tag":-1}}}}, + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"0s"}}}}]}},"castSpell":{"spellId":{"spellId":2825}}}}, + {"action":{"condition":{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49238}}},"rhs":{"const":{"val":"1.1s"}}}},"castSpell":{"spellId":{"spellId":16166}}}}, + {"action":{"condition":{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49238}}},"rhs":{"const":{"val":"1.1s"}}}},"castSpell":{"spellId":{"spellId":54758}}}}, + {"action":{"condition":{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49238}}},"rhs":{"const":{"val":"1.1s"}}}},"castSpell":{"spellId":{"spellId":26297}}}}, + {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":60479}}},{"auraIsActive":{"auraId":{"spellId":60064}}},{"auraIsActive":{"auraId":{"spellId":60494}}},{"auraIsActive":{"auraId":{"spellId":64741}}},{"auraIsActive":{"auraId":{"spellId":64713}}},{"auraIsActive":{"auraId":{"spellId":67669}}},{"auraIsActive":{"auraId":{"spellId":71605}}},{"auraIsActive":{"auraId":{"spellId":71636}}},{"auraIsActive":{"auraId":{"spellId":75466}}},{"auraIsActive":{"auraId":{"spellId":75473}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":40432}}},"rhs":{"const":{"val":"10"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":45308}}},"rhs":{"const":{"val":"5"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":50340}}},"rhs":{"const":{"val":"10"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":50345}}},"rhs":{"const":{"val":"10"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":50353}}},"rhs":{"const":{"val":"10"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":50348}}},"rhs":{"const":{"val":"10"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":60479}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":60479}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":60064}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":60064}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":60494}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":60494}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":64741}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":64741}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":64713}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":64713}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":67669}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":67669}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":71605}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":71605}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":71636}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":71636}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":75466}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":75466}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":75473}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":75473}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"itemId":50353}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"itemId":50353}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"itemId":50348}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"itemId":50348}}},"rhs":{"const":{"val":"1s"}}}}]}},{"and":{"vals":[{"auraIsActive":{"auraId":{"itemId":40212}}},{"or":{"vals":[{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":55637}}},{"auraIsActive":{"auraId":{"spellId":72416}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"itemId":40212}}},"rhs":{"const":{"val":"1s"}}}}]}},{"cmp":{"op":"OpLe","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"120s"}}}}]}},{"or":{"vals":[{"auraIsActive":{"auraId":{"spellId":60479}}},{"auraIsActive":{"auraId":{"spellId":60064}}},{"auraIsActive":{"auraId":{"spellId":60494}}},{"auraIsActive":{"auraId":{"spellId":64741}}},{"auraIsActive":{"auraId":{"spellId":64713}}},{"auraIsActive":{"auraId":{"spellId":67669}}},{"auraIsActive":{"auraId":{"spellId":71605}}},{"auraIsActive":{"auraId":{"spellId":71636}}},{"auraIsActive":{"auraId":{"spellId":75466}}},{"auraIsActive":{"auraId":{"spellId":75473}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":40432}}},"rhs":{"const":{"val":"10"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":45308}}},"rhs":{"const":{"val":"5"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":50340}}},"rhs":{"const":{"val":"10"}}}},{"cmp":{"op":"OpGe","lhs":{"auraNumStacks":{"auraId":{"itemId":50345}}},"rhs":{"const":{"val":"10"}}}}]}}]}}]}}]}},"strictSequence":{"actions":[{"castSpell":{"spellId":{"spellId":33697}}},{"castSpell":{"spellId":{"itemId":37873}}},{"castSpell":{"spellId":{"itemId":45148}}},{"castSpell":{"spellId":{"itemId":48724}}},{"castSpell":{"spellId":{"itemId":50357}}},{"castSpell":{"spellId":{"spellId":2894}}}]}}}, + {"action":{"condition":{"and":{"vals":[{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2894}}}}},{"not":{"val":{"spellIsReady":{"spellId":{"spellId":2894}}}}},{"not":{"val":{"dotIsActive":{"spellId":{"spellId":58704}}}}},{"not":{"val":{"dotIsActive":{"spellId":{"spellId":58734}}}}}]}},"castSpell":{"spellId":{"spellId":58704}}}}, + {"action":{"multidot":{"spellId":{"spellId":49233},"maxDots":3,"maxOverlap":{"const":{"val":"250ms"}}}}}, + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGt","lhs":{"dotRemainingTime":{"spellId":{"spellId":49233}}},"rhs":{"spellCastTime":{"spellId":{"spellId":60043}}}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"spellCastTime":{"spellId":{"spellId":60043}}}}}]}},"castSpell":{"spellId":{"spellId":60043}}}}, + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49271}}},"rhs":{"const":{"val":".92s"}}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"spellCastTime":{"spellId":{"spellId":49271}}}}},{"cmp":{"op":"OpGe","lhs":{"currentManaPercent":{}},"rhs":{"math":{"op":"OpAdd","lhs":{"remainingTimePercent":{}},"rhs":{"const":{"val":"4%"}}}}}}]}},"castSpell":{"spellId":{"spellId":49271}}}}, + {"action":{"condition":{"cmp":{"op":"OpGe","lhs":{"spellCastTime":{"spellId":{"spellId":49238}}},"rhs":{"const":{"val":"1.00s"}}}},"castSpell":{"spellId":{"itemId":40211}}}}, + {"action":{"condition":{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"60s"}}}},"castSpell":{"spellId":{"spellId":33697}}}}, + {"action":{"castSpell":{"spellId":{"itemId":42641}}}}, + {"action":{"castSpell":{"spellId":{"itemId":41119}}}}, + {"action":{"condition":{"cmp":{"op":"OpLe","lhs":{"remainingTime":{}},"rhs":{"spellCastTime":{"spellId":{"spellId":49238}}}}},"castSpell":{"spellId":{"spellId":49236}}}}, + {"action":{"castSpell":{"spellId":{"spellId":49238}}}}, + {"action":{"castSpell":{"spellId":{"spellId":59159}}}} ] -} \ No newline at end of file +} diff --git a/ui/elemental_shaman/presets.ts b/ui/elemental_shaman/presets.ts index febf62e60f..ba40cbe940 100644 --- a/ui/elemental_shaman/presets.ts +++ b/ui/elemental_shaman/presets.ts @@ -71,25 +71,10 @@ export const ROTATION_PRESET_ADVANCED = PresetUtils.makePresetAPLRotation('Advan // https://wowhead.com/wotlk/talent-calc and copy the numbers in the url. export const StandardTalents = { name: 'Standard', - data: SavedTalents.create({ - talentsString: '0532001523212351322301351-005052031', - glyphs: Glyphs.create({ - major1: ShamanMajorGlyph.GlyphOfLava, - major2: ShamanMajorGlyph.GlyphOfTotemOfWrath, - major3: ShamanMajorGlyph.GlyphOfLightningBolt, - minor1: ShamanMinorGlyph.GlyphOfThunderstorm, - minor2: ShamanMinorGlyph.GlyphOfWaterShield, - minor3: ShamanMinorGlyph.GlyphOfGhostWolf, - }), - }), -}; - -export const Phase4Talents = { - name: 'Phase 4', data: SavedTalents.create({ talentsString: '0533001523213351322301351-005050031', glyphs: Glyphs.create({ - major1: ShamanMajorGlyph.GlyphOfFlameShock, + major1: ShamanMajorGlyph.GlyphOfFlametongueWeapon, major2: ShamanMajorGlyph.GlyphOfTotemOfWrath, major3: ShamanMajorGlyph.GlyphOfLightningBolt, minor1: ShamanMinorGlyph.GlyphOfThunderstorm, diff --git a/ui/elemental_shaman/sim.ts b/ui/elemental_shaman/sim.ts index 2982c4acff..8218352fd4 100644 --- a/ui/elemental_shaman/sim.ts +++ b/ui/elemental_shaman/sim.ts @@ -158,7 +158,6 @@ export class ElementalShamanSimUI extends IndividualSimUI({ - fieldName: 'customRotation', - numColumns: 3, - values: [ - { actionId: ActionId.fromSpellId(57823), value: SpellOption.Revenge }, - { actionId: ActionId.fromSpellId(47488), value: SpellOption.ShieldSlam }, - { actionId: ActionId.fromSpellId(47440), value: SpellOption.Shout }, - { actionId: ActionId.fromSpellId(47502), value: SpellOption.ThunderClap }, - { actionId: ActionId.fromSpellId(25203), value: SpellOption.DemoralizingShout }, - { actionId: ActionId.fromSpellId(47486), value: SpellOption.MortalStrike }, - { actionId: ActionId.fromSpellId(47498), value: SpellOption.Devastate }, - { actionId: ActionId.fromSpellId(47467), value: SpellOption.SunderArmor }, - { actionId: ActionId.fromSpellId(12809), value: SpellOption.ConcussionBlow }, - { actionId: ActionId.fromSpellId(46968), value: SpellOption.Shockwave }, - ], - }), - InputHelpers.makeRotationNumberInput({ - fieldName: 'hsRageThreshold', - label: 'HS rage threshold', - labelTooltip: 'Heroic Strike when rage is above:', - }), - InputHelpers.makeRotationBooleanInput({ - fieldName: 'prioSslamOnShieldBlock', - label: 'Prio SSlam on Shield Block', - labelTooltip: 'The rotation code will prio SSlam over Revenge during active shield block windows.', - }), - InputHelpers.makeRotationEnumInput({ - fieldName: 'demoShoutChoice', - label: 'Demo Shout', - values: [ - { name: 'Never', value: DemoShoutChoice.DemoShoutChoiceNone }, - { name: 'Maintain Debuff', value: DemoShoutChoice.DemoShoutChoiceMaintain }, - { name: 'Filler', value: DemoShoutChoice.DemoShoutChoiceFiller }, - ], - }), - InputHelpers.makeRotationEnumInput({ - fieldName: 'thunderClapChoice', - label: 'Thunder Clap', - values: [ - { name: 'Never', value: ThunderClapChoice.ThunderClapChoiceNone }, - { name: 'Maintain Debuff', value: ThunderClapChoice.ThunderClapChoiceMaintain }, - { name: 'On CD', value: ThunderClapChoice.ThunderClapChoiceOnCD }, - ], - }), + // TODO: Currently these are unhooked and not configurable in Simple mode. + // InputHelpers.makeCustomRotationInput({ + // fieldName: 'customRotation', + // numColumns: 3, + // values: [ + // { actionId: ActionId.fromSpellId(57823), value: SpellOption.Revenge }, + // { actionId: ActionId.fromSpellId(47488), value: SpellOption.ShieldSlam }, + // { actionId: ActionId.fromSpellId(47440), value: SpellOption.Shout }, + // { actionId: ActionId.fromSpellId(47502), value: SpellOption.ThunderClap }, + // { actionId: ActionId.fromSpellId(25203), value: SpellOption.DemoralizingShout }, + // { actionId: ActionId.fromSpellId(47486), value: SpellOption.MortalStrike }, + // { actionId: ActionId.fromSpellId(47498), value: SpellOption.Devastate }, + // { actionId: ActionId.fromSpellId(47467), value: SpellOption.SunderArmor }, + // { actionId: ActionId.fromSpellId(12809), value: SpellOption.ConcussionBlow }, + // { actionId: ActionId.fromSpellId(46968), value: SpellOption.Shockwave }, + // ], + // }), + // InputHelpers.makeRotationNumberInput({ + // fieldName: 'hsRageThreshold', + // label: 'HS rage threshold', + // labelTooltip: 'Heroic Strike when rage is above:', + // }), + // InputHelpers.makeRotationBooleanInput({ + // fieldName: 'prioSslamOnShieldBlock', + // label: 'Prio SSlam on Shield Block', + // labelTooltip: 'The rotation code will prio SSlam over Revenge during active shield block windows.', + // }), + // InputHelpers.makeRotationEnumInput({ + // fieldName: 'demoShoutChoice', + // label: 'Demo Shout', + // values: [ + // { name: 'Never', value: DemoShoutChoice.DemoShoutChoiceNone }, + // { name: 'Maintain Debuff', value: DemoShoutChoice.DemoShoutChoiceMaintain }, + // { name: 'Filler', value: DemoShoutChoice.DemoShoutChoiceFiller }, + // ], + // }), + // InputHelpers.makeRotationEnumInput({ + // fieldName: 'thunderClapChoice', + // label: 'Thunder Clap', + // values: [ + // { name: 'Never', value: ThunderClapChoice.ThunderClapChoiceNone }, + // { name: 'Maintain Debuff', value: ThunderClapChoice.ThunderClapChoiceMaintain }, + // { name: 'On CD', value: ThunderClapChoice.ThunderClapChoiceOnCD }, + // ], + // }), ], }; diff --git a/ui/protection_warrior/presets.ts b/ui/protection_warrior/presets.ts index 18e5a1cf08..0f960cbc28 100644 --- a/ui/protection_warrior/presets.ts +++ b/ui/protection_warrior/presets.ts @@ -8,6 +8,7 @@ import { Glyphs, GuardianElixir, Potions, + Spec, } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; @@ -25,8 +26,11 @@ import { import * as PresetUtils from '../core/preset_utils.js'; import PreraidBalancedGear from './gear_sets/preraid_balanced.gear.json'; +import PreraidP4Gear from './gear_sets/p4_preraid.gear.json'; import P1BalancedGear from './gear_sets/p1_balanced.gear.json'; import P2SurvivalGear from './gear_sets/p2_survival.gear.json'; +import P3Gear from './gear_sets/p3.gear.json'; +import P4Gear from './gear_sets/p4.gear.json'; import DefaultApl from './apls/default.apl.json'; @@ -34,9 +38,12 @@ import DefaultApl from './apls/default.apl.json'; // Eventually we will import these values for the raid sim too, so its good to // keep them in a separate file. -export const PRERAID_BALANCED_PRESET = PresetUtils.makePresetGear('PreRaid Balanced', PreraidBalancedGear); -export const P1_BALANCED_PRESET = PresetUtils.makePresetGear('P1 Balanced Preset', P1BalancedGear); -export const P2_SURVIVAL_PRESET = PresetUtils.makePresetGear('P2 Survival Preset', P2SurvivalGear); +export const PRERAID_BALANCED_PRESET = PresetUtils.makePresetGear('P1 PreRaid Preset', PreraidBalancedGear); +export const P4_PRERAID_PRESET = PresetUtils.makePresetGear('P4 PreRaid Preset', PreraidP4Gear); +export const P1_BALANCED_PRESET = PresetUtils.makePresetGear('P1 Preset', P1BalancedGear); +export const P2_SURVIVAL_PRESET = PresetUtils.makePresetGear('P2 Preset', P2SurvivalGear); +export const P3_PRESET = PresetUtils.makePresetGear('P3 Preset', P3Gear); +export const P4_PRESET = PresetUtils.makePresetGear('P4 Preset', P4Gear); export const DefaultRotation = ProtectionWarriorRotation.create({ customRotation: CustomRotation.create({ @@ -58,7 +65,9 @@ export const DefaultRotation = ProtectionWarriorRotation.create({ hsRageThreshold: 30, }); -export const ROTATION_DEFAULT = PresetUtils.makePresetAPLRotation('Default', DefaultApl); +export const ROTATION_DEFAULT = PresetUtils.makePresetAPLRotation('Default APL', DefaultApl); +export const ROTATION_PRESET_SIMPLE = PresetUtils.makePresetSimpleRotation('Simple Cooldowns', Spec.SpecProtectionWarrior, DefaultRotation); + // Default talents. Uses the wowhead calculator format, make the talents on // https://wowhead.com/wotlk/talent-calc and copy the numbers in the url. diff --git a/ui/protection_warrior/sim.ts b/ui/protection_warrior/sim.ts index 6de21d26d6..f86d495166 100644 --- a/ui/protection_warrior/sim.ts +++ b/ui/protection_warrior/sim.ts @@ -1,12 +1,18 @@ -import { RaidBuffs } from '../core/proto/common.js'; -import { PartyBuffs } from '../core/proto/common.js'; -import { IndividualBuffs } from '../core/proto/common.js'; -import { Debuffs } from '../core/proto/common.js'; -import { Spec } from '../core/proto/common.js'; -import { Stat, PseudoStat } from '../core/proto/common.js'; -import { TristateEffect } from '../core/proto/common.js' +import { + Cooldowns, + Debuffs, + IndividualBuffs, + PartyBuffs, + RaidBuffs, + Spec, + Stat, + PseudoStat, + TristateEffect +} from '../core/proto/common.js'; + import { APLAction, + APLPrepullAction, APLListItem, APLRotation, } from '../core/proto/apl.js'; @@ -18,6 +24,8 @@ import { ProtectionWarrior, ProtectionWarrior_Rotation as ProtectionWarriorRotat import * as IconInputs from '../core/components/icon_inputs.js'; import * as OtherInputs from '../core/components/other_inputs.js'; +import * as Tooltips from '../core/constants/tooltips.js'; +import * as AplUtils from '../core/proto_utils/apl_utils.js'; import * as ProtectionWarriorInputs from './inputs.js'; import * as Presets from './presets.js'; @@ -86,7 +94,7 @@ export class ProtectionWarriorSimUI extends IndividualSimUI): APLRotation => { return Presets.ROTATION_DEFAULT.rotation.rotation!; }, + + simpleRotation: (player: Player, simple: ProtectionWarriorRotation, cooldowns: Cooldowns): APLRotation => { + let [prepullActions, actions] = AplUtils.standardCooldownDefaults(cooldowns); + + const preShout = APLPrepullAction.fromJsonString(`{"action":{"castSpell":{"spellId":{"spellId":47440}}},"doAtValue":{"const":{"val":"-10s"}}}`); + + const heroicStrike = APLAction.fromJsonString(`{"condition":{"cmp":{"op":"OpGe","lhs":{"currentRage":{}},"rhs":{"const":{"val":"30"}}}},"castSpell":{"spellId":{"tag":1,"spellId":47450}}}`); + const shieldSlam = APLAction.fromJsonString(`{"castSpell":{"spellId":{"spellId":47488}}}`); + const revenge = APLAction.fromJsonString(`{"castSpell":{"spellId":{"spellId":57823}}}`); + const refreshShout = APLAction.fromJsonString(`{"condition":{"auraShouldRefresh":{"sourceUnit":{"type":"Self"},"auraId":{"spellId":47440},"maxOverlap":{"const":{"val":"3s"}}}},"castSpell":{"spellId":{"spellId":47440}}}`); + const refreshTclap = APLAction.fromJsonString(`{"condition":{"auraShouldRefresh":{"auraId":{"spellId":47502},"maxOverlap":{"const":{"val":"2s"}}}},"castSpell":{"spellId":{"spellId":47502}}}`); + const refreshDemo = APLAction.fromJsonString(`{"condition":{"auraShouldRefresh":{"auraId":{"spellId":47437},"maxOverlap":{"const":{"val":"2s"}}}},"castSpell":{"spellId":{"spellId":25203}}}`); + const devastate = APLAction.fromJsonString(`{"castSpell":{"spellId":{"spellId":47498}}}`); + + prepullActions.push(preShout); + + actions.push(...[ + heroicStrike, + shieldSlam, + revenge, + refreshShout, + refreshTclap, + refreshDemo, + devastate, + ].filter(a => a) as Array) + + return APLRotation.create({ + prepullActions: prepullActions, + priorityList: actions.map(action => APLListItem.create({ + action: action, + })) + }); + }, + }); } }