Skip to content

Commit

Permalink
Merge pull request #1322 from wowsims/feral
Browse files Browse the repository at this point in the history
[Feral] Talents Code Refactor
  • Loading branch information
NerdEgghead authored Jan 26, 2025
2 parents 9fdef6c + 9c10b34 commit 3c60708
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 98 deletions.
34 changes: 34 additions & 0 deletions sim/core/aura_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,10 @@ func (parentAura *Aura) AttachStatsBuff(stats stats.Stats) {
parentAura.ApplyOnExpire(func(aura *Aura, sim *Simulation) {
aura.Unit.AddStatsDynamic(sim, stats.Invert())
})

if parentAura.IsActive() {
parentAura.Unit.AddStats(stats)
}
}

// Adds a Stat to a parent Aura
Expand All @@ -400,6 +404,36 @@ func (parentAura *Aura) AttachStatBuff(stat stats.Stat, value float64) {
parentAura.AttachStatsBuff(statsToAdd)
}

// Attaches a multiplicative PseudoStat buff to a parent Aura
func (parentAura *Aura) AttachMultiplicativePseudoStatBuff(fieldPointer *float64, multiplier float64) {
parentAura.ApplyOnGain(func(_ *Aura, _ *Simulation) {
*fieldPointer *= multiplier
})

parentAura.ApplyOnExpire(func(_ *Aura, _ *Simulation) {
*fieldPointer /= multiplier
})

if parentAura.IsActive() {
*fieldPointer *= multiplier
}
}

// Attaches an additive PseudoStat buff to a parent Aura
func (parentAura *Aura) AttachAdditivePseudoStatBuff(fieldPointer *float64, bonus float64) {
parentAura.ApplyOnGain(func(_ *Aura, _ *Simulation) {
*fieldPointer += bonus
})

parentAura.ApplyOnExpire(func(_ *Aura, _ *Simulation) {
*fieldPointer -= bonus
})

if parentAura.IsActive() {
*fieldPointer += bonus
}
}

type ShieldStrengthCalculator func(unit *Unit) float64

type DamageAbsorptionAura struct {
Expand Down
20 changes: 19 additions & 1 deletion sim/core/character.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ func (character *Character) ApplyDynamicEquipScaling(sim *Simulation, stat stats
character.AddStatDynamic(sim, stat, statDiff)
}

func (character *Character) ApplyBuildPhaseEquipScaling(sim *Simulation, stat stats.Stat, multiplier float64) {
if character.Env.MeasuringStats && (character.Env.State != Finalized) {
character.ApplyEquipScaling(stat, multiplier)
} else {
character.ApplyDynamicEquipScaling(sim, stat, multiplier)
}
}

func (character *Character) RemoveEquipScaling(stat stats.Stat, multiplier float64) {
var statDiff stats.Stats
statDiff[stat] = character.applyEquipScaling(stat, 1/multiplier)
Expand All @@ -233,6 +241,14 @@ func (character *Character) RemoveDynamicEquipScaling(sim *Simulation, stat stat
character.AddStatDynamic(sim, stat, statDiff)
}

func (character *Character) RemoveBuildPhaseEquipScaling(sim *Simulation, stat stats.Stat, multiplier float64) {
if character.Env.MeasuringStats && (character.Env.State != Finalized) {
character.RemoveEquipScaling(stat, multiplier)
} else {
character.RemoveDynamicEquipScaling(sim, stat, multiplier)
}
}

func (character *Character) EquipStats() stats.Stats {
var baseEquipStats = character.Equipment.Stats()
var bonusEquipStats = baseEquipStats.Add(character.bonusStats)
Expand Down Expand Up @@ -777,7 +793,7 @@ func (character *Character) MeetsArmorSpecializationRequirement(armorType proto.
return true
}

func (character *Character) ApplyArmorSpecializationEffect(primaryStat stats.Stat, armorType proto.ArmorType, spellID int32) {
func (character *Character) ApplyArmorSpecializationEffect(primaryStat stats.Stat, armorType proto.ArmorType, spellID int32) *Aura {
armorSpecializationDependency := character.NewDynamicMultiplyStat(primaryStat, 1.05)
isEnabled := character.MeetsArmorSpecializationRequirement(armorType)

Expand Down Expand Up @@ -813,4 +829,6 @@ func (character *Character) ApplyArmorSpecializationEffect(primaryStat stats.Sta
aura.Deactivate(sim)
}
})

return aura
}
33 changes: 23 additions & 10 deletions sim/druid/druid.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ type Druid struct {
RebirthTiming float64
BleedsActive int
AssumeBleedActive bool
LeatherSpecActive bool

MHAutoSpell *core.Spell
ReplaceBearMHFunc core.ReplaceMHSwing
MHAutoSpell *core.Spell

HotWCatDep *stats.StatDependency
HotWBearDep *stats.StatDependency

Barkskin *DruidSpell
Berserk *DruidSpell
Expand Down Expand Up @@ -124,6 +125,9 @@ type Druid struct {
form DruidForm
disabledMCDs []*core.MajorCooldown

// Leather specialization tracker
LeatherSpec *core.Aura

// Item sets
T11Feral2pBonus *core.Aura
T11Feral4pBonus *core.Aura
Expand Down Expand Up @@ -266,19 +270,14 @@ func (druid *Druid) RegisterSpell(formMask DruidForm, config core.SpellConfig) *
}

func (druid *Druid) Initialize() {
druid.LeatherSpecActive = druid.MeetsArmorSpecializationRequirement(proto.ArmorType_ArmorTypeLeather)
druid.form = druid.StartingForm
druid.BleedCategories = druid.GetEnemyExclusiveCategories(core.BleedEffectCategory)

druid.Env.RegisterPostFinalizeEffect(func() {
druid.MHAutoSpell = druid.AutoAttacks.MHAuto()
druid.BlazeOfGloryAura = druid.GetAura("Blaze of Glory")
})

// Leather spec would always provide 5% intellect regardless of the Druid spec or form
if druid.LeatherSpecActive {
druid.MultiplyStat(stats.Intellect, 1.05)
}

druid.registerFaerieFireSpell()
// druid.registerRebirthSpell()
druid.registerInnervateCD()
Expand Down Expand Up @@ -323,8 +322,8 @@ func (druid *Druid) RegisterFeralCatSpells() {

func (druid *Druid) RegisterFeralTankSpells() {
druid.registerBarkskinCD()
druid.registerBerserkCD()
druid.registerBearFormSpell()
druid.registerBerserkCD()
druid.registerDemoralizingRoarSpell()
druid.registerEnrageSpell()
druid.registerFrenziedRegenerationCD()
Expand All @@ -340,6 +339,18 @@ func (druid *Druid) RegisterFeralTankSpells() {
druid.registerThrashBearSpell()
}

func (druid *Druid) RegisterLeatherSpecialization() {
// Druid armor spec behaves differently from other classes because the boosted stats are linked to form rather
// than talents. For this reason, we modify the default tracker Aura to activate at BuildPhaseGear rather than
// BuildPhaseTalents, and also add custom handlers for the cat Agi bonus and the bear Stam bonus in forms.go (the
// Int bonus applies in all forms).
druid.LeatherSpec = druid.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeLeather, 87505)

if druid.LeatherSpec.BuildPhase == core.CharacterBuildPhaseTalents {
druid.LeatherSpec.BuildPhase = core.CharacterBuildPhaseGear
}
}

func (druid *Druid) Reset(_ *core.Simulation) {
druid.eclipseEnergyBar.reset()
druid.BleedsActive = 0
Expand Down Expand Up @@ -371,6 +382,8 @@ func New(char *core.Character, form DruidForm, selfBuffs SelfBuffs, talents stri
// Base dodge is unaffected by Diminishing Returns
druid.PseudoStats.BaseDodgeChance += 0.04951

druid.RegisterLeatherSpecialization()

if druid.Talents.ForceOfNature {
druid.Treants = &Treants{
Treant1: druid.NewTreant(),
Expand Down
6 changes: 3 additions & 3 deletions sim/druid/feral/feral.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ func NewFeralDruid(character *core.Character, options *proto.Player) *FeralDruid
MainHand: cat.GetCatWeapon(),
AutoSwingMelee: true,
})
// cat.ReplaceBearMHFunc = func(sim *core.Simulation, mhSwingSpell *core.Spell) *core.Spell {
// return cat.checkReplaceMaul(sim, mhSwingSpell)
// }

cat.RegisterCatFormAura()
cat.RegisterBearFormAura()

return cat
}
Expand Down
Loading

0 comments on commit 3c60708

Please sign in to comment.