wowlab_engine_content/hooks/feral_druid/
config.rs1use wowlab_engine_combat::{AccumulatingImpactProc, ImpactActorFilter, ImpactProc};
2use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
3use wowlab_types::{
4 constants::{HUNDRED, THOUSAND},
5};
6
7use crate::generated::specs::feral_druid::{EFFECT, SET_BONUS, TALENT};
8
9use super::hooks::{
10 apex_predator_fire, bloodseeker_vines_fire, builder_filter, primal_fury_fire, rip_filter,
11 rip_or_rake_filter, thriving_growth_contribution,
12};
13
14#[derive(Clone, Copy, Debug)]
15pub(super) enum ConvokeCast {
16 Exceptional,
17 Main,
18 Offspec,
19 Spec,
20}
21
22#[derive(Debug, Default)]
23pub(super) struct FeralRuntime {
24 pub(super) convoke_casts: Vec<ConvokeCast>,
25 pub(super) convoke_exceptional_deck: Vec<bool>,
26}
27
28crate::hooks::define_spec_config! {
29 pub(super) struct FeralConfig {
30 ashamanes_guidance: bool { provenance: "Ashamane's Guidance 391548 selection; learned passive 391538 is folded generically into Convoke's action count, channel duration, and cooldown.", gate: params.talent_picked(TALENT::ASHAMANES_GUIDANCE), source: true, transform: |value| value, },
31 soul_of_the_forest: bool { provenance: "Soul of the Forest (158476): finishers refund 2 energy per CP (e1).", gate: params.talent_picked(TALENT::SOUL_OF_THE_FOREST), source: true, transform: |value| value, },
32 panthers_guile: bool { provenance: "Panther's Guile (1280316): Shred/LI can fill combo points.", gate: params.talent_picked(TALENT::PANTHERS_GUILE), source: true, transform: |value| value, },
33 tigers_tenacity: bool { provenance: "Tiger's Tenacity (391872): Tiger's Fury readies combo refunds.", gate: params.talent_picked(TALENT::TIGERS_TENACITY), source: true, transform: |value| value, },
34 sabertooth: bool { provenance: "Sabertooth (202031): Ferocious Bite applies 391722.", gate: params.talent_picked(TALENT::SABERTOOTH), source: true, transform: |value| value, },
35 flash_of_clarity: bool { provenance: "MID1 Feral 2pc (1264812): Clearcasting procs grant Flash of Clarity 1272262 (`sc_druid.cpp:9708`).", gate: params.set_bonus_auras.contains(&SET_BONUS::MID1_FERAL_2PC), source: true, transform: |value| value, },
36 omen_of_clarity: bool { provenance: "Omen of Clarity 16864 selection gates its white-melee proc (`sc_druid.cpp:9670`).", gate: params.talent_picked(TALENT::OMEN_OF_CLARITY), source: true, transform: |value| value, },
37 moment_of_clarity_proc_bonus: f64 { provenance: "Moment of Clarity 236068 e2 increases Omen frequency (`sc_druid.cpp:9673`).", gate: params.talent_picked(TALENT::MOMENT_OF_CLARITY), source: params.game_data.effect_base_points(EFFECT::MOMENT_OF_CLARITY_PROC_BONUS), transform: |value| value / HUNDRED, },
38 lycaras_teachings: bool { provenance: "Lycara's Teachings (378988): Cat Form carries the 378990 critical-strike variant (`sc_druid.cpp:3592`).", gate: params.talent_picked(TALENT::LYCARAS_TEACHINGS), source: true, transform: |value| value, },
39 strategic_infusion: bool { provenance: "Strategic Infusion (439890): Tiger's Fury readies 439891 (`sc_druid.cpp:4806`).", gate: params.talent_picked(TALENT::STRATEGIC_INFUSION), source: true, transform: |value| value, },
40 sudden_ambush_chance: f64 { provenance: "Sudden Ambush 384667 e1 is the per-combo-point chance in percent points (`sc_druid.cpp:11166`).", gate: params.talent_picked(TALENT::SUDDEN_AMBUSH), source: params.game_data.effect_base_points(EFFECT::SUDDEN_AMBUSH_CHANCE), transform: |value| value / HUNDRED, },
41 apex_proc_chance: f64 { provenance: "Apex Predator's Craving 391881 e1 stores chance in tenths of a percent.", gate: params.talent_picked(TALENT::APEX_PREDATORS_CRAVING), source: params.game_data.effect_base_points(EFFECT::APEX_PREDATOR_CHANCE), transform: |value| value / THOUSAND, },
42 thriving_rake_contribution: f64 { provenance: "Thriving Growth 439528 e2 contributes a randomized amount on each Rake tick.", gate: params.talent_picked(TALENT::THRIVING_GROWTH), source: params.game_data.effect_base_points(EFFECT::THRIVING_GROWTH_RAKE), transform: |value| value, },
43 thriving_rip_contribution: f64 { provenance: "Thriving Growth 439528 e1 contributes a randomized amount on each Rip tick.", gate: params.talent_picked(TALENT::THRIVING_GROWTH), source: params.game_data.effect_base_points(EFFECT::THRIVING_GROWTH_RIP), transform: |value| value, },
44 }
45 accessor pub(super) fn feral_config(ctx);
46 register pub(super) fn register_feral(built, params) -> ();
47 prepare {}
48 auras {}
49 wiring {
50 { provenance: "Primal Fury critical builder proc.", gate: params.talent_picked(TALENT::PRIMAL_FURY), apply: {
51 built.register_impact_proc(ImpactProc::new(primal_fury_fire).with_spell_filter(builder_filter).skip_periodic().crit_only());
52 } },
53 { provenance: "Apex Predator's Craving procs from Rip periodic damage in the single-target repair lens.", gate: cfg.apex_proc_chance > 0.0, apply: {
54 built.register_impact_proc(ImpactProc::new(apex_predator_fire).with_chance(cfg.apex_proc_chance).with_spell_filter(rip_filter).periodic_only());
55 } },
56 { provenance: "Thriving Growth accumulates randomized Rip/Rake tick contributions until Bloodseeker Vines triggers.", gate: cfg.thriving_rip_contribution > 0.0 || cfg.thriving_rake_contribution > 0.0, apply: {
57 built.register_accumulating_impact_proc(AccumulatingImpactProc { driver: wowlab_engine_combat::ProcDriver::default(), actor_filter: ImpactActorFilter::Player, threshold: 1000.0, accumulator: f64::NAN, contribution: thriving_growth_contribution, fire: bloodseeker_vines_fire, spell_filter: Some(rip_or_rake_filter), periodic_only: true, skip_periodic: false, crit_only: false });
58 } },
59 }
60 finish |cfg| {
61 built.state.set_spec_config(cfg);
62 built.state.set_spec_runtime(FeralRuntime::default());
63 }
64}