diff --git a/engine/class_modules/sc_demon_hunter.cpp b/engine/class_modules/sc_demon_hunter.cpp
index 9eede248198..851e261f138 100644
--- a/engine/class_modules/sc_demon_hunter.cpp
+++ b/engine/class_modules/sc_demon_hunter.cpp
@@ -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
@@ -3171,7 +3172,7 @@ struct student_of_suffering_trigger_t : public BASE
using base_t = student_of_suffering_trigger_t;
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 )
{
}
@@ -4868,6 +4869,13 @@ struct metamorphosis_t : public mass_acceleration_trigger_tbuff.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();
@@ -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;
@@ -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 ) )
{
@@ -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;
@@ -5942,7 +5953,8 @@ struct reap_t : public reap_base_t
}
};
-struct void_ray_t : public student_of_suffering_trigger_t>>
+struct void_ray_t
+ : public student_of_suffering_trigger_t>>
{
struct void_ray_tick_t : public demon_hunter_spell_t
{
@@ -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;
+ }
}
}
@@ -8642,6 +8659,11 @@ struct metamorphosis_buff_t : public demon_hunter_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() )
+ {
+ p()->trigger_demonsurge( demonsurge_ability::ENTER_META, false );
+ }
}
const timespan_t extend_duration = p()->talent.havoc.demonic->effectN( 1 ).time_value();
@@ -8693,19 +8715,9 @@ struct metamorphosis_buff_t : public demon_hunter_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();
}
}
@@ -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() )
{
@@ -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 )
@@ -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 )
{
@@ -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 )