diff --git a/proto/apl.proto b/proto/apl.proto index 32a93d9bfe..016b53da72 100644 --- a/proto/apl.proto +++ b/proto/apl.proto @@ -81,7 +81,7 @@ message APLAction { } } -// NextIndex: 77 +// NextIndex: 78 message APLValue { oneof value { // Operators @@ -184,6 +184,7 @@ message APLValue { APLValueWarlockShouldRecastDrainSoul warlock_should_recast_drain_soul = 59; APLValueWarlockShouldRefreshCorruption warlock_should_refresh_corruption = 60; APLValueCurrentEclipsePhase druid_current_eclipse_phase = 70; + APLValueMageCurrentCombustionDotEstimate mage_current_combustion_dot_estimate = 77; } } @@ -584,3 +585,5 @@ message APLValueWarlockShouldRecastDrainSoul { message APLValueWarlockShouldRefreshCorruption { UnitReference target_unit = 1; } +message APLValueMageCurrentCombustionDotEstimate { +} diff --git a/proto/mage.proto b/proto/mage.proto index a1b5d87d8f..6831a6b80e 100644 --- a/proto/mage.proto +++ b/proto/mage.proto @@ -134,10 +134,15 @@ message ArcaneMage { message FireMage { message Rotation { - // Minimum Ignite threshold to combust at during lust - int32 ignite_combust_threshold = 1; - double ignite_last_moment_lust_percentage = 2; - double ignite_no_lust_percentage = 3; + // Minimum Combustion threshold to cast Combustion at during lust + int32 combust_threshold = 4; + double combust_last_moment_lust_percentage = 5; + double combust_no_lust_percentage = 6; + + // deprecated fields + int32 ignite_combust_threshold = 1 [deprecated=true]; + double ignite_last_moment_lust_percentage = 2 [deprecated=true]; + double ignite_no_lust_percentage = 3 [deprecated=true]; } message Options { diff --git a/sim/core/dot.go b/sim/core/dot.go index 2ee7a722da..afa3e16f23 100644 --- a/sim/core/dot.go +++ b/sim/core/dot.go @@ -119,9 +119,22 @@ func (dot *Dot) TimeUntilNextTick(sim *Simulation) time.Duration { return dot.NextTickAt() - sim.CurrentTime } +func (dot *Dot) calculateHastedTickCount(baseDuration time.Duration, tickPeriod time.Duration) int32 { + return int32(math.Round(float64(baseDuration) / float64(tickPeriod))) +} + // Returns the total amount of ticks with the snapshotted haste func (dot *Dot) HastedTickCount() int32 { - return int32(math.Round(float64(dot.BaseDuration()) / float64(dot.tickPeriod))) + return dot.calculateHastedTickCount(dot.BaseDuration(), dot.tickPeriod) +} + +func (dot *Dot) ExpectedTickCount() int32 { + tickCount := dot.BaseTickCount + if dot.affectedByCastSpeed && !dot.hasteReducesDuration { + tickPeriod := dot.Spell.Unit.ApplyCastSpeedForSpell(dot.BaseTickLength, dot.Spell).Round(time.Millisecond) + tickCount = dot.calculateHastedTickCount(dot.BaseDuration(), tickPeriod) + } + return tickCount } func (dot *Dot) RemainingTicks() int32 { diff --git a/sim/mage/apl_values.go b/sim/mage/apl_values.go new file mode 100644 index 0000000000..22c2561f95 --- /dev/null +++ b/sim/mage/apl_values.go @@ -0,0 +1,60 @@ +package mage + +import ( + "github.com/wowsims/cata/sim/core" + "github.com/wowsims/cata/sim/core/proto" +) + +func (mage *Mage) NewAPLValue(rot *core.APLRotation, config *proto.APLValue) core.APLValue { + switch config.Value.(type) { + case *proto.APLValue_MageCurrentCombustionDotEstimate: + return mage.newValueCurrentCombustionDotEstimate(config.GetMageCurrentCombustionDotEstimate()) + default: + return nil + } +} + +type APLValueMageCurrentCombustionDotEstimate struct { + core.DefaultAPLValueImpl + mage *Mage +} + +func (mage *Mage) newValueCurrentCombustionDotEstimate(_ *proto.APLValueMageCurrentCombustionDotEstimate) core.APLValue { + if !mage.Talents.Combustion { + return nil + } + + return &APLValueMageCurrentCombustionDotEstimate{ + mage: mage, + } +} +func (value *APLValueMageCurrentCombustionDotEstimate) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeInt +} + +func (value *APLValueMageCurrentCombustionDotEstimate) GetInt(sim *core.Simulation) int32 { + mage := value.mage + + combustionDotDamage := 0.0 + tickCount := int(mage.Combustion.RelatedDotSpell.Dot(mage.CurrentTarget).ExpectedTickCount()) + + for i := 0; i < tickCount; i++ { + damage := mage.Combustion.RelatedDotSpell.ExpectedTickDamage(sim, mage.CurrentTarget) + combustionDotDamage += damage + } + + combustionDotDamageAsInt := int32(combustionDotDamage) + + if combustionDotDamageAsInt != mage.previousCombustionDotEstimate { + mage.previousCombustionDotEstimate = int32(combustionDotDamage) + if sim.Log != nil { + mage.Log(sim, "Combustion Dot Estimate: %d", combustionDotDamageAsInt) + } + } + + return combustionDotDamageAsInt +} + +func (value *APLValueMageCurrentCombustionDotEstimate) String() string { + return "Combustion Dot Estimated Value" +} diff --git a/sim/mage/combustion.go b/sim/mage/combustion.go index bcc85d9d00..9021f92793 100644 --- a/sim/mage/combustion.go +++ b/sim/mage/combustion.go @@ -11,8 +11,10 @@ func (mage *Mage) registerCombustionSpell() { return } + actionID := core.ActionID{SpellID: 11129} + mage.Combustion = mage.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 11129}, + ActionID: actionID, SpellSchool: core.SpellSchoolFire, ProcMask: core.ProcMaskSpellDamage, // need to check proc mask for impact damage ClassSpellMask: MageSpellCombustionApplication, @@ -47,8 +49,26 @@ func (mage *Mage) registerCombustionSpell() { MageSpellPyroblastDot: 0.175 * mage.ClassSpellScaling, } + calculatedDotTick := func(target *core.Unit) float64 { + tickDamage := 0.0 + dotSpells := []*core.Spell{mage.LivingBomb, mage.Ignite, mage.Pyroblast.RelatedDotSpell} + for _, spell := range dotSpells { + dot := spell.Dot(target) + if dot.IsActive() { + if spell.ClassSpellMask&(MageSpellLivingBombDot|MageSpellPyroblastDot) != 0 { + dps := dotBase[spell.ClassSpellMask] + dot.BonusCoefficient*dot.Spell.SpellPower() + dps *= spell.DamageMultiplier * spell.DamageMultiplierAdditive + tickDamage += dps / dot.BaseTickLength.Seconds() + } else { + tickDamage += dot.SnapshotBaseDamage / 2 + } + } + } + return tickDamage + } + mage.Combustion.RelatedDotSpell = mage.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 11129}.WithTag(1), + ActionID: actionID.WithTag(1), SpellSchool: core.SpellSchoolFire, ProcMask: core.ProcMaskEmpty, ClassSpellMask: MageSpellCombustion, @@ -72,27 +92,23 @@ func (mage *Mage) registerCombustionSpell() { AffectedByCastSpeed: true, OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, _ bool) { - combustionDotDamage := 0.0 - dotSpells := []*core.Spell{mage.LivingBomb, mage.Ignite, mage.Pyroblast.RelatedDotSpell} - for _, spell := range dotSpells { - dot := spell.Dot(target) - if dot.IsActive() { - if spell.ClassSpellMask&(MageSpellLivingBombDot|MageSpellPyroblastDot) != 0 { - dps := dotBase[spell.ClassSpellMask] + dot.BonusCoefficient*dot.Spell.SpellPower() - dps *= spell.DamageMultiplier * spell.DamageMultiplierAdditive - combustionDotDamage += dps / dot.BaseTickLength.Seconds() - } else { - combustionDotDamage += dot.SnapshotBaseDamage / 2 - } - } - } - dot.Snapshot(target, combustionDotDamage) + tickBase := calculatedDotTick(target) + dot.Snapshot(target, tickBase) }, OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeSnapshotCrit) }, }, + ExpectedTickDamage: func(sim *core.Simulation, target *core.Unit, spell *core.Spell, useSnapshot bool) *core.SpellResult { + tickBase := calculatedDotTick(target) + result := spell.CalcPeriodicDamage(sim, target, tickBase, spell.OutcomeExpectedMagicAlwaysHit) + critChance := spell.SpellCritChance(target) + critMod := (critChance * (spell.CritMultiplier - 1)) + result.Damage *= 1 + critMod + + return result + }, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { spell.Dot(target).Apply(sim) }, diff --git a/sim/mage/fire/TestFire.results b/sim/mage/fire/TestFire.results index 198d944ef0..8bf1af2e33 100644 --- a/sim/mage/fire/TestFire.results +++ b/sim/mage/fire/TestFire.results @@ -38,1928 +38,1928 @@ character_stats_results: { dps_results: { key: "TestFire-AllItems-AgileShadowspiritDiamond" value: { - dps: 37611.66109 - tps: 36066.05459 + dps: 38435.2452 + tps: 36819.87948 } } dps_results: { key: "TestFire-AllItems-Althor'sAbacus-50366" value: { - dps: 35557.05573 - tps: 34079.44079 + dps: 36271.77218 + tps: 34683.31254 } } dps_results: { key: "TestFire-AllItems-AncientPetrifiedSeed-69001" value: { - dps: 35750.11593 - tps: 34283.54762 + dps: 36309.83929 + tps: 34727.52019 } } dps_results: { key: "TestFire-AllItems-Anhuur'sHymnal-55889" value: { - dps: 36038.55358 - tps: 34543.36844 + dps: 36627.81857 + tps: 35006.32076 } } dps_results: { key: "TestFire-AllItems-Anhuur'sHymnal-56407" value: { - dps: 36176.65152 - tps: 34671.17245 + dps: 36503.3034 + tps: 34897.55478 } } dps_results: { key: "TestFire-AllItems-ApparatusofKhaz'goroth-68972" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ApparatusofKhaz'goroth-69113" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ArrowofTime-72897" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-AustereShadowspiritDiamond" value: { - dps: 37032.67045 - tps: 35501.99145 + dps: 37700.12603 + tps: 36110.37729 } } dps_results: { key: "TestFire-AllItems-BaubleofTrueBlood-50726" value: { - dps: 34853.46893 - tps: 33401.89227 - hps: 104.53836 + dps: 35561.67037 + tps: 33996.36167 + hps: 105.32075 } } dps_results: { key: "TestFire-AllItems-BedrockTalisman-58182" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BellofEnragingResonance-59326" value: { - dps: 37436.70158 - tps: 35925.28719 + dps: 37504.78375 + tps: 35927.97381 } } dps_results: { key: "TestFire-AllItems-BellofEnragingResonance-65053" value: { - dps: 37879.15614 - tps: 36358.85371 + dps: 37823.25092 + tps: 36223.60269 } } dps_results: { key: "TestFire-AllItems-BindingPromise-67037" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Blood-SoakedAleMug-63843" value: { - dps: 35180.04609 - tps: 33728.8647 + dps: 35999.79171 + tps: 34421.01238 } } dps_results: { key: "TestFire-AllItems-BloodofIsiset-55995" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-BloodofIsiset-56414" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sBadgeofConquest-64687" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sBadgeofDominance-64688" value: { - dps: 36082.31836 - tps: 34593.65215 + dps: 36637.19753 + tps: 35019.90463 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sBadgeofVictory-64689" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sEmblemofCruelty-64740" value: { - dps: 36017.32718 - tps: 34545.56516 + dps: 36064.84518 + tps: 34500.52169 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sEmblemofMeditation-64741" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sEmblemofTenacity-64742" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sInsigniaofConquest-64761" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sInsigniaofDominance-64762" value: { - dps: 35983.44221 - tps: 34498.0568 + dps: 36660.88581 + tps: 35048.47859 } } dps_results: { key: "TestFire-AllItems-BloodthirstyGladiator'sInsigniaofVictory-64763" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Bone-LinkFetish-77210" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Bone-LinkFetish-77982" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Bone-LinkFetish-78002" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BottledLightning-66879" value: { - dps: 36060.07475 - tps: 34594.84553 + dps: 36628.56572 + tps: 35033.75337 } } dps_results: { key: "TestFire-AllItems-BottledWishes-77114" value: { - dps: 37392.78753 - tps: 35879.12531 + dps: 37699.4221 + tps: 36111.22291 } } dps_results: { key: "TestFire-AllItems-BottledWishes-77985" value: { - dps: 37194.27701 - tps: 35694.78818 + dps: 37249.72469 + tps: 35660.8186 } } dps_results: { key: "TestFire-AllItems-BottledWishes-78005" value: { - dps: 37498.05484 - tps: 35996.32375 + dps: 37848.15738 + tps: 36258.37589 } } dps_results: { key: "TestFire-AllItems-BracingShadowspiritDiamond" value: { - dps: 37176.82217 - tps: 34936.5026 + dps: 37926.69414 + tps: 35597.02439 } } dps_results: { key: "TestFire-AllItems-Brawler'sTrophy-232015" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-BurningShadowspiritDiamond" value: { - dps: 37870.87736 - tps: 36330.90054 + dps: 38669.82148 + tps: 37040.72983 } } dps_results: { key: "TestFire-AllItems-ChaoticShadowspiritDiamond" value: { - dps: 37763.19515 - tps: 36216.84119 + dps: 38602.57867 + tps: 36979.1101 } } dps_results: { key: "TestFire-AllItems-Coren'sChilledChromiumCoaster-232012" value: { - dps: 35968.27773 - tps: 34501.80308 + dps: 36074.03355 + tps: 34509.71005 } } dps_results: { key: "TestFire-AllItems-CoreofRipeness-58184" value: { - dps: 36202.42388 - tps: 34706.48418 + dps: 36978.61342 + tps: 35386.28004 } } dps_results: { key: "TestFire-AllItems-CorpseTongueCoin-50349" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-CrecheoftheFinalDragon-77205" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-CrecheoftheFinalDragon-77972" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-CrecheoftheFinalDragon-77992" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-CrushingWeight-59506" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-CrushingWeight-65118" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-CunningoftheCruel-77208" value: { - dps: 37173.45319 - tps: 35723.28721 + dps: 37271.92024 + tps: 35694.22825 } } dps_results: { key: "TestFire-AllItems-CunningoftheCruel-77980" value: { - dps: 37051.17342 - tps: 35564.41558 + dps: 37646.63522 + tps: 36043.95195 } } dps_results: { key: "TestFire-AllItems-CunningoftheCruel-78000" value: { - dps: 37985.83637 - tps: 36470.76593 + dps: 38272.33713 + tps: 36669.41291 } } dps_results: { key: "TestFire-AllItems-DarkmoonCard:Earthquake-62048" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-DarkmoonCard:Hurricane-62049" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-DarkmoonCard:Hurricane-62051" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-DarkmoonCard:Tsunami-62050" value: { - dps: 36202.42388 - tps: 34706.48418 + dps: 36978.61342 + tps: 35386.28004 } } dps_results: { key: "TestFire-AllItems-Deathbringer'sWill-50363" value: { - dps: 35491.13258 - tps: 34024.85736 + dps: 35899.92343 + tps: 34325.24231 } } dps_results: { key: "TestFire-AllItems-DestructiveShadowspiritDiamond" value: { - dps: 37072.08553 - tps: 35548.84459 + dps: 37858.00142 + tps: 36252.60976 } } dps_results: { key: "TestFire-AllItems-DislodgedForeignObject-50348" value: { - dps: 36525.68118 - tps: 35039.44636 + dps: 36586.66181 + tps: 35007.50719 } } dps_results: { key: "TestFire-AllItems-Dwyer'sCaber-70141" value: { - dps: 36537.01681 - tps: 35045.02861 + dps: 36799.81773 + tps: 35202.24279 } } dps_results: { key: "TestFire-AllItems-EffulgentShadowspiritDiamond" value: { - dps: 37032.67045 - tps: 35501.99145 + dps: 37700.12603 + tps: 36110.37729 } } dps_results: { key: "TestFire-AllItems-ElectrosparkHeartstarter-67118" value: { - dps: 35435.18253 - tps: 34001.78662 + dps: 36204.69862 + tps: 34610.06501 } } dps_results: { key: "TestFire-AllItems-EmberShadowspiritDiamond" value: { - dps: 37176.82217 - tps: 35647.53072 + dps: 37926.69414 + tps: 36321.52507 } } dps_results: { key: "TestFire-AllItems-EnigmaticShadowspiritDiamond" value: { - dps: 37072.08553 - tps: 35548.84459 + dps: 37858.00142 + tps: 36252.60976 } } dps_results: { key: "TestFire-AllItems-EssenceoftheCyclone-59473" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-EssenceoftheCyclone-65140" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-EssenceoftheEternalFlame-69002" value: { - dps: 35750.11593 - tps: 34283.54762 + dps: 36309.83929 + tps: 34727.52019 } } dps_results: { key: "TestFire-AllItems-EternalShadowspiritDiamond" value: { - dps: 37032.67045 - tps: 35501.99145 + dps: 37700.12603 + tps: 36110.37729 } } dps_results: { key: "TestFire-AllItems-EyeofUnmaking-77200" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-EyeofUnmaking-77977" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-EyeofUnmaking-77997" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-FallofMortality-59500" value: { - dps: 36202.42388 - tps: 34706.48418 + dps: 36978.61342 + tps: 35386.28004 } } dps_results: { key: "TestFire-AllItems-FallofMortality-65124" value: { - dps: 36437.56906 - tps: 34942.20445 + dps: 37194.22711 + tps: 35597.09876 } } dps_results: { key: "TestFire-AllItems-FieryQuintessence-69000" value: { - dps: 36747.22981 - tps: 35283.73009 + dps: 37070.88455 + tps: 35473.01838 } } dps_results: { key: "TestFire-AllItems-Figurine-DemonPanther-52199" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-Figurine-DreamOwl-52354" value: { - dps: 36125.64155 - tps: 34634.12456 + dps: 36782.95505 + tps: 35193.62035 } } dps_results: { key: "TestFire-AllItems-Figurine-EarthenGuardian-52352" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Figurine-JeweledSerpent-52353" value: { - dps: 37315.76763 - tps: 35784.2598 + dps: 37689.24073 + tps: 36068.38193 } } dps_results: { key: "TestFire-AllItems-Figurine-KingofBoars-52351" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-FirehawkRobesofConflagration" value: { - dps: 33850.60598 - tps: 32436.72367 + dps: 34353.48473 + tps: 32896.43705 } } dps_results: { key: "TestFire-AllItems-Firelord'sVestments" value: { - dps: 31977.56168 - tps: 31565.20763 + dps: 32477.16134 + tps: 31966.74191 } } dps_results: { key: "TestFire-AllItems-FireoftheDeep-77117" value: { - dps: 35885.62362 - tps: 34418.21212 + dps: 36415.40603 + tps: 34833.08693 } } dps_results: { key: "TestFire-AllItems-FireoftheDeep-77988" value: { - dps: 35750.11593 - tps: 34283.54762 + dps: 36309.83929 + tps: 34727.52019 } } dps_results: { key: "TestFire-AllItems-FireoftheDeep-78008" value: { - dps: 35988.7024 - tps: 34521.2909 + dps: 36520.97277 + tps: 34938.65367 } } dps_results: { key: "TestFire-AllItems-FleetShadowspiritDiamond" value: { - dps: 37032.67045 - tps: 35501.99145 + dps: 37700.12603 + tps: 36110.37729 } } dps_results: { key: "TestFire-AllItems-FluidDeath-58181" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-ForlornShadowspiritDiamond" value: { - dps: 37176.82217 - tps: 35647.53072 + dps: 37926.69414 + tps: 36321.52507 } } dps_results: { key: "TestFire-AllItems-FoulGiftoftheDemonLord-72898" value: { - dps: 37382.2614 - tps: 35857.70561 + dps: 38250.08005 + tps: 36655.10494 } } dps_results: { key: "TestFire-AllItems-FuryofAngerforge-59461" value: { - dps: 36113.33612 - tps: 34630.82703 + dps: 36049.74261 + tps: 34480.64853 } } dps_results: { key: "TestFire-AllItems-GaleofShadows-56138" value: { - dps: 36549.7311 - tps: 35076.64764 + dps: 36588.81132 + tps: 35020.91283 } } dps_results: { key: "TestFire-AllItems-GaleofShadows-56462" value: { - dps: 36895.33155 - tps: 35412.61865 + dps: 36804.12315 + tps: 35237.43685 } } dps_results: { key: "TestFire-AllItems-GearDetector-61462" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-GlowingTwilightScale-54589" value: { - dps: 35597.40987 - tps: 34118.97065 + dps: 36313.71338 + tps: 34724.30073 } } dps_results: { key: "TestFire-AllItems-GraceoftheHerald-55266" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-GraceoftheHerald-56295" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-HarmlightToken-63839" value: { - dps: 36234.43577 - tps: 34761.95413 + dps: 36343.17715 + tps: 34767.16937 } } dps_results: { key: "TestFire-AllItems-Harrison'sInsigniaofPanache-65803" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-HeartofIgnacious-59514" value: { - dps: 37392.39714 - tps: 35869.47266 + dps: 37354.76252 + tps: 35766.75253 } } dps_results: { key: "TestFire-AllItems-HeartofIgnacious-65110" value: { - dps: 37598.35612 - tps: 36062.08626 + dps: 37300.61644 + tps: 35703.9091 } } dps_results: { key: "TestFire-AllItems-HeartofRage-59224" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-HeartofRage-65072" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-HeartofSolace-55868" value: { - dps: 35732.30794 - tps: 34279.63594 + dps: 35652.0799 + tps: 34111.7842 } } dps_results: { key: "TestFire-AllItems-HeartofSolace-56393" value: { - dps: 35885.70933 - tps: 34431.90202 + dps: 35682.70122 + tps: 34137.02457 } } dps_results: { key: "TestFire-AllItems-HeartofThunder-55845" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-HeartofThunder-56370" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-HeartoftheVile-66969" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Heartpierce-50641" value: { - dps: 37870.87736 - tps: 36330.90054 + dps: 38669.82148 + tps: 37040.72983 } } dps_results: { key: "TestFire-AllItems-ImpassiveShadowspiritDiamond" value: { - dps: 37072.08553 - tps: 35548.84459 + dps: 37858.00142 + tps: 36252.60976 } } dps_results: { key: "TestFire-AllItems-ImpatienceofYouth-62464" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-ImpatienceofYouth-62469" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-ImpetuousQuery-55881" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-ImpetuousQuery-56406" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-IndomitablePride-77211" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-IndomitablePride-77983" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-IndomitablePride-78003" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-InsigniaofDiplomacy-61433" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-InsigniaoftheCorruptedMind-77203" value: { - dps: 39601.07188 - tps: 38056.5994 + dps: 39115.12328 + tps: 37507.33604 } } dps_results: { key: "TestFire-AllItems-InsigniaoftheCorruptedMind-77971" value: { - dps: 38392.00894 - tps: 36872.30374 + dps: 38447.17229 + tps: 36812.93457 } } dps_results: { key: "TestFire-AllItems-InsigniaoftheCorruptedMind-77991" value: { - dps: 39839.95766 - tps: 38269.01673 + dps: 40048.51139 + tps: 38406.57104 } } dps_results: { key: "TestFire-AllItems-InsigniaoftheEarthenLord-61429" value: { - dps: 36032.1605 - tps: 34567.26151 + dps: 36627.63464 + tps: 35039.45018 } } dps_results: { key: "TestFire-AllItems-JarofAncientRemedies-59354" value: { - dps: 34928.16372 - tps: 33500.08711 + dps: 35702.98373 + tps: 34161.16091 } } dps_results: { key: "TestFire-AllItems-JarofAncientRemedies-65029" value: { - dps: 34928.16372 - tps: 33502.88711 + dps: 35702.98373 + tps: 34163.96091 } } dps_results: { key: "TestFire-AllItems-JawsofDefeat-68926" value: { - dps: 36471.45143 - tps: 34975.35325 + dps: 37336.89056 + tps: 35744.67318 } } dps_results: { key: "TestFire-AllItems-JawsofDefeat-69111" value: { - dps: 36728.86023 - tps: 35231.10392 + dps: 37462.24327 + tps: 35845.69719 } } dps_results: { key: "TestFire-AllItems-JujuofNimbleness-63840" value: { - dps: 35180.04609 - tps: 33728.8647 + dps: 35999.79171 + tps: 34421.01238 } } dps_results: { key: "TestFire-AllItems-KeytotheEndlessChamber-55795" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-KeytotheEndlessChamber-56328" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-KiroptyricSigil-77113" value: { - dps: 35779.81398 - tps: 34280.45178 + dps: 35809.2586 + tps: 34251.71828 } } dps_results: { key: "TestFire-AllItems-KiroptyricSigil-77984" value: { - dps: 35770.37441 - tps: 34284.12845 + dps: 35655.1616 + tps: 34111.92893 } } dps_results: { key: "TestFire-AllItems-KiroptyricSigil-78004" value: { - dps: 35689.84501 - tps: 34210.6574 + dps: 36118.42792 + tps: 34568.75578 } } dps_results: { key: "TestFire-AllItems-KvaldirBattleStandard-59685" value: { - dps: 35484.01079 - tps: 34016.8594 + dps: 35708.42746 + tps: 34142.69537 } } dps_results: { key: "TestFire-AllItems-KvaldirBattleStandard-59689" value: { - dps: 35484.01079 - tps: 34016.8594 + dps: 35708.42746 + tps: 34142.69537 } } dps_results: { key: "TestFire-AllItems-LadyLa-La'sSingingShell-67152" value: { - dps: 34926.15477 - tps: 33470.7728 + dps: 35640.7563 + tps: 34097.92899 } } dps_results: { key: "TestFire-AllItems-LeadenDespair-55816" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-LeadenDespair-56347" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-LeftEyeofRajh-56102" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-LeftEyeofRajh-56427" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-LicensetoSlay-58180" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-MagnetiteMirror-55814" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-MagnetiteMirror-56345" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-MandalaofStirringPatterns-62467" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-MandalaofStirringPatterns-62472" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-MarkofKhardros-56132" value: { - dps: 35580.44144 - tps: 34119.17704 + dps: 36136.03432 + tps: 34565.02406 } } dps_results: { key: "TestFire-AllItems-MarkofKhardros-56458" value: { - dps: 35666.50219 - tps: 34208.73878 + dps: 36249.3898 + tps: 34679.79513 } } dps_results: { key: "TestFire-AllItems-MatrixRestabilizer-68994" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-MatrixRestabilizer-69150" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-MightoftheOcean-55251" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-MightoftheOcean-56285" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-MirrorofBrokenImages-62466" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-MirrorofBrokenImages-62471" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-MithrilStopwatch-232013" value: { - dps: 37213.17499 - tps: 35722.00466 + dps: 37253.39257 + tps: 35674.74278 } } dps_results: { key: "TestFire-AllItems-MoonwellChalice-70142" value: { - dps: 37225.1509 - tps: 35696.08913 + dps: 37624.65983 + tps: 36022.36908 } } dps_results: { key: "TestFire-AllItems-MoonwellPhial-70143" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-NecromanticFocus-68982" value: { - dps: 37204.88478 - tps: 35708.25074 + dps: 38023.57408 + tps: 36425.21001 } } dps_results: { key: "TestFire-AllItems-NecromanticFocus-69139" value: { - dps: 37498.35096 - tps: 35974.08847 + dps: 38119.62881 + tps: 36506.01981 } } dps_results: { key: "TestFire-AllItems-Oremantle'sFavor-61448" value: { - dps: 35949.67625 - tps: 34484.99361 + dps: 36098.52412 + tps: 34527.99982 } } dps_results: { key: "TestFire-AllItems-PetrifiedPickledEgg-232014" value: { - dps: 36126.59796 - tps: 34631.98061 + dps: 36917.49664 + tps: 35326.83529 } } dps_results: { key: "TestFire-AllItems-PetrifiedTwilightScale-54591" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-PhylacteryoftheNamelessLich-50365" value: { - dps: 36421.57308 - tps: 34935.8821 + dps: 36884.27709 + tps: 35308.19311 } } dps_results: { key: "TestFire-AllItems-PorcelainCrab-55237" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-PorcelainCrab-56280" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-PowerfulShadowspiritDiamond" value: { - dps: 37032.67045 - tps: 35501.99145 + dps: 37700.12603 + tps: 36110.37729 } } dps_results: { key: "TestFire-AllItems-Prestor'sTalismanofMachination-59441" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Prestor'sTalismanofMachination-65026" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Rainsong-55854" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Rainsong-56377" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ReflectionoftheLight-77115" value: { - dps: 36689.63478 - tps: 35212.07813 + dps: 37121.93768 + tps: 35532.15459 } } dps_results: { key: "TestFire-AllItems-ReflectionoftheLight-77986" value: { - dps: 36501.30415 - tps: 35022.45016 + dps: 37047.11965 + tps: 35460.17268 } } dps_results: { key: "TestFire-AllItems-ReflectionoftheLight-78006" value: { - dps: 36904.91934 - tps: 35424.87198 + dps: 37366.04081 + tps: 35780.72041 } } dps_results: { key: "TestFire-AllItems-ResolveofUndying-77201" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ResolveofUndying-77978" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ResolveofUndying-77998" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ReverberatingShadowspiritDiamond" value: { - dps: 37611.66109 - tps: 36066.05459 + dps: 38435.2452 + tps: 36819.87948 } } dps_results: { key: "TestFire-AllItems-RevitalizingShadowspiritDiamond" value: { - dps: 37611.66109 - tps: 36066.05459 + dps: 38435.2452 + tps: 36819.87948 } } dps_results: { key: "TestFire-AllItems-Ricket'sMagneticFireball-70144" value: { - dps: 36071.69803 - tps: 34569.20119 + dps: 35922.69749 + tps: 34355.63018 } } dps_results: { key: "TestFire-AllItems-RightEyeofRajh-56100" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-RightEyeofRajh-56431" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-RosaryofLight-72901" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-RottingSkull-77116" value: { - dps: 36343.42538 - tps: 34883.91283 + dps: 36361.16235 + tps: 34779.4969 } } dps_results: { key: "TestFire-AllItems-RottingSkull-77987" value: { - dps: 36368.30707 - tps: 34869.01051 + dps: 36183.1352 + tps: 34595.51691 } } dps_results: { key: "TestFire-AllItems-RottingSkull-78007" value: { - dps: 36847.82124 - tps: 35377.65501 + dps: 36539.82799 + tps: 34953.44119 } } dps_results: { key: "TestFire-AllItems-RuneofZeth-68998" value: { - dps: 37920.04713 - tps: 36393.02244 + dps: 37712.23059 + tps: 36104.41857 } } dps_results: { key: "TestFire-AllItems-ScalesofLife-68915" value: { - dps: 34851.23041 - tps: 33400.59398 + dps: 35561.62783 + tps: 33997.63307 hps: 369.06908 } } dps_results: { key: "TestFire-AllItems-ScalesofLife-69109" value: { - dps: 34851.23041 - tps: 33400.59398 + dps: 35561.62783 + tps: 33997.63307 hps: 416.30647 } } dps_results: { key: "TestFire-AllItems-Schnottz'sMedallionofCommand-65805" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-SeaStar-55256" value: { - dps: 35390.38012 - tps: 33932.11526 + dps: 36123.69654 + tps: 34520.06316 } } dps_results: { key: "TestFire-AllItems-SeaStar-56290" value: { - dps: 36017.62774 - tps: 34529.9487 + dps: 36566.39341 + tps: 34950.52899 } } dps_results: { key: "TestFire-AllItems-ShardofWoe-60233" value: { - dps: 35912.24344 - tps: 34434.29074 + dps: 36621.17019 + tps: 35047.3076 } } dps_results: { key: "TestFire-AllItems-Shrine-CleansingPurifier-63838" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Sindragosa'sFlawlessFang-50364" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Skardyn'sGrace-56115" value: { - dps: 35557.49221 - tps: 34084.62069 + dps: 36087.50608 + tps: 34493.06879 } } dps_results: { key: "TestFire-AllItems-Skardyn'sGrace-56440" value: { - dps: 35638.05385 - tps: 34165.18233 + dps: 36206.32233 + tps: 34614.55385 } } dps_results: { key: "TestFire-AllItems-Sorrowsong-55879" value: { - dps: 36212.38852 - tps: 34728.73991 + dps: 36973.28689 + tps: 35374.35684 } } dps_results: { key: "TestFire-AllItems-Sorrowsong-56400" value: { - dps: 36317.39898 - tps: 34831.97386 + dps: 37077.49598 + tps: 35475.89505 } } dps_results: { key: "TestFire-AllItems-Soul'sAnguish-66994" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-SoulCasket-58183" value: { - dps: 37145.5994 - tps: 35631.12069 + dps: 37411.44713 + tps: 35808.65351 } } dps_results: { key: "TestFire-AllItems-SoulshifterVortex-77206" value: { - dps: 36678.36593 - tps: 35182.15624 + dps: 36747.85865 + tps: 35174.75061 } } dps_results: { key: "TestFire-AllItems-SoulshifterVortex-77970" value: { - dps: 36551.39063 - tps: 35038.52617 + dps: 36640.2979 + tps: 35066.41184 } } dps_results: { key: "TestFire-AllItems-SoulshifterVortex-77990" value: { - dps: 36802.94344 - tps: 35277.82946 + dps: 36839.0503 + tps: 35258.60442 } } dps_results: { key: "TestFire-AllItems-SpidersilkSpindle-68981" value: { - dps: 35750.11593 - tps: 34283.54762 + dps: 36309.83929 + tps: 34727.52019 } } dps_results: { key: "TestFire-AllItems-SpidersilkSpindle-69138" value: { - dps: 35750.11593 - tps: 34283.54762 + dps: 36309.83929 + tps: 34727.52019 } } dps_results: { key: "TestFire-AllItems-StarcatcherCompass-77202" value: { - dps: 36483.3633 - tps: 35011.19875 + dps: 37041.19139 + tps: 35474.56949 } } dps_results: { key: "TestFire-AllItems-StarcatcherCompass-77973" value: { - dps: 36940.13696 - tps: 35470.54509 + dps: 37191.67185 + tps: 35606.65942 } } dps_results: { key: "TestFire-AllItems-StarcatcherCompass-77993" value: { - dps: 37124.96029 - tps: 35615.31313 + dps: 37042.40875 + tps: 35470.07201 } } dps_results: { key: "TestFire-AllItems-StayofExecution-68996" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Stonemother'sKiss-61411" value: { - dps: 36249.68411 - tps: 34767.96993 + dps: 36838.30552 + tps: 35231.4272 } } dps_results: { key: "TestFire-AllItems-StumpofTime-62465" value: { - dps: 36622.7957 - tps: 35093.80955 + dps: 37259.77419 + tps: 35637.61653 } } dps_results: { key: "TestFire-AllItems-StumpofTime-62470" value: { - dps: 36728.00001 - tps: 35211.42033 + dps: 37124.07707 + tps: 35506.20405 } } dps_results: { key: "TestFire-AllItems-SymbioticWorm-59332" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-SymbioticWorm-65048" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-TalismanofSinisterOrder-65804" value: { - dps: 36476.20576 - tps: 34974.29132 + dps: 36772.66989 + tps: 35178.83183 } } dps_results: { key: "TestFire-AllItems-Tank-CommanderInsignia-63841" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-TearofBlood-55819" value: { - dps: 35760.69967 - tps: 34269.72337 + dps: 36469.71133 + tps: 34878.71185 } } dps_results: { key: "TestFire-AllItems-TearofBlood-56351" value: { - dps: 36125.64155 - tps: 34634.12456 + dps: 36782.95505 + tps: 35193.62035 } } dps_results: { key: "TestFire-AllItems-TendrilsofBurrowingDark-55810" value: { - dps: 36060.94342 - tps: 34586.70788 + dps: 36832.54894 + tps: 35228.55772 } } dps_results: { key: "TestFire-AllItems-TendrilsofBurrowingDark-56339" value: { - dps: 36485.40602 - tps: 35000.67954 + dps: 37176.50361 + tps: 35560.67677 } } dps_results: { key: "TestFire-AllItems-TheHungerer-68927" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-TheHungerer-69112" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Theralion'sMirror-59519" value: { - dps: 37311.17014 - tps: 35775.2945 + dps: 37869.65254 + tps: 36260.18418 } } dps_results: { key: "TestFire-AllItems-Theralion'sMirror-65105" value: { - dps: 37657.58619 - tps: 36136.35435 + dps: 37943.99674 + tps: 36348.39079 } } dps_results: { key: "TestFire-AllItems-Throngus'sFinger-56121" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Throngus'sFinger-56449" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Tia'sGrace-55874" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-Tia'sGrace-56394" value: { - dps: 35281.78119 - tps: 33830.5998 + dps: 36105.4219 + tps: 34526.64258 } } dps_results: { key: "TestFire-AllItems-TimeLord'sRegalia" value: { - dps: 32019.34969 - tps: 31505.50753 + dps: 31942.77326 + tps: 31353.41116 } } dps_results: { key: "TestFire-AllItems-TinyAbominationinaJar-50706" value: { - dps: 35404.37156 - tps: 33918.88485 + dps: 35858.24375 + tps: 34295.70043 } } dps_results: { key: "TestFire-AllItems-Tyrande'sFavoriteDoll-64645" value: { - dps: 36425.11833 - tps: 34953.95931 + dps: 37130.20184 + tps: 35550.41973 } } dps_results: { key: "TestFire-AllItems-UnheededWarning-59520" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-UnquenchableFlame-67101" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-UnsolvableRiddle-62463" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-UnsolvableRiddle-62468" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-UnsolvableRiddle-68709" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-VariablePulseLightningCapacitor-68925" value: { - dps: 37117.23746 - tps: 35624.95208 + dps: 37096.65834 + tps: 35484.30853 } } dps_results: { key: "TestFire-AllItems-Varo'then'sBrooch-72899" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VeilofLies-72900" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VesselofAcceleration-68995" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VesselofAcceleration-69167" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VialofShadows-77207" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VialofShadows-77979" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VialofShadows-77999" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VialofStolenMemories-59515" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-VialofStolenMemories-65109" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sBadgeofConquest-61033" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sBadgeofDominance-61035" value: { - dps: 36140.19944 - tps: 34650.64998 + dps: 36727.20633 + tps: 35111.30414 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sBadgeofVictory-61034" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sEmblemofAccuracy-61027" value: { - dps: 35436.15424 - tps: 33962.65249 + dps: 35670.57748 + tps: 34086.08392 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sEmblemofAlacrity-61028" value: { - dps: 35996.30801 - tps: 34491.29662 + dps: 35217.17728 + tps: 33671.19467 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sEmblemofCruelty-61026" value: { - dps: 36191.6554 - tps: 34704.11153 + dps: 36044.78448 + tps: 34480.85674 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sEmblemofProficiency-61030" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sEmblemofProwess-61029" value: { - dps: 35522.37431 - tps: 34055.41921 + dps: 36211.0521 + tps: 34632.27277 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sEmblemofTenacity-61032" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sInsigniaofConquest-61047" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sInsigniaofDominance-61045" value: { - dps: 36288.01283 - tps: 34793.97798 + dps: 36740.121 + tps: 35126.88131 } } dps_results: { key: "TestFire-AllItems-ViciousGladiator'sInsigniaofVictory-61046" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-WillofUnbinding-77198" value: { - dps: 38709.35268 - tps: 37162.79622 + dps: 39319.81636 + tps: 37669.14779 } } dps_results: { key: "TestFire-AllItems-WillofUnbinding-77975" value: { - dps: 38435.40557 - tps: 36919.97039 + dps: 39223.9205 + tps: 37588.39072 } } dps_results: { key: "TestFire-AllItems-WillofUnbinding-77995" value: { - dps: 39075.7481 - tps: 37502.55839 + dps: 39809.71365 + tps: 38157.404 } } dps_results: { key: "TestFire-AllItems-WitchingHourglass-55787" value: { - dps: 36487.39487 - tps: 34970.55706 + dps: 36749.26824 + tps: 35174.25035 } } dps_results: { key: "TestFire-AllItems-WitchingHourglass-56320" value: { - dps: 37529.76141 - tps: 36029.68277 + dps: 37275.2654 + tps: 35694.74532 } } dps_results: { key: "TestFire-AllItems-World-QuellerFocus-63842" value: { - dps: 35180.04609 - tps: 33728.8647 + dps: 35999.79171 + tps: 34421.01238 } } dps_results: { key: "TestFire-AllItems-WrathofUnchaining-77197" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-WrathofUnchaining-77974" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-WrathofUnchaining-77994" value: { - dps: 34874.8408 - tps: 33423.65941 + dps: 35702.87944 + tps: 34134.75907 } } dps_results: { key: "TestFire-AllItems-Za'brox'sLuckyTooth-63742" value: { - dps: 35519.72625 - tps: 34058.46186 + dps: 36085.41645 + tps: 34514.06911 } } dps_results: { key: "TestFire-AllItems-Za'brox'sLuckyTooth-63745" value: { - dps: 35519.72625 - tps: 34058.46186 + dps: 36085.41645 + tps: 34514.06911 } } dps_results: { key: "TestFire-Average-Default" value: { - dps: 39218.68503 - tps: 37658.4094 + dps: 39439.58621 + tps: 37801.07618 } } dps_results: { key: "TestFire-Settings-Troll-p3_fire-Fire-fire-FullBuffs-0.0yards-LongMultiTarget" value: { - dps: 62147.60926 - tps: 62580.79663 + dps: 64450.93805 + tps: 64718.42447 } } dps_results: { key: "TestFire-Settings-Troll-p3_fire-Fire-fire-FullBuffs-0.0yards-LongSingleTarget" value: { - dps: 37870.87736 - tps: 36330.90054 + dps: 38669.82148 + tps: 37040.72983 } } dps_results: { key: "TestFire-Settings-Troll-p3_fire-Fire-fire-FullBuffs-0.0yards-ShortSingleTarget" value: { - dps: 48346.62271 - tps: 46450.61279 + dps: 49243.10375 + tps: 47313.45584 } } dps_results: { key: "TestFire-Settings-Troll-p3_fire-Fire-fire-NoBuffs-0.0yards-LongMultiTarget" value: { - dps: 43349.69609 - tps: 46349.6273 + dps: 43089.94803 + tps: 46188.93996 } } dps_results: { key: "TestFire-Settings-Troll-p3_fire-Fire-fire-NoBuffs-0.0yards-LongSingleTarget" value: { - dps: 25910.0482 - tps: 24852.52112 + dps: 26024.94616 + tps: 24987.22243 } } dps_results: { key: "TestFire-Settings-Troll-p3_fire-Fire-fire-NoBuffs-0.0yards-ShortSingleTarget" value: { - dps: 29328.58069 - tps: 27776.67784 + dps: 29016.31014 + tps: 27633.08097 } } dps_results: { key: "TestFire-Settings-Worgen-p3_fire-Fire-fire-FullBuffs-0.0yards-LongMultiTarget" value: { - dps: 60535.03179 - tps: 60908.42248 + dps: 61852.90025 + tps: 62198.61392 } } dps_results: { key: "TestFire-Settings-Worgen-p3_fire-Fire-fire-FullBuffs-0.0yards-LongSingleTarget" value: { - dps: 38025.12517 - tps: 36551.97925 + dps: 37632.63748 + tps: 36100.45695 } } dps_results: { key: "TestFire-Settings-Worgen-p3_fire-Fire-fire-FullBuffs-0.0yards-ShortSingleTarget" value: { - dps: 47147.14546 - tps: 45319.16597 + dps: 46849.85418 + tps: 45048.46743 } } dps_results: { key: "TestFire-Settings-Worgen-p3_fire-Fire-fire-NoBuffs-0.0yards-LongMultiTarget" value: { - dps: 44238.35876 - tps: 47078.73695 + dps: 43591.33113 + tps: 46611.70942 } } dps_results: { key: "TestFire-Settings-Worgen-p3_fire-Fire-fire-NoBuffs-0.0yards-LongSingleTarget" value: { - dps: 26114.86826 - tps: 24867.89592 + dps: 25855.29761 + tps: 24833.78204 } } dps_results: { key: "TestFire-Settings-Worgen-p3_fire-Fire-fire-NoBuffs-0.0yards-ShortSingleTarget" value: { - dps: 28147.64337 - tps: 26452.79036 + dps: 26500.71704 + tps: 25229.96602 } } dps_results: { key: "TestFire-SwitchInFrontOfTarget-Default" value: { - dps: 37870.87736 - tps: 36330.90054 + dps: 38669.82148 + tps: 37040.72983 } } diff --git a/sim/mage/mage.go b/sim/mage/mage.go index b72a32107a..77dc7fd4a8 100644 --- a/sim/mage/mage.go +++ b/sim/mage/mage.go @@ -50,6 +50,8 @@ type Mage struct { brainFreezeProcChance float64 hotStreakProcChance float64 + previousCombustionDotEstimate int32 + ClassSpellScaling float64 } diff --git a/ui/core/components/detailed_results/log_runner.tsx b/ui/core/components/detailed_results/log_runner.tsx index 72e6ebe2bc..7ea45b3eee 100644 --- a/ui/core/components/detailed_results/log_runner.tsx +++ b/ui/core/components/detailed_results/log_runner.tsx @@ -132,7 +132,8 @@ export class LogRunner extends ResultComponent { } onSimResult(resultData: SimResultData): void { - this.virtualScroll?.setItems(this.getLogs(resultData) || []); + this.getLogs(resultData) + this.searchLogs(this.ui.search.value) } getLogs(resultData: SimResultData) { diff --git a/ui/core/components/individual_sim_ui/apl_values.ts b/ui/core/components/individual_sim_ui/apl_values.ts index b13983eb04..c3fe76c940 100644 --- a/ui/core/components/individual_sim_ui/apl_values.ts +++ b/ui/core/components/individual_sim_ui/apl_values.ts @@ -48,6 +48,7 @@ import { APLValueInputDelay, APLValueIsExecutePhase, APLValueIsExecutePhase_ExecutePhaseThreshold as ExecutePhaseThreshold, + APLValueMageCurrentCombustionDotEstimate, APLValueMath, APLValueMath_MathOperator as MathOperator, APLValueMax, @@ -1040,4 +1041,12 @@ const valueKindFactories: { [f in NonNullable]: ValueKindConfig, _isPrepull: boolean) => player.getClass() == Class.ClassWarlock, fields: [AplHelpers.unitFieldConfig('targetUnit', 'targets')], }), + mageCurrentCombustionDotEstimate: inputBuilder({ + label: 'Combustion Dot Value', + submenu: ['Mage'], + shortDescription: 'Returns the current estimated size of your Combustion Dot.', + newValue: APLValueMageCurrentCombustionDotEstimate.create, + includeIf: (player: Player, _isPrepull: boolean) => player.getSpec() == Spec.SpecFireMage, + fields: [], + }), }; diff --git a/ui/core/components/individual_sim_ui/gear_tab.ts b/ui/core/components/individual_sim_ui/gear_tab.ts index 2f67cab23f..de819168b9 100644 --- a/ui/core/components/individual_sim_ui/gear_tab.ts +++ b/ui/core/components/individual_sim_ui/gear_tab.ts @@ -54,7 +54,7 @@ export class GearTab extends SimTab { } private buildPresetConfigurationPicker() { - new PresetConfigurationPicker(this.rightPanel, this.simUI, 'gear'); + new PresetConfigurationPicker(this.rightPanel, this.simUI, ['gear']); } private buildSavedGearsetPicker() { diff --git a/ui/core/components/individual_sim_ui/preset_configuration_picker.tsx b/ui/core/components/individual_sim_ui/preset_configuration_picker.tsx index b3938370e3..c6d41e2abd 100644 --- a/ui/core/components/individual_sim_ui/preset_configuration_picker.tsx +++ b/ui/core/components/individual_sim_ui/preset_configuration_picker.tsx @@ -10,19 +10,19 @@ import { TypedEvent } from '../../typed_event'; import { Component } from '../component'; import { ContentBlock } from '../content_block'; -type PresetConfigurationCategory = 'gear' | 'talents' | 'rotation' | 'encounter'; +type PresetConfigurationCategory = 'gear' | 'talents' | 'rotation' | 'encounter' | 'race'; export class PresetConfigurationPicker extends Component { readonly simUI: IndividualSimUI; readonly builds: Array; - constructor(parentElem: HTMLElement, simUI: IndividualSimUI, type?: PresetConfigurationCategory) { + constructor(parentElem: HTMLElement, simUI: IndividualSimUI, types?: PresetConfigurationCategory[]) { super(parentElem, 'preset-configuration-picker-root'); this.rootElem.classList.add('saved-data-manager-root'); this.simUI = simUI; this.builds = (this.simUI.individualConfig.presets.builds ?? []).filter(build => - Object.keys(build).some(category => category === type && !!build[category]), + Object.keys(build).some(category => types?.includes(category as PresetConfigurationCategory) && !!build[category as PresetConfigurationCategory]), ); if (!this.builds.length) { @@ -83,10 +83,11 @@ export class PresetConfigurationPicker extends Component { }); } - private applyBuild({ gear, rotation, talents, epWeights, encounter }: PresetBuild) { + private applyBuild({ gear, rotation, talents, epWeights, encounter, race }: PresetBuild) { const eventID = TypedEvent.nextEventID(); TypedEvent.freezeAllAndDo(() => { if (gear) this.simUI.player.setGear(eventID, this.simUI.sim.db.lookupEquipmentSpec(gear.gear)); + if (race) this.simUI.player.setRace(eventID, race); if (talents) { this.simUI.player.setTalentsString(eventID, talents.data.talentsString); if (talents.data.glyphs) this.simUI.player.setGlyphs(eventID, talents.data.glyphs); @@ -107,8 +108,9 @@ export class PresetConfigurationPicker extends Component { }); } - private isBuildActive({ gear, rotation, talents, epWeights, encounter }: PresetBuild): boolean { + private isBuildActive({ gear, rotation, talents, epWeights, encounter, race }: PresetBuild): boolean { const hasGear = gear ? EquipmentSpec.equals(gear.gear, this.simUI.player.getGear().asSpec()) : true; + const hasRace = typeof race === 'number' ? race === this.simUI.player.getRace() : true; const hasTalents = talents ? SavedTalents.equals( talents.data, @@ -124,7 +126,10 @@ export class PresetConfigurationPicker extends Component { // Ensure that the auto rotation can be matched with a preset if (activeRotation.type === APLRotation_Type.TypeAuto) activeRotation.type = APLRotation_Type.TypeAPL; if (rotation.rotation?.rotation?.type === APLRotation_Type.TypeSimple && rotation.rotation.rotation?.simple?.specRotationJson) { - hasRotation = this.simUI.player.specTypeFunctions.rotationEquals(this.simUI.player.specTypeFunctions.rotationFromJson(JSON.parse(rotation.rotation.rotation.simple.specRotationJson)), this.simUI.player.getSimpleRotation()); + hasRotation = this.simUI.player.specTypeFunctions.rotationEquals( + this.simUI.player.specTypeFunctions.rotationFromJson(JSON.parse(rotation.rotation.rotation.simple.specRotationJson)), + this.simUI.player.getSimpleRotation(), + ); } else { hasRotation = APLRotation.equals(rotation.rotation.rotation, activeRotation); } @@ -133,6 +138,6 @@ export class PresetConfigurationPicker extends Component { const hasEncounter = encounter?.encounter ? Encounter.equals(encounter.encounter, this.simUI.sim.encounter.toProto()) : true; const hasHealingModel = encounter?.healingModel ? HealingModel.equals(encounter.healingModel, this.simUI.player.getHealingModel()) : true; - return hasGear && hasTalents && hasRotation && hasEpWeights && hasEncounter && hasHealingModel; + return hasGear && hasRace && hasTalents && hasRotation && hasEpWeights && hasEncounter && hasHealingModel; } } diff --git a/ui/core/components/individual_sim_ui/rotation_tab.tsx b/ui/core/components/individual_sim_ui/rotation_tab.tsx index 3f6cafc6cc..9801ed4cae 100644 --- a/ui/core/components/individual_sim_ui/rotation_tab.tsx +++ b/ui/core/components/individual_sim_ui/rotation_tab.tsx @@ -189,7 +189,7 @@ export class RotationTab extends SimTab { } private buildPresetConfigurationPicker() { - new PresetConfigurationPicker(this.rightPanel, this.simUI, 'rotation'); + new PresetConfigurationPicker(this.rightPanel, this.simUI, ['rotation']); } private buildSavedDataPickers() { diff --git a/ui/core/components/individual_sim_ui/settings_tab.ts b/ui/core/components/individual_sim_ui/settings_tab.ts index b25d0556c2..f9195fda2c 100644 --- a/ui/core/components/individual_sim_ui/settings_tab.ts +++ b/ui/core/components/individual_sim_ui/settings_tab.ts @@ -247,7 +247,7 @@ export class SettingsTab extends SimTab { } private buildPresetConfigurationPicker() { - new PresetConfigurationPicker(this.rightPanel, this.simUI, 'encounter'); + new PresetConfigurationPicker(this.rightPanel, this.simUI, ['encounter', 'race']); } private buildSavedDataPickers() { diff --git a/ui/core/components/individual_sim_ui/talents_tab.ts b/ui/core/components/individual_sim_ui/talents_tab.ts index 10c7bab18a..2d4ee32bb1 100644 --- a/ui/core/components/individual_sim_ui/talents_tab.ts +++ b/ui/core/components/individual_sim_ui/talents_tab.ts @@ -107,7 +107,7 @@ export class TalentsTab extends SimTab { } private buildPresetConfigurationPicker() { - new PresetConfigurationPicker(this.rightPanel, this.simUI, 'talents'); + new PresetConfigurationPicker(this.rightPanel, this.simUI, ['talents']); } private buildSavedTalentsPicker() { diff --git a/ui/core/preset_utils.tsx b/ui/core/preset_utils.tsx index 158551d300..06ea9018cb 100644 --- a/ui/core/preset_utils.tsx +++ b/ui/core/preset_utils.tsx @@ -13,6 +13,7 @@ import { Faction, HealingModel, IndividualBuffs, + Race, RaidBuffs, Spec, UnitReference, @@ -81,6 +82,7 @@ export interface PresetBuild { rotation?: PresetRotation; epWeights?: PresetEpWeights; encounter?: PresetEncounter; + race?: Race; } export interface PresetBuildOptions extends Omit {} @@ -222,8 +224,8 @@ export const makePresetEncounter = (name: string, encounter?: PresetEncounter['e }; }; -export const makePresetBuild = (name: string, { gear, talents, rotation, epWeights, encounter }: PresetBuildOptions): PresetBuild => { - return { name, gear, talents, rotation, epWeights, encounter }; +export const makePresetBuild = (name: string, { gear, talents, rotation, epWeights, encounter, race }: PresetBuildOptions): PresetBuild => { + return { name, gear, talents, rotation, epWeights, encounter, race }; }; export type SpecCheckWarning = { diff --git a/ui/mage/fire/apls/fire.apl.json b/ui/mage/fire/apls/fire.apl.json index 3425fd8590..db5c882081 100644 --- a/ui/mage/fire/apls/fire.apl.json +++ b/ui/mage/fire/apls/fire.apl.json @@ -12,10 +12,10 @@ {"action":{"condition":{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"7s"}}}},"castSpell":{"spellId":{"spellId":82174}}}}, {"action":{"condition":{"or":{"vals":[{"spellIsReady":{"spellId":{"spellId":11129}}}]}},"castSpell":{"spellId":{"itemId":58091}}}}, {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"10s"}}}},{"cmp":{"op":"OpGt","lhs":{"currentManaPercent":{}},"rhs":{"const":{"val":"25%"}}}}]}},"castSpell":{"spellId":{"spellId":30482}}}}, - {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"cmp":{"op":"OpGt","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"34000"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":11366,"tag":1}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, - {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLt","lhs":{"auraRemainingTime":{"auraId":{"spellId":26297}}},"rhs":{"const":{"val":"2.5s"}}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"11220"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, - {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"22100"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":11366,"tag":1}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, - {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"15s"}}}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"11220"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, + {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"cmp":{"op":"OpGt","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"515000"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, + {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLt","lhs":{"auraRemainingTime":{"auraId":{"spellId":26297}}},"rhs":{"const":{"val":"2.5s"}}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"260000"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, + {"action":{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"190000"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"15s"}}}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"190000"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}}, {"action":{"condition":{"and":{"vals":[{"auraIsActiveWithReactionTime":{"auraId":{"spellId":48108}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"spellTravelTime":{"spellId":{"spellId":11366}}}}}]}},"castSpell":{"spellId":{"spellId":11366}}}}, {"action":{"condition":{"and":{"vals":[{"auraIsInactiveWithReactionTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}},{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"5s"}}}}]}},"castSpell":{"spellId":{"spellId":44457}}}}, {"action":{"condition":{"not":{"val":{"spellIsReady":{"spellId":{"spellId":11129}}}}},"castSpell":{"spellId":{"spellId":82731}}}}, diff --git a/ui/mage/fire/inputs.tsx b/ui/mage/fire/inputs.tsx index 2a94bf0d82..9b379f9c58 100644 --- a/ui/mage/fire/inputs.tsx +++ b/ui/mage/fire/inputs.tsx @@ -10,45 +10,27 @@ export const MageRotationConfig = { // FIRE INPUTS // ******************************************************** InputHelpers.makeRotationNumberInput({ - fieldName: 'igniteCombustThreshold', - label: 'Ignite Combust Threshold', - labelTooltip: 'The Ignite damage threshold to use Combustion during Bloodlust', - description: ( - <> -

Should be set to the Ignite damage threshold at which you want to use Combustion during Bloodlust.

-

You can check the Sim or your logs to find a value that is feasible to hit.

-

Furthermore a % of this value will be used for other Combust usages outside of the Bloodlust window:

-

Example: Setting the Ignite Combust Threshold to 30.000 will:

-
    -
  • Cast Combust whilst Bloodlust is active when Ignite exceeds 30.000 (100%) damage.
  • -
  • Cast Combust at the last moment when Bloodlust (+ Berserking) is running out when Ignite exceeds 10.000 (33%) damage
  • -
  • Cast Combust outside of Bloodlust when Ignite exceeds 15.000 (50%) damage
  • -
  • Cast Combust when encounter is ending in 15 seconds when Ignite exceeds 10.000 (33%) damage
  • -
- - ), + fieldName: 'combustThreshold', + label: 'Combust Threshold - Bloodlust', + labelTooltip: 'The value at which Combustion should be cast during Bloodlust', changeEmitter: player => player.rotationChangeEmitter, - getValue: player => player.getSimpleRotation().igniteCombustThreshold, + getValue: player => player.getSimpleRotation().combustThreshold, positive: true, }), InputHelpers.makeRotationNumberInput({ - fieldName: 'igniteLastMomentLustPercentage', - label: 'Max Ignite % - Last moment during Bloodlust', - labelTooltip: 'Using a % of the "Ignite Combust Threshold" to use Combustion when Bloodlust (+ Berserking) is about to run out.', + fieldName: 'combustLastMomentLustPercentage', + label: 'Combust Threshold - Last moment during Bloodlust', + labelTooltip: 'The value at which Combustion should be cast when Bloodlust (+ Berserking) is about to run out.', changeEmitter: player => player.rotationChangeEmitter, - getValue: player => player.getSimpleRotation().igniteLastMomentLustPercentage, - percent: true, - max: 1, + getValue: player => player.getSimpleRotation().combustLastMomentLustPercentage, positive: true, }), InputHelpers.makeRotationNumberInput({ - fieldName: 'igniteNoLustPercentage', - label: 'Max Ignite % - Outside of Bloodlust', - labelTooltip: 'Using a % of the "Ignite Combust Threshold" to use Combustion when Bloodlust is not up.', + fieldName: 'combustNoLustPercentage', + label: 'Combust Threshold - Outside of Bloodlust', + labelTooltip: 'The value at which Combustion should be cast when Bloodlust is not up.', changeEmitter: player => player.rotationChangeEmitter, - getValue: player => player.getSimpleRotation().igniteNoLustPercentage, - percent: true, - max: 1, + getValue: player => player.getSimpleRotation().combustNoLustPercentage, positive: true, }), ], diff --git a/ui/mage/fire/presets.ts b/ui/mage/fire/presets.ts index 387a1877c0..443266a3b5 100644 --- a/ui/mage/fire/presets.ts +++ b/ui/mage/fire/presets.ts @@ -1,5 +1,5 @@ import * as PresetUtils from '../../core/preset_utils'; -import { Consumes, Debuffs, Flask, Food, Glyphs, Potions, Profession, PseudoStat, RaidBuffs, Spec, Stat, TinkerHands } from '../../core/proto/common'; +import { Consumes, Debuffs, Flask, Food, Glyphs, Potions, Profession, PseudoStat, Race, RaidBuffs, Spec, Stat, TinkerHands } from '../../core/proto/common'; import { FireMage_Options as MageOptions, FireMage_Rotation, @@ -24,19 +24,26 @@ export const FIRE_P1_PREBIS = PresetUtils.makePresetGear('P1 Pre-raid', P1FirePr export const FIRE_P3_PRESET = PresetUtils.makePresetGear('P3 Preset', P3FireBisGear, { talentTree: 1 }); export const P1DefaultSimpleRotation = FireMage_Rotation.create({ - igniteCombustThreshold: 30000, - igniteLastMomentLustPercentage: 0.3, - igniteNoLustPercentage: 0.6, + combustThreshold: 400000, + combustLastMomentLustPercentage: 190000, + combustNoLustPercentage: 230000, }); -export const P3DefaultSimpleRotation = FireMage_Rotation.create({ - igniteCombustThreshold: 34000, - igniteLastMomentLustPercentage: 0.33, - igniteNoLustPercentage: 0.65, +export const P3TrollDefaultSimpleRotation = FireMage_Rotation.create({ + combustThreshold: 515000, + combustLastMomentLustPercentage: 190000, + combustNoLustPercentage: 260000, +}); + +export const P3NoTrollDefaultSimpleRotation = FireMage_Rotation.create({ + combustThreshold: 370000, + combustLastMomentLustPercentage: 210000, + combustNoLustPercentage: 250000, }); export const P1_SIMPLE_ROTATION_DEFAULT = PresetUtils.makePresetSimpleRotation('P1 - Default', Spec.SpecFireMage, P1DefaultSimpleRotation); -export const P3_SIMPLE_ROTATION_DEFAULT = PresetUtils.makePresetSimpleRotation('P3 - Default', Spec.SpecFireMage, P3DefaultSimpleRotation); +export const P3_SIMPLE_ROTATION_DEFAULT = PresetUtils.makePresetSimpleRotation('P3 - Default', Spec.SpecFireMage, P3TrollDefaultSimpleRotation); +export const P3_SIMPLE_ROTATION_NO_TROLL = PresetUtils.makePresetSimpleRotation('P3 - Not Troll', Spec.SpecFireMage, P3NoTrollDefaultSimpleRotation); //export const ROTATION_PRESET_SIMPLE = PresetUtils.makePresetSimpleRotation('Simple Default', Spec.SpecFireMage, DefaultSimpleRotation); export const FIRE_ROTATION_PRESET_DEFAULT = PresetUtils.makePresetAPLRotation('APL', FireApl, { talentTree: 1 }); @@ -157,11 +164,19 @@ export const FIRE_BREAKPOINTS: UnitStatPresets[] = [ ]; export const P1_PRESET_BUILD = PresetUtils.makePresetBuild('P1 - Default', { + race: Race.RaceTroll, gear: FIRE_P1_PRESET, rotation: P1_SIMPLE_ROTATION_DEFAULT, }); -export const P3_PRESET_BUILD = PresetUtils.makePresetBuild('P3 - Default', { +export const P3_PRESET_BUILD = PresetUtils.makePresetBuild('P3 - Default (Troll)', { + race: Race.RaceTroll, gear: FIRE_P3_PRESET, rotation: P3_SIMPLE_ROTATION_DEFAULT, }); + +export const P3_PRESET_NO_TROLL = PresetUtils.makePresetBuild('P3 - Default (Worgen)', { + race: Race.RaceWorgen, + gear: FIRE_P3_PRESET, + rotation: P3_SIMPLE_ROTATION_NO_TROLL, +}); diff --git a/ui/mage/fire/sim.tsx b/ui/mage/fire/sim.tsx index b92be6eefe..040500ea91 100644 --- a/ui/mage/fire/sim.tsx +++ b/ui/mage/fire/sim.tsx @@ -8,6 +8,7 @@ import { APLAction, APLListItem, APLRotation, APLRotation_Type, SimpleRotation } import { Cooldowns, Faction, IndividualBuffs, PartyBuffs, PseudoStat, Race, Spec, Stat } from '../../core/proto/common'; import { StatCapType } from '../../core/proto/ui'; import { StatCap, Stats, UnitStat } from '../../core/proto_utils/stats'; +import { TypedEvent } from '../../core/typed_event'; import { formatToNumber } from '../../core/utils'; import { sharedMageDisplayStatsModifiers } from '../shared'; import * as FireInputs from './inputs'; @@ -121,39 +122,44 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFireMage, { presets: { epWeights: [Presets.DEFAULT_EP_PRESET], // Preset rotations that the user can quickly select. - rotations: [Presets.P1_SIMPLE_ROTATION_DEFAULT, Presets.P3_SIMPLE_ROTATION_DEFAULT, Presets.FIRE_ROTATION_PRESET_DEFAULT], + rotations: [ + Presets.P1_SIMPLE_ROTATION_DEFAULT, + Presets.P3_SIMPLE_ROTATION_DEFAULT, + Presets.P3_SIMPLE_ROTATION_NO_TROLL, + Presets.FIRE_ROTATION_PRESET_DEFAULT, + ], // Preset talents that the user can quickly select. talents: [Presets.FireTalents], // Preset gear configurations that the user can quickly select. gear: [Presets.FIRE_P1_PRESET, Presets.FIRE_P1_PREBIS, Presets.FIRE_P3_PRESET], - builds: [Presets.P1_PRESET_BUILD, Presets.P3_PRESET_BUILD], + builds: [Presets.P1_PRESET_BUILD, Presets.P3_PRESET_BUILD, Presets.P3_PRESET_NO_TROLL], }, autoRotation: (): APLRotation => { return Presets.FIRE_ROTATION_PRESET_DEFAULT.rotation.rotation!; }, - simpleRotation: (_, simple): APLRotation => { + simpleRotation: (player, simple): APLRotation => { + // Migrate old Ignite based settings to new format by defaulting to the P3 rotation. + if (simple.igniteCombustThreshold !== 0 || simple.igniteLastMomentLustPercentage !== 0 || simple.igniteNoLustPercentage !== 0) { + const rotation = player.getRace() === Race.RaceTroll ? Presets.P3TrollDefaultSimpleRotation : Presets.P3NoTrollDefaultSimpleRotation; + player.setSimpleRotation(TypedEvent.nextEventID(), rotation); + } + const rotation = Presets.FIRE_ROTATION_PRESET_DEFAULT.rotation.rotation!; - const { igniteCombustThreshold, igniteLastMomentLustPercentage, igniteNoLustPercentage } = simple; + const { combustThreshold, combustLastMomentLustPercentage, combustNoLustPercentage } = simple; const maxCombustDuringLust = APLAction.fromJsonString( - `{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"cmp":{"op":"OpGt","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"${igniteCombustThreshold}"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":11366,"tag":1}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, + `{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"cmp":{"op":"OpGt","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"${combustThreshold}"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, ); const lastMomentCombustDuringLust = APLAction.fromJsonString( - `{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLt","lhs":{"auraRemainingTime":{"auraId":{"spellId":26297}}},"rhs":{"const":{"val":"2.5s"}}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"${ - igniteCombustThreshold * igniteLastMomentLustPercentage - }"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, + `{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"auraIsActive":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpLt","lhs":{"auraRemainingTime":{"auraId":{"spellId":26297}}},"rhs":{"const":{"val":"2.5s"}}}},{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"auraId":{"spellId":2825,"tag":-1}}},"rhs":{"const":{"val":"2s"}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"${combustLastMomentLustPercentage}"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, ); const combustOutsideOfLustAndBerserking = APLAction.fromJsonString( - `{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"${ - igniteCombustThreshold * igniteNoLustPercentage - }"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":11366,"tag":1}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, + `{"condition":{"and":{"vals":[{"or":{"vals":[{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":26297}}},{"cmp":{"op":"OpGt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"17s"}}}}]}},{"and":{"vals":[{"not":{"val":{"auraIsKnown":{"auraId":{"spellId":26297}}}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":2825,"tag":-1}}}}}]}}]}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"${combustNoLustPercentage}"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, ); const lastMomentCombustBeforeEncounter = APLAction.fromJsonString( - `{"condition":{"and":{"vals":[{"cmp":{"op":"OpLt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"15s"}}}},{"cmp":{"op":"OpGt","lhs":{"auraNumStacks":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},"rhs":{"const":{"val":"${ - igniteCombustThreshold * igniteLastMomentLustPercentage - }"}}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":12846}}},{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":44457}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, + `{"condition":{"and":{"vals":[{"cmp":{"op":"OpLt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"15s"}}}},{"cmp":{"op":"OpGt","lhs":{"mageCurrentCombustionDotEstimate":{}},"rhs":{"const":{"val":"${combustLastMomentLustPercentage}"}}}}]}},"castSpell":{"spellId":{"spellId":11129}}}`, ); const modifiedSimpleRotation = rotation;