Documentation ¶
Index ¶
- Constants
- Variables
- type RageMultiplierCB
- type SpellEffectWeaponDmgPctConfig
- type Stance
- type Warrior
- func (warrior *Warrior) AddPartyBuffs(_ *proto.PartyBuffs)
- func (warrior *Warrior) AddRaidBuffs(raidBuffs *proto.RaidBuffs)
- func (warrior *Warrior) ApplyCommonTalents()
- func (warrior *Warrior) ApplyGlyphs()
- func (warrior *Warrior) CanApplySunderAura(target *core.Unit) bool
- func (warrior *Warrior) GetCharacter() *core.Character
- func (warrior *Warrior) GetCriticalBlockChance() float64
- func (warrior *Warrior) HasMajorGlyph(glyph proto.WarriorMajorGlyph) bool
- func (warrior *Warrior) HasMinorGlyph(glyph proto.WarriorMinorGlyph) bool
- func (warrior *Warrior) HasPrimeGlyph(glyph proto.WarriorPrimeGlyph) bool
- func (warrior *Warrior) Initialize()
- func (warrior *Warrior) IntensifyRageCooldown(baseCd time.Duration) time.Duration
- func (warrior *Warrior) MakeShoutSpellHelper(actionID core.ActionID, spellMask int64, allyAuras core.AuraArray) *core.Spell
- func (warrior *Warrior) RecklessnessDeadlyCalmLock() *core.Timer
- func (warrior *Warrior) RegisterBerserkerRageSpell()
- func (warrior *Warrior) RegisterCharge()
- func (warrior *Warrior) RegisterCleaveSpell()
- func (warrior *Warrior) RegisterColossusSmash()
- func (warrior *Warrior) RegisterDeepWounds()
- func (warrior *Warrior) RegisterDemoralizingShoutSpell()
- func (warrior *Warrior) RegisterExecuteSpell()
- func (warrior *Warrior) RegisterHeroicLeap()
- func (warrior *Warrior) RegisterHeroicStrikeSpell()
- func (warrior *Warrior) RegisterHeroicThrow()
- func (warrior *Warrior) RegisterInnerRage()
- func (warrior *Warrior) RegisterOverpowerSpell()
- func (warrior *Warrior) RegisterRecklessnessCD()
- func (warrior *Warrior) RegisterRendSpell()
- func (warrior *Warrior) RegisterRevengeSpell()
- func (warrior *Warrior) RegisterShatteringThrowCD()
- func (warrior *Warrior) RegisterShieldBlockCD()
- func (warrior *Warrior) RegisterShieldWallCD()
- func (warrior *Warrior) RegisterShouts()
- func (warrior *Warrior) RegisterSlamSpell()
- func (warrior *Warrior) RegisterSunderArmor() *core.Spell
- func (warrior *Warrior) RegisterThunderClapSpell()
- func (warrior *Warrior) RegisterWhirlwindSpell()
- func (warrior *Warrior) Reset(_ *core.Simulation)
- func (warrior *Warrior) StanceMatches(other Stance) bool
- func (warrior *Warrior) TryApplySunderArmorEffect(sim *core.Simulation, target *core.Unit)
- type WarriorAgent
- type WarriorInputs
Constants ¶
const ( SpellFlagBleed = core.SpellFlagAgentReserved1 ArmsTree = 0 FuryTree = 1 ProtTree = 2 )
const ( SpellMaskSpecialAttack int64 = 1 << iota // Abilities that don't cost rage and aren't attacks SpellMaskBattleShout SpellMaskBerserkerRage SpellMaskCommandingShout SpellMaskRecklessness SpellMaskShieldWall SpellMaskLastStand SpellMaskDeadlyCalm SpellMaskCharge // Abilities that cost rage but aren't attacks SpellMaskDemoShout SpellMaskInnerRage SpellMaskShieldBlock SpellMaskDeathWish SpellMaskSweepingStrikes // Special attacks SpellMaskCleave SpellMaskColossusSmash SpellMaskExecute SpellMaskHeroicStrike SpellMaskHeroicThrow SpellMaskOverpower SpellMaskRend SpellMaskRevenge SpellMaskShatteringThrow SpellMaskSlam SpellMaskSunderArmor SpellMaskThunderClap SpellMaskWhirlwind SpellMaskWhirlwindOh SpellMaskShieldSlam SpellMaskConcussionBlow SpellMaskDevastate SpellMaskShockwave SpellMaskVictoryRush SpellMaskBloodthirst SpellMaskRagingBlow SpellMaskMortalStrike SpellMaskBladestorm SpellMaskHeroicLeap SpellMaskShouts = SpellMaskCommandingShout | SpellMaskBattleShout )
const EnableOverpowerTag = "EnableOverpower"
const EnrageTag = "EnrageEffect"
const InnerRageExclusionTag = "InnerRageDeadlyCalm"
const ShoutExpirationThreshold = time.Second * 3
const SpellMaskNone int64 = 0
Variables ¶
var ItemSetColossalDragonplateArmor = core.NewItemSet(core.ItemSet{ Name: "Colossal Dragonplate Armor", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { character := agent.GetCharacter() actionID := core.ActionID{SpellID: 105909} shieldAura := character.RegisterAura(core.Aura{ Label: "Shield of Fury", ActionID: actionID, Duration: 6 * time.Second, OnGain: func(aura *core.Aura, sim *core.Simulation) { }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { }, }) core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ Name: "Shield of Fury Trigger", ActionID: actionID, Callback: core.CallbackOnSpellHitDealt, ClassSpellMask: SpellMaskRevenge, Outcome: core.OutcomeLanded, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { shieldAura.Activate(sim) }, }) }, 4: func(agent core.Agent) { }, }, })
var ItemSetColossalDragonplateBattlegear = core.NewItemSet(core.ItemSet{ Name: "Colossal Dragonplate Battlegear", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { character := agent.GetCharacter() mod := character.AddDynamicMod(core.SpellModConfig{ ClassMask: SpellMaskHeroicStrike, Kind: core.SpellMod_PowerCost_Flat, FloatValue: -10, }) actionID := core.ActionID{SpellID: 105860} buffAura := character.RegisterAura(core.Aura{ Label: "Volatile Outrage", ActionID: actionID, Duration: 15 * time.Second, OnGain: func(aura *core.Aura, sim *core.Simulation) { mod.Activate() }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { mod.Deactivate() }, }) core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ Name: "Volatile Outrage Trigger", ActionID: actionID, Callback: core.CallbackOnCastComplete, ClassSpellMask: SpellMaskInnerRage, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { buffAura.Activate(sim) }, }) }, 4: func(agent core.Agent) { warrior := agent.(WarriorAgent).GetWarrior() actionID := core.ActionID{SpellID: 108126} procCS := warrior.RegisterSpell(core.SpellConfig{ ActionID: actionID, SpellSchool: core.SpellSchoolPhysical, Flags: core.SpellFlagNoOnDamageDealt | core.SpellFlagNoOnCastComplete, Cast: core.CastConfig{ DefaultCast: core.Cast{ GCD: 0, }, }, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { warrior.ColossusSmashAuras.Get(target).Activate(sim) }, }) core.MakeProcTriggerAura(&warrior.Unit, core.ProcTrigger{ Name: "Warrior T13 4P Bloodthirst Trigger", ActionID: actionID, Callback: core.CallbackOnSpellHitDealt, ClassSpellMask: SpellMaskBloodthirst, ProcChance: 0.06, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { procCS.Cast(sim, result.Target) }, }) core.MakeProcTriggerAura(&warrior.Unit, core.ProcTrigger{ Name: "Warrior T13 4P Mortal Strike Trigger", ActionID: actionID, Callback: core.CallbackOnSpellHitDealt, ClassSpellMask: SpellMaskMortalStrike, ProcChance: 0.13, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { procCS.Cast(sim, result.Target) }, }) }, }, })
var ItemSetEarthenBattleplate = core.NewItemSet(core.ItemSet{ Name: "Earthen Battleplate", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { agent.GetCharacter().AddStaticMod(core.SpellModConfig{ ClassMask: SpellMaskShieldSlam, Kind: core.SpellMod_DamageDone_Flat, FloatValue: 0.05, }) }, 4: func(agent core.Agent) { agent.GetCharacter().AddStaticMod(core.SpellModConfig{ ClassMask: SpellMaskShieldWall, Kind: core.SpellMod_Cooldown_Multiplier, FloatValue: -0.5, }) }, }, })
var ItemSetEarthenWarplate = core.NewItemSet(core.ItemSet{ Name: "Earthen Warplate", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { agent.GetCharacter().AddStaticMod(core.SpellModConfig{ ClassMask: SpellMaskBloodthirst | SpellMaskMortalStrike, Kind: core.SpellMod_DamageDone_Flat, FloatValue: 0.05, }) }, 4: func(agent core.Agent) { character := agent.GetCharacter() actionID := core.ActionID{SpellID: 90294} apDep := make([]*stats.StatDependency, 3) for i := 1; i <= 3; i++ { apDep[i-1] = character.NewDynamicMultiplyStat(stats.AttackPower, 1.0+float64(i)*0.01) } buff := character.RegisterAura(core.Aura{ Label: "Rage of the Ages", ActionID: actionID, Duration: 30 * time.Second, MaxStacks: 3, OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) { if oldStacks > 0 { character.DisableDynamicStatDep(sim, apDep[oldStacks-1]) } if newStacks > 0 { character.EnableDynamicStatDep(sim, apDep[newStacks-1]) } }, }) core.MakeProcTriggerAura(&agent.GetCharacter().Unit, core.ProcTrigger{ Name: "Rage of the Ages Trigger", ActionID: actionID, Callback: core.CallbackOnCastComplete, ClassSpellMask: SpellMaskOverpower | SpellMaskRagingBlow, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { buff.Activate(sim) buff.AddStack(sim) }, }) }, }, })
var ItemSetGladiatorsBattlegear = core.NewItemSet(core.ItemSet{ ID: 909, Name: "Gladiator's Battlegear", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { agent.GetCharacter().AddStats(stats.Stats{ stats.Strength: 70, }) }, 4: func(agent core.Agent) { agent.GetCharacter().AddStats(stats.Stats{ stats.Strength: 90, }) }, }, })
var ItemSetMoltenGiantBattleplate = core.NewItemSet(core.ItemSet{ Name: "Molten Giant Battleplate", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { character := agent.GetCharacter() actionID := core.ActionID{SpellID: 23922} // TODO (4.2): Test if this rolls damage over like deep wounds or just resets it var shieldSlamDamage float64 = 0.0 debuff := character.RegisterSpell(core.SpellConfig{ ActionID: actionID.WithTag(3), SpellSchool: core.SpellSchoolFire, ProcMask: core.ProcMaskEmpty, Flags: core.SpellFlagPassiveSpell, DamageMultiplier: 1, ThreatMultiplier: 1, Dot: core.DotConfig{ Aura: core.Aura{ Label: "Combust", }, NumberOfTicks: 2, TickLength: 2 * time.Second, OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, isRollover bool) { dot.Snapshot(target, shieldSlamDamage/float64(dot.BaseTickCount)) }, OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeTick) }, }, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { spell.Dot(target).Apply(sim) }, }) core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ Name: "Combust Trigger", ActionID: actionID, Callback: core.CallbackOnSpellHitDealt, ClassSpellMask: SpellMaskShieldSlam, Outcome: core.OutcomeLanded, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { shieldSlamDamage = result.Damage * 0.2 debuff.Cast(sim, result.Target) }, }) }, 4: func(agent core.Agent) { character := agent.GetCharacter() character.RegisterAura(core.Aura{ Label: "T12 4P Bonus", ActionID: core.ActionID{SpellID: 99242}, Duration: 10 * time.Second, OnGain: func(aura *core.Aura, sim *core.Simulation) { character.PseudoStats.BaseParryChance += 0.06 }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { character.PseudoStats.BaseParryChance -= 0.06 }, }) }, }, })
var ItemSetMoltenGiantWarplate = core.NewItemSet(core.ItemSet{ Name: "Molten Giant Warplate", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { character := agent.GetCharacter() actionID := core.ActionID{SpellID: 99233} warrior := agent.(WarriorAgent).GetWarrior() talentReduction := time.Duration(warrior.Talents.BoomingVoice*3) * time.Second buff := character.RegisterAura(core.Aura{ Label: "Burning Rage", ActionID: actionID, Duration: 12*time.Second - talentReduction, OnGain: func(aura *core.Aura, sim *core.Simulation) { character.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexPhysical] *= 1.1 }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { character.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexPhysical] /= 1.1 }, }) core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ Name: "Burning Rage Trigger", ActionID: actionID, ClassSpellMask: SpellMaskShouts, Callback: core.CallbackOnCastComplete, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { buff.Activate(sim) }, }) }, 4: func(agent core.Agent) { character := agent.GetCharacter() actionID := core.ActionID{SpellID: 99237} fieryAttackActionID := core.ActionID{} if character.Spec == proto.Spec_SpecArmsWarrior { fieryAttackActionID.SpellID = 12294 } if character.Spec == proto.Spec_SpecFuryWarrior { fieryAttackActionID.SpellID = 85288 } fieryAttack := character.RegisterSpell(core.SpellConfig{ ActionID: fieryAttackActionID.WithTag(3), SpellSchool: core.SpellSchoolFire, ProcMask: core.ProcMaskEmpty, Flags: core.SpellFlagMeleeMetrics | core.SpellFlagPassiveSpell, CritMultiplier: character.DefaultMeleeCritMultiplier(), DamageMultiplier: 1, ThreatMultiplier: 1, ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { baseDamage := spell.Unit.MHNormalizedWeaponDamage(sim, spell.MeleeAttackPower()) spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMagicCrit) }, }) core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{ Name: "Fiery Attack Trigger", ActionID: actionID, Callback: core.CallbackOnSpellHitDealt, ClassSpellMask: SpellMaskMortalStrike | SpellMaskRagingBlow, ProcChance: 0.3, Outcome: core.OutcomeLanded, Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { fieryAttack.Cast(sim, result.Target) }, }) }, }, })
var TalentTreeSizes = [3]int{20, 21, 20}
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 SpellEffectWeaponDmgPctConfig ¶
type SpellEffectWeaponDmgPctConfig struct { BaseWeapon_Pct float64 Coefficient float64 EffectPerLevel float64 BaseSpellLevel int32 MaxSpellLevel int32 ClassSpellScaling float64 }
func (*SpellEffectWeaponDmgPctConfig) CalcAddedSpellDamage ¶
func (config *SpellEffectWeaponDmgPctConfig) CalcAddedSpellDamage() float64
func (*SpellEffectWeaponDmgPctConfig) CalcSpellDamagePct ¶
func (config *SpellEffectWeaponDmgPctConfig) CalcSpellDamagePct() float64
type Warrior ¶
type Warrior struct { core.Character ClassSpellScaling float64 Talents *proto.WarriorTalents WarriorInputs // Current state Stance Stance EnrageEffectMultiplier float64 CriticalBlockChance []float64 // Can be gained as non-prot via certain talents and spells PrecisionKnown bool BattleShout *core.Spell CommandingShout *core.Spell BattleStance *core.Spell DefensiveStance *core.Spell BerserkerStance *core.Spell BerserkerRage *core.Spell ColossusSmash *core.Spell DemoralizingShout *core.Spell Execute *core.Spell Overpower *core.Spell Rend *core.Spell Revenge *core.Spell ShieldBlock *core.Spell Slam *core.Spell SunderArmor *core.Spell ThunderClap *core.Spell Whirlwind *core.Spell DeepWounds *core.Spell Charge *core.Spell HeroicStrike *core.Spell Cleave *core.Spell BattleStanceAura *core.Aura DefensiveStanceAura *core.Aura BerserkerStanceAura *core.Aura BerserkerRageAura *core.Aura BloodsurgeAura *core.Aura SuddenDeathAura *core.Aura ShieldBlockAura *core.Aura ThunderstruckAura *core.Aura InnerRageAura *core.Aura DemoralizingShoutAuras core.AuraArray SunderArmorAuras core.AuraArray ThunderClapAuras core.AuraArray ColossusSmashAuras core.AuraArray // contains filtered or unexported fields }
func NewWarrior ¶
func NewWarrior(character *core.Character, talents string, inputs WarriorInputs) *Warrior
func (*Warrior) AddPartyBuffs ¶
func (warrior *Warrior) AddPartyBuffs(_ *proto.PartyBuffs)
func (*Warrior) AddRaidBuffs ¶
func (*Warrior) ApplyCommonTalents ¶
func (warrior *Warrior) ApplyCommonTalents()
Applies the effects of "common" talents: talents in the first two rows of each tree that any spec could theoretically take Because cata restricts you to 10 points in a different tree, anything more is inaccessible. The rest of the trees are handled in each spec's implementation
func (*Warrior) ApplyGlyphs ¶
func (warrior *Warrior) ApplyGlyphs()
func (*Warrior) CanApplySunderAura ¶
func (*Warrior) GetCharacter ¶
func (*Warrior) GetCriticalBlockChance ¶
func (*Warrior) HasMajorGlyph ¶
func (warrior *Warrior) HasMajorGlyph(glyph proto.WarriorMajorGlyph) bool
func (*Warrior) HasMinorGlyph ¶
func (warrior *Warrior) HasMinorGlyph(glyph proto.WarriorMinorGlyph) bool
func (*Warrior) HasPrimeGlyph ¶
func (warrior *Warrior) HasPrimeGlyph(glyph proto.WarriorPrimeGlyph) bool
func (*Warrior) Initialize ¶
func (warrior *Warrior) Initialize()
func (*Warrior) IntensifyRageCooldown ¶
func (*Warrior) MakeShoutSpellHelper ¶
func (*Warrior) RecklessnessDeadlyCalmLock ¶
Shared cooldown for Deadly Calm and Recklessness Activation
func (*Warrior) RegisterBerserkerRageSpell ¶
func (warrior *Warrior) RegisterBerserkerRageSpell()
func (*Warrior) RegisterCharge ¶
func (warrior *Warrior) RegisterCharge()
func (*Warrior) RegisterCleaveSpell ¶
func (warrior *Warrior) RegisterCleaveSpell()
func (*Warrior) RegisterColossusSmash ¶
func (warrior *Warrior) RegisterColossusSmash()
func (*Warrior) RegisterDeepWounds ¶
func (warrior *Warrior) RegisterDeepWounds()
func (*Warrior) RegisterDemoralizingShoutSpell ¶
func (warrior *Warrior) RegisterDemoralizingShoutSpell()
func (*Warrior) RegisterExecuteSpell ¶
func (warrior *Warrior) RegisterExecuteSpell()
func (*Warrior) RegisterHeroicLeap ¶
func (warrior *Warrior) RegisterHeroicLeap()
func (*Warrior) RegisterHeroicStrikeSpell ¶
func (warrior *Warrior) RegisterHeroicStrikeSpell()
func (*Warrior) RegisterHeroicThrow ¶
func (warrior *Warrior) RegisterHeroicThrow()
TODO: No patch notes for this ability, need to validate the damage and threat coefficients haven't changed
func (*Warrior) RegisterInnerRage ¶
func (warrior *Warrior) RegisterInnerRage()
func (*Warrior) RegisterOverpowerSpell ¶
func (warrior *Warrior) RegisterOverpowerSpell()
func (*Warrior) RegisterRecklessnessCD ¶
func (warrior *Warrior) RegisterRecklessnessCD()
func (*Warrior) RegisterRendSpell ¶
func (warrior *Warrior) RegisterRendSpell()
TODO (maybe) https://github.com/magey/wotlk-warrior/issues/23 - Rend is not benefitting from Two-Handed Weapon Specialization
func (*Warrior) RegisterRevengeSpell ¶
func (warrior *Warrior) RegisterRevengeSpell()
func (*Warrior) RegisterShatteringThrowCD ¶
func (warrior *Warrior) RegisterShatteringThrowCD()
func (*Warrior) RegisterShieldBlockCD ¶
func (warrior *Warrior) RegisterShieldBlockCD()
func (*Warrior) RegisterShieldWallCD ¶
func (warrior *Warrior) RegisterShieldWallCD()
func (*Warrior) RegisterShouts ¶
func (warrior *Warrior) RegisterShouts()
func (*Warrior) RegisterSlamSpell ¶
func (warrior *Warrior) RegisterSlamSpell()
func (*Warrior) RegisterSunderArmor ¶
func (*Warrior) RegisterThunderClapSpell ¶
func (warrior *Warrior) RegisterThunderClapSpell()
func (*Warrior) RegisterWhirlwindSpell ¶
func (warrior *Warrior) RegisterWhirlwindSpell()
func (*Warrior) Reset ¶
func (warrior *Warrior) Reset(_ *core.Simulation)
func (*Warrior) StanceMatches ¶
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
}
Source Files ¶
- berserker_rage.go
- charge.go
- colossus_smash.go
- deep_wounds.go
- demoralizing_shout.go
- execute.go
- glyphs.go
- heroic_leap.go
- heroic_strike_cleave.go
- heroic_throw.go
- inner_rage.go
- items.go
- overpower.go
- recklessness.go
- rend.go
- revenge.go
- shattering_throw.go
- shield_block.go
- shield_wall.go
- shouts.go
- slam.go
- stances.go
- sunder_armor.go
- talents.go
- thunder_clap.go
- warrior.go
- weapon_dmg_pct_helper.go
- whirlwind.go