hunter

package
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2023 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const BiteSpellID = 27050

These IDs are needed for certain talents.

View Source
const ClawSpellID = 27049
View Source
const PetExpertiseScale = 3.25
View Source
const PetGCD = time.Millisecond * 1600

Pet AI doesn't use abilities immediately, so model this with a 1.6s GCD.

View Source
const SmackSpellID = 49974
View Source
const ThoridalTheStarsFuryItemID = 34334

Variables

View Source
var ItemSetAhnKaharBloodHuntersBattlegear = core.NewItemSet(core.ItemSet{
	Name: "Ahn'Kahar Blood Hunter's Battlegear",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()
			const procChance = 0.05
			actionID := core.ActionID{SpellID: 70727}

			procAura := hunter.RegisterAura(core.Aura{
				Label:    "AhnKahar 2pc Proc",
				ActionID: actionID,
				Duration: time.Second * 10,
				OnGain: func(aura *core.Aura, sim *core.Simulation) {
					aura.Unit.PseudoStats.DamageDealtMultiplier *= 1.15
				},
				OnExpire: func(aura *core.Aura, sim *core.Simulation) {
					aura.Unit.PseudoStats.DamageDealtMultiplier /= 1.15
				},
			})

			hunter.RegisterAura(core.Aura{
				Label:    "AhnKahar 2pc",
				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 == hunter.AutoAttacks.RangedAuto && sim.RandomFloat("AhnKahar 2pc") < procChance {
						procAura.Activate(sim)
					}
				},
			})
		},
		4: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()
			const procChance = 0.05
			actionID := core.ActionID{SpellID: 70730}

			var curBonus stats.Stats
			procAura := hunter.RegisterAura(core.Aura{
				Label:    "AhnKahar 4pc Proc",
				ActionID: actionID,
				Duration: time.Second * 10,
				OnGain: func(aura *core.Aura, sim *core.Simulation) {
					curBonus = stats.Stats{
						stats.AttackPower:       aura.Unit.GetStat(stats.AttackPower) * 0.1,
						stats.RangedAttackPower: aura.Unit.GetStat(stats.RangedAttackPower) * 0.1,
					}

					aura.Unit.AddStatsDynamic(sim, curBonus)
				},
				OnExpire: func(aura *core.Aura, sim *core.Simulation) {
					aura.Unit.AddStatsDynamic(sim, curBonus.Multiply(-1))
				},
			})

			hunter.RegisterAura(core.Aura{
				Label:    "AhnKahar 4pc",
				Duration: core.NeverExpires,
				OnReset: func(aura *core.Aura, sim *core.Simulation) {
					aura.Activate(sim)
				},
				OnPeriodicDamageDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
					if spell == hunter.SerpentSting && sim.RandomFloat("AhnKahar 4pc") < procChance {
						procAura.Activate(sim)
					}
				},
			})
		},
	},
})
View Source
var ItemSetBeastLord = core.NewItemSet(core.ItemSet{
	Name: "Beast Lord Armor",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
		},
		4: func(agent core.Agent) {

		},
	},
})
View Source
var ItemSetCryptstalkerBattlegear = core.NewItemSet(core.ItemSet{
	Name: "Cryptstalker Battlegear",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()
			if hunter.pet != nil {
				hunter.pet.PseudoStats.DamageDealtMultiplier *= 1.05
			}
		},
		4: func(agent core.Agent) {
		},
	},
})
View Source
var ItemSetDemonStalker = core.NewItemSet(core.ItemSet{
	Name: "Demon Stalker Armor",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
		},
		4: func(agent core.Agent) {

		},
	},
})
View Source
var ItemSetGladiatorsPursuit = core.NewItemSet(core.ItemSet{
	Name: "Gladiator's Pursuit",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()
			hunter.AddStats(stats.Stats{
				stats.AttackPower:       50,
				stats.RangedAttackPower: 50,
				stats.Resilience:        50,
			})
		},
		4: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()
			hunter.AddStats(stats.Stats{
				stats.AttackPower:       150,
				stats.RangedAttackPower: 150,
			})
		},
	},
})
View Source
var ItemSetGronnstalker = core.NewItemSet(core.ItemSet{
	Name: "Gronnstalker's Armor",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {

		},
		4: func(agent core.Agent) {

		},
	},
})
View Source
var ItemSetRiftStalker = core.NewItemSet(core.ItemSet{
	Name: "Rift Stalker Armor",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
		},
		4: func(agent core.Agent) {

		},
	},
})
View Source
var ItemSetScourgestalkerBattlegear = core.NewItemSet(core.ItemSet{
	Name: "Scourgestalker Battlegear",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
		},
		4: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()

			procAura := hunter.NewTemporaryStatsAura("Scourgestalker 4pc Proc", core.ActionID{SpellID: 64860}, stats.Stats{stats.AttackPower: 600, stats.RangedAttackPower: 600}, time.Second*15)
			const procChance = 0.1

			icd := core.Cooldown{
				Timer:    hunter.NewTimer(),
				Duration: time.Second * 45,
			}
			procAura.Icd = &icd

			hunter.RegisterAura(core.Aura{
				Label:    "Windrunner 4pc",
				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 !result.Landed() || spell != hunter.SteadyShot {
						return
					}
					if !icd.IsReady(sim) {
						return
					}
					if sim.RandomFloat("Scourgestalker 4pc") > procChance {
						return
					}

					icd.Use(sim)
					procAura.Activate(sim)
				},
			})
		},
	},
})
View Source
var ItemSetWindrunnersPursuit = core.NewItemSet(core.ItemSet{
	Name:            "Windrunner's Pursuit",
	AlternativeName: "Windrunner's Battlegear",
	Bonuses: map[int32]core.ApplyEffect{
		2: func(agent core.Agent) {
		},
		4: func(agent core.Agent) {
			hunter := agent.(HunterAgent).GetHunter()
			if hunter.pet == nil {
				return
			}

			procAura := hunter.pet.NewTemporaryStatsAura("Windrunner 4pc Proc", core.ActionID{SpellID: 68130}, stats.Stats{stats.AttackPower: 600}, time.Second*15)
			const procChance = 0.35

			icd := core.Cooldown{
				Timer:    hunter.NewTimer(),
				Duration: time.Second * 45,
			}
			procAura.Icd = &icd

			hunter.RegisterAura(core.Aura{
				Label:    "Windrunner 4pc",
				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 !result.Landed() || !spell.ProcMask.Matches(core.ProcMaskRanged) {
						return
					}
					if !icd.IsReady(sim) {
						return
					}
					if sim.RandomFloat("Windrunner 4pc") > procChance {
						return
					}

					icd.Use(sim)
					procAura.Activate(sim)
				},
			})
		},
	},
})
View Source
var PetConfigs = map[proto.Hunter_Options_PetType]PetConfig{
	proto.Hunter_Options_Bat: {
		Name:           "Bat",
		SpecialAbility: SonicBlast,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_Bear: {
		Name:           "Bear",
		SpecialAbility: Swipe,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_BirdOfPrey: {
		Name:           "Bird of Prey",
		SpecialAbility: Snatch,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_Boar: {
		Name:           "Boar",
		SpecialAbility: Gore,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_CarrionBird: {
		Name:           "Carrion Bird",
		SpecialAbility: DemoralizingScreech,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Cat: {
		Name:           "Cat",
		SpecialAbility: Rake,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_Chimaera: {
		Name:           "Chimaera",
		SpecialAbility: FroststormBreath,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_CoreHound: {
		Name:           "Core Hound",
		SpecialAbility: LavaBreath,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Crab: {
		Name:           "Crab",
		SpecialAbility: Pin,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_Crocolisk: {
		Name: "Crocolisk",

		FocusDump: Bite,
	},
	proto.Hunter_Options_Devilsaur: {
		Name:           "Devilsaur",
		SpecialAbility: MonstrousBite,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Dragonhawk: {
		Name:           "Dragonhawk",
		SpecialAbility: FireBreath,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Gorilla: {
		Name: "Gorilla",

		FocusDump: Smack,
	},
	proto.Hunter_Options_Hyena: {
		Name:           "Hyena",
		SpecialAbility: TendonRip,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Moth: {
		Name: "Moth",

		FocusDump: Smack,
	},
	proto.Hunter_Options_NetherRay: {
		Name:           "Nether Ray",
		SpecialAbility: NetherShock,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Raptor: {
		Name:           "Raptor",
		SpecialAbility: SavageRend,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_Ravager: {
		Name:           "Ravager",
		SpecialAbility: Ravage,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Rhino: {
		Name:           "Rhino",
		SpecialAbility: Stampede,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Scorpid: {
		Name:           "Scorpid",
		SpecialAbility: ScorpidPoison,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Serpent: {
		Name:           "Serpent",
		SpecialAbility: PoisonSpit,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Silithid: {
		Name:           "Silithid",
		SpecialAbility: VenomWebSpray,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_Spider: {
		Name: "Spider",

		FocusDump: Bite,
	},
	proto.Hunter_Options_SpiritBeast: {
		Name:           "Spirit Beast",
		SpecialAbility: SpiritStrike,
		FocusDump:      Claw,
	},
	proto.Hunter_Options_SporeBat: {
		Name:           "Spore Bat",
		SpecialAbility: SporeCloud,
		FocusDump:      Smack,
	},
	proto.Hunter_Options_Tallstrider: {
		Name: "Tallstrider",

		FocusDump: Claw,
	},
	proto.Hunter_Options_Turtle: {
		Name: "Turtle",

		FocusDump: Bite,
	},
	proto.Hunter_Options_WarpStalker: {
		Name: "Warp Stalker",

		FocusDump: Bite,
	},
	proto.Hunter_Options_Wasp: {
		Name:           "Wasp",
		SpecialAbility: Sting,
		FocusDump:      Smack,
	},
	proto.Hunter_Options_WindSerpent: {
		Name:           "Wind Serpent",
		SpecialAbility: LightningBreath,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Wolf: {
		Name:           "Wolf",
		SpecialAbility: FuriousHowl,
		FocusDump:      Bite,
	},
	proto.Hunter_Options_Worm: {
		Name:           "Worm",
		SpecialAbility: AcidSpit,
		FocusDump:      Bite,
	},
}

Abilities reference: https://wotlk.wowhead.com/hunter-pets https://wotlk.wowhead.com/guides/hunter-dps-best-pets-taming-loyalty-burning-crusade-classic

View Source
var TalentTreeSizes = [3]int{26, 27, 28}

Functions

func RegisterHunter

func RegisterHunter()

Types

type Hunter

type Hunter struct {
	core.Character

	Talents  *proto.HunterTalents
	Options  *proto.Hunter_Options
	Rotation *proto.Hunter_Rotation

	AmmoDPS                   float64
	AmmoDamageBonus           float64
	NormalizedAmmoDamageBonus float64

	AspectOfTheHawk  *core.Spell
	AspectOfTheViper *core.Spell

	AimedShot       *core.Spell
	ArcaneShot      *core.Spell
	BlackArrow      *core.Spell
	ChimeraShot     *core.Spell
	ExplosiveShotR4 *core.Spell
	ExplosiveShotR3 *core.Spell
	ExplosiveTrap   *core.Spell
	KillCommand     *core.Spell
	// KillShot        *core.Spell
	MultiShot     *core.Spell
	RapidFire     *core.Spell
	RaptorStrike  *core.Spell
	ScorpidSting  *core.Spell
	SerpentSting  *core.Spell
	SilencingShot *core.Spell
	SteadyShot    *core.Spell
	Volley        *core.Spell

	// Fake spells to encapsulate weaving logic.
	TrapWeaveSpell *core.Spell

	AspectOfTheHawkAura    *core.Aura
	AspectOfTheViperAura   *core.Aura
	ImprovedSteadyShotAura *core.Aura
	LockAndLoadAura        *core.Aura
	RapidFireAura          *core.Aura
	ScorpidStingAuras      core.AuraArray
	TalonOfAlarAura        *core.Aura

	CustomRotation *common.CustomRotation
	// contains filtered or unexported fields
}

func NewHunter

func NewHunter(character core.Character, options *proto.Player) *Hunter

func (*Hunter) AddPartyBuffs

func (hunter *Hunter) AddPartyBuffs(_ *proto.PartyBuffs)

func (*Hunter) AddRaidBuffs

func (hunter *Hunter) AddRaidBuffs(raidBuffs *proto.RaidBuffs)

func (*Hunter) ApplyTalents

func (hunter *Hunter) ApplyTalents()

func (*Hunter) GetAllHuntersWithGlyphOfSteadyShot

func (hunter *Hunter) GetAllHuntersWithGlyphOfSteadyShot() []*Hunter

func (*Hunter) GetCharacter

func (hunter *Hunter) GetCharacter() *core.Character

func (*Hunter) GetHunter

func (hunter *Hunter) GetHunter() *Hunter

func (*Hunter) HasMajorGlyph

func (hunter *Hunter) HasMajorGlyph(glyph proto.HunterMajorGlyph) bool

func (*Hunter) HasMinorGlyph

func (hunter *Hunter) HasMinorGlyph(glyph proto.HunterMinorGlyph) bool

func (*Hunter) Initialize

func (hunter *Hunter) Initialize()

func (*Hunter) MultiShotCastTime

func (hunter *Hunter) MultiShotCastTime() time.Duration

func (*Hunter) NewHunterPet

func (hunter *Hunter) NewHunterPet() *HunterPet

func (*Hunter) OnAutoAttack

func (hunter *Hunter) OnAutoAttack(sim *core.Simulation, spell *core.Spell)

func (*Hunter) OnGCDReady

func (hunter *Hunter) OnGCDReady(sim *core.Simulation)

func (*Hunter) Reset

func (hunter *Hunter) Reset(_ *core.Simulation)

func (*Hunter) SteadyShotCastTime

func (hunter *Hunter) SteadyShotCastTime() time.Duration

func (*Hunter) TryRaptorStrike

func (hunter *Hunter) TryRaptorStrike(_ *core.Simulation, mhSwingSpell *core.Spell) *core.Spell

Returns true if the regular melee swing should be used, false otherwise.

type HunterAgent

type HunterAgent interface {
	GetHunter() *Hunter
}

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

type HunterPet

type HunterPet struct {
	core.Pet

	CobraStrikesAura *core.Aura
	KillCommandAura  *core.Aura
	// contains filtered or unexported fields
}

func (*HunterPet) ApplyTalents

func (hp *HunterPet) ApplyTalents()

func (*HunterPet) GetPet

func (hp *HunterPet) GetPet() *core.Pet

func (*HunterPet) Initialize

func (hp *HunterPet) Initialize()

func (*HunterPet) NewPetAbility

func (hp *HunterPet) NewPetAbility(abilityType PetAbilityType, isPrimary bool) *core.Spell

func (*HunterPet) OnGCDReady

func (hp *HunterPet) OnGCDReady(sim *core.Simulation)

func (*HunterPet) Reset

func (hp *HunterPet) Reset(_ *core.Simulation)

func (*HunterPet) Talents

func (hp *HunterPet) Talents() *proto.HunterPetTalents

type PetAbilityType

type PetAbilityType int
const (
	Unknown PetAbilityType = iota
	AcidSpit
	Bite
	Claw
	DemoralizingScreech
	FireBreath
	FuriousHowl
	FroststormBreath
	Gore
	LavaBreath
	LightningBreath
	MonstrousBite
	NetherShock
	Pin
	PoisonSpit
	Rake
	Ravage
	SavageRend
	ScorpidPoison
	Smack
	Snatch
	SonicBlast
	SpiritStrike
	SporeCloud
	Stampede
	Sting
	Swipe
	TendonRip
	VenomWebSpray
)

type PetConfig

type PetConfig struct {
	Name string

	SpecialAbility PetAbilityType
	FocusDump      PetAbilityType

	// Randomly select between abilities instead of using a prio.
	RandomSelection bool
}

type PetSpecialAbilityConfig

type PetSpecialAbilityConfig struct {
	Type    PetAbilityType
	Cost    float64
	SpellID int32
	School  core.SpellSchool
	GCD     time.Duration
	CD      time.Duration
	MinDmg  float64
	MaxDmg  float64
	APRatio float64

	Dot core.DotConfig

	OnSpellHitDealt func(*core.Simulation, *core.Spell, *core.SpellResult)
}

type RotationCondition added in v1.0.1

type RotationCondition struct {
	CanUse func(sim *core.Simulation, target *core.Unit) bool
}

Jump to

Keyboard shortcuts

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