forked from simulationcraft/simc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsc_hunter.cpp
More file actions
10424 lines (8339 loc) · 357 KB
/
sc_hunter.cpp
File metadata and controls
10424 lines (8339 loc) · 357 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//==========================================================================
// Dedmonwakeen's DPS-DPM Simulator.
// Send questions to natehieter@gmail.com
// ==========================================================================
#include <memory>
#include "simulationcraft.hpp"
#include "player/pet_spawner.hpp"
#include "class_modules/apl/apl_hunter.hpp"
namespace
{ // UNNAMED NAMESPACE
// helper smartpointer-like struct for spell data pointers
struct spell_data_ptr_t
{
spell_data_ptr_t():
data_( spell_data_t::not_found() ) {}
spell_data_ptr_t( const spell_data_t* s ):
data_( s ? s : spell_data_t::not_found() ) {}
spell_data_ptr_t& operator=( const spell_data_t* s )
{
data_ = s ? s : spell_data_t::not_found();
return *this;
}
const spell_data_t* operator->() const { return data_; }
operator const spell_data_t*() const { return data_; }
bool ok() const { return data_ -> ok(); }
const spell_data_t* data_;
};
static void print_affected_by( const action_t* a, const spelleffect_data_t& effect, util::string_view label = {} )
{
fmt::memory_buffer out;
const spell_data_t& spell = *effect.spell();
const auto& spell_text = a->player->dbc->spell_text( spell.id() );
fmt::format_to( std::back_inserter(out), "{} {} is affected by {}", *a->player, *a, spell.name_cstr() );
if ( spell_text.rank() )
fmt::format_to( std::back_inserter(out), " (desc={})", spell_text.rank() );
fmt::format_to( std::back_inserter(out), " (id={}) effect#{}", spell.id(), effect.spell_effect_num() + 1 );
if ( !label.empty() )
fmt::format_to( std::back_inserter(out), ": {}", label );
a -> sim -> print_debug( "{}", util::string_view( out.data(), out.size() ) );
}
static bool check_affected_by( action_t* a, const spelleffect_data_t& effect )
{
bool affected = a->data().affected_by( effect ) || a->data().affected_by_label( effect );
if ( affected && a->sim->debug )
print_affected_by( a, effect );
return affected;
}
struct damage_affected_by {
uint8_t direct = 0;
uint8_t tick = 0;
};
static damage_affected_by parse_damage_affecting_aura( action_t* a, spell_data_ptr_t spell )
{
damage_affected_by affected_by;
for ( const spelleffect_data_t& effect : spell -> effects() )
{
if ( effect.type() != E_APPLY_AURA )
continue;
if ( ( effect.subtype() == A_MOD_DAMAGE_FROM_CASTER_SPELLS && a->data().affected_by( effect ) ) ||
( effect.subtype() == A_MOD_DAMAGE_FROM_CASTER_SPELLS_LABEL && a->data().affected_by_label( effect ) ) )
{
affected_by.direct = as<uint8_t>( effect.spell_effect_num() + 1 );
affected_by.tick = as<uint8_t>( effect.spell_effect_num() + 1 );
print_affected_by( a, effect, "spell damage taken increase" );
return affected_by;
}
if ( ( effect.subtype() == A_ADD_PCT_MODIFIER && a->data().affected_by( effect ) ) ||
( effect.subtype() == A_ADD_PCT_LABEL_MODIFIER && a->data().affected_by_label( effect ) ) )
{
if ( effect.misc_value1() == P_GENERIC )
{
affected_by.direct = as<uint8_t>( effect.spell_effect_num() + 1 );
print_affected_by( a, effect, "direct damage increase" );
}
else if ( effect.misc_value1() == P_TICK_DAMAGE )
{
affected_by.tick = as<uint8_t>( effect.spell_effect_num() + 1 );
print_affected_by( a, effect, "tick damage increase" );
}
}
}
return affected_by;
}
namespace cdwaste {
struct action_data_t
{
simple_sample_data_with_min_max_t exec;
simple_sample_data_with_min_max_t cumulative;
timespan_t iter_sum;
void update_ready( const action_t* action, timespan_t cd )
{
const cooldown_t* cooldown = action -> cooldown;
sim_t* sim = action -> sim;
if ( ( cd > 0_ms || ( cd <= 0_ms && cooldown -> duration > 0_ms ) ) &&
cooldown -> current_charge == cooldown -> charges && cooldown -> last_charged > 0_ms &&
cooldown -> last_charged < sim -> current_time() )
{
timespan_t time_ = sim -> current_time() - cooldown -> last_charged;
if ( sim -> debug )
{
sim -> out_debug.print( "{} {} cooldown waste tracking waste={} exec_time={}",
action -> player -> name(), action -> name(),
time_, action -> time_to_execute );
}
time_ -= action -> time_to_execute;
if ( time_ > 0_ms )
{
exec.add( time_.total_seconds() );
iter_sum += time_;
}
}
}
};
struct player_data_t
{
using record_t = std::pair<std::string, std::unique_ptr<action_data_t>>;
std::vector<record_t> data_;
action_data_t* get( const action_t* a )
{
auto it = range::find( data_, a -> name_str, &record_t::first );
if ( it != data_.cend() )
return it -> second.get();
data_.emplace_back( a -> name_str, std::make_unique<action_data_t>( ) );
return data_.back().second.get();
}
void merge( const player_data_t& other )
{
for ( size_t i = 0, end = data_.size(); i < end; i++ )
{
data_[ i ].second -> exec.merge( other.data_[ i ].second -> exec );
data_[ i ].second -> cumulative.merge( other.data_[ i ].second -> cumulative );
}
}
void datacollection_begin()
{
for ( auto& rec : data_ )
rec.second -> iter_sum = 0_ms;
}
void datacollection_end()
{
for ( auto& rec : data_ )
rec.second -> cumulative.add( rec.second -> iter_sum.total_seconds() );
}
};
void print_html_report( const player_t& player, const player_data_t& data, report::sc_html_stream& os )
{
if ( data.data_.empty() )
return;
os << "<h3 class='toggle open'>Cooldown waste details</h3>\n"
<< "<div class='toggle-content'>\n";
os << "<table class='sc' style='float: left;margin-right: 10px;'>\n"
<< "<tr>"
<< "<th></th>"
<< "<th colspan='3'>Seconds per Execute</th>"
<< "<th colspan='3'>Seconds per Iteration</th>"
<< "</tr>\n"
<< "<tr>"
<< "<th>Ability</th>"
<< "<th>Average</th><th>Minimum</th><th>Maximum</th>"
<< "<th>Average</th><th>Minimum</th><th>Maximum</th>"
<< "</tr>\n";
size_t n = 0;
for ( const auto& rec : data.data_ )
{
const auto& entry = rec.second -> exec;
if ( entry.count() == 0 )
continue;
const auto& iter_entry = rec.second -> cumulative;
const action_t* a = player.find_action( rec.first );
++n;
fmt::print( os,
"<tr{}>"
"<td class='left'>{}</td>"
"<td class='right'>{:.3f}</td><td class='right'>{:.3f}</td><td class='right'>{:.3f}</td>"
"<td class='right'>{:.3f}</td><td class='right'>{:.3f}</td><td class='right'>{:.3f}</td>"
"</tr>\n",
n & 1 ? " class='odd'" : "",
a ? report_decorators::decorated_action( *a ) : util::encode_html( rec.first ),
entry.mean(), entry.min(), entry.max(),
iter_entry.mean(), iter_entry.min(), iter_entry.max()
);
}
os << "</table>\n"
<< "</div>\n"
<< "<div class='clear'></div>\n";
}
} // end namespace cd_waste
// ==========================================================================
// Hunter
// ==========================================================================
// in-game the buffs are actually 8 distinct spells, so the player can't get more than 8 simultaneously
constexpr unsigned BARBED_SHOT_BUFFS_MAX = 8;
enum howl_of_the_pack_leader_beast
{
WYVERN,
BOAR,
BEAR
};
struct maybe_bool {
enum class value_e : uint8_t {
None, True, False
};
constexpr maybe_bool() = default;
constexpr maybe_bool& operator=( bool val ) {
set( val );
return *this;
}
constexpr void set( bool val ) {
value_ = val ? value_e::True : value_e::False;
}
constexpr bool is_none() const { return value_ == value_e::None; }
constexpr operator bool() const { return value_ == value_e::True; }
value_e value_ = value_e::None;
};
template <typename Data, typename Base = action_state_t>
struct hunter_action_state_t : public Base, public Data
{
static_assert( std::is_base_of_v<action_state_t, Base> );
static_assert( std::is_default_constructible_v<Data> ); // required for initialize
static_assert( std::is_copy_assignable_v<Data> ); // required for copy_state
using Base::Base;
void initialize() override
{
Base::initialize();
*static_cast<Data*>( this ) = Data{};
}
std::ostringstream& debug_str( std::ostringstream& s ) override
{
Base::debug_str( s );
if constexpr ( fmt::is_formattable<Data>::value )
fmt::print( s, " {}", *static_cast<const Data*>( this ) );
return s;
}
void copy_state( const action_state_t* o ) override
{
Base::copy_state( o );
*static_cast<Data*>( this ) = *static_cast<const Data*>( debug_cast<const hunter_action_state_t*>( o ) );
}
};
struct pet_amount_expr_t : public expr_t
{
public:
action_t& action;
action_t& pet_action;
action_state_t* state;
pet_amount_expr_t( util::string_view name, action_t& a, action_t& pet_a )
: expr_t( name ), action( a ), pet_action( pet_a ), state( pet_a.get_state() )
{
state->n_targets = 1;
state->chain_target = 0;
state->result = RESULT_HIT;
}
double evaluate() override
{
state->target = action.target;
pet_action.snapshot_state( state, result_amount_type::DMG_DIRECT );
state->result_amount = pet_action.calculate_direct_amount( state );
state->target->target_mitigation( action.get_school(), result_amount_type::DMG_DIRECT, state );
return state->result_amount;
}
~pet_amount_expr_t() override
{
delete state;
}
};
struct hunter_t;
namespace pets
{
struct natures_ally_pet_t;
struct dire_critter_t;
struct dire_beast_t;
struct dark_hound_t;
struct fenryr_t;
struct hati_t;
struct bear_t;
struct stable_pet_t;
struct call_of_the_wild_pet_t;
struct hunter_main_pet_base_t;
struct animal_companion_t;
struct hunter_main_pet_t;
}
namespace events
{
struct tar_trap_aoe_t;
}
struct hunter_td_t: public actor_target_data_t
{
bool damaged = false;
struct cooldowns_t
{
cooldown_t* overwatch;
} cooldowns;
struct debuffs_t
{
buff_t* cull_the_herd;
buff_t* outland_venom;
buff_t* spotters_mark;
buff_t* kill_zone;
buff_t* ohnahran_winds;
buff_t* sentinels_mark;
buff_t* crescent_steel;
buff_t* headshot;
} debuffs;
struct dots_t
{
dot_t* explosive_shot;
dot_t* serpent_sting;
dot_t* barbed_shot;
dot_t* laceration;
dot_t* wildfire_bomb;
dot_t* merciless_blow;
dot_t* spearhead;
dot_t* cull_the_herd;
dot_t* sanctified_armaments;
dot_t* black_arrow;
} dots;
hunter_td_t( player_t* target, hunter_t* p );
void target_demise();
};
struct hunter_t final : public player_t
{
public:
struct pets_t
{
pets::hunter_main_pet_t* main = nullptr;
pets::animal_companion_t* animal_companion = nullptr;
spawner::pet_spawner_t<pets::natures_ally_pet_t, hunter_t> natures_ally_pet;
spawner::pet_spawner_t<pets::dire_beast_t, hunter_t> dire_beast;
spawner::pet_spawner_t<pets::dark_hound_t, hunter_t> dark_hound;
spawner::pet_spawner_t<pets::fenryr_t, hunter_t> fenryr;
spawner::pet_spawner_t<pets::hati_t, hunter_t> hati;
spawner::pet_spawner_t<pets::bear_t, hunter_t> bear;
spawner::pet_spawner_t<pets::call_of_the_wild_pet_t, hunter_t> cotw_stable_pet;
pets_t( hunter_t* p ) :
natures_ally_pet( "natures_ally_pet", p ),
dire_beast( "dire_beast", p ),
dark_hound( "dark_hound", p ),
fenryr( "fenryr", p ),
hati( "hati", p ),
bear( "bear", p ),
cotw_stable_pet( "call_of_the_wild_pet", p )
{
}
} pets;
struct tier_sets_t
{
// TWW Season 1 - Nerub'ar Palace
spell_data_ptr_t tww_s1_bm_2pc;
spell_data_ptr_t tww_s1_bm_4pc;
spell_data_ptr_t tww_s1_mm_2pc;
spell_data_ptr_t tww_s1_mm_4pc;
spell_data_ptr_t tww_s1_sv_2pc;
spell_data_ptr_t tww_s1_sv_4pc;
// TWW Season 2 - Liberation of Undermine
spell_data_ptr_t tww_s2_bm_2pc;
spell_data_ptr_t tww_s2_bm_4pc;
spell_data_ptr_t tww_s2_mm_2pc;
spell_data_ptr_t tww_s2_mm_4pc;
spell_data_ptr_t tww_s2_sv_2pc;
spell_data_ptr_t tww_s2_sv_4pc;
// TWW Season 3 - Manaforge Omega
spell_data_ptr_t tww_s3_dark_ranger_2pc;
spell_data_ptr_t tww_s3_dark_ranger_4pc;
spell_data_ptr_t tww_s3_dark_ranger_4pc_buff;
spell_data_ptr_t tww_s3_sentinel_2pc;
spell_data_ptr_t tww_s3_sentinel_2pc_buff;
spell_data_ptr_t tww_s3_sentinel_4pc;
spell_data_ptr_t tww_s3_sentinel_4pc_buff;
spell_data_ptr_t tww_s3_pack_leader_2pc;
spell_data_ptr_t tww_s3_pack_leader_2pc_haste_buff;
spell_data_ptr_t tww_s3_pack_leader_2pc_mastery_buff;
spell_data_ptr_t tww_s3_pack_leader_2pc_crit_buff;
spell_data_ptr_t tww_s3_pack_leader_4pc;
// Midnight Season 1 - Whatever the raid is called
spell_data_ptr_t mid_s1_bm_2pc;
spell_data_ptr_t mid_s1_bm_4pc;
spell_data_ptr_t mid_s1_mm_2pc;
spell_data_ptr_t mid_s1_mm_4pc;
spell_data_ptr_t mid_s1_mm_4pc_damage;
spell_data_ptr_t mid_s1_sv_2pc;
spell_data_ptr_t mid_s1_sv_4pc;
} tier_set;
struct buffs_t
{
// Hunter Tree
buff_t* deathblow;
// Marksmanship Tree
buff_t* precise_shots;
buff_t* trick_shots;
buff_t* lock_and_load;
buff_t* in_the_rhythm;
buff_t* trueshot;
buff_t* moving_target;
buff_t* precision_detonation_hidden;
buff_t* bullseye;
buff_t* bulletstorm;
buff_t* volley;
buff_t* double_tap;
buff_t* focus_fire;
// Beast Mastery Tree
std::array<buff_t*, BARBED_SHOT_BUFFS_MAX> barbed_shot;
buff_t* bestial_wrath;
buff_t* call_of_the_wild;
buff_t* beast_cleave;
buff_t* serpentine_rhythm;
buff_t* serpentine_blessing;
buff_t* huntmasters_call;
buff_t* summon_fenryr;
buff_t* summon_hati;
buff_t* heart_of_the_pack;
buff_t* natures_ally_3;
buff_t* bloody_frenzy;
// Survival Tree
buff_t* tip_of_the_spear;
buff_t* tip_of_the_spear_boomstick;
buff_t* tip_of_the_spear_chakram;
buff_t* mongoose_fury;
buff_t* frenzy_strikes;
buff_t* sulfurlined_pockets_building;
buff_t* sulfurlined_pockets_ready;
buff_t* bloodseeker;
buff_t* aspect_of_the_eagle;
buff_t* terms_of_engagement;
buff_t* coordinated_assault;
buff_t* ruthless_marauder;
buff_t* relentless_primal_ferocity;
buff_t* bombardier;
buff_t* wallop;
buff_t* takedown;
buff_t* wildfire_imbuement;
buff_t* raptor_swipe;
// Pet family buffs
buff_t* endurance_training;
buff_t* pathfinding;
buff_t* predators_thirst;
// Tier Set Bonuses
// TWW - S2
buff_t* jackpot; // MM 2pc
buff_t* winning_streak; // SV 2pc - Wildfire Bomb damage stacking buff
buff_t* strike_it_rich; // SV 4pc - Mongoose Bite damage buff, consuming it reduces Wildfire Bomb cooldown
// TWW - S3
buff_t* boon_of_elune_2pc; // Sentinel 2pc
buff_t* boon_of_elune_4pc; // Sentinel 4pc
buff_t* grizzled_fur; // Pack Leader 2pc mastery
buff_t* hasted_hooves; // Pack Leader 2pc haste
// Hero Talents
// Pack Leader
buff_t* howl_of_the_pack_leader_wyvern;
buff_t* howl_of_the_pack_leader_boar;
buff_t* howl_of_the_pack_leader_bear;
buff_t* howl_of_the_pack_leader_cooldown;
buff_t* wyverns_cry;
buff_t* hogstrider;
buff_t* stampede;
buff_t* lead_from_the_front;
// Sentinel
buff_t* eyes_closed;
buff_t* stargazer;
buff_t* moonlight_chakram;
// Dark Ranger
buff_t* withering_fire;
buff_t* wailing_arrow;
} buffs;
struct cooldowns_t
{
cooldown_t* kill_shot;
cooldown_t* explosive_shot;
cooldown_t* aimed_shot;
cooldown_t* rapid_fire;
cooldown_t* trueshot;
cooldown_t* target_acquisition;
cooldown_t* volley;
cooldown_t* salvo;
cooldown_t* kill_command;
cooldown_t* wild_thrash;
cooldown_t* barbed_shot;
cooldown_t* bestial_wrath;
cooldown_t* wildfire_bomb;
cooldown_t* butchery;
cooldown_t* harpoon;
cooldown_t* boomstick;
cooldown_t* flanking_strike;
cooldown_t* strike_as_one;
cooldown_t* ruthless_marauder;
cooldown_t* coordinated_assault;
cooldown_t* takedown;
cooldown_t* flamefang_pitch;
cooldown_t* black_arrow;
cooldown_t* bleak_powder;
cooldown_t* sentinels_mark;
} cooldowns;
struct gains_t
{
gain_t* barbed_shot;
gain_t* terms_of_engagement;
gain_t* invigorating_pulse;
gain_t* serpentine_strikes;
gain_t* lethal_barbs;
} gains;
struct procs_t
{
proc_t* snakeskin_quiver;
proc_t* wild_call;
proc_t* dire_command;
proc_t* bear_without_lftf;
proc_t* deathblow;
proc_t* precision_detonation;
proc_t* tww_s2_mm_4pc_explosive;
proc_t* release_and_reload_stacks;
proc_t* crescent_steel_stacks;
proc_t* overwatch_implosions;
} procs;
struct rppm_t
{
real_ppm_t* shadow_hounds;
real_ppm_t* shadow_surge;
real_ppm_t* let_fly;
} rppm;
struct talents_t
{
// Hunter Tree
spell_data_ptr_t rejuvenating_winds; //Utility talent, won't implement
spell_data_ptr_t survival_of_the_fittest; //Utility talent, won't implement
spell_data_ptr_t posthaste; //Utility talent, won't implement
spell_data_ptr_t natural_mending; //Utility talent, won't implement
spell_data_ptr_t padded_armor; //Utility talent, won't implement
spell_data_ptr_t hunters_avoidance; //Utility talent, won't implement
spell_data_ptr_t wilderness_medicine; //Utility talent, won't implement
spell_data_ptr_t combat_experience; //TODO fix runtime error
spell_data_ptr_t improved_aspect_of_the_cheetah; //Utility talent, won't implement
spell_data_ptr_t concussive_shot; //TODO Not implemented - probably not needed
spell_data_ptr_t precision_strikes;
spell_data_ptr_t counter_shot;
spell_data_ptr_t muzzle;
spell_data_ptr_t serrated_tips;
spell_data_ptr_t tranquilizing_shot; //TODO Not implemented - probably not needed
spell_data_ptr_t pathfinding; //Utility talent, won't implement
spell_data_ptr_t disruptive_rounds; //TODO Not implemented
spell_data_ptr_t improved_feign_death; //Utility talent, won't implement
spell_data_ptr_t misdirection; //Utility talent, won't implement
spell_data_ptr_t kodo_tranquilizer; //Utility talent, won't implement
spell_data_ptr_t devilsaur_tranquilizer; //Utility talent, won't implement
spell_data_ptr_t kindling_flare; //Utility talent, won't implement
spell_data_ptr_t trigger_finger;
spell_data_ptr_t tar_trap;
spell_data_ptr_t scare_beast; //Utility talent, won't implement
spell_data_ptr_t touch_of_grass; //Utility talent, won't implement
spell_data_ptr_t camouflage; //Utility talent, won't implement
spell_data_ptr_t no_hard_feelings; //Utility talent, won't implement
spell_data_ptr_t improved_aspect_of_the_turtle; //Utility talent, won't implement
spell_data_ptr_t specialized_arsenal;
spell_data_ptr_t scouts_instincts; //Utility talent, won't implement
spell_data_ptr_t shell_wall; //Utility talent, won't implement
spell_data_ptr_t intimidation; //Utility talent, won't implement
spell_data_ptr_t improved_snaring; //Utility talent, won't implement
spell_data_ptr_t lone_survivor; //Utility talent, won't implement
spell_data_ptr_t catlike_reflexes; //Utility talent, won't implement
spell_data_ptr_t binding_shot; //Utility talent, won't implement
spell_data_ptr_t trailblazer; //Utility talent, won't implement
spell_data_ptr_t moment_of_opportunity; //Utility talent, won't implement
spell_data_ptr_t cold_feet; //Utility talent, won't implement
spell_data_ptr_t territorial_instincts; //Utility talent, won't implement
spell_data_ptr_t guttural_roar; //Utility talent, won't implement
spell_data_ptr_t born_to_be_wild; //Utility talent, won't implement
spell_data_ptr_t keen_eyesight;
spell_data_ptr_t tar_coated_bindings; //Utility talent, won't implement
spell_data_ptr_t horsehair_tether; //Utility talent, won't implement
spell_data_ptr_t improved_traps; //Utility talent, won't implement
spell_data_ptr_t emergency_salve; //Utility talent, won't implement
spell_data_ptr_t roar_of_sacrifice; //Utility talent, won't implement
spell_data_ptr_t guardians_hide; //Utility talent, won't implement
spell_data_ptr_t unnatural_causes;
spell_data_ptr_t unnatural_causes_debuff;
spell_data_ptr_t deathblow_buff;
spell_data_ptr_t explosive_shot; //TODO Removed
spell_data_ptr_t explosive_shot_cast; //TODO Removed
spell_data_ptr_t explosive_shot_damage; //TODO Removed
spell_data_ptr_t high_explosive_trap; //TODO Removed
spell_data_ptr_t implosive_trap; //TODO Removed
spell_data_ptr_t explosive_trap_damage; //TODO Removed
// Beast Mastery Tree
spell_data_ptr_t kill_command_bm_player;
spell_data_ptr_t kill_command_bm_pet;
spell_data_ptr_t animal_companion;
spell_data_ptr_t solitary_companion;
spell_data_ptr_t barbed_shot;
spell_data_ptr_t alpha_predator;
spell_data_ptr_t dire_beast;
spell_data_ptr_t stomp;
spell_data_ptr_t stomp_dmg;
spell_data_ptr_t war_orders;
spell_data_ptr_t wild_thrash_player;
spell_data_ptr_t wild_thrash_pet;
spell_data_ptr_t bestial_wrath;
spell_data_ptr_t cobra_shot;
spell_data_ptr_t cobra_shot_data;
spell_data_ptr_t beast_cleave;
spell_data_ptr_t scent_of_blood;
spell_data_ptr_t thundering_hooves;
spell_data_ptr_t go_for_the_throat;
spell_data_ptr_t laceration;
spell_data_ptr_t laceration_driver;
spell_data_ptr_t laceration_bleed;
spell_data_ptr_t kill_cleave;
spell_data_ptr_t training_expert;
spell_data_ptr_t the_beast_within;
spell_data_ptr_t thrill_of_the_hunt;
spell_data_ptr_t pack_tactics;
spell_data_ptr_t barbed_scales;
spell_data_ptr_t aspect_of_the_beast;
spell_data_ptr_t dire_cleave;
spell_data_ptr_t dire_command;
spell_data_ptr_t jagged_wounds;
spell_data_ptr_t serpentine_strikes;
spell_data_ptr_t serpentine_strikes_energize;
spell_data_ptr_t snakeskin_quiver;
spell_data_ptr_t cobra_senses;
spell_data_ptr_t natures_ally_1;
spell_data_ptr_t dire_frenzy;
spell_data_ptr_t frenzy;
spell_data_ptr_t killer_instinct;
spell_data_ptr_t natures_ally_2;
spell_data_ptr_t brutal_companion;
spell_data_ptr_t huntmasters_call;
spell_data_ptr_t heart_of_the_pack;
spell_data_ptr_t heart_of_the_pack_buff;
spell_data_ptr_t bloodshed;
spell_data_ptr_t bloodshed_dot;
spell_data_ptr_t savagery_bm;
spell_data_ptr_t killer_cobra;
spell_data_ptr_t master_handler;
spell_data_ptr_t natures_ally_3;
spell_data_ptr_t natures_ally_3_buff;
spell_data_ptr_t wildspeaker;
spell_data_ptr_t wildspeaker_kill_command;
spell_data_ptr_t wildspeaker_bestial_wrath;
spell_data_ptr_t wild_instincts;
spell_data_ptr_t bloody_frenzy;
spell_data_ptr_t bloody_frenzy_buff;
spell_data_ptr_t piercing_fangs;
spell_data_ptr_t multishot_bm; //TODO removed
spell_data_ptr_t wild_call; //TODO removed
spell_data_ptr_t hunters_prey; //TODO removed
spell_data_ptr_t hunters_prey_hidden_buff; //TODO removed
spell_data_ptr_t poisoned_barbs; //TODO removed
spell_data_ptr_t serpentine_rhythm; //TODO removed
spell_data_ptr_t barbed_wrath; //TODO removed
spell_data_ptr_t call_of_the_wild; //TODO removed
// Marksmanship Tree
spell_data_ptr_t aimed_shot;
spell_data_ptr_t rapid_fire;
spell_data_ptr_t rapid_fire_tick;
spell_data_ptr_t rapid_fire_energize;
spell_data_ptr_t precise_shots;
spell_data_ptr_t precise_shots_buff;
spell_data_ptr_t quick_draw; //TODO implement move speed buff?
spell_data_ptr_t lock_and_load; // TODO how does its blp work
spell_data_ptr_t lock_and_load_buff;
spell_data_ptr_t surging_shots;
spell_data_ptr_t avian_specialization;
spell_data_ptr_t unbreakable_bond;
spell_data_ptr_t trick_shots;
spell_data_ptr_t trick_shots_data;
spell_data_ptr_t trick_shots_buff;
spell_data_ptr_t aspect_of_the_hydra;
spell_data_ptr_t in_the_rhythm;
spell_data_ptr_t in_the_rhythm_buff;
spell_data_ptr_t penetrating_shots;
spell_data_ptr_t tenacious; //Utility talent, won't implement
spell_data_ptr_t cunning; //Utility talent, won't implement
spell_data_ptr_t master_marksman;
spell_data_ptr_t master_marksman_bleed;
spell_data_ptr_t light_ammo;
spell_data_ptr_t obsidian_arrowhead;
spell_data_ptr_t on_target;
spell_data_ptr_t trueshot;
spell_data_ptr_t kill_shot; //TODO Moved to MM exclusive
spell_data_ptr_t target_acquisition;
spell_data_ptr_t critical_precision;
spell_data_ptr_t no_scope;
spell_data_ptr_t feathered_frenzy;
spell_data_ptr_t lethality;
spell_data_ptr_t headshot;
spell_data_ptr_t headshot_debuff;
spell_data_ptr_t deadeye;
spell_data_ptr_t deathblow;
spell_data_ptr_t take_aim_1;
spell_data_ptr_t unmatched_precision;
spell_data_ptr_t bullseye;
spell_data_ptr_t bullseye_buff;
spell_data_ptr_t calling_the_shots;
spell_data_ptr_t unerring_vision; /* Spelldata now scuffed because of Streamline's removal, manual parsing likely needed
TODO reconfirm before launch */
spell_data_ptr_t small_game_hunter;
spell_data_ptr_t eagles_accuracy;
spell_data_ptr_t take_aim_2;
spell_data_ptr_t focused_aim;
spell_data_ptr_t bulletstorm;
spell_data_ptr_t bulletstorm_buff;
spell_data_ptr_t tensile_bowstring;
spell_data_ptr_t volley;
spell_data_ptr_t volley_data;
spell_data_ptr_t volley_dmg;
spell_data_ptr_t focus_fire;
spell_data_ptr_t focus_fire_buff;
spell_data_ptr_t take_aim_3;
spell_data_ptr_t windrunner_quiver;
spell_data_ptr_t incendiary_ammunition;
spell_data_ptr_t double_tap;
spell_data_ptr_t double_tap_buff;
spell_data_ptr_t salvo;
spell_data_ptr_t bullet_hell;
spell_data_ptr_t shrapnel_shot;
spell_data_ptr_t unload;
spell_data_ptr_t ammo_conservation; //TODO Removed
spell_data_ptr_t moving_target; //TODO Removed
spell_data_ptr_t moving_target_buff; //TODO Removed
spell_data_ptr_t precision_detonation; //TODO Removed
spell_data_ptr_t precision_detonation_buff; //TODO Removed
spell_data_ptr_t magnetic_gunpowder; //TODO Removed
spell_data_ptr_t ohnahran_winds; //TODO Removed
spell_data_ptr_t ohnahran_winds_debuff; //TODO Removed
spell_data_ptr_t kill_zone; //TODO Removed
spell_data_ptr_t kill_zone_debuff; //TODO Removed
// Survival Tree
spell_data_ptr_t kill_command_sv_player;
spell_data_ptr_t kill_command_sv_pet;
spell_data_ptr_t wildfire_bomb;
spell_data_ptr_t wildfire_bomb_data;
spell_data_ptr_t wildfire_bomb_dmg;
spell_data_ptr_t wildfire_bomb_dot;
spell_data_ptr_t raptor_strike;
spell_data_ptr_t raptor_strike_eagle;
spell_data_ptr_t raptor_swipe_1;
spell_data_ptr_t raptor_swipe_2;
spell_data_ptr_t raptor_swipe_3;
spell_data_ptr_t raptor_swipe_spell;
spell_data_ptr_t raptor_swipe_buff;
spell_data_ptr_t guerrilla_tactics;
spell_data_ptr_t tip_of_the_spear;
spell_data_ptr_t tip_of_the_spear_buff;
spell_data_ptr_t tip_of_the_spear_boomstick_buff;
spell_data_ptr_t tip_of_the_spear_chakram_buff;
spell_data_ptr_t lunge;
spell_data_ptr_t boomstick;
spell_data_ptr_t strike_as_one;
spell_data_ptr_t strike_as_one_dmg;
spell_data_ptr_t shrapnel_bomb;
spell_data_ptr_t shrapnel_bomb_bleed;
spell_data_ptr_t flamebreak;
spell_data_ptr_t bloodseeker;
spell_data_ptr_t quick_reload;
spell_data_ptr_t flankers_advantage;
spell_data_ptr_t two_against_many;
spell_data_ptr_t mongoose_fury;
spell_data_ptr_t mongoose_fury_buff;
spell_data_ptr_t mongoose_rounds;
spell_data_ptr_t wildfire_shells;
spell_data_ptr_t shellshock;
spell_data_ptr_t sic_em;
spell_data_ptr_t sic_em_bleed;
spell_data_ptr_t bloody_claws;
spell_data_ptr_t wallop;
spell_data_ptr_t wallop_buff;
spell_data_ptr_t improved_wildfire_bomb;
spell_data_ptr_t bonding;
spell_data_ptr_t sweeping_spear;
spell_data_ptr_t vulnerability;
spell_data_ptr_t blackrock_munitions;
spell_data_ptr_t shower_of_blood;
spell_data_ptr_t outland_venom;
spell_data_ptr_t outland_venom_debuff;
spell_data_ptr_t explosives_expert;
spell_data_ptr_t takedown;
spell_data_ptr_t takedown_energize;
spell_data_ptr_t takedown_dmg;
spell_data_ptr_t takedown_pet;
spell_data_ptr_t killer_companion;
spell_data_ptr_t flamefang_pitch;
spell_data_ptr_t flamefang_pitch_data;
spell_data_ptr_t flamefang_pitch_dmg;
spell_data_ptr_t flamefang_pitch_aoe;
spell_data_ptr_t twin_fangs;
spell_data_ptr_t savagery_sv;
spell_data_ptr_t wildfire_infusion;
spell_data_ptr_t grenade_juggler;
spell_data_ptr_t wildfire_imbuement;
spell_data_ptr_t wildfire_imbuement_dmg;
spell_data_ptr_t wildfire_imbuement_buff;
spell_data_ptr_t flanked;
spell_data_ptr_t lethal_calibration;
spell_data_ptr_t primal_surge;
spell_data_ptr_t mongoose_bite; //TODO Removed
spell_data_ptr_t mongoose_bite_eagle; //TODO Removed
spell_data_ptr_t sulfurlined_pockets; //TODO Removed
spell_data_ptr_t sulfurlined_pockets_building_buff; //TODO Removed
spell_data_ptr_t sulfurlined_pockets_ready_buff; //TODO Removed
spell_data_ptr_t butchery; //TODO Removed
spell_data_ptr_t flanking_strike; //TODO Removed
spell_data_ptr_t flanking_strike_player; //TODO Removed
spell_data_ptr_t flanking_strike_pet; //TODO Removed
spell_data_ptr_t ranger; //TODO Removed
spell_data_ptr_t cull_the_herd; //TODO Removed
spell_data_ptr_t cull_the_herd_dot; //TODO Removed
spell_data_ptr_t frenzy_strikes; //TODO Removed
spell_data_ptr_t frenzy_strikes_buff; //TODO Removed
spell_data_ptr_t merciless_blow; //TODO Removed
spell_data_ptr_t merciless_blow_flanking_bleed; //TODO Removed
spell_data_ptr_t merciless_blow_butchery_bleed; //TODO Removed
spell_data_ptr_t vipers_venom; //TODO Removed
spell_data_ptr_t terms_of_engagement; //TODO Removed
spell_data_ptr_t terms_of_engagement_dmg; //TODO Removed
spell_data_ptr_t terms_of_engagement_buff; //TODO Removed
spell_data_ptr_t born_to_kill; //TODO Removed
spell_data_ptr_t tactical_advantage; //TODO Removed
spell_data_ptr_t contagious_reagents; //TODO Removed
spell_data_ptr_t coordinated_assault; //TODO Removed
spell_data_ptr_t coordinated_assault_dmg; //TODO Removed
spell_data_ptr_t spearhead; //TODO Removed
spell_data_ptr_t spearhead_bleed; //TODO Removed
spell_data_ptr_t spearhead_debuff; //TODO Removed
spell_data_ptr_t ruthless_marauder; //TODO Removed
spell_data_ptr_t ruthless_marauder_buff; //TODO Removed
spell_data_ptr_t symbiotic_adrenaline; //TODO Removed
spell_data_ptr_t relentless_primal_ferocity; //TODO Removed
spell_data_ptr_t relentless_primal_ferocity_buff; //TODO Removed
spell_data_ptr_t bombardier; //TODO Removed
spell_data_ptr_t bombardier_buff; //TODO Removed
spell_data_ptr_t deadly_duo; //TODO Removed
// Dark Ranger
spell_data_ptr_t black_arrow;
spell_data_ptr_t black_arrow_spell;
spell_data_ptr_t black_arrow_dot;
spell_data_ptr_t bleak_arrows;
spell_data_ptr_t bleak_arrows_spell;
spell_data_ptr_t soul_drinker;
spell_data_ptr_t bleak_powder;
spell_data_ptr_t bleak_powder_spell;