Skip to content

Commit

Permalink
fix warlock T2.5 Tank 4p
Browse files Browse the repository at this point in the history
  • Loading branch information
kayla-glick committed Nov 30, 2024
1 parent 974752a commit dc922c9
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 81 deletions.
24 changes: 24 additions & 0 deletions sim/core/pet.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@ func (pet *Pet) Enable(sim *Simulation, petAgent PetAgent) {
}
}

func (pet *Pet) ApplyOnPetEnable(newOnPetEnable OnPetEnable) {
oldOnPetEnable := pet.OnPetEnable
if oldOnPetEnable == nil {
pet.OnPetEnable = oldOnPetEnable
} else {
pet.OnPetEnable = func(sim *Simulation) {
oldOnPetEnable(sim)
newOnPetEnable(sim)
}
}
}

// Helper for enabling a pet that will expire after a certain duration.
func (pet *Pet) EnableWithTimeout(sim *Simulation, petAgent PetAgent, petDuration time.Duration) {
pet.Enable(sim, petAgent)
Expand Down Expand Up @@ -260,6 +272,18 @@ func (pet *Pet) Disable(sim *Simulation) {
}
}

func (pet *Pet) ApplyOnPetDisable(newOnPetDisable OnPetDisable) {
oldOnPetDisable := pet.OnPetDisable
if oldOnPetDisable == nil {
pet.OnPetDisable = oldOnPetDisable
} else {
pet.OnPetDisable = func(sim *Simulation) {
oldOnPetDisable(sim)
newOnPetDisable(sim)
}
}
}

func (pet *Pet) UpdateStatInheritance(newStatInheritance PetStatInheritance) {
pet.statInheritance = newStatInheritance
}
Expand Down
2 changes: 1 addition & 1 deletion sim/warlock/item_sets_pve.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ var ItemSetDoomcallersMalevolence = core.NewItemSet(core.ItemSet{
core.MakePermanent(warlock.RegisterAura(core.Aura{
Label: "S03 - Item - TAQ - Warlock - Tank 4P Bonus",
OnInit: func(aura *core.Aura, sim *core.Simulation) {
warlock.disableMasterDemonologistOnSacrifice = false
warlock.maintainBuffsOnSacrifice = true
},
}))
},
Expand Down
41 changes: 31 additions & 10 deletions sim/warlock/pet.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import (
"github.com/wowsims/sod/sim/core/stats"
)

type OnPetDisable func(sim *core.Simulation, isSacrifice bool)

type WarlockPet struct {
core.Pet

OnPetDisable OnPetDisable

owner *Warlock

primaryAbility *core.Spell
Expand Down Expand Up @@ -50,13 +54,13 @@ func (warlock *Warlock) setDefaultActivePet() {
}

func (warlock *Warlock) changeActivePet(sim *core.Simulation, newPet *WarlockPet, isSacrifice bool) {
hasMasterDemonologist := warlock.MasterDemonologistAura != nil

if warlock.ActivePet != nil {
warlock.ActivePet.Disable(sim)
warlock.ActivePet.Disable(sim, isSacrifice)

// Sacrificed pets lose all buffs
if isSacrifice {
warlock.SacrificedPet = warlock.ActivePet

// Sacrificed pets lose all buffs, but don't remove trigger auras
for _, aura := range warlock.ActivePet.GetAuras() {
if aura.Duration == core.NeverExpires {
continue
Expand All @@ -65,10 +69,6 @@ func (warlock *Warlock) changeActivePet(sim *core.Simulation, newPet *WarlockPet
aura.Deactivate(sim)
}
}

if hasMasterDemonologist && (!isSacrifice || warlock.disableMasterDemonologistOnSacrifice) {
warlock.MasterDemonologistAura.Deactivate(sim)
}
}

warlock.ActivePet = newPet
Expand All @@ -94,8 +94,9 @@ func (warlock *Warlock) registerPets() {

func (warlock *Warlock) makePet(cfg PetConfig, enabledOnStart bool) *WarlockPet {
wp := &WarlockPet{
Pet: core.NewPet(cfg.Name, &warlock.Character, cfg.Stats, warlock.makeStatInheritance(), enabledOnStart, false),
owner: warlock,
Pet: core.NewPet(cfg.Name, &warlock.Character, cfg.Stats, warlock.makeStatInheritance(), enabledOnStart, false),
owner: warlock,
OnPetDisable: func(sim *core.Simulation, isSacrifice bool) {},
}

wp.EnableManaBarWithModifier(cfg.PowerModifier)
Expand Down Expand Up @@ -152,6 +153,26 @@ func (wp *WarlockPet) Reset(_ *core.Simulation) {
wp.manaPooling = false
}

func (wp *WarlockPet) Disable(sim *core.Simulation, isSacrifice bool) {
wp.Pet.Disable(sim)

if wp.OnPetDisable != nil {
wp.OnPetDisable(sim, isSacrifice)
}
}

func (wp *WarlockPet) ApplyOnPetDisable(newOnPetDisable OnPetDisable) {
oldOnPetDisable := wp.OnPetDisable
if oldOnPetDisable == nil {
wp.OnPetDisable = oldOnPetDisable
} else {
wp.OnPetDisable = func(sim *core.Simulation, isSacrifice bool) {
oldOnPetDisable(sim, isSacrifice)
newOnPetDisable(sim, isSacrifice)
}
}
}

func (wp *WarlockPet) ExecuteCustomRotation(sim *core.Simulation) {
if !wp.IsEnabled() || wp.primaryAbility == nil {
return
Expand Down
4 changes: 2 additions & 2 deletions sim/warlock/runes.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ func (warlock *Warlock) applyDemonicKnowledge() {
}

oldOnPetDisable := pet.OnPetDisable
pet.OnPetDisable = func(sim *core.Simulation) {
oldOnPetDisable(sim)
pet.OnPetDisable = func(sim *core.Simulation, isSacrifice bool) {
oldOnPetDisable(sim, isSacrifice)
warlock.DemonicKnowledgeAura.Deactivate(sim)
}
}
Expand Down
200 changes: 139 additions & 61 deletions sim/warlock/talents.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,6 @@ func (warlock *Warlock) applyMasterDemonologist() {
return
}

warlock.disableMasterDemonologistOnSacrifice = true

hasMetaRune := warlock.HasRune(proto.WarlockRune_RuneHandsMetamorphosis)

points := float64(warlock.Talents.MasterDemonologist)
Expand All @@ -299,70 +297,143 @@ func (warlock *Warlock) applyMasterDemonologist() {
threatMultiplier := 1 + (core.TernaryFloat64(hasMetaRune, 0.04*points, -0.04*points) * bonusMultiplier)
bonusResistance := 2 * points * bonusMultiplier

masterDemonologistConfig := core.Aura{
Label: "Master Demonologist",
ActionID: core.ActionID{SpellID: 23825},
impConfig := core.Aura{
Label: "Master Demonologist (Imp)",
ActionID: core.ActionID{SpellID: 23825, Tag: 1},
Duration: core.NeverExpires,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
if warlock.ActivePet == nil {
return
}
aura.Unit.PseudoStats.ThreatMultiplier *= threatMultiplier
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.ThreatMultiplier /= threatMultiplier
},
}

switch warlock.ActivePet {
case warlock.Felguard:
aura.Unit.PseudoStats.DamageDealtMultiplier *= damageDealtMultiplier
aura.Unit.PseudoStats.DamageTakenMultiplier *= damageTakenMultiplier
aura.Unit.PseudoStats.ThreatMultiplier *= threatMultiplier
aura.Unit.AddResistancesDynamic(sim, bonusResistance)
case warlock.Felhunter:
aura.Unit.AddResistancesDynamic(sim, bonusResistance)
case warlock.Imp:
aura.Unit.PseudoStats.ThreatMultiplier *= threatMultiplier
case warlock.Succubus:
aura.Unit.PseudoStats.DamageDealtMultiplier *= damageDealtMultiplier
case warlock.Voidwalker:
aura.Unit.PseudoStats.DamageTakenMultiplier *= damageTakenMultiplier
}
voidwalkerConfig := core.Aura{
Label: "Master Demonologist (Voidwalker)",
ActionID: core.ActionID{SpellID: 23825, Tag: 2},
Duration: core.NeverExpires,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.DamageTakenMultiplier *= damageTakenMultiplier
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
if warlock.ActivePet == nil {
return
aura.Unit.PseudoStats.DamageTakenMultiplier /= damageTakenMultiplier
},
}

succubusConfig := core.Aura{
Label: "Master Demonologist (Succubus)",
ActionID: core.ActionID{SpellID: 23825, Tag: 3},
Duration: core.NeverExpires,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.DamageDealtMultiplier *= damageDealtMultiplier
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.DamageDealtMultiplier /= damageDealtMultiplier
},
}

felhunterConfig := core.Aura{
Label: "Master Demonologist (Felhunter)",
ActionID: core.ActionID{SpellID: 23825, Tag: 4},
Duration: core.NeverExpires,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.AddResistancesDynamic(sim, bonusResistance)
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.AddResistancesDynamic(sim, -bonusResistance)
},
}

for _, pet := range warlock.BasePets {
pet.ApplyOnPetEnable(func(sim *core.Simulation) {
if warlock.MasterDemonologistAura != nil {
warlock.MasterDemonologistAura.Deactivate(sim)
}
})
}

switch warlock.ActivePet {
case warlock.Felguard:
aura.Unit.PseudoStats.DamageDealtMultiplier /= damageDealtMultiplier
aura.Unit.PseudoStats.DamageTakenMultiplier /= damageTakenMultiplier
aura.Unit.PseudoStats.ThreatMultiplier /= threatMultiplier
aura.Unit.AddResistancesDynamic(sim, -bonusResistance)
case warlock.Felhunter:
aura.Unit.AddResistancesDynamic(sim, -bonusResistance)
case warlock.Imp:
warlockImpAura := warlock.RegisterAura(impConfig)
impAura := warlock.Imp.RegisterAura(impConfig)
warlock.Imp.ApplyOnPetEnable(func(sim *core.Simulation) {
impAura.Activate(sim)
warlock.MasterDemonologistAura = warlockImpAura
})
warlock.Imp.ApplyOnPetDisable(func(sim *core.Simulation, isSacrifice bool) {
impAura.Deactivate(sim)
})

warlockVoidwalkerAura := warlock.RegisterAura(voidwalkerConfig)
voidwalkerAura := warlock.Voidwalker.RegisterAura(voidwalkerConfig)
warlock.Voidwalker.ApplyOnPetEnable(func(sim *core.Simulation) {
voidwalkerAura.Activate(sim)
warlock.MasterDemonologistAura = warlockVoidwalkerAura
})
warlock.Voidwalker.ApplyOnPetDisable(func(sim *core.Simulation, isSacrifice bool) {
voidwalkerAura.Deactivate(sim)
})

warlockSuccubusAura := warlock.RegisterAura(succubusConfig)
succubusAura := warlock.Succubus.RegisterAura(succubusConfig)
warlock.Succubus.ApplyOnPetEnable(func(sim *core.Simulation) {
succubusAura.Activate(sim)
warlock.MasterDemonologistAura = warlockSuccubusAura
})
warlock.Succubus.ApplyOnPetDisable(func(sim *core.Simulation, isSacrifice bool) {
succubusAura.Deactivate(sim)
})

warlockFelhunterAura := warlock.RegisterAura(felhunterConfig)
felhunterAura := warlock.Felhunter.RegisterAura(felhunterConfig)
warlock.Felhunter.ApplyOnPetEnable(func(sim *core.Simulation) {
felhunterAura.Activate(sim)
warlock.MasterDemonologistAura = warlockFelhunterAura
})
warlock.Felhunter.ApplyOnPetDisable(func(sim *core.Simulation, isSacrifice bool) {
felhunterAura.Deactivate(sim)
})

if warlock.HasRune(proto.WarlockRune_RuneBracerSummonFelguard) {
felguardConfig := core.Aura{
Label: "Master Demonologist (Felguard)",
ActionID: core.ActionID{SpellID: 23825, Tag: 5},
Duration: core.NeverExpires,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.ThreatMultiplier *= threatMultiplier
aura.Unit.PseudoStats.DamageTakenMultiplier *= damageTakenMultiplier
aura.Unit.PseudoStats.DamageDealtMultiplier *= damageDealtMultiplier
aura.Unit.AddResistancesDynamic(sim, bonusResistance)
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.ThreatMultiplier /= threatMultiplier
case warlock.Succubus:
aura.Unit.PseudoStats.DamageDealtMultiplier /= damageDealtMultiplier
case warlock.Voidwalker:
aura.Unit.PseudoStats.DamageTakenMultiplier /= damageTakenMultiplier
}
},
aura.Unit.PseudoStats.DamageDealtMultiplier /= damageDealtMultiplier
aura.Unit.AddResistancesDynamic(sim, -bonusResistance)
},
}

warlockFelguardAura := warlock.RegisterAura(felguardConfig)
felguardAura := warlock.Felguard.RegisterAura(felguardConfig)
warlock.Felguard.ApplyOnPetEnable(func(sim *core.Simulation) {
felguardAura.Activate(sim)
warlock.MasterDemonologistAura = warlockFelguardAura
})
warlock.Felguard.ApplyOnPetDisable(func(sim *core.Simulation, isSacrifice bool) {
felguardAura.Deactivate(sim)
})
}

warlock.MasterDemonologistAura = warlock.RegisterAura(masterDemonologistConfig)
for _, pet := range warlock.BasePets {
petAura := pet.RegisterAura(masterDemonologistConfig)

oldOnPetEnable := pet.OnPetEnable
pet.OnPetEnable = func(sim *core.Simulation) {
oldOnPetEnable(sim)
pet.ApplyOnPetEnable(func(sim *core.Simulation) {
warlock.MasterDemonologistAura.Activate(sim)
petAura.Activate(sim)
}
})

oldOnPetDisable := pet.OnPetDisable
pet.OnPetDisable = func(sim *core.Simulation) {
oldOnPetDisable(sim)
petAura.Deactivate(sim)
}
pet.ApplyOnPetDisable(func(sim *core.Simulation, isSacrifice bool) {
if !isSacrifice || !warlock.maintainBuffsOnSacrifice {
warlock.MasterDemonologistAura.Deactivate(sim)
warlock.MasterDemonologistAura = nil
}
})
}
}

Expand Down Expand Up @@ -391,8 +462,8 @@ func (warlock *Warlock) applySoulLink() {
pet.SoulLinkAura = pet.RegisterAura(soulLinkConfig)

oldOnPetDisable := pet.OnPetDisable
pet.OnPetDisable = func(sim *core.Simulation) {
oldOnPetDisable(sim)
pet.OnPetDisable = func(sim *core.Simulation, isSacrifice bool) {
oldOnPetDisable(sim, isSacrifice)
warlock.SoulLinkAura.Deactivate(sim)
pet.SoulLinkAura.Deactivate(sim)
}
Expand Down Expand Up @@ -495,14 +566,16 @@ func (warlock *Warlock) applyDemonicSacrifice() {
})

dsAuras := []*core.Aura{felhunterAura, impAura, succubusAura, voidwalkerAura}
for _, pet := range warlock.BasePets {
oldOnPetEnable := pet.OnPetEnable
pet.OnPetEnable = func(sim *core.Simulation) {
oldOnPetEnable(sim)
for _, dsAura := range dsAuras {
dsAura.Deactivate(sim)
for idx := range warlock.BasePets {
pet := warlock.BasePets[idx]

pet.ApplyOnPetEnable(func(sim *core.Simulation) {
if !warlock.maintainBuffsOnSacrifice || pet == warlock.SacrificedPet {
for _, dsAura := range dsAuras {
dsAura.Deactivate(sim)
}
}
}
})
}

warlock.GetOrRegisterSpell(core.SpellConfig{
Expand All @@ -516,6 +589,11 @@ func (warlock *Warlock) applyDemonicSacrifice() {
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
felhunterAura.Deactivate(sim)
impAura.Deactivate(sim)
succubusAura.Deactivate(sim)
voidwalkerAura.Deactivate(sim)

switch warlock.ActivePet {
case warlock.Felguard:
felhunterAura.Activate(sim)
Expand Down
Loading

0 comments on commit dc922c9

Please sign in to comment.