Skip to main content

wowlab_engine_content/hooks/marksmanship_hunter/
config.rs

1use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
2use wowlab_types::{constants::HUNDRED, sim::SpellIdx};
3
4use crate::{
5    generated::specs::marksmanship_hunter::{EFFECT, HERO, REPORTED_SPELL, TALENT},
6    hooks::gated,
7};
8
9crate::hooks::define_spec_config! {
10/// Talent-gated Marksmanship hook parameters.
11pub(super) struct MarksmanshipConfig {
12    black_arrow: bool { provenance: "Dark Ranger Black Arrow talent 466932.", gate: black_arrow, source: true, transform: |value| value, },
13    ba_coef: f64 { provenance: "Black Arrow 466930 e1 AP coefficient.", gate: true, source: ap(EFFECT::BLACK_ARROW_DAMAGE), transform: |value| value, },
14    ba_lower_pct: f64 { provenance: "Black Arrow 466930 e2 lower health threshold.", gate: true, source: base(EFFECT::BLACK_ARROW_LOWER_PCT), transform: |value| value / HUNDRED, },
15    ba_upper_pct: f64 { provenance: "Black Arrow 466930 e3 upper health threshold.", gate: true, source: base(EFFECT::BLACK_ARROW_UPPER_PCT), transform: |value| value / HUNDRED, },
16    ks_coef: f64 { provenance: "Kill Shot 53351 e1 AP coefficient.", gate: true, source: ap(EFFECT::KILL_SHOT_DAMAGE), transform: |value| value, },
17    ks_threshold: f64 { provenance: "Kill Shot 53351 e2 execute threshold.", gate: true, source: base(EFFECT::KILL_SHOT_THRESHOLD), transform: |value| value / HUNDRED, },
18    kill_shot: bool { provenance: "Kill Shot talent selection.", gate: params.talent_picked(TALENT::KILL_SHOT_TALENT), source: true, transform: |value| value, },
19    deathblow: bool { provenance: "Deathblow is enabled by its talent or Black Arrow.", gate: deathblow_talent || black_arrow, source: true, transform: |value| value, },
20    aimed_deathblow_chance: f64 { provenance: "Deathblow 343248 e1 plus Soul Drinker 469638 e3.", gate: deathblow_talent, source: aimed_chance, transform: |value| value, },
21    rf_deathblow_chance: f64 { provenance: "Deathblow 343248 e2 plus Soul Drinker 469638 e4.", gate: deathblow_talent, source: rf_chance, transform: |value| value, },
22    withering_fire: bool { provenance: "Withering Fire talent 466990.", gate: params.talent_picked(HERO::DARK_RANGER::SPELL::WITHERING_FIRE_TALENT), source: true, transform: |value| value, },
23    wf_count: i32 { provenance: "Withering Fire e3 plus Blighted Quiver e7 volley count.", gate: true, source: wf_count, transform: |value| value, },
24    wf_arrow_coef: f64 { provenance: "Withering Fire arrow AP coefficient.", gate: true, source: ap(EFFECT::WITHERING_FIRE_ARROW), transform: |value| value, },
25    unload: bool { provenance: "Unload 1277548 selection.", gate: params.talent_picked(TALENT::UNLOAD), source: true, transform: |value| value, },
26    no_scope: bool { provenance: "No Scope 473385 selection.", gate: params.talent_picked(TALENT::NO_SCOPE), source: true, transform: |value| value, },
27    precise_shots: bool { provenance: "Precise Shots 260240 selection.", gate: params.talent_picked(TALENT::PRECISE_SHOTS), source: true, transform: |value| value, },
28    arcane_coef: f64 { provenance: "Arcane Shot 185358 e1 AP coefficient.", gate: true, source: ap(EFFECT::ARCANE_SHOT_DAMAGE), transform: |value| value, },
29    bleak_arrows: bool { provenance: "Bleak Arrows 467749 selection.", gate: params.talent_picked(HERO::DARK_RANGER::SPELL::BLEAK_ARROWS_TALENT), source: true, transform: |value| value, },
30    headshot: bool { provenance: "Headshot 471363 selection.", gate: params.talent_picked(TALENT::HEADSHOT), source: true, transform: |value| value, },
31    focused_aim_cdr_ms: u32 { provenance: "Focused Aim 378767 e1 cooldown reduction milliseconds.", gate: params.talent_picked(TALENT::FOCUSED_AIM), source: base(EFFECT::FOCUSED_AIM_CDR_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc, },
32    windrunner_quiver_chance: f64 { provenance: "Windrunner Quiver 473523 e3 retrigger chance.", gate: params.talent_picked(TALENT::WINDRUNNER_QUIVER), source: base(EFFECT::WINDRUNNER_QUIVER_PCT), transform: |value| value / HUNDRED, },
33    spotters_mark_chance: f64 { provenance: "Spotter's Mark 1219616 e1 chance.", gate: true, source: base(EFFECT::SPOTTERS_MARK_CHANCE), transform: |value| value / HUNDRED, },
34    spotters_mark_mult: f64 { provenance: "Spotter's Mark 466872 e1 Aimed Shot multiplier.", gate: true, source: base(EFFECT::SPOTTERS_MARK_PCT), transform: |value| 1.0 + value / HUNDRED, },
35    feathered_frenzy_mult: f64 { provenance: "Feathered Frenzy 470943 e1 mark-chance multiplier.", gate: params.talent_picked(TALENT::FEATHERED_FRENZY), source: base(EFFECT::FEATHERED_FRENZY_PCT), transform: |value| 1.0 + value / HUNDRED, fallback: 1.0, },
36    aimed_coef: f64 { provenance: "Aimed Shot 19434 e1 AP coefficient.", gate: true, source: ap(EFFECT::AIMED_SHOT_DAMAGE), transform: |value| value, },
37    master_marksman: bool { provenance: "Master Marksman 260309 selection.", gate: params.talent_picked(TALENT::MASTER_MARKSMAN), source: true, transform: |value| value, },
38    master_marksman_fraction: f64 { provenance: "Master Marksman banked damage fraction.", gate: true, source: base(EFFECT::MASTER_MARKSMAN_PCT), transform: |value| value / HUNDRED, },
39    corpsecaller: bool { provenance: "Corpsecaller 1264289 selection; RPPM-rolls a Dark Minion on Black Arrow `DoT` ticks (`sc_hunter.cpp:4727`).", gate: params.talent_picked(HERO::DARK_RANGER::SPELL::CORPSECALLER_TALENT), source: true, transform: |value| value, },
40    wailing_dead: bool { provenance: "Wailing Dead 1264290 selection; Trueshot summons a Dark Minion (`sc_hunter.cpp:6967`).", gate: params.talent_picked(HERO::DARK_RANGER::SPELL::WAILING_DEAD_TALENT), source: true, transform: |value| value, },
41    pact_of_the_hollow: bool { provenance: "Pact of the Hollow 1264690 selection; Aimed Shot commands every Dark Minion to fire Blighted Arrow (`sc_hunter.cpp:5682`).", gate: params.talent_picked(HERO::DARK_RANGER::SPELL::PACT_OF_THE_HOLLOW_TALENT), source: true, transform: |value| value, },
42    dark_minion_duration_ms: u32 { provenance: "Dark Minion summon 1264345 duration (`sc_hunter.cpp:4728`).", gate: true, source: dark_minion_duration_ms, transform: |value| value, },
43    dark_minion_shoot_cast_ms: u32 { provenance: "Dark Minion Shoot 1264357 cast time; the pet inherits no haste (`sc_hunter.cpp:1794`).", gate: true, source: dark_minion_shoot_cast_ms, transform: |value| value, },
44}
45accessor pub(super) fn marksmanship_config(ctx);
46register pub(super) fn derive_config(built, params) -> MarksmanshipConfig;
47prepare {
48    let data = &params.game_data;
49    let base = |e: (u32, u8)| data.base_points(SpellIdx::from_raw(e.0), e.1);
50    let ap = |effect| data.effect_ap_coefficient(effect);
51
52    let black_arrow = params.talent_picked(HERO::DARK_RANGER::SPELL::BLACK_ARROW_TALENT);
53    let deathblow_talent = params.talent_picked(TALENT::DEATHBLOW);
54    let soul_drinker = params.talent_picked(HERO::DARK_RANGER::SPELL::SOUL_DRINKER_TALENT);
55
56    let (aimed_chance, rf_chance) = gated(deathblow_talent, || {
57        (
58            base(EFFECT::DEATHBLOW_AIMED_PCT) / HUNDRED
59                + gated(soul_drinker, || base(EFFECT::SOUL_DRINKER_AIMED_PCT) / HUNDRED),
60            base(EFFECT::DEATHBLOW_RF_PCT) / HUNDRED
61                + gated(soul_drinker, || base(EFFECT::SOUL_DRINKER_RF_PCT) / HUNDRED),
62        )
63    });
64
65    let wf_count = wowlab_types::numeric::f64_to_i32_saturating_trunc(base(EFFECT::WITHERING_FIRE_COUNT))
66        + gated(params.talent_picked(HERO::DARK_RANGER::SPELL::BLIGHTED_QUIVER_TALENT), || wowlab_types::numeric::f64_to_i32_saturating_trunc(base(EFFECT::BLIGHTED_QUIVER_EXTRA)));
67
68    let dark_minion_duration_ms = data
69        .aura_duration_ms(SpellIdx::from_raw(HERO::DARK_RANGER::SPELL::DARK_MINION_SUMMON))
70        .unwrap_or_default();
71    let dark_minion_shoot_cast_ms = data
72        .cast_time_ms(SpellIdx::from_raw(REPORTED_SPELL::SHOOT))
73        .unwrap_or_default();
74}
75auras {}
76finish |cfg| {
77    let _ = built;
78    cfg
79}
80}