From 8729254a307c059b8962c9059e123f9822b14dea Mon Sep 17 00:00:00 2001 From: Justin Driggers Date: Thu, 15 Jan 2026 16:19:32 -0500 Subject: [PATCH 1/2] [Monk] Fuel on the Fire * TODO: Improve hit chance calculation from real world data --- engine/class_modules/monk/sc_monk.cpp | 47 +++++++++++++++++++++++++++ engine/class_modules/monk/sc_monk.hpp | 3 ++ 2 files changed, 50 insertions(+) diff --git a/engine/class_modules/monk/sc_monk.cpp b/engine/class_modules/monk/sc_monk.cpp index 99dae1bd95b..780538a0a06 100644 --- a/engine/class_modules/monk/sc_monk.cpp +++ b/engine/class_modules/monk/sc_monk.cpp @@ -2166,9 +2166,28 @@ struct keg_smash_t : monk_melee_attack_t } }; + struct fuel_on_the_fire_t : public monk_spell_t + { + fuel_on_the_fire_t( monk_t *player ) + : monk_spell_t( player, "fuel_on_the_fire", player->talent.brewmaster.fuel_on_the_fire_damage ) + { + aoe = -1; + background = dual = true; + } + + void impact( action_state_t *s ) override + { + // A "whirl of flame which spirals outwards" has a pretty high chance to hit, but doesn't always. + // TODO: Improve hit chance calculation from real world data + if ( rng().roll( 0.75 ) ) + monk_spell_t::impact( s ); + } + } + cooldown_t *breath_of_fire; action_t *empty_barrel; action_t *extra_kick; + action_t *fuel_on_the_fire; keg_smash_t( monk_t *player, std::string_view options_str, std::string_view name = "keg_smash" ) : monk_melee_attack_t( player, name, player->talent.brewmaster.keg_smash ), @@ -2211,6 +2230,12 @@ struct keg_smash_t : monk_melee_attack_t extra_kick = new extra_kick_t( player ); add_child( extra_kick ); } + + if ( player->talent.brewmaster.fuel_on_the_fire->ok() ) + { + fuel_on_the_fire = new fuel_on_the_fire_t( player ); + add_child( fuel_on_the_fire ); + } } void execute() override @@ -2249,6 +2274,18 @@ struct keg_smash_t : monk_melee_attack_t if ( extra_kick ) extra_kick->execute(); + + if ( p()->buff.fuel_on_the_fire->up() ) + { + p()->buff.fuel_on_the_fire->decrement(); + + make_event( *sim, p(), ground_aoe_params_t() + .target( target ) + .duration( data().duration() ) + .pulse_time( timespan_t::from_seconds( 1.0 ) ) + .n_pulses( 3 ) + .action( fuel_on_the_fire ), true ); + } } void impact( action_state_t *state ) override @@ -3063,6 +3100,11 @@ struct exploding_keg_t : public monk_spell_t { p()->buff.exploding_keg->trigger(); p()->buff.empty_the_cellar->trigger(); + + if ( p()->talent.brewmaster.fuel_on_the_fire->ok() ) + p()->buff.fuel_on_the_fire->trigger( + as( p()->talent.brewmaster.fuel_on_the_fire->effectN( 1 ).base_value() ) ); + monk_spell_t::execute(); } @@ -5274,6 +5316,8 @@ void monk_t::init_spells() talent.brewmaster.invoke_niuzao_the_black_ox_npc = find_spell( 123904 ); talent.brewmaster.invoke_niuzao_the_black_ox_stomp = find_spell( 227291 ); talent.brewmaster.fuel_on_the_fire = _ST( "Fuel on the Fire" ); + talent.brewmaster.fuel_on_the_fire_buff = find_spell( 1262035 ); + talent.brewmaster.fuel_on_the_fire_damage = find_spell( 1262159 ); talent.brewmaster.empty_the_cellar = _ST( "Empty the Cellar" ); talent.brewmaster.empty_the_cellar_buff = find_spell( 1262768 ); talent.brewmaster.empty_the_cellar_driver = find_spell( 1263438 ); @@ -5794,6 +5838,9 @@ void monk_t::create_buffs() talent.brewmaster.elixir_of_determination->ok(), this, "elixir_of_determination", talent.brewmaster.elixir_of_determination->effectN( 1 ).trigger() ); + buff.fuel_on_the_fire = make_buff_fallback( talent.brewmaster.fuel_on_the_fire->ok(), this, "fuel_on_the_fire", + talent.brewmaster.fuel_on_the_fire_buff ); + buff.invoke_niuzao = make_buff_fallback( talent.brewmaster.invoke_niuzao_the_black_ox->ok(), this, "invoke_niuzao_the_black_ox", talent.brewmaster.invoke_niuzao_the_black_ox ) ->set_default_value_from_effect( 2 ) diff --git a/engine/class_modules/monk/sc_monk.hpp b/engine/class_modules/monk/sc_monk.hpp index 838cd49a4f7..403a877b981 100644 --- a/engine/class_modules/monk/sc_monk.hpp +++ b/engine/class_modules/monk/sc_monk.hpp @@ -503,6 +503,7 @@ struct monk_t : public stagger_t propagate_const empty_the_cellar; propagate_const exploding_keg; propagate_const fortifying_brew; + propagate_const fuel_on_the_fire; propagate_const gift_of_the_ox; propagate_const expel_harm_accumulator; propagate_const invoke_niuzao; @@ -837,6 +838,8 @@ struct monk_t : public stagger_t const spell_data_t *invoke_niuzao_the_black_ox_stomp; // row 10 player_talent_t fuel_on_the_fire; + const spell_data_t *fuel_on_the_fire_buff; + const spell_data_t *fuel_on_the_fire_damage; player_talent_t empty_the_cellar; const spell_data_t *empty_the_cellar_buff; const spell_data_t *empty_the_cellar_driver; From 48e656f6b59ca8c665f8728b2484217625eb77c2 Mon Sep 17 00:00:00 2001 From: Kate Martin <51387586+renanthera@users.noreply.github.com> Date: Mon, 9 Feb 2026 20:00:32 -0700 Subject: [PATCH 2/2] Missing semicolon. --- engine/class_modules/monk/sc_monk.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/engine/class_modules/monk/sc_monk.cpp b/engine/class_modules/monk/sc_monk.cpp index 780538a0a06..81f83f5a4c5 100644 --- a/engine/class_modules/monk/sc_monk.cpp +++ b/engine/class_modules/monk/sc_monk.cpp @@ -2171,7 +2171,7 @@ struct keg_smash_t : monk_melee_attack_t fuel_on_the_fire_t( monk_t *player ) : monk_spell_t( player, "fuel_on_the_fire", player->talent.brewmaster.fuel_on_the_fire_damage ) { - aoe = -1; + aoe = -1; background = dual = true; } @@ -2182,7 +2182,7 @@ struct keg_smash_t : monk_melee_attack_t if ( rng().roll( 0.75 ) ) monk_spell_t::impact( s ); } - } + }; cooldown_t *breath_of_fire; action_t *empty_barrel; @@ -2279,12 +2279,14 @@ struct keg_smash_t : monk_melee_attack_t { p()->buff.fuel_on_the_fire->decrement(); - make_event( *sim, p(), ground_aoe_params_t() - .target( target ) - .duration( data().duration() ) - .pulse_time( timespan_t::from_seconds( 1.0 ) ) - .n_pulses( 3 ) - .action( fuel_on_the_fire ), true ); + make_event( *sim, p(), + ground_aoe_params_t() + .target( target ) + .duration( data().duration() ) + .pulse_time( timespan_t::from_seconds( 1.0 ) ) + .n_pulses( 3 ) + .action( fuel_on_the_fire ), + true ); } }