Skip to content

Commit

Permalink
Merge pull request #3 from wowsims/kg/ring-bonuses
Browse files Browse the repository at this point in the history
Add remaining timeworn ring bonuses
  • Loading branch information
Adamrch authored Nov 17, 2024
2 parents b8539d5 + 870f0b6 commit d6d965d
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 101 deletions.
258 changes: 188 additions & 70 deletions sim/common/sod/item_effects/phase_6.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,42 @@ import (
)

const (
SignetRingDominatorR5 = 234034
SignetRingDominatorR4 = 234030
SignetRingDominatorR3 = 234026
SignetRingDominatorR2 = 234021
SignetRingDominatorR1 = 234017
SignetRingInvokerR5 = 234032
SignetRingInvokerR4 = 234028
SignetRingInvokerR3 = 234024
SignetRingInvokerR2 = 234020
SignetRingInvokerR1 = 234016
SignetRingFlamekeeperR5 = 234964
SignetRingFlamekeeperR4 = 234965
SignetRingFlamekeeperR3 = 234966
SignetRingFlamekeeperR2 = 234967
SignetRingFlamekeeperR1 = 234968
SignetRingPreserverR5 = 234033
SignetRingPreserverR4 = 234029
SignetRingPreserverR3 = 234025
SignetRingPreserverR2 = 234023
SignetRingPreserverR1 = 234019
SignetRingProtectorR5 = 234035
SignetRingProtectorR4 = 234031
SignetRingProtectorR3 = 234027
SignetRingProtectorR2 = 234022
SignetRingProtectorR1 = 234018
SignetRingSubjugatorR5 = 234436
SignetRingSubjugatorR4 = 234437
SignetRingSubjugatorR3 = 234438
SignetRingSubjugatorR2 = 234439
SignetRingSubjugatorR1 = 234440
SignetRingConquerorR5 = 234202
SignetRingConquerorR4 = 234201
SignetRingConquerorR3 = 234200
SignetRingConquerorR2 = 234199
SignetRingConquerorR1 = 234198
// Brood of Nozdormu Reputations Rings
SignetRingBronzeDominatorR5 = 234034
SignetRingBronzeDominatorR4 = 234030
SignetRingBronzeDominatorR3 = 234026
SignetRingBronzeDominatorR2 = 234021
SignetRingBronzeDominatorR1 = 234017
SignetRingBronzeInvokerR5 = 234032
SignetRingBronzeInvokerR4 = 234028
SignetRingBronzeInvokerR3 = 234024
SignetRingBronzeInvokerR2 = 234020
SignetRingBronzeInvokerR1 = 234016
SignetRingBronzeFlamekeeperR5 = 234964
SignetRingBronzeFlamekeeperR4 = 234965
SignetRingBronzeFlamekeeperR3 = 234966
SignetRingBronzeFlamekeeperR2 = 234967
SignetRingBronzeFlamekeeperR1 = 234968
SignetRingBronzePreserverR5 = 234033
SignetRingBronzePreserverR4 = 234029
SignetRingBronzePreserverR3 = 234025
SignetRingBronzePreserverR2 = 234023
SignetRingBronzePreserverR1 = 234019
SignetRingBronzeProtectorR5 = 234035
SignetRingBronzeProtectorR4 = 234031
SignetRingBronzeProtectorR3 = 234027
SignetRingBronzeProtectorR2 = 234022
SignetRingBronzeProtectorR1 = 234018
SignetRingBronzeSubjugatorR5 = 234436
SignetRingBronzeSubjugatorR4 = 234437
SignetRingBronzeSubjugatorR3 = 234438
SignetRingBronzeSubjugatorR2 = 234439
SignetRingBronzeSubjugatorR1 = 234440
SignetRingBronzeConquerorR5 = 234202
SignetRingBronzeConquerorR4 = 234201
SignetRingBronzeConquerorR3 = 234200
SignetRingBronzeConquerorR2 = 234199
SignetRingBronzeConquerorR1 = 234198
)

func init() {
Expand All @@ -52,40 +53,160 @@ func init() {
// Rings
///////////////////////////////////////////////////////////////////////////

core.NewItemEffect(SignetRingDominatorR5, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingDominatorR4, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingDominatorR3, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingDominatorR2, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingDominatorR1, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingConquerorR5, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingConquerorR4, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingConquerorR3, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingConquerorR2, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingConquerorR1, func(agent core.Agent) { TimeswornStrikeAura(agent.GetCharacter()) })

core.NewItemEffect(SignetRingProtectorR5, func(agent core.Agent) { TimeswornExpertiseAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingProtectorR4, func(agent core.Agent) { TimeswornExpertiseAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingProtectorR3, func(agent core.Agent) { TimeswornExpertiseAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingProtectorR2, func(agent core.Agent) { TimeswornExpertiseAura(agent.GetCharacter()) })
core.NewItemEffect(SignetRingProtectorR1, func(agent core.Agent) { TimeswornExpertiseAura(agent.GetCharacter()) })
// https://www.wowhead.com/classic/item=234198/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzeConquerorR5, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeConquerorR4, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeConquerorR3, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeConquerorR2, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeConquerorR1, TimeswornStrikeAura)

// https://www.wowhead.com/classic/item=234034/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzeDominatorR5, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeDominatorR4, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeDominatorR3, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeDominatorR2, TimeswornStrikeAura)
core.NewItemEffect(SignetRingBronzeDominatorR1, TimeswornStrikeAura)

// https://www.wowhead.com/classic/item=234964/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzeFlamekeeperR5, TimeswornPyromancyAura)
core.NewItemEffect(SignetRingBronzeFlamekeeperR4, TimeswornPyromancyAura)
core.NewItemEffect(SignetRingBronzeFlamekeeperR3, TimeswornPyromancyAura)
core.NewItemEffect(SignetRingBronzeFlamekeeperR2, TimeswornPyromancyAura)
core.NewItemEffect(SignetRingBronzeFlamekeeperR1, TimeswornPyromancyAura)

// https://www.wowhead.com/classic/item=234032/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzeInvokerR5, TimeswornSpellAura)
core.NewItemEffect(SignetRingBronzeInvokerR4, TimeswornSpellAura)
core.NewItemEffect(SignetRingBronzeInvokerR3, TimeswornSpellAura)
core.NewItemEffect(SignetRingBronzeInvokerR2, TimeswornSpellAura)
core.NewItemEffect(SignetRingBronzeInvokerR1, TimeswornSpellAura)

// https://www.wowhead.com/classic/item=234032/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzePreserverR5, TimewornHealing)
core.NewItemEffect(SignetRingBronzePreserverR4, TimewornHealing)
core.NewItemEffect(SignetRingBronzePreserverR3, TimewornHealing)
core.NewItemEffect(SignetRingBronzePreserverR2, TimewornHealing)
core.NewItemEffect(SignetRingBronzePreserverR1, TimewornHealing)

// https://www.wowhead.com/classic/item=234035/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzeProtectorR5, TimeswornExpertiseAura)
core.NewItemEffect(SignetRingBronzeProtectorR4, TimeswornExpertiseAura)
core.NewItemEffect(SignetRingBronzeProtectorR3, TimeswornExpertiseAura)
core.NewItemEffect(SignetRingBronzeProtectorR2, TimeswornExpertiseAura)
core.NewItemEffect(SignetRingBronzeProtectorR1, TimeswornExpertiseAura)

// https://www.wowhead.com/classic/item=234436/signet-ring-of-the-bronze-dragonflight
core.NewItemEffect(SignetRingBronzeSubjugatorR5, TimewornDecayAura)
core.NewItemEffect(SignetRingBronzeSubjugatorR4, TimewornDecayAura)
core.NewItemEffect(SignetRingBronzeSubjugatorR3, TimewornDecayAura)
core.NewItemEffect(SignetRingBronzeSubjugatorR2, TimewornDecayAura)
core.NewItemEffect(SignetRingBronzeSubjugatorR1, TimewornDecayAura)

core.AddEffectsToTest = true
}

// https://www.wowhead.com/classic/spell=1214155/timeworn-decay
// Increases the damage dealt by all of your damage over time spells by 2% per piece of Timeworn armor equipped.
func TimewornDecayAura(agent core.Agent) {
character := agent.GetCharacter()
multiplier := 1 + 0.02*character.GetStat(stats.Timeworn)

character.OnSpellRegistered(func(spell *core.Spell) {
if spell.SpellCode != 0 && len(spell.Dots()) > 0 {
spell.PeriodicDamageMultiplier *= multiplier
}
})
}
func TimeswornExpertiseAura(character *core.Character) {

// https://www.wowhead.com/classic/spell=1213407/timeworn-expertise
// Reduces the chance for your attacks to be dodged or parried by 1% per piece of Timeworn armor equipped.
func TimeswornExpertiseAura(agent core.Agent) {
character := agent.GetCharacter()
stats := stats.Stats{stats.Expertise: character.GetStat(stats.Timeworn) * core.ExpertiseRatingPerExpertiseChance}

core.MakePermanent(character.GetOrRegisterAura(core.Aura{
ActionID: core.ActionID{SpellID: 1214218},
Label: "Timeworn Expertise Aura",
Duration: core.NeverExpires,
BuildPhase: core.CharacterBuildPhaseBuffs,
OnReset: func(aura *core.Aura, sim *core.Simulation) {
aura.Activate(sim)
character.AddStatDynamic(sim, stats.Expertise, aura.Unit.GetStat(stats.Timeworn)*core.CritRatingPerCritChance)
OnGain: func(aura *core.Aura, sim *core.Simulation) {
if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized {
aura.Unit.AddStats(stats)
} else {
aura.Unit.AddStatsDynamic(sim, stats)
}
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
if aura.Unit.Env.MeasuringStats && aura.Unit.Env.State != core.Finalized {
aura.Unit.AddStats(stats.Multiply(-1))
} else {
aura.Unit.AddStatsDynamic(sim, stats.Multiply(-1))
}
},
}))
}

func TimeswornStrikeAura(character *core.Character) {
// https://www.wowhead.com/classic/spell=1213405/timeworn-healing
// Increases the effectiveness of your healing and shielding spells by 2% per piece of Timeworn armor equipped.
func TimewornHealing(agent core.Agent) {
character := agent.GetCharacter()
healShieldMultiplier := 1 + 0.02*character.GetStat(stats.Timeworn)

chance := character.Unit.GetStat(stats.Timeworn) * 0.01
core.MakePermanent(character.GetOrRegisterAura(core.Aura{
ActionID: core.ActionID{SpellID: 1213405},
Label: "Timeworn Healing Aura",
OnGain: func(aura *core.Aura, sim *core.Simulation) {
character.PseudoStats.HealingDealtMultiplier *= healShieldMultiplier
character.PseudoStats.ShieldDealtMultiplier *= healShieldMultiplier
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
character.PseudoStats.HealingDealtMultiplier /= healShieldMultiplier
character.PseudoStats.ShieldDealtMultiplier /= healShieldMultiplier
},
}))
}

// https://www.wowhead.com/classic/spell=1215404/timeworn-pyromancy
// Increases the effectiveness of your Fire damage spells by 3% per piece of Timeworn armor equipped.
func TimeswornPyromancyAura(agent core.Agent) {
character := agent.GetCharacter()
fireMultiplier := 1 + 0.03*character.GetStat(stats.Timeworn)

core.MakePermanent(character.GetOrRegisterAura(core.Aura{
ActionID: core.ActionID{SpellID: 1215404},
Label: "Timeworn Pyromancy Aura",
OnGain: func(aura *core.Aura, sim *core.Simulation) {
character.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFire] *= fireMultiplier
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
character.PseudoStats.SchoolDamageDealtMultiplier[stats.SchoolIndexFire] /= fireMultiplier
},
}))
}

// https://www.wowhead.com/classic/spell=1213398/timeworn-spell
// Increases the casting speed of your spells by 2% per piece of Timeworn armor equipped.
func TimeswornSpellAura(agent core.Agent) {
character := agent.GetCharacter()
castSpeedMultiplier := 1 / (1 - 0.02*character.GetStat(stats.Timeworn))

core.MakePermanent(character.GetOrRegisterAura(core.Aura{
ActionID: core.ActionID{SpellID: 1213398},
Label: "Timeworn Spell Aura",
OnGain: func(aura *core.Aura, sim *core.Simulation) {
character.MultiplyCastSpeed(castSpeedMultiplier)
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
character.MultiplyCastSpeed(1 / castSpeedMultiplier)
},
}))
}

// https://www.wowhead.com/classic/spell=1213390/timeworn-strike
// Gives you 1% chance per piece of Timeworn armor equipped to get an extra attack on regular melee or ranged hit that deals 100% weapon damage.
// (100ms cooldown)
func TimeswornStrikeAura(agent core.Agent) {
character := agent.GetCharacter()
procChance := character.Unit.GetStat(stats.Timeworn) * 0.01

timeStrikeSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: 1213381},
Expand All @@ -94,6 +215,7 @@ func TimeswornStrikeAura(character *core.Character) {
ProcMask: core.ProcMaskMeleeMHSpecial,
Flags: core.SpellFlagNoOnCastComplete,

BonusCoefficient: 1,
DamageMultiplier: 1,
ThreatMultiplier: 1,

Expand All @@ -104,19 +226,15 @@ func TimeswornStrikeAura(character *core.Character) {
})

core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Timeworn Strike Aura",
ActionID: core.ActionID{SpellID: 468782},
Callback: core.CallbackOnSpellHitDealt,
Outcome: core.OutcomeLanded,
ProcMask: core.ProcMaskWhiteHit,
ICD: time.Millisecond * 100,
Name: "Timeworn Strike Aura",
ActionID: core.ActionID{SpellID: 468782},
Callback: core.CallbackOnSpellHitDealt,
Outcome: core.OutcomeLanded,
ProcMask: core.ProcMaskWhiteHit,
ProcChance: procChance,
ICD: time.Millisecond * 100,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
roll := sim.RandomFloat("Timeworn Strike Aura")

if roll < chance {
character.Unit.GetStat(stats.Timeworn)
timeStrikeSpell.Cast(sim, result.Target)
}
timeStrikeSpell.Cast(sim, result.Target)
},
})
}
1 change: 1 addition & 0 deletions sim/core/base_stats_auto_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const CritRatingPerCritChance = 1
const SpellCritRatingPerCritChance = 1
const MeleeHitRatingPerHitChance = 1
const SpellHitRatingPerHitChance = 1
const ExpertiseRatingPerExpertiseChance = 1
const DefenseRatingPerDefense = 1
const DodgeRatingPerDodgeChance = 1
const ParryRatingPerParryChance = 1
Expand Down
4 changes: 2 additions & 2 deletions sim/core/buffs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2610,11 +2610,11 @@ func ApplyAshenvaleRallyingCry(unit *Unit) {
Category: "AshenvaleRallyingCry",
ExtraOnGain: func(aura *Aura, sim *Simulation) {
aura.Unit.PseudoStats.DamageDealtMultiplier *= 1.05
// TODO: healing dealt multiplier?
aura.Unit.PseudoStats.HealingDealtMultiplier *= 1.05
},
ExtraOnExpire: func(aura *Aura, sim *Simulation) {
aura.Unit.PseudoStats.DamageDealtMultiplier /= 1.05
// TODO: healing dealt multiplier?
aura.Unit.PseudoStats.HealingDealtMultiplier /= 1.05
},
})
}
Expand Down
4 changes: 2 additions & 2 deletions sim/core/shield.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ func (shield *Shield) Apply(sim *Simulation, shieldAmount float64) {
//attackTable := caster.AttackTables[target.UnitIndex][shield.Spell.CastType]

// Shields are not affected by healing pseudostats the same way heals are.
// So we only apply the spell-specific multiplier.
shieldAmount *= shield.Spell.DamageMultiplier
// So we only apply the spell-specific multiplier and shield-specific multiplier.
shieldAmount *= shield.Spell.DamageMultiplier * caster.PseudoStats.ShieldDealtMultiplier

shield.Aura.Deactivate(sim)
shield.Aura.Activate(sim)
Expand Down
30 changes: 15 additions & 15 deletions sim/core/spell.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ type SpellConfig struct {

CritDamageBonus float64

BaseDamageMultiplierAdditive float64
DamageMultiplier float64
DoTDamageMultiplier float64
ImpactDamageMultiplier float64
DamageMultiplierAdditive float64
BaseDamageMultiplierAdditive float64 // Applies an additive multiplier to spell base damage
DamageMultiplier float64 // Applies a multiplicative multiplier to full spell damage
DamageMultiplierAdditive float64 // Applies an additive multiplier to full spell damage
ImpactDamageMultiplier float64 // Applies a multiplicative multiplier to full non-periodic spell damage
PeriodicDamageMultiplier float64 // Applies a multiplicative multiplier to full spell periodic damage

BonusDamage float64 // Bonus scaling power e.g. Idol of the Moon "Increases the damage of X spell by N" https://www.wowhead.com/classic/item=23197/idol-of-the-moon
BonusCoefficient float64 // EffectBonusCoefficient in SpellEffect client DB table, "SP mod" on Wowhead (not necessarily shown there even if > 0)
Expand Down Expand Up @@ -139,11 +139,11 @@ type Spell struct {
BonusCritRating float64
CastTimeMultiplier float64

BaseDamageMultiplierAdditive float64
DamageMultiplier float64
DoTDamageMultiplier float64
ImpactDamageMultiplier float64
DamageMultiplierAdditive float64
BaseDamageMultiplierAdditive float64 // Applies an additive multiplier to spell base damage
DamageMultiplier float64 // Applies a multiplicative multiplier to full spell damage
DamageMultiplierAdditive float64 // Applies an additive multiplier to full spell damage
ImpactDamageMultiplier float64 // Applies a multiplicative multiplier to full non-periodic spell damage
PeriodicDamageMultiplier float64 // Applies a multiplicative multiplier to full spell periodic damage

BonusDamage float64 // Bonus scaling power e.g. Idol of the Moon "Increases the damage of X spell by N" https://www.wowhead.com/classic/item=23197/idol-of-the-moon
BonusCoefficient float64 // EffectBonusCoefficient in SpellEffect client DB table, "SP mod" on Wowhead (not necessarily shown there even if > 0)
Expand Down Expand Up @@ -199,12 +199,12 @@ func (unit *Unit) RegisterSpell(config SpellConfig) *Spell {
} else if config.DamageMultiplierAdditive != 0 && config.DamageMultiplier == 0 {
config.DamageMultiplier = 1
}
if config.DoTDamageMultiplier == 0 {
config.DoTDamageMultiplier = 1
}
if config.ImpactDamageMultiplier == 0 {
config.ImpactDamageMultiplier = 1
}
if config.PeriodicDamageMultiplier == 0 {
config.PeriodicDamageMultiplier = 1
}

// Default CastSlot to mainhand
if config.CastType == proto.CastType_CastTypeUnknown {
Expand Down Expand Up @@ -267,9 +267,9 @@ func (unit *Unit) RegisterSpell(config SpellConfig) *Spell {

BaseDamageMultiplierAdditive: config.BaseDamageMultiplierAdditive,
DamageMultiplier: config.DamageMultiplier,
DoTDamageMultiplier: config.DoTDamageMultiplier,
ImpactDamageMultiplier: config.ImpactDamageMultiplier,
DamageMultiplierAdditive: config.DamageMultiplierAdditive,
ImpactDamageMultiplier: config.ImpactDamageMultiplier,
PeriodicDamageMultiplier: config.PeriodicDamageMultiplier,

BonusCoefficient: config.BonusCoefficient,

Expand Down
Loading

0 comments on commit d6d965d

Please sign in to comment.