Skip to content

Commit

Permalink
Merge branch 'master' into kg/spell-known-aura-known
Browse files Browse the repository at this point in the history
  • Loading branch information
rosenrusinov authored Apr 1, 2024
2 parents 0b7959f + ab474e6 commit c793cd0
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 5 deletions.
3 changes: 3 additions & 0 deletions assets/database/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -9839,6 +9839,7 @@
{"id":415236,"name":"Engrave Chest - Healing Rain","icon":"spell_nature_tranquility","class":7,"type":5,"requiresLevel":1},
{"id":415320,"name":"Engrave Pants - Flanking Strike","icon":"ability_hunter_harass","class":2,"type":9,"requiresLevel":1},
{"id":415352,"name":"Engrave Belt - Melee Specialist","icon":"inv_axe_03","class":2,"type":8,"requiresLevel":1},
{"id":415358,"name":"Engrave Bracers - Raptor Fury","icon":"ability_mount_raptor","class":2,"type":6,"requiresLevel":1},
{"id":415370,"name":"Engrave Chest - Lone Wolf","icon":"ability_mount_whitedirewolf","class":2,"type":5,"requiresLevel":1},
{"id":415399,"name":"Engrave Pants - Sniper Training","icon":"ability_hunter_longshots","class":2,"type":9,"requiresLevel":1},
{"id":415413,"name":"Engrave Helm - Lock and Load","icon":"ability_hunter_lockandload","class":2,"type":1,"requiresLevel":1},
Expand Down Expand Up @@ -9900,6 +9901,7 @@
{"id":427717,"name":"Engrave Bracers - Unstable Affliction","icon":"spell_shadow_unstableaffliction_3","class":8,"type":6,"requiresLevel":1},
{"id":427726,"name":"Engrave Bracers - Immolation Aura","icon":"spell_fire_felimmolation","class":8,"type":6,"requiresLevel":1},
{"id":427733,"name":"Engrave Bracers - Summon Felguard","icon":"spell_shadow_summonfelguard","class":8,"type":6,"requiresLevel":1},
{"id":428726,"name":"Engrave Bracers - Focus Fire","icon":"inv_weapon_crossbow_19","class":2,"type":6,"requiresLevel":1},
{"id":428738,"name":"Engrave Helm - Advanced Warding","icon":"spell_arcane_arcaneresilience","class":3,"type":1,"requiresLevel":1},
{"id":428739,"name":"Engrave Helm - Deep Freeze","icon":"ability_mage_deepfreeze","class":3,"type":1,"requiresLevel":1},
{"id":428741,"name":"Engrave Bracers - Molten Armor","icon":"ability_mage_moltenarmor","class":3,"type":6,"requiresLevel":1},
Expand Down Expand Up @@ -13585,6 +13587,7 @@
{"id":426445,"name":"Engrave Belt - Grimoire of Synergy","icon":"inv_misc_desecrated_leatherbelt","requiresLevel":1},
{"id":426452,"name":"Engrave Belt - Shadow and Flame","icon":"inv_misc_desecrated_leatherbelt","requiresLevel":1},
{"id":426467,"name":"Engrave Boots - Shadowflame","icon":"inv_misc_desecrated_leatherboots","requiresLevel":1},
{"id":428728,"name":"Frenzy","icon":"ability_ghoulfrenzy","requiresLevel":1},
{"id":429304,"name":"Engrave Helm - Deep Freeze","icon":"inv_misc_desecrated_leatherhelm","requiresLevel":1},
{"id":429306,"name":"Engrave Helm - Temporal Anomaly","icon":"inv_misc_desecrated_leatherhelm","requiresLevel":1},
{"id":429308,"name":"Engrave Bracers - Molten Armor","icon":"inv_misc_desecrated_clothbracer","requiresLevel":1},
Expand Down
3 changes: 3 additions & 0 deletions proto/hunter.proto
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ enum HunterRune {
RuneBootsInvigoration = 437997;

RuneHelmLockAndLoad = 415413;

RuneBracersFocusFire = 428726;
RuneBracersRaptorFury = 415358;
}

message Hunter {
Expand Down
100 changes: 100 additions & 0 deletions sim/hunter/focus_fire.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package hunter

import (
"time"

"github.com/wowsims/sod/sim/core"
"github.com/wowsims/sod/sim/core/proto"
)

func (hunter *Hunter) registerFocusFireSpell() {
if hunter.pet == nil || !hunter.HasRune(proto.HunterRune_RuneBracersFocusFire) {
return
}

focusFireMetrics := hunter.pet.NewFocusMetrics(core.ActionID{SpellID: int32(proto.HunterRune_RuneBracersFocusFire)})
focusFireActionId := core.ActionID{SpellID: int32(proto.HunterRune_RuneBracersFocusFire)}
focusFireFrenzyActionId := core.ActionID{SpellID: 428728}

// For tracking in timeline
hunterFrenzyAura := hunter.RegisterAura(core.Aura{
Label: "Focus Fire Frenzy (Hunter)",
ActionID: focusFireFrenzyActionId,
Duration: time.Second * 10,
MaxStacks: 5,
})

hunterPetFrenzyAura := hunter.pet.RegisterAura(core.Aura{
Label: "Focus Fire Frenzy",
ActionID: focusFireFrenzyActionId,
Duration: time.Second * 10,
MaxStacks: 5,
OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks int32, newStacks int32) {
// revert previous attack speed bonus from stacks and apply new attack speed bonus
aura.Unit.MultiplyMeleeSpeed(sim, 1/(1+(0.06*float64(oldStacks))))
aura.Unit.MultiplyMeleeSpeed(sim, 1+(0.06*float64(newStacks)))

// this is just so we can see the frenzy stacks working on the sim timeline
if !hunterFrenzyAura.IsActive() { hunterFrenzyAura.Activate(sim) }
hunterFrenzyAura.SetStacks(sim, newStacks)
},
})

hunterFocusFireAura := hunter.RegisterAura(core.Aura{
Label: "Focus Fire",
ActionID: focusFireActionId,
Duration: time.Second * 20,
MaxStacks: 5,
OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
aura.Unit.MultiplyRangedSpeed(sim, 1/(1+(0.03*float64(oldStacks))))
aura.Unit.MultiplyRangedSpeed(sim, 1+(0.03*float64(newStacks)))
},
})

hunter.pet.RegisterAura(core.Aura{
Label: "Focus Fire Pet",
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.ProcMask.Matches(core.ProcMaskMeleeMHAuto) {
if !hunterPetFrenzyAura.IsActive() {
hunterPetFrenzyAura.Activate(sim)
}

hunterPetFrenzyAura.AddStack(sim)
hunterPetFrenzyAura.Refresh(sim)
hunterFrenzyAura.Refresh(sim)
}
},
})

hunter.FocusFire = hunter.RegisterSpell(core.SpellConfig{
ActionID: focusFireActionId,
Flags: core.SpellFlagAPL,
ManaCost: core.ManaCostOptions{
FlatCost: 0, // TODO: Update when mana cost is known
},
Cast: core.CastConfig{
DefaultCast: core.Cast{
GCD: core.GCDDefault,
},
CD: core.Cooldown{
Timer: hunter.NewTimer(),
Duration: time.Second * 15, // TODO: Update when cooldown is known (Currently using the cooldown value from Cataclysm)
},
},
ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool {
return hunter.pet.IsEnabled() && (hunterPetFrenzyAura.GetStacks() > 0)
},
ApplyEffects: func(sim *core.Simulation, _ *core.Unit, _ *core.Spell) {
frenzyStacks := hunterPetFrenzyAura.GetStacks()
hunter.pet.AddFocus(sim, float64(4 * frenzyStacks), focusFireMetrics)

hunterFocusFireAura.Activate(sim)
hunterFocusFireAura.SetStacks(sim, frenzyStacks)
hunterPetFrenzyAura.SetStacks(sim, 0)
},
})
}
3 changes: 3 additions & 0 deletions sim/hunter/hunter.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type Hunter struct {
KillCommand *core.Spell
KillShot *core.Spell
MultiShot *core.Spell
FocusFire *core.Spell
RapidFire *core.Spell
RaptorStrike *core.Spell
FlankingStrike *core.Spell
Expand All @@ -66,6 +67,7 @@ type Hunter struct {
SerpentStingChimeraShot *core.Spell

FlankingStrikeAura *core.Aura
RaptorFuryAura *core.Aura
SniperTrainingAura *core.Aura
CobraStrikesAura *core.Aura

Expand Down Expand Up @@ -126,6 +128,7 @@ func (hunter *Hunter) Initialize() {

hunter.registerKillCommand()
hunter.registerRapidFire()
hunter.registerFocusFireSpell()
}

func (hunter *Hunter) Reset(sim *core.Simulation) {
Expand Down
26 changes: 24 additions & 2 deletions sim/hunter/raptor_strike.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ func (hunter *Hunter) getRaptorStrikeConfig(rank int) core.SpellConfig {
manaCost := [9]float64{0, 15, 25, 35, 45, 55, 70, 80, 100}[rank]
level := [9]int{0, 1, 8, 16, 24, 32, 40, 48, 56}[rank]
hasFlankingStrike := hunter.HasRune(proto.HunterRune_RuneLegsFlankingStrike)
hasRaptorFury := hunter.HasRune(proto.HunterRune_RuneBracersRaptorFury)
hasDualWieldSpec := hunter.HasRune(proto.HunterRune_RuneBootsDualWieldSpecialization)
hasMeleeSpecialist := hunter.HasRune(proto.HunterRune_RuneBeltMeleeSpecialist)

flankingStrikeDmgMult := 0.1
raptorFuryDmgMult := 0.15 // TODO: Verify value after launch, has been datamined to possibly get changed to 0.1 instead of 0.15 but until further confirmation

if hasMeleeSpecialist {
spellId = [9]int32{0, 415335, 415336, 415337, 415338, 415340, 415341, 415342, 415343}[rank]
}
Expand Down Expand Up @@ -73,6 +77,9 @@ func (hunter *Hunter) getRaptorStrikeConfig(rank int) core.SpellConfig {
DamageMultiplier: 1 * dwSpecMulti,

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
flankingStrikeStacks := float64(hunter.FlankingStrikeAura.GetStacks())
raptorFuryStacks := float64(hunter.RaptorFuryAura.GetStacks())

weaponDamage := 0.0
if hasMeleeSpecialist {
weaponDamage = spell.Unit.MHNormalizedWeaponDamage(sim, spell.MeleeAttackPower())
Expand All @@ -85,13 +92,17 @@ func (hunter *Hunter) getRaptorStrikeConfig(rank int) core.SpellConfig {
spell.BonusWeaponDamage()

if hasFlankingStrike && hunter.FlankingStrikeAura.IsActive() {
mhBaseDamage *= 1.0 + (0.1 * float64(hunter.FlankingStrikeAura.GetStacks()))
mhBaseDamage *= 1.0 + (flankingStrikeDmgMult * flankingStrikeStacks)
}

if hasFlankingStrike && sim.RandomFloat("Flanking Strike Refresh") < 0.2 {
hunter.FlankingStrike.CD.Set(sim.CurrentTime)
}

if hasRaptorFury && hunter.RaptorFuryAura.IsActive() {
mhBaseDamage *= 1.0 + (raptorFuryDmgMult * raptorFuryStacks)
}

spell.CalcAndDealDamage(sim, target, mhBaseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit)

if ohSpell != nil {
Expand All @@ -109,7 +120,11 @@ func (hunter *Hunter) getRaptorStrikeConfig(rank int) core.SpellConfig {
ohSpell.BonusWeaponDamage()

if hasFlankingStrike && hunter.FlankingStrikeAura.IsActive() {
ohBaseDamage *= 1.0 + (0.1 * float64(hunter.FlankingStrikeAura.GetStacks()))
ohBaseDamage *= 1.0 + (flankingStrikeDmgMult * flankingStrikeStacks)
}

if hasRaptorFury && hunter.RaptorFuryAura.IsActive() {
ohBaseDamage *= 1.0 + (raptorFuryDmgMult * raptorFuryStacks)
}

ohSpell.CalcAndDealDamage(sim, target, ohBaseDamage, ohSpell.OutcomeMeleeWeaponSpecialHitAndCrit)
Expand All @@ -122,6 +137,13 @@ func (hunter *Hunter) getRaptorStrikeConfig(rank int) core.SpellConfig {
if hasMeleeSpecialist && sim.RandomFloat("Raptor Strike Reset") < 0.3 {
spell.CD.Reset()
}

if hasRaptorFury {
if !hunter.RaptorFuryAura.IsActive() {
hunter.RaptorFuryAura.Activate(sim)
}
hunter.RaptorFuryAura.AddStack(sim)
}
},
}

Expand Down
16 changes: 15 additions & 1 deletion sim/hunter/runes.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (hunter *Hunter) ApplyRunes() {
hunter.applyExposeWeakness()
hunter.applyInvigoration()
hunter.applyLockAndLoad()
hunter.applyRaptorFury()
}

func (hunter *Hunter) applyInvigoration() {
Expand Down Expand Up @@ -194,9 +195,22 @@ func (hunter *Hunter) applyLockAndLoad() {
OnCastComplete: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell) {
if spell.ProcMask.Matches(core.ProcMaskRangedSpecial) && spell.Flags.Matches(core.SpellFlagMeleeMetrics) {
aura.Deactivate(sim)
hunter.AddMana(sim, spell.DefaultCast.Cost, lockAndLoadMetrics)
hunter.AddMana(sim, spell.CurCast.Cost, lockAndLoadMetrics)
spell.CD.Reset()
}
},
})
}

func (hunter *Hunter) applyRaptorFury() {
if !hunter.HasRune(proto.HunterRune_RuneBracersRaptorFury){
return
}

hunter.RaptorFuryAura = hunter.GetOrRegisterAura(core.Aura{
Label: "Raptor Fury Buff",
ActionID: core.ActionID{SpellID: int32(proto.HunterRune_RuneBracersRaptorFury)},
Duration: time.Second * 15,
MaxStacks: 5,
})
}
2 changes: 0 additions & 2 deletions tools/database/rune_overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ var UnimplementedRuneOverrides = []int32{
// Hunter
415428, // Catlike Reflexes
415405, // Rapid Killing
428726, // Focus Fire
415358, // Raptor Fury
428717, // T.N.T.

// Paladin
Expand Down

0 comments on commit c793cd0

Please sign in to comment.