Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b181ff2
Added mistweaver to alpha
Patrick-Hogeveen May 13, 2025
fb1ada6
Merge branch 'wowsims:master' into master
Patrick-Hogeveen May 13, 2025
5fb6473
Merge branch 'wowsims:master' into master
Patrick-Hogeveen May 16, 2025
eeec9ce
Merge branch 'wowsims:master' into master
Patrick-Hogeveen May 17, 2025
78e9266
Adding monk as healer spec in the front end
Patrick-Hogeveen May 17, 2025
72d980a
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen May 17, 2025
6aa67fc
Renewing mist (wip) + surging mist
Patrick-Hogeveen May 17, 2025
d685e5e
Merge branch 'wowsims:master' into master
Patrick-Hogeveen May 27, 2025
80b9f3e
Mistweaver changes
Patrick-Hogeveen May 27, 2025
2687aab
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen May 27, 2025
ce9108c
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 6, 2025
2bdec85
Working on making monk spells functional
Patrick-Hogeveen Jun 6, 2025
668dd2a
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jun 6, 2025
bf11a9e
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 22, 2025
26cca5c
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 22, 2025
590b2ab
Added cast while channeling logic
Patrick-Hogeveen Jun 22, 2025
93a5f01
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jun 22, 2025
aaf950e
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 25, 2025
2cdfa93
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 26, 2025
7c773ef
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jun 26, 2025
ea67b07
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 28, 2025
8e59baa
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jun 28, 2025
42ca540
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 29, 2025
22ba653
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jun 29, 2025
0f986db
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 29, 2025
b173c2d
Soothing mist fix + passives
Patrick-Hogeveen Jun 29, 2025
ce8f36a
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jun 29, 2025
bc16a63
channel fix + monk core changes
Patrick-Hogeveen Jun 29, 2025
10f82a9
Merge branch 'wowsims:master' into master
Patrick-Hogeveen Jun 30, 2025
09f417e
Remove debug prints
Patrick-Hogeveen Jun 30, 2025
67ca075
Merge branch 'master' of https://github.com/Patrick-Hogeveen/mop
Patrick-Hogeveen Jul 1, 2025
894f836
Fix muscle memory passive
Patrick-Hogeveen Jul 1, 2025
5563765
Vital mists implementation
Patrick-Hogeveen Jul 2, 2025
9b5d21a
Fix spell_mod function placements in code
Patrick-Hogeveen Jul 2, 2025
258aa4c
Soothing mist aura consolidation
Patrick-Hogeveen Jul 4, 2025
b4dcd50
Changes / fixes based on pr draft comments
Patrick-Hogeveen Jul 10, 2025
eb1e58c
Mistweaver aura updates
Patrick-Hogeveen Jul 14, 2025
ff438d4
Merge branch 'master' of github.com:wowsims/mop
Patrick-Hogeveen Jul 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 128 additions & 128 deletions sim/common/mop/stat_bonus_procs_auto_gen.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions sim/core/apl.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ func (rot *APLRotation) reset(sim *Simulation) {
rot.inLoop = false
rot.interruptChannelIf = nil
rot.allowChannelRecastOnInterrupt = false

//rot.allowCastWhileChanneling = slices.ContainsFunc(rot.unit.Spellbook, func(spell *Spell) bool {
// return spell.Flags.Matches(SpellFlagCastWhileChanneling)
//})
Comment on lines +269 to +271

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General comment: delete any unused commented code like this for cleanliness once you are done debugging.


for _, action := range rot.allAPLActions() {
action.impl.Reset(sim)
}
Expand Down
8 changes: 4 additions & 4 deletions sim/core/pet.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ func (pet *Pet) enableDynamicMeleeSpeed(sim *Simulation) {
panic("Pet already present in dynamic melee speed pet list!")
}

if math.Abs(pet.inheritedMeleeSpeedMultiplier - 1) > 1e-14 {
if math.Abs(pet.inheritedMeleeSpeedMultiplier-1) > 1e-14 {
panic(fmt.Sprintf("Pet melee speed multiplier was not reset properly! Current inherited value = %.17f", pet.inheritedMeleeSpeedMultiplier))
}

Expand All @@ -338,7 +338,7 @@ func (pet *Pet) resetDynamicMeleeSpeed(sim *Simulation) {
panic("Pet not present in dynamic melee speed pet list!")
}

pet.dynamicMeleeSpeedInheritance(sim, 1 / pet.inheritedMeleeSpeedMultiplier)
pet.dynamicMeleeSpeedInheritance(sim, 1/pet.inheritedMeleeSpeedMultiplier)
pet.dynamicMeleeSpeedInheritance = nil
}

Expand All @@ -347,7 +347,7 @@ func (pet *Pet) enableDynamicCastSpeed(sim *Simulation) {
panic("Pet already present in dynamic cast speed pet list!")
}

if math.Abs(pet.inheritedCastSpeedMultiplier - 1) > 1e-14 {
if math.Abs(pet.inheritedCastSpeedMultiplier-1) > 1e-14 {
panic(fmt.Sprintf("Pet cast speed multiplier was not reset properly! Current inherited value = %.17f", pet.inheritedCastSpeedMultiplier))
}

Expand All @@ -371,7 +371,7 @@ func (pet *Pet) resetDynamicCastSpeed(sim *Simulation) {
panic("Pet not present in dynamic cast speed pet list!")
}

pet.dynamicCastSpeedInheritance(sim, 1 / pet.inheritedCastSpeedMultiplier)
pet.dynamicCastSpeedInheritance(sim, 1/pet.inheritedCastSpeedMultiplier)
pet.dynamicCastSpeedInheritance = nil
}

Expand Down
1 change: 1 addition & 0 deletions sim/core/spell.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ func (spell *Spell) CanCast(sim *Simulation, target *Unit) bool {
//if sim.Log != nil {
// sim.Log("Cant cast because already casting/channeling")
//}

return false
}

Expand Down
2 changes: 1 addition & 1 deletion sim/druid/druid.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type Druid struct {
ProwlAura *core.Aura
SurvivalInstinctsAura *core.Aura

form DruidForm
form DruidForm

// Guardian leather specialization is form-specific
GuardianLeatherSpecTracker *core.Aura
Expand Down
4 changes: 2 additions & 2 deletions sim/druid/feral/feral.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ func (cat *FeralDruid) applyMastery() {
razorClaws := cat.AddDynamicMod(core.SpellModConfig{
ClassMask: druid.DruidSpellThrashCat | druid.DruidSpellRake | druid.DruidSpellRip,
Kind: core.SpellMod_DamageDone_Pct,
FloatValue: baseMasteryMod + masteryModPerPoint * cat.GetMasteryPoints(),
FloatValue: baseMasteryMod + masteryModPerPoint*cat.GetMasteryPoints(),
})

cat.AddOnMasteryStatChanged(func(_ *core.Simulation, _ float64, newMasteryRating float64) {
razorClaws.UpdateFloatValue(baseMasteryMod + masteryModPerPoint * core.MasteryRatingToMasteryPoints(newMasteryRating))
razorClaws.UpdateFloatValue(baseMasteryMod + masteryModPerPoint*core.MasteryRatingToMasteryPoints(newMasteryRating))
})

razorClaws.Activate()
Expand Down
6 changes: 3 additions & 3 deletions sim/druid/feral/savage_roar.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (cat *FeralDruid) registerSavageRoarSpell() {
isGlyphed := cat.HasMajorGlyph(proto.DruidMajorGlyph_GlyphOfSavagery)

cat.SavageRoarDurationTable = [6]time.Duration{
core.TernaryDuration(isGlyphed, time.Second * 12, 0),
core.TernaryDuration(isGlyphed, time.Second*12, 0),
time.Second * 18,
time.Second * 24,
time.Second * 30,
Expand Down Expand Up @@ -78,8 +78,8 @@ func (cat *FeralDruid) registerSavageRoarSpell() {

if !isGlyphed {
aura.Deactivate(sim)
} else if aura.RemainingDuration(sim) > time.Second * 12 {
aura.UpdateExpires(sim.CurrentTime + time.Second * 12)
} else if aura.RemainingDuration(sim) > time.Second*12 {
aura.UpdateExpires(sim.CurrentTime + time.Second*12)
}
},
},
Expand Down
4 changes: 2 additions & 2 deletions sim/druid/rip.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (druid *Druid) registerRipSpell() {
const attackPowerCoeff = 0.0484

// Scaled parameters for spell code
baseDamage := coefficient * druid.ClassSpellScaling // 112.7582
baseDamage := coefficient * druid.ClassSpellScaling // 112.7582
comboPointCoeff := resourceCoefficient * druid.ClassSpellScaling // 319.664

druid.Rip = druid.RegisterSpell(Cat, core.SpellConfig{
Expand Down Expand Up @@ -62,7 +62,7 @@ func (druid *Druid) registerRipSpell() {

cp := float64(druid.ComboPoints())
ap := dot.Spell.MeleeAttackPower()
dot.SnapshotPhysical(target, baseDamage + comboPointCoeff*cp + attackPowerCoeff*cp*ap)
dot.SnapshotPhysical(target, baseDamage+comboPointCoeff*cp+attackPowerCoeff*cp*ap)

// Store snapshot power parameters for later use.
druid.UpdateBleedPower(druid.Rip, sim, target, true, true)
Expand Down
2 changes: 1 addition & 1 deletion sim/hunter/a_murder_of_crows.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (hunter *Hunter) registerAMOCSpell() {
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
result := spell.CalcAndDealOutcome(sim, target, spell.OutcomeAlwaysHit)
pa := sim.GetConsumedPendingActionFromPool()
pa.NextActionAt = sim.CurrentTime + time.Second * 2
pa.NextActionAt = sim.CurrentTime + time.Second*2

pa.OnAction = func(sim *core.Simulation) {
if result.Landed() {
Expand Down
6 changes: 6 additions & 0 deletions sim/monk/blackout_kick.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func blackoutKickSpellConfig(monk *Monk, isSEFClone bool, overrides core.SpellCo
func (monk *Monk) registerBlackoutKick() {
chiMetrics := monk.NewChiMetrics(blackoutKickActionID)
chiCost := int32(2)
manaMetrics := monk.NewManaMetrics(blackoutKickActionID)

monk.RegisterSpell(blackoutKickSpellConfig(monk, false, core.SpellConfig{
Cast: core.CastConfig{
Expand All @@ -92,6 +93,11 @@ func (monk *Monk) registerBlackoutKick() {
} else {
monk.SpendChi(sim, chiCost, chiMetrics)
}

if monk.MuscleMemoryAura.IsActive() {
result.Damage += result.Damage * 1.5
Copy link

@1337LutZ 1337LutZ Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably become a 0.5 DamageDonePct SpellMod on the Aura itself, because right now you are actually not going a 150% mod, but 250%. (100% of the original result + 150% of the original result * 1.5)

monk.AddMana(sim, monk.MaxMana()*0.04, manaMetrics)
}
}

spell.DealOutcome(sim, result)
Expand Down
4 changes: 2 additions & 2 deletions sim/monk/jab.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (monk *Monk) registerJab() {
Refund: 0.8,
},
ManaCost: core.ManaCostOptions{
BaseCostPercent: core.TernaryFloat64(monk.StanceMatches(WiseSerpent), 8, 0),
BaseCostPercent: 6, //Lowed from 8 based on patch notes
},

Cast: core.CastConfig{
Expand All @@ -84,9 +84,9 @@ func (monk *Monk) registerJab() {
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {

baseDamage := monk.CalculateMonkStrikeDamage(sim, spell)
result := spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMeleeSpecialHitAndCrit)

if result.Landed() {
chiGain := core.TernaryInt32(monk.StanceMatches(FierceTiger), 2, 1)
monk.AddChi(sim, spell, chiGain, chiMetrics)
Expand Down
88 changes: 88 additions & 0 deletions sim/monk/mistweaver/enveloping_mist.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package mistweaver

import (
"fmt"
"time"

"github.com/wowsims/mop/sim/core"
"github.com/wowsims/mop/sim/monk"
)

func (mw *MistweaverMonk) registerEnvelopingMist() {
actionID := core.ActionID{SpellID: 124682}
chiMetrics := mw.NewChiMetrics(actionID)
spellCoeff := 0.45

mw.envelopingMist = mw.RegisterSpell(core.SpellConfig{
ActionID: actionID,
SpellSchool: core.SpellSchoolNature,
ProcMask: core.ProcMaskSpellHealing,
Flags: core.SpellFlagHelpful | core.SpellFlagAPL, // | core.SpellFlagCastWhileChanneling,
Comment on lines +19 to +20

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you intend to comment out the extra flag here?

ClassSpellMask: monk.MonkSpellEnvelopingMist,

ManaCost: core.ManaCostOptions{BaseCostPercent: 0},
Comment on lines +22 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just omit this field if the cost is 0.

Cast: core.CastConfig{
DefaultCast: core.Cast{
GCD: core.GCDDefault,
CastTime: time.Millisecond * 2000,
},
},
DamageMultiplier: 1,
ThreatMultiplier: 1,
CritMultiplier: mw.DefaultCritMultiplier(),

ExtraCastCondition: func(_ *core.Simulation, _ *core.Unit) bool {
return mw.GetChi() >= 3
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {

mw.SpendChi(sim, 3, chiMetrics)
spell.RelatedDotSpell.Cast(sim, target)

},
})

mw.envelopingMist.RelatedDotSpell = mw.RegisterSpell(core.SpellConfig{
ActionID: actionID,
SpellSchool: core.SpellSchoolNature,
ProcMask: core.ProcMaskSpellHealing,
Flags: core.SpellFlagHelpful,
//ClassSpellMask: monk.MonkSpellEnvelopingMist,

Comment on lines +51 to +52

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you intend to comment out the spell mask here?

DamageMultiplier: 1,
ThreatMultiplier: 1,
CritMultiplier: mw.DefaultCritMultiplier(),
Hot: core.DotConfig{
Aura: core.Aura{
Label: "Enveloping Mist",
},
NumberOfTicks: 6,
TickLength: 1 * time.Second,
AffectedByCastSpeed: true,
HasteReducesDuration: true,
OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, _ bool) {
dot.SnapshotBaseDamage = 0 + mw.CalcScalingSpellDmg(spellCoeff)
dot.SnapshotAttackerMultiplier = dot.Spell.CasterHealingMultiplier()
},

OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) {

dot.CalcAndDealPeriodicSnapshotHealing(sim, target, dot.OutcomeTick)

},
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
hot := spell.Hot(target)
//Will probably have to remove enemy units as options for friendly spells?
if target.Type == core.EnemyUnit {
fmt.Printf("Attemping to cast Enveloping mist on enemy: %v\n", target.Label)
return
}
Comment on lines +79 to +82

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to panic here rather than printing a message and returning. Forcing a crash is more likely to alert the user that their APL was set up incorrectly.


hot.Apply(sim)

},
})
}
101 changes: 101 additions & 0 deletions sim/monk/mistweaver/mana_tea.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package mistweaver

import (
"time"

"github.com/wowsims/mop/sim/core"
"github.com/wowsims/mop/sim/core/stats"
"github.com/wowsims/mop/sim/monk"
)

func (mw *MistweaverMonk) registerManaTea() {

buffActionID := core.ActionID{SpellID: 115294}
stackActionID := core.ActionID{SpellID: 123766}
manaMetrics := mw.NewManaMetrics(buffActionID)
manaPerTick := 0.0
//numerOFTicks := 6

mw.Monk.RegisterOnChiSpent(func(sim *core.Simulation, chiSpent int32) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mw.RegisterOnChiSpent should work

accumulatedChi := mw.outstandingChi + chiSpent

for accumulatedChi >= 4 {

mw.AddBrewStacks(sim, 1)
accumulatedChi -= 4
}

mw.outstandingChi = accumulatedChi

})

mw.ManaTeaStackAura = mw.RegisterAura(core.Aura{
Label: "Mana Tea Stacks" + mw.Label,
ActionID: stackActionID,
Duration: time.Hour,
MaxStacks: 20,
})

mw.Monk.RegisterOnNewBrewStacks(func(sim *core.Simulation, stacksToAdd int32) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mw.RegisterOnNewBrewStacks should work

mw.ManaTeaStackAura.Activate(sim)

procChance := mw.GetStat(stats.SpellCritPercent)

if sim.Proc(procChance/100, "Mana Tea") {
stacksToAdd += 1
}

mw.ManaTeaStackAura.SetStacks(sim, mw.ManaTeaStackAura.GetStacks()+stacksToAdd)
})

mw.RegisterSpell(core.SpellConfig{
ActionID: buffActionID,
Flags: core.SpellFlagAPL | core.SpellFlagNoOnCastComplete | core.SpellFlagHelpful | core.SpellFlagChanneled,
ClassSpellMask: monk.MonkSpellManaTea,

Cast: core.CastConfig{
DefaultCast: core.Cast{
GCD: time.Millisecond * 1000,
},
},

Hot: core.DotConfig{
SelfOnly: true,
Aura: core.Aura{
Label: "Mana Tea",
Duration: 3 * time.Second, //Set at activation
},
NumberOfTicks: 6,
TickLength: 500 * time.Millisecond,
AffectedByCastSpeed: false, //?
OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, isRollover bool) {
mw.manaTeaAura = dot.Aura
},
Comment on lines +71 to +73

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General comment for readability: replace any unused function inputs (in this case sim, target, and isRollover) with _.

OnTick: func(sim *core.Simulation, target *core.Unit, spell *core.Dot) {
mw.AddMana(sim, manaPerTick, manaMetrics)

mw.ManaTeaStackAura.RemoveStack(sim)

},
},

ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool {

return mw.ManaTeaStackAura.GetStacks() > 0
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
manaPerTick = mw.MaxMana() * 0.05 //Patched to restore 5% instead of original 4%

hot := spell.SelfHot()
stacksToUse := min(mw.ManaTeaStackAura.GetStacks(), 6.0)
hot.Duration = time.Duration(stacksToUse) * 500 * time.Millisecond
hot.BaseTickCount = stacksToUse
hot.Activate(sim)
//mw.ManaTeaStackAura.SetStacks(sim, mw.ManaTeaStackAura.GetStacks()-1)

//spell.SelfHot().Apply(sim)

},
})
}
21 changes: 21 additions & 0 deletions sim/monk/mistweaver/mistweaver.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ func NewMistweaverMonk(character *core.Character, options *proto.Player) *Mistwe

type MistweaverMonk struct {
*monk.Monk

ManaTeaStackAura *core.Aura

renewingMist *core.Spell
envelopingMist *core.Spell

JadeSerpentAura *core.Aura
//May move this to monk as both ww and mw use this
outstandingChi int32

manaTeaAura *core.Aura
}

func (mw *MistweaverMonk) GetMonk() *monk.Monk {
Expand All @@ -68,11 +79,21 @@ func (mw *MistweaverMonk) ApplyTalents() {
}

func (mw *MistweaverMonk) Reset(sim *core.Simulation) {
mw.outstandingChi = 0
mw.Monk.Reset(sim)
}

func (mw *MistweaverMonk) RegisterSpecializationEffects() {
mw.RegisterMastery()
mw.registerRenewingMist()
mw.registerSurgingMist()
mw.registerSoothingMist()
mw.registerEnvelopingMist()
mw.registerUplift()
mw.registerRevival()
mw.registerSummonJadeSerpentStatue()
mw.registerManaTea()
mw.registerPassives()
}

func (mw *MistweaverMonk) RegisterMastery() {
Expand Down
Loading