Skip to content

Commit

Permalink
master merge and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sanguinerarogue committed Jan 13, 2025
2 parents 0cd30d9 + 712f1b3 commit ed7ba68
Show file tree
Hide file tree
Showing 11 changed files with 513 additions and 353 deletions.
260 changes: 170 additions & 90 deletions sim/common/item_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const (
DragonsCall = 10847
VilerendSlicer = 11603
HookfangShanker = 11635
Naglering = 11669
Ironfoe = 11684
Bloodfist = 11744
FlameWrath = 11809
Expand Down Expand Up @@ -91,6 +92,7 @@ const (
AlcorsSunrazor = 14555
HameyasSlayer = 15814
JoonhosMercy = 17054
DrillborerDisk = 17066
Deathbringer = 17068
GutgoreRipper = 17071
Shadowstrike = 17074
Expand All @@ -104,9 +106,11 @@ const (
ThrashBlade = 17705
SatyrsLash = 17752
MarkOfTheChosen = 17774
ForceReactiveDisk = 18168
EskhandarsLeftClaw = 18202
EskhandarsRightClaw = 18203
FiendishMachete = 18310
RazorGauntlets = 18326
QuelSerrar = 18348
BaronCharrsSceptre = 18671
TalismanOfEphemeralPower = 18820
Expand Down Expand Up @@ -192,7 +196,22 @@ func init() {
// https://www.wowhead.com/classic/spell=16916/strength-of-the-champion
// Chance on hit: Heal self for 270 to 450 and Increases Strength by 120 for 30 sec.
// TODO: Proc rate assumed and needs testing
itemhelpers.CreateWeaponProcAura(ArcaniteChampion, "Arcanite Champion", 1.0, StrengthOfTheChampionAura)
itemhelpers.CreateWeaponProcAura(ArcaniteChampion, "Arcanite Champion", 1.0, func(character *core.Character) *core.Aura {
actionID := core.ActionID{SpellID: 16916}
healthMetrics := character.NewHealthMetrics(actionID)
return character.GetOrRegisterAura(core.Aura{
Label: "Strength of the Champion",
ActionID: actionID,
Duration: time.Second * 30,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
character.GainHealth(sim, sim.Roll(270, 450), healthMetrics)
character.AddStatDynamic(sim, stats.Strength, 120)
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
character.AddStatDynamic(sim, stats.Strength, -120)
},
})
})

// https://www.wowhead.com/classic/item=13246/argent-avenger
// Chance on hit: Increases Attack Power against Undead by 200 for 10 sec.
Expand Down Expand Up @@ -1699,8 +1718,45 @@ func init() {
itemhelpers.CreateWeaponCoHProcDamage(Nightblade, "Nightblade", 1.0, 18211, core.SpellSchoolShadow, 125, 150, 0, core.DefenseTypeMagic)

// https://www.wowhead.com/classic/item=19169/nightfall
// Chance on hit: Spell damage taken by target increased by 15% for 5 sec.
core.NewItemEffect(Nightfall, func(agent core.Agent) {
makeNightfallProc(agent.GetCharacter(), "Nightfall")
character := agent.GetCharacter()

procAuras := character.NewEnemyAuraArray(func(target *core.Unit) *core.Aura {
return target.GetOrRegisterAura(core.Aura{
Label: "Spell Vulnerability",
ActionID: core.ActionID{SpellID: 23605},
Duration: time.Second * 5,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexArcane] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFire] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFrost] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexHoly] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexNature] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexShadow] *= 1.15
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexArcane] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFire] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFrost] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexHoly] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexNature] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexShadow] /= 1.15
},
})
})

core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Nightfall Trigger",
Callback: core.CallbackOnSpellHitDealt,
Outcome: core.OutcomeLanded,
ProcMask: core.ProcMaskMelee,
SpellFlagsExclude: core.SpellFlagSuppressWeaponProcs,
PPM: 2,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
procAuras.Get(result.Target).Activate(sim)
},
})
})

// https://www.wowhead.com/classic/item=9425/pendulum-of-doom
Expand Down Expand Up @@ -3234,13 +3290,93 @@ func init() {
// Equip: Adds 2 fire damage to your melee attacks.
core.NewItemEffect(BlazefuryMedallion, func(agent core.Agent) {
character := agent.GetCharacter()
BlazefuryTriggerAura(character, 7712, core.SpellSchoolFire, 2)

procSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: 7712},
SpellSchool: core.SpellSchoolFire,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskMeleeDamageProc,
Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell,
DamageMultiplier: 1,
ThreatMultiplier: 1,
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
spell.CalcAndDealDamage(sim, target, 2, spell.OutcomeMagicCrit)
},
})

core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Blazefury Medallion Trigger",
Callback: core.CallbackOnSpellHitDealt,
Outcome: core.OutcomeLanded,
ProcMask: core.ProcMaskMelee,
SpellFlagsExclude: core.SpellFlagSuppressEquipProcs,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if spell.ProcMask.Matches(core.ProcMaskMeleeSpecial) {
procSpell.ProcMask = core.ProcMaskEmpty
} else {
procSpell.ProcMask = core.ProcMaskDamageProc // Both spell and melee procs
}
procSpell.Cast(sim, result.Target)
},
})
})

// https://www.wowhead.com/classic/item=14554/cloudkeeper-legplates
// Use: Increases Attack Power by 100 for 30 sec. (15 Min Cooldown)
core.NewSimpleStatOffensiveTrinketEffect(CloudkeeperLegplates, stats.Stats{stats.AttackPower: 100, stats.RangedAttackPower: 100}, time.Second*30, time.Minute*15)

// https://www.wowhead.com/classic/item=228266/drillborer-disk
// Equip: When struck in combat inflicts 3 Arcane damage to the attacker.
core.NewItemEffect(DrillborerDisk, func(agent core.Agent) {
thornsArcaneDamageEffect(agent, DrillborerDisk, "Drillborer Disk", 3)
})

// https://www.wowhead.com/classic/item=18168/force-reactive-disk
// Equip: When the shield blocks it releases an electrical charge that damages all nearby enemies. (1s cooldown)
core.NewItemEffect(ForceReactiveDisk, func(agent core.Agent) {
character := agent.GetCharacter()

procSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{ItemID: ForceReactiveDisk},
SpellSchool: core.SpellSchoolNature,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell,

DamageMultiplier: 1,
ThreatMultiplier: 1,

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
for _, aoeTarget := range sim.Encounter.TargetUnits {
spell.CalcAndDealDamage(sim, aoeTarget, 25, spell.OutcomeMagicHitAndCrit)
}
},
})

core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: "Force Reactive Disk",
Callback: core.CallbackOnSpellHitTaken,
ProcMask: core.ProcMaskMelee,
Outcome: core.OutcomeBlock,
ICD: time.Second,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
procSpell.Cast(sim, spell.Unit)
},
})
})

// https://www.wowhead.com/classic/item=11669/naglering
// Equip: When struck in combat inflicts 3 Arcane damage to the attacker.
core.NewItemEffect(Naglering, func(agent core.Agent) {
thornsArcaneDamageEffect(agent, Naglering, "Naglering", 3)
})

// https://www.wowhead.com/classic/item=18326/razor-gauntlets
// Equip: When struck in combat inflicts 3 Arcane damage to the attacker.
core.NewItemEffect(RazorGauntlets, func(agent core.Agent) {
thornsArcaneDamageEffect(agent, RazorGauntlets, "Razor Gauntlets", 3)
})

// https://www.wowhead.com/classic/item=1168/skullflame-shield
// Equip: When struck in combat has a 3% chance of stealing 35 life from target enemy. (Proc chance: 3%)
// Equip: When struck in combat has a 1% chance of dealing 75 to 125 Fire damage to all targets around you. (Proc chance: 1%)
Expand All @@ -3250,24 +3386,32 @@ func init() {
drainLifeActionID := core.ActionID{SpellID: 18817}
healthMetrics := character.NewHealthMetrics(drainLifeActionID)
drainLifeSpell := character.RegisterSpell(core.SpellConfig{
ActionID: drainLifeActionID,
SpellSchool: core.SpellSchoolShadow,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskEmpty,
ActionID: drainLifeActionID,
SpellSchool: core.SpellSchoolShadow,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell,

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

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
result := spell.CalcAndDealDamage(sim, target, 35, spell.OutcomeAlwaysHit)
character.GainHealth(sim, result.Damage, healthMetrics)
},
})

flamestrikeSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: 18818},
SpellSchool: core.SpellSchoolFire,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskEmpty,
ActionID: core.ActionID{SpellID: 18818},
SpellSchool: core.SpellSchoolFire,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell,

DamageMultiplier: 1,
ThreatMultiplier: 1,

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
for _, aoeTarget := range sim.Encounter.TargetUnits {
spell.CalcAndDealDamage(sim, aoeTarget, sim.Roll(75, 125), spell.OutcomeMagicHit)
Expand Down Expand Up @@ -3330,95 +3474,31 @@ func init() {
core.AddEffectsToTest = true
}

func BlazefuryTriggerAura(character *core.Character, spellID int32, spellSchool core.SpellSchool, damage float64) {
if character.GetSpell(core.ActionID{SpellID: spellID}) != nil {
return
}
func thornsArcaneDamageEffect(agent core.Agent, itemID int32, itemName string, damage float64) {
character := agent.GetCharacter()

procSpell := character.RegisterSpell(core.SpellConfig{
ActionID: core.ActionID{SpellID: spellID},
SpellSchool: spellSchool,
DefenseType: core.DefenseTypeMagic,
ProcMask: core.ProcMaskMeleeDamageProc,
Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell,
ActionID: core.ActionID{ItemID: itemID},
SpellSchool: core.SpellSchoolArcane,
ProcMask: core.ProcMaskEmpty,
Flags: core.SpellFlagBinary | core.SpellFlagNoOnCastComplete | core.SpellFlagPassiveSpell,

DamageMultiplier: 1,
ThreatMultiplier: 1,

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
spell.CalcAndDealDamage(sim, target, damage, spell.OutcomeMagicCrit)
spell.CalcAndDealDamage(sim, target, damage, spell.OutcomeMagicHit)
},
})

core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: fmt.Sprintf("Blazefury Trigger (%d)", spellID),
Callback: core.CallbackOnSpellHitDealt,
Outcome: core.OutcomeLanded,
ProcMask: core.ProcMaskMelee,
SpellFlagsExclude: core.SpellFlagSuppressEquipProcs,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if spell.ProcMask.Matches(core.ProcMaskMeleeSpecial) {
procSpell.ProcMask = core.ProcMaskEmpty
} else {
procSpell.ProcMask = core.ProcMaskDamageProc // Both spell and melee procs
core.MakePermanent(character.GetOrRegisterAura(core.Aura{
Label: fmt.Sprintf("Thorns (%s)", itemName),
OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
if result.Landed() && spell.ProcMask.Matches(core.ProcMaskMelee) {
procSpell.Cast(sim, spell.Unit)
}
procSpell.Cast(sim, result.Target)
},
})
}

// Chance on hit: Spell damage taken by target increased by 15% for 5 sec.
func makeNightfallProc(character *core.Character, itemName string) {
procAuras := character.NewEnemyAuraArray(func(target *core.Unit) *core.Aura {
return target.GetOrRegisterAura(core.Aura{
Label: fmt.Sprintf("Spell Vulnerability (%s)", itemName),
ActionID: core.ActionID{SpellID: 23605},
Duration: time.Second * 5,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexArcane] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFire] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFrost] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexHoly] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexNature] *= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexShadow] *= 1.15
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexArcane] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFire] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexFrost] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexHoly] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexNature] /= 1.15
aura.Unit.PseudoStats.SchoolBonusDamageTaken[stats.SchoolIndexShadow] /= 1.15
},
})
})

core.MakeProcTriggerAura(&character.Unit, core.ProcTrigger{
Name: fmt.Sprintf("%s Trigger", itemName),
Callback: core.CallbackOnSpellHitDealt,
Outcome: core.OutcomeLanded,
ProcMask: core.ProcMaskMelee,
SpellFlagsExclude: core.SpellFlagSuppressWeaponProcs,
PPM: 2,
Handler: func(sim *core.Simulation, spell *core.Spell, result *core.SpellResult) {
procAuras.Get(result.Target).Activate(sim)
},
})
}

func StrengthOfTheChampionAura(character *core.Character) *core.Aura {
actionID := core.ActionID{SpellID: 16916}
healthMetrics := character.NewHealthMetrics(actionID)
return character.GetOrRegisterAura(core.Aura{
Label: "Strength of the Champion",
ActionID: actionID,
Duration: time.Second * 30,
OnGain: func(aura *core.Aura, sim *core.Simulation) {
character.GainHealth(sim, sim.Roll(270, 450), healthMetrics)
character.AddStatDynamic(sim, stats.Strength, 120)
},
OnExpire: func(aura *core.Aura, sim *core.Simulation) {
character.AddStatDynamic(sim, stats.Strength, -120)
},
})
}))
}

var minorArmorReductionEffectCategory = "MinorArmorReduction"
Expand Down
Loading

0 comments on commit ed7ba68

Please sign in to comment.