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
65 changes: 45 additions & 20 deletions engine/class_modules/sc_demon_hunter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ class demon_hunter_t : public parse_player_effects_t
const spell_data_t* pierce_the_veil;
const spell_data_t* reapers_toll;
const spell_data_t* volatile_instinct;
const spell_data_t* demonsurge_meta_trigger;
} hero_spec;

// Set Bonus effects
Expand Down Expand Up @@ -3171,7 +3172,7 @@ struct student_of_suffering_trigger_t : public BASE
using base_t = student_of_suffering_trigger_t<BASE>;

student_of_suffering_trigger_t( util::string_view n, demon_hunter_t* p, const spell_data_t* s = spell_data_t::nil(),
util::string_view o = {} )
util::string_view o = {} )
: BASE( n, p, s, o )
{
}
Expand Down Expand Up @@ -4868,6 +4869,13 @@ struct metamorphosis_t : public mass_acceleration_trigger_t<demon_hunter_spell_t
p()->buff.metamorphosis_move->distance_moved = landing_distance;
p()->buff.metamorphosis_move->trigger();
}

if ( p()->talent.scarred.volatile_instinct->ok() )
{
p()->trigger_demonsurge(
demonsurge_ability::ENTER_META,
timespan_t::from_millis( p()->hero_spec.demonsurge_meta_trigger->effectN( 1 ).misc_value1() ), false );
}
break;
case DEMON_HUNTER_VENGEANCE:
p()->buff.metamorphosis->trigger();
Expand Down Expand Up @@ -4920,7 +4928,7 @@ struct pick_up_fragment_t : public demon_hunter_spell_t
// Evaluate if_expr to make sure the actor still wants to consume.
if ( frag && frag->active() && ( !expr || expr->eval() ) && dh->active.consume_soul_greater )
{
frag->consume( true );
frag->consume();
}

dh->soul_fragment_pick_up = nullptr;
Expand Down Expand Up @@ -5008,7 +5016,7 @@ struct pick_up_fragment_t : public demon_hunter_spell_t
// Havoc Lesser and Greater souls: 8 yards
// Havoc Greater Demon soul: 10 yards
// TODO: 11.2 Empowered soul for both specs: 6 yards
// TOCHECK: Devourer souls (currently default to previous 6 yard)
// Devourer has a 4 yard pickup range
double dtm;
if ( frag->is_type( soul_fragment::EMPOWERED_DEMON ) )
{
Expand All @@ -5024,6 +5032,9 @@ struct pick_up_fragment_t : public demon_hunter_spell_t
case DEMON_HUNTER_VENGEANCE:
dtm = std::max( 0.0, frag->get_distance( p() ) - 4.0 );
break;
case DEMON_HUNTER_DEVOURER:
dtm = std::max( 0.0, frag->get_distance( p() ) - 4.0 );
break;
default:
dtm = std::max( 0.0, frag->get_distance( p() ) - 6.0 );
break;
Expand Down Expand Up @@ -5942,7 +5953,8 @@ struct reap_t : public reap_base_t
}
};

struct void_ray_t : public student_of_suffering_trigger_t<final_breath_trigger_t<doomsayer_trigger_t<demon_hunter_spell_t>>>
struct void_ray_t
: public student_of_suffering_trigger_t<final_breath_trigger_t<doomsayer_trigger_t<demon_hunter_spell_t>>>
{
struct void_ray_tick_t : public demon_hunter_spell_t
{
Expand Down Expand Up @@ -6804,6 +6816,11 @@ struct blade_dance_base_t
first_blood_attacks.back()->trail_of_ruin_dot = trail_of_ruin_dot;
}
}

if ( first_blood_attacks.front() )
{
first_blood_attacks.front()->first_attack = true;
}
}
}

Expand Down Expand Up @@ -8642,6 +8659,11 @@ struct metamorphosis_buff_t : public demon_hunter_buff_t<buff_t>
p()->buff.demonsurge_abilities[ demonsurge_ability::ANNIHILATION ]->trigger();
p()->buff.demonsurge_abilities[ demonsurge_ability::DEATH_SWEEP ]->trigger();
p()->buff.demonsurge_demonsurge->trigger();

if ( p()->talent.scarred.volatile_instinct->ok() )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to go in extend_duration_or_trigger instead

{
p()->trigger_demonsurge( demonsurge_ability::ENTER_META, false );
}
}

const timespan_t extend_duration = p()->talent.havoc.demonic->effectN( 1 ).time_value();
Expand Down Expand Up @@ -8693,19 +8715,9 @@ struct metamorphosis_buff_t : public demon_hunter_buff_t<buff_t>
p()->buff.enduring_torment->expire();
}

if ( p()->talent.scarred.volatile_instinct->ok() )
if ( p()->talent.scarred.volatile_instinct->ok() && p()->specialization() == DEMON_HUNTER_DEVOURER )
{
switch ( p()->specialization() )
{
case DEMON_HUNTER_DEVOURER:
p()->buff.volatile_instinct->trigger();
break;
case DEMON_HUNTER_HAVOC:
p()->trigger_demonsurge( demonsurge_ability::ENTER_META, false );
break;
default:
break;
}
p()->buff.volatile_instinct->trigger();
}
}

Expand Down Expand Up @@ -10801,6 +10813,8 @@ void demon_hunter_t::init_spells()
hero_spec.reapers_toll = spec_talent_spell_lookup( DEMON_HUNTER_DEVOURER, talent.scarred.demonsurge, 1245470 );
hero_spec.volatile_instinct =
spec_talent_spell_lookup( DEMON_HUNTER_DEVOURER, talent.scarred.volatile_instinct, 1272462 );
hero_spec.demonsurge_meta_trigger =
spec_talent_spell_lookup( DEMON_HUNTER_HAVOC, talent.scarred.volatile_instinct, 1238696 );

switch ( specialization() )
{
Expand Down Expand Up @@ -11884,7 +11898,7 @@ double demon_hunter_t::fury_state_t::fury_drain_per_second( int stacks ) const
double drain = base_fury_drain_per_second( stacks );

bool has_reduced_drain = !p()->in_combat || p()->buff.voidrush->check() ||
p()->executing && p()->executing->id == p()->talent.devourer.collapsing_star->id() ||
p()->executing && p()->executing->id == p()->spec.collapsing_star_spell->id() ||
p()->channeling && p()->channeling->id == p()->talent.devourer.void_ray->id();

if ( has_reduced_drain )
Expand Down Expand Up @@ -11992,7 +12006,7 @@ void demon_hunter_t::activate_soul_fragment( soul_fragment_t* frag )
{
if ( it->is_type( soul_fragment::LESSER ) && it->active() )
{
it->consume( true );
it->consume();

if ( sim->debug )
{
Expand Down Expand Up @@ -12083,8 +12097,19 @@ void demon_hunter_t::trigger_demonic() const

void demon_hunter_t::trigger_demonsurge( const demonsurge_ability ability, const bool check_buff )
{
trigger_demonsurge( ability, timespan_t::from_millis( hero_spec.demonsurge_trigger->effectN( 1 ).misc_value1() ),
check_buff );
timespan_t delay;

// TOCHECK: Death sweep currently uses a 700 ms delay, while all other abilities use 450 ms delay.
switch ( ability )
{
case demonsurge_ability::DEATH_SWEEP:
delay = timespan_t::from_millis( hero_spec.demonsurge_meta_trigger->effectN( 1 ).misc_value1() );
break;
default:
delay = timespan_t::from_millis( hero_spec.demonsurge_trigger->effectN( 1 ).misc_value1() );
break;
}
trigger_demonsurge( ability, delay, check_buff );
}

void demon_hunter_t::trigger_demonsurge( const demonsurge_ability ability, timespan_t delay, const bool check_buff )
Expand Down