Skip to content

Commit 5a801e4

Browse files
committed
Boilerplate Water Ele and Nether Tempest code. I don't really know how to extend half of the dot damage to random targets very well so I may have to abandon using dots for something a bit more barebones. Water elemental stamina and intellect not dialed in, hp of ele appears to be about 70% of user, and intellect I have no idea whatsoever how to calculate. Haste and SP appear to be 1 to 1
1 parent 5b09793 commit 5a801e4

3 files changed

Lines changed: 84 additions & 38 deletions

File tree

sim/mage/frost/water_elemental.go

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"github.com/wowsims/mop/sim/core/stats"
88
)
99

10-
// The numbers in this file are VERY rough approximations based on logs.
11-
1210
func (Mage *FrostMage) registerSummonWaterElementalSpell() {
1311

1412
Mage.SummonWaterElemental = Mage.RegisterSpell(core.SpellConfig{
@@ -35,9 +33,8 @@ func (Mage *FrostMage) registerSummonWaterElementalSpell() {
3533
})
3634

3735
Mage.AddMajorCooldown(core.MajorCooldown{
38-
Spell: Mage.SummonWaterElemental,
39-
Priority: core.CooldownPriorityDrums + 1000, // Always prefer to cast before drums or lust so the ele gets their benefits.
40-
Type: core.CooldownTypeDPS,
36+
Spell: Mage.SummonWaterElemental,
37+
Type: core.CooldownTypeDPS,
4138
})
4239
}
4340

@@ -46,14 +43,10 @@ type WaterElemental struct {
4643

4744
mageOwner *FrostMage
4845

49-
// Water Ele almost never just stands still and spams like we want, it sometimes
50-
// does its own thing. This controls how much it does that.
51-
disobeyChance float64
52-
5346
Waterbolt *core.Spell
5447
}
5548

56-
func (Mage *FrostMage) NewWaterElemental(disobeyChance float64) *WaterElemental {
49+
func (Mage *FrostMage) NewWaterElemental() *WaterElemental {
5750
waterElemental := &WaterElemental{
5851
Pet: core.NewPet(core.PetConfig{
5952
Name: "Water Elemental",
@@ -63,8 +56,7 @@ func (Mage *FrostMage) NewWaterElemental(disobeyChance float64) *WaterElemental
6356
EnabledOnStart: true,
6457
IsGuardian: true,
6558
}),
66-
mageOwner: Mage,
67-
disobeyChance: disobeyChance,
59+
mageOwner: Mage,
6860
}
6961
waterElemental.EnableManaBarWithModifier(0.333)
7062

@@ -86,41 +78,29 @@ func (we *WaterElemental) Reset(_ *core.Simulation) {
8678

8779
func (we *WaterElemental) ExecuteCustomRotation(sim *core.Simulation) {
8880
spell := we.Waterbolt
89-
90-
if sim.Proc(we.disobeyChance, "Disobey") {
91-
// Water ele has decided not to cooperate, so just wait for the cast time
92-
// instead of casting.
93-
we.WaitUntil(sim, sim.CurrentTime+spell.DefaultCast.CastTime)
94-
return
95-
}
96-
9781
spell.Cast(sim, we.CurrentTarget)
9882
}
9983

100-
// These numbers are just rough guesses based on looking at some logs.
10184
var waterElementalBaseStats = stats.Stats{
102-
// TODO update. taken at level 80 on beta
103-
stats.Mana: 16123,
104-
stats.Intellect: 369, //unsure on beta
85+
// Mana seems to always be at 300k on beta
86+
stats.Mana: 300000,
10587
}
10688

10789
var waterElementalStatInheritance = func(ownerStats stats.Stats) stats.Stats {
108-
// These numbers are just rough guesses based on looking at some logs.
10990
return stats.Stats{
110-
// TODO Pet stats scale dynamically in combat
111-
stats.Stamina: ownerStats[stats.Stamina] * 0.2,
112-
stats.Intellect: ownerStats[stats.Intellect] * 0.3,
113-
stats.SpellPower: ownerStats[stats.SpellPower] * 0.333,
114-
115-
// TODO test crit chance. It does crit, so figure out how often and if it scales
116-
/* Results: owner 5% crit, Waterbolt 13% crit
117-
owner 18% crit, waterbolt 18% crit
118-
*/
91+
stats.Stamina: ownerStats[stats.Stamina] * 0.2,
92+
stats.Intellect: ownerStats[stats.Intellect] * 0.3,
93+
stats.SpellPower: ownerStats[stats.SpellPower],
11994
stats.HasteRating: ownerStats[stats.HasteRating],
120-
stats.SpellCritPercent: ownerStats[stats.SpellCritPercent],
95+
stats.SpellCritPercent: ownerStats[stats.SpellCritPercent] * 0.5,
96+
// 500 hits 85 misses 4.2% crit with character at 8.09% crit, it's likely around 50%
12197
}
12298
}
12399

100+
var waterboltVariance = 0.25 // Per https://wago.tools/db2/SpellEffect?build=5.5.0.60802&filter%5BSpellID%5D=31707 Field: "Variance"
101+
var waterboltScale = 0.5 // Per https://wago.tools/db2/SpellEffect?build=5.5.0.60802&filter%5BSpellID%5D=31707 Field: "Coefficient"
102+
var waterboltCoefficient = 0.5 // Per https://wago.tools/db2/SpellEffect?build=5.5.0.60802&filter%5BSpellID%5D=31707 Field: "BonusCoefficient"
103+
124104
func (we *WaterElemental) registerWaterboltSpell() {
125105
we.Waterbolt = we.RegisterSpell(core.SpellConfig{
126106
ActionID: core.ActionID{SpellID: 31707},
@@ -140,11 +120,14 @@ func (we *WaterElemental) registerWaterboltSpell() {
140120
DamageMultiplier: 1,
141121
CritMultiplier: we.mageOwner.DefaultCritMultiplier(),
142122
ThreatMultiplier: 1,
143-
BonusCoefficient: 0.833,
123+
BonusCoefficient: waterboltCoefficient,
144124

145125
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
146-
baseDamage := .405 * we.mageOwner.ClassSpellScaling
147-
spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMagicHitAndCrit)
126+
baseDamage := we.CalcAndRollDamageRange(sim, waterboltScale, waterboltVariance)
127+
result := spell.CalcDamage(sim, target, baseDamage, spell.OutcomeMagicHitAndCrit)
128+
spell.WaitTravelTime(sim, func(sim *core.Simulation) {
129+
spell.DealDamage(sim, result)
130+
})
148131
},
149132
})
150133
}

sim/mage/mage.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Mage struct {
2828
Combustion *core.Spell
2929
Ignite *core.Spell
3030
LivingBomb *core.Spell
31+
NetherTempest *core.Spell
3132
FireBlast *core.Spell
3233
FlameOrbExplode *core.Spell
3334
Flamestrike *core.Spell
@@ -323,6 +324,7 @@ const (
323324
MageSpellLivingBombDot
324325
MageSpellManaGems
325326
MageSpellMirrorImage
327+
MageSpellNetherTempest
326328
MageSpellPresenceOfMind
327329
MageSpellPyroblast
328330
MageSpellPyroblastDot

sim/mage/nether_tempest.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package mage
2+
3+
import (
4+
"time"
5+
6+
"github.com/wowsims/mop/sim/core"
7+
)
8+
9+
func (mage *Mage) registerNetherTempestSpell() {
10+
if !mage.Talents.NetherTempest {
11+
return
12+
}
13+
var netherTempestCoefficient = 0.24 // Per https://wago.tools/db2/SpellEffect?build=5.5.0.60802&filter%5BSpellID%5D=114923 Field "EffetBonusCoefficient"
14+
var netherTempestScaling = .31 // Per https://wago.tools/db2/SpellEffect?build=5.5.0.60802&filter%5BSpellID%5D=114923 Field "Coefficient"
15+
16+
mage.NetherTempest = mage.GetOrRegisterSpell(core.SpellConfig{
17+
ActionID: core.ActionID{SpellID: 114923},
18+
SpellSchool: core.SpellSchoolArcane,
19+
ProcMask: core.ProcMaskSpellDamage,
20+
Flags: core.SpellFlagAPL,
21+
ClassSpellMask: MageSpellNetherTempest,
22+
23+
ManaCost: core.ManaCostOptions{
24+
BaseCostPercent: 1.5,
25+
},
26+
Cast: core.CastConfig{
27+
DefaultCast: core.Cast{
28+
GCD: core.GCDDefault,
29+
},
30+
},
31+
32+
DamageMultiplierAdditive: 1,
33+
CritMultiplier: mage.DefaultCritMultiplier(),
34+
ThreatMultiplier: 1,
35+
36+
Dot: core.DotConfig{
37+
Aura: core.Aura{
38+
Label: "Nether Tempest",
39+
},
40+
NumberOfTicks: 12,
41+
TickLength: time.Second * 1,
42+
AffectedByCastSpeed: true,
43+
BonusCoefficient: netherTempestCoefficient,
44+
OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, isRollover bool) {
45+
dot.Snapshot(target, mage.CalcScalingSpellDmg(netherTempestScaling))
46+
},
47+
OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) {
48+
dot.CalcAndDealPeriodicSnapshotDamage(sim, target, dot.OutcomeSnapshotCrit)
49+
},
50+
},
51+
52+
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
53+
result := spell.CalcOutcome(sim, target, spell.OutcomeMagicHitNoHitCounter)
54+
if result.Landed() {
55+
spell.Dot(target).Apply(sim)
56+
}
57+
58+
spell.DealOutcome(sim, result)
59+
},
60+
})
61+
}

0 commit comments

Comments
 (0)