From fce2792d900e8a8b240dfbb92e8695f4128b7cc2 Mon Sep 17 00:00:00 2001 From: Adrian Klingen Date: Fri, 10 Jan 2025 21:11:57 +0100 Subject: [PATCH] Refactor Armor Spec application --- sim/core/aura_helpers.go | 12 ++++ sim/core/character.go | 89 ++++++++++---------------- sim/core/item_sets.go | 22 +++---- sim/death_knight/blood/blood.go | 2 +- sim/death_knight/frost/frost.go | 2 +- sim/death_knight/unholy/unholy.go | 2 +- sim/hunter/talents.go | 2 +- sim/mage/mage.go | 2 +- sim/paladin/holy/holy.go | 2 +- sim/paladin/protection/protection.go | 2 +- sim/paladin/retribution/retribution.go | 2 +- sim/priest/talents.go | 2 +- sim/rogue/talents.go | 2 +- sim/shaman/elemental/elemental.go | 2 +- sim/shaman/enhancement/enhancement.go | 2 +- sim/shaman/restoration/restoration.go | 2 +- sim/warlock/warlock.go | 2 +- sim/warrior/arms/talents.go | 2 +- sim/warrior/fury/talents.go | 2 +- sim/warrior/protection/talents.go | 2 +- 20 files changed, 72 insertions(+), 85 deletions(-) diff --git a/sim/core/aura_helpers.go b/sim/core/aura_helpers.go index 5826c9226d..29485a6e7d 100644 --- a/sim/core/aura_helpers.go +++ b/sim/core/aura_helpers.go @@ -370,6 +370,18 @@ func (parentAura *Aura) AttachSpellMod(spellModConfig SpellModConfig) { }) } +// Attaches a StatDependency to a parent Aura +func (parentAura *Aura) AttachStatDependency(statDep *stats.StatDependency) { + + parentAura.ApplyOnGain(func(_ *Aura, sim *Simulation) { + parentAura.Unit.EnableBuildPhaseStatDep(sim, statDep) + }) + + parentAura.ApplyOnExpire(func(_ *Aura, sim *Simulation) { + parentAura.Unit.DisableBuildPhaseStatDep(sim, statDep) + }) +} + // Adds Stats to a parent Aura func (parentAura *Aura) AttachStatsBuff(stats stats.Stats) { parentAura.ApplyOnGain(func(aura *Aura, sim *Simulation) { diff --git a/sim/core/character.go b/sim/core/character.go index b25f8523a9..0ea0b2e04f 100644 --- a/sim/core/character.go +++ b/sim/core/character.go @@ -775,63 +775,40 @@ func (character *Character) MeetsArmorSpecializationRequirement(armorType proto. return true } -func (character *Character) ApplyArmorSpecializationEffect(primaryStat stats.Stat, armorType proto.ArmorType) { - armorSpecializationDepdency := character.NewDynamicMultiplyStat(primaryStat, 1.05) - var isEnabled bool +func (character *Character) ApplyArmorSpecializationEffect(primaryStat stats.Stat, armorType proto.ArmorType, spellID int32) { + armorSpecializationDependency := character.NewDynamicMultiplyStat(primaryStat, 1.05) + isEnabled := character.MeetsArmorSpecializationRequirement(armorType) - enableArmorSpecialization := func(sim *Simulation) { - character.EnableBuildPhaseStatDep(sim, armorSpecializationDepdency) - - if isEnabled { - return - } - isEnabled = true - if sim.Log != nil { - sim.Log("Armor Specialization: Active") - } - } - disableArmorSpecialization := func(sim *Simulation) { - character.DisableBuildPhaseStatDep(sim, armorSpecializationDepdency) - - if !isEnabled { - return - } - isEnabled = false - if sim.Log != nil { - sim.Log("Armor Specialization: Inactive") - } - } - - processArmorSpecialization := func(sim *Simulation) { - hasBonus := character.MeetsArmorSpecializationRequirement(armorType) - if hasBonus { - enableArmorSpecialization(sim) - } else { - disableArmorSpecialization(sim) - } - } - - MakePermanent(character.RegisterAura(Aura{ + aura := character.RegisterAura(Aura{ Label: "Armor Specialization", - BuildPhase: CharacterBuildPhaseTalents, - OnGain: func(aura *Aura, sim *Simulation) { - processArmorSpecialization(sim) - }, - })) + ActionID: ActionID{SpellID: spellID}, + BuildPhase: Ternary(isEnabled, CharacterBuildPhaseTalents, CharacterBuildPhaseNone), + Duration: NeverExpires, + }) - if character.ItemSwap.IsEnabled() { - character.RegisterItemSwapCallback([]proto.ItemSlot{ - proto.ItemSlot_ItemSlotHead, - proto.ItemSlot_ItemSlotShoulder, - proto.ItemSlot_ItemSlotChest, - proto.ItemSlot_ItemSlotWrist, - proto.ItemSlot_ItemSlotHands, - proto.ItemSlot_ItemSlotWaist, - proto.ItemSlot_ItemSlotLegs, - proto.ItemSlot_ItemSlotFeet, - }, - func(sim *Simulation, _ proto.ItemSlot) { - processArmorSpecialization(sim) - }) - } + aura.AttachStatDependency(armorSpecializationDependency) + + if isEnabled { + aura = MakePermanent(aura) + } + + character.RegisterItemSwapCallback([]proto.ItemSlot{ + proto.ItemSlot_ItemSlotHead, + proto.ItemSlot_ItemSlotShoulder, + proto.ItemSlot_ItemSlotChest, + proto.ItemSlot_ItemSlotWrist, + proto.ItemSlot_ItemSlotHands, + proto.ItemSlot_ItemSlotWaist, + proto.ItemSlot_ItemSlotLegs, + proto.ItemSlot_ItemSlotFeet, + }, + func(sim *Simulation, _ proto.ItemSlot) { + if character.MeetsArmorSpecializationRequirement(armorType) { + if !aura.IsActive() { + aura.Activate(sim) + } + } else { + aura.Deactivate(sim) + } + }) } diff --git a/sim/core/item_sets.go b/sim/core/item_sets.go index e8910669f0..04e64b0d96 100644 --- a/sim/core/item_sets.go +++ b/sim/core/item_sets.go @@ -236,15 +236,15 @@ func (character *Character) makeSetBonusStatusAura(setName string, numPieces int statusAura = MakePermanent(statusAura) } - if character.ItemSwap.IsEnabled() { - character.RegisterItemSwapCallback(slots, func(sim *Simulation, _ proto.ItemSlot) { - if character.hasActiveSetBonus(setName, numPieces) { + character.RegisterItemSwapCallback(slots, func(sim *Simulation, _ proto.ItemSlot) { + if character.hasActiveSetBonus(setName, numPieces) { + if !statusAura.IsActive() { statusAura.Activate(sim) - } else { - statusAura.Deactivate(sim) } - }) - } + } else { + statusAura.Deactivate(sim) + } + }) return statusAura } @@ -279,9 +279,7 @@ func (character *Character) RegisterPvPGloveMod(itemIDs []int32, config SpellMod checkGloves() - if character.ItemSwap.IsEnabled() { - character.RegisterItemSwapCallback([]proto.ItemSlot{proto.ItemSlot_ItemSlotHands}, func(_ *Simulation, _ proto.ItemSlot) { - checkGloves() - }) - } + character.RegisterItemSwapCallback([]proto.ItemSlot{proto.ItemSlot_ItemSlotHands}, func(_ *Simulation, _ proto.ItemSlot) { + checkGloves() + }) } diff --git a/sim/death_knight/blood/blood.go b/sim/death_knight/blood/blood.go index 4d6a76c043..c61722c1a0 100644 --- a/sim/death_knight/blood/blood.go +++ b/sim/death_knight/blood/blood.go @@ -74,7 +74,7 @@ func (bdk BloodDeathKnight) getBloodShieldMasteryBonus() float64 { func (bdk *BloodDeathKnight) ApplyTalents() { bdk.DeathKnight.ApplyTalents() - bdk.ApplyArmorSpecializationEffect(stats.Stamina, proto.ArmorType_ArmorTypePlate) + bdk.ApplyArmorSpecializationEffect(stats.Stamina, proto.ArmorType_ArmorTypePlate, 86524) // Veteran of the Third War bdk.AddStaticMod(core.SpellModConfig{ diff --git a/sim/death_knight/frost/frost.go b/sim/death_knight/frost/frost.go index 102dd00c84..37c8dd5bc8 100644 --- a/sim/death_knight/frost/frost.go +++ b/sim/death_knight/frost/frost.go @@ -59,7 +59,7 @@ func (fdk *FrostDeathKnight) Initialize() { func (fdk *FrostDeathKnight) ApplyTalents() { fdk.DeathKnight.ApplyTalents() - fdk.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate) + fdk.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate, 86524) masteryMod := fdk.AddDynamicMod(core.SpellModConfig{ Kind: core.SpellMod_DamageDone_Pct, diff --git a/sim/death_knight/unholy/unholy.go b/sim/death_knight/unholy/unholy.go index 07d9e972ac..323f3d1768 100644 --- a/sim/death_knight/unholy/unholy.go +++ b/sim/death_knight/unholy/unholy.go @@ -68,7 +68,7 @@ func (uhdk *UnholyDeathKnight) Initialize() { func (uhdk *UnholyDeathKnight) ApplyTalents() { uhdk.DeathKnight.ApplyTalents() - uhdk.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate) + uhdk.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate, 86524) // Mastery: Dreadblade masteryMod := uhdk.AddDynamicMod(core.SpellModConfig{ diff --git a/sim/hunter/talents.go b/sim/hunter/talents.go index 15fd95e636..2f9225eafb 100644 --- a/sim/hunter/talents.go +++ b/sim/hunter/talents.go @@ -6,7 +6,7 @@ import ( ) func (hunter *Hunter) ApplyTalents() { - hunter.ApplyArmorSpecializationEffect(stats.Agility, proto.ArmorType_ArmorTypeMail) + hunter.ApplyArmorSpecializationEffect(stats.Agility, proto.ArmorType_ArmorTypeMail, 86529) if hunter.Pet != nil { hunter.applyFrenzy() diff --git a/sim/mage/mage.go b/sim/mage/mage.go index ca41f634c7..8614269163 100644 --- a/sim/mage/mage.go +++ b/sim/mage/mage.go @@ -84,7 +84,7 @@ func (mage *Mage) AddPartyBuffs(partyBuffs *proto.PartyBuffs) { } func (mage *Mage) ApplyTalents() { - mage.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeCloth) + mage.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeCloth, 89744) mage.ApplyArcaneTalents() mage.ApplyFireTalents() diff --git a/sim/paladin/holy/holy.go b/sim/paladin/holy/holy.go index b3a4fdc525..e7391648c4 100644 --- a/sim/paladin/holy/holy.go +++ b/sim/paladin/holy/holy.go @@ -47,7 +47,7 @@ func (holy *HolyPaladin) GetPaladin() *paladin.Paladin { func (holy *HolyPaladin) ApplyTalents() { holy.Paladin.ApplyTalents() - holy.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypePlate) + holy.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypePlate, 86525) } func (holy *HolyPaladin) Initialize() { diff --git a/sim/paladin/protection/protection.go b/sim/paladin/protection/protection.go index d876c8041c..0ae3239b91 100644 --- a/sim/paladin/protection/protection.go +++ b/sim/paladin/protection/protection.go @@ -67,7 +67,7 @@ func (prot *ProtectionPaladin) Initialize() { func (prot *ProtectionPaladin) ApplyTalents() { prot.Paladin.ApplyTalents() - prot.ApplyArmorSpecializationEffect(stats.Stamina, proto.ArmorType_ArmorTypePlate) + prot.ApplyArmorSpecializationEffect(stats.Stamina, proto.ArmorType_ArmorTypePlate, 86525) } func (prot *ProtectionPaladin) Reset(sim *core.Simulation) { diff --git a/sim/paladin/retribution/retribution.go b/sim/paladin/retribution/retribution.go index dc7b1aaf09..d334790559 100644 --- a/sim/paladin/retribution/retribution.go +++ b/sim/paladin/retribution/retribution.go @@ -56,7 +56,7 @@ func (ret *RetributionPaladin) Initialize() { func (ret *RetributionPaladin) ApplyTalents() { ret.Paladin.ApplyTalents() - ret.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate) + ret.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate, 86525) } func (ret *RetributionPaladin) Reset(sim *core.Simulation) { diff --git a/sim/priest/talents.go b/sim/priest/talents.go index 19eed314a5..3c17eae7a5 100644 --- a/sim/priest/talents.go +++ b/sim/priest/talents.go @@ -10,7 +10,7 @@ import ( ) func (priest *Priest) ApplyTalents() { - priest.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeCloth) + priest.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeCloth, 89745) // TODO: // Reflective Shield // Improved Flash Heal diff --git a/sim/rogue/talents.go b/sim/rogue/talents.go index 11c01fcb6a..f89ca980e6 100644 --- a/sim/rogue/talents.go +++ b/sim/rogue/talents.go @@ -7,7 +7,7 @@ import ( ) func (rogue *Rogue) ApplyTalents() { - rogue.ApplyArmorSpecializationEffect(stats.Agility, proto.ArmorType_ArmorTypeLeather) + rogue.ApplyArmorSpecializationEffect(stats.Agility, proto.ArmorType_ArmorTypeLeather, 87504) rogue.PseudoStats.MeleeSpeedMultiplier *= []float64{1, 1.02, 1.04, 1.06}[rogue.Talents.LightningReflexes] rogue.AddStat(stats.PhysicalHitPercent, 2*float64(rogue.Talents.Precision)) rogue.AddStat(stats.SpellHitPercent, 2*float64(rogue.Talents.Precision)) diff --git a/sim/shaman/elemental/elemental.go b/sim/shaman/elemental/elemental.go index 5119d14b1c..6331e71b5b 100644 --- a/sim/shaman/elemental/elemental.go +++ b/sim/shaman/elemental/elemental.go @@ -87,7 +87,7 @@ func (eleShaman *ElementalShaman) Initialize() { func (ele *ElementalShaman) ApplyTalents() { ele.Shaman.ApplyTalents() - ele.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeMail) + ele.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeMail, 86529) } type ElementalShaman struct { diff --git a/sim/shaman/enhancement/enhancement.go b/sim/shaman/enhancement/enhancement.go index a4740fb9aa..27f5cb14a8 100644 --- a/sim/shaman/enhancement/enhancement.go +++ b/sim/shaman/enhancement/enhancement.go @@ -91,7 +91,7 @@ func (enh *EnhancementShaman) GetShaman() *shaman.Shaman { func (enh *EnhancementShaman) ApplyTalents() { enh.Shaman.ApplyTalents() - enh.ApplyArmorSpecializationEffect(stats.Agility, proto.ArmorType_ArmorTypeMail) + enh.ApplyArmorSpecializationEffect(stats.Agility, proto.ArmorType_ArmorTypeMail, 86529) } func (enh *EnhancementShaman) Initialize() { diff --git a/sim/shaman/restoration/restoration.go b/sim/shaman/restoration/restoration.go index 4ea2cbd52d..614f1a6b7f 100644 --- a/sim/shaman/restoration/restoration.go +++ b/sim/shaman/restoration/restoration.go @@ -87,5 +87,5 @@ func (resto *RestorationShaman) Initialize() { func (resto *RestorationShaman) ApplyTalents() { resto.Shaman.ApplyTalents() - resto.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeMail) + resto.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeMail, 86529) } diff --git a/sim/warlock/warlock.go b/sim/warlock/warlock.go index a834090844..00a4837daf 100644 --- a/sim/warlock/warlock.go +++ b/sim/warlock/warlock.go @@ -53,7 +53,7 @@ func (warlock *Warlock) GetWarlock() *Warlock { } func (warlock *Warlock) ApplyTalents() { - warlock.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeCloth) + warlock.ApplyArmorSpecializationEffect(stats.Intellect, proto.ArmorType_ArmorTypeCloth, 86091) warlock.ApplyAfflictionTalents() warlock.ApplyDemonologyTalents() diff --git a/sim/warrior/arms/talents.go b/sim/warrior/arms/talents.go index 2c41dbae11..afef52282a 100644 --- a/sim/warrior/arms/talents.go +++ b/sim/warrior/arms/talents.go @@ -10,7 +10,7 @@ import ( ) func (war *ArmsWarrior) ApplyTalents() { - war.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate) + war.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate, 86526) war.Warrior.ApplyCommonTalents() war.RegisterBladestorm() diff --git a/sim/warrior/fury/talents.go b/sim/warrior/fury/talents.go index 3b96e17b6b..85de7df3ae 100644 --- a/sim/warrior/fury/talents.go +++ b/sim/warrior/fury/talents.go @@ -10,7 +10,7 @@ import ( ) func (war *FuryWarrior) ApplyTalents() { - war.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate) + war.ApplyArmorSpecializationEffect(stats.Strength, proto.ArmorType_ArmorTypePlate, 86526) war.Warrior.ApplyCommonTalents() war.RegisterDeathWish() diff --git a/sim/warrior/protection/talents.go b/sim/warrior/protection/talents.go index f267064f51..2b0eeaa47f 100644 --- a/sim/warrior/protection/talents.go +++ b/sim/warrior/protection/talents.go @@ -10,7 +10,7 @@ import ( ) func (war *ProtectionWarrior) ApplyTalents() { - war.ApplyArmorSpecializationEffect(stats.Stamina, proto.ArmorType_ArmorTypePlate) + war.ApplyArmorSpecializationEffect(stats.Stamina, proto.ArmorType_ArmorTypePlate, 86526) // Vigilance is not implemented as it requires a second friendly target // We can probably fake it or make it configurable or something, but I expect it wouldn't