From 135c4d85477c224bc5ba6f7be6d8cacf4671f16c Mon Sep 17 00:00:00 2001
From: Kate Martin <51387586+renanthera@users.noreply.github.com>
Date: Thu, 9 Jul 2026 14:04:58 -0600
Subject: [PATCH 1/3] [monk] Zenith Stomp can be cast while channeling Spinning
Crane Kick. Zenith Stomp is considered a combo strike ability.
---
engine/class_modules/monk/sc_monk.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/engine/class_modules/monk/sc_monk.cpp b/engine/class_modules/monk/sc_monk.cpp
index 7087ce112ae..cc763b8154d 100644
--- a/engine/class_modules/monk/sc_monk.cpp
+++ b/engine/class_modules/monk/sc_monk.cpp
@@ -3958,8 +3958,9 @@ struct zenith_stomp_t : monk_spell_t
aoe = -1;
reduced_aoe_targets = player->talent.monk.zenith_stomp->effectN( 1 ).base_value();
- may_combo_strike = false;
+ may_combo_strike = player->wowv_ge( { 12, 1, 0 } );
ww_mastery = true;
+ cast_during_sck = true;
}
void init() override
From 3af7969a4c23659b0b9ed9e736e07b1df307de44 Mon Sep 17 00:00:00 2001
From: Kate Martin <51387586+renanthera@users.noreply.github.com>
Date: Sat, 11 Jul 2026 13:05:49 -0600
Subject: [PATCH 2/3] [monk] Reimplement `cast_during_sck` using
`action_t::usable_during_current_cast()` and by setting
`action_t::usable_while_casting` and `action_t::use_while_casting`
automatically to avoid a terrible APL experience.
---
engine/class_modules/monk/sc_monk.cpp | 31 ++++++---------------------
engine/class_modules/monk/sc_monk.hpp | 2 +-
2 files changed, 7 insertions(+), 26 deletions(-)
diff --git a/engine/class_modules/monk/sc_monk.cpp b/engine/class_modules/monk/sc_monk.cpp
index cc763b8154d..aeb3053313e 100644
--- a/engine/class_modules/monk/sc_monk.cpp
+++ b/engine/class_modules/monk/sc_monk.cpp
@@ -221,18 +221,12 @@ bool monk_action_t::usable_moving() const
}
template
-bool monk_action_t::ready()
+bool monk_action_t::usable_during_current_cast() const
{
- // Spell data nil or not_found
- if ( base_t::data().id() == 0 )
- return false;
-
- // These abilities are able to be used during Spinning Crane Kick
- if ( cast_during_sck )
- base_t::usable_while_casting = p()->channeling && p()->baseline.monk.spinning_crane_kick &&
- ( p()->channeling->id == p()->baseline.monk.spinning_crane_kick->id() );
+ if ( cast_during_sck && p()->channeling && p()->channeling->id == p()->baseline.monk.spinning_crane_kick->id() )
+ return true;
- return base_t::ready();
+ return base_t::usable_during_current_cast();
}
template
@@ -260,20 +254,8 @@ void monk_action_t::init()
}
}
- // Allow this ability to be cast during SCK
- if ( cast_during_sck && !base_t::background && !base_t::dual )
- {
- if ( base_t::usable_while_casting )
- {
- cast_during_sck = false;
- p()->sim->print_debug( "{}: cast_during_sck ignored because usable_while_casting = true", full_name() );
- }
- else
- {
- base_t::usable_while_casting = true;
- base_t::use_while_casting = true;
- }
- }
+ if ( cast_during_sck )
+ base_t::usable_while_casting = base_t::use_while_casting = true;
}
template
@@ -2502,7 +2484,6 @@ struct keg_smash_t : monk_melee_attack_t
fuel_on_the_fire( nullptr )
{
parse_options( options_str );
- // TODO: can cast_during_sck be automated?
cast_during_sck = true;
full_amount_targets = 1;
diff --git a/engine/class_modules/monk/sc_monk.hpp b/engine/class_modules/monk/sc_monk.hpp
index c96afdd6741..923171a3450 100644
--- a/engine/class_modules/monk/sc_monk.hpp
+++ b/engine/class_modules/monk/sc_monk.hpp
@@ -97,7 +97,7 @@ struct monk_action_t : public parse_action_effects_t
std::unique_ptr create_expression( std::string_view name_str ) override;
bool usable_moving() const override;
- bool ready() override;
+ bool usable_during_current_cast() const override;
void init() override;
void init_finished() override;
void reset_swing();
From a29f51f42792df411e2a3485e9ebf0357b844879 Mon Sep 17 00:00:00 2001
From: Kate Martin <51387586+renanthera@users.noreply.github.com>
Date: Sat, 11 Jul 2026 13:14:35 -0600
Subject: [PATCH 3/3] [monk] Clean up some unused actions. Use Slicing Winds
constructor for Flying Serpent Kick actions if talent is selected.
---
engine/class_modules/monk/sc_monk.cpp | 115 +-------------------------
1 file changed, 2 insertions(+), 113 deletions(-)
diff --git a/engine/class_modules/monk/sc_monk.cpp b/engine/class_modules/monk/sc_monk.cpp
index aeb3053313e..21deaee0570 100644
--- a/engine/class_modules/monk/sc_monk.cpp
+++ b/engine/class_modules/monk/sc_monk.cpp
@@ -2799,60 +2799,6 @@ struct touch_of_karma_t : public monk_melee_attack_t
}
};
-struct provoke_t : public monk_melee_attack_t
-{
- provoke_t( monk_t *p, std::string_view options_str ) : monk_melee_attack_t( p, "provoke", p->baseline.monk.provoke )
- {
- parse_options( options_str );
- use_off_gcd = true;
- ignore_false_positive = true;
- }
-
- void impact( action_state_t *s ) override
- {
- if ( s->target->is_enemy() )
- target->taunt( player );
-
- monk_melee_attack_t::impact( s );
- }
-};
-
-struct spear_hand_strike_t : public monk_melee_attack_t
-{
- spear_hand_strike_t( monk_t *p, std::string_view options_str )
- : monk_melee_attack_t( p, "spear_hand_strike", p->talent.monk.spear_hand_strike )
- {
- parse_options( options_str );
- ignore_false_positive = true;
- is_interrupt = true;
- cast_during_sck = player->specialization() != MONK_WINDWALKER;
- may_miss = may_block = may_dodge = may_parry = false;
- }
-};
-
-struct leg_sweep_t : public monk_melee_attack_t
-{
- leg_sweep_t( monk_t *p, std::string_view options_str )
- : monk_melee_attack_t( p, "leg_sweep", p->baseline.monk.leg_sweep )
- {
- parse_options( options_str );
- ignore_false_positive = true;
- may_miss = may_block = may_dodge = may_parry = false;
- cast_during_sck = true;
- }
-};
-
-struct paralysis_t : public monk_melee_attack_t
-{
- paralysis_t( monk_t *p, std::string_view options_str )
- : monk_melee_attack_t( p, "paralysis", p->talent.monk.paralysis )
- {
- parse_options( options_str );
- ignore_false_positive = true;
- may_miss = may_block = may_dodge = may_parry = false;
- }
-};
-
struct flying_serpent_kick_t : public monk_melee_attack_t
{
bool first_charge;
@@ -3139,31 +3085,6 @@ struct black_ox_brew_t : public brew_t
}
};
-struct roll_t : public monk_spell_t
-{
- roll_t( monk_t *player, std::string_view options_str )
- : monk_spell_t( player, "roll",
- ( player->talent.monk.chi_torpedo->ok() ? spell_data_t::not_found() : player->baseline.monk.roll ) )
- {
- cast_during_sck = true;
-
- parse_options( options_str );
- }
-};
-
-struct chi_torpedo_t : public monk_spell_t
-{
- chi_torpedo_t( monk_t *player, std::string_view options_str )
- : monk_spell_t(
- player, "chi_torpedo",
- ( player->talent.monk.chi_torpedo->ok() ? player->talent.monk.chi_torpedo : spell_data_t::not_found() ) )
- {
- parse_options( options_str );
-
- cast_during_sck = true;
- }
-};
-
struct crackling_jade_lightning_t : public monk_spell_t
{
struct aoe_dot_t : public monk_spell_t
@@ -4013,26 +3934,6 @@ struct zenith_t : public monk_spell_t
}
};
-struct vivify_t : public harmonic_surge_t
-{
- vivify_t( monk_t *player, std::string_view options_str ) : base_t( player, "vivify", player->baseline.monk.vivify )
- {
- parse_options( options_str );
-
- spell_power_mod.direct = data().effectN( 1 ).sp_coeff();
- base_execute_time += player->talent.monk.vivacious_vivification->effectN( 1 ).time_value();
-
- cast_during_sck = false;
- }
-
- void execute() override
- {
- base_t::execute();
-
- p()->action.chi_wave->execute();
- }
-};
-
struct expel_harm_t : monk_heal_t
{
struct damage_t : monk_spell_t
@@ -5364,28 +5265,14 @@ action_t *monk_t::create_action( std::string_view name, std::string_view options
return new blackout_kick_t( this, options_str );
if ( name == "expel_harm" )
return new expel_harm_t( this, options_str );
- if ( name == "leg_sweep" )
- return new leg_sweep_t( this, options_str );
- if ( name == "paralysis" )
- return new paralysis_t( this, options_str );
if ( name == "rising_sun_kick" )
return new rising_sun_kick_t( this, options_str );
if ( name == "rushing_wind_kick" )
return new rushing_wind_kick_t( this, options_str );
- if ( name == "roll" )
- return new roll_t( this, options_str );
- if ( name == "spear_hand_strike" )
- return new spear_hand_strike_t( this, options_str );
if ( name == "spinning_crane_kick" )
return new spinning_crane_kick_t( this, options_str );
- if ( name == "vivify" )
- return new vivify_t( this, options_str );
if ( name == "fortifying_brew" )
return new fortifying_brew_t( this, options_str );
- if ( name == "provoke" )
- return new provoke_t( this, options_str );
- if ( name == "chi_torpedo" )
- return new chi_torpedo_t( this, options_str );
if ( name == "touch_of_death" )
return new touch_of_death_t( this, options_str );
@@ -5418,6 +5305,8 @@ action_t *monk_t::create_action( std::string_view name, std::string_view options
// Windwalker
if ( name == "fists_of_fury" )
return new fists_of_fury_t( this, options_str );
+ if ( name == "flying_serpent_kick" && talent.windwalker.slicing_winds->ok() )
+ return new slicing_winds_t( this, options_str );
if ( name == "flying_serpent_kick" )
return new flying_serpent_kick_t( this, options_str );
if ( name == "slicing_winds" )