Skip to content

Commit

Permalink
Merge pull request #1290 from wowsims/feature/spell-mod-additions
Browse files Browse the repository at this point in the history
Additional Spell Mods
  • Loading branch information
NerdEgghead authored Jan 10, 2025
2 parents f24ab71 + ab46a0c commit 11a2037
Show file tree
Hide file tree
Showing 24 changed files with 180 additions and 41 deletions.
53 changes: 53 additions & 0 deletions sim/core/aura.go
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,26 @@ func (auras AuraArray) Get(target *Unit) *Aura {
return auras[target.UnitIndex]
}

func (auras AuraArray) IsEmpty() bool {
for _, aura := range auras {
if aura != nil {
return false
}
}

return true
}

func (auras AuraArray) FindLabel() string {
for _, aura := range auras {
if aura != nil {
return aura.Label
}
}

panic("No valid auras in array!")
}

func (caster *Unit) NewAllyAuraArray(makeAura func(*Unit) *Aura) AuraArray {
auras := make([]*Aura, len(caster.Env.AllUnits))
for _, target := range caster.Env.AllUnits {
Expand All @@ -917,3 +937,36 @@ func (caster *Unit) NewEnemyAuraArray(makeAura func(*Unit) *Aura) AuraArray {
}
return auras
}

type LabeledAuraArrays map[string]AuraArray

func (auras AuraArray) ToMap() LabeledAuraArrays {
if auras.IsEmpty() {
return nil
} else {
return LabeledAuraArrays{auras.FindLabel(): auras}
}
}

func (auraArrays LabeledAuraArrays) AnyActive(target *Unit) bool {
for _, auras := range auraArrays {
if auras.Get(target).IsActive() {
return true
}
}

return false
}

func (auraArrays LabeledAuraArrays) Append(auras AuraArray) LabeledAuraArrays {
if auras.IsEmpty() {
return auraArrays
}

if auraArrays == nil {
auraArrays = make(LabeledAuraArrays)
}

auraArrays[auras.FindLabel()] = auras
return auraArrays
}
2 changes: 1 addition & 1 deletion sim/core/exclusive_effect.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (aura *Aura) ShouldRefreshExclusiveEffects(sim *Simulation, refreshWindow t
return false
}
func (spell *Spell) ShouldRefreshExclusiveEffects(sim *Simulation, target *Unit, refreshWindow time.Duration) bool {
for _, auraArray := range spell.RelatedAuras {
for _, auraArray := range spell.RelatedAuraArrays {
aura := auraArray.Get(target)
if aura != nil && aura.ShouldRefreshExclusiveEffects(sim, refreshWindow) {
return true
Expand Down
15 changes: 9 additions & 6 deletions sim/core/spell.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ type SpellConfig struct {
Hot DotConfig
Shield ShieldConfig

RelatedAuras []AuraArray
RelatedDotSpell *Spell
RelatedAuraArrays LabeledAuraArrays
RelatedDotSpell *Spell
RelatedSelfBuff *Aura
}

type Spell struct {
Expand Down Expand Up @@ -153,8 +154,9 @@ type Spell struct {
selfShield *Shield

// Per-target auras that are related to this spell, usually buffs or debuffs applied by the spell.
RelatedAuras []AuraArray
RelatedDotSpell *Spell
RelatedAuraArrays LabeledAuraArrays
RelatedDotSpell *Spell
RelatedSelfBuff *Aura
}

func (unit *Unit) OnSpellRegistered(handler SpellRegisteredHandler) {
Expand Down Expand Up @@ -239,8 +241,9 @@ func (unit *Unit) RegisterSpell(config SpellConfig) *Spell {

splitSpellMetrics: make([][]SpellMetrics, max(1, config.MetricSplits)),

RelatedAuras: config.RelatedAuras,
RelatedDotSpell: config.RelatedDotSpell,
RelatedAuraArrays: config.RelatedAuraArrays,
RelatedDotSpell: config.RelatedDotSpell,
RelatedSelfBuff: config.RelatedSelfBuff,
}

switch {
Expand Down
100 changes: 91 additions & 9 deletions sim/core/spell_mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ SpellMod implementation.
*/

type SpellModConfig struct {
ClassMask int64
Kind SpellModType
School SpellSchool
ProcMask ProcMask
IntValue int64
TimeValue time.Duration
FloatValue float64
ClassMask int64
Kind SpellModType
School SpellSchool
ProcMask ProcMask
IntValue int64
TimeValue time.Duration
FloatValue float64
KeyValue string
ApplyCustom SpellModApply
RemoveCustom SpellModRemove
}

type SpellMod struct {
Expand All @@ -27,6 +30,7 @@ type SpellMod struct {
floatValue float64
intValue int64
timeValue time.Duration
keyValue string
Apply SpellModApply
Remove SpellModRemove
IsActive bool
Expand All @@ -46,6 +50,21 @@ func buildMod(unit *Unit, config SpellModConfig) *SpellMod {
panic("SpellMod " + strconv.Itoa(int(config.Kind)) + " not implmented")
}

var applyFn SpellModApply
var removeFn SpellModRemove

if config.Kind == SpellMod_Custom {
if (config.ApplyCustom == nil) || (config.RemoveCustom == nil) {
panic("ApplyCustom and RemoveCustom are mandatory fields for SpellMod_Custom")
}

applyFn = config.ApplyCustom
removeFn = config.RemoveCustom
} else {
applyFn = functions.Apply
removeFn = functions.Remove
}

mod := &SpellMod{
ClassMask: config.ClassMask,
Kind: config.Kind,
Expand All @@ -54,8 +73,9 @@ func buildMod(unit *Unit, config SpellModConfig) *SpellMod {
floatValue: config.FloatValue,
intValue: config.IntValue,
timeValue: config.TimeValue,
Apply: functions.Apply,
Remove: functions.Remove,
keyValue: config.KeyValue,
Apply: applyFn,
Remove: removeFn,
IsActive: false,
}

Expand Down Expand Up @@ -245,6 +265,18 @@ const (
// Add/subtract bonus expertise rating
// Uses: FloatValue
SpellMod_BonusExpertise_Rating

// Add/subtract duration for associated debuff
// Uses: KeyValue, TimeValue
SpellMod_DebuffDuration_Flat

// Add/subtract duration for associated self-buff
// Uses: TimeValue
SpellMod_BuffDuration_Flat

// User-defined implementation
// Uses: ApplyCustom | RemoveCustom
SpellMod_Custom
)

var spellModMap = map[SpellModType]*SpellModFunctions{
Expand Down Expand Up @@ -341,6 +373,20 @@ var spellModMap = map[SpellModType]*SpellModFunctions{
Apply: applyBonusExpertiseRating,
Remove: removeBonusExpertiseRating,
},

SpellMod_DebuffDuration_Flat: {
Apply: applyDebuffDurationFlat,
Remove: removeDebuffDurationFlat,
},

SpellMod_BuffDuration_Flat: {
Apply: applyBuffDurationFlat,
Remove: removeBuffDurationFlat,
},

SpellMod_Custom: {
// Doesn't have dedicated Apply/Remove functions as ApplyCustom/RemoveCustom is handled in buildMod()
},
}

func applyDamageDonePercent(mod *SpellMod, spell *Spell) {
Expand Down Expand Up @@ -534,3 +580,39 @@ func applyBonusExpertiseRating(mod *SpellMod, spell *Spell) {
func removeBonusExpertiseRating(mod *SpellMod, spell *Spell) {
spell.BonusExpertiseRating -= mod.floatValue
}

func applyDebuffDurationFlat(mod *SpellMod, spell *Spell) {
debuffAuraArray := spell.RelatedAuraArrays[mod.keyValue]

if debuffAuraArray == nil {
panic("No debuff found for key: " + mod.keyValue)
}

for _, debuffAura := range debuffAuraArray {
if debuffAura != nil {
debuffAura.Duration += mod.timeValue
}
}
}

func removeDebuffDurationFlat(mod *SpellMod, spell *Spell) {
debuffAuraArray := spell.RelatedAuraArrays[mod.keyValue]

if debuffAuraArray == nil {
panic("No debuff found for key: " + mod.keyValue)
}

for _, debuffAura := range debuffAuraArray {
if debuffAura != nil {
debuffAura.Duration -= mod.timeValue
}
}
}

func applyBuffDurationFlat(mod *SpellMod, spell *Spell) {
spell.RelatedSelfBuff.Duration += mod.timeValue
}

func removeBuffDurationFlat(mod *SpellMod, spell *Spell) {
spell.RelatedSelfBuff.Duration -= mod.timeValue
}
2 changes: 1 addition & 1 deletion sim/death_knight/diseases.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (dk *DeathKnight) registerFrostFever() {
spell.Dot(target).Apply(sim)
},

RelatedAuras: []core.AuraArray{extraEffectAura},
RelatedAuraArrays: extraEffectAura.ToMap(),
})
}

Expand Down
2 changes: 1 addition & 1 deletion sim/death_knight/talents_blood.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func (dk *DeathKnight) applyScarletFever() {
return core.ScarletFeverAura(target, dk.Talents.ScarletFever, dk.Talents.Epidemic)
})
dk.Env.RegisterPreFinalizeEffect(func() {
dk.BloodPlagueSpell.RelatedAuras = append(dk.BloodPlagueSpell.RelatedAuras, dk.ScarletFeverAura)
dk.BloodPlagueSpell.RelatedAuraArrays = dk.BloodPlagueSpell.RelatedAuraArrays.Append(dk.ScarletFeverAura)
})

core.MakeProcTriggerAura(&dk.Unit, core.ProcTrigger{
Expand Down
4 changes: 2 additions & 2 deletions sim/death_knight/talents_unholy.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ func (dk *DeathKnight) applyEbonPlaguebringer() {
return aura
})
dk.Env.RegisterPreFinalizeEffect(func() {
dk.FrostFeverSpell.RelatedAuras = append(dk.FrostFeverSpell.RelatedAuras, dk.EbonPlagueAura)
dk.BloodPlagueSpell.RelatedAuras = append(dk.BloodPlagueSpell.RelatedAuras, dk.EbonPlagueAura)
dk.FrostFeverSpell.RelatedAuraArrays = dk.FrostFeverSpell.RelatedAuraArrays.Append(dk.EbonPlagueAura)
dk.BloodPlagueSpell.RelatedAuraArrays = dk.BloodPlagueSpell.RelatedAuraArrays.Append(dk.EbonPlagueAura)
})

var lastDiseaseTarget *core.Unit = nil
Expand Down
2 changes: 1 addition & 1 deletion sim/druid/demoralizing_roar.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ func (druid *Druid) registerDemoralizingRoarSpell() {
}
},

RelatedAuras: []core.AuraArray{druid.DemoralizingRoarAuras},
RelatedAuraArrays: druid.DemoralizingRoarAuras.ToMap(),
})
}
2 changes: 1 addition & 1 deletion sim/druid/faerie_fire.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (druid *Druid) registerFaerieFireSpell() {
}
},

RelatedAuras: []core.AuraArray{druid.FaerieFireAuras},
RelatedAuraArrays: druid.FaerieFireAuras.ToMap(),
})
}

Expand Down
4 changes: 2 additions & 2 deletions sim/druid/mangle.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (druid *Druid) registerMangleBearSpell() {
}
},

RelatedAuras: []core.AuraArray{mangleAuras},
RelatedAuraArrays: mangleAuras.ToMap(),
})
}

Expand Down Expand Up @@ -139,7 +139,7 @@ func (druid *Druid) registerMangleCatSpell() {
return spell.CalcDamage(sim, target, baseDamage, spell.OutcomeExpectedMeleeWeaponSpecialHitAndCrit)
},

RelatedAuras: []core.AuraArray{mangleAuras},
RelatedAuraArrays: mangleAuras.ToMap(),
})
}

Expand Down
2 changes: 1 addition & 1 deletion sim/druid/talents.go
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ func (druid *Druid) applyInfectedWounds() {

for _, spell := range triggeringSpells {
if spell != nil {
spell.RelatedAuras = append(spell.RelatedAuras, iwAuras)
spell.RelatedAuraArrays = spell.RelatedAuraArrays.Append(iwAuras)
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion sim/hunter/pet_abilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (hp *HunterPet) newPetDebuff(config PetDebuffSpellConfig) *core.Spell {
spell.DealOutcome(sim, result)
},

RelatedAuras: []core.AuraArray{auraArray},
RelatedAuraArrays: auraArray.ToMap(),
})
}

Expand Down
2 changes: 1 addition & 1 deletion sim/rogue/expose_armor.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,6 @@ func (rogue *Rogue) registerExposeArmorSpell() {
spell.DealOutcome(sim, result)
},

RelatedAuras: []core.AuraArray{rogue.ExposeArmorAuras},
RelatedAuraArrays: rogue.ExposeArmorAuras.ToMap(),
})
}
2 changes: 1 addition & 1 deletion sim/rogue/subtlety/hemorrhage.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (subRogue *SubtletyRogue) registerHemorrhageSpell() {
}
},

RelatedAuras: []core.AuraArray{hemoAuras},
RelatedAuraArrays: hemoAuras.ToMap(),
})

subRogue.RegisterOnItemSwap(func(s *core.Simulation) {
Expand Down
4 changes: 2 additions & 2 deletions sim/rogue/subtlety/sanguinary_vein.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ func (subRogue *SubtletyRogue) registerSanguinaryVein() {

subRogue.Env.RegisterPreFinalizeEffect(func() {
if subRogue.Rupture != nil {
subRogue.Rupture.RelatedAuras = append(subRogue.Rupture.RelatedAuras, svDebuffArray)
subRogue.Rupture.RelatedAuraArrays = subRogue.Rupture.RelatedAuraArrays.Append(svDebuffArray)
}
if subRogue.Hemorrhage != nil && hasGlyph {
subRogue.Hemorrhage.RelatedAuras = append(subRogue.Hemorrhage.RelatedAuras, svDebuffArray)
subRogue.Hemorrhage.RelatedAuraArrays = subRogue.Hemorrhage.RelatedAuraArrays.Append(svDebuffArray)
}
})

Expand Down
3 changes: 2 additions & 1 deletion sim/warlock/affliction/haunt.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (affliction *AfflictionWarlock) registerHaunt() {
}
})
},
RelatedAuras: []core.AuraArray{affliction.HauntDebuffAuras},

RelatedAuraArrays: affliction.HauntDebuffAuras.ToMap(),
})
}
Loading

0 comments on commit 11a2037

Please sign in to comment.