wowlab_engine_content/hooks/devastation_evoker/
config.rs1use wowlab_engine_combat::BuffEffect;
2use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
3use wowlab_types::{constants::HUNDRED};
4
5use crate::generated::specs::devastation_evoker::{
6 AURA_IRIDESCENCE_BLUE, AURA_IRIDESCENCE_RED, AURA_UNBOUND_FLAME, EFFECT, REPORTED_SPELL,
7 SET_BONUS, SPELL_ETERNITY_SURGE, TALENT,
8};
9
10static IRIDESCENCE_BLUE_REPORTED_SPELLS: [u32; 1] = [REPORTED_SPELL::ETERNITY_SURGE_DAMAGE];
11static UNBOUND_FLAME_REPORTED_SPELLS: [u32; 1] = [REPORTED_SPELL::UNBOUND_FLAME_DAMAGE];
12#[rustfmt::skip]
13static IRIDESCENCE_RED_REPORTED_SPELLS: [u32; 3] = [
14 REPORTED_SPELL::LIVING_FLAME_DAMAGE,
15 REPORTED_SPELL::FIRE_BREATH_DAMAGE,
16 REPORTED_SPELL::PYRE_DAMAGE,
17];
18
19crate::hooks::define_spec_config! {
20 pub(super) struct DevastationConfig {
21 causality_tick_cdr_ms: u32 { provenance: "Causality 375777 e1 plus MID2 four-piece 1296640 e1 empower CDR per Disintegrate tick.", gate: params.talent_picked(TALENT::CAUSALITY), source: base_points(EFFECT::CAUSALITY_DISINTEGRATE_CDR) + if params.set_bonus_auras.contains(&SET_BONUS::MID2_DEVASTATION_4PC) { base_points(EFFECT::MID2_4PC_CAUSALITY_CDR) } else { 0.0 }, transform: |value: f64| wowlab_types::numeric::f64_to_u32_saturating_trunc(value.abs()) },
22 scintillation_chance: f64 { provenance: "Scintillation 370821 e2: chance per Disintegrate tick.", gate: params.talent_picked(TALENT::SCINTILLATION), source: base_points(EFFECT::SCINTILLATION_CHANCE), transform: |value| value / HUNDRED },
23 scintillation_coef: f64 { provenance: "Scintillation 370821 e1 scales Eternity Surge rank-one SP coefficient, including the MID2 four-piece bonus.", gate: params.talent_picked(TALENT::SCINTILLATION), source: data.effect_sp_coefficient(EFFECT::ETERNITY_SURGE_DAMAGE) * base_points(EFFECT::SCINTILLATION_POWER) * mid2_eternity_surge_mult, transform: |value| value / HUNDRED },
24 shattering_star_coef: f64 { provenance: "Shattering Stars 1265804 e1 SP coefficient.", gate: params.talent_picked(TALENT::SHATTERING_STARS), source: data.effect_sp_coefficient(EFFECT::SHATTERING_STAR), transform: |value| value },
25 shattering_star_per_rank: f64 { provenance: "Shattering Stars 1265802 e1 bonus per Eternity Surge empower rank above one.", gate: params.talent_picked(TALENT::SHATTERING_STARS), source: base_points(EFFECT::SHATTERING_STARS_PER_RANK), transform: |value| value / HUNDRED },
26 mid2_shattering_star_mult: f64 { provenance: "MID2 Devastation two-piece 1296639 e1 Shattering Star damage bonus.", gate: params.set_bonus_auras.contains(&SET_BONUS::MID2_DEVASTATION_2PC), source: base_points(EFFECT::MID2_2PC_SHATTERING_STAR_DAMAGE), transform: |value| 1.0 + value / HUNDRED, fallback: 1.0 },
27 mid2_max_shattering_star: bool { provenance: "MID2 Devastation two-piece makes Shattering Star use maximum empower rank.", gate: params.set_bonus_auras.contains(&SET_BONUS::MID2_DEVASTATION_2PC), source: true, transform: |value| value },
28 titanic_wrath_mult: f64 { provenance: "Titanic Wrath 386272 e1 snapshots its Disintegrate damage multiplier when Essence Burst is consumed.", gate: params.talent_picked(TALENT::TITANIC_WRATH), source: base_points(EFFECT::TITANIC_WRATH_MULT), transform: |value| 1.0 + value / HUNDRED, fallback: 1.0 },
29 animosity_extend_ms: u32 { provenance: "Animosity 375797 e1 Dragonrage extension milliseconds.", gate: params.talent_picked(TALENT::ANIMOSITY), source: base_points(EFFECT::ANIMOSITY_EXTEND), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
30 ruby_eb_chance: f64 { provenance: "Ruby Essence Burst 376872 e1 proc chance.", gate: params.talent_picked(TALENT::RUBY_ESSENCE_BURST), source: base_points(EFFECT::RUBY_EB_CHANCE), transform: |value| value / HUNDRED },
31 azure_eb_chance: f64 { provenance: "Azure Essence Burst 375721 e1 proc chance.", gate: params.talent_picked(TALENT::AZURE_ESSENCE_BURST), source: base_points(EFFECT::AZURE_EB_CHANCE), transform: |value| value / HUNDRED },
32 burnout_chance: f64 { provenance: "Burnout 375801 e1 proc chance.", gate: params.talent_picked(TALENT::BURNOUT), source: base_points(EFFECT::BURNOUT_CHANCE), transform: |value| value / HUNDRED },
33 eye_of_infinity: bool { provenance: "Eye of Infinity 411165 enables Essence Burst on Eternity Surge crits.", gate: params.talent_picked(TALENT::EYE_OF_INFINITY), source: true, transform: |value| value },
34 mass_disintegrate: bool { provenance: "Mass Disintegrate 436335 gate enables empower-generated stacks.", gate: params.talent_picked(TALENT::MASS_DISINTEGRATE_GATE), source: true, transform: |value| value },
35 bombardments: bool { provenance: "Bombardments gate enables application during Mass Disintegrate.", gate: params.talent_picked(TALENT::BOMBARDMENTS_GATE), source: true, transform: |value| value },
36 blast_furnace_bonus_ticks: u8 { provenance: "Blast Furnace 375510 e1 adds Fire Breath duration; the server converts its seconds to two-second ticks.", gate: params.talent_picked(TALENT::BLAST_FURNACE), source: base_points(EFFECT::BLAST_FURNACE_DURATION), transform: |value| wowlab_types::numeric::f64_to_u8_saturating_trunc(value / 2.0) },
37 melt_armor: bool { provenance: "Melt Armor requires its gate and Maneuverability.", gate: params.talent_picked(TALENT::MELT_ARMOR_GATE) && params.talent_picked(TALENT::MANEUVERABILITY_GATE), source: true, transform: |value| value },
38 imminent_destruction: bool { provenance: "Imminent Destruction 370781 triggers from Deep Breath.", gate: params.talent_picked(TALENT::IMMINENT_DESTRUCTION), source: true, transform: |value| value },
39 rising_fury: bool { provenance: "Rising Fury 1271687 stacks during Dragonrage.", gate: params.talent_picked(TALENT::RISING_FURY), source: true, transform: |value| value },
40 rising_fury_3: bool { provenance: "Rising Fury rank three 1271788 preserves stacks and grants Unbound Flame when Dragonrage ends.", gate: params.talent_picked(TALENT::RISING_FURY_3), source: true, transform: |value| value },
41 rising_fury_persist_ms: u32 { provenance: "Rising Fury rank three 1271788 e1 persistence per stack.", gate: params.talent_picked(TALENT::RISING_FURY_3), source: base_points(EFFECT::RISING_FURY_PERSIST_MS), transform: wowlab_types::numeric::f64_to_u32_saturating_trunc },
42 iridescence: bool { provenance: "Iridescence 370867 enables color damage windows.", gate: params.talent_picked(TALENT::IRIDESCENCE), source: true, transform: |value| value },
43 strafing_run: bool { provenance: "Strafing Run 1266151 enables the Deep Breath recast window.", gate: params.talent_picked(TALENT::STRAFING_RUN_GATE), source: true, transform: |value| value },
44 }
45 accessor pub(super) fn config(ctx);
46 register pub(super) fn register_devastation(built, params) -> ();
47 prepare {
48 let data = ¶ms.game_data;
49 let base_points = |effect| data.effect_base_points(effect);
50 let mid2_eternity_surge_mult = if params.set_bonus_auras.contains(&SET_BONUS::MID2_DEVASTATION_4PC) {
51 1.0 + base_points(EFFECT::MID2_4PC_ETERNITY_SURGE_DAMAGE) / HUNDRED
52 } else {
53 1.0
54 };
55 }
56 auras {
57 { provenance: "Iridescence blue-school damage window.", gate: params.talent_picked(TALENT::IRIDESCENCE), aura: AURA_IRIDESCENCE_BLUE, effect: BuffEffect::DamageMultSpells(1.0 + base_points(EFFECT::IRIDESCENCE_BLUE_MULT) / HUNDRED, &IRIDESCENCE_BLUE_REPORTED_SPELLS) },
58 { provenance: "Iridescence red-school damage window.", gate: params.talent_picked(TALENT::IRIDESCENCE), aura: AURA_IRIDESCENCE_RED, effect: BuffEffect::DamageMultSpells(1.0 + base_points(EFFECT::IRIDESCENCE_RED_MULT) / HUNDRED, &IRIDESCENCE_RED_REPORTED_SPELLS) },
59 { provenance: "Unbound Flame always critically strikes.", gate: params.talent_picked(TALENT::RISING_FURY_3), aura: AURA_UNBOUND_FLAME, effect: BuffEffect::CritChanceSpells(HUNDRED, &UNBOUND_FLAME_REPORTED_SPELLS) },
60 }
61 wiring {
62 { provenance: "MID2 Devastation four-piece direct Eternity Surge damage bonus.", gate: mid2_eternity_surge_mult > 1.0, apply: {
63 built.patch_spell(SPELL_ETERNITY_SURGE, |spell| {
64 spell.damage = spell.damage.scaled(mid2_eternity_surge_mult);
65 });
66 } },
67 }
68 finish |cfg| {
69 built.set_spec_config(cfg);
70 }
71}
72
73#[cfg(test)]
74#[path = "config_tests.rs"]
75mod tests;