Skip to content

Commit

Permalink
Merge pull request #918 from hillerstorm/remove_restrictions
Browse files Browse the repository at this point in the history
Allow Apparatus of Khaz'goroth to be used at any stack size
  • Loading branch information
hillerstorm authored Aug 19, 2024
2 parents a02ad7f + feb4e54 commit bfa9af8
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 197 deletions.
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

0 comments on commit bfa9af8

Please sign in to comment.