Skip to content

Commit

Permalink
blood dk related updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Rosen Rusinov committed Apr 24, 2024
1 parent e6bfa17 commit c5db23e
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 132 deletions.
2 changes: 0 additions & 2 deletions sim/core/metrics_aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,6 @@ type SpellMetrics struct {
Parries int32
Blocks int32

// Partial or full resists aren't tracked, at the moment, cp. applyResistances()

TotalDamage float64 // Damage done by all casts of this spell.
TotalThreat float64 // Threat generated by all casts of this spell.
TotalHealing float64 // Healing done by all casts of this spell.
Expand Down
3 changes: 2 additions & 1 deletion sim/core/vengeance.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ func UpdateVengeance(sim *Simulation, character *Character, tracker *VengeanceTr
tracker.apBonus -= (VengeanceAPDecayRate * tracker.recentMaxAPBonus)
}

// TODO: verify that stam actually shows up in this formula, currently implemented as simcraft has it
// Vengeance tooltip is wrong in sake of simplicity as stated by blizzard
// Actual formula used is Stamina + 10% of Base HP
apBonusMax := character.GetStat(stats.Stamina) + 0.1*character.MaxHealth()
tracker.apBonus = Clamp(tracker.apBonus, 0, apBonusMax)

Expand Down
104 changes: 0 additions & 104 deletions sim/death_knight/_heart_strike.go

This file was deleted.

52 changes: 44 additions & 8 deletions sim/death_knight/blood/blood.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package blood

import (
"time"

"github.com/wowsims/cata/sim/core"
"github.com/wowsims/cata/sim/core/proto"
"github.com/wowsims/cata/sim/core/stats"
"github.com/wowsims/cata/sim/death_knight"
)

Expand All @@ -25,6 +28,8 @@ func RegisterBloodDeathKnight() {

type BloodDeathKnight struct {
*death_knight.DeathKnight

vengeance *core.VengeanceTracker
}

func NewBloodDeathKnight(character *core.Character, options *proto.Player) *BloodDeathKnight {
Expand All @@ -35,6 +40,7 @@ func NewBloodDeathKnight(character *core.Character, options *proto.Player) *Bloo
IsDps: false,
StartingRunicPower: dkOptions.Options.ClassOptions.StartingRunicPower,
}, options.TalentsString, 50034),
vengeance: &core.VengeanceTracker{},
}

bdk.EnableAutoAttacks(bdk, core.AutoAttackOptions{
Expand All @@ -53,17 +59,47 @@ func NewBloodDeathKnight(character *core.Character, options *proto.Player) *Bloo
return bdk
}

func (dk *BloodDeathKnight) GetDeathKnight() *death_knight.DeathKnight {
return dk.DeathKnight
func (bdk *BloodDeathKnight) GetDeathKnight() *death_knight.DeathKnight {
return bdk.DeathKnight
}

func (bdk *BloodDeathKnight) Initialize() {
bdk.DeathKnight.Initialize()

bdk.registerHeartStrikeSpell()
}

func (dk *BloodDeathKnight) Initialize() {
dk.DeathKnight.Initialize()
func (bdk BloodDeathKnight) getMasteryBonus() float64 {
return 0.5 + 0.0625*bdk.GetMasteryPoints()
}

func (dk *BloodDeathKnight) Reset(sim *core.Simulation) {
dk.DeathKnight.Reset(sim)
func (bdk *BloodDeathKnight) ApplyTalents() {
bdk.DeathKnight.ApplyTalents()

// Veteran of the Third War
bdk.AddStaticMod(core.SpellModConfig{
Kind: core.SpellMod_Cooldown_Flat,
ClassMask: death_knight.DeathKnightSpellOutbreak,
TimeValue: time.Second * -30,
})
bdk.MultiplyStat(stats.Stamina, 1.09)
bdk.AddStat(stats.Expertise, 6*core.ExpertisePerQuarterPercentReduction)
core.MakePermanent(bdk.GetOrRegisterAura(core.Aura{
Label: "Veteran of the Third War",
ActionID: core.ActionID{SpellID: 50029},
}))

// Vengeance
core.ApplyVengeanceEffect(&bdk.Character, bdk.vengeance, 93099)

// Mastery: Blood Shield
core.MakePermanent(bdk.GetOrRegisterAura(core.Aura{
Label: "Blood Shield",
ActionID: core.ActionID{SpellID: 77513},
}))

}

//dk.Presence = death_knight.UnsetPresence
//dk.DeathKnight.PseudoStats.Stunned = false
func (bdk *BloodDeathKnight) Reset(sim *core.Simulation) {
bdk.DeathKnight.Reset(sim)
}
69 changes: 69 additions & 0 deletions sim/death_knight/blood/heart_strike.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package blood

import (
"github.com/wowsims/cata/sim/core"
"github.com/wowsims/cata/sim/death_knight"
)

var HeartStrikeActionID = core.ActionID{SpellID: 55050}

func (dk *BloodDeathKnight) registerHeartStrikeSpell() {
numHits := min(3, dk.Env.GetNumTargets())
results := make([]*core.SpellResult, numHits)

dk.GetOrRegisterSpell(core.SpellConfig{
ActionID: HeartStrikeActionID,
SpellSchool: core.SpellSchoolPhysical,
ProcMask: core.ProcMaskMeleeMHSpecial,
Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL,
ClassSpellMask: death_knight.DeathKnightSpellHeartStrike,

RuneCost: core.RuneCostOptions{
BloodRuneCost: 1,
RunicPowerGain: 10,
Refundable: true,
},
Cast: core.CastConfig{
DefaultCast: core.Cast{
GCD: core.GCDDefault,
},
IgnoreHaste: true,
},

DamageMultiplier: 1.75,
CritMultiplier: dk.DefaultMeleeCritMultiplier(),
ThreatMultiplier: 1,

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
baseDamage := dk.ClassBaseScaling*0.72799998522 +
spell.Unit.MHNormalizedWeaponDamage(sim, spell.MeleeAttackPower())

currentTarget := target
for idx := int32(0); idx < numHits; idx++ {
targetDamage := baseDamage * dk.GetDiseaseMulti(currentTarget, 1.0, 0.15)

results[idx] = spell.CalcDamage(sim, currentTarget, targetDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit)
if idx == 0 {
spell.SpendRefundableCost(sim, results[idx])
}

spell.DamageMultiplier *= 0.75
currentTarget = dk.Env.NextTargetUnit(currentTarget)
}

for _, result := range results {
spell.DealDamage(sim, result)
spell.DamageMultiplier /= 0.75
}
},
})
}

// func (dk *DeathKnight) registerDrwHeartStrikeSpell() {
// if !dk.Talents.HeartStrike {
// return
// }

// dk.RuneWeapon.HeartStrike = dk.newHeartStrikeSpell(true, true)
// dk.RuneWeapon.HeartStrikeOffHit = dk.newHeartStrikeSpell(false, true)
// }
2 changes: 2 additions & 0 deletions sim/death_knight/death_knight.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ const (
DeathKnightSpellPlagueStrike
DeathKnightSpellFesteringStrike
DeathKnightSpellScourgeStrike
DeathKnightSpellHeartStrike
DeathKnightSpellDeathStrike
DeathKnightSpellScourgeStrikeShadow
DeathKnightSpellFrostFever
DeathKnightSpellBloodPlague
Expand Down
4 changes: 2 additions & 2 deletions sim/death_knight/diseases.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func (dk *DeathKnight) DiseasesAreActive(target *core.Unit) bool {
return dk.FrostFeverSpell.Dot(target).IsActive() || dk.BloodPlagueSpell.Dot(target).IsActive()
}

func (dk *DeathKnight) CountActiveDiseases(target *core.Unit) float64 {
func (dk *DeathKnight) GetDiseaseMulti(target *core.Unit, base float64, increase float64) float64 {
count := 0
if dk.FrostFeverSpell.Dot(target).IsActive() {
count++
Expand All @@ -21,7 +21,7 @@ func (dk *DeathKnight) CountActiveDiseases(target *core.Unit) float64 {
if dk.Talents.EbonPlaguebringer > 0 && dk.EbonPlagueAura.Get(target).IsActive() {
count++
}
return float64(count)
return base + increase*float64(count)
}

func (dk *DeathKnight) registerOutbreak() {
Expand Down
35 changes: 34 additions & 1 deletion sim/death_knight/glyphs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,40 @@ func (dk *DeathKnight) ApplyGlyphs() {
dk.AddStaticMod(core.SpellModConfig{
Kind: core.SpellMod_DamageDone_Flat,
ClassMask: DeathKnightSpellScourgeStrikeShadow,
FloatValue: 0.30,
FloatValue: 0.3,
})
}

if dk.HasPrimeGlyph(proto.DeathKnightPrimeGlyph_GlyphOfHeartStrike) {
dk.AddStaticMod(core.SpellModConfig{
Kind: core.SpellMod_DamageDone_Flat,
ClassMask: DeathKnightSpellHeartStrike,
FloatValue: 0.3,
})
}

if dk.HasPrimeGlyph(proto.DeathKnightPrimeGlyph_GlyphOfDeathStrike) {
dsMod := dk.AddDynamicMod(core.SpellModConfig{
Kind: core.SpellMod_DamageDone_Pct,
ClassMask: DeathKnightSpellDeathStrike,
})

core.MakeProcTriggerAura(&dk.Unit, core.ProcTrigger{
Name: "Death Strike Glyph Activate",
Callback: core.CallbackOnApplyEffects,
ClassSpellMask: DeathKnightSpellDeathStrike,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
dsMod.UpdateFloatValue(min(0.4, (dk.CurrentRunicPower()/5.0)*0.02))
dsMod.Activate()
},
})
}

if dk.HasPrimeGlyph(proto.DeathKnightPrimeGlyph_GlyphOfRuneStrike) {
dk.AddStaticMod(core.SpellModConfig{
Kind: core.SpellMod_BonusCrit_Rating,
ClassMask: DeathKnightSpellRuneStrike,
FloatValue: 10 * core.CritRatingPerCritChance,
})
}

Expand Down
10 changes: 7 additions & 3 deletions sim/death_knight/howling_blast.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ func (dk *DeathKnight) registerHowlingBlastSpell() {
return
}

results := make([]*core.SpellResult, dk.Env.GetNumTargets())

dk.RegisterSpell(core.SpellConfig{
ActionID: HowlingBlastActionID,
Flags: core.SpellFlagAPL,
Expand All @@ -35,14 +37,16 @@ func (dk *DeathKnight) registerHowlingBlastSpell() {
CritMultiplier: dk.DefaultMeleeCritMultiplier(),

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
results := make([]*core.SpellResult, sim.GetNumTargets())
for idx, aoeTarget := range sim.Encounter.TargetUnits {
baseDamage := dk.ClassBaseScaling*1.17499995232 + 0.44*spell.MeleeAttackPower()

if aoeTarget != target {
baseDamage *= 0.5
spell.DamageMultiplier *= 0.5
results[idx] = spell.CalcDamage(sim, aoeTarget, baseDamage, spell.OutcomeMagicHitAndCrit)
spell.DamageMultiplier /= 0.5
} else {
results[idx] = spell.CalcDamage(sim, aoeTarget, baseDamage, spell.OutcomeMagicHitAndCrit)
}
results[idx] = spell.CalcDamage(sim, aoeTarget, baseDamage, spell.OutcomeMagicHitAndCrit)

if aoeTarget == target {
spell.SpendRefundableCost(sim, results[idx])
Expand Down
2 changes: 1 addition & 1 deletion sim/death_knight/obliterate.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (dk *DeathKnight) registerObliterateSpell() {
baseDamage := dk.ClassBaseScaling*0.57800000906 +
spell.Unit.MHNormalizedWeaponDamage(sim, spell.MeleeAttackPower())

baseDamage *= 1.0 + dk.CountActiveDiseases(target)*0.125
baseDamage *= dk.GetDiseaseMulti(target, 1.0, 0.125)

result := spell.CalcDamage(sim, target, baseDamage, spell.OutcomeMeleeWeaponSpecialHitAndCrit)

Expand Down
Loading

0 comments on commit c5db23e

Please sign in to comment.