wowlab_engine_content/hooks/shadow_priest/
config.rs1use wowlab_engine_combat::{BuffEffect, ImpactProc, LocalThresholdIdx, ThresholdTracker};
2use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
3use wowlab_types::{constants::HUNDRED};
4
5use crate::{
6 generated::specs::shadow_priest::{AURA_INSIDIOUS_IRE, EFFECT, SPELL, TALENT},
7 hooks::gated,
8};
9
10use super::hooks::{shadowy_insight_fire, swp_filter, tormented_spirits_fire};
11
12const TORMENTED_SPIRITS_CHANCE: f64 = 0.13;
13const SHADOWY_INSIGHT_INCREMENT_MAX: f64 = 0.08;
15
16#[rustfmt::skip]
17static INSIDIOUS_IRE_SPELLS: [u32; 4] = [
18 SPELL::MIND_BLAST,
19 EFFECT::VOID_BLAST_DAMAGE.0,
20 SPELL::MIND_FLAY,
21 SPELL::VOID_TORRENT,
22];
23
24crate::hooks::define_spec_config! {
25 pub(super) struct ShadowConfig {
27 void_apparition_chance: f64 { provenance: "Void Apparitions 1264104 e2 chance multiplied by selected ranks.", gate: params.talent_ranks(TALENT::VOID_APPARITIONS_2) > 0, source: data.effect_base_points(EFFECT::VOID_APPARITIONS_CHANCE) * f64::from(params.talent_ranks(TALENT::VOID_APPARITIONS_2)), transform: |value| value / HUNDRED },
28 auspicious_insanity: f64 { provenance: "Auspicious Spirits 155271 e2 insanity per apparition.", gate: params.talent_picked(TALENT::AUSPICIOUS_SPIRITS), source: data.effect_base_points(EFFECT::AUSPICIOUS_SPIRITS_INSANITY), transform: |value| value / HUNDRED },
29 mind_flay_tick_insanity: f64 { provenance: "Mind Flay 15407 e3 insanity, scaled by Surge of Insanity 391399 e2.", gate: true, source: data.effect_base_points(EFFECT::MIND_FLAY_TICK_INSANITY) / HUNDRED, transform: |value| value * if params.talent_picked(TALENT::SURGE_OF_INSANITY) { 1.0 + data.effect_base_points(EFFECT::SURGE_OF_INSANITY_GEN) / HUNDRED } else { 1.0 } },
30 collapsing_void_pct: f64 { provenance: "Collapsing Void 448403 e3 damage bonus per Madness stack.", gate: params.talent_picked(TALENT::COLLAPSING_VOID), source: data.effect_base_points(EFFECT::COLLAPSING_VOID_PCT), transform: |value| value / HUNDRED },
31 shadowy_apparitions: bool { provenance: "Shadowy Apparitions enables apparition volleys.", gate: params.talent_picked(TALENT::SHADOWY_APPARITIONS), source: true, transform: |value| value },
32 void_blast: bool { provenance: "Void Blast enables Mind Blast replacement during Entropic Rift.", gate: params.talent_picked(TALENT::VOID_BLAST), source: true, transform: |value| value },
33 voidheart: bool { provenance: "Voidheart enables its Entropic Rift window aura.", gate: params.talent_picked(TALENT::VOIDHEART), source: true, transform: |value| value },
34 darkening_horizon: bool { provenance: "Darkening Horizon enables Void Blast rift extensions.", gate: params.talent_picked(TALENT::DARKENING_HORIZON), source: true, transform: |value| value },
35 insidious_ire: bool { provenance: "Insidious Ire enables the three-DoT damage window.", gate: params.talent_picked(TALENT::INSIDIOUS_IRE), source: true, transform: |value| value },
36 shattered_psyche: bool { provenance: "Shattered Psyche 391090 e2 stacks buff 391092 on Mind Flay ticks and Mind Blast expires it (`sc_priest_shadow.cpp:77`, `sc_priest.cpp:148`).", gate: params.talent_picked(TALENT::SHATTERED_PSYCHE), source: true, transform: |value| value },
37 shadowy_insight_threshold: Option<LocalThresholdIdx> { provenance: "Shadowy Insight 375888 accumulated-threshold tracker slot (`SimC` `threshold_rng`, `sc_priest_shadow.cpp:2180`).", gate: true, source: shadowy_insight_threshold, transform: |value| value },
38 }
39 accessor pub(super) fn shadow_config(ctx);
40 register pub(super) fn register_shadow(built, params) -> ();
41 prepare {
42 let data = ¶ms.game_data;
43 let shadowy_insight_threshold = gated(params.talent_picked(TALENT::SHADOWY_INSIGHT), || {
44 let idx = built
45 .register_threshold_tracker(ThresholdTracker {
46 increment_max: SHADOWY_INSIGHT_INCREMENT_MAX,
47 accumulated: f64::NAN,
48 roll_over: true,
49 })
50 .expect("Shadow threshold tracker count fits the local-index contract");
51 Some(idx)
52 });
53 }
54 auras {
55 { provenance: "Insidious Ire three-DoT damage window.", gate: params.talent_picked(TALENT::INSIDIOUS_IRE), aura: AURA_INSIDIOUS_IRE, effect: BuffEffect::DamageMultSpells(1.0 + data.effect_base_points(EFFECT::INSIDIOUS_IRE_BONUS) / HUNDRED, &INSIDIOUS_IRE_SPELLS) },
56 }
57 wiring {
58 { provenance: "Tormented Spirits apparition proc.", gate: params.talent_picked(TALENT::TORMENTED_SPIRITS) && params.talent_picked(TALENT::SHADOWY_APPARITIONS), apply: {
59 built.register_impact_proc(ImpactProc::new(tormented_spirits_fire).with_chance(TORMENTED_SPIRITS_CHANCE).with_spell_filter(swp_filter).periodic_only());
60 } },
61 { provenance: "Shadowy Insight threshold proc off Shadow Word: Pain ticks (sc_priest_shadow.cpp:640).", gate: params.talent_picked(TALENT::SHADOWY_INSIGHT), apply: {
62 built.register_impact_proc(ImpactProc::new(shadowy_insight_fire).with_spell_filter(swp_filter).periodic_only());
63 } },
64 }
65 finish |cfg| {
66 built.state.set_spec_config(cfg);
67 }
68}