wowlab_engine_content/hooks/fire_mage/
config.rs1use 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}