diff --git a/engine/class_modules/warlock/sc_warlock.cpp b/engine/class_modules/warlock/sc_warlock.cpp index 43e271c4a1a..4a35b4bc59d 100644 --- a/engine/class_modules/warlock/sc_warlock.cpp +++ b/engine/class_modules/warlock/sc_warlock.cpp @@ -104,6 +104,14 @@ warlock_td_t::warlock_td_t( player_t* target, warlock_t& p ) // Hellcaller dots_wither = target->get_dot( "wither", &p ); + debuffs_blackened_soul = make_buff( *this, "blackened_soul", p.hero.blackened_soul_trigger ) + ->set_duration( 0_ms ) + ->set_tick_zero( false ) + ->set_period( p.hero.blackened_soul_trigger->effectN( 1 ).period() ) + ->set_tick_time_behavior( buff_tick_time_behavior::UNHASTED ) + ->set_tick_callback( [ this, target ]( buff_t*, int, timespan_t ) + { warlock.proc_actions.blackened_soul->execute_on_target( target ); } ); + target->register_on_demise_callback( &p, [ this ]( player_t* ) { target_demise(); } ); } diff --git a/engine/class_modules/warlock/sc_warlock.hpp b/engine/class_modules/warlock/sc_warlock.hpp index 2083dfe9f69..1aae49c15d0 100644 --- a/engine/class_modules/warlock/sc_warlock.hpp +++ b/engine/class_modules/warlock/sc_warlock.hpp @@ -71,6 +71,8 @@ struct warlock_td_t : public actor_target_data_t // Hellcaller propagate_const dots_wither; + propagate_const debuffs_blackened_soul; // Dummy/Hidden debuff that triggers stack collapse + double soc_threshold; // Aff - Seed of Corruption counts damage from cross-spec spells such as Drain Life warlock_t& warlock; @@ -511,6 +513,8 @@ struct warlock_t : public player_t player_talent_t xalans_ferocity; // TODO: This has similar issues to Flames of Xoroth. Is/should this be affecting pets? player_talent_t blackened_soul; + const spell_data_t* blackened_soul_trigger; // Contains interval for stack collapse + const spell_data_t* blackened_soul_dmg; player_talent_t xalans_cruelty; player_talent_t hatefury_rituals; @@ -545,6 +549,7 @@ struct warlock_t : public player_t action_t* bilescourge_bombers_proc; // From Shadow Invocation talent action_t* doom_proc; action_t* rain_of_fire_tick; + action_t* blackened_soul; } proc_actions; struct tier_sets_t @@ -690,6 +695,11 @@ struct warlock_t : public player_t proc_t* conflagration_of_chaos_sb; proc_t* decimation; proc_t* dimension_ripper; + + // Diabolist + + // Hellcaller + proc_t* blackened_soul; } procs; int initial_soul_shards; @@ -721,6 +731,8 @@ struct warlock_t : public player_t void create_affliction_proc_actions(); void create_demonology_proc_actions(); void create_destruction_proc_actions(); + void create_diabolist_proc_actions(); + void create_hellcaller_proc_actions(); action_t* create_action( util::string_view name, util::string_view options ) override; pet_t* create_pet( util::string_view name, util::string_view type = {} ) override; void create_pets() override; @@ -827,5 +839,7 @@ namespace helpers bool crescendo_check( warlock_t* p ); void nightfall_updater( warlock_t* p, dot_t* d ); + + void trigger_blackened_soul( warlock_t* p ); } } // namespace warlock diff --git a/engine/class_modules/warlock/sc_warlock_actions.cpp b/engine/class_modules/warlock/sc_warlock_actions.cpp index 20fcd4c6fae..bfba0300ac6 100644 --- a/engine/class_modules/warlock/sc_warlock_actions.cpp +++ b/engine/class_modules/warlock/sc_warlock_actions.cpp @@ -223,6 +223,11 @@ using namespace helpers; break; } } + + if ( hellcaller() && base_shards > 0 && harmful && p()->hero.blackened_soul.ok() ) + { + helpers::trigger_blackened_soul( p() ); + } } } @@ -1118,6 +1123,7 @@ using namespace helpers; : warlock_spell_t( "Wither", p, p->hero.wither_dot ) { background = dual = true; + dot_ignore_stack = true; affected_by.chaotic_energies = destruction(); @@ -1203,6 +1209,28 @@ using namespace helpers; { return impact_action->get_dot( t ); } }; + struct blackened_soul_t : public warlock_spell_t + { + blackened_soul_t( warlock_t* p ) + : warlock_spell_t( "Blackened Soul", p, p->hero.blackened_soul_dmg ) + { + background = dual = true; + + affected_by.chaotic_energies = destruction(); + } + + void impact( action_state_t* s ) override + { + warlock_spell_t::impact( s ); + + if ( td( s->target )->dots_wither->current_stack() > 1 ) + td( s->target )->dots_wither->decrement( 1 ); + + if ( td( s->target )->dots_wither->current_stack() <= 1 ) + make_event( *sim, 0_ms, [ this, s ] { td( s->target )->debuffs_blackened_soul->expire(); } ); + } + }; + // Hellcaller Actions End // Affliction Actions Begin @@ -3985,6 +4013,28 @@ using namespace helpers; } } + void helpers::trigger_blackened_soul( warlock_t* p ) + { + for ( const auto target : p->sim->target_non_sleeping_list ) + { + warlock_td_t* tdata = p->get_target_data( target ); + if ( !tdata ) + continue; + + if ( !tdata->dots_wither->is_ticking() ) + continue; + + tdata->dots_wither->increment( 1 ); + + // TOCHECK: Chance for this effect is not in spell data! + if ( p->rng().roll( 0.1 ) ) + { + tdata->debuffs_blackened_soul->trigger(); + p->procs.blackened_soul->occur(); + } + } + } + // Event for spawning Wild Imps for Demonology imp_delay_event_t::imp_delay_event_t( warlock_t* p, double delay, double exp ) : player_event_t( *p, timespan_t::from_millis( delay ) ) { diff = timespan_t::from_millis( exp - delay ); } @@ -4208,6 +4258,10 @@ using namespace helpers; if ( specialization() == WARLOCK_DESTRUCTION ) create_destruction_proc_actions(); + create_diabolist_proc_actions(); + + create_hellcaller_proc_actions(); + player_t::create_actions(); } @@ -4223,6 +4277,14 @@ using namespace helpers; void warlock_t::create_destruction_proc_actions() { } + void warlock_t::create_diabolist_proc_actions() + { } + + void warlock_t::create_hellcaller_proc_actions() + { + proc_actions.blackened_soul = new blackened_soul_t( this ); + } + void warlock_t::init_special_effects() { player_t::init_special_effects(); diff --git a/engine/class_modules/warlock/sc_warlock_init.cpp b/engine/class_modules/warlock/sc_warlock_init.cpp index bf6d3bd2310..5b18caac7fd 100644 --- a/engine/class_modules/warlock/sc_warlock_init.cpp +++ b/engine/class_modules/warlock/sc_warlock_init.cpp @@ -531,6 +531,10 @@ namespace warlock hero.wither_dot = find_spell( 445474 ); hero.xalans_ferocity = find_talent_spell( talent_tree::HERO, "Xalan's Ferocity" ); // Should be ID 440044 + + hero.blackened_soul = find_talent_spell( talent_tree::HERO, "Blackened Soul" ); // Should be ID 440043 + hero.blackened_soul_trigger = find_spell( 445731 ); + hero.blackened_soul_dmg = find_spell( 445736 ); } void warlock_t::init_base_stats() @@ -916,6 +920,7 @@ namespace warlock void warlock_t::init_procs_hellcaller() { + procs.blackened_soul = get_proc( "blackened_soul" ); } void warlock_t::init_rng()