@@ -623,14 +623,17 @@ struct hunter_t final : public player_t
623
623
624
624
spell_data_ptr_t streamline;
625
625
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
+
626
631
spell_data_ptr_t surging_shots;
627
632
spell_data_ptr_t improved_steady_shot;
628
633
spell_data_ptr_t pin_cushion;
629
634
spell_data_ptr_t crack_shot;
630
635
631
636
spell_data_ptr_t penetrating_shots;
632
- spell_data_ptr_t trick_shots;
633
- spell_data_ptr_t trick_shots_data;
634
637
spell_data_ptr_t master_marksman;
635
638
spell_data_ptr_t master_marksman_bleed;
636
639
@@ -3823,7 +3826,7 @@ struct wind_arrow_t final : public hunter_ranged_attack_t
3823
3826
3824
3827
// Rapid Fire/Rapid Fire Barrage (Marksmanship Talent) ========================================================
3825
3828
3826
- struct rapid_fire_tick_t final : public hunter_ranged_attack_t
3829
+ struct rapid_fire_tick_t : public hunter_ranged_attack_t
3827
3830
{
3828
3831
const int trick_shots_targets;
3829
3832
@@ -4005,12 +4008,41 @@ struct arcane_shot_base_t: public hunter_ranged_attack_t
4005
4008
4006
4009
struct arcane_shot_t : public arcane_shot_base_t
4007
4010
{
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
+
4008
4023
arcane_shot_t ( hunter_t * p, util::string_view options_str ) : arcane_shot_base_t ( " arcane_shot" , p )
4009
4024
{
4010
4025
parse_options ( options_str );
4011
4026
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
+ }
4014
4046
}
4015
4047
};
4016
4048
@@ -5354,16 +5386,48 @@ struct aimed_shot_base_t : public hunter_ranged_attack_t
5354
5386
5355
5387
struct aimed_shot_t : public aimed_shot_base_t
5356
5388
{
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
+
5357
5401
aimed_shot_t ( hunter_t * p, util::string_view options_str ) :
5358
5402
aimed_shot_base_t ( " aimed_shot" , p, p->talents.aimed_shot )
5359
5403
{
5360
5404
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" );
5361
5408
}
5362
5409
5363
5410
bool ready () override
5364
5411
{
5365
5412
return !p ()->buffs .wailing_arrow_override ->check () && aimed_shot_base_t::ready ();
5366
5413
}
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
+ }
5367
5431
};
5368
5432
5369
5433
// Wailing Arrow =====================================================================
@@ -5489,7 +5553,16 @@ struct steady_shot_t: public hunter_ranged_attack_t
5489
5553
5490
5554
struct rapid_fire_t : public hunter_spell_t
5491
5555
{
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
+
5492
5564
rapid_fire_tick_t * damage;
5565
+ rapid_fire_tick_aspect_of_the_hydra* aspect_of_the_hydra;
5493
5566
int base_num_ticks;
5494
5567
5495
5568
struct {
@@ -5518,7 +5591,7 @@ struct rapid_fire_t: public hunter_spell_t
5518
5591
{
5519
5592
hunter_spell_t::init ();
5520
5593
5521
- damage -> gain = gain;
5594
+ damage -> gain = gain;
5522
5595
damage -> stats = stats;
5523
5596
stats -> action_list.push_back ( damage );
5524
5597
}
@@ -5537,8 +5610,10 @@ struct rapid_fire_t: public hunter_spell_t
5537
5610
{
5538
5611
hunter_spell_t::tick ( d );
5539
5612
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 );
5542
5617
5543
5618
if ( p () -> talents.bulletstorm -> ok () && d -> current_tick == 1 && damage -> execute_state && damage -> execute_state -> chain_target > 0 )
5544
5619
p () -> buffs.bulletstorm -> increment ( damage -> execute_state -> chain_target );
@@ -7679,16 +7754,19 @@ void hunter_t::init_spells()
7679
7754
talents.precise_shots = find_talent_spell ( talent_tree::SPECIALIZATION, " Precise Shots" , HUNTER_MARKSMANSHIP );
7680
7755
talents.precise_shots_buff = talents.precise_shots .ok () ? find_spell ( 260242 ) : spell_data_t::not_found ();
7681
7756
7682
- talents.surging_shots = find_talent_spell ( talent_tree::SPECIALIZATION, " Surging Shots" , HUNTER_MARKSMANSHIP );
7683
7757
talents.streamline = find_talent_spell ( talent_tree::SPECIALIZATION, " Streamline" , HUNTER_MARKSMANSHIP );
7684
7758
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 );
7685
7765
talents.improved_steady_shot = find_talent_spell ( talent_tree::SPECIALIZATION, " Improved Steady Shot" , HUNTER_MARKSMANSHIP );
7686
7766
talents.pin_cushion = find_talent_spell ( talent_tree::SPECIALIZATION, " Pin Cushion" , HUNTER_MARKSMANSHIP );
7687
7767
talents.crack_shot = find_talent_spell ( talent_tree::SPECIALIZATION, " Crack Shot" , HUNTER_MARKSMANSHIP );
7688
7768
7689
7769
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 );
7692
7770
talents.master_marksman = find_talent_spell ( talent_tree::SPECIALIZATION, " Master Marksman" , HUNTER_MARKSMANSHIP );
7693
7771
talents.master_marksman_bleed = talents.master_marksman .ok () ? find_spell ( 269576 ) : spell_data_t::not_found ();
7694
7772
@@ -8106,8 +8184,7 @@ void hunter_t::create_buffs()
8106
8184
-> set_period ( 0_ms ) // disable ticks as an optimization
8107
8185
-> set_refresh_behavior ( buff_refresh_behavior::DURATION );
8108
8186
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 );
8111
8188
8112
8189
buffs.steady_focus =
8113
8190
make_buff ( this , " steady_focus" , find_spell ( 193534 ) )
0 commit comments