warlock

package
v0.0.32 Latest Latest
Warning

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

Go to latest
Published: Nov 18, 2024 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	InfernalPactEssence         = 216509
	ZIlaGular                   = 223214
	ScytheOfChaos               = 229910
	TheBlackBook                = 230238
	HazzarahsCharmOfDestruction = 231284
	KezansUnstoppableTaint      = 231346
)
View Source
const (
	WarlockFlagAffliction  = core.SpellFlagAgentReserved1
	WarlockFlagDemonology  = core.SpellFlagAgentReserved2
	WarlockFlagDestruction = core.SpellFlagAgentReserved3
	WarlockFlagHaunt       = core.SpellFlagAgentReserved4

	SpellFlagWarlock = WarlockFlagAffliction | WarlockFlagDemonology | WarlockFlagDestruction
)
View Source
const (
	SpellCode_WarlockNone int32 = iota

	SpellCode_WarlockConflagrate
	SpellCode_WarlockCorruption
	SpellCode_WarlockCurseOfAgony
	SpellCode_WarlockCurseOfDoom
	SpellCode_WarlockDeathCoil
	SpellCode_WarlockDemonicSacrifice
	SpellCode_WarlockDrainLife
	SpellCode_WarlockDrainSoul
	SpellCode_WarlockHaunt
	SpellCode_WarlockImmolate
	SpellCode_WarlockIncinerate
	SpellCode_WarlockLifeTap
	SpellCode_WarlockSearingPain
	SpellCode_WarlockShadowflame
	SpellCode_WarlockShadowCleave
	SpellCode_WarlockShadowBolt
	SpellCode_WarlockShadowburn
	SpellCode_WarlockSoulFire
	SpellCode_WarlockUnstableAffliction
)
View Source
const ConflagrateRanks = 4
View Source
const CorruptionRanks = 7
View Source
const CurseOfAgonyRanks = 6
View Source
const DeathCoilRanks = 3
View Source
const DrainLifeRanks = 6
View Source
const DrainSoulRanks = 4
View Source
const ImmolateCastTime = time.Millisecond * 2000
View Source
const ImmolateRanks = 8
View Source
const IncinerateCastTime = time.Millisecond * 2250
View Source
const LifeTapRanks = 6
View Source
const RainOfFireRanks = 4
View Source
const SearingPainRanks = 6
View Source
const ShadowBoltRanks = 10
View Source
const ShadowburnRanks = 6
View Source
const ShadowflameCastTime = time.Second * 2
View Source
const SiphonLifeRanks = 4
View Source
const SoulFireCastTime = time.Millisecond * 6000
View Source
const SoulFireRanks = 2
View Source
const SoulSiphonDoTMultiplier = 0.06

https://www.wowhead.com/classic/spell=403511/soul-siphon Causes your Drain Soul to to deal damage 3 times faster and increases the amount drained by your Drain Life and Drain Soul spells by an additional 6% for each of your Warlock Shadow effects afflicting the target, up to a maximum of 18% additional effect. When Drain Soul is cast on a target below 20% health, it instead gains 50% per effect, up to a maximum of 150%.

View Source
const SoulSiphonDoTMultiplierExecute = 1.00
View Source
const SoulSiphonDoTMultiplierMax = 0.18
View Source
const SoulSiphonDoTMultiplierMaxExecute = 3.00

Variables

View Source
var ItemSetChampionsThreads = core.NewItemSet(core.ItemSet{
	Name: "Champion's Threads",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.SpellPower, 23)
		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.GetOrRegisterAura(core.Aura{
				Label: "Immolate Cast Time Reduction",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.Immolate {
						spell.DefaultCast.CastTime -= time.Millisecond * 200
					}
				},
			})
		},

		6: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.Stamina, 20)
		},
	},
})
View Source
var ItemSetCorruptedFelheart = core.NewItemSet(core.ItemSet{
	Name: "Corrupted Felheart",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.RegisterAura(core.Aura{
				Label:    "S03 - Item - T1 - Warlock - Damage 2P Bonus",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
				},
				OnGain: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.LifeTap {
						spell.DamageMultiplier *= 1.5
						spell.ThreatMultiplier *= -1
					}
				},
				OnExpire: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.LifeTap {
						spell.DamageMultiplier /= 1.5
						spell.ThreatMultiplier *= -1
					}
				},
			})
		},

		4: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStats(stats.Stats{
				stats.MeleeCrit: 2 * core.CritRatingPerCritChance,
				stats.SpellCrit: 2 * core.CritRatingPerCritChance,
			})
		},

		6: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			warlock6pt1Aura := warlock.RegisterAura(core.Aura{
				Label:    "S03 - Item - T1 - Warlock - Damage 6P Bonus",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
				},
				OnGain: func(_ *core.Aura, _ *core.Simulation) {
					warlock.nightfallProcChance += 0.04
				},
				OnExpire: func(_ *core.Aura, _ *core.Simulation) {
					warlock.nightfallProcChance -= 0.04
				},
			})

			if !warlock.HasRune(proto.WarlockRune_RuneBracerIncinerate) || !warlock.HasRune(proto.WarlockRune_RuneBootsDecimation) {
				return
			}

			warlock6pt1Aura.OnSpellHitDealt = func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
				if spell.SpellCode == SpellCode_WarlockIncinerate && result.Landed() && sim.Proc(.04, "T1 6P Incinerate Proc") {
					warlock.DecimationAura.Activate(sim)
				}
			}
		},
	},
})
View Source
var ItemSetCorruptedNemesis = core.NewItemSet(core.ItemSet{
	Name: "Corrupted Nemesis",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			if warlock.HasRune(proto.WarlockRune_RuneBracerSummonFelguard) {
				warlock.Felguard.PseudoStats.DamageDealtMultiplier *= 1.10
			}

			core.MakePermanent(warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - T2 - Warlock - Damage 2P Bonus",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.Spellbook {
						if spell.Flags.Matches(SpellFlagWarlock) && len(spell.Dots()) > 0 {
							spell.DamageMultiplier *= 1.10
						}
					}
				},
			}))
		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			procChance := 0.04

			affectedSpellCodes := []int32{SpellCode_WarlockCurseOfAgony, SpellCode_WarlockShadowflame, SpellCode_WarlockUnstableAffliction}
			core.MakePermanent(warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - T2 - Warlock - Damage 4P Bonus",
				OnPeriodicDamageDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if slices.Contains(affectedSpellCodes, spell.SpellCode) && sim.Proc(procChance, "Proc Shadow Trance") {
						warlock.ShadowTranceAura.Activate(sim)
					}
				},
			}))

			if !warlock.HasRune(proto.WarlockRune_RuneBracerSummonFelguard) {
				return
			}

			core.MakePermanent(warlock.Felguard.RegisterAura(core.Aura{
				Label: "S03 - Item - T2 - Warlock - Damage 4P Bonus - Felguard Bonus",
				OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if result.Landed() && sim.Proc(procChance, "Proc Shadow Trance") {
						warlock.ShadowTranceAura.Activate(sim)
					}
				},
			}))
		},

		6: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			warlock.shadowBoltActiveEffectMultiplierPer = .10
			warlock.shadowBoltActiveEffectMultiplierMax = 1.30
		},
	},
})
View Source
var ItemSetDeathmistRaiment = core.NewItemSet(core.ItemSet{
	Name: "Deathmist Raiment",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.SpellPower, 23)
		},

		4: func(agent core.Agent) {
			c := agent.GetCharacter()
			manaMetrics := c.NewManaMetrics(core.ActionID{SpellID: 450583})

			handler := func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) {
				if c.HasManaBar() {
					c.AddMana(sim, sim.Roll(270, 300), manaMetrics)
				}
			}

			core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{
				Name:       "S03 - Heal Proc on Cast - Dreadmist Raiment (Melee Auto)",
				Callback:   core.CallbackOnSpellHitDealt,
				Outcome:    core.OutcomeLanded,
				ProcMask:   core.ProcMaskWhiteHit,
				ProcChance: 0.06,
				Handler:    handler,
			})
			core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{
				Name:       "S03 - Heal Proc on Cast - Dreadmist Raiment (Spell Cast)",
				Callback:   core.CallbackOnCastComplete,
				ProcMask:   core.ProcMaskSpellDamage | core.ProcMaskSpellHealing,
				ProcChance: 0.06,
				Handler:    handler,
			})
		},

		6: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddResistances(8)
		},

		8: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.Armor, 200)
		},
	},
})
View Source
var ItemSetDemoniacsThreads = core.NewItemSet(core.ItemSet{
	Name: "Demoniac's Threads",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.AddStat(stats.SpellPower, 12)
		},

		3: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			core.MakePermanent(warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - ZG - Warlock - Demonology 3P Bonus",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, pet := range warlock.BasePets {
						oldStatInheritance := pet.GetStatInheritance()
						pet.UpdateStatInheritance(
							func(ownerStats stats.Stats) stats.Stats {
								s := oldStatInheritance(ownerStats)
								s[stats.AttackPower] *= 1.20
								s[stats.SpellPower] *= 1.20
								return s
							},
						)
					}
				},
			}))
		},

		5: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.masterDemonologistBonus += .50
		},
	},
})
View Source
var ItemSetDoomcallersCorruption = core.NewItemSet(core.ItemSet{
	Name: "Doomcaller's Corruption",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			if !warlock.HasRune(proto.WarlockRune_RuneHandsChaosBolt) {
				return
			}

			warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - TAQ - Warlock - Damage 2P Bonus",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					warlock.ChaosBolt.CD.Duration /= 2
					warlock.ChaosBolt.DamageMultiplier *= 1.10
				},
			})
		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			buffAura := warlock.RegisterAura(core.Aura{
				ActionID:  core.ActionID{SpellID: 1214088},
				Label:     "Infernalist",
				Duration:  time.Second * 20,
				MaxStacks: 5,
				OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
					warlock.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFire] *= 1 + 0.02*(float64(newStacks-oldStacks))
				},
			})

			core.MakePermanent(warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - TAQ - Warlock - Damage 4P Bonus",
				OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if spell.SpellCode == SpellCode_WarlockConflagrate && result.Landed() {
						buffAura.Activate(sim)
						buffAura.AddStack(sim)
					}
				},
			}))
		},
	},
})
View Source
var ItemSetDoomcallersMalevolence = core.NewItemSet(core.ItemSet{
	Name: "Doomcaller's Malevolence",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			if !warlock.HasRune(proto.WarlockRune_RuneHandsMetamorphosis) {
				return
			}

			warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - TAQ - Warlock - Tank 2P Bonus",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.ShadowCleave {
						spell.CD.Duration -= time.Millisecond * 1500
					}
				},
			})
		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			core.MakePermanent(warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - TAQ - Warlock - Tank 4P Bonus",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					warlock.disableMasterDemonologistOnSacrifice = false
				},
			}))
		},
	},
})
View Source
var ItemSetFieldMarshalsThreads = core.NewItemSet(core.ItemSet{
	Name: "Field Marshal's Threads",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.Stamina, 20)
		},

		3: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.GetOrRegisterAura(core.Aura{
				Label: "Immolate Cast Time Reduction",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.Immolate {
						spell.DefaultCast.CastTime -= time.Millisecond * 200
					}
				},
			})
		},

		6: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.SpellPower, 23)
		},
	},
})
View Source
var ItemSetImplementsOfUnspokenNames = core.NewItemSet(core.ItemSet{
	Name: "Implements of Unspoken Names",
	Bonuses: map[int32]core.ApplyEffect{

		3: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			if !warlock.HasRune(proto.WarlockRune_RuneHandsMetamorphosis) || len(warlock.Env.Encounter.TargetUnits) <= 1 {
				return
			}

			buffAura := warlock.RegisterAura(core.Aura{
				ActionID: core.ActionID{SpellID: 1214156},
				Label:    "Spreading Pain",
				Duration: time.Second * 6,
				OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if spell.SpellCode == SpellCode_WarlockSearingPain {
						aura.Deactivate(sim)
						spell.ApplyEffects(sim, warlock.Env.NextTargetUnit(result.Target), spell)
					}
				},
			})

			core.MakePermanent(warlock.RegisterAura(core.Aura{
				Label: "S03 - Item - RAQ - Warlock - Tank 3P Bonus",
				OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) {
					if spell.SpellCode == SpellCode_WarlockShadowCleave {
						buffAura.Activate(sim)
					}
				},
			}))
		},
	},
})
View Source
var ItemSetLieutenantCommandersThreads = core.NewItemSet(core.ItemSet{
	Name: "Lieutenant Commander's Threads",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.SpellPower, 23)
		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.GetOrRegisterAura(core.Aura{
				Label:    "Immolate Cast Time Reduction",
				ActionID: core.ActionID{SpellID: 23047},
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.Immolate {
						spell.DefaultCast.CastTime -= time.Millisecond * 200
					}
				},
			})
		},

		6: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.Stamina, 20)
		},
	},
})
View Source
var ItemSetNightmareProphetsGarb = core.NewItemSet(core.ItemSet{
	Name: "Nightmare Prophet's Garb",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.MeleeHit, 1)
			c.AddStat(stats.SpellHit, 1)
		},
		3: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			warlock.shadowSparkAura = warlock.GetOrRegisterAura(core.Aura{
				Label:     "Shadow Spark Proc",
				ActionID:  core.ActionID{SpellID: 450013},
				Duration:  time.Second * 12,
				MaxStacks: 2,
			})

			core.MakePermanent(warlock.GetOrRegisterAura(core.Aura{
				Label: "Shadow Spark",
				OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if spell.SpellCode == SpellCode_WarlockShadowCleave && result.Landed() {
						warlock.shadowSparkAura.Activate(sim)
						warlock.shadowSparkAura.AddStack(sim)
					}
				},
			}))
		},
	},
})
View Source
var ItemSetWarlordsThreads = core.NewItemSet(core.ItemSet{
	Name: "Warlord's Threads",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.Stamina, 20)
		},

		3: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			warlock.GetOrRegisterAura(core.Aura{
				Label: "Immolate Cast Time Reduction",
				OnInit: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.Immolate {
						spell.DefaultCast.CastTime -= time.Millisecond * 200
					}
				},
			})
		},

		6: func(agent core.Agent) {
			c := agent.GetCharacter()
			c.AddStat(stats.SpellPower, 23)
		},
	},
})
View Source
var ItemSetWickedFelheart = core.NewItemSet(core.ItemSet{
	Name: "Wicked Felheart",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {

		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()
			actionID := core.ActionID{SpellID: 457572}
			icd := core.Cooldown{
				Timer:    warlock.NewTimer(),
				Duration: time.Millisecond * 3500,
			}
			manaMetrics := warlock.NewManaMetrics(actionID)
			for _, pet := range warlock.BasePets {
				pet.T1Tank4PManaMetrics = pet.NewManaMetrics(actionID)
			}
			warlock.RegisterAura(core.Aura{
				Label:    "S03 - Item - T1 - Warlock - Tank 4P Bonus",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
				},
				OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if icd.IsReady(sim) {
						restoreAmount := min(result.Damage, 420)
						warlock.AddMana(sim, restoreAmount, manaMetrics)
						if warlock.ActivePet != nil {
							warlock.ActivePet.AddMana(sim, restoreAmount, warlock.ActivePet.T1Tank4PManaMetrics)
						}
					}
				},
			})
		},

		6: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			soulFireCastTime := SoulFireCastTime
			procAura := warlock.RegisterAura(core.Aura{
				ActionID: core.ActionID{SpellID: 457643},
				Label:    "Soul Fire!",
				Duration: time.Second * 10,
				OnGain: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.SoulFire {
						spell.DefaultCast.CastTime = 0
					}
				},
				OnExpire: func(aura *core.Aura, sim *core.Simulation) {
					for _, spell := range warlock.SoulFire {
						spell.DefaultCast.CastTime = soulFireCastTime
					}
				},
				OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) {
					if spell.SpellCode == SpellCode_WarlockSoulFire {
						aura.Deactivate(sim)
					}
				},
			})

			icd := core.Cooldown{
				Timer:    warlock.NewTimer(),
				Duration: time.Millisecond * 100,
			}

			warlock.RegisterAura(core.Aura{
				Label:    "S03 - Item - T1 - Warlock - Tank 6P Bonus",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
					soulFireCastTime = warlock.SoulFire[0].DefaultCast.CastTime
				},
				OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if result.Landed() && spell.SpellCode == SpellCode_WarlockShadowCleave && icd.IsReady(sim) && sim.Proc(0.2, "Soul Fire! Proc") {
						procAura.Activate(sim)
						icd.Use(sim)
					}
				},
			})
		},
	},
})
View Source
var ItemSetWickedNemesis = core.NewItemSet(core.ItemSet{
	Name: "Wicked Nemesis",
	Bonuses: map[int32]core.ApplyEffect{

		2: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			var healthMetrics [LifeTapRanks + 1]*core.ResourceMetrics

			for i, spellId := range LifeTapSpellId {
				healthMetrics[i] = warlock.NewHealthMetrics(core.ActionID{SpellID: spellId})
			}

			warlock.RegisterAura(core.Aura{
				Label:    "S03 - Item - T2 - Warlock - Tank 2P Bonus",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
				},
				OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if spell.SpellCode == SpellCode_WarlockLifeTap {
						warlock.GainHealth(sim, result.Damage, healthMetrics[spell.Rank])
					}
				},
				OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) {
					if spell.SpellCode == SpellCode_WarlockLifeTap && warlock.CurrentTarget != nil {

						spell.Flags &= ^core.SpellFlagBinary
						spell.DamageMultiplier /= 2
						var damageResult = spell.CalcDamage(sim, warlock.CurrentTarget, LifeTapBaseDamage[spell.Rank], spell.OutcomeMagicHit)
						spell.DealDamage(sim, damageResult)
						spell.DamageMultiplier *= 2
						spell.Flags |= core.SpellFlagBinary
					}
				},
			},
			)
		},

		4: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			healingSpell := warlock.GetOrRegisterSpell(core.SpellConfig{
				ActionID:    core.ActionID{SpellID: 468062},
				SpellSchool: core.SpellSchoolPhysical,
				ProcMask:    core.ProcMaskSpellHealing,
				Flags:       core.SpellFlagPassiveSpell | core.SpellFlagHelpful,

				DamageMultiplier: 1,
				ThreatMultiplier: 0,
			})

			warlock.RegisterAura(core.Aura{
				Label:    "S03 - Item - T2 - Warlock - Tank 4P Bonus",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
				},
				OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if spell.SpellCode == SpellCode_WarlockShadowburn && result.Landed() {
						healAmount := warlock.MaxHealth() * 0.15
						healingSpell.CalcAndDealHealing(sim, healingSpell.Unit, healAmount, healingSpell.OutcomeHealing)
					}
				},
			})
		},

		6: func(agent core.Agent) {
			warlock := agent.(WarlockAgent).GetWarlock()

			shieldIncreaseAmount := 0.0
			currentShieldAmount := 0.0

			shieldSpell := warlock.GetOrRegisterSpell(core.SpellConfig{
				ActionID:    core.ActionID{SpellID: 470279},
				ProcMask:    core.ProcMaskSpellHealing,
				SpellSchool: core.SpellSchoolShadow,
				Flags:       core.SpellFlagPassiveSpell,

				DamageMultiplier: 1,
				ThreatMultiplier: 1,

				Shield: core.ShieldConfig{
					SelfOnly: true,
					Aura: core.Aura{
						Label:    "Demonic Aegis",
						Duration: 12 * time.Second,
					},
				},

				ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
					spell.SelfShield().Apply(sim, currentShieldAmount)
				},
			})

			warlock.RegisterAura(core.Aura{
				Duration: core.NeverExpires,
				Label:    "S03 - Item - T2 - Warlock - Tank 6P Bonus",

				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					shieldIncreaseAmount = 0.0
					currentShieldAmount = 0.0
					aura.Activate(sim)
				},
				OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if currentShieldAmount <= 0 || result.Damage <= 0 || spell.SpellCode == SpellCode_WarlockLifeTap {
						return
					}

					damageAbsorbed := min(result.Damage, currentShieldAmount)
					currentShieldAmount -= damageAbsorbed

					warlock.GainHealth(sim, damageAbsorbed, shieldSpell.HealthMetrics(result.Target))

					if currentShieldAmount <= 0 {
						currentShieldAmount = 0
						shieldSpell.SelfShield().Deactivate(sim)
					}
				},
				OnHealDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					shieldIncreaseAmount = result.Damage + warlock.CurrentHealth() - warlock.MaxHealth()
					if shieldIncreaseAmount > 0 {
						currentShieldAmount += shieldIncreaseAmount
						currentShieldAmount = min(warlock.MaxHealth()*0.30, currentShieldAmount)
						shieldSpell.Cast(sim, result.Target)
					}
				},
			})
		},
	},
})
View Source
var LifeTapBaseDamage = [LifeTapRanks + 1]float64{0, 30, 75, 140, 220, 310, 424}
View Source
var LifeTapSpellId = [LifeTapRanks + 1]int32{0, 1454, 1455, 1456, 11687, 11688, 11689}
View Source
var TalentTreeSizes = [3]int{17, 17, 16}

Functions

This section is empty.

Types

type APLValueWarlockCurrentPetMana added in v0.0.6

type APLValueWarlockCurrentPetMana struct {
	core.DefaultAPLValueImpl
	// contains filtered or unexported fields
}

func (*APLValueWarlockCurrentPetMana) GetFloat added in v0.0.6

func (value *APLValueWarlockCurrentPetMana) GetFloat(sim *core.Simulation) float64

func (*APLValueWarlockCurrentPetMana) String added in v0.0.6

func (value *APLValueWarlockCurrentPetMana) String() string

func (*APLValueWarlockCurrentPetMana) Type added in v0.0.6

type APLValueWarlockCurrentPetManaPercent added in v0.0.6

type APLValueWarlockCurrentPetManaPercent struct {
	core.DefaultAPLValueImpl
	// contains filtered or unexported fields
}

func (*APLValueWarlockCurrentPetManaPercent) GetFloat added in v0.0.6

func (*APLValueWarlockCurrentPetManaPercent) String added in v0.0.6

func (*APLValueWarlockCurrentPetManaPercent) Type added in v0.0.6

type APLValueWarlockPetIsActive added in v0.0.25

type APLValueWarlockPetIsActive struct {
	core.DefaultAPLValueImpl
	// contains filtered or unexported fields
}

func (*APLValueWarlockPetIsActive) GetBool added in v0.0.25

func (value *APLValueWarlockPetIsActive) GetBool(sim *core.Simulation) bool

func (*APLValueWarlockPetIsActive) String added in v0.0.25

func (value *APLValueWarlockPetIsActive) String() string

func (*APLValueWarlockPetIsActive) Type added in v0.0.25

type APLValueWarlockShouldRecastDrainSoul

type APLValueWarlockShouldRecastDrainSoul struct {
	core.DefaultAPLValueImpl
	// contains filtered or unexported fields
}

func (*APLValueWarlockShouldRecastDrainSoul) GetBool

func (*APLValueWarlockShouldRecastDrainSoul) String

func (*APLValueWarlockShouldRecastDrainSoul) Type

type APLValueWarlockShouldRefreshCorruption

type APLValueWarlockShouldRefreshCorruption struct {
	core.DefaultAPLValueImpl
	// contains filtered or unexported fields
}

func (*APLValueWarlockShouldRefreshCorruption) GetBool

func (*APLValueWarlockShouldRefreshCorruption) String

func (*APLValueWarlockShouldRefreshCorruption) Type

type PetConfig added in v0.0.16

type PetConfig struct {
	Name          string
	PowerModifier float64 // GetUnitPowerModifier("pet")
	Stats         stats.Stats
	AutoAttacks   core.AutoAttackOptions
}

type Warlock

type Warlock struct {
	core.Character
	Talents *proto.WarlockTalents
	Options *proto.WarlockOptions

	BasePets   []*WarlockPet
	ActivePet  *WarlockPet
	Felhunter  *WarlockPet
	Felguard   *WarlockPet
	Imp        *WarlockPet
	Succubus   *WarlockPet
	Voidwalker *WarlockPet

	ChaosBolt          *core.Spell
	Conflagrate        []*core.Spell
	Corruption         []*core.Spell
	DarkPact           *core.Spell
	DrainSoul          []*core.Spell
	Haunt              *core.Spell
	Immolate           []*core.Spell
	Incinerate         *core.Spell
	LifeTap            []*core.Spell
	SearingPain        []*core.Spell
	ShadowBolt         []*core.Spell
	ShadowCleave       []*core.Spell
	Shadowburn         []*core.Spell
	SoulFire           []*core.Spell
	DemonicGrace       *core.Spell
	DrainLife          []*core.Spell
	RainOfFire         []*core.Spell
	SiphonLife         []*core.Spell
	DeathCoil          []*core.Spell
	Shadowflame        *core.Spell
	UnstableAffliction *core.Spell

	ActiveCurseAura          core.AuraArray
	CurseOfElements          *core.Spell
	CurseOfElementsAuras     core.AuraArray
	CurseOfShadow            *core.Spell
	CurseOfShadowAuras       core.AuraArray
	CurseOfRecklessness      *core.Spell
	CurseOfRecklessnessAuras core.AuraArray
	CurseOfWeakness          *core.Spell
	CurseOfWeaknessAuras     core.AuraArray
	CurseOfTongues           *core.Spell
	CurseOfTonguesAuras      core.AuraArray
	CurseOfAgony             []*core.Spell
	CurseOfDoom              *core.Spell
	AmplifyCurse             *core.Spell

	// Track all DoT spells for effecrs that add multipliers based on active effects
	DoTSpells         []*core.Spell
	DebuffSpells      []*core.Spell
	SummonDemonSpells []*core.Spell

	DemonicKnowledgeAura    *core.Aura
	HauntDebuffAuras        core.AuraArray
	ImmolationAura          *core.Spell
	IncinerateAura          *core.Aura
	Metamorphosis           *core.Spell
	MetamorphosisAura       *core.Aura
	ShadowTranceAura        *core.Aura
	PyroclasmAura           *core.Aura
	DemonicGraceAura        *core.Aura
	AmplifyCurseAura        *core.Aura
	BackdraftAura           *core.Aura
	ImprovedShadowBoltAuras core.AuraArray
	MarkOfChaosAuras        core.AuraArray
	SoulLinkAura            *core.Aura
	DecimationAura          *core.Aura
	MasterDemonologistAura  *core.Aura

	// The sum total of demonic pact spell power * seconds.
	DPSPAggregate float64
	// contains filtered or unexported fields
}

func NewWarlock

func NewWarlock(character *core.Character, options *proto.Player, warlockOptions *proto.WarlockOptions) *Warlock

func (*Warlock) AddRaidBuffs

func (warlock *Warlock) AddRaidBuffs(raidBuffs *proto.RaidBuffs)

func (*Warlock) ApplyRunes

func (warlock *Warlock) ApplyRunes()

func (*Warlock) ApplyTalents

func (warlock *Warlock) ApplyTalents()

func (*Warlock) GetCharacter

func (warlock *Warlock) GetCharacter() *core.Character

func (*Warlock) GetWarlock

func (warlock *Warlock) GetWarlock() *Warlock

func (*Warlock) HasRune

func (warlock *Warlock) HasRune(rune proto.WarlockRune) bool

func (*Warlock) Initialize

func (warlock *Warlock) Initialize()

func (*Warlock) InvocationRefresh

func (warlock *Warlock) InvocationRefresh(sim *core.Simulation, dot *core.Dot)

func (*Warlock) NewAPLValue

func (warlock *Warlock) NewAPLValue(rot *core.APLRotation, config *proto.APLValue) core.APLValue

func (*Warlock) OnGCDReady

func (warlock *Warlock) OnGCDReady(_ *core.Simulation)

func (*Warlock) Reset

func (warlock *Warlock) Reset(sim *core.Simulation)

type WarlockAgent

type WarlockAgent interface {
	GetWarlock() *Warlock
}

Agent is a generic way to access underlying warlock on any of the agents.

type WarlockPet

type WarlockPet struct {
	core.Pet

	SoulLinkAura           *core.Aura
	DemonicEmpowermentAura *core.Aura

	DanceOfTheWickedManaMetrics *core.ResourceMetrics
	LifeTapManaMetrics          *core.ResourceMetrics
	T1Tank4PManaMetrics         *core.ResourceMetrics // https://www.wowhead.com/classic/spell=457572/s03-item-t1-warlock-tank-4p-bonus
	// contains filtered or unexported fields
}

func (*WarlockPet) ExecuteCustomRotation

func (wp *WarlockPet) ExecuteCustomRotation(sim *core.Simulation)

func (*WarlockPet) GetPet

func (wp *WarlockPet) GetPet() *core.Pet

func (*WarlockPet) Initialize

func (wp *WarlockPet) Initialize()

func (*WarlockPet) Reset

func (wp *WarlockPet) Reset(_ *core.Simulation)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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