From fab23e02c469dae8e0da7f27592113989ed87a3a Mon Sep 17 00:00:00 2001 From: Lucasmingus Date: Thu, 10 Sep 2026 12:07:46 +0200 Subject: [PATCH 1/2] tidal insight sim bug --- engine/player/unique_gear_midnight.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/engine/player/unique_gear_midnight.cpp b/engine/player/unique_gear_midnight.cpp index 7b92d799978..343c7be20e3 100644 --- a/engine/player/unique_gear_midnight.cpp +++ b/engine/player/unique_gear_midnight.cpp @@ -3535,8 +3535,10 @@ void wavecallers_seastone( special_effect_t& effect ) if ( new_ == b->max_stack() ) make_event( *effect.player->sim, 0_ms, [ b ] { b->set_reverse( true ); } ); } ) - ->set_expire_callback( [ effect ]( buff_t* b, int, timespan_t ) { - make_event( *effect.player->sim, 0_ms, [ b ] { b->set_reverse( false ); } ); + ->set_expire_callback( []( buff_t* b, int, timespan_t ) { + // must be immediate; combat_end() expires buffs after the event manager stops, so a + // delayed reset would never run and reverse would leak into the next iteration + b->set_reverse( false ); } ); new dbc_proc_callback_t( effect.player, effect ); From cf4e2e69f06cbd164e7460eaf89ebd5be2ccf98d Mon Sep 17 00:00:00 2001 From: Lucasmingus Date: Thu, 10 Sep 2026 13:21:21 +0200 Subject: [PATCH 2/2] convert to custom struct with reset override --- engine/player/unique_gear_midnight.cpp | 35 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/engine/player/unique_gear_midnight.cpp b/engine/player/unique_gear_midnight.cpp index 343c7be20e3..047dfeb2d07 100644 --- a/engine/player/unique_gear_midnight.cpp +++ b/engine/player/unique_gear_midnight.cpp @@ -3529,17 +3529,30 @@ void sporelords_mycelium( special_effect_t& effect ) // 1295057 Tidal Insight Buff void wavecallers_seastone( special_effect_t& effect ) { - effect.custom_buff = create_buff( effect.player, effect.player->find_spell( 1295057 ) ) - ->set_stat_from_effect_type( A_MOD_STAT, effect.driver()->effectN( 1 ).average( effect ) ) - ->set_stack_change_callback( [ effect ]( buff_t* b, int, int new_ ) { - if ( new_ == b->max_stack() ) - make_event( *effect.player->sim, 0_ms, [ b ] { b->set_reverse( true ); } ); - } ) - ->set_expire_callback( []( buff_t* b, int, timespan_t ) { - // must be immediate; combat_end() expires buffs after the event manager stops, so a - // delayed reset would never run and reverse would leak into the next iteration - b->set_reverse( false ); - } ); + struct tidal_insight_buff_t : public stat_buff_t + { + tidal_insight_buff_t( player_t* p, std::string_view n, const spell_data_t* s ) : stat_buff_t( p, n, s ) + { + set_stack_change_callback( []( buff_t* b, int, int new_ ) { + if ( new_ == b->max_stack() ) + make_event( *b->sim, 0_ms, [ b ] { b->set_reverse( true ); } ); + } ); + + set_expire_callback( []( buff_t* b, int, timespan_t ) { + make_event( *b->sim, 0_ms, [ b ] { b->set_reverse( false ); } ); + } ); + } + + void reset() override + { + stat_buff_t::reset(); + set_reverse( false ); + } + }; + + effect.custom_buff = + create_buff( effect.player, "tidal_insight", effect.player->find_spell( 1295057 ) ) + ->set_stat_from_effect_type( A_MOD_STAT, effect.driver()->effectN( 1 ).average( effect ) ); new dbc_proc_callback_t( effect.player, effect ); }