Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Apparatus of Khaz'goroth to be used at any stack size #918

Merged
merged 4 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
263 changes: 117 additions & 146 deletions sim/common/cata/other_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,154 +525,17 @@ func init() {
})
})

core.NewItemEffect(68972, func(agent core.Agent) {
character := agent.GetCharacter()

dummyAura := character.RegisterAura(core.Aura{
Label: "Titanic Power",
ActionID: core.ActionID{SpellID: 96923},
Duration: time.Second * 30,
MaxStacks: 5,
})

core.MakePermanent(core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Titanic Power Aura",
ActionID: core.ActionID{ItemID: 68972},
Callback: core.CallbackOnSpellHitDealt,
ProcMask: core.ProcMaskMelee,
ProcChance: 1,
Outcome: core.OutcomeCrit,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
dummyAura.Activate(sim)
dummyAura.AddStack(sim)
},
}))

statBonus := float64(508 * dummyAura.MaxStacks)
buffAuraCrit := character.NewTemporaryStatsAura("Blessing of the Shaper Crit", core.ActionID{SpellID: 96928}, stats.Stats{stats.CritRating: statBonus}, time.Second*15)
buffAuraHaste := character.NewTemporaryStatsAura("Blessing of the Shaper Haste", core.ActionID{SpellID: 96927}, stats.Stats{stats.HasteRating: statBonus}, time.Second*15)
buffAuraMastery := character.NewTemporaryStatsAura("Blessing of the Shaper Mastery", core.ActionID{SpellID: 96929}, stats.Stats{stats.MasteryRating: statBonus}, time.Second*15)

sharedCD := character.GetOffensiveTrinketCD()
trinketSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{ItemID: 68972},
SpellSchool: core.SpellSchoolPhysical,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagNoOnCastComplete,
Cast: core.CastConfig{
SharedCD: core.Cooldown{
Timer: sharedCD,
Duration: time.Second * 15,
},
CD: core.Cooldown{
Timer: character.NewTimer(),
Duration: time.Minute * 2,
},
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})
switch statType {
case stats.CritRating:
buffAuraCrit.Activate(sim)
case stats.HasteRating:
buffAuraHaste.Activate(sim)
case stats.MasteryRating:
buffAuraMastery.Activate(sim)
default:
panic("unexpected statType")
}
dummyAura.Deactivate(sim)
},
ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool {
return dummyAura.GetStacks() == 5
},
})

character.AddMajorCooldown(core.MajorCooldown{
Spell: trinketSpell,
Priority: core.CooldownPriorityDefault,
Type: core.CooldownTypeDPS,
ShouldActivate: func(s *core.Simulation, c *core.Character) bool {
return dummyAura.GetStacks() == 5
},
})
// Normal
registerApparatusOfKhazGoroth(apparatusConfig{
ItemID: 68972,
BonusPerStack: 508,
})

core.NewItemEffect(69113, func(agent core.Agent) {
character := agent.GetCharacter()

dummyAura := character.RegisterAura(core.Aura{
Label: "Titanic Power (Heroic)",
ActionID: core.ActionID{SpellID: 96923},
Duration: time.Second * 30,
MaxStacks: 5,
})

core.MakePermanent(core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Titanic Power Aura (Heroic)",
ActionID: core.ActionID{ItemID: 69113},
Callback: core.CallbackOnSpellHitDealt,
ProcMask: core.ProcMaskMelee,
ProcChance: 1,
Outcome: core.OutcomeCrit,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
dummyAura.Activate(sim)
dummyAura.AddStack(sim)
},
}))

// TODO: discuss the following scenario:
// the trinket should allow to activate at any number of stacks, should we allow this behaviour at all to the users?
// would also mean that we need the temporary aura to be created on the fly after an environment is finalized
statBonus := float64(575 * dummyAura.MaxStacks)
buffAuraCrit := character.NewTemporaryStatsAura("Blessing of the Shaper Crit (Heroic)", core.ActionID{SpellID: 96928}, stats.Stats{stats.CritRating: statBonus}, time.Second*15)
buffAuraHaste := character.NewTemporaryStatsAura("Blessing of the Shaper Haste (Heroic)", core.ActionID{SpellID: 96927}, stats.Stats{stats.HasteRating: statBonus}, time.Second*15)
buffAuraMastery := character.NewTemporaryStatsAura("Blessing of the Shaper Mastery (Heroic)", core.ActionID{SpellID: 96929}, stats.Stats{stats.MasteryRating: statBonus}, time.Second*15)

sharedCD := character.GetOffensiveTrinketCD()
trinketSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{ItemID: 69113},
SpellSchool: core.SpellSchoolPhysical,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagNoOnCastComplete,
Cast: core.CastConfig{
SharedCD: core.Cooldown{
Timer: sharedCD,
Duration: time.Second * 15,
},
CD: core.Cooldown{
Timer: character.NewTimer(),
Duration: time.Minute * 2,
},
},
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})
switch statType {
case stats.CritRating:
buffAuraCrit.Activate(sim)
case stats.HasteRating:
buffAuraHaste.Activate(sim)
case stats.MasteryRating:
buffAuraMastery.Activate(sim)
default:
panic("unexpected statType")
}
dummyAura.Deactivate(sim)
},
ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool {
return dummyAura.GetStacks() == 5
},
})

character.AddMajorCooldown(core.MajorCooldown{
Spell: trinketSpell,
Priority: core.CooldownPriorityDefault,
Type: core.CooldownTypeDPS,
ShouldActivate: func(s *core.Simulation, c *core.Character) bool {
return dummyAura.GetStacks() == 5
},
})
// Heroic
registerApparatusOfKhazGoroth(apparatusConfig{
ItemID: 69113,
BonusPerStack: 575,
Heroic: true,
})

core.NewItemEffect(68994, func(agent core.Agent) {
Expand Down Expand Up @@ -761,3 +624,111 @@ func init() {
})
})
}

type apparatusConfig struct {
ItemID int32
BonusPerStack float64
Heroic bool
}

func registerApparatusOfKhazGoroth(config apparatusConfig) {
core.NewItemEffect(config.ItemID, func(agent core.Agent) {
character := agent.GetCharacter()

labelSuffix := core.Ternary(config.Heroic, " (Heroic)", "")
buffDuration := time.Second * 15

buffAuraCrit := character.NewTemporaryStatBuffWithStacks(
"Blessing of the Shaper Crit"+labelSuffix,
core.ActionID{SpellID: 96928},
stats.Stats{stats.CritRating: config.BonusPerStack},
5,
buffDuration)

buffAuraHaste := character.NewTemporaryStatBuffWithStacks(
"Blessing of the Shaper Haste"+labelSuffix,
core.ActionID{SpellID: 96927},
stats.Stats{stats.HasteRating: config.BonusPerStack},
5,
buffDuration)

buffAuraMastery := character.NewTemporaryStatBuffWithStacks(
"Blessing of the Shaper Mastery"+labelSuffix,
core.ActionID{SpellID: 96929},
stats.Stats{stats.MasteryRating: config.BonusPerStack},
5,
buffDuration)

titanicPower := character.RegisterAura(core.Aura{
Label: "Titanic Power" + labelSuffix,
ActionID: core.ActionID{SpellID: 96923},
Duration: time.Second * 30,
MaxStacks: 5,
})

core.MakePermanent(core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Titanic Power Aura" + labelSuffix,
ActionID: core.ActionID{SpellID: 96924},
Callback: core.CallbackOnSpellHitDealt,
ProcMask: core.ProcMaskMelee,
ProcChance: 1,
Outcome: core.OutcomeCrit,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if buffAuraCrit.IsActive() || buffAuraHaste.IsActive() || buffAuraMastery.IsActive() {
return
}

titanicPower.Activate(sim)
titanicPower.AddStack(sim)
},
}))

trinketSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{ItemID: config.ItemID},
SpellSchool: core.SpellSchoolPhysical,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagNoOnCastComplete,
Cast: core.CastConfig{
SharedCD: core.Cooldown{
Timer: character.GetOffensiveTrinketCD(),
Duration: time.Second * 15,
},
CD: core.Cooldown{
Timer: character.NewTimer(),
Duration: time.Minute * 2,
},
},
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})

switch statType {
case stats.CritRating:
buffAuraCrit.Activate(sim)
buffAuraCrit.SetStacks(sim, titanicPower.GetStacks())
case stats.HasteRating:
buffAuraHaste.Activate(sim)
buffAuraHaste.SetStacks(sim, titanicPower.GetStacks())
case stats.MasteryRating:
buffAuraMastery.Activate(sim)
buffAuraMastery.SetStacks(sim, titanicPower.GetStacks())
default:
panic("unexpected statType")
}

titanicPower.Deactivate(sim)
},
ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool {
return titanicPower.IsActive()
},
})

character.AddMajorCooldown(core.MajorCooldown{
Spell: trinketSpell,
Priority: core.CooldownPriorityDefault,
Type: core.CooldownTypeDPS,
ShouldActivate: func(sim *core.Simulation, character *core.Character) bool {
return titanicPower.IsActive()
},
})
})
}
12 changes: 12 additions & 0 deletions sim/core/aura_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,18 @@ func MakePermanent(aura *Aura) *Aura {
return aura
}

func (character *Character) NewTemporaryStatBuffWithStacks(auraLabel string, actionID ActionID, bonusPerStack stats.Stats, maxStacks int32, duration time.Duration) *Aura {
return MakeStackingAura(character, StackingStatAura{
Aura: Aura{
Label: auraLabel,
ActionID: actionID,
Duration: duration,
MaxStacks: maxStacks,
},
BonusPerStack: bonusPerStack,
})
}

// Helper for the common case of making an aura that adds stats.
func (character *Character) NewTemporaryStatsAura(auraLabel string, actionID ActionID, tempStats stats.Stats, duration time.Duration) *Aura {
return character.NewTemporaryStatsAuraWrapped(auraLabel, actionID, tempStats, duration, nil)
Expand Down
10 changes: 5 additions & 5 deletions sim/death_knight/frost/TestFrost.results
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,16 @@ dps_results: {
dps_results: {
key: "TestFrost-AllItems-ApparatusofKhaz'goroth-68972"
value: {
dps: 22067.2198
tps: 20055.76419
hps: 218.63072
dps: 21920.68689
tps: 19962.48269
hps: 217.92998
}
}
dps_results: {
key: "TestFrost-AllItems-ApparatusofKhaz'goroth-69113"
value: {
dps: 22238.03054
tps: 20224.97843
dps: 22121.41929
tps: 20106.73742
hps: 217.92998
}
}
Expand Down
12 changes: 6 additions & 6 deletions sim/death_knight/unholy/TestUnholy.results
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ dps_results: {
dps_results: {
key: "TestUnholy-AllItems-ApparatusofKhaz'goroth-68972"
value: {
dps: 31540.40851
tps: 23371.35894
hps: 490.05478
dps: 31461.98752
tps: 23327.34034
hps: 485.83623
}
}
dps_results: {
key: "TestUnholy-AllItems-ApparatusofKhaz'goroth-69113"
value: {
dps: 31877.07432
tps: 23648.34593
hps: 494.27332
dps: 31713.08283
tps: 23495.50639
hps: 485.83623
}
}
dps_results: {
Expand Down
8 changes: 4 additions & 4 deletions sim/druid/feral/TestFeral.results
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ dps_results: {
dps_results: {
key: "TestFeral-AllItems-ApparatusofKhaz'goroth-68972"
value: {
dps: 26010.16289
tps: 36366.3166
dps: 25884.26602
tps: 36625.42619
}
}
dps_results: {
key: "TestFeral-AllItems-ApparatusofKhaz'goroth-69113"
value: {
dps: 26164.81755
tps: 36466.50053
dps: 25984.84193
tps: 36758.48515
}
}
dps_results: {
Expand Down
8 changes: 4 additions & 4 deletions sim/druid/guardian/TestGuardian.results
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ dps_results: {
dps_results: {
key: "TestGuardian-AllItems-ApparatusofKhaz'goroth-68972"
value: {
dps: 7800.83542
tps: 39070.13604
dps: 7843.78516
tps: 39285.30684
}
}
dps_results: {
key: "TestGuardian-AllItems-ApparatusofKhaz'goroth-69113"
value: {
dps: 7833.11618
tps: 39231.31568
dps: 7887.29914
tps: 39502.63676
}
}
dps_results: {
Expand Down
Loading
Loading