diff --git a/engine/class_modules/apl/apl_monk.cpp b/engine/class_modules/apl/apl_monk.cpp index 76e8d8f2972..526cf1aa92e 100644 --- a/engine/class_modules/apl/apl_monk.cpp +++ b/engine/class_modules/apl/apl_monk.cpp @@ -186,10 +186,6 @@ void live_apl( monk_t* player ) // Default List def->add_action( "auto_attack,target_if=max:target.time_to_die", "Default List" ); def->add_action( "touch_of_karma,target_if=max:target.time_to_die" ); - def->add_action( "roll,if=movement.distance>5", "Move to target" ); - def->add_action( "chi_torpedo,if=movement.distance>5" ); - def->add_action( "flying_serpent_kick,if=movement.distance>5" ); - def->add_action( "spear_hand_strike,if=target.debuff.casting.react" ); def->add_action( "potion,if=buff.invoke_xuen_the_white_tiger.remains>15|fight_remains<=30" ); def->add_action( "potion,if=talent.flurry_strikes&chi>2&(time<5|cooldown.zenith.up&time<5|time>300&((trinket.1.is.algethar_puzzle_box&trinket.1.cooldown.remains>100|trinket.2.is.algethar_puzzle_box&trinket.2.cooldown.remains>100)|!trinket.1.has_use_buff&!trinket.2.has_use_buff)&talent.flurry_strikes|time>300&buff.zenith.up)" ); def->add_action( "variable,name=has_external_pi,value=cooldown.invoke_power_infusion_0.duration>0", "Enable PI if available" ); diff --git a/engine/class_modules/monk/sc_monk.cpp b/engine/class_modules/monk/sc_monk.cpp index 7087ce112ae..2660eee363f 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; @@ -2818,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; @@ -3158,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 @@ -3956,10 +3858,15 @@ struct zenith_stomp_t : monk_spell_t trigger_gcd = 0_ms; } - aoe = -1; - reduced_aoe_targets = player->talent.monk.zenith_stomp->effectN( 1 ).base_value(); - may_combo_strike = false; + aoe = -1; + // 2026-07-11 Zenith Stomp is erroneously referencing effect 1 for sqrt scaling + // in tooltip, which instead is used to set up the Zenith Stomp buff that controls + // whether or not the action is available. + // reduced_aoe_targets = player->talent.monk.zenith_stomp->effectN( 1 ).base_value(); + reduced_aoe_targets = 5.0; + may_combo_strike = player->wowv_ge( { 12, 1, 0 } ); ww_mastery = true; + cast_during_sck = true; } void init() override @@ -3970,6 +3877,15 @@ struct zenith_stomp_t : monk_spell_t zenith->add_child( this ); } + bool usable_during_current_cast() const override + { + if ( p()->channeling && + p()->channeling->id == p()->talent.conduit_of_the_celestials.celestial_conduit_action->id() ) + return true; + + return monk_spell_t::usable_during_current_cast(); + } + bool ready() override { if ( source == ZENITH_STOMP_TRIGGER ) @@ -3985,7 +3901,8 @@ struct zenith_stomp_t : monk_spell_t { monk_spell_t::execute(); - p()->buff.zenith_stomp->decrement(); + if ( source == ZENITH_STOMP_CAST ) + p()->buff.zenith_stomp->decrement(); } }; @@ -4031,26 +3948,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 @@ -5382,28 +5279,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 ); @@ -5436,6 +5319,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" ) @@ -6463,11 +6348,8 @@ void monk_t::create_buffs() buff.zenith = make_buff_fallback( talent.windwalker.zenith->ok(), this, "zenith" ); - buff.zenith_stomp = - make_buff_fallback( talent.monk.zenith_stomp->ok(), this, "zenith_stomp", talent.monk.zenith_stomp_buff ) - ->modify_initial_stack( as( talent.windwalker.tigereye_brew_3->ok() - ? talent.windwalker.tigereye_brew_3->effectN( 1 ).base_value() - : 0 ) ); + buff.zenith_stomp = make_buff_fallback( talent.windwalker.tigereye_brew_3->ok(), this, "zenith_stomp", + talent.monk.zenith_stomp_buff ); buff.rushing_wind_kick = make_buff_fallback( talent.windwalker.rushing_wind_kick->ok(), this, "rushing_wind_kick", talent.windwalker.rushing_wind_kick_buff ); @@ -7407,6 +7289,10 @@ class monk_report_t : public player_report_extension_t ReportIssue( "Chi Burst consumes both stacks of the buff on use", "2024-08-09", true ); ReportIssue( "Press the Advantage Tiger Palm does not trigger Overwhelming Force", "2026-02-09", true ); ReportIssue( "Dragonfire Brew causes Breath of Fire damage to scale with Stagger level", "2026-04-14", true ); + ReportIssue( + "Zenith Stomp erroneously references effect 1 for sqrt scaling in tooltip, which is instead used to modify the " + "Zenith Stomp charge buff.", + "2026-07-11", true ); os << "
\n"; os << "

Known Bugs and Issues

\n"; 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();