From 1134f147dba43361755cfff4bdb82299c15e2baf Mon Sep 17 00:00:00 2001 From: rosenrusinov Date: Sun, 26 Feb 2023 13:00:54 +0100 Subject: [PATCH 1/3] add blood boil and blood strike to drw --- proto/deathknight.proto | 10 ++ sim/deathknight/blood_boil.go | 23 +++++ sim/deathknight/blood_strike.go | 32 +++++++ sim/deathknight/dancing_rune_weapon.go | 8 ++ sim/deathknight/deathknight.go | 4 + sim/deathknight/dps/dps_deathknight_test.go | 2 + sim/deathknight/dps/rotation_blood.go | 98 +++++++++++--------- sim/deathknight/dps/rotation_blood_helper.go | 5 + sim/deathknight/icy_touch.go | 2 +- sim/deathknight/pestilence.go | 1 + sim/deathknight/plague_strike.go | 2 +- ui/deathknight/inputs.ts | 28 +++++- ui/deathknight/presets.ts | 5 + 13 files changed, 174 insertions(+), 46 deletions(-) diff --git a/proto/deathknight.proto b/proto/deathknight.proto index 7de57b0d79..1a527b6e2a 100644 --- a/proto/deathknight.proto +++ b/proto/deathknight.proto @@ -195,6 +195,12 @@ message Deathknight { Experimental_1 = 1; Experimental_2 = 2; } + + enum BloodSpell { + HS = 0; + BB = 1; + BS = 2; + } enum CustomSpellOption { CustomNoSpell = 0; @@ -259,6 +265,10 @@ message Deathknight { bool enable_weapon_swap = 28; ItemSwap weapon_swap = 29; + + bool use_dancing_rune_weapon = 30; + + BloodSpell blood_spender = 31; } Rotation rotation = 1; diff --git a/sim/deathknight/blood_boil.go b/sim/deathknight/blood_boil.go index 8f8bd74d00..8917d3b14c 100644 --- a/sim/deathknight/blood_boil.go +++ b/sim/deathknight/blood_boil.go @@ -46,3 +46,26 @@ func (dk *Deathknight) registerBloodBoilSpell() { }, }) } + +func (dk *Deathknight) registerDrwBloodBoilSpell() { + dk.RuneWeapon.BloodBoil = dk.RuneWeapon.RegisterSpell(core.SpellConfig{ + ActionID: BloodBoilActionID, + SpellSchool: core.SpellSchoolShadow, + ProcMask: core.ProcMaskSpellDamage, + + DamageMultiplier: dk.bloodyStrikesBonus(dk.BloodBoil), + CritMultiplier: dk.bonusCritMultiplier(dk.Talents.MightOfMograine), + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + for _, aoeTarget := range sim.Encounter.Targets { + aoeUnit := &aoeTarget.Unit + + baseDamage := (sim.Roll(180, 220) + 0.06*dk.RuneWeapon.getImpurityBonus(spell)) * core.TernaryFloat64(dk.DrwDiseasesAreActive(aoeUnit), 1.5, 1.0) + baseDamage *= sim.Encounter.AOECapMultiplier() + + spell.CalcAndDealDamage(sim, aoeUnit, baseDamage, spell.OutcomeMagicHitAndCrit) + } + }, + }) +} diff --git a/sim/deathknight/blood_strike.go b/sim/deathknight/blood_strike.go index aa8c74f02a..26fccf58c4 100644 --- a/sim/deathknight/blood_strike.go +++ b/sim/deathknight/blood_strike.go @@ -86,3 +86,35 @@ func (dk *Deathknight) registerBloodStrikeSpell() { dk.BloodStrikeOhHit = dk.newBloodStrikeSpell(false) dk.BloodStrike = dk.BloodStrikeMhHit } + +func (dk *Deathknight) registerDrwBloodStrikeSpell() { + bonusBaseDamage := dk.sigilOfTheDarkRiderBonus() + diseaseMulti := dk.dkDiseaseMultiplier(0.125) + + dk.RuneWeapon.BloodStrike = dk.RuneWeapon.RegisterSpell(core.SpellConfig{ + ActionID: BloodStrikeActionID.WithTag(1), + SpellSchool: core.SpellSchoolPhysical, + ProcMask: core.ProcMaskMeleeSpecial, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagIgnoreAttackerModifiers, + + BonusCritRating: (dk.subversionCritBonus() + dk.annihilationCritBonus()) * core.CritRatingPerCritChance, + DamageMultiplier: .5 * 0.4 * + dk.bloodOfTheNorthCoeff() * + dk.thassariansPlateDamageBonus() * + dk.bloodyStrikesBonus(dk.BloodStrike), + CritMultiplier: dk.bonusCritMultiplier(dk.Talents.MightOfMograine + dk.Talents.GuileOfGorefiend), + ThreatMultiplier: 1, + + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + baseDamage := 764 + + bonusBaseDamage + + spell.Unit.MHNormalizedWeaponDamage(sim, spell.MeleeAttackPower()) + + spell.BonusWeaponDamage() + + baseDamage *= dk.RoRTSBonus(target) * + (1.0 + dk.drwCountActiveDiseases(target)*diseaseMulti) + + spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit) + }, + }) +} diff --git a/sim/deathknight/dancing_rune_weapon.go b/sim/deathknight/dancing_rune_weapon.go index 3c2d2c086d..3fada25661 100644 --- a/sim/deathknight/dancing_rune_weapon.go +++ b/sim/deathknight/dancing_rune_weapon.go @@ -31,12 +31,16 @@ func (dk *Deathknight) registerDancingRuneWeaponCD() { dk.RuneWeapon.PlagueStrike.Cast(sim, spell.Unit.CurrentTarget) case dk.DeathStrike: dk.RuneWeapon.DeathStrike.Cast(sim, spell.Unit.CurrentTarget) + case dk.BloodStrike: + dk.RuneWeapon.BloodStrike.Cast(sim, spell.Unit.CurrentTarget) case dk.HeartStrike: dk.RuneWeapon.HeartStrike.Cast(sim, spell.Unit.CurrentTarget) case dk.DeathCoil: dk.RuneWeapon.DeathCoil.Cast(sim, spell.Unit.CurrentTarget) case dk.Pestilence: dk.RuneWeapon.Pestilence.Cast(sim, spell.Unit.CurrentTarget) + case dk.BloodBoil: + dk.RuneWeapon.BloodBoil.Cast(sim, spell.Unit.CurrentTarget) } }, }) @@ -85,10 +89,12 @@ type RuneWeaponPet struct { DeathStrike *core.Spell DeathCoil *core.Spell + BloodStrike *core.Spell HeartStrike *core.Spell HeartStrikeOffHit *core.Spell Pestilence *core.Spell + BloodBoil *core.Spell // Diseases FrostFeverSpell *core.Spell @@ -98,10 +104,12 @@ type RuneWeaponPet struct { func (runeWeapon *RuneWeaponPet) Initialize() { runeWeapon.dkOwner.registerDrwDiseaseDots() runeWeapon.dkOwner.registerDrwPestilenceSpell() + runeWeapon.dkOwner.registerDrwBloodBoilSpell() runeWeapon.dkOwner.registerDrwIcyTouchSpell() runeWeapon.dkOwner.registerDrwPlagueStrikeSpell() runeWeapon.dkOwner.registerDrwDeathStrikeSpell() + runeWeapon.dkOwner.registerDrwBloodStrikeSpell() runeWeapon.dkOwner.registerDrwHeartStrikeSpell() runeWeapon.dkOwner.registerDrwDeathCoilSpell() } diff --git a/sim/deathknight/deathknight.go b/sim/deathknight/deathknight.go index 60f96affff..fdbe4cd590 100644 --- a/sim/deathknight/deathknight.go +++ b/sim/deathknight/deathknight.go @@ -471,6 +471,10 @@ func (dk *Deathknight) DiseasesAreActive(target *core.Unit) bool { return dk.FrostFeverSpell.Dot(target).IsActive() || dk.BloodPlagueSpell.Dot(target).IsActive() } +func (dk *Deathknight) DrwDiseasesAreActive(target *core.Unit) bool { + return dk.Talents.DancingRuneWeapon && dk.RuneWeapon.FrostFeverSpell.Dot(target).IsActive() || dk.RuneWeapon.BloodPlagueSpell.Dot(target).IsActive() +} + func (dk *Deathknight) bonusCritMultiplier(bonusTalentPoints int32) float64 { return dk.MeleeCritMultiplier(1, 0.15*float64(bonusTalentPoints)) } diff --git a/sim/deathknight/dps/dps_deathknight_test.go b/sim/deathknight/dps/dps_deathknight_test.go index cad6cf92ca..c0bc09f81b 100644 --- a/sim/deathknight/dps/dps_deathknight_test.go +++ b/sim/deathknight/dps/dps_deathknight_test.go @@ -134,6 +134,8 @@ var bloodRotation = &proto.Deathknight_Rotation{ DrwDiseases: proto.Deathknight_Rotation_Pestilence, UseEmpowerRuneWeapon: true, PreNerfedGargoyle: false, + UseDancingRuneWeapon: true, + BloodSpender: proto.Deathknight_Rotation_HS, } var unholyRotation = &proto.Deathknight_Rotation{ diff --git a/sim/deathknight/dps/rotation_blood.go b/sim/deathknight/dps/rotation_blood.go index fdf785cee9..1e225ba53d 100644 --- a/sim/deathknight/dps/rotation_blood.go +++ b/sim/deathknight/dps/rotation_blood.go @@ -14,55 +14,66 @@ func (dk *DpsDeathknight) setupBloodRotations() { dk.Inputs.FuStrike = deathknight.FuStrike_Obliterate } - if dk.Talents.DancingRuneWeapon { + switch dk.Rotation.BloodSpender { + case proto.Deathknight_Rotation_HS: + dk.br.bloodSpell = dk.HeartStrike + if !dk.Talents.HeartStrike { + dk.br.bloodSpell = dk.BloodStrike + } + case proto.Deathknight_Rotation_BB: + dk.br.bloodSpell = dk.BloodBoil + case proto.Deathknight_Rotation_BS: + dk.br.bloodSpell = dk.BloodStrike + } + + if dk.Rotation.UseDancingRuneWeapon && dk.Talents.DancingRuneWeapon { dk.setupDrwCooldowns() } - //if dk.Inputs.BloodOpener == proto.Deathknight_Rotation_Standard { dk.RotationSequence.Clear(). NewAction(dk.RotationActionCallback_IT). NewAction(dk.RotationActionCallback_PS). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_FU). - NewAction(dk.RotationActionCallback_HS). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_FU). + NewAction(dk.RotationActionBL_BS). NewAction(dk.RotationActionCallback_ERW). NewAction(dk.RotationActionCallback_RD). - NewAction(dk.RotationActionCallback_DRW_Custom) + NewAction(dk.RotationActionBL_DRW_Custom) - if dk.sr.hasGod && dk.Rotation.DrwDiseases == proto.Deathknight_Rotation_Pestilence { + if dk.Rotation.UseDancingRuneWeapon && dk.sr.hasGod && dk.Rotation.DrwDiseases == proto.Deathknight_Rotation_Pestilence { dk.RotationSequence. NewAction(dk.RotationActionCallback_Pesti). NewAction(dk.RotationActionCallback_BT). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_FU). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS) - } else if dk.Rotation.DrwDiseases == proto.Deathknight_Rotation_Normal { + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_FU). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS) + } else if dk.Rotation.UseDancingRuneWeapon && dk.Rotation.DrwDiseases == proto.Deathknight_Rotation_Normal { dk.RotationSequence. NewAction(dk.RotationActionCallback_IT). NewAction(dk.RotationActionCallback_PS). - NewAction(dk.RotationActionCallback_HS). + NewAction(dk.RotationActionBL_BS). NewAction(dk.RotationActionCallback_BT). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS) + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS) } else { dk.RotationSequence. - NewAction(dk.RotationActionCallback_HS). + NewAction(dk.RotationActionBL_BS). NewAction(dk.RotationActionCallback_BT). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_FU). - NewAction(dk.RotationActionCallback_HS). - NewAction(dk.RotationActionCallback_HS) + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_FU). + NewAction(dk.RotationActionBL_BS). + NewAction(dk.RotationActionBL_BS) } - dk.RotationSequence.NewAction(dk.RotationActionCallback_BloodRotation) + dk.RotationSequence.NewAction(dk.RotationActionBL_BloodRotation) } -func (dk *DpsDeathknight) RotationActionCallback_BloodRotation(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { +func (dk *DpsDeathknight) RotationActionBL_BloodRotation(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { casted := false if !dk.blDiseaseCheck(sim, target, dk.RaiseDead, true, 1) { @@ -88,15 +99,11 @@ func (dk *DpsDeathknight) RotationActionCallback_BloodRotation(sim *core.Simulat } if !casted { - if dk.blDiseaseCheck(sim, target, dk.BloodStrike, true, 1) { + if dk.blDiseaseCheck(sim, target, dk.br.bloodSpell, true, 1) { if dk.shShouldSpreadDisease(sim) { return dk.blSpreadDiseases(sim, target, s) } else { - if dk.Talents.HeartStrike { - casted = dk.HeartStrike.Cast(sim, target) - } else { - casted = dk.BloodStrike.Cast(sim, target) - } + casted = dk.br.bloodSpell.Cast(sim, target) } } else { dk.blRecastDiseasesSequence(sim) @@ -127,7 +134,7 @@ func (dk *DpsDeathknight) blAfterDrwSequence(sim *core.Simulation) { dk.RotationSequence.Clear() if dk.sr.hasGod && dk.Rotation.DrwDiseases == proto.Deathknight_Rotation_Pestilence { - dk.RotationSequence.NewAction(dk.RotationActionCallback_Pesti_DRW) + dk.RotationSequence.NewAction(dk.RotationActionBL_Pesti_DRW) } else if dk.Rotation.DrwDiseases == proto.Deathknight_Rotation_Normal { dk.RotationSequence. NewAction(dk.RotationActionBL_IT_DRW). @@ -135,7 +142,7 @@ func (dk *DpsDeathknight) blAfterDrwSequence(sim *core.Simulation) { } dk.RotationSequence. - NewAction(dk.RotationAction_ResetToBloodMain) + NewAction(dk.RotationActionBL_ResetToBloodMain) } func (dk *DpsDeathknight) blRecastDiseasesSequence(sim *core.Simulation) { @@ -160,17 +167,17 @@ func (dk *DpsDeathknight) blRecastDiseasesSequence(sim *core.Simulation) { } dk.RotationSequence. - NewAction(dk.RotationAction_ResetToBloodMain) + NewAction(dk.RotationActionBL_ResetToBloodMain) } -func (dk *DpsDeathknight) RotationAction_ResetToBloodMain(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { +func (dk *DpsDeathknight) RotationActionBL_ResetToBloodMain(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { dk.RotationSequence.Clear(). - NewAction(dk.RotationActionCallback_BloodRotation) + NewAction(dk.RotationActionBL_BloodRotation) return sim.CurrentTime } -func (dk *DpsDeathknight) RotationActionCallback_DRW_Snapshot(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { +func (dk *DpsDeathknight) RotationActionBL_DRW_Snapshot(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { dk.br.activatingDrw = true dk.br.drwSnapshot.ActivateMajorCooldowns(sim) dk.br.activatingDrw = false @@ -178,8 +185,8 @@ func (dk *DpsDeathknight) RotationActionCallback_DRW_Snapshot(sim *core.Simulati return sim.CurrentTime } -func (dk *DpsDeathknight) RotationActionCallback_DRW_Custom(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { - if dk.Talents.DancingRuneWeapon { +func (dk *DpsDeathknight) RotationActionBL_DRW_Custom(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { + if dk.Rotation.UseDancingRuneWeapon && dk.Talents.DancingRuneWeapon { casted := dk.DancingRuneWeapon.Cast(sim, target) if casted { dk.br.drwSnapshot.ResetProcTrackers() @@ -192,7 +199,14 @@ func (dk *DpsDeathknight) RotationActionCallback_DRW_Custom(sim *core.Simulation return -1 } -func (dk *DpsDeathknight) RotationActionCallback_FU(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { +func (dk *DpsDeathknight) RotationActionBL_BS(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { + casted := dk.br.bloodSpell.Cast(sim, target) + advance := dk.LastOutcome.Matches(core.OutcomeLanded) + s.ConditionalAdvance(casted && advance) + return -1 +} + +func (dk *DpsDeathknight) RotationActionBL_FU(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { casted := false if dk.Inputs.FuStrike == deathknight.FuStrike_DeathStrike { casted = dk.DeathStrike.Cast(sim, target) @@ -205,7 +219,7 @@ func (dk *DpsDeathknight) RotationActionCallback_FU(sim *core.Simulation, target return -1 } -func (dk *DpsDeathknight) RotationActionCallback_Pesti_DRW(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { +func (dk *DpsDeathknight) RotationActionBL_Pesti_DRW(sim *core.Simulation, target *core.Unit, s *deathknight.Sequence) time.Duration { casted := dk.Pestilence.Cast(sim, target) advance := dk.LastOutcome.Matches(core.OutcomeLanded) diff --git a/sim/deathknight/dps/rotation_blood_helper.go b/sim/deathknight/dps/rotation_blood_helper.go index e6a9e64a82..14abc29326 100644 --- a/sim/deathknight/dps/rotation_blood_helper.go +++ b/sim/deathknight/dps/rotation_blood_helper.go @@ -13,6 +13,8 @@ type BloodRotation struct { drwSnapshot *core.SnapshotManager drwMaxDelay time.Duration + bloodSpell *core.Spell + activatingDrw bool } @@ -152,6 +154,9 @@ func (dk *DpsDeathknight) blDrwCanCast(sim *core.Simulation, castTime time.Durat if !dk.Talents.DancingRuneWeapon { return false } + if !dk.Rotation.UseDancingRuneWeapon { + return false + } if !dk.DancingRuneWeapon.IsReady(sim) { return false } diff --git a/sim/deathknight/icy_touch.go b/sim/deathknight/icy_touch.go index 937e9b5a52..b599698e31 100644 --- a/sim/deathknight/icy_touch.go +++ b/sim/deathknight/icy_touch.go @@ -70,7 +70,7 @@ func (dk *Deathknight) registerDrwIcyTouchSpell() { BonusCritRating: dk.rimeCritBonus() * core.CritRatingPerCritChance, DamageMultiplier: 0.5 * (1 + 0.05*float64(dk.Talents.ImprovedIcyTouch)), - CritMultiplier: dk.RuneWeapon.DefaultMeleeCritMultiplier(), + CritMultiplier: dk.DefaultMeleeCritMultiplier(), ThreatMultiplier: 7, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { diff --git a/sim/deathknight/pestilence.go b/sim/deathknight/pestilence.go index ae681b6bed..3015299994 100644 --- a/sim/deathknight/pestilence.go +++ b/sim/deathknight/pestilence.go @@ -74,6 +74,7 @@ func (dk *Deathknight) registerPestilenceSpell() { }, }) } + func (dk *Deathknight) registerDrwPestilenceSpell() { hasGlyphOfDisease := dk.HasMajorGlyph(proto.DeathknightMajorGlyph_GlyphOfDisease) dk.RuneWeapon.Pestilence = dk.RuneWeapon.RegisterSpell(core.SpellConfig{ diff --git a/sim/deathknight/plague_strike.go b/sim/deathknight/plague_strike.go index a7808015ed..fdf00b4087 100644 --- a/sim/deathknight/plague_strike.go +++ b/sim/deathknight/plague_strike.go @@ -86,7 +86,7 @@ func (dk *Deathknight) registerDrwPlagueStrikeSpell() { BonusCritRating: (dk.annihilationCritBonus() + dk.scourgebornePlateCritBonus() + dk.viciousStrikesCritChanceBonus()) * core.CritRatingPerCritChance, DamageMultiplier: 0.5 * 0.5 * (1.0 + 0.1*float64(dk.Talents.Outbreak)), - CritMultiplier: dk.RuneWeapon.DefaultMeleeCritMultiplier(), + CritMultiplier: dk.bonusCritMultiplier(dk.Talents.ViciousStrikes), ThreatMultiplier: 1, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { diff --git a/ui/deathknight/inputs.ts b/ui/deathknight/inputs.ts index 1696a4c18e..1c77e310da 100644 --- a/ui/deathknight/inputs.ts +++ b/ui/deathknight/inputs.ts @@ -6,6 +6,7 @@ import { Deathknight_Rotation_ArmyOfTheDead as ArmyOfTheDead, Deathknight_Rotation_DrwDiseases as DrwDiseases, Deathknight_Rotation_BloodOpener as BloodOpener, + Deathknight_Rotation_BloodSpell as BloodSpell, Deathknight_Rotation_FirstDisease as FirstDisease, Deathknight_Rotation_DeathAndDecayPrio as DeathAndDecayPrio, Deathknight_Rotation_Presence as StartingPresence, @@ -113,7 +114,7 @@ export const UseEmpowerRuneWeapon = InputHelpers.makeRotationBooleanInput) => !player.getRotation().autoRotation && player.getRotation().frostRotationType != FrostRotationType.Custom, + showWhen: (player: Player) => !player.getRotation().autoRotation && player.getTalentTree() != 0 && player.getRotation().frostRotationType != FrostRotationType.Custom, }); export const UseGargoyle = InputHelpers.makeRotationBooleanInput({ @@ -300,6 +301,27 @@ export const Presence = InputHelpers.makeRotationEnumInput) => TypedEvent.onAny([player.rotationChangeEmitter, player.talentsChangeEmitter]), }); +export const BloodSpenderInput = InputHelpers.makeRotationEnumInput({ + fieldName: 'bloodSpender', + label: 'Blood Spender', + labelTooltip: 'Chose how to use Blood Runes.', + values: [ + { name: 'Heart Strike', value: BloodSpell.HS }, + { name: 'Blood Boil', value: BloodSpell.BB }, + { name: 'Blood Strike', value: BloodSpell.BS }, + ], + showWhen: (player: Player) => !player.getRotation().autoRotation && player.getTalentTree() == 0, + changeEmitter: (player: Player) => TypedEvent.onAny([player.rotationChangeEmitter, player.talentsChangeEmitter]), +}); + +export const UseDancingRuneWeapon = InputHelpers.makeRotationBooleanInput({ + fieldName: 'useDancingRuneWeapon', + label: 'Dancing Rune Weapon', + labelTooltip: 'Use Dancing Rune Weapon.', + showWhen: (player: Player) => player.getTalents().dancingRuneWeapon && !player.getRotation().autoRotation, + changeEmitter: (player: Player) => TypedEvent.onAny([player.rotationChangeEmitter, player.talentsChangeEmitter]), +}); + export const DrwDiseasesInput = InputHelpers.makeRotationEnumInput({ fieldName: 'drwDiseases', label: 'DRW Disease', @@ -309,7 +331,7 @@ export const DrwDiseasesInput = InputHelpers.makeRotationEnumInput) => !player.getRotation().autoRotation && player.getTalentTree() == 0 && player.getRotation().bloodOpener == BloodOpener.Standard, + showWhen: (player: Player) => player.getRotation().useDancingRuneWeapon && !player.getRotation().autoRotation && player.getTalents().dancingRuneWeapon && player.getRotation().bloodOpener == BloodOpener.Standard, changeEmitter: (player: Player) => TypedEvent.onAny([player.rotationChangeEmitter, player.talentsChangeEmitter]), }); @@ -383,8 +405,10 @@ export const DeathKnightRotationConfig = { EnableWeaponSwap, WeaponSwapInputs, UseEmpowerRuneWeapon, + UseDancingRuneWeapon, HoldErwArmy, BloodTapInput, + BloodSpenderInput, ArmyOfTheDeadInput, //BloodOpenerInput, DrwDiseasesInput, diff --git a/ui/deathknight/presets.ts b/ui/deathknight/presets.ts index efbf0e1c88..fab8bab850 100644 --- a/ui/deathknight/presets.ts +++ b/ui/deathknight/presets.ts @@ -27,6 +27,7 @@ import { DeathknightMajorGlyph, DeathknightMinorGlyph, Deathknight_Rotation_DrwDiseases, + Deathknight_Rotation_BloodSpell, } from '../core/proto/deathknight.js'; import * as Tooltips from '../core/constants/tooltips.js'; @@ -128,6 +129,8 @@ export const DefaultUnholyRotation = DeathKnightRotation.create({ bloodRuneFiller: Deathknight_Rotation_BloodRuneFiller.BloodBoil, useAms: false, drwDiseases: Deathknight_Rotation_DrwDiseases.Pestilence, + bloodSpender: Deathknight_Rotation_BloodSpell.HS, + useDancingRuneWeapon: true }); export const DefaultUnholyOptions = DeathKnightOptions.create({ @@ -190,6 +193,8 @@ export const DefaultBloodRotation = DeathKnightRotation.create({ holdErwArmy: false, useAms: false, drwDiseases: Deathknight_Rotation_DrwDiseases.Pestilence, + bloodSpender: Deathknight_Rotation_BloodSpell.HS, + useDancingRuneWeapon: true }); export const DefaultBloodOptions = DeathKnightOptions.create({ From 5b11613a5223ff3a5251957fdbfea5a9dbd9ece9 Mon Sep 17 00:00:00 2001 From: rosenrusinov Date: Sun, 26 Feb 2023 13:03:40 +0100 Subject: [PATCH 2/3] fix drw bb modifier --- sim/deathknight/blood_boil.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/deathknight/blood_boil.go b/sim/deathknight/blood_boil.go index 8917d3b14c..d2e58cac0d 100644 --- a/sim/deathknight/blood_boil.go +++ b/sim/deathknight/blood_boil.go @@ -53,7 +53,7 @@ func (dk *Deathknight) registerDrwBloodBoilSpell() { SpellSchool: core.SpellSchoolShadow, ProcMask: core.ProcMaskSpellDamage, - DamageMultiplier: dk.bloodyStrikesBonus(dk.BloodBoil), + DamageMultiplier: 0.5 * dk.bloodyStrikesBonus(dk.BloodBoil), CritMultiplier: dk.bonusCritMultiplier(dk.Talents.MightOfMograine), ThreatMultiplier: 1, From 2b64b67710042ac6e7e7acac4bd6e80fc74b28f4 Mon Sep 17 00:00:00 2001 From: rosenrusinov Date: Sun, 26 Feb 2023 13:04:11 +0100 Subject: [PATCH 3/3] add missing spell flag --- sim/deathknight/blood_boil.go | 1 + 1 file changed, 1 insertion(+) diff --git a/sim/deathknight/blood_boil.go b/sim/deathknight/blood_boil.go index d2e58cac0d..9c70c5c464 100644 --- a/sim/deathknight/blood_boil.go +++ b/sim/deathknight/blood_boil.go @@ -52,6 +52,7 @@ func (dk *Deathknight) registerDrwBloodBoilSpell() { ActionID: BloodBoilActionID, SpellSchool: core.SpellSchoolShadow, ProcMask: core.ProcMaskSpellDamage, + Flags: core.SpellFlagIgnoreAttackerModifiers, DamageMultiplier: 0.5 * dk.bloodyStrikesBonus(dk.BloodBoil), CritMultiplier: dk.bonusCritMultiplier(dk.Talents.MightOfMograine),