Skip to main content

wowlab_engine_content/hooks/fire_mage/
config.rs

1use wowlab_engine_combat::{BuffEffect, BuiltCombatSystem, DriverSpellModifier, ImpactProc};
2use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
3use wowlab_engine_ports::HandlerParams;
4use wowlab_types::{
5    constants::{HUNDRED, TEN_THOUSAND},
6};
7
8use crate::generated::specs::fire_mage::{
9    AURA_COMBUSTION, AURA_HYPERTHERMIA, EFFECT, SET_BONUS, TALENT,
10};
11
12use super::hooks::{
13    FIRESTARTER_CRIT_SPELLS, HYPERTHERMIA_CRIT_SPELLS, combustion_dynamic_mult,
14    controlled_destruction_impact, controlled_destruction_spell_filter, fevered_incantation_impact,
15    firestarter_crit_modifier, hot_streak_impact, hot_streak_spell_filter, ignite_fire,
16    ignite_spell_filter, intensifying_flame_fire, is_fireball, is_ignite, pyrotechnics_impact,
17};
18
19#[derive(Clone, Copy, Debug, Default)]
20pub(super) struct FireRuntime {
21    pub(super) glorious_incandescence: bool,
22    pub(super) heating_up_applied_ms: u32,
23    pub(super) hot_streak_pyro_in_flight: bool,
24    pub(super) fired_up_count: usize,
25    pub(super) spellfire_spheres: u8,
26    pub(super) combustion_spheres: u8,
27    pub(super) phoenix_exceptional_remaining: u8,
28}
29
30crate::hooks::define_spec_config! {
31    pub(super) struct FireConfig {
32        burnout_fraction: f64 { provenance: "Burnout effect damage fraction.", gate: params.talent_picked(TALENT::BURNOUT), source: effect_fraction(EFFECT::BURNOUT_PCT), transform: |value| value },
33        firestarter_health_fraction: f64 { provenance: "Firestarter target-health threshold.", gate: params.talent_picked(TALENT::FIRESTARTER), source: params.game_data.effect_base_points(EFFECT::FIRESTARTER_THRESHOLD), transform: |value| value / HUNDRED },
34        intensifying_flame_fraction: f64 { provenance: "Intensifying Flame effect damage fraction.", gate: params.talent_picked(TALENT::INTENSIFYING_FLAME), source: effect_fraction(EFFECT::INTENSIFYING_FLAME_PCT), transform: |value| value },
35        fired_up: bool { provenance: "Fired Up rank one enables accumulated proc rolls.", gate: params.talent_picked(TALENT::FIRED_UP_1), source: true, transform: |value| value },
36        fired_up_chance: f64 { provenance: "Fired Up effect proc chance.", gate: true, source: effect_fraction(EFFECT::FIRED_UP_CHANCE), transform: |value| value },
37        fired_up_fire_blast_cdr_ms: u32 { provenance: "Fired Up effect Fire Blast cooldown reduction milliseconds.", gate: true, source: params.game_data.effect_base_points(EFFECT::FIRED_UP_FIRE_BLAST_CDR_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
38        fired_up_combustion_extend_ms: u32 { provenance: "Fired Up effect Combustion extension milliseconds.", gate: true, source: params.game_data.effect_base_points(EFFECT::FIRED_UP_COMBUSTION_EXTEND_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
39        set4pc_fire_blast_cdr_ms: u32 { provenance: "MID1 Fire four-piece Fire Blast cooldown reduction milliseconds.", gate: params.set_bonus_auras.contains(&SET_BONUS::MID1_FIRE_4PC), source: params.game_data.effect_base_points(EFFECT::SET4PC_FIRE_BLAST_CDR_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
40        combustion_base_pct: f64 { provenance: "Burn It All base Combustion percentage.", gate: params.talent_picked(TALENT::BURN_IT_ALL), source: params.game_data.effect_base_points(EFFECT::BURN_IT_ALL_BASE_PCT), transform: |value| value },
41        combustion_crit_fraction: f64 { provenance: "Burn It All critical-strike contribution fraction.", gate: params.talent_picked(TALENT::BURN_IT_ALL), source: effect_fraction(EFFECT::BURN_IT_ALL_CRIT_PCT), transform: |value| value },
42        combustion_pct_per_sphere: f64 { provenance: "Codex of the Sunstriders Combustion percentage per sphere.", gate: params.talent_picked(TALENT::CODEX_OF_THE_SUNSTRIDERS), source: params.game_data.effect_base_points(EFFECT::CODEX_COMBUSTION_PCT), transform: |value| value },
43        combustion_ms_per_sphere: u32 { provenance: "Savor the Moment Combustion milliseconds per sphere.", gate: params.talent_picked(TALENT::SAVOR_THE_MOMENT), source: params.game_data.effect_base_points(EFFECT::SAVOR_PER_SPHERE_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
44        combustion_extension_cap_ms: u32 { provenance: "Savor the Moment Combustion extension cap milliseconds.", gate: params.talent_picked(TALENT::SAVOR_THE_MOMENT), source: params.game_data.effect_base_points(EFFECT::SAVOR_CAP_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
45    controlled_destruction_fraction: f64 { provenance: "Controlled Destruction hundredth-percent value converted to a fraction.", gate: params.talent_picked(TALENT::CONTROLLED_DESTRUCTION), source: params.game_data.effect_base_points(EFFECT::CONTROLLED_DESTRUCTION_PCT_X100), transform: |value| value / TEN_THOUSAND },
46        invocation_arcane_phoenix: bool { provenance: "Invocation: Arcane Phoenix enables guardian summoning.", gate: params.talent_picked(TALENT::INVOCATION_ARCANE_PHOENIX), source: true, transform: |value| value },
47        memory_of_alar: bool { provenance: "Memory of Al'ar enables its sphere rider.", gate: params.talent_picked(TALENT::MEMORY_OF_ALAR), source: true, transform: |value| value },
48        codex_of_the_sunstriders: bool { provenance: "Codex of the Sunstriders enables sphere scaling.", gate: params.talent_picked(TALENT::CODEX_OF_THE_SUNSTRIDERS), source: true, transform: |value| value },
49        master_of_flame: bool { provenance: "Master of Flame enables its Ignite modifier.", gate: params.talent_picked(TALENT::MASTER_OF_FLAME), source: true, transform: |value| value },
50        pyromaniac: bool { provenance: "Pyromaniac enables its duplicate Pyroblast proc.", gate: params.talent_picked(TALENT::PYROMANIAC), source: true, transform: |value| value },
51    }
52    register fn register_fire_config(built, params) -> ();
53    prepare {
54        let effect_fraction = |effect| params.game_data.effect_percent(effect);
55    }
56    auras {}
57    wiring {
58        { provenance: "Firestarter evaluates the exact damage target's live health.", gate: params.talent_picked(TALENT::FIRESTARTER), apply: {
59            built.register_driver_spell_modifier(DriverSpellModifier::new(
60                TALENT::FIRESTARTER,
61                &FIRESTARTER_CRIT_SPELLS,
62                firestarter_crit_modifier,
63            ));
64        } },
65    }
66    finish |cfg| {
67        built.state.set_spec_config(cfg);
68        built.state.set_spec_runtime(FireRuntime::default());
69    }
70}
71
72pub(super) fn wire_fire(built: &mut BuiltCombatSystem, params: &HandlerParams<'_>) {
73    register_fire_config(built, params);
74    built.set_aura_effect(
75        AURA_COMBUSTION,
76        BuffEffect::DynamicDamageMult(combustion_dynamic_mult),
77    );
78    built.set_aura_effect(
79        AURA_HYPERTHERMIA,
80        BuffEffect::CritChanceSpells(HUNDRED, &HYPERTHERMIA_CRIT_SPELLS),
81    );
82    built.register_impact_proc(
83        ImpactProc::new(ignite_fire)
84            .with_spell_filter(ignite_spell_filter)
85            .skip_periodic(),
86    );
87    built.register_impact_proc(
88        ImpactProc::new(intensifying_flame_fire)
89            .with_spell_filter(is_ignite)
90            .periodic_only(),
91    );
92    built.register_impact_proc(
93        ImpactProc::new(hot_streak_impact)
94            .with_spell_filter(hot_streak_spell_filter)
95            .skip_periodic(),
96    );
97    built.register_impact_proc(
98        ImpactProc::new(fevered_incantation_impact)
99            .with_spell_filter(ignite_spell_filter)
100            .skip_periodic(),
101    );
102    built.register_impact_proc(
103        ImpactProc::new(pyrotechnics_impact)
104            .with_spell_filter(is_fireball)
105            .skip_periodic(),
106    );
107    built.register_impact_proc(
108        ImpactProc::new(controlled_destruction_impact)
109            .with_spell_filter(controlled_destruction_spell_filter)
110            .skip_periodic(),
111    );
112}