Skip to content

Commit 52c7e11

Browse files
committed
[Hunter] Aspect of the Hydra
1 parent 293e95c commit 52c7e11

File tree

1 file changed

+90
-13
lines changed

1 file changed

+90
-13
lines changed

engine/class_modules/sc_hunter.cpp

+90-13
Original file line numberDiff line numberDiff line change
@@ -623,14 +623,17 @@ struct hunter_t final : public player_t
623623

624624
spell_data_ptr_t streamline;
625625
spell_data_ptr_t streamline_buff;
626+
spell_data_ptr_t trick_shots;
627+
spell_data_ptr_t trick_shots_data;
628+
spell_data_ptr_t trick_shots_buff;
629+
spell_data_ptr_t aspect_of_the_hydra;
630+
626631
spell_data_ptr_t surging_shots;
627632
spell_data_ptr_t improved_steady_shot;
628633
spell_data_ptr_t pin_cushion;
629634
spell_data_ptr_t crack_shot;
630635

631636
spell_data_ptr_t penetrating_shots;
632-
spell_data_ptr_t trick_shots;
633-
spell_data_ptr_t trick_shots_data;
634637
spell_data_ptr_t master_marksman;
635638
spell_data_ptr_t master_marksman_bleed;
636639

@@ -3823,7 +3826,7 @@ struct wind_arrow_t final : public hunter_ranged_attack_t
38233826

38243827
// Rapid Fire/Rapid Fire Barrage (Marksmanship Talent) ========================================================
38253828

3826-
struct rapid_fire_tick_t final : public hunter_ranged_attack_t
3829+
struct rapid_fire_tick_t : public hunter_ranged_attack_t
38273830
{
38283831
const int trick_shots_targets;
38293832

@@ -4005,12 +4008,41 @@ struct arcane_shot_base_t: public hunter_ranged_attack_t
40054008

40064009
struct arcane_shot_t : public arcane_shot_base_t
40074010
{
4011+
struct arcane_shot_aspect_of_the_hydra_t : arcane_shot_base_t
4012+
{
4013+
arcane_shot_aspect_of_the_hydra_t( util::string_view n, hunter_t* p ) : arcane_shot_base_t( n, p )
4014+
{
4015+
background = dual = true;
4016+
base_costs[ RESOURCE_FOCUS ] = 0;
4017+
base_multiplier *= p->talents.aspect_of_the_hydra->effectN( 1 ).percent();
4018+
}
4019+
};
4020+
4021+
arcane_shot_aspect_of_the_hydra_t* aspect_of_the_hydra = nullptr;
4022+
40084023
arcane_shot_t( hunter_t* p, util::string_view options_str ) : arcane_shot_base_t( "arcane_shot", p )
40094024
{
40104025
parse_options( options_str );
40114026

4012-
if ( p->specialization() == HUNTER_MARKSMANSHIP && p->talents.chimaera_shot.ok() )
4013-
background = true;
4027+
if ( p->talents.aspect_of_the_hydra.ok() )
4028+
aspect_of_the_hydra = p->get_background_action<arcane_shot_aspect_of_the_hydra_t>( "arcane_shot_aspect_of_the_hydra" );
4029+
}
4030+
4031+
void execute() override
4032+
{
4033+
arcane_shot_base_t::execute();
4034+
4035+
// TODO 15/1/25: secondary cast is using primary target if no secondary target is near
4036+
// note (not modeled): there is some kind of dead zone where a secondary target is too far to get hit by the
4037+
// secondary cast but close enough to cause the primary cast target to not be used as the secondary cast target
4038+
if ( aspect_of_the_hydra )
4039+
{
4040+
auto tl = target_list();
4041+
if ( target_list().size() > 1 )
4042+
aspect_of_the_hydra->execute_on_target( tl[1] );
4043+
else
4044+
aspect_of_the_hydra->execute_on_target( target );
4045+
}
40144046
}
40154047
};
40164048

@@ -5354,16 +5386,48 @@ struct aimed_shot_base_t : public hunter_ranged_attack_t
53545386

53555387
struct aimed_shot_t : public aimed_shot_base_t
53565388
{
5389+
struct aimed_shot_aspect_of_the_hydra_t : aimed_shot_base_t
5390+
{
5391+
aimed_shot_aspect_of_the_hydra_t( util::string_view n, hunter_t* p ) : aimed_shot_base_t( n, p, p->talents.aimed_shot )
5392+
{
5393+
background = dual = true;
5394+
base_costs[ RESOURCE_FOCUS ] = 0;
5395+
base_multiplier *= p->talents.aspect_of_the_hydra->effectN( 1 ).percent();
5396+
}
5397+
};
5398+
5399+
aimed_shot_aspect_of_the_hydra_t* aspect_of_the_hydra = nullptr;
5400+
53575401
aimed_shot_t( hunter_t* p, util::string_view options_str ) :
53585402
aimed_shot_base_t( "aimed_shot", p, p->talents.aimed_shot )
53595403
{
53605404
parse_options( options_str );
5405+
5406+
if ( p->talents.aspect_of_the_hydra.ok() )
5407+
aspect_of_the_hydra = p->get_background_action<aimed_shot_aspect_of_the_hydra_t>( "aimed_shot_aspect_of_the_hydra" );
53615408
}
53625409

53635410
bool ready() override
53645411
{
53655412
return !p()->buffs.wailing_arrow_override->check() && aimed_shot_base_t::ready();
53665413
}
5414+
5415+
void execute() override
5416+
{
5417+
hunter_ranged_attack_t::execute();
5418+
5419+
// TODO 15/1/25: secondary cast is using primary target if no secondary target is near
5420+
// note (not modeled): there is some kind of dead zone where a secondary target is too far to get hit by the
5421+
// secondary cast but close enough to cause the primary cast target to not be used as the secondary cast target
5422+
if ( aspect_of_the_hydra )
5423+
{
5424+
auto tl = target_list();
5425+
if ( target_list().size() > 1 )
5426+
aspect_of_the_hydra->execute_on_target( tl[1] );
5427+
else
5428+
aspect_of_the_hydra->execute_on_target( target );
5429+
}
5430+
}
53675431
};
53685432

53695433
// Wailing Arrow =====================================================================
@@ -5489,7 +5553,16 @@ struct steady_shot_t: public hunter_ranged_attack_t
54895553

54905554
struct rapid_fire_t: public hunter_spell_t
54915555
{
5556+
struct rapid_fire_tick_aspect_of_the_hydra : rapid_fire_tick_t
5557+
{
5558+
rapid_fire_tick_aspect_of_the_hydra( util::string_view n, hunter_t* p ) : rapid_fire_tick_t( n, p )
5559+
{
5560+
base_multiplier *= p->talents.aspect_of_the_hydra->effectN( 1 ).percent();
5561+
}
5562+
};
5563+
54925564
rapid_fire_tick_t* damage;
5565+
rapid_fire_tick_aspect_of_the_hydra* aspect_of_the_hydra;
54935566
int base_num_ticks;
54945567

54955568
struct {
@@ -5518,7 +5591,7 @@ struct rapid_fire_t: public hunter_spell_t
55185591
{
55195592
hunter_spell_t::init();
55205593

5521-
damage -> gain = gain;
5594+
damage -> gain = gain;
55225595
damage -> stats = stats;
55235596
stats -> action_list.push_back( damage );
55245597
}
@@ -5537,8 +5610,10 @@ struct rapid_fire_t: public hunter_spell_t
55375610
{
55385611
hunter_spell_t::tick( d );
55395612

5540-
damage -> parent_dot = d; // BfA Surging Shots shenanigans
5541-
damage -> execute_on_target( d -> target );
5613+
damage -> execute_on_target( d->target );
5614+
// TODO 15/1/25: secondary cast is using primary target in all situations
5615+
if ( aspect_of_the_hydra )
5616+
aspect_of_the_hydra->execute_on_target( d->target );
55425617

55435618
if ( p() -> talents.bulletstorm -> ok() && d -> current_tick == 1 && damage -> execute_state && damage -> execute_state -> chain_target > 0 )
55445619
p() -> buffs.bulletstorm -> increment( damage -> execute_state -> chain_target );
@@ -7679,16 +7754,19 @@ void hunter_t::init_spells()
76797754
talents.precise_shots = find_talent_spell( talent_tree::SPECIALIZATION, "Precise Shots", HUNTER_MARKSMANSHIP );
76807755
talents.precise_shots_buff = talents.precise_shots.ok() ? find_spell( 260242 ) : spell_data_t::not_found();
76817756

7682-
talents.surging_shots = find_talent_spell( talent_tree::SPECIALIZATION, "Surging Shots", HUNTER_MARKSMANSHIP );
76837757
talents.streamline = find_talent_spell( talent_tree::SPECIALIZATION, "Streamline", HUNTER_MARKSMANSHIP );
76847758
talents.streamline_buff = talents.streamline.ok() ? find_spell( 342076 ) : spell_data_t::not_found();
7759+
talents.trick_shots = find_talent_spell( talent_tree::SPECIALIZATION, "Trick Shots", HUNTER_MARKSMANSHIP );
7760+
talents.trick_shots_data = find_spell( 257621 );
7761+
talents.trick_shots_buff = find_spell( 257622 );
7762+
talents.aspect_of_the_hydra = find_talent_spell( talent_tree::SPECIALIZATION, "Aspect of the Hydra", HUNTER_MARKSMANSHIP );
7763+
7764+
talents.surging_shots = find_talent_spell( talent_tree::SPECIALIZATION, "Surging Shots", HUNTER_MARKSMANSHIP );
76857765
talents.improved_steady_shot = find_talent_spell( talent_tree::SPECIALIZATION, "Improved Steady Shot", HUNTER_MARKSMANSHIP );
76867766
talents.pin_cushion = find_talent_spell( talent_tree::SPECIALIZATION, "Pin Cushion", HUNTER_MARKSMANSHIP );
76877767
talents.crack_shot = find_talent_spell( talent_tree::SPECIALIZATION, "Crack Shot", HUNTER_MARKSMANSHIP );
76887768

76897769
talents.penetrating_shots = find_talent_spell( talent_tree::SPECIALIZATION, "Penetrating Shots", HUNTER_MARKSMANSHIP );
7690-
talents.trick_shots = find_talent_spell( talent_tree::SPECIALIZATION, "Trick Shots", HUNTER_MARKSMANSHIP );
7691-
talents.trick_shots_data = find_spell( 257621 );
76927770
talents.master_marksman = find_talent_spell( talent_tree::SPECIALIZATION, "Master Marksman", HUNTER_MARKSMANSHIP );
76937771
talents.master_marksman_bleed = talents.master_marksman.ok() ? find_spell( 269576 ) : spell_data_t::not_found();
76947772

@@ -8106,8 +8184,7 @@ void hunter_t::create_buffs()
81068184
-> set_period( 0_ms ) // disable ticks as an optimization
81078185
-> set_refresh_behavior( buff_refresh_behavior::DURATION );
81088186

8109-
buffs.trick_shots =
8110-
make_buff<buffs::trick_shots_t>( this, "trick_shots", find_spell( 257622 ) );
8187+
buffs.trick_shots = make_buff<buffs::trick_shots_t>( this, "trick_shots", talents.trick_shots_buff );
81118188

81128189
buffs.steady_focus =
81138190
make_buff( this, "steady_focus", find_spell( 193534 ) )

0 commit comments

Comments
 (0)