Documentation ¶
Index ¶
- Constants
- Variables
- func RegisterHunter()
- type Hunter
- func (hunter *Hunter) AddPartyBuffs(_ *proto.PartyBuffs)
- func (hunter *Hunter) AddRaidBuffs(raidBuffs *proto.RaidBuffs)
- func (hunter *Hunter) ApplyRunes()
- func (hunter *Hunter) ApplyTalents()
- func (hunter *Hunter) GetCharacter() *core.Character
- func (hunter *Hunter) GetHunter() *Hunter
- func (hunter *Hunter) HasRune(rune proto.HunterRune) bool
- func (hunter *Hunter) Initialize()
- func (hunter *Hunter) NewHunterPet() *HunterPet
- func (hunter *Hunter) OnGCDReady(_ *core.Simulation)
- func (hunter *Hunter) Reset(sim *core.Simulation)
- func (hunter *Hunter) TryRaptorStrike(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell
- type HunterAgent
- type HunterPet
- func (hp *HunterPet) ApplyTalents()
- func (hp *HunterPet) ExecuteCustomRotation(sim *core.Simulation)
- func (hp *HunterPet) GetPet() *core.Pet
- func (hp *HunterPet) Initialize()
- func (hp *HunterPet) NewPetAbility(abilityType PetAbilityType, isPrimary bool) *core.Spell
- func (hp *HunterPet) Reset(_ *core.Simulation)
- func (hp *HunterPet) Talents() *proto.HunterPetTalents
- type PetAbilityType
- type PetConfig
Constants ¶
View Source
const ( SpellFlagShot = core.SpellFlagAgentReserved1 SpellFlagStrike = core.SpellFlagAgentReserved2 SpellFlagSting = core.SpellFlagAgentReserved3 SpellFlagTrap = core.SpellFlagAgentReserved4 )
View Source
const ( SpellCode_HunterNone int32 = iota // Shots SpellCode_HunterAimedShot SpellCode_HunterArcaneShot SpellCode_HunterChimeraShot SpellCode_HunterExplosiveShot SpellCode_HunterKillShot SpellCode_HunterMultiShot SpellCode_HunterSteadyShot // Strikes SpellCode_HunterFlankingStrike SpellCode_HunterRaptorStrike SpellCode_HunterRaptorStrikeHit SpellCode_HunterWyvernStrike // Stings SpellCode_HunterSerpentSting // Traps SpellCode_HunterExplosiveTrap SpellCode_HunterFreezingTrap SpellCode_HunterImmolationTrap // Other SpellCode_HunterCarve SpellCode_HunterCarveHit SpellCode_HunterMongooseBite SpellCode_HunterWingClip SpellCode_HunterVolley SpellCode_HunterChimeraSerpent // Pet Spells SpellCode_HunterPetFlankingStrike SpellCode_HunterPetClaw SpellCode_HunterPetBite SpellCode_HunterPetLightningBreath SpellCode_HunterPetLavaBreath SpellCode_HunterPetScreech SpellCode_HunterPetScorpidPoison )
View Source
const ( DevilsaurEye = 19991 DevilsaurTooth = 19992 SignetOfBeasts = 209823 BloodlashBow = 216516 GurubashiPitFightersBow = 221450 BloodChainVices = 227075 KnightChainVices = 227077 BloodChainGrips = 227081 KnightChainGrips = 227087 WhistleOfTheBeast = 228432 ArcaneInfusedGem = 230237 RenatakisCharmOfRavaging = 231288 MaelstromsWrath = 231320 ZandalarPredatorsMantle = 231321 ZandalarPredatorsBelt = 231322 ZandalarPredatorsBracers = 231323 MarshalChainGrips = 231560 GeneralChainGrips = 231569 GeneralChainVices = 231575 MarshalChainVices = 231578 Kestrel = 231754 Peregrine = 231755 CloakOfTheUnseenPath = 233420 ScytheOfTheUnseenPath = 233421 SignetOfTheUnseenPath = 233422 )
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 RaptorFuryPerStackDamageMultiplier = 0.15
View Source
const RaptorStrikeRanks = 8
Variables ¶
View Source
var ItemSetBeastmasterArmor = core.NewItemSet(core.ItemSet{ Name: "Beastmaster Armor", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ stats.AttackPower: 40, stats.RangedAttackPower: 40, }) }, 4: func(agent core.Agent) { c := agent.GetCharacter() actionID := core.ActionID{SpellID: 450577} manaMetrics := c.NewManaMetrics(actionID) core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ ActionID: actionID, Name: "S03 - Mana Proc on Cast - Beaststalker Armor", Callback: core.CallbackOnSpellHitDealt, Outcome: core.OutcomeLanded, ProcMask: core.ProcMaskWhiteHit, ProcChance: 0.06, Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { if c.HasManaBar() { c.AddMana(sim, 300, manaMetrics) } }, }) }, 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 ItemSetBloodGuardsChain = core.NewItemSet(core.ItemSet{ Name: "Blood Guard's Chain", Bonuses: map[int32]core.ApplyEffect{ 3: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 15) }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.AttackPower, 30) c.AddStat(stats.RangedAttackPower, 20) }, }, })
View Source
var ItemSetChampionsProwess = core.NewItemSet(core.ItemSet{ Name: "Champion's Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ stats.AttackPower: 40, stats.RangedAttackPower: 40, }) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, }, })
View Source
var ItemSetChampionsPursuit = core.NewItemSet(core.ItemSet{ Name: "Champion's Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Agility, 20) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, }, })
View Source
var ItemSetDragonstalkerProwess = core.NewItemSet(core.ItemSet{ Name: "Dragonstalker's Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() affectedSpells := make(map[*core.Spell]bool) procAura := hunter.RegisterAura(core.Aura{ ActionID: core.ActionID{SpellID: 467331}, Label: "Clever Strikes", Duration: time.Second * 5, OnInit: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range hunter.MeleeSpells { if spell.SpellCode != SpellCode_HunterRaptorStrikeHit && spell.SpellCode != SpellCode_HunterRaptorStrike && spell.SpellCode != SpellCode_HunterWingClip { affectedSpells[spell] = true } } }, OnGain: func(aura *core.Aura, sim *core.Simulation) { for spell := range affectedSpells { spell.DamageMultiplier *= 1.20 } }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { for spell := range affectedSpells { spell.DamageMultiplier /= 1.20 } }, OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { if !affectedSpells[spell] { return } aura.Deactivate(sim) }, }) core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T2 - Hunter - Melee 2P Bonus Trigger", OnSpellHitDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { if spell.SpellCode == SpellCode_HunterRaptorStrikeHit { procAura.Activate(sim) } }, })) }, 4: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() hunter.OnSpellRegistered(func(spell *core.Spell) { if spell.SpellCode == SpellCode_HunterWyvernStrike || (spell.SpellCode == SpellCode_HunterRaptorStrikeHit && spell.ProcMask.Matches(core.ProcMaskMeleeMHSpecial)) { spell.DamageMultiplier *= 1.20 } }) }, 6: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T2 - Hunter - Melee 6P Bonus Trigger", ActionID: core.ActionID{SpellID: 467334}, OnPeriodicDamageDealt: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { if sim.Proc(0.05, "T2 Melee 6PC Strike Reset") { maxSpell := hunter.RaptorStrike for _, strike := range hunter.Strikes { if strike.TimeToReady(sim) > maxSpell.TimeToReady(sim) { maxSpell = strike } } maxSpell.CD.Reset() aura.Activate(sim) } }, })) }, }, })
View Source
var ItemSetDragonstalkerPursuit = core.NewItemSet(core.ItemSet{ Name: "Dragonstalker's Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { }, 4: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() shotSpells := []*core.Spell{} procAura := hunter.RegisterAura(core.Aura{ ActionID: core.ActionID{SpellID: 467312}, Label: "S03 - Item - T2 - Hunter - Ranged 4P Bonus", Duration: time.Second * 12, OnInit: func(aura *core.Aura, sim *core.Simulation) { shotSpells = core.FilterSlice(hunter.Shots, func(s *core.Spell) bool { return s != nil }) }, OnGain: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range shotSpells { if spell.SpellCode != hunter.LastShot.SpellCode { spell.DamageMultiplier *= 1.10 } } }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range shotSpells { if spell.SpellCode != hunter.LastShot.SpellCode { spell.DamageMultiplier /= 1.10 } } }, }) core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T2 - Hunter - Ranged 4P Bonus Trigger", OnCastComplete: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell) { if spell.Flags.Matches(SpellFlagShot) { procAura.Deactivate(sim) hunter.LastShot = spell procAura.Activate(sim) } }, })) }, 6: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T2 - Hunter - Ranged 6P Bonus", OnInit: func(aura *core.Aura, sim *core.Simulation) { hunter.SerpentStingAPCoeff += 0.25 }, })) }, }, })
View Source
var ItemSetDreadHuntersChain = core.NewItemSet(core.ItemSet{ Name: "Dread Hunter's Chain", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.AttackPower, 20) c.AddStat(stats.RangedAttackPower, 20) }, 3: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.MeleeCrit, 1*core.CritRatingPerCritChance) }, }, })
View Source
var ItemSetFieldMarshalsProwess = core.NewItemSet(core.ItemSet{ Name: "Field Marshal's Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ stats.AttackPower: 40, stats.RangedAttackPower: 40, }) }, }, })
View Source
var ItemSetFieldMarshalsPursuit = core.NewItemSet(core.ItemSet{ Name: "Field Marshal's Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Agility, 20) }, }, })
View Source
var ItemSetGiantstalkerProwess = core.NewItemSet(core.ItemSet{ Name: "Giantstalker Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() procBonus := stats.Stats{ stats.SpellHit: 1, stats.MeleeHit: 1, } stalkerAura := hunter.RegisterAura(core.Aura{ ActionID: core.ActionID{SpellID: 458403}, Label: "Stalker", Duration: time.Second * 30, OnGain: func(aura *core.Aura, sim *core.Simulation) { aura.Unit.AddStatsDynamic(sim, procBonus) }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { aura.Unit.AddStatsDynamic(sim, procBonus.Invert()) }, }) debuffAuras := hunter.NewEnemyAuraArray(core.MeleeHunterDodgeReductionAura) core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T1 - Hunter - Melee 2P Bonus Trigger", OnSpellHitDealt: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { if spell.SpellCode == SpellCode_HunterMongooseBite && result.Landed() { debuffAuras.Get(result.Target).Activate(sim) stalkerAura.Activate(sim) } }, })) }, 4: func(agent core.Agent) { c := agent.GetCharacter() c.PseudoStats.DamageDealtMultiplier *= 1.03 }, 6: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T1 - Hunter - Melee 6P Bonus Trigger", OnSpellHitDealt: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { if spell.ProcMask.Matches(core.ProcMaskMelee) && (result.Outcome == core.OutcomeMiss || result.Outcome == core.OutcomeBlock || result.Outcome == core.OutcomeParry) { hunter.DefensiveState.Activate(sim) } }, })) }, }, })
View Source
var ItemSetGiantstalkerPursuit = core.NewItemSet(core.ItemSet{ Name: "Giantstalker Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { }, 4: func(agent core.Agent) { c := agent.GetCharacter() c.PseudoStats.DamageDealtMultiplier *= 1.03 }, 6: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if !hunter.Talents.AimedShot { return } procAura := hunter.RegisterAura(core.Aura{ ActionID: core.ActionID{SpellID: 456379}, Label: "S03 - Item - T1 - Hunter - Ranged 6P Bonus", Duration: time.Second * 12, OnGain: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range hunter.Shots { if spell != nil { spell.DamageMultiplier *= 1.20 } } }, OnExpire: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range hunter.Shots { if spell != nil { spell.DamageMultiplier /= 1.20 } } }, OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { if !spell.Flags.Matches(SpellFlagShot) || (aura.RemainingDuration(sim) == aura.Duration && spell.SpellCode == SpellCode_HunterAimedShot) { return } aura.Deactivate(sim) }, }) core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "S03 - Item - T1 - Hunter - Ranged 6P Bonus Trigger", OnCastComplete: func(_ *core.Aura, sim *core.Simulation, spell *core.Spell) { if spell.SpellCode == SpellCode_HunterAimedShot { procAura.Activate(sim) } }, })) }, }, })
View Source
var ItemSetKnightLieutenantsChain = core.NewItemSet(core.ItemSet{ Name: "Knight-Lieutenant's Chain", Bonuses: map[int32]core.ApplyEffect{ 3: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 15) }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.AttackPower, 30) c.AddStat(stats.RangedAttackPower, 20) }, }, })
View Source
var ItemSetLieutenantCommandersProwess = core.NewItemSet(core.ItemSet{ Name: "Lieutenant Commander's Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ stats.AttackPower: 40, stats.RangedAttackPower: 40, }) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, }, })
View Source
var ItemSetLieutenantCommandersPursuit = core.NewItemSet(core.ItemSet{ Name: "Lieutenant Commander's Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Agility, 20) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, }, })
View Source
var ItemSetPredatorArmor = core.NewItemSet(core.ItemSet{ Name: "Predator's Armor", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.AttackPower, 20) c.AddStat(stats.RangedAttackPower, 20) }, 3: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if hunter.pet == nil { return } core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "Predator's Armor 3P", OnInit: func(aura *core.Aura, sim *core.Simulation) { oldStatInheritance := hunter.pet.GetStatInheritance() hunter.pet.UpdateStatInheritance( func(ownerStats stats.Stats) stats.Stats { s := oldStatInheritance(ownerStats) s[stats.AttackPower] *= 1.20 return s }, ) }, })) }, 5: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if hunter.pet == nil { return } hunter.RegisterAura(core.Aura{ Label: "Predator's Armor 5P", OnInit: func(aura *core.Aura, sim *core.Simulation) { hunter.pet.AddFocusRegenMultiplier(0.20) }, }) }, }, })
View Source
var ItemSetWarlordsProwess = core.NewItemSet(core.ItemSet{ Name: "Warlord's Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStats(stats.Stats{ stats.AttackPower: 40, stats.RangedAttackPower: 40, }) }, }, })
View Source
var ItemSetWarlordsPursuit = core.NewItemSet(core.ItemSet{ Name: "Warlord's Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Stamina, 20) }, 4: func(agent core.Agent) { }, 6: func(agent core.Agent) { c := agent.GetCharacter() c.AddStat(stats.Agility, 20) }, }, })
View Source
var PetConfigs = map[proto.Hunter_Options_PetType]PetConfig{ proto.Hunter_Options_Cat: { Name: "Cat", MobType: proto.MobType_MobTypeBeast, SpecialAbility: Bite, FocusDump: Claw, Health: 0.98, Armor: 1.00, Damage: 1.10, CustomRotation: func(sim *core.Simulation, hp *HunterPet, tryCast func(*core.Spell) bool) { if hp.specialAbility.CD.IsReady(sim) && hp.CurrentFocusPerSecond() > hp.focusDump.Cost.BaseCost/1.6 { if !tryCast(hp.specialAbility) && hp.GCD.IsReady(sim) { hp.WaitUntil(sim, sim.CurrentTime+time.Millisecond*500) } } else { if !tryCast(hp.focusDump) && hp.GCD.IsReady(sim) { hp.WaitUntil(sim, sim.CurrentTime+time.Millisecond*500) } } }, }, proto.Hunter_Options_WindSerpent: { Name: "Wind Serpent", MobType: proto.MobType_MobTypeBeast, SpecialAbility: Bite, FocusDump: LightningBreath, Health: 1.00, Armor: 1.00, Damage: 1.07, }, proto.Hunter_Options_Bat: { Name: "Bat", MobType: proto.MobType_MobTypeBeast, SpecialAbility: Bite, FocusDump: Screech, Health: 1.00, Armor: 1.00, Damage: 1.07, CustomRotation: func(sim *core.Simulation, hp *HunterPet, tryCast func(*core.Spell) bool) { if hp.specialAbility.CD.IsReady(sim) { if !tryCast(hp.specialAbility) && hp.GCD.IsReady(sim) { hp.WaitUntil(sim, sim.CurrentTime+time.Millisecond*500) } } else { if !tryCast(hp.focusDump) && hp.GCD.IsReady(sim) { hp.WaitUntil(sim, sim.CurrentTime+time.Millisecond*500) } } }, }, proto.Hunter_Options_Bear: { Name: "Bear", MobType: proto.MobType_MobTypeBeast, SpecialAbility: Bite, FocusDump: Claw, Health: 1.08, Armor: 1.05, Damage: 0.91, }, proto.Hunter_Options_Boar: { Name: "Boar", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.04, Armor: 1.09, Damage: 0.90, }, proto.Hunter_Options_CarrionBird: { Name: "Carrion Bird", MobType: proto.MobType_MobTypeBeast, SpecialAbility: Bite, FocusDump: Claw, Health: 1.00, Armor: 1.05, Damage: 1.00, }, proto.Hunter_Options_Owl: { Name: "Owl", MobType: proto.MobType_MobTypeBeast, FocusDump: Claw, Health: 1.00, Armor: 1.00, Damage: 1.07, }, proto.Hunter_Options_CoreHound: { Name: "Core Hound", MobType: proto.MobType_MobTypeBeast, FocusDump: LavaBreath, Health: 1.06, Armor: 1.01, Damage: 1.02, }, proto.Hunter_Options_Crab: { Name: "Crab", MobType: proto.MobType_MobTypeBeast, FocusDump: Claw, Health: 0.96, Armor: 1.13, Damage: 0.95, }, proto.Hunter_Options_Crocolisk: { Name: "Crocolisk", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 0.95, Armor: 1.10, Damage: 1.00, }, proto.Hunter_Options_Gorilla: { Name: "Gorilla", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.04, Armor: 1.00, Damage: 1.02, }, proto.Hunter_Options_Hyena: { Name: "Hyena", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.00, Armor: 1.05, Damage: 1.00, }, proto.Hunter_Options_Raptor: { Name: "Raptor", MobType: proto.MobType_MobTypeBeast, SpecialAbility: Bite, FocusDump: Claw, Health: 0.95, Armor: 1.03, Damage: 1.10, }, proto.Hunter_Options_Scorpid: { Name: "Scorpid", MobType: proto.MobType_MobTypeBeast, SpecialAbility: ScorpidPoison, FocusDump: Claw, Health: 1.00, Armor: 1.10, Damage: 0.94, CustomRotation: func(sim *core.Simulation, hp *HunterPet, tryCast func(*core.Spell) bool) { target := hp.CurrentTarget if (hp.specialAbility.Dot(target).GetStacks() < hp.specialAbility.Dot(target).MaxStacks || hp.specialAbility.Dot(target).RemainingDuration(sim) < time.Second*3) && hp.CurrentFocus() < 90 { if !tryCast(hp.specialAbility) && hp.GCD.IsReady(sim) { hp.WaitUntil(sim, sim.CurrentTime+time.Millisecond*500) } } else { if !tryCast(hp.focusDump) && hp.GCD.IsReady(sim) { hp.WaitUntil(sim, sim.CurrentTime+time.Millisecond*500) } } }, }, proto.Hunter_Options_Spider: { Name: "Spider", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.00, Armor: 1.00, Damage: 1.07, }, proto.Hunter_Options_Tallstrider: { Name: "Tallstrider", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.05, Armor: 1.00, Damage: 1.00, }, proto.Hunter_Options_Turtle: { Name: "Turtle", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.00, Armor: 1.13, Damage: 0.90, }, proto.Hunter_Options_Wolf: { Name: "Wolf", MobType: proto.MobType_MobTypeBeast, FocusDump: Bite, Health: 1.00, Armor: 1.05, Damage: 1.00, }, }
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 RaptorStrikeBaseDamage = [RaptorStrikeRanks + 1]float64{0, 5, 11, 21, 34, 50, 80, 110, 140}
View Source
var RaptorStrikeLevel = [RaptorStrikeRanks + 1]int{0, 1, 8, 16, 24, 32, 40, 48, 56}
View Source
var RaptorStrikeManaCost = [RaptorStrikeRanks + 1]float64{0, 15, 25, 35, 45, 55, 70, 80, 100}
View Source
var RaptorStrikeSpellId = [RaptorStrikeRanks + 1]int32{0, 2973, 14260, 14261, 14262, 14263, 14264, 14265, 14266}
View Source
var RaptorStrikeSpellIdMeleeSpecialist = [RaptorStrikeRanks + 1]int32{0, 415335, 415336, 415337, 415338, 415340, 415341, 415342, 415343}
View Source
var StrikersProwess = core.NewItemSet(core.ItemSet{ Name: "Striker's Prowess", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if !hunter.Talents.WyvernSting || !hunter.HasRune(proto.HunterRune_RuneBootsWyvernStrike) { return } hunter.RegisterAura(core.Aura{ Label: "Striker's Prowess 2P", OnInit: func(aura *core.Aura, sim *core.Simulation) { hunter.WyvernStrike.PeriodicDamageMultiplierAdditive += 0.50 }, }) }, 4: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() hunter.RegisterAura(core.Aura{ Label: "Striker's Prowess 4P", OnInit: func(aura *core.Aura, sim *core.Simulation) { for _, spell := range hunter.Strikes { spell.ImpactDamageMultiplierAdditive += 0.10 } hunter.RaptorStrikeMH.ImpactDamageMultiplierAdditive += 0.10 hunter.RaptorStrikeOH.ImpactDamageMultiplierAdditive += 0.10 hunter.MongooseBite.ImpactDamageMultiplierAdditive += 0.10 }, }) }, }, })
View Source
var StrikersPursuit = core.NewItemSet(core.ItemSet{ Name: "Striker's Pursuit", Bonuses: map[int32]core.ApplyEffect{ 2: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if !hunter.HasRune(proto.HunterRune_RuneLegsKillShot) { return } core.MakePermanent(hunter.RegisterAura(core.Aura{ Label: "Striker's Pursuit 2P", OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) { if spell.SpellCode != SpellCode_HunterKillShot { return } if hunter.HasActiveAura("Rapid Fire") { spell.CD.Reset() } else if sim.CurrentTime > sim.Encounter.Duration/2 { spell.CD.Set(sim.CurrentTime + spell.CD.TimeToReady(sim)/2) } }, })) }, 4: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if !hunter.HasRune(proto.HunterRune_RuneLegsKillShot) { return } hunter.RegisterAura(core.Aura{ Label: "Striker's Pursuit 4P", OnInit: func(aura *core.Aura, sim *core.Simulation) { hunter.KillShot.DamageMultiplier *= 1.50 }, }) }, }, })
View Source
var TalentTreeSizes = [3]int{16, 14, 16}
View Source
var TrappingsOfTheUnseenPath = core.NewItemSet(core.ItemSet{ Name: "Trappings of the Unseen Path", Bonuses: map[int32]core.ApplyEffect{ 3: func(agent core.Agent) { hunter := agent.(HunterAgent).GetHunter() if hunter.pet == nil { return } hunter.RegisterAura(core.Aura{ Label: "Trappings of the Unseen Path 3P", OnInit: func(aura *core.Aura, sim *core.Simulation) { hunter.pet.AddFocusRegenMultiplier(1.00) }, }) }, }, })
Functions ¶
func RegisterHunter ¶
func RegisterHunter()
Types ¶
type Hunter ¶
type Hunter struct { core.Character Talents *proto.HunterTalents Options *proto.Hunter_Options AmmoDPS float64 AmmoDamageBonus float64 NormalizedAmmoDamageBonus float64 // Miscellaneous set bonuses that require extra logic inside of spells SerpentStingAPCoeff float64 AimedShot *core.Spell ArcaneShot *core.Spell ChimeraShot *core.Spell ExplosiveShot *core.Spell ExplosiveTrap *core.Spell ImmolationTrap *core.Spell FreezingTrap *core.Spell KillCommand *core.Spell KillShot *core.Spell MultiShot *core.Spell FocusFire *core.Spell RapidFire *core.Spell RaptorStrike *core.Spell RaptorStrikeMH *core.Spell RaptorStrikeOH *core.Spell FlankingStrike *core.Spell WyvernStrike *core.Spell MongooseBite *core.Spell ScorpidSting *core.Spell SerpentSting *core.Spell SilencingShot *core.Spell SteadyShot *core.Spell Volley *core.Spell CarveMH *core.Spell CarveOH *core.Spell WingClip *core.Spell Shots []*core.Spell Strikes []*core.Spell MeleeSpells []*core.Spell LastShot *core.Spell SerpentStingChimeraShot *core.Spell FlankingStrikeAura *core.Aura RaptorFuryAura *core.Aura SniperTrainingAura *core.Aura CobraStrikesAura *core.Aura HitAndRunAura *core.Aura // The aura that allows you to cast Mongoose Bite DefensiveState *core.Aura ImprovedSteadyShotAura *core.Aura LockAndLoadAura *core.Aura RapidFireAura *core.Aura BestialWrathPetAura *core.Aura // contains filtered or unexported fields }
func (*Hunter) AddPartyBuffs ¶
func (hunter *Hunter) AddPartyBuffs(_ *proto.PartyBuffs)
func (*Hunter) AddRaidBuffs ¶
func (*Hunter) ApplyRunes ¶
func (hunter *Hunter) ApplyRunes()
func (*Hunter) ApplyTalents ¶
func (hunter *Hunter) ApplyTalents()
func (*Hunter) GetCharacter ¶
func (*Hunter) Initialize ¶
func (hunter *Hunter) Initialize()
func (*Hunter) NewHunterPet ¶
func (*Hunter) OnGCDReady ¶
func (hunter *Hunter) OnGCDReady(_ *core.Simulation)
func (*Hunter) Reset ¶
func (hunter *Hunter) Reset(sim *core.Simulation)
func (*Hunter) TryRaptorStrike ¶
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 ¶
func (*HunterPet) ApplyTalents ¶
func (hp *HunterPet) ApplyTalents()
func (*HunterPet) ExecuteCustomRotation ¶
func (hp *HunterPet) ExecuteCustomRotation(sim *core.Simulation)
func (*HunterPet) Initialize ¶
func (hp *HunterPet) Initialize()
func (*HunterPet) NewPetAbility ¶
func (hp *HunterPet) NewPetAbility(abilityType PetAbilityType, isPrimary bool) *core.Spell
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 Bite Claw Screech FuriousHowl LightningBreath ScorpidPoison LavaBreath )
Source Files ¶
- aimed_shot.go
- arcane_shot.go
- aspects.go
- carve.go
- chimera_shot.go
- explosive_shot.go
- explosive_trap.go
- flanking_strike.go
- focus_fire.go
- freezing_trap.go
- hunter.go
- immolation_trap.go
- item_sets_pve.go
- item_sets_pvp.go
- items.go
- kill_command.go
- kill_shot.go
- mongoose_bite.go
- multi_shot.go
- pet.go
- pet_abilities.go
- pet_talents.go
- rapid_fire.go
- raptor_strike.go
- runes.go
- serpent_sting.go
- steady_shot.go
- talents.go
- volley.go
- wing_clip.go
- wyvern_strike.go
Click to show internal directories.
Click to hide internal directories.