warrior

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2025 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SpellMaskNone int64 = 0
	// Abilities that don't cost rage and aren't attacks
	SpellMaskBattleShout int64 = 1 << iota
	SpellMaskCommandingShout
	SpellMaskBerserkerRage
	SpellMaskRallyingCry
	SpellMaskRecklessness
	SpellMaskShieldWall
	SpellMaskLastStand
	SpellMaskCharge
	SpellMaskSkullBanner
	SpellMaskDemoralizingBanner
	SpellMaskAvatar
	SpellMaskDemoralizingShout

	// Special attacks
	SpellMaskSweepingStrikes
	SpellMaskSweepingStrikesHit
	SpellMaskCleave
	SpellMaskColossusSmash
	SpellMaskExecute
	SpellMaskHeroicStrike
	SpellMaskHeroicThrow
	SpellMaskOverpower
	SpellMaskRevenge
	SpellMaskShatteringThrow
	SpellMaskSlam
	SpellMaskSunderArmor
	SpellMaskThunderClap
	SpellMaskWhirlwind
	SpellMaskWhirlwindOh
	SpellMaskShieldBarrier
	SpellMaskShieldSlam
	SpellMaskDevastate
	SpellMaskBloodthirst
	SpellMaskRagingBlow
	SpellMaskRagingBlowMH
	SpellMaskRagingBlowOH
	SpellMaskMortalStrike
	SpellMaskHeroicLeap
	SpellMaskWildStrike
	SpellMaskShieldBlock

	// Talents
	SpellMaskImpendingVictory
	SpellMaskBladestorm
	SpellMaskBladestormMH
	SpellMaskBladestormOH
	SpellMaskDragonRoar
	SpellMaskBloodbath
	SpellMaskBloodbathDot
	SpellMaskStormBolt
	SpellMaskStormBoltOH
	SpellMaskShockwave

	SpellMaskShouts = SpellMaskCommandingShout | SpellMaskBattleShout
)
View Source
const EnrageTag = "EnrageEffect"
View Source
const ShoutExpirationThreshold = time.Second * 3
View Source
const (
	SpellFlagBleed = core.SpellFlagAgentReserved1
)

Variables

View Source
var ItemSetBattleplateOfResoundingRings = core.NewItemSet(core.ItemSet{
	Name: "Battleplate of Resounding Rings",
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {
			setBonusAura.AttachSpellMod(core.SpellModConfig{
				ClassMask:  SpellMaskMortalStrike | SpellMaskBloodthirst,
				Kind:       core.SpellMod_DamageDone_Pct,
				FloatValue: 0.25,
			})

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

			setBonusAura.ExposeToAPL(123144)
		},
	},
})

T14 - DPS

View Source
var ItemSetBattleplateOfTheLastMogu = core.NewItemSet(core.ItemSet{
	Name: "Battleplate of the Last Mogu",
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()

			core.MakeProcTriggerAura(&war.Unit, core.ProcTrigger{
				Name:     "Item - Warrior T15 DPS 2P Bonus",
				ActionID: core.ActionID{SpellID: 138120},
				ICD:      250 * time.Millisecond,
				DPM: war.NewSetBonusRPPMProcManager(138120, setBonusAura, core.ProcMaskMeleeWhiteHit, core.RPPMConfig{
					PPM: 1.1,
				}.WithSpecMod(-0.625, proto.Spec_SpecFuryWarrior)),
				Outcome:  core.OutcomeHit,
				Callback: core.CallbackOnSpellHitDealt,
				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					war.EnrageAura.Deactivate(sim)
					war.EnrageAura.Activate(sim)
				},
			})
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()

			aura := war.RegisterAura(core.Aura{
				Label:    "Skull Banner - T15 4P Bonus",
				ActionID: core.ActionID{SpellID: 138127},
				Duration: 10 * time.Second,
			}).AttachSpellMod(core.SpellModConfig{
				Kind:       core.SpellMod_BonusCrit_Percent,
				FloatValue: 35,
			})

			war.OnSpellRegistered(func(spell *core.Spell) {
				if !spell.Matches(SpellMaskSkullBanner) {
					return
				}

				war.SkullBannerAura.AttachDependentAura(aura)
			})

			setBonusAura.ExposeToAPL(138126)
		},
	},
})

T15 - DPS

View Source
var ItemSetBattleplateOfThePrehistoricMarauder = core.NewItemSet(core.ItemSet{
	Name: "Battleplate of the Prehistoric Marauder",
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()
			actionID := core.ActionID{SpellID: 144438}
			rageMetrics := war.NewRageMetrics(actionID)

			core.MakeProcTriggerAura(&war.Unit, core.ProcTrigger{
				Name:     "Colossal Rage",
				ActionID: actionID,
				ProcMask: core.ProcMaskMeleeSpecial,
				Outcome:  core.OutcomeHit,
				Callback: core.CallbackOnSpellHitDealt,
				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if war.ColossusSmashAuras.Get(result.Target).IsActive() {
						war.AddRage(sim, 5, rageMetrics)
					}
				},
			})

			setBonusAura.ExposeToAPL(144436)
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()

			costMod := war.AddDynamicMod(core.SpellModConfig{
				ClassMask: SpellMaskExecute,
				Kind:      core.SpellMod_PowerCost_Flat,
				IntValue:  -30,
			})

			war.T16Dps4P = war.RegisterAura(core.Aura{
				Label:    "Death Sentence",
				ActionID: core.ActionID{SpellID: 144442},
				Duration: 12 * time.Second,
			}).ApplyOnGain(func(aura *core.Aura, sim *core.Simulation) {
				if sim.IsExecutePhase20() {
					costMod.Activate()
				}
			}).ApplyOnExpire(func(aura *core.Aura, sim *core.Simulation) {
				costMod.Deactivate()
			})

			core.MakeProcTriggerAura(&war.Unit, core.ProcTrigger{
				Name:           "Death Sentence - Consume",
				ClassSpellMask: SpellMaskExecute,
				Callback:       core.CallbackOnCastComplete,
				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					war.T16Dps4P.Deactivate(sim)
				},
			})

			core.MakeProcTriggerAura(&war.Unit, core.ProcTrigger{
				Name:           "Death Sentence - Trigger",
				ActionID:       core.ActionID{SpellID: 144442},
				ClassSpellMask: SpellMaskMortalStrike | SpellMaskBloodthirst,
				Outcome:        core.OutcomeHit,
				ProcChance:     0.1,
				Callback:       core.CallbackOnSpellHitDealt,
				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					war.T16Dps4P.Activate(sim)
				},
			})

			setBonusAura.ExposeToAPL(144441)
		},
	},
})

T16 - DPS

View Source
var ItemSetPlaceOfTheLastMogu = core.NewItemSet(core.ItemSet{
	Name: "Plate of the Last Mogu",
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()
			war.T15Tank2P = core.MakeProcTriggerAura(&war.Unit, core.ProcTrigger{
				Name:           "Victorious -  T15 Protection 2P Bonus",
				ActionID:       core.ActionID{SpellID: 138279},
				ClassSpellMask: SpellMaskRevenge | SpellMaskShieldSlam,
				ProcChance:     0.1,
				Outcome:        core.OutcomeHit,
				Callback:       core.CallbackOnSpellHitDealt,
				Duration:       15 * time.Second,
				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					war.VictoryRushAura.Activate(sim)
				},
			})

			setBonusAura.ExposeToAPL(138280)
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()
			war.T15Tank4P = setBonusAura

			setBonusAura.ExposeToAPL(138281)
		},
	},
})

T15 - Tank

View Source
var ItemSetPlateOfResoundingRings = core.NewItemSet(core.ItemSet{
	Name: "Plate of Resounding Rings",
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {
			setBonusAura.AttachSpellMod(core.SpellModConfig{
				ClassMask: SpellMaskLastStand,
				Kind:      core.SpellMod_Cooldown_Flat,
				TimeValue: -60 * time.Second,
			})

			setBonusAura.ExposeToAPL(123146)
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()

			war.T14Tank2P = setBonusAura

			setBonusAura.AttachSpellMod(core.SpellModConfig{
				ClassMask: SpellMaskShieldBlock,
				Kind:      core.SpellMod_PowerCost_Flat,
				IntValue:  -5,
			})

			setBonusAura.ExposeToAPL(123147)
		},
	},
})

T14 - Tank

View Source
var ItemSetPlateOfThePrehistoricMarauder = core.NewItemSet(core.ItemSet{
	Name: "Plate of the Prehistoric Marauder",
	Bonuses: map[int32]core.ApplySetBonus{
		2: func(agent core.Agent, setBonusAura *core.Aura) {

			war := agent.(WarriorAgent).GetWarrior()
			healthMetrics := war.NewHealthMetrics(core.ActionID{SpellID: 144503})

			war.OnSpellRegistered(func(spell *core.Spell) {
				if !spell.Matches(SpellMaskShieldBarrier) {
					return
				}

				war.ShieldBarrierAura.Aura.ApplyOnStacksChange(func(aura *core.Aura, sim *core.Simulation, oldStacks int32, newStacks int32) {
					if setBonusAura.IsActive() {
						absorbLoss := float64(oldStacks - newStacks)
						war.GainHealth(sim, absorbLoss*0.3, healthMetrics)
					}
				})
			})

			setBonusAura.AttachProcTrigger(core.ProcTrigger{
				Name:     "Item - Warrior T16 Tank 2P Bonus",
				Callback: core.CallbackOnSpellHitTaken,
				Outcome:  core.OutcomeBlock,
				Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					blockDamageReduction := result.Target.BlockDamageReduction()
					preBlockDamage := result.Damage / (1 - blockDamageReduction) * blockDamageReduction
					blockedDamage := result.Damage - preBlockDamage
					war.GainHealth(sim, blockedDamage*0.3, healthMetrics)
				},
			})

			setBonusAura.ExposeToAPL(144503)
		},
		4: func(agent core.Agent, setBonusAura *core.Aura) {
			war := agent.(WarriorAgent).GetWarrior()
			actionID := core.ActionID{SpellID: 144500}
			rageMetrics := war.NewRageMetrics(actionID)

			aura := war.RegisterAura(core.Aura{
				Label:    "Reckless Defense",
				ActionID: actionID,
				Duration: 10 * time.Second,
			})

			for _, aura := range war.DemoralizingShoutAuras {
				aura.ApplyOnExpire(func(aura *core.Aura, sim *core.Simulation) {
					if setBonusAura.IsActive() {
						aura.Activate(sim)
					}
				})
			}

			war.AddDynamicDamageTakenModifier(func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult, isPeriodic bool) {
				if aura.IsActive() {
					war.AddRage(sim, result.Damage/war.MaxHealth()*100, rageMetrics)
				}
			})

			setBonusAura.ExposeToAPL(144502)
		},
	},
})

T16 - Tank

Functions

This section is empty.

Types

type RageMultiplierCB

type RageMultiplierCB func() float64

Rather than update a variable somewhere for one effect (Fury's Unshackled Fury) just take a callback to fetch its multiplier when needed

type Stance

type Stance uint8
const (
	StanceNone          = 0
	BattleStance Stance = 1 << iota
	DefensiveStance
	BerserkerStance
)

type Warrior

type Warrior struct {
	core.Character

	ClassSpellScaling float64

	Talents *proto.WarriorTalents

	WarriorInputs

	// Current state
	Stance              Stance
	CriticalBlockChance []float64 // Can be gained as non-prot via certain talents and spells

	BattleShout     *core.Spell
	CommandingShout *core.Spell
	BattleStance    *core.Spell
	DefensiveStance *core.Spell
	BerserkerStance *core.Spell

	ColossusSmash *core.Spell
	MortalStrike  *core.Spell
	DeepWounds    *core.Spell
	ShieldSlam    *core.Spell

	BattleStanceAura    *core.Aura
	DefensiveStanceAura *core.Aura
	BerserkerStanceAura *core.Aura

	EnrageAura        *core.Aura
	BerserkerRageAura *core.Aura
	ShieldBlockAura   *core.Aura
	LastStandAura     *core.Aura
	RallyingCryAura   *core.Aura
	VictoryRushAura   *core.Aura
	SwordAndBoardAura *core.Aura
	ShieldBarrierAura *core.DamageAbsorptionAura

	SkullBannerAura         *core.Aura
	DemoralizingBannerAuras core.AuraArray

	DemoralizingShoutAuras core.AuraArray
	SunderArmorAuras       core.AuraArray
	ThunderClapAuras       core.AuraArray
	ColossusSmashAuras     core.AuraArray
	WeakenedArmorAuras     core.AuraArray

	// Set Bonuses
	T14Tank2P *core.Aura
	T15Tank2P *core.Aura
	T15Tank4P *core.Aura
	T16Dps4P  *core.Aura
	// contains filtered or unexported fields
}

func NewWarrior

func NewWarrior(character *core.Character, options *proto.WarriorOptions, talents string, inputs WarriorInputs) *Warrior

func (*Warrior) AddPartyBuffs

func (warrior *Warrior) AddPartyBuffs(_ *proto.PartyBuffs)

func (*Warrior) AddRaidBuffs

func (warrior *Warrior) AddRaidBuffs(raidBuffs *proto.RaidBuffs)

func (*Warrior) ApplyGlyphs

func (war *Warrior) ApplyGlyphs()

func (*Warrior) ApplyTalents

func (warrior *Warrior) ApplyTalents()

func (*Warrior) CanApplySunderAura

func (warrior *Warrior) CanApplySunderAura(target *core.Unit) bool

func (*Warrior) GetCharacter

func (warrior *Warrior) GetCharacter() *core.Character

func (*Warrior) GetCriticalBlockChance

func (warrior *Warrior) GetCriticalBlockChance() float64

func (*Warrior) GetRageMultiplier

func (warrior *Warrior) GetRageMultiplier(target *core.Unit) float64

Used for T15 Protection 4P bonus.

func (*Warrior) HasMajorGlyph

func (warrior *Warrior) HasMajorGlyph(glyph proto.WarriorMajorGlyph) bool

func (*Warrior) HasMinorGlyph

func (warrior *Warrior) HasMinorGlyph(glyph proto.WarriorMinorGlyph) bool

func (*Warrior) Initialize

func (warrior *Warrior) Initialize()

func (*Warrior) MakeShoutSpellHelper

func (warrior *Warrior) MakeShoutSpellHelper(actionID core.ActionID, spellMask int64, allyAuras core.AuraArray) *core.Spell

func (*Warrior) Reset

func (warrior *Warrior) Reset(_ *core.Simulation)

func (*Warrior) StanceMatches

func (warrior *Warrior) StanceMatches(other Stance) bool

func (*Warrior) TryApplySunderArmorEffect

func (warrior *Warrior) TryApplySunderArmorEffect(sim *core.Simulation, target *core.Unit)

type WarriorAgent

type WarriorAgent interface {
	GetWarrior() *Warrior
}

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

type WarriorInputs

type WarriorInputs struct {
	StanceSnapshot bool
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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