Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion engine/class_modules/sc_demon_hunter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,10 @@ class demon_hunter_t : public parse_player_effects_t
double wounded_quarry_chance_vengeance = 0.30;
// Proc rate for Wounded Quarry for Havoc
double wounded_quarry_chance_havoc = 0.10;
// Proc rate for Voidfall per current building stack count (from WCL analysis)
double voidfall_proc_chance_0_stacks = 0.40;
double voidfall_proc_chance_1_stacks = 0.32;
double voidfall_proc_chance_2_stacks = 0.275;
// How many seconds that Vengeful Retreat locks out Felblade
double felblade_lockout_from_vengeful_retreat = 0.6;
bool enable_dungeon_slice = false;
Expand Down Expand Up @@ -2935,10 +2939,25 @@ struct voidfall_building_trigger_t : public BASE
{
using base_t = voidfall_building_trigger_t<BASE>;

// Proc chance per current building stack count, cached at construction.
// Vengeance uses per-stack rates from WCL analysis; Devourer uses flat spell data rate.
std::array<double, 3> voidfall_proc_chances;

voidfall_building_trigger_t( util::string_view n, demon_hunter_t* p, const spell_data_t* s = spell_data_t::nil(),
util::string_view o = {} )
: BASE( n, p, s, o )
{
if ( p->specialization() == DEMON_HUNTER_VENGEANCE )
{
voidfall_proc_chances = { p->options.voidfall_proc_chance_0_stacks,
p->options.voidfall_proc_chance_1_stacks,
p->options.voidfall_proc_chance_2_stacks };
}
else
{
double flat = p->talent.annihilator.voidfall->effectN( 3 ).percent();
voidfall_proc_chances = { flat, flat, flat };
}
}

void execute() override
Expand All @@ -2948,7 +2967,9 @@ struct voidfall_building_trigger_t : public BASE
if ( !BASE::p()->talent.annihilator.voidfall->ok() )
return;

if ( !BASE::rng().roll( BASE::p()->talent.annihilator.voidfall->effectN( 3 ).percent() ) )
// clamp to max index; building buff expires at 3 stacks so 2 is the highest we see
int stacks = std::min( BASE::p()->buff.voidfall_building->check(), 2 );
if ( !BASE::rng().roll( voidfall_proc_chances[ stacks ] ) )
return;

// can't gain building while spending is up
Expand Down Expand Up @@ -10113,6 +10134,9 @@ void demon_hunter_t::create_options()
opt_float( "soul_fragment_movement_consume_chance", options.soul_fragment_movement_consume_chance, 0, 1 ) );
add_option( opt_float( "wounded_quarry_chance_vengeance", options.wounded_quarry_chance_vengeance, 0, 1 ) );
add_option( opt_float( "wounded_quarry_chance_havoc", options.wounded_quarry_chance_havoc, 0, 1 ) );
add_option( opt_float( "voidfall_proc_chance_0_stacks", options.voidfall_proc_chance_0_stacks, 0, 1 ) );
add_option( opt_float( "voidfall_proc_chance_1_stacks", options.voidfall_proc_chance_1_stacks, 0, 1 ) );
add_option( opt_float( "voidfall_proc_chance_2_stacks", options.voidfall_proc_chance_2_stacks, 0, 1 ) );
add_option(
opt_float( "felblade_lockout_from_vengeful_retreat", options.felblade_lockout_from_vengeful_retreat, 0, 1 ) );
add_option( opt_bool( "enable_dungeon_slice", options.enable_dungeon_slice ) );
Expand Down
Loading