SimulationCraft
SimulationCraft is a tool to explore combat mechanics in the popular MMO RPG World of Warcraft (tm).
sc_priest.hpp
1 // ==========================================================================
2 // Priest Definitions Sim File
3 // Contact: https://github.com/orgs/simulationcraft/teams/priest/members
4 // Wiki: https://github.com/simulationcraft/simc/wiki/Priests
5 // ==========================================================================
6 //
7 // This file contains all definitions for priests. Implementations should
8 // be done in sc_priest.cpp if they are shared by more than one spec or
9 // in the respective spec file if they are limited to one spec only.
10 
11 #pragma once
12 #include "player/covenant.hpp"
13 #include "player/pet_spawner.hpp"
14 #include "sc_enums.hpp"
15 
16 #include "simulationcraft.hpp"
17 
18 namespace priestspace
19 {
20 /* Forward declarations
21  */
22 struct priest_t;
23 
24 namespace actions::spells
25 {
26 struct ascended_blast_heal_t;
27 struct mind_sear_tick_t;
28 struct shadowy_apparition_spell_t;
29 struct ascended_eruption_t;
30 struct ascended_eruption_heal_t;
31 struct wrathful_faerie_t;
32 struct wrathful_faerie_fermata_t;
33 struct psychic_link_t;
34 struct shadow_weaving_t;
35 struct eternal_call_to_the_void_t;
36 struct unholy_transfusion_healing_t;
37 } // namespace actions::spells
38 
43 struct priest_td_t final : public actor_target_data_t
44 {
45 public:
46  struct dots_t
47  {
48  propagate_const<dot_t*> shadow_word_pain;
49  propagate_const<dot_t*> vampiric_touch;
50  propagate_const<dot_t*> devouring_plague;
51  propagate_const<dot_t*> unholy_transfusion;
52  } dots;
53 
54  struct buffs_t
55  {
57  propagate_const<buff_t*> death_and_madness_debuff;
58  propagate_const<buff_t*> surrender_to_madness_debuff;
59  propagate_const<buff_t*> wrathful_faerie;
60  propagate_const<buff_t*> wrathful_faerie_fermata;
61  propagate_const<buff_t*> hungering_void;
62  } buffs;
63 
64  priest_t& priest()
65  {
66  return *debug_cast<priest_t*>( source );
67  }
68  const priest_t& priest() const
69  {
70  return *debug_cast<priest_t*>( source );
71  }
72 
73  priest_td_t( player_t* target, priest_t& p );
74  void reset();
75  void target_demise();
76 };
77 
82 struct priest_t final : public player_t
83 {
84 public:
85  using base_t = player_t;
86 
87  // Buffs
88  struct
89  {
90  // Generic
91  propagate_const<buff_t*> desperate_prayer;
92 
93  // Talents
94  propagate_const<buff_t*> twist_of_fate;
95 
96  // Discipline
97  propagate_const<buff_t*> inner_focus;
98  propagate_const<buff_t*> power_of_the_dark_side;
99  propagate_const<buff_t*> sins_of_the_many;
100  propagate_const<buff_t*> shadow_covenant;
101  propagate_const<buff_t*> spirit_shell;
102 
103  // Holy
104  propagate_const<buff_t*> apotheosis;
105 
106  // Shadow
107  propagate_const<buff_t*> dispersion;
108  propagate_const<buff_t*> shadowform;
109  propagate_const<buff_t*> shadowform_state; // Dummy buff to track whether player entered Shadowform initially
110  propagate_const<buff_t*> surrender_to_madness;
111  propagate_const<buff_t*> surrender_to_madness_death;
112  propagate_const<buff_t*> vampiric_embrace;
113  propagate_const<buff_t*> void_torrent;
114  propagate_const<buff_t*> voidform;
115  propagate_const<buff_t*> death_and_madness_buff;
116  propagate_const<buff_t*> unfurling_darkness;
117  propagate_const<buff_t*> unfurling_darkness_cd; // Blizzard uses a buff to track the ICD
118  propagate_const<buff_t*> ancient_madness;
119  propagate_const<buff_t*> dark_thought;
120 
121  // Runeforge Legendary
122  propagate_const<buff_t*> the_penitent_one;
123  propagate_const<buff_t*> sephuzs_proclamation;
124  propagate_const<buff_t*> talbadars_stratagem;
125  propagate_const<buff_t*> shadow_word_manipulation;
126  propagate_const<buff_t*> rigor_mortis;
127 
128  // Conduits
129  propagate_const<buff_t*> translucent_image;
130  propagate_const<buff_t*> mind_devourer;
131  propagate_const<buff_t*> dissonant_echoes;
132 
133  // Covenants
134  propagate_const<buff_t*> fae_guardians;
135  propagate_const<buff_t*> boon_of_the_ascended;
136 
137  // Tier Sets
138  propagate_const<buff_t*> living_shadow;
139  } buffs;
140 
141  // Talents
142  struct
143  {
144  // Shared
145  const spell_data_t* mindbender;
146  const spell_data_t* twist_of_fate;
147  const spell_data_t* angelic_feather;
148  const spell_data_t* body_and_soul; // implemented for PW:S
149  const spell_data_t* shining_force;
150  const spell_data_t* psychic_voice;
151  const spell_data_t* divine_star;
152  const spell_data_t* halo;
153 
154  // Discipline
155  // T15
156  const spell_data_t* castigation;
157  const spell_data_t* schism;
158  // T30
159  const spell_data_t* power_word_solace;
160  // T40
161  const spell_data_t* sins_of_the_many; // assumes 0 atonement targets
162  const spell_data_t* shadow_covenant; // healing not fully implemented, only dmg/healing buff
163  // T45
164  const spell_data_t* purge_the_wicked;
165  // T50
166  const spell_data_t* spirit_shell; // not fully implemented
167 
168  // Holy
169  // // T15
170  const spell_data_t* enlightenment;
171  // // T50
172  const spell_data_t* light_of_the_naaru;
173  const spell_data_t* apotheosis;
174 
175  // Shadow
176  // T15
177  const spell_data_t* fortress_of_the_mind;
178  const spell_data_t* death_and_madness;
179  const spell_data_t* death_and_madness_insanity;
180  const spell_data_t* unfurling_darkness;
181  // T25
182  const spell_data_t* sanlayn;
183  const spell_data_t* intangibility; // CDR implemented, healing NYI
184  // T30
185  const spell_data_t* searing_nightmare;
186  const spell_data_t* misery;
187  // T35
188  const spell_data_t* last_word;
189  const spell_data_t* mind_bomb;
190  const spell_data_t* psychic_horror;
191  // T40
192  const spell_data_t* auspicious_spirits;
193  const spell_data_t* psychic_link;
194  const spell_data_t* shadow_crash;
195  // T45
196  const spell_data_t* damnation;
197  const spell_data_t* void_torrent;
198  // T50
199  const spell_data_t* hungering_void;
200  const spell_data_t* hungering_void_buff; // not linked from hungering void talent spell
201  const spell_data_t* ancient_madness;
202  const spell_data_t* surrender_to_madness;
203  } talents;
204 
205  // Specialization Spells
206  struct
207  {
208  const spell_data_t* mind_blast;
209  const spell_data_t* mind_sear;
210  const spell_data_t* mind_sear_insanity;
211  const spell_data_t* priest; // General priest data
212  const spell_data_t* shadow_word_death;
213  const spell_data_t* shadow_word_death_self_damage;
214 
215  // Discipline
216  const spell_data_t* discipline_priest; // General discipline data
217  const spell_data_t* power_of_the_dark_side; // For buffing the damage of penance
218 
219  // Holy
220  const spell_data_t* holy_priest; // General holy data
221  const spell_data_t* holy_words;
222  const spell_data_t* holy_word_serenity;
223 
224  // Shadow
225  const spell_data_t* dark_thought; // Actual buff, holds proc rate
226  const spell_data_t* dark_thoughts; // Passive effect
227  const spell_data_t* dispersion;
228  const spell_data_t* mind_flay;
229  const spell_data_t* shadow_priest; // General shadow data
230  const spell_data_t* shadowy_apparition; // Damage event
231  const spell_data_t* shadowy_apparitions; // Passive effect
232  const spell_data_t* shadowform;
233  const spell_data_t* silence;
234  const spell_data_t* vampiric_embrace;
235  const spell_data_t* void_bolt;
236  const spell_data_t* voidform;
237  const spell_data_t* void_eruption;
238  const spell_data_t* void_eruption_damage;
239 
240  // Legendary Effects
241  const spell_data_t* cauterizing_shadows_health;
242  const spell_data_t* painbreaker_psalm_insanity;
243  } specs;
244 
245  // DoT Spells
246  struct
247  {
248  const spell_data_t* shadow_word_pain;
249  const spell_data_t* vampiric_touch;
250  const spell_data_t* devouring_plague;
251  } dot_spells;
252 
253  // Mastery Spells
254  struct
255  {
256  const spell_data_t* grace;
257  const spell_data_t* echo_of_light;
258  const spell_data_t* shadow_weaving;
259  } mastery_spells;
260 
261  // Cooldowns
262  struct
263  {
264  // Shared
265  propagate_const<cooldown_t*> wrathful_faerie;
266  propagate_const<cooldown_t*> wrathful_faerie_fermata;
267 
268  // Shadow
270  propagate_const<cooldown_t*> mind_blast;
271  propagate_const<cooldown_t*> void_eruption;
272 
273  // Holy
274  propagate_const<cooldown_t*> holy_word_serenity;
276  } cooldowns;
277 
278  struct realppm_t
279  {
280  propagate_const<real_ppm_t*> eternal_call_to_the_void;
281  } rppm;
282 
283  // Gains
284  struct
285  {
286  propagate_const<gain_t*> cauterizing_shadows_health;
287  propagate_const<gain_t*> insanity_auspicious_spirits;
288  propagate_const<gain_t*> insanity_death_and_madness;
289  propagate_const<gain_t*> insanity_eternal_call_to_the_void_mind_flay;
290  propagate_const<gain_t*> insanity_eternal_call_to_the_void_mind_sear;
291  propagate_const<gain_t*> insanity_mind_sear;
292  propagate_const<gain_t*> insanity_mindgames;
293  propagate_const<gain_t*> insanity_pet;
294  propagate_const<gain_t*> insanity_surrender_to_madness;
295  propagate_const<gain_t*> mindbender;
296  propagate_const<gain_t*> painbreaker_psalm;
297  propagate_const<gain_t*> power_of_the_dark_side;
298  propagate_const<gain_t*> power_word_solace;
299  } gains;
300 
301  // Benefits
302  struct
303  {
304  } benefits;
305 
306  // Procs
307  struct
308  {
309  propagate_const<proc_t*> serendipity;
310  propagate_const<proc_t*> serendipity_overflow;
311  propagate_const<proc_t*> shadowy_apparition;
312  propagate_const<proc_t*> shadowy_apparition_overflow;
313  propagate_const<proc_t*> surge_of_light;
314  propagate_const<proc_t*> surge_of_light_overflow;
315  propagate_const<proc_t*> holy_fire_cd;
316  propagate_const<proc_t*> power_of_the_dark_side;
317  propagate_const<proc_t*> power_of_the_dark_side_overflow;
318  propagate_const<proc_t*> dissonant_echoes;
319  propagate_const<proc_t*> mind_devourer;
320  propagate_const<proc_t*> void_tendril;
321  propagate_const<proc_t*> void_lasher;
322  propagate_const<proc_t*> dark_thoughts_flay;
323  propagate_const<proc_t*> dark_thoughts_sear;
324  propagate_const<proc_t*> dark_thoughts_devouring_plague;
325  propagate_const<proc_t*> dark_thoughts_searing_nightmare;
326  propagate_const<proc_t*> dark_thoughts_missed;
327  propagate_const<proc_t*> living_shadow;
328  } procs;
329 
330  // Special
331  struct
332  {
343  } background_actions;
344 
345  // Items
346  struct
347  {
348  } active_items;
349 
350  // Pets
352  {
353  propagate_const<pet_t*> shadowfiend;
354  propagate_const<pet_t*> mindbender;
360 
361  priest_pets_t( priest_t& p );
362  } pets;
363 
364  // Options
365  struct
366  {
367  bool autoUnshift = true; // Shift automatically out of stance/form
368  bool fixed_time = true;
369 
370  // Default param to set if you should cast Power Infusion on yourself
371  bool self_power_infusion = true;
372 
373  // Add in easy options to change if you are in range or not
374  bool use_ascended_nova = true;
375  bool use_ascended_eruption = true;
376 
377  // Add in options to override insanity gained
378  // Mindgames gives 20 insanity from the healing and 20 from damage dealt
379  // For most content the healing part won't proc, only default damage dealt
380  bool mindgames_healing_reversal = false;
381  bool mindgames_damage_reversal = true;
382 
383  // Fae Blessings CDR can be given to another player, but you can still get the insanity gen
384  bool self_benevolent_faerie = true;
385 
386  // The amount of allies to assume for Cauterizing Shadows healing
387  int cauterizing_shadows_allies = 3;
388 
389  // Bwonsamdi's Pact Option
390  // Options: "benevolent" or "wrathful"
391  std::string bwonsamdis_pact_mask_type = "benevolent";
392 
393  // Shadow Word: Manipulation expire time
394  // Accepts a range of the amount of time left on Mindgames when the shield expires
395  // Min: 0, Max: 8, Default: 7
396  // Shattered Perception Conduit increase is handled outside of this
397  int shadow_word_manipulation_seconds_remaining = 7;
398 
399  // Pallid Command Allies
400  // Sets number of allies to use as an artificial modifier for Rigor Mortis stacks
401  // For each damage ability the priest will do it will add the amount of stacks equal
402  // to the number of allies
403  // 20m raid this stacks in 1-2s
404  int pallid_command_allies = 50;
405  } options;
406 
407  // Legendaries
408  struct
409  {
410  // Generic
411  item_runeforge_t sephuzs_proclamation;
412  // Shared
413  item_runeforge_t cauterizing_shadows;
414  item_runeforge_t twins_of_the_sun_priestess;
415  item_runeforge_t bwonsamdis_pact;
416  item_runeforge_t shadow_word_manipulation;
417  item_runeforge_t spheres_harmony;
418  item_runeforge_t pallid_command;
419  // Holy
420  item_runeforge_t divine_image; // NYI
421  item_runeforge_t harmonious_apparatus; // NYI
422  // Disc
423  item_runeforge_t kiss_of_death;
424  item_runeforge_t the_penitent_one; // Effect implemented, but not hooked up to PW:Radiance
425  // Shadow
426  item_runeforge_t painbreaker_psalm;
427  item_runeforge_t shadowflame_prism;
428  item_runeforge_t eternal_call_to_the_void;
429  item_runeforge_t talbadars_stratagem;
430  } legendary;
431 
432  // Conduits
433  struct
434  {
435  // Generic Priest
436  conduit_data_t power_unto_others;
437  conduit_data_t translucent_image;
438  // Holy
439  conduit_data_t holy_oration; // NYI
440  // Discipline
441  conduit_data_t swift_penitence; // NYI
442  // Shadow
443  conduit_data_t dissonant_echoes;
444  conduit_data_t mind_devourer;
445  conduit_data_t rabid_shadows;
446  conduit_data_t haunting_apparitions;
447  // Covenant
448  conduit_data_t courageous_ascension;
449  conduit_data_t festering_transfusion;
450  conduit_data_t fae_fermata;
451  conduit_data_t shattered_perceptions;
452  } conduits;
453 
454  // Covenants
455  struct
456  {
457  // Night Fae
458  const spell_data_t* fae_guardians;
459  // Necrolord
460  const spell_data_t* unholy_nova;
461  // Venthyr
462  const spell_data_t* mindgames;
463  const spell_data_t* mindgames_healing_reversal;
464  const spell_data_t* mindgames_damage_reversal;
465  // Kyrian
466  const spell_data_t* ascended_blast;
467  const spell_data_t* ascended_blast_heal;
468  const spell_data_t* ascended_eruption;
469  const spell_data_t* ascended_nova;
470  const spell_data_t* boon_of_the_ascended;
471  } covenant;
472 
473  priest_t( sim_t* sim, util::string_view name, race_e r );
474 
475  // player_t overrides
476  void init_base_stats() override;
477  void init_resources( bool force ) override;
478  void init_spells() override;
479  void create_buffs() override;
480  void init_scaling() override;
481  void init_finished() override;
482  void init_background_actions() override;
483  void reset() override;
484  void create_options() override;
485  std::string create_profile( save_e ) override;
486  action_t* create_action( util::string_view name, util::string_view options ) override;
487  pet_t* create_pet( util::string_view name, util::string_view type = {} ) override;
488  void create_pets() override;
489  void copy_from( player_t* source ) override;
490  resource_e primary_resource() const override
491  {
492  return RESOURCE_MANA;
493  }
494  role_e primary_role() const override;
495  stat_e convert_hybrid_stat( stat_e s ) const override;
496  void assess_damage( school_e school, result_amount_type dtype, action_state_t* s ) override;
497  double composite_melee_haste() const override;
498  double composite_spell_haste() const override;
499  double composite_spell_crit_chance() const override;
500  double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override;
501  double composite_player_absorb_multiplier( const action_state_t* s ) const override;
502  double composite_player_heal_multiplier( const action_state_t* s ) const override;
503  double composite_player_target_multiplier( player_t* t, school_e school ) const override;
504  double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const override;
505  double matching_gear_multiplier( attribute_e attr ) const override;
506  void target_mitigation( school_e, result_amount_type, action_state_t* ) override;
507  void init_action_list() override;
508  void combat_begin() override;
509  void init_rng() override;
510  const priest_td_t* find_target_data( const player_t* target ) const override;
511  priest_td_t* get_target_data( player_t* target ) const override;
512  std::unique_ptr<expr_t> create_expression( util::string_view expression_str ) override;
513  std::unique_ptr<expr_t> create_pet_expression( util::string_view expression_str,
514  util::span<util::string_view> splits );
515  void arise() override;
516  void do_dynamic_regen( bool ) override;
517  void apply_affecting_auras( action_t& ) override;
518  void invalidate_cache( cache_e ) override;
519 
520 private:
521  void create_cooldowns();
522  void create_gains();
523  void create_procs();
524  void create_benefits();
525  void create_buffs_shadow();
526  void init_rng_shadow();
527  void init_spells_shadow();
528  std::unique_ptr<expr_t> create_expression_shadow( util::string_view name_str );
529  action_t* create_action_shadow( util::string_view name, util::string_view options_str );
530 
531  void create_buffs_discipline();
532  void init_spells_discipline();
533  void init_rng_discipline();
534 
535  void init_background_actions_shadow();
536  std::unique_ptr<expr_t> create_expression_discipline( action_t* a, const util::string_view name_str );
537  action_t* create_action_discipline( util::string_view name, util::string_view options_str );
538 
539  void create_buffs_holy();
540  void init_spells_holy();
541  void init_rng_holy();
542  void generate_apl_holy();
543  expr_t* create_expression_holy( action_t* a, util::string_view name_str );
544  action_t* create_action_holy( util::string_view name, util::string_view options_str );
545  target_specific_t<priest_td_t> _target_data;
546 
547 public:
548  void generate_insanity( double num_amount, gain_t* g, action_t* action );
549  void adjust_holy_word_serenity_cooldown();
550  double tick_damage_over_time( timespan_t duration, const dot_t* dot ) const;
551  void trigger_shadowflame_prism( player_t* target );
552  void trigger_eternal_call_to_the_void( action_state_t* );
553  void trigger_shadowy_apparitions( action_state_t* );
554  void trigger_psychic_link( action_state_t* );
555  void trigger_shadow_weaving( action_state_t* );
556  bool hungering_void_active( player_t* target ) const;
557  void remove_hungering_void( player_t* target );
558  void refresh_talbadars_buff( action_state_t* s );
559  void trigger_wrathful_faerie();
560  void trigger_wrathful_faerie_fermata();
561  void remove_wrathful_faerie();
562  void remove_wrathful_faerie_fermata();
563  int shadow_weaving_active_dots( const player_t* target, const unsigned int spell_id ) const;
564  double shadow_weaving_multiplier( const player_t* target, const unsigned int spell_id ) const;
565  void trigger_unholy_transfusion_healing();
566  event_t* t28_4pc_summon_event;
567  timespan_t t28_4pc_summon_duration;
568 
569  std::string default_potion() const override;
570  std::string default_flask() const override;
571  std::string default_food() const override;
572  std::string default_rune() const override;
573  std::string default_temporary_enchant() const override;
574 };
575 
576 namespace actions
577 {
586 template <typename Base>
587 struct priest_action_t : public Base
588 {
589  struct
590  {
591  bool voidform_da;
592  bool voidform_ta;
593  bool shadowform_da;
594  bool shadowform_ta;
595  bool twist_of_fate_da;
596  bool twist_of_fate_ta;
597  bool shadow_covenant_da;
598  bool shadow_covenant_ta;
599  bool schism;
600  } affected_by;
601 
602  double vf_da_multiplier;
603  double vf_ta_multiplier;
604 
605 public:
606  priest_action_t( util::string_view name, priest_t& p, const spell_data_t* s = spell_data_t::nil() )
607  : ab( name, &p, s ), affected_by(), vf_da_multiplier( 1 ), vf_ta_multiplier( 1 )
608  {
609  init_affected_by();
610  ab::may_crit = true;
611  ab::tick_may_crit = true;
612  ab::weapon_multiplier = 0.0;
613 
614  if ( p.talents.sins_of_the_many->ok() )
615  {
616  ab::base_dd_multiplier *= 1.0 + p.talents.sins_of_the_many->effectN( 1 ).percent();
617  ab::base_td_multiplier *= 1.0 + p.talents.sins_of_the_many->effectN( 1 ).percent();
618  }
619 
620  if ( affected_by.voidform_da )
621  {
622  vf_da_multiplier = 1 + priest().buffs.voidform->data().effectN( 1 ).percent();
623  }
624  if ( affected_by.voidform_ta )
625  {
626  vf_ta_multiplier = 1 + priest().buffs.voidform->data().effectN( 2 ).percent();
627  }
628  }
629 
634  {
635  struct affect_init_t
636  {
637  const spelleffect_data_t& effect;
638  bool& affects;
639  } affects[] = { { priest().buffs.voidform->data().effectN( 1 ), affected_by.voidform_da },
640  { priest().buffs.voidform->data().effectN( 2 ), affected_by.voidform_ta },
641  { priest().buffs.shadowform->data().effectN( 1 ), affected_by.shadowform_da },
642  { priest().buffs.shadowform->data().effectN( 4 ), affected_by.shadowform_ta },
643  { priest().buffs.twist_of_fate->data().effectN( 1 ), affected_by.twist_of_fate_da },
644  { priest().buffs.twist_of_fate->data().effectN( 2 ), affected_by.twist_of_fate_ta },
645  { priest().buffs.shadow_covenant->data().effectN( 2 ), affected_by.shadow_covenant_da },
646  { priest().buffs.shadow_covenant->data().effectN( 3 ), affected_by.shadow_covenant_ta },
647  { priest().talents.schism->effectN( 2 ), affected_by.schism } };
648 
649  for ( const auto& a : affects )
650  {
651  a.affects = base_t::data().affected_by( a.effect );
652  if ( a.affects && ab::sim->debug )
653  {
654  ab::sim->print_debug( "{} {} ({}) affected by {} (idx={}).", *ab::player, *this, ab::data().id(),
655  a.effect.spell()->name_cstr(), a.effect.spell_effect_num() + 1 );
656  }
657  }
658  }
659 
660  priest_td_t& get_td( player_t* t )
661  {
662  return *( priest().get_target_data( t ) );
663  }
664 
665  const priest_td_t* find_td( const player_t* t ) const
666  {
667  return priest().find_target_data( t );
668  }
669 
670  void trigger_power_of_the_dark_side()
671  {
672  int stack = priest().buffs.power_of_the_dark_side->check();
673  if ( priest().buffs.power_of_the_dark_side->trigger() )
674  {
675  if ( priest().buffs.power_of_the_dark_side->check() == stack )
676  {
677  priest().procs.power_of_the_dark_side_overflow->occur();
678  }
679  else
680  {
681  priest().procs.power_of_the_dark_side->occur();
682  }
683  }
684  }
685 
686  double cost() const override
687  {
688  double c = ab::cost();
689 
690  return c;
691  }
692 
693  double composite_target_multiplier( player_t* target ) const override
694  {
695  double m = ab::composite_target_multiplier( target );
696 
697  auto target_data = find_td( target );
698  if ( target_data && target_data->buffs.schism->check() )
699  {
700  m *= 1.0 + target_data->buffs.schism->data().effectN( 2 ).percent();
701  }
702 
703  return m;
704  }
705 
706  double action_da_multiplier() const override
707  {
708  double m = ab::action_da_multiplier();
709 
710  if ( affected_by.voidform_da && priest().buffs.voidform->check() )
711  {
712  m *= vf_da_multiplier;
713  }
714  if ( affected_by.shadowform_da && priest().buffs.shadowform->check() )
715  {
716  m *= 1.0 + priest().buffs.shadowform->data().effectN( 1 ).percent();
717  }
718  if ( affected_by.twist_of_fate_da && priest().buffs.twist_of_fate->check() )
719  {
720  m *= 1.0 + priest().buffs.twist_of_fate->data().effectN( 1 ).percent();
721  }
722  if ( affected_by.shadow_covenant_da && priest().buffs.shadow_covenant->check() )
723  {
724  m *= 1 + priest().buffs.shadow_covenant->data().effectN( 2 ).percent();
725  }
726  return m;
727  }
728 
729  double action_ta_multiplier() const override
730  {
731  double m = ab::action_ta_multiplier();
732 
733  if ( affected_by.voidform_ta && priest().buffs.voidform->check() )
734  {
735  m *= vf_ta_multiplier;
736  }
737  if ( affected_by.shadowform_ta && priest().buffs.shadowform->check() )
738  {
739  m *= 1.0 + priest().buffs.shadowform->data().effectN( 4 ).percent();
740  }
741  if ( affected_by.twist_of_fate_ta && priest().buffs.twist_of_fate->check() )
742  {
743  m *= 1.0 + priest().buffs.twist_of_fate->data().effectN( 2 ).percent();
744  }
745  if ( affected_by.shadow_covenant_ta && priest().buffs.shadow_covenant->check() )
746  {
747  m *= 1 + priest().buffs.shadow_covenant->data().effectN( 3 ).percent();
748  }
749  return m;
750  }
751 
752  void gain_energize_resource( resource_e resource_type, double amount, gain_t* gain ) override
753  {
754  if ( resource_type == RESOURCE_INSANITY )
755  {
756  priest().generate_insanity( amount, gain, this );
757  }
758  else
759  {
760  ab::gain_energize_resource( resource_type, amount, gain );
761  }
762  }
763 
764 protected:
765  priest_t& priest()
766  {
767  return *debug_cast<priest_t*>( ab::player );
768  }
769  const priest_t& priest() const
770  {
771  return *debug_cast<priest_t*>( ab::player );
772  }
773 
774  // typedef for priest_action_t<action_base_t>
775  using base_t = priest_action_t;
776 
777 private:
778  // typedef for the templated action type, eg. spell_t, attack_t, heal_t
779  using ab = Base;
780 }; // namespace actions
781 
782 struct priest_absorb_t : public priest_action_t<absorb_t>
783 {
784 public:
785  priest_absorb_t( util::string_view name, priest_t& player, const spell_data_t* s = spell_data_t::nil() )
786  : base_t( name, player, s )
787  {
788  may_crit = true;
789  tick_may_crit = false;
790  may_miss = false;
791  }
792 };
793 
794 struct priest_heal_t : public priest_action_t<heal_t>
795 {
796  priest_heal_t( util::string_view name, priest_t& player, const spell_data_t* s = spell_data_t::nil() )
797  : base_t( name, player, s )
798  {
799  }
800 
801  void impact( action_state_t* s ) override
802  {
803  double save_health_percentage = s->target->health_percentage();
804 
805  base_t::impact( s );
806 
807  if ( s->result_amount > 0 )
808  {
809  if ( priest().specialization() != PRIEST_SHADOW && priest().talents.twist_of_fate->ok() &&
810  ( save_health_percentage < priest().talents.twist_of_fate->effectN( 1 ).base_value() ) )
811  {
812  priest().buffs.twist_of_fate->trigger();
813  }
814  }
815  }
816 };
817 
818 struct priest_spell_t : public priest_action_t<spell_t>
819 {
820  bool affected_by_shadow_weaving;
821  bool ignores_automatic_mastery;
822  unsigned int mind_sear_id;
823 
824  priest_spell_t( util::string_view name, priest_t& player, const spell_data_t* s = spell_data_t::nil() )
825  : base_t( name, player, s ),
826  affected_by_shadow_weaving( false ),
827  ignores_automatic_mastery( false ),
828  mind_sear_id( priest().find_class_spell( "Mind Sear" )->effectN( 1 ).trigger()->id() )
829  {
830  weapon_multiplier = 0.0;
831  }
832 
833  bool usable_moving() const override
834  {
835  if ( priest().buffs.surrender_to_madness->check() )
836  {
837  return true;
838  }
839 
840  return base_t::usable_moving();
841  }
842 
843  bool ready() override
844  {
845  if ( priest().specialization() == PRIEST_SHADOW && priest().talents.surrender_to_madness->ok() )
846  {
847  if ( priest().buffs.surrender_to_madness_death->check() )
848  {
849  return false;
850  }
851  }
852 
853  if ( priest().specialization() == PRIEST_DISCIPLINE && priest().talents.shadow_covenant->ok() )
854  {
855  if ( school == SCHOOL_HOLY && priest().buffs.shadow_covenant->check() )
856  {
857  return false;
858  }
859  }
860 
861  return action_t::ready();
862  }
863 
864  void impact( action_state_t* s ) override
865  {
866  double save_health_percentage = s->target->health_percentage();
867 
868  base_t::impact( s );
869 
870  if ( result_is_hit( s->result ) )
871  {
872  if ( priest().specialization() == PRIEST_SHADOW && priest().talents.twist_of_fate->ok() &&
873  ( save_health_percentage < priest().talents.twist_of_fate->effectN( 1 ).base_value() ) )
874  {
875  priest().buffs.twist_of_fate->trigger();
876  }
877 
878  if ( s->result_amount > 0 )
879  {
880  const priest_td_t* td = find_td( s->target );
881  // Wrathful Faerie works for any direct attacks by anyone, bugging this for now
882  // TODO: maybe rework this to just be a buff that gives insanity every tick instead?
883  // https://github.com/SimCMinMax/WoW-BugTracker/issues/777
884  if ( s->result_type == result_amount_type::DMG_DIRECT || priest().bugs )
885  {
886  if ( td && td->buffs.wrathful_faerie->check() )
887  {
888  priest().trigger_wrathful_faerie();
889  }
890  if ( td && td->buffs.wrathful_faerie_fermata->check() )
891  {
892  priest().trigger_wrathful_faerie_fermata();
893  }
894  }
895 
896  if ( td && td->dots.unholy_transfusion->is_ticking() )
897  {
898  priest().trigger_unholy_transfusion_healing();
899 
900  if ( priest().legendary.pallid_command->ok() && s->result_type == result_amount_type::DMG_DIRECT )
901  {
902  // BUG: https://github.com/SimCMinMax/WoW-BugTracker/issues/856
903  if ( priest().options.pallid_command_allies > 0 )
904  {
905  priest().buffs.rigor_mortis->trigger( priest().options.pallid_command_allies );
906  }
907  }
908  }
909  }
910  }
911  }
912 
913  double composite_target_da_multiplier( player_t* t ) const override
914  {
916 
917  if ( affected_by_shadow_weaving )
918  {
919  // Guarding against Unfurling Darkness, it does not get the mastery benefit
920  unsigned int spell_id = id;
921  if ( ignores_automatic_mastery )
922  {
923  sim->print_debug( "{} {} cast does not benefit from Mastery automatically.", *player, name_str );
924  spell_id = 1;
925  }
926 
927  tdm *= priest().shadow_weaving_multiplier( t, spell_id );
928  }
929 
930  if ( priest().hungering_void_active( t ) )
931  {
932  tdm *= ( 1 + priest().talents.hungering_void_buff->effectN( 1 ).percent() );
933  }
934 
935  return tdm;
936  }
937 
938  double composite_target_ta_multiplier( player_t* t ) const override
939  {
941 
942  if ( affected_by_shadow_weaving )
943  {
944  ttm *= priest().shadow_weaving_multiplier( t, id );
945  }
946 
947  if ( priest().hungering_void_active( t ) )
948  {
949  ttm *= ( 1 + priest().talents.hungering_void_buff->effectN( 1 ).percent() );
950  }
951 
952  return ttm;
953  }
954 
955  void trigger_dark_thoughts( const player_t* target, proc_t* proc, action_state_t* s )
956  {
957  auto action_id = s->action->id;
958 
959  if ( !priest().specs.dark_thoughts->ok() )
960  return;
961  const priest_td_t* td = find_td( target );
962  if ( !td )
963  return;
964  const dot_t* swp = td->dots.shadow_word_pain;
965  const dot_t* vt = td->dots.vampiric_touch;
966  const dot_t* dp = td->dots.devouring_plague;
967 
968  int dots = swp->is_ticking() + vt->is_ticking() + dp->is_ticking();
969  double dark_thoughts_proc_percent = priest().specs.dark_thoughts->effectN( 1 ).percent();
970 
971  // Currently Mind-Sear has 1/3 the proc rate of Mind Flay 3% -> 1%
972  // https://github.com/SimCMinMax/WoW-BugTracker/issues/699
973  if ( priest().bugs && action_id == mind_sear_id )
974  {
975  dark_thoughts_proc_percent /= 3;
976  }
977 
978  if ( rng().roll( dark_thoughts_proc_percent * swp->is_ticking() ) ||
979  rng().roll( dark_thoughts_proc_percent * vt->is_ticking() ) ||
980  rng().roll( dark_thoughts_proc_percent * dp->is_ticking() ) )
981  {
982  if ( sim->debug )
983  {
984  sim->print_debug( "{} activated Dark Thoughts using {} with {} chance with {} dots", *player, *this,
985  dark_thoughts_proc_percent * dots, dots );
986  }
987  priest().buffs.dark_thought->trigger();
988  proc->occur();
989  }
990  }
991 
992  void assess_damage( result_amount_type type, action_state_t* s ) override
993  {
994  base_t::assess_damage( type, s );
995 
996  if ( aoe == 0 && result_is_hit( s->result ) && priest().buffs.vampiric_embrace->up() )
997  trigger_vampiric_embrace( s );
998  }
999 
1000  /* Based on previous implementation ( pets don't count but get full heal )
1001  * and https://www.wowhead.com/spell=15286#comments:id=1796701
1002  * Last checked 2013-05-25
1003  */
1004  void trigger_vampiric_embrace( action_state_t* s )
1005  {
1006  double amount = s->result_amount;
1007  amount *= priest().buffs.vampiric_embrace->data().effectN( 1 ).percent(); // FIXME additive or multiplicative?
1008 
1009  for ( player_t* ally : sim->player_no_pet_list )
1010  {
1011  if ( ally->current.sleeping )
1012  {
1013  continue;
1014  }
1015  ally->resource_gain( RESOURCE_HEALTH, amount, ally->gains.vampiric_embrace );
1016 
1017  for ( pet_t* pet : ally->pet_list )
1018  {
1019  pet->resource_gain( RESOURCE_HEALTH, amount, pet->gains.vampiric_embrace );
1020  }
1021  }
1022  }
1023 };
1024 
1025 } // namespace actions
1026 
1027 namespace buffs
1028 {
1037 template <typename Base = buff_t>
1038 struct priest_buff_t : public Base
1039 {
1040 public:
1041  using base_t = priest_buff_t; // typedef for priest_buff_t<buff_base_t>
1042 
1043  priest_buff_t( priest_td_t& td, util::string_view name, const spell_data_t* s = spell_data_t::nil(),
1044  const item_t* item = nullptr )
1045  : Base( td, name, s, item )
1046  {
1047  }
1048 
1049  priest_buff_t( priest_t& p, util::string_view name, const spell_data_t* s = spell_data_t::nil(),
1050  const item_t* item = nullptr )
1051  : Base( &p, name, s, item )
1052  {
1053  }
1054 
1055 protected:
1056  priest_t& priest()
1057  {
1058  return *debug_cast<priest_t*>( Base::source );
1059  }
1060  const priest_t& priest() const
1061  {
1062  return *debug_cast<priest_t*>( Base::source );
1063  }
1064 };
1065 } // namespace buffs
1066 
1067 } // namespace priestspace
Definition: sc_priest.hpp:54
This is a template for common code between priest buffs.
Definition: sc_priest.hpp:1038
bool ready() override
Is the ability ready based on spell characteristics.
Definition: sc_priest.hpp:843
Priest class definition Derived from player_t.
Definition: sc_priest.hpp:82
Definition: sc_demon_hunter.cpp:42
Definition: sc_death_knight.cpp:45
Definition: gain.hpp:17
Definition: sc_priest.hpp:278
Definition: target_specific.hpp:20
Definition: spell_data.hpp:398
Definition: sc_priest.hpp:794
Priest target data Contains target specific things.
Definition: sc_priest.hpp:43
virtual double composite_target_ta_multiplier(player_t *target) const
Tick amount multiplier due to debuffs on the target.
Definition: action.hpp:872
double composite_target_da_multiplier(player_t *t) const override
Direct amount multiplier due to debuffs on the target.
Definition: sc_priest.hpp:913
Definition: action.hpp:47
void init_affected_by()
Initialize all affected_by members and print out debug info.
Definition: sc_priest.hpp:633
Definition: unique_gear.cpp:62
Definition: generic.hpp:567
Definition: sc_priest.hpp:46
Definition: action_state.hpp:20
Definition: runeforge_data.hpp:20
Definition: sc_priest.hpp:818
Definition: covenant.cpp:108
Definition: sc_priest.cpp:16
Definition: sc_shaman.cpp:2212
Definition: sc_priest.hpp:351
Definition: proc.hpp:18
Definition: item.hpp:60
double composite_target_ta_multiplier(player_t *t) const override
Tick amount multiplier due to debuffs on the target.
Definition: sc_priest.hpp:938
virtual double composite_target_da_multiplier(player_t *target) const
Direct amount multiplier due to debuffs on the target.
Definition: action.hpp:868
Class for representing InGame time.
Definition: timespan.hpp:37
Definition: sc_priest.hpp:782
Definition: player.hpp:109
Definition: pet.hpp:14
Definition: dot.hpp:27
Definition: sc_demon_hunter.cpp:1887
Action expression.
Definition: expressions.hpp:79
Definition: covenant.hpp:34
Definition: spell_data.hpp:145
Priest action base class.
Definition: sc_priest.hpp:587
Definition: spell_base.hpp:11
unsigned id
Spell id if available, 0 otherwise.
Definition: action.hpp:80
Definition: heal.hpp:12
Random number generation.
Definition: action.hpp:37
A wrapper object to enable dynamic pet spawns in simulationcraft.
Definition: pet_spawner.hpp:56
Definition: sc_demon_hunter.cpp:44
Definition: event.hpp:45
Simulation engine.
Definition: sim.hpp:61
Definition: actor_target_data.hpp:15
virtual bool ready()
Is the ability ready based on spell characteristics.
Definition: action.cpp:2362