death_knight

package
v0.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2025 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DDBC_MercilessCombat int = 0
	DDBC_RuneOfRazorice      = iota

	DDBC_Total
)

Damage Done By Caster setup

View Source
const (
	DeathKnightSpellFlagNone      int64 = 0
	DeathKnightSpellAntiMagicZone int64 = 1 << iota
	DeathKnightSpellArmyOfTheDead
	DeathKnightSpellBloodBoil
	DeathKnightSpellBloodPlague
	DeathKnightSpellBloodPresence
	DeathKnightSpellBloodStrike
	DeathKnightSpellBloodTap
	DeathKnightSpellBoneShield
	DeathKnightSpellConversion
	DeathKnightSpellDancingRuneWeapon
	DeathKnightSpellDarkCommand
	DeathKnightSpellDarkTransformation
	DeathKnightSpellDeathAndDecay
	DeathKnightSpellDeathCoil
	DeathKnightSpellDeathCoilHeal
	DeathKnightSpellDeathPact
	DeathKnightSpellDeathSiphon
	DeathKnightSpellDeathStrike
	DeathKnightSpellDeathStrikeHeal
	DeathKnightSpellEmpowerRuneWeapon
	DeathKnightSpellFesteringStrike
	DeathKnightSpellFrostFever
	DeathKnightSpellFrostPresence
	DeathKnightSpellFrostStrike
	DeathKnightSpellHeartStrike
	DeathKnightSpellHornOfWinter
	DeathKnightSpellHowlingBlast
	DeathKnightSpellIceboundFortitude
	DeathKnightSpellIcyTouch
	DeathKnightSpellLichborne
	DeathKnightSpellObliterate
	DeathKnightSpellOutbreak
	DeathKnightSpellPestilence
	DeathKnightSpellPillarOfFrost
	DeathKnightSpellPlagueLeech
	DeathKnightSpellPlagueStrike
	DeathKnightSpellRaiseDead
	DeathKnightSpellRuneStrike
	DeathKnightSpellRuneTap
	DeathKnightSpellScourgeStrike
	DeathKnightSpellScourgeStrikeShadow
	DeathKnightSpellSoulReaper
	DeathKnightSpellSummonGargoyle
	DeathKnightSpellUnholyBlight
	DeathKnightSpellUnholyFrenzy
	DeathKnightSpellUnholyPresence
	DeathKnightSpellVampiricBlood

	DeathKnightSpellKillingMachine     // Used to react to km procs
	DeathKnightSpellSuddenDoom         // Used to react to km procs
	DeathKnightSpellConvertToDeathRune // Used to react to death rune gains

	DeathKnightSpellLast
	DeathKnightSpellsAll = DeathKnightSpellLast<<1 - 1

	DeathKnightSpellDisease = DeathKnightSpellFrostFever | DeathKnightSpellBloodPlague
)
View Source
const (
	GhoulSpellNone int64 = 0
	GhoulSpellClaw int64 = 1 << iota

	GhoulSpellLast
	GhoulSpellsAll = GhoulSpellLast<<1 - 1
)

Variables

View Source
var BloodBoilActionID = core.ActionID{SpellID: 48721}
View Source
var DeathCoilActionID = core.ActionID{SpellID: 47541}
View Source
var DeathSiphonActionID = core.ActionID{SpellID: 108196}
View Source
var DeathStrikeActionID = core.ActionID{SpellID: 49998}
View Source
var IcyTouchActionID = core.ActionID{SpellID: 45477}
View Source
var ItemSetBattlegearOfTheLostCatacomb = core.NewItemSet(core.ItemSet{
	Name:                    "Battlegear of the Lost Catacomb",
	ID:                      1123,
	DisabledInChallengeMode: true,
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec == proto.Spec_SpecBloodDeathKnight {
				return
			}

			setBonusAura.AttachSpellMod(core.SpellModConfig{
				Kind:       core.SpellMod_DamageDone_Pct,
				ClassMask:  DeathKnightSpellFrostStrike | DeathKnightSpellObliterate | DeathKnightSpellScourgeStrike,
				FloatValue: 0.04,
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec == proto.Spec_SpecBloodDeathKnight {
				return
			}

			dk.T14Dps4pc = setBonusAura
		},
	},
})

T14 DPS

View Source
var ItemSetBattleplateOfCyclopeanDread = core.NewItemSet(core.ItemSet{
	Name:                    "Battleplate of Cyclopean Dread",
	ID:                      1200,
	DisabledInChallengeMode: true,
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec == proto.Spec_SpecBloodDeathKnight {
				return
			}

			var duration time.Duration
			if dk.Spec == proto.Spec_SpecUnholyDeathKnight {
				duration = time.Second * 15
			} else if dk.MainHand().HandType == proto.HandType_HandTypeTwoHand {
				duration = time.Second * 8
			} else {
				duration = time.Second * 6
			}

			currentStat := stats.HasteRating
			deathShroudAura := dk.RegisterAura(core.Aura{
				Label:     "Death Shroud" + dk.Label,
				ActionID:  core.ActionID{SpellID: 144901},
				Duration:  duration,
				MaxStacks: 10,

				OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
					newStat := core.Ternary(
						dk.GetStat(stats.HasteRating) > dk.GetStat(stats.MasteryRating),
						stats.HasteRating,
						stats.MasteryRating)
					if currentStat == newStat {
						dk.AddStatDynamic(sim, currentStat, 500*float64(newStacks-oldStacks))
					} else {
						dk.AddStatDynamic(sim, currentStat, -500*float64(oldStacks))
						dk.AddStatDynamic(sim, newStat, 500*float64(newStacks))
						currentStat = newStat
					}
				},
			})

			setBonusAura.AttachProcTrigger(core.ProcTrigger{
				Callback:       core.CallbackOnCastComplete,
				ClassSpellMask: DeathKnightSpellKillingMachine | DeathKnightSpellSuddenDoom,

				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					deathShroudAura.Activate(sim)
					deathShroudAura.AddStack(sim)
				},
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()

			if dk.Spec == proto.Spec_SpecUnholyDeathKnight {
				setBonusAura.AttachProcTrigger(core.ProcTrigger{
					Callback:       core.CallbackOnSpellHitDealt | core.CallbackOnHealDealt,
					ClassSpellMask: DeathKnightSpellDeathCoil | DeathKnightSpellDeathCoilHeal,

					Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
						if dk.Ghoul.DarkTransformationAura.IsActive() {
							dk.Ghoul.DarkTransformationAura.UpdateExpires(dk.Ghoul.DarkTransformationAura.ExpiresAt() + time.Second*2)
						}
					},
				})
			} else if dk.Spec == proto.Spec_SpecFrostDeathKnight {
				frozenPowerSpell := dk.RegisterSpell(core.SpellConfig{
					ActionID:    core.ActionID{SpellID: 147620},
					SpellSchool: core.SpellSchoolFrost,
					ProcMask:    core.ProcMaskEmpty,
					Flags:       core.SpellFlagPassiveSpell,

					DamageMultiplier: 1,
					CritMultiplier:   dk.DefaultCritMultiplier(),
					ThreatMultiplier: 1,

					ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
						baseDamage := 500.0 + 0.07999999821*spell.MeleeAttackPower()
						spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeSpecialHitAndCrit)
					},
				})

				dk.OnSpellRegistered(func(spell *core.Spell) {
					if !spell.Matches(DeathKnightSpellPillarOfFrost) {
						return
					}

					dk.PillarOfFrostAura.AttachProcTrigger(core.ProcTrigger{
						Callback: core.CallbackOnSpellHitDealt,
						ProcMask: core.ProcMaskSpecial,
						Outcome:  core.OutcomeLanded,
						Harmful:  true,

						Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
							frozenPowerSpell.Cast(sim, result.Target)
						},
					})
				})
			}
		},
	},
})

T16 DPS

View Source
var ItemSetBattleplateOfTheAllConsumingMaw = core.NewItemSet(core.ItemSet{
	Name:                    "Battleplate of the All-Consuming Maw",
	ID:                      1152,
	DisabledInChallengeMode: true,
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()

			risenZandalariSpell := dk.RegisterSpell(core.SpellConfig{
				ActionID:    core.ActionID{SpellID: 138342},
				SpellSchool: core.SpellSchoolPhysical,
				Flags:       core.SpellFlagPassiveSpell,

				ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
					for _, troll := range dk.FallenZandalari {
						if troll.IsActive() {
							continue
						}

						troll.EnableWithTimeout(sim, troll, time.Second*15)

						return
					}

					if sim.Log != nil {
						dk.Log(sim, "No Fallen Zandalari available for the T15 4pc to proc, this is unreasonable.")
					}
				},
			})

			setBonusAura.AttachProcTrigger(core.ProcTrigger{
				Callback: core.CallbackOnSpellHitDealt,
				Outcome:  core.OutcomeLanded,
				DPM: dk.NewSetBonusRPPMProcManager(138343, setBonusAura, core.ProcMaskDirect, core.RPPMConfig{
					PPM: 1.14999997616,
				}),
				ICD: time.Millisecond * 250,

				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					risenZandalariSpell.Cast(sim, result.Target)
				},
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()

			setBonusAura.ApplyOnGain(func(aura *core.Aura, sim *core.Simulation) {
				dk.soulReaper45Percent = true
			}).ApplyOnExpire(func(aura *core.Aura, sim *core.Simulation) {
				dk.soulReaper45Percent = false
			}).ExposeToAPL(138347)
		},
	},
})

T15 DPS

View Source
var ItemSetPlateOfCyclopeanDread = core.NewItemSet(core.ItemSet{
	Name:                    "Plate of Cyclopean Dread",
	ID:                      1201,
	DisabledInChallengeMode: true,
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec != proto.Spec_SpecBloodDeathKnight {
				return
			}

			dk.BoneWallAura = dk.RegisterAura(core.Aura{
				Label:     "Bone Wall" + dk.Label,
				ActionID:  core.ActionID{SpellID: 144948},
				Duration:  time.Minute * 2,
				MaxStacks: 6,
			}).AttachProcTrigger(core.ProcTrigger{
				Callback:       core.CallbackOnCastComplete,
				ClassSpellMask: DeathKnightSpellBoneShield,

				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					dk.BoneWallAura.Deactivate(sim)
				},
			})

			boneWallDriver := dk.RegisterAura(core.Aura{
				Label:     "Bone Wall Driver" + dk.Label,
				ActionID:  core.ActionID{SpellID: 145719},
				Duration:  time.Minute * 10,
				MaxStacks: 10,

				OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
					if newStacks == 10 {
						dk.BoneWallAura.Activate(sim)
						dk.BoneWallAura.AddStack(sim)
						aura.SetStacks(sim, 1)
					}
				},
			})

			setBonusAura.AttachProcTrigger(core.ProcTrigger{
				Callback: core.CallbackOnCastComplete,
				ClassSpellMask: DeathKnightSpellHeartStrike |
					DeathKnightSpellRuneStrike |
					DeathKnightSpellDeathCoil |
					DeathKnightSpellSoulReaper |
					DeathKnightSpellBloodBoil,

				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					boneWallDriver.Activate(sim)
					boneWallDriver.AddStack(sim)
				},
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec != proto.Spec_SpecBloodDeathKnight {
				return
			}

			deathRuneMetrics := dk.NewDeathRuneMetrics(core.ActionID{SpellID: 144950})

			setBonusAura.AttachProcTrigger(core.ProcTrigger{
				Callback:       core.CallbackOnCastComplete,
				ClassSpellMask: DeathKnightSpellDancingRuneWeapon,

				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					dk.RegenAllFrostAndUnholyRunesAsDeath(sim, deathRuneMetrics)
				},
			})
		},
	},
})

T16 Tank

View Source
var ItemSetPlateOfTheAllConsumingMaw = core.NewItemSet(core.ItemSet{
	Name:                    "Plate of the All-Consuming Maw",
	ID:                      1151,
	DisabledInChallengeMode: true,
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec != proto.Spec_SpecBloodDeathKnight {
				return
			}

			setBonusAura.AttachSpellMod(core.SpellModConfig{
				Kind:      core.SpellMod_Cooldown_Flat,
				ClassMask: DeathKnightSpellRuneTap,
				TimeValue: time.Second * -10,
			}).AttachSpellMod(core.SpellModConfig{
				Kind:       core.SpellMod_PowerCost_Pct,
				ClassMask:  DeathKnightSpellRuneTap,
				FloatValue: -2.0,
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec != proto.Spec_SpecBloodDeathKnight {
				return
			}

			rpMetrics := dk.NewRunicPowerMetrics(core.ActionID{SpellID: 138214})

			dk.OnSpellRegistered(func(spell *core.Spell) {
				if !spell.Matches(DeathKnightSpellBoneShield) {
					return
				}

				dk.BoneShieldAura.ApplyOnStacksChange(func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
					if !setBonusAura.IsActive() {
						return
					}

					if newStacks < oldStacks {
						dk.AddRunicPower(sim, 15, rpMetrics)
					}
				})
			})
		},
	},
})

T15 Tank

View Source
var ItemSetPlateOfTheLostCatacomb = core.NewItemSet(core.ItemSet{
	Name:                    "Plate of the Lost Catacomb",
	ID:                      1124,
	DisabledInChallengeMode: true,
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()
			if dk.Spec != proto.Spec_SpecBloodDeathKnight {
				return
			}

			setBonusAura.AttachSpellMod(core.SpellModConfig{
				Kind:      core.SpellMod_Cooldown_Flat,
				ClassMask: DeathKnightSpellVampiricBlood,
				TimeValue: time.Second * -20,
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {

			dk := agent.(DeathKnightAgent).GetDeathKnight()

			setBonusAura.AttachMultiplicativePseudoStatBuff(
				&dk.deathStrikeHealingMultiplier, 1.1,
			)
		},
	},
})

T14 Tank

View Source
var OutbreakActionID = core.ActionID{SpellID: 77575}
View Source
var PestilenceActionID = core.ActionID{SpellID: 50842}
View Source
var PlagueStrikeActionID = core.ActionID{SpellID: 45462}
View Source
var SoulReaperActionID = core.ActionID{SpellID: 114867}

Functions

func CopySpellMultipliers

func CopySpellMultipliers(sourceSpell *core.Spell, targetSpell *core.Spell, target *core.Unit)

Types

type DeathKnight

type DeathKnight struct {
	core.Character
	Talents *proto.DeathKnightTalents

	Inputs DeathKnightInputs

	// Pets
	Ghoul           *GhoulPet
	ArmyGhoul       []*GhoulPet
	FallenZandalari []*GhoulPet
	AllGhoulPets    []*GhoulPet
	RuneWeapon      *RuneWeaponPet

	BloodPresenceSpell  *core.Spell
	FrostPresenceSpell  *core.Spell
	UnholyPresenceSpell *core.Spell

	PestilenceSpell *core.Spell

	BoneShieldAura         *core.Aura
	BoneWallAura           *core.Aura
	ConversionAura         *core.Aura
	PillarOfFrostAura      *core.Aura
	RaiseDeadAura          *core.Aura
	ThreatOfThassarianAura *core.Aura

	// Diseases
	FrostFeverSpell  *core.Spell
	BloodPlagueSpell *core.Spell

	// Runic power decay, used during pre pull
	RunicPowerDecayAura *core.Aura

	// Item sets
	T14Dps4pc *core.Aura
	// contains filtered or unexported fields
}

func NewDeathKnight

func NewDeathKnight(character *core.Character, inputs DeathKnightInputs, talents string, deathRuneConvertSpellId int32) *DeathKnight

func (*DeathKnight) AddPartyBuffs

func (dk *DeathKnight) AddPartyBuffs(partyBuffs *proto.PartyBuffs)

func (*DeathKnight) AddRaidBuffs

func (dk *DeathKnight) AddRaidBuffs(raidBuffs *proto.RaidBuffs)

func (*DeathKnight) ApplyTalents

func (dk *DeathKnight) ApplyTalents()

func (*DeathKnight) DiseasesAreActive

func (dk *DeathKnight) DiseasesAreActive(target *core.Unit) bool

func (*DeathKnight) GetAllActiveGhoulPets added in v0.0.6

func (dk *DeathKnight) GetAllActiveGhoulPets() []*core.Pet

func (*DeathKnight) GetCharacter

func (dk *DeathKnight) GetCharacter() *core.Character

func (*DeathKnight) GetDeathKnight

func (dk *DeathKnight) GetDeathKnight() *DeathKnight

func (*DeathKnight) GetDiseaseMulti

func (dk *DeathKnight) GetDiseaseMulti(target *core.Unit, base float64, increase float64) float64

func (*DeathKnight) HasMajorGlyph

func (dk *DeathKnight) HasMajorGlyph(glyph proto.DeathKnightMajorGlyph) bool

func (*DeathKnight) HasMinorGlyph

func (dk *DeathKnight) HasMinorGlyph(glyph proto.DeathKnightMinorGlyph) bool

func (*DeathKnight) Initialize

func (dk *DeathKnight) Initialize()

func (*DeathKnight) NewArmyGhoulPet

func (dk *DeathKnight) NewArmyGhoulPet() *GhoulPet

func (*DeathKnight) NewFallenZandalariPet

func (dk *DeathKnight) NewFallenZandalariPet() *GhoulPet

func (*DeathKnight) NewGhoulPet

func (dk *DeathKnight) NewGhoulPet(permanent bool) *GhoulPet

func (*DeathKnight) NewRuneWeapon

func (dk *DeathKnight) NewRuneWeapon() *RuneWeaponPet

func (*DeathKnight) OnEncounterStart added in v0.0.13

func (dk *DeathKnight) OnEncounterStart(sim *core.Simulation)

func (*DeathKnight) Reset

func (dk *DeathKnight) Reset(sim *core.Simulation)

func (*DeathKnight) SetupGhoul

func (dk *DeathKnight) SetupGhoul(ghoulPet *GhoulPet, scalingCoef float64)

type DeathKnightAgent

type DeathKnightAgent interface {
	GetDeathKnight() *DeathKnight
}

type DeathKnightInputs

type DeathKnightInputs struct {
	// Option Vars
	IsDps bool

	UnholyFrenzyTarget *proto.UnitReference

	Spec proto.Spec
}

type GhoulPet

type GhoulPet struct {
	core.Pet

	DarkTransformationAura *core.Aura
	ShadowInfusionAura     *core.Aura
	Claw                   *core.Spell
	// contains filtered or unexported fields
}

func (*GhoulPet) Enable

func (ghoulPet *GhoulPet) Enable(sim *core.Simulation, petAgent core.PetAgent)

func (*GhoulPet) EnableWithTimeout added in v0.0.2

func (ghoulPet *GhoulPet) EnableWithTimeout(sim *core.Simulation, petAgent core.PetAgent, petDuration time.Duration)

func (*GhoulPet) ExecuteCustomRotation

func (ghoulPet *GhoulPet) ExecuteCustomRotation(sim *core.Simulation)

func (*GhoulPet) GetPet

func (ghoulPet *GhoulPet) GetPet() *core.Pet

func (*GhoulPet) Initialize

func (ghoulPet *GhoulPet) Initialize()

func (*GhoulPet) OnEncounterStart added in v0.0.13

func (ghoulPet *GhoulPet) OnEncounterStart(_ *core.Simulation)

func (*GhoulPet) Reset

func (ghoulPet *GhoulPet) Reset(_ *core.Simulation)

type RuneWeaponPet

type RuneWeaponPet struct {
	core.Pet

	// Diseases
	FrostFeverSpell  *core.Spell
	BloodPlagueSpell *core.Spell

	StrikeWeapon       *core.Weapon
	StrikeWeaponDamage float64

	RuneWeaponSpells map[core.ActionID]*core.Spell
	// contains filtered or unexported fields
}

func (*RuneWeaponPet) AddCopySpell

func (runeWeapon *RuneWeaponPet) AddCopySpell(actionId core.ActionID, spell *core.Spell)

func (*RuneWeaponPet) DiseasesAreActive

func (runeWeapon *RuneWeaponPet) DiseasesAreActive(target *core.Unit) bool

func (*RuneWeaponPet) ExecuteCustomRotation

func (runeWeapon *RuneWeaponPet) ExecuteCustomRotation(_ *core.Simulation)

func (*RuneWeaponPet) GetDiseaseMulti

func (runeWeapon *RuneWeaponPet) GetDiseaseMulti(target *core.Unit, base float64, increase float64) float64

func (*RuneWeaponPet) GetPet

func (runeWeapon *RuneWeaponPet) GetPet() *core.Pet

func (*RuneWeaponPet) Initialize

func (runeWeapon *RuneWeaponPet) Initialize()

func (*RuneWeaponPet) OnEncounterStart added in v0.0.13

func (runeWeapon *RuneWeaponPet) OnEncounterStart(_ *core.Simulation)

func (*RuneWeaponPet) Reset

func (runeWeapon *RuneWeaponPet) Reset(_ *core.Simulation)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL