diff --git a/sim/core/apl.go b/sim/core/apl.go index fa36b70f03..1041630d1d 100644 --- a/sim/core/apl.go +++ b/sim/core/apl.go @@ -282,7 +282,7 @@ func (apl *APLRotation) DoNextAction(sim *Simulation) { return } - if apl.unit.ChanneledDot != nil { + if apl.unit.IsChanneling() && !apl.unit.ChanneledDot.Spell.Flags.Matches(SpellFlagCastWhileChanneling) { return } @@ -347,13 +347,7 @@ func (apl *APLRotation) popControllingAction(ca APLActionImpl) { func (apl *APLRotation) shouldInterruptChannel(sim *Simulation) bool { channeledDot := apl.unit.ChanneledDot - if channeledDot.remainingTicks == 0 { - // Channel has ended, but apl.unit.ChanneledDot hasn't been cleared yet meaning the aura is still active. - return false - } - - if apl.interruptChannelIf == nil || !apl.interruptChannelIf.GetBool(sim) { - // Continue the channel. + if !channeledDot.ChannelCanBeInterrupted(sim) { return false } diff --git a/sim/core/cast.go b/sim/core/cast.go index 64a5f00b2c..32b4766aaf 100644 --- a/sim/core/cast.go +++ b/sim/core/cast.go @@ -150,6 +150,10 @@ func (spell *Spell) makeCastFunc(config CastConfig) CastSuccessFunc { return spell.castFailureHelper(sim, "casting/channeling %v for %s, curTime = %s", hc.ActionID, hc.Expires-sim.CurrentTime, sim.CurrentTime) } + if spell.Unit.IsCastingDuringChannel() && !spell.CanCastDuringChannel(sim) { + return spell.castFailureHelper(sim, "cannot interrupt in-progress channel of %v with a cast of %v", spell.Unit.ChanneledDot.ActionID, spell.ActionID) + } + if effectiveTime := spell.CurCast.EffectiveTime(); effectiveTime != 0 { // do not add channeled time here as they have variable cast length diff --git a/sim/core/dot.go b/sim/core/dot.go index f6bb04f805..8859750a80 100644 --- a/sim/core/dot.go +++ b/sim/core/dot.go @@ -323,6 +323,24 @@ func (dot *Dot) getChannelClipDelay(sim *Simulation) time.Duration { return dot.Spell.Unit.ChannelClipDelay } +func (dot *Dot) ChannelCanBeInterrupted(sim *Simulation) bool { + if !dot.isChanneled { + return false + } + + // Channel has ended, but dot.Spell.Unit.ChanneledDot hasn't been cleared yet, meaning the Aura is still active. + if dot.remainingTicks == 0 { + return false + } + + // APL specifies that the channel should be continued. + apl := dot.Spell.Unit.Rotation + if (apl.interruptChannelIf == nil) || !apl.interruptChannelIf.GetBool(sim) { + return false + } + + return true +} func newDot(config Dot) *Dot { dot := &config diff --git a/sim/core/flags.go b/sim/core/flags.go index 7de3bdf4d4..53ff6fbe66 100644 --- a/sim/core/flags.go +++ b/sim/core/flags.go @@ -165,6 +165,7 @@ const ( SpellFlagCannotBeDodged // Ignores dodge in physical hit rolls SpellFlagBinary // Does not do partial resists and could need a different hit roll. SpellFlagChanneled // Spell is channeled + SpellFlagCastWhileChanneling // Spell can be cast while channeling. If SpellFlagChanneled and SpellFlagCastWhileChanneling are both set, it means that other spells with the SpellFlagCastWhileChanneling flag can be cast without interrupting the channeled spell. SpellFlagDisease // Spell is categorized as disease SpellFlagHelpful // For healing spells / buffs. SpellFlagMeleeMetrics // Marks a spell as a melee ability for metrics. diff --git a/sim/core/spell.go b/sim/core/spell.go index 43fd330b95..1c3379686e 100644 --- a/sim/core/spell.go +++ b/sim/core/spell.go @@ -601,7 +601,7 @@ func (spell *Spell) CanCast(sim *Simulation, target *Unit) bool { } // While casting or channeling, no other action is possible - if spell.Unit.Hardcast.Expires > sim.CurrentTime { + if (spell.Unit.Hardcast.Expires > sim.CurrentTime) || (spell.Unit.IsCastingDuringChannel() && !spell.CanCastDuringChannel(sim)) { //if sim.Log != nil { // sim.Log("Cant cast because already casting/channeling") //} @@ -639,6 +639,19 @@ func (spell *Spell) CanCast(sim *Simulation, target *Unit) bool { return true } +func (spell *Spell) CanCastDuringChannel(sim *Simulation) bool { + // Don't allow bypassing of channel clip logic for re-casts of the same channel + if spell == spell.Unit.ChanneledDot.Spell { + return false + } + + if spell.Flags.Matches(SpellFlagCastWhileChanneling) { + return true + } + + return spell.Unit.ChanneledDot.ChannelCanBeInterrupted(sim) +} + func (spell *Spell) Cast(sim *Simulation, target *Unit) bool { if spell.DefaultCast.EffectiveTime() > 0 { spell.Unit.CancelQueuedSpell(sim) diff --git a/sim/core/spell_mod.go b/sim/core/spell_mod.go index 9c70f69b74..8e01e1a862 100644 --- a/sim/core/spell_mod.go +++ b/sim/core/spell_mod.go @@ -329,6 +329,9 @@ const ( // Enables casting while moving SpellMod_AllowCastWhileMoving + // Enables casting while channeling + SpellMod_AllowCastWhileChanneling + // Add/subtract bonus spell power // Uses: FloatValue SpellMod_BonusSpellPower_Flat @@ -448,6 +451,11 @@ var spellModMap = map[SpellModType]*SpellModFunctions{ Remove: removeAllowCastWhileMoving, }, + SpellMod_AllowCastWhileChanneling: { + Apply: applyAllowCastWhileChanneling, + Remove: removeAllowCastWhileChanneling, + }, + SpellMod_BonusSpellPower_Flat: { Apply: applyBonusSpellPowerFlat, Remove: removeBonusSpellPowerFlat, @@ -680,6 +688,14 @@ func removeAllowCastWhileMoving(mod *SpellMod, spell *Spell) { spell.Flags ^= SpellFlagCanCastWhileMoving } +func applyAllowCastWhileChanneling(mod *SpellMod, spell *Spell) { + spell.Flags |= SpellFlagCastWhileChanneling +} + +func removeAllowCastWhileChanneling(mod *SpellMod, spell *Spell) { + spell.Flags ^= SpellFlagCastWhileChanneling +} + func applyBonusSpellPowerFlat(mod *SpellMod, spell *Spell) { spell.BonusSpellPower += mod.floatValue } diff --git a/sim/core/spell_queueing.go b/sim/core/spell_queueing.go index 7a5d6d45ad..99e47a43d6 100644 --- a/sim/core/spell_queueing.go +++ b/sim/core/spell_queueing.go @@ -94,7 +94,7 @@ func (spell *Spell) CanQueue(sim *Simulation, target *Unit) bool { } // Apply SQW leniency to any pending hardcasts - if spell.Unit.Hardcast.Expires > sim.CurrentTime+MaxSpellQueueWindow { + if (spell.Unit.Hardcast.Expires > sim.CurrentTime+MaxSpellQueueWindow) || (spell.Unit.IsCastingDuringChannel() && !spell.CanCastDuringChannel(sim)) { return false } diff --git a/sim/core/unit.go b/sim/core/unit.go index 2676971bbb..15d2269a3b 100644 --- a/sim/core/unit.go +++ b/sim/core/unit.go @@ -471,6 +471,14 @@ func (unit *Unit) InitialCastSpeed() float64 { return unit.initialCastSpeed } +func (unit *Unit) IsChanneling() bool { + return unit.ChanneledDot != nil +} + +func (unit *Unit) IsCastingDuringChannel() bool { + return unit.IsChanneling() && unit.ChanneledDot.Spell.Flags.Matches(SpellFlagCastWhileChanneling) +} + func (unit *Unit) SpellGCD() time.Duration { return max(GCDMin, unit.ApplyCastSpeed(GCDDefault)) } diff --git a/sim/warrior/arms/TestArms.results b/sim/warrior/arms/TestArms.results index c73b03fbdd..3e8f95cad6 100644 --- a/sim/warrior/arms/TestArms.results +++ b/sim/warrior/arms/TestArms.results @@ -418,8 +418,8 @@ dps_results: { dps_results: { key: "TestArms-Settings-Orc-p1_arms_bis-Basic-arms-FullBuffs-9.0yards-LongMultiTarget" value: { - dps: 815502.44048 - tps: 733565.51284 + dps: 816625.5827 + tps: 734597.01461 } } dps_results: { @@ -439,15 +439,15 @@ dps_results: { dps_results: { key: "TestArms-Settings-Orc-p1_arms_bis-Basic-arms-NoBuffs-9.0yards-LongMultiTarget" value: { - dps: 605318.17578 - tps: 546072.39177 + dps: 608789.67555 + tps: 549770.27992 } } dps_results: { key: "TestArms-Settings-Orc-p1_arms_bis-Basic-arms-NoBuffs-9.0yards-LongSingleTarget" value: { - dps: 115255.20253 - tps: 77660.94882 + dps: 114139.37496 + tps: 77273.53479 } } dps_results: { @@ -481,15 +481,15 @@ dps_results: { dps_results: { key: "TestArms-Settings-Orc-p1_prebis_poor-Basic-arms-NoBuffs-9.0yards-LongMultiTarget" value: { - dps: 451335.74648 - tps: 407629.77861 + dps: 455713.88423 + tps: 411190.19995 } } dps_results: { key: "TestArms-Settings-Orc-p1_prebis_poor-Basic-arms-NoBuffs-9.0yards-LongSingleTarget" value: { - dps: 81467.78038 - tps: 55545.42702 + dps: 80481.95625 + tps: 55218.60156 } } dps_results: { @@ -502,8 +502,8 @@ dps_results: { dps_results: { key: "TestArms-Settings-Orc-p1_prebis_rich-Basic-arms-FullBuffs-9.0yards-LongMultiTarget" value: { - dps: 650217.71719 - tps: 583916.55449 + dps: 649230.41863 + tps: 583010.40765 } } dps_results: { @@ -523,29 +523,29 @@ dps_results: { dps_results: { key: "TestArms-Settings-Orc-p1_prebis_rich-Basic-arms-NoBuffs-9.0yards-LongMultiTarget" value: { - dps: 468785.57275 - tps: 423021.75843 + dps: 470297.39602 + tps: 425026.33379 } } dps_results: { key: "TestArms-Settings-Orc-p1_prebis_rich-Basic-arms-NoBuffs-9.0yards-LongSingleTarget" value: { - dps: 82740.85016 - tps: 56685.44122 + dps: 81614.73537 + tps: 56294.40991 } } dps_results: { key: "TestArms-Settings-Orc-p1_prebis_rich-Basic-arms-NoBuffs-9.0yards-ShortSingleTarget" value: { - dps: 88081.03733 - tps: 56666.25486 + dps: 88313.06686 + tps: 56821.60559 } } dps_results: { key: "TestArms-Settings-Worgen-p1_arms_bis-Basic-arms-FullBuffs-9.0yards-LongMultiTarget" value: { - dps: 806507.52547 - tps: 728088.95638 + dps: 807341.48657 + tps: 728789.72235 } } dps_results: { @@ -565,15 +565,15 @@ dps_results: { dps_results: { key: "TestArms-Settings-Worgen-p1_arms_bis-Basic-arms-NoBuffs-9.0yards-LongMultiTarget" value: { - dps: 597856.93282 - tps: 540271.32116 + dps: 599962.90676 + tps: 542635.74019 } } dps_results: { key: "TestArms-Settings-Worgen-p1_arms_bis-Basic-arms-NoBuffs-9.0yards-LongSingleTarget" value: { - dps: 115269.25831 - tps: 77526.62221 + dps: 114067.0206 + tps: 77151.71549 } } dps_results: { @@ -607,15 +607,15 @@ dps_results: { dps_results: { key: "TestArms-Settings-Worgen-p1_prebis_poor-Basic-arms-NoBuffs-9.0yards-LongMultiTarget" value: { - dps: 444963.21995 - tps: 402679.15845 + dps: 449481.20297 + tps: 406609.42969 } } dps_results: { key: "TestArms-Settings-Worgen-p1_prebis_poor-Basic-arms-NoBuffs-9.0yards-LongSingleTarget" value: { - dps: 80707.9687 - tps: 55072.9703 + dps: 79729.00925 + tps: 54758.34887 } } dps_results: { @@ -628,8 +628,8 @@ dps_results: { dps_results: { key: "TestArms-Settings-Worgen-p1_prebis_rich-Basic-arms-FullBuffs-9.0yards-LongMultiTarget" value: { - dps: 641392.48667 - tps: 577705.4991 + dps: 641301.63061 + tps: 577309.73844 } } dps_results: { @@ -649,22 +649,22 @@ dps_results: { dps_results: { key: "TestArms-Settings-Worgen-p1_prebis_rich-Basic-arms-NoBuffs-9.0yards-LongMultiTarget" value: { - dps: 464060.34972 - tps: 419973.38632 + dps: 465700.56971 + tps: 421639.47444 } } dps_results: { key: "TestArms-Settings-Worgen-p1_prebis_rich-Basic-arms-NoBuffs-9.0yards-LongSingleTarget" value: { - dps: 82435.3786 - tps: 56563.67852 + dps: 81379.2926 + tps: 56196.92275 } } dps_results: { key: "TestArms-Settings-Worgen-p1_prebis_rich-Basic-arms-NoBuffs-9.0yards-ShortSingleTarget" value: { - dps: 86794.76911 - tps: 56243.55992 + dps: 86530.29456 + tps: 56073.08963 } } dps_results: { diff --git a/sim/warrior/fury/TestFury.results b/sim/warrior/fury/TestFury.results index 977e998388..6f6e362790 100644 --- a/sim/warrior/fury/TestFury.results +++ b/sim/warrior/fury/TestFury.results @@ -33,435 +33,435 @@ character_stats_results: { dps_results: { key: "TestFury-AllItems-AgilePrimalDiamond" value: { - dps: 145988.6081 - tps: 91728.63943 + dps: 144523.56145 + tps: 91254.09093 } } dps_results: { key: "TestFury-AllItems-AssuranceofConsequence-105472" value: { - dps: 143479.44595 - tps: 90220.60399 + dps: 142001.48519 + tps: 89743.62451 } } dps_results: { key: "TestFury-AllItems-AusterePrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-BattleplateofResoundingRings" value: { - dps: 127473.91523 - tps: 82722.76224 + dps: 127800.47557 + tps: 82544.33692 } } dps_results: { key: "TestFury-AllItems-BattleplateoftheLastMogu" value: { - dps: 142425.11745 - tps: 90723.88518 + dps: 143133.41494 + tps: 90579.78156 } } dps_results: { key: "TestFury-AllItems-BattleplateofthePrehistoricMarauder" value: { - dps: 137591.25098 - tps: 88180.11389 + dps: 137240.84017 + tps: 87755.35712 } } dps_results: { key: "TestFury-AllItems-BurningPrimalDiamond" value: { - dps: 145979.34783 - tps: 91722.22868 + dps: 144514.30118 + tps: 91247.68017 } } dps_results: { key: "TestFury-AllItems-CapacitivePrimalDiamond" value: { - dps: 143851.95513 - tps: 90422.10303 + dps: 143152.114 + tps: 90171.86305 } } dps_results: { key: "TestFury-AllItems-CourageousPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-DelicateVialoftheSanguinaire-96895" value: { - dps: 143353.94765 - tps: 90151.14277 + dps: 141917.01509 + tps: 89682.89726 } } dps_results: { key: "TestFury-AllItems-DestructivePrimalDiamond" value: { - dps: 143882.90667 - tps: 90372.61297 + dps: 143507.6862 + tps: 90072.55568 } } dps_results: { key: "TestFury-AllItems-EffulgentPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-EmberPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-EnchantWeapon-BloodyDancingSteel-5125" value: { - dps: 146818.07494 - tps: 92195.03245 + dps: 145217.13552 + tps: 91685.96547 } } dps_results: { key: "TestFury-AllItems-EnchantWeapon-Colossus-4445" value: { - dps: 143975.03922 - tps: 90433.46688 + dps: 142474.83406 + tps: 89962.50856 } } dps_results: { key: "TestFury-AllItems-EnchantWeapon-JadeSpirit-4442" value: { - dps: 143977.88879 - tps: 90433.46688 + dps: 142474.83406 + tps: 89962.50856 } } dps_results: { key: "TestFury-AllItems-EnchantWeapon-River'sSong-4446" value: { - dps: 143978.15814 - tps: 90433.46688 + dps: 142477.72977 + tps: 89962.50856 } } dps_results: { key: "TestFury-AllItems-EnchantWeapon-SpiritofConquest-5124" value: { - dps: 143975.03922 - tps: 90433.46688 + dps: 142474.83406 + tps: 89962.50856 } } dps_results: { key: "TestFury-AllItems-EnchantWeapon-Windsong-4441" value: { - dps: 147236.95403 - tps: 92958.64424 + dps: 146811.62036 + tps: 92284.99432 } } dps_results: { key: "TestFury-AllItems-EnigmaticPrimalDiamond" value: { - dps: 143882.90667 - tps: 90372.61297 + dps: 143507.6862 + tps: 90072.55568 } } dps_results: { key: "TestFury-AllItems-EternalPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-EvilEyeofGalakras-105491" value: { - dps: 161051.6319 - tps: 106495.61884 + dps: 160721.29526 + tps: 105936.05266 } } dps_results: { key: "TestFury-AllItems-FabledFeatherofJi-Kun-96842" value: { - dps: 144331.44318 - tps: 91797.58839 + dps: 145091.89514 + tps: 91896.39471 } } dps_results: { key: "TestFury-AllItems-Fen-Yu,FuryofXuen-102248" value: { - dps: 150729.2399 - tps: 96488.46066 + dps: 151039.16023 + tps: 97223.55044 } } dps_results: { key: "TestFury-AllItems-FleetPrimalDiamond" value: { - dps: 144608.19008 - tps: 90804.83792 + dps: 143164.78572 + tps: 90337.87926 } } dps_results: { key: "TestFury-AllItems-ForlornPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-GazeoftheTwins-96915" value: { - dps: 154492.84748 - tps: 96610.57823 + dps: 153413.49873 + tps: 95815.88116 } } dps_results: { key: "TestFury-AllItems-Gong-Lu,StrengthofXuen-102249" value: { - dps: 158692.41395 - tps: 102448.33382 + dps: 159254.40077 + tps: 102783.36693 } } dps_results: { key: "TestFury-AllItems-Horridon'sLastGasp-96757" value: { - dps: 143353.94765 - tps: 90151.14277 + dps: 141917.01509 + tps: 89682.89726 } } dps_results: { key: "TestFury-AllItems-ImpassivePrimalDiamond" value: { - dps: 143882.90667 - tps: 90372.61297 + dps: 143507.6862 + tps: 90072.55568 } } dps_results: { key: "TestFury-AllItems-IndomitablePrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-InscribedBagofHydra-Spawn-96828" value: { - dps: 143353.94765 - tps: 90151.14277 + dps: 141917.01509 + tps: 89682.89726 } } dps_results: { key: "TestFury-AllItems-Ji-Kun'sRisingWinds-96843" value: { - dps: 143353.94765 - tps: 90151.14277 + dps: 141917.01509 + tps: 89682.89726 } } dps_results: { key: "TestFury-AllItems-PhaseFingers-4697" value: { - dps: 146145.08481 - tps: 91819.89078 + dps: 144675.75409 + tps: 91344.95046 } } dps_results: { key: "TestFury-AllItems-PlateofResoundingRings" value: { - dps: 110936.60546 - tps: 72314.29655 + dps: 110315.22141 + tps: 71954.12574 } } dps_results: { key: "TestFury-AllItems-PlateoftheLastMogu" value: { - dps: 118835.25796 - tps: 76846.72829 + dps: 120493.44842 + tps: 77276.25507 } } dps_results: { key: "TestFury-AllItems-PlateofthePrehistoricMarauder" value: { - dps: 125377.26125 - tps: 80621.23417 + dps: 125550.21205 + tps: 80483.29321 } } dps_results: { key: "TestFury-AllItems-PowerfulPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-PriceofProgress-81266" value: { - dps: 143353.94765 - tps: 90151.14277 + dps: 141917.01509 + tps: 89682.89726 } } dps_results: { key: "TestFury-AllItems-Primordius'TalismanofRage-96873" value: { - dps: 154354.22256 - tps: 97344.86223 + dps: 153284.98586 + tps: 96485.20039 } } dps_results: { key: "TestFury-AllItems-Qian-Le,CourageofNiuzao-102245" value: { - dps: 146690.04809 - tps: 92457.31035 + dps: 147055.41919 + tps: 92102.88523 } } dps_results: { key: "TestFury-AllItems-Qian-Ying,FortitudeofNiuzao-102250" value: { - dps: 148441.91496 - tps: 94084.70983 + dps: 148767.77272 + tps: 93819.45515 } } dps_results: { key: "TestFury-AllItems-Renataki'sSoulCharm-96741" value: { - dps: 143392.66547 - tps: 90254.32411 + dps: 142372.88758 + tps: 89895.60241 } } dps_results: { key: "TestFury-AllItems-ReverberatingPrimalDiamond" value: { - dps: 146745.68086 - tps: 92180.81592 + dps: 145272.42793 + tps: 91704.42761 } } dps_results: { key: "TestFury-AllItems-RevitalizingPrimalDiamond" value: { - dps: 145979.34783 - tps: 91722.22868 + dps: 144514.30118 + tps: 91247.68017 } } dps_results: { key: "TestFury-AllItems-SinisterPrimalDiamond" value: { - dps: 143851.95513 - tps: 90422.10303 + dps: 143152.114 + tps: 90171.86305 } } dps_results: { key: "TestFury-AllItems-SynapseSprings(MarkII)-4898" value: { - dps: 147713.09191 - tps: 92863.32368 + dps: 146242.80287 + tps: 92380.92044 } } dps_results: { key: "TestFury-AllItems-TalismanofBloodlust-96864" value: { - dps: 145383.71123 - tps: 92394.90503 + dps: 144961.33246 + tps: 92169.93889 } } dps_results: { key: "TestFury-AllItems-TheGloamingBlade-88149" value: { - dps: 146745.68086 - tps: 92180.81592 + dps: 145272.42793 + tps: 91704.42761 } } dps_results: { key: "TestFury-AllItems-TyrannicalPrimalDiamond" value: { - dps: 143554.55736 - tps: 90141.41819 + dps: 142127.74313 + tps: 89684.10099 } } dps_results: { key: "TestFury-AllItems-UnerringVisionofLeiShen-96930" value: { - dps: 146478.43303 - tps: 91895.18986 + dps: 145898.73096 + tps: 91860.09198 } } dps_results: { key: "TestFury-AllItems-Wushoolay'sFinalChoice-96785" value: { - dps: 144331.44318 - tps: 91797.58839 + dps: 145091.89514 + tps: 91896.39471 } } dps_results: { key: "TestFury-AllItems-Xing-Ho,BreathofYu'lon-102246" value: { - dps: 146033.94681 - tps: 92667.1873 + dps: 144979.42692 + tps: 92079.26348 } } dps_results: { key: "TestFury-AllItems-YaungolFireCarrier-86518" value: { - dps: 146745.68086 - tps: 92180.81592 + dps: 145272.42793 + tps: 91704.42761 } } dps_results: { key: "TestFury-AllItems-ZenAlchemistStone-75274" value: { - dps: 150227.65868 - tps: 94459.99913 + dps: 148698.51037 + tps: 93934.55213 } } dps_results: { key: "TestFury-Average-Default" value: { - dps: 147015.09971 - tps: 93108.93279 + dps: 147226.10047 + tps: 93068.38295 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_smf-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongMultiTarget" value: { - dps: 350987.02674 - tps: 237784.74311 + dps: 360447.70797 + tps: 237775.35649 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_smf-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongSingleTarget" value: { - dps: 141403.57105 - tps: 90038.82427 + dps: 141809.78885 + tps: 89884.46243 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_smf-DefaultTalents-Basic-default-FullBuffs-5.0yards-ShortSingleTarget" value: { - dps: 173402.73496 - tps: 111457.92763 + dps: 173470.52872 + tps: 111476.73865 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_smf-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongMultiTarget" value: { - dps: 275188.24801 - tps: 181586.51185 + dps: 272847.26341 + tps: 180435.3895 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_smf-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongSingleTarget" value: { - dps: 101806.50928 - tps: 65870.4992 + dps: 102380.85456 + tps: 65994.76941 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_smf-DefaultTalents-Basic-default-NoBuffs-5.0yards-ShortSingleTarget" value: { - dps: 111450.37916 - tps: 72286.11254 + dps: 111478.91349 + tps: 72238.78716 } } dps_results: { @@ -509,43 +509,43 @@ dps_results: { dps_results: { key: "TestFury-Settings-Troll-p1_fury_tg-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongMultiTarget" value: { - dps: 384006.076 - tps: 250778.94091 + dps: 385817.78455 + tps: 253319.20764 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_tg-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongSingleTarget" value: { - dps: 148316.23278 - tps: 93224.24882 + dps: 146839.47671 + tps: 92740.39759 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_tg-DefaultTalents-Basic-default-FullBuffs-5.0yards-ShortSingleTarget" value: { - dps: 181903.7254 + dps: 181930.03688 tps: 114784.42862 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_tg-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongMultiTarget" value: { - dps: 303861.55885 - tps: 193508.3041 + dps: 308440.67266 + tps: 192102.93771 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_tg-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongSingleTarget" value: { - dps: 108905.31915 - tps: 69991.57864 + dps: 110396.08865 + tps: 70348.63359 } } dps_results: { key: "TestFury-Settings-Troll-p1_fury_tg-DefaultTalents-Basic-default-NoBuffs-5.0yards-ShortSingleTarget" value: { - dps: 120868.9604 - tps: 75902.49981 + dps: 120707.44708 + tps: 75785.99554 } } dps_results: { @@ -593,43 +593,43 @@ dps_results: { dps_results: { key: "TestFury-Settings-Worgen-p1_fury_smf-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongMultiTarget" value: { - dps: 345159.63105 - tps: 237357.03329 + dps: 353200.8128 + tps: 235841.86851 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_smf-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongSingleTarget" value: { - dps: 142454.11267 - tps: 90394.33276 + dps: 143242.23401 + tps: 90416.81651 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_smf-DefaultTalents-Basic-default-FullBuffs-5.0yards-ShortSingleTarget" value: { - dps: 175139.81723 - tps: 108946.36557 + dps: 175236.45776 + tps: 108957.80055 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_smf-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongMultiTarget" value: { - dps: 277350.18614 - tps: 179016.06224 + dps: 276016.45949 + tps: 179979.58562 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_smf-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongSingleTarget" value: { - dps: 102254.98128 - tps: 66480.85253 + dps: 102384.47546 + tps: 66342.20824 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_smf-DefaultTalents-Basic-default-NoBuffs-5.0yards-ShortSingleTarget" value: { - dps: 112491.23935 - tps: 71131.76952 + dps: 112391.62413 + tps: 71129.15873 } } dps_results: { @@ -677,43 +677,43 @@ dps_results: { dps_results: { key: "TestFury-Settings-Worgen-p1_fury_tg-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongMultiTarget" value: { - dps: 394826.77542 - tps: 254229.77458 + dps: 383080.35543 + tps: 254913.47009 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_tg-DefaultTalents-Basic-default-FullBuffs-5.0yards-LongSingleTarget" value: { - dps: 147796.30324 - tps: 92502.94346 + dps: 147434.22171 + tps: 92357.44327 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_tg-DefaultTalents-Basic-default-FullBuffs-5.0yards-ShortSingleTarget" value: { - dps: 177652.01043 - tps: 111769.03997 + dps: 177704.05075 + tps: 111779.17072 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_tg-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongMultiTarget" value: { - dps: 309277.13009 - tps: 192427.08856 + dps: 310812.2585 + tps: 192988.793 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_tg-DefaultTalents-Basic-default-NoBuffs-5.0yards-LongSingleTarget" value: { - dps: 110967.11793 - tps: 70320.12493 + dps: 109347.60169 + tps: 69616.6659 } } dps_results: { key: "TestFury-Settings-Worgen-p1_fury_tg-DefaultTalents-Basic-default-NoBuffs-5.0yards-ShortSingleTarget" value: { - dps: 120040.1344 - tps: 74696.80061 + dps: 120094.78169 + tps: 74601.8632 } } dps_results: { @@ -761,7 +761,7 @@ dps_results: { dps_results: { key: "TestFury-SwitchInFrontOfTarget-Default" value: { - dps: 132862.32859 - tps: 85253.37061 + dps: 133221.37864 + tps: 84981.29344 } } diff --git a/sim/warrior/talents.go b/sim/warrior/talents.go index 4ca8e31ef4..0f5d2d9a83 100644 --- a/sim/warrior/talents.go +++ b/sim/warrior/talents.go @@ -188,11 +188,16 @@ func (war *Warrior) registerBladestorm() { }, }) + channelMod := war.AddDynamicMod(core.SpellModConfig{ + ClassMask: SpellMaskBattleShout | SpellMaskCommandingShout | SpellMaskRallyingCry | SpellMaskLastStand | SpellMaskDemoralizingShout | SpellMaskBerserkerRage, + Kind: core.SpellMod_AllowCastWhileChanneling, + }) + spell := war.RegisterSpell(core.SpellConfig{ ActionID: actionID.WithTag(0), SpellSchool: core.SpellSchoolPhysical, ClassSpellMask: SpellMaskBladestorm, - Flags: core.SpellFlagChanneled | core.SpellFlagMeleeMetrics | core.SpellFlagAPL, + Flags: core.SpellFlagChanneled | core.SpellFlagMeleeMetrics | core.SpellFlagAPL | core.SpellFlagCastWhileChanneling, ProcMask: core.ProcMaskEmpty, Cast: core.CastConfig{ @@ -212,6 +217,12 @@ func (war *Warrior) registerBladestorm() { IsAOE: true, Aura: core.Aura{ Label: "Bladestorm", + OnGain: func(aura *core.Aura, sim *core.Simulation) { + channelMod.Activate() + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + channelMod.Deactivate() + }, }, NumberOfTicks: 6, TickLength: time.Second * 1, diff --git a/ui/warrior/arms/apls/arms.apl.json b/ui/warrior/arms/apls/arms.apl.json index 14e3e3deb8..1325d99456 100644 --- a/ui/warrior/arms/apls/arms.apl.json +++ b/ui/warrior/arms/apls/arms.apl.json @@ -1,16 +1,16 @@ { "type": "TypeAPL", "prepullActions": [ + {"action":{"castSpell":{"spellId":{"spellId":6673}}},"doAtValue":{"const":{"val":"-60s"}}}, {"action":{"castSpell":{"spellId":{"spellId":2457}}},"doAtValue":{"const":{"val":"-5s"}}}, - {"action":{"castSpell":{"spellId":{"spellId":6673}}},"doAtValue":{"const":{"val":"-3.2s"}}}, {"action":{"castSpell":{"spellId":{"otherId":"OtherActionPotion"}}},"doAtValue":{"const":{"val":"-1.7s"}}}, {"action":{"castSpell":{"spellId":{"spellId":1249459}}},"doAtValue":{"const":{"val":"-1.7s"}}}, {"action":{"castSpell":{"spellId":{"spellId":1250619}}},"doAtValue":{"const":{"val":"-.5s"}}} ], "priorityList": [ {"action":{"autocastOtherCooldowns":{}}}, - {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLe","lhs":{"currentRage":{}},"rhs":{"math":{"op":"OpSub","lhs":{"maxRage":{}},"rhs":{"const":{"val":"35"}}}}}},{"cmp":{"op":"OpGe","lhs":{"autoTimeToNext":{}},"rhs":{"const":{"val":"1.5s"}}}},{"spellIsReady":{"spellId":{"spellId":1250619}}}]}},"move":{"rangeFromTarget":{"const":{"val":"6"}}}}}, - {"action":{"condition":{"cmp":{"op":"OpGe","lhs":{"unitDistance":{"sourceUnit":{"type":"CurrentTarget"}}},"rhs":{"const":{"val":"5"}}}},"castSpell":{"spellId":{"spellId":1250619}}}}, + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLe","lhs":{"currentRage":{}},"rhs":{"math":{"op":"OpSub","lhs":{"maxRage":{}},"rhs":{"const":{"val":"35"}}}}}},{"cmp":{"op":"OpGe","lhs":{"autoTimeToNext":{}},"rhs":{"const":{"val":"1.5s"}}}},{"spellIsReady":{"spellId":{"spellId":1250619}}}]}},"move":{"rangeFromTarget":{"const":{"val":"6"}}}}}, + {"action":{"condition":{"cmp":{"op":"OpGe","lhs":{"unitDistance":{"sourceUnit":{"type":"CurrentTarget"}}},"rhs":{"const":{"val":"5"}}}},"castSpell":{"spellId":{"spellId":1250619}}}}, {"action":{"condition":{"or":{"vals":[{"and":{"vals":[{"isExecutePhase":{"threshold":"E20"}},{"or":{"vals":[{"and":{"vals":[{"anyTrinketStatProcsActive":{"statType2":6,"statType3":-1,"minIcdSeconds":54}},{"cmp":{"op":"OpGe","lhs":{"trinketProcsMinRemainingTime":{"statType2":6,"statType3":-1,"minIcdSeconds":54}},"rhs":{"const":{"val":"10s"}}}}]}},{"cmp":{"op":"OpEq","lhs":{"numEquippedStatProcTrinkets":{"statType2":6,"statType3":-1,"minIcdSeconds":54}},"rhs":{"const":{"val":"0"}}}}]}},{"or":{"vals":[{"cmp":{"op":"OpLe","lhs":{"numStatBuffCooldowns":{"statType2":-1,"statType3":-1}},"rhs":{"const":{"val":"1"}}}},{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"trinketProcsMaxRemainingIcd":{"statType2":6,"statType3":-1,"minIcdSeconds":54}},"rhs":{"math":{"op":"OpSub","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"25s"}}}}}},{"spellIsReady":{"spellId":{"itemId":81268}}}]}}]}},{"spellIsReady":{"spellId":{"spellId":1719}}},{"spellIsReady":{"spellId":{"spellId":12292}}}]}},{"cmp":{"op":"OpLe","lhs":{"remainingTime":{}},"rhs":{"math":{"op":"OpAdd","lhs":{"gcdTimeToReady":{}},"rhs":{"const":{"val":"25s"}}}}}}]}},"castSpell":{"spellId":{"otherId":"OtherActionPotion"}}}}, {"action":{"condition":{"or":{"vals":[{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"125s"}}}},{"and":{"vals":[{"isExecutePhase":{"threshold":"E20"}},{"auraIsActive":{"auraId":{"itemId":76095}}}]}},{"cmp":{"op":"OpLe","lhs":{"remainingTime":{}},"rhs":{"math":{"op":"OpAdd","lhs":{"gcdTimeToReady":{}},"rhs":{"const":{"val":"15s"}}}}}}]}},"castSpell":{"spellId":{"spellId":33697}}}}, {"action":{"condition":{"cmp":{"op":"OpLe","lhs":{"currentTime":{}},"rhs":{"const":{"val":"1s"}}}},"castSpell":{"spellId":{"spellId":1719}}}}, @@ -38,8 +38,8 @@ {"action":{"condition":{"or":{"vals":[{"and":{"vals":[{"cmp":{"op":"OpGe","lhs":{"currentRage":{}},"rhs":{"const":{"val":"110"}}}},{"auraIsInactiveWithReactionTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":86346}}},{"not":{"val":{"isExecutePhase":{"threshold":"E20"}}}}]}}]}},"castSpell":{"spellId":{"spellId":1464}}}}, {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpEq","lhs":{"numberTargets":{}},"rhs":{"const":{"val":"1"}}}},{"not":{"val":{"and":{"vals":[{"auraIsActive":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":86346}}},{"isExecutePhase":{"threshold":"E20"}},{"cmp":{"op":"OpGe","lhs":{"currentRage":{}},"rhs":{"const":{"val":"30"}}}}]}}}},{"not":{"val":{"spellIsReady":{"spellId":{"spellId":1250619}}}}}]}},"channelSpell":{"spellId":{"spellId":46924},"interruptIf":{"spellIsReady":{"spellId":{"spellId":12294}}}}}}, {"action":{"condition":{"auraIsActive":{"auraId":{"spellId":60503}}},"castSpell":{"spellId":{"spellId":7384}}}}, + {"action":{"condition":{"and":{"vals":[{"spellIsKnown":{"spellId":{"spellId":46924}}},{"spellIsChanneling":{"spellId":{"spellId":46924}}},{"cmp":{"op":"OpGe","lhs":{"dotRemainingTime":{"spellId":{"spellId":46924}}},"rhs":{"gcdTimeToReady":{}}}}]}},"castSpell":{"spellId":{"spellId":6673}}}}, {"action":{"condition":{"and":{"vals":[{"not":{"val":{"spellCanCast":{"spellId":{"spellId":1250619}}}}},{"not":{"val":{"unitIsMoving":{}}}}]}},"channelSpell":{"spellId":{"spellId":46924},"interruptIf":{"cmp":{"op":"OpEq","lhs":{"spellChanneledTicks":{"spellId":{"spellId":46924}}},"rhs":{"const":{"val":"4"}}}}}}}, - {"action":{"condition":{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":46924}}},{"spellIsKnown":{"spellId":{"spellId":46924}}}]}},"castSpell":{"spellId":{"spellId":6673}}}}, {"action":{"condition":{"cmp":{"op":"OpLt","lhs":{"currentRage":{}},"rhs":{"const":{"val":"10"}}}},"castSpell":{"spellId":{"spellId":6673}}}}, {"action":{"condition":{"or":{"vals":[{"cmp":{"op":"OpGe","lhs":{"currentRage":{}},"rhs":{"const":{"val":"100"}}}},{"and":{"vals":[{"cmp":{"op":"OpLt","lhs":{"spellTimeToReady":{"spellId":{"spellId":1250619}}},"rhs":{"const":{"val":"1.5s"}}}},{"cmp":{"op":"OpGt","lhs":{"currentRage":{}},"rhs":{"math":{"op":"OpSub","lhs":{"maxRage":{}},"rhs":{"const":{"val":"35"}}}}}}]}}]}},"castSpell":{"spellId":{"spellId":78}}}} ]