Skip to content

Commit

Permalink
[core] introduce WeaponAttack, a per weapon (MH, OH, Ranged) AutoAttack
Browse files Browse the repository at this point in the history
[warrior] ranged attacks (namely Thunder Clap) now properly trigger MH Deep Wounds
  • Loading branch information
vigo2 committed Oct 31, 2023
1 parent b234954 commit c089322
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 294 deletions.
449 changes: 205 additions & 244 deletions sim/core/attack.go

Large diffs are not rendered by default.

19 changes: 9 additions & 10 deletions sim/core/character.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,16 +624,15 @@ func (character *Character) doneIteration(sim *Simulation) {
}

func (character *Character) GetPseudoStatsProto() []float64 {
vals := make([]float64, stats.PseudoStatsLen)
vals[proto.PseudoStat_PseudoStatMainHandDps] = character.AutoAttacks.MH().DPS()
vals[proto.PseudoStat_PseudoStatOffHandDps] = character.AutoAttacks.OH().DPS()
vals[proto.PseudoStat_PseudoStatRangedDps] = character.AutoAttacks.Ranged().DPS()
vals[proto.PseudoStat_PseudoStatBlockValueMultiplier] = character.PseudoStats.BlockValueMultiplier
// Base values are modified by Enemy attackTables, but we display for LVL 80 enemy as paperdoll default
vals[proto.PseudoStat_PseudoStatDodge] = character.PseudoStats.BaseDodge + character.GetDiminishedDodgeChance()
vals[proto.PseudoStat_PseudoStatParry] = character.PseudoStats.BaseParry + character.GetDiminishedParryChance()
//vals[proto.PseudoStat_PseudoStatMiss] = 0.05 + character.GetDiminishedMissChance() + character.PseudoStats.ReducedPhysicalHitTakenChance
return vals
return []float64{
proto.PseudoStat_PseudoStatMainHandDps: character.AutoAttacks.MH().DPS(),
proto.PseudoStat_PseudoStatOffHandDps: character.AutoAttacks.OH().DPS(),
proto.PseudoStat_PseudoStatRangedDps: character.AutoAttacks.Ranged().DPS(),
proto.PseudoStat_PseudoStatBlockValueMultiplier: character.PseudoStats.BlockValueMultiplier,
// Base values are modified by Enemy attackTables, but we display for LVL 80 enemy as paperdoll default
proto.PseudoStat_PseudoStatDodge: character.PseudoStats.BaseDodge + character.GetDiminishedDodgeChance(),
proto.PseudoStat_PseudoStatParry: character.PseudoStats.BaseParry + character.GetDiminishedParryChance(),
}
}

func (character *Character) GetMetricsProto() *proto.UnitMetrics {
Expand Down
2 changes: 0 additions & 2 deletions sim/core/item_swaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,6 @@ func (swap *ItemSwap) swapWeapon(slot proto.ItemSlot) {
character.AutoAttacks.SetRanged(character.WeaponFromRanged(swap.rangedCritMultiplier))
}
}

character.AutoAttacks.isDualWielding = character.MainHand().SwingSpeed != 0 && character.OffHand().SwingSpeed != 0
}

func (swap *ItemSwap) finalize() {
Expand Down
8 changes: 4 additions & 4 deletions sim/druid/forms.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (druid *Druid) registerCatFormSpell() {
}

if !druid.Env.MeasuringStats {
druid.AutoAttacks.ReplaceMHSwing = nil
druid.AutoAttacks.SetReplaceMHSwing(nil)
druid.AutoAttacks.EnableAutoSwing(sim)
druid.manageCooldownsEnabled()
druid.UpdateManaRegenRates()
Expand Down Expand Up @@ -181,7 +181,7 @@ func (druid *Druid) registerCatFormSpell() {
}

if !druid.Env.MeasuringStats {
druid.AutoAttacks.ReplaceMHSwing = nil
druid.AutoAttacks.SetReplaceMHSwing(nil)
druid.AutoAttacks.EnableAutoSwing(sim)
druid.manageCooldownsEnabled()
druid.UpdateManaRegenRates()
Expand Down Expand Up @@ -292,7 +292,7 @@ func (druid *Druid) registerBearFormSpell() {
druid.GainHealth(sim, healthFrac*druid.MaxHealth()-druid.CurrentHealth(), healthMetrics)

if !druid.Env.MeasuringStats {
druid.AutoAttacks.ReplaceMHSwing = druid.ReplaceBearMHFunc
druid.AutoAttacks.SetReplaceMHSwing(druid.ReplaceBearMHFunc)
druid.AutoAttacks.EnableAutoSwing(sim)

druid.manageCooldownsEnabled()
Expand Down Expand Up @@ -324,7 +324,7 @@ func (druid *Druid) registerBearFormSpell() {
druid.RemoveHealth(sim, druid.CurrentHealth()-healthFrac*druid.MaxHealth())

if !druid.Env.MeasuringStats {
druid.AutoAttacks.ReplaceMHSwing = nil
druid.AutoAttacks.SetReplaceMHSwing(nil)
druid.AutoAttacks.EnableAutoSwing(sim)

druid.manageCooldownsEnabled()
Expand Down
4 changes: 2 additions & 2 deletions sim/encounters/ulduar/hodir_ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,12 @@ func (ai *HodirAI) registerFrozenBlowSpell(target *core.Target) {
})

// Replace MH Hit when under Frozen Blows buff
ai.Target.Unit.AutoAttacks.ReplaceMHSwing = func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
ai.Target.Unit.AutoAttacks.SetReplaceMHSwing(func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
if ai.FrozenBlowsAura.IsActive() {
return ai.FrozenBlowsAuto
}
return mhSwingSpell
}
})

ai.FrozenBlowsAuto = target.GetOrRegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: core.TernaryInt32(ai.raidSize == 25, 63511, 62867)}.WithTag(1),
Expand Down
10 changes: 5 additions & 5 deletions sim/shaman/enhancement/enhancement.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,25 +160,25 @@ func (enh *EnhancementShaman) ApplySyncType(syncType proto.ShamanSyncType) {

switch syncType {
case proto.ShamanSyncType_SyncMainhandOffhandSwings:
enh.AutoAttacks.ReplaceMHSwing = func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
enh.AutoAttacks.SetReplaceMHSwing(func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
if aa := &enh.AutoAttacks; aa.OffhandSwingAt()-sim.CurrentTime > FlurryICD {
if nextMHSwingAt := sim.CurrentTime + aa.MainhandSwingSpeed(); nextMHSwingAt > aa.OffhandSwingAt() {
aa.SetOffhandSwingAt(nextMHSwingAt)
}
}
return mhSwingSpell
}
})
case proto.ShamanSyncType_DelayOffhandSwings:
enh.AutoAttacks.ReplaceMHSwing = func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
enh.AutoAttacks.SetReplaceMHSwing(func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
if aa := &enh.AutoAttacks; aa.OffhandSwingAt()-sim.CurrentTime > FlurryICD {
if nextMHSwingAt := sim.CurrentTime + aa.MainhandSwingSpeed() + 100*time.Millisecond; nextMHSwingAt > aa.OffhandSwingAt() {
aa.SetOffhandSwingAt(nextMHSwingAt)
}
}
return mhSwingSpell
}
})
default:
enh.AutoAttacks.ReplaceMHSwing = nil
enh.AutoAttacks.SetReplaceMHSwing(nil)
}
}

Expand Down
14 changes: 7 additions & 7 deletions sim/warrior/deep_wounds.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,27 @@ func (warrior *Warrior) applyDeepWounds() {
return
}
if result.Outcome.Matches(core.OutcomeCrit) {
warrior.procDeepWounds(sim, result.Target, spell.IsMH())
warrior.procDeepWounds(sim, result.Target, spell.IsOH())
}
},
})
}

func (warrior *Warrior) procDeepWounds(sim *core.Simulation, target *core.Unit, isMh bool) {
func (warrior *Warrior) procDeepWounds(sim *core.Simulation, target *core.Unit, isOh bool) {
dot := warrior.DeepWounds.Dot(target)

outstandingDamage := core.TernaryFloat64(dot.IsActive(), dot.SnapshotBaseDamage*float64(dot.NumberOfTicks-dot.TickCount), 0)

attackTable := warrior.AttackTables[target.UnitIndex]
var awd float64
if isMh {
adm := warrior.AutoAttacks.MHAuto().AttackerDamageMultiplier(attackTable)
tdm := warrior.AutoAttacks.MHAuto().TargetDamageMultiplier(attackTable, false)
awd = (warrior.AutoAttacks.MH().CalculateAverageWeaponDamage(dot.Spell.MeleeAttackPower()) + dot.Spell.BonusWeaponDamage()) * adm * tdm
} else {
if isOh {
adm := warrior.AutoAttacks.OHAuto().AttackerDamageMultiplier(attackTable)
tdm := warrior.AutoAttacks.OHAuto().TargetDamageMultiplier(attackTable, false)
awd = ((warrior.AutoAttacks.OH().CalculateAverageWeaponDamage(dot.Spell.MeleeAttackPower()) * 0.5) + dot.Spell.BonusWeaponDamage()) * adm * tdm
} else { // MH, Ranged (e.g. Thunder Clap)
adm := warrior.AutoAttacks.MHAuto().AttackerDamageMultiplier(attackTable)
tdm := warrior.AutoAttacks.MHAuto().TargetDamageMultiplier(attackTable, false)
awd = (warrior.AutoAttacks.MH().CalculateAverageWeaponDamage(dot.Spell.MeleeAttackPower()) + dot.Spell.BonusWeaponDamage()) * adm * tdm
}
newDamage := awd * 0.16 * float64(warrior.Talents.DeepWounds)

Expand Down
16 changes: 8 additions & 8 deletions sim/warrior/dps/TestArms.results
Original file line number Diff line number Diff line change
Expand Up @@ -932,8 +932,8 @@ dps_results: {
dps_results: {
key: "TestArms-Settings-Human-p1_arms-Basic-arms-FullBuffs-LongMultiTarget"
value: {
dps: 10652.07342
tps: 10007.49125
dps: 11906.57829
tps: 11011.09514
}
}
dps_results: {
Expand All @@ -953,8 +953,8 @@ dps_results: {
dps_results: {
key: "TestArms-Settings-Human-p1_arms-Basic-arms-NoBuffs-LongMultiTarget"
value: {
dps: 5528.79397
tps: 5348.07684
dps: 6198.0661
tps: 5883.49454
}
}
dps_results: {
Expand Down Expand Up @@ -1016,8 +1016,8 @@ dps_results: {
dps_results: {
key: "TestArms-Settings-Orc-p1_arms-Basic-arms-FullBuffs-LongMultiTarget"
value: {
dps: 10689.87998
tps: 10049.09221
dps: 11940.61768
tps: 11049.68237
}
}
dps_results: {
Expand All @@ -1037,8 +1037,8 @@ dps_results: {
dps_results: {
key: "TestArms-Settings-Orc-p1_arms-Basic-arms-NoBuffs-LongMultiTarget"
value: {
dps: 5670.62396
tps: 5482.18162
dps: 6345.88031
tps: 6022.3867
}
}
dps_results: {
Expand Down
24 changes: 12 additions & 12 deletions sim/warrior/protection/TestProtectionWarrior.results
Original file line number Diff line number Diff line change
Expand Up @@ -950,22 +950,22 @@ dps_results: {
dps_results: {
key: "TestProtectionWarrior-Settings-Human-p1_balanced-Basic-default-NoBuffs-LongMultiTarget"
value: {
dps: 1050.46307
tps: 3335.71088
dps: 1084.94322
tps: 3407.20547
}
}
dps_results: {
key: "TestProtectionWarrior-Settings-Human-p1_balanced-Basic-default-NoBuffs-LongSingleTarget"
value: {
dps: 865.20912
tps: 2483.44764
dps: 866.97075
tps: 2487.10038
}
}
dps_results: {
key: "TestProtectionWarrior-Settings-Human-p1_balanced-Basic-default-NoBuffs-ShortSingleTarget"
value: {
dps: 831.10607
tps: 2403.87441
dps: 833.49622
tps: 2408.83039
}
}
dps_results: {
Expand All @@ -992,22 +992,22 @@ dps_results: {
dps_results: {
key: "TestProtectionWarrior-Settings-Orc-p1_balanced-Basic-default-NoBuffs-LongMultiTarget"
value: {
dps: 1063.03306
tps: 3372.37903
dps: 1097.36592
tps: 3443.56821
}
}
dps_results: {
key: "TestProtectionWarrior-Settings-Orc-p1_balanced-Basic-default-NoBuffs-LongSingleTarget"
value: {
dps: 880.11232
tps: 2527.63516
dps: 881.93425
tps: 2531.41294
}
}
dps_results: {
key: "TestProtectionWarrior-Settings-Orc-p1_balanced-Basic-default-NoBuffs-ShortSingleTarget"
value: {
dps: 853.54235
tps: 2468.41035
dps: 854.88707
tps: 2471.19863
}
}
dps_results: {
Expand Down

0 comments on commit c089322

Please sign in to comment.