wowlab_engine_content/hooks/elemental_shaman/
config.rs1use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
2use wowlab_engine_ports::HandlerParams;
3use wowlab_types::{constants::HUNDRED};
4
5use crate::{
6 generated::specs::elemental_shaman::{EFFECT, SET_BONUS, TALENT},
7 hooks::gated,
8};
9
10pub(super) const ELEMENTAL_BLAST_COST: f64 = 90.0;
11
12crate::hooks::define_spec_config! {
13 pub(super) struct ElementalConfig {
14 supercharge_chance: f64 { provenance: "Supercharge effect proc chance.", gate: params.talent_picked(TALENT::SUPERCHARGE), source: effect_fraction(EFFECT::SUPERCHARGE_CHANCE), transform: |value| value },
15 feedback_loop_chance: f64 { provenance: "Feedback Loop rank-three bonus chance.", gate: params.talent_picked(TALENT::FEEDBACK_LOOP_3), source: effect_fraction(EFFECT::FEEDBACK_LOOP_BONUS), transform: |value| value },
16 fusion_of_elements_mult: f64 { provenance: "Fusion of Elements effect damage fraction.", gate: params.talent_picked(TALENT::FUSION_OF_ELEMENTS), source: effect_fraction(EFFECT::FUSION_OF_ELEMENTS_BONUS), transform: |value| value },
17 eb_overload_mult: f64 { provenance: "Mountains Will Fall Elemental Blast overload fraction.", gate: params.talent_picked(TALENT::MOUNTAINS_WILL_FALL), source: effect_fraction(EFFECT::MOUNTAINS_WILL_FALL_BONUS), transform: |value| value },
18 aftershock_chance: f64 { provenance: "Aftershock effect refund chance.", gate: params.talent_picked(TALENT::AFTERSHOCK), source: effect_fraction(EFFECT::AFTERSHOCK_CHANCE), transform: |value| value },
19 potm_chance: f64 { provenance: "Power of the Maelstrom effect proc chance.", gate: params.talent_picked(TALENT::POWER_OF_THE_MAELSTROM), source: effect_fraction(EFFECT::POWER_OF_THE_MAELSTROM_CHANCE), transform: |value| value },
20 stormwell_tempest_maelstrom: f64 { provenance: "Live bug: Tempest applying a NEW Stormkeeper via Arc Discharge triggers Stormwell's Maelstrom grant (`sc_shaman.cpp:9686`, bugs=1).", gate: params.talent_picked(TALENT::STORMWELL) && params.talent_picked(TALENT::ARC_DISCHARGE), source: params.game_data.effect_base_points(EFFECT::STORMWELL_SK_MAELSTROM), transform: |value| value },
21 tempest_chance_on_blast: f64 { provenance: "Tempest and Awakening Storms per-point chances folded across Elemental Blast cost.", gate: true, source: tempest_chance_on_blast(params), transform: |value| value },
22 eb_overload: bool { provenance: "Mountains Will Fall enables Elemental Blast overloads.", gate: params.talent_picked(TALENT::MOUNTAINS_WILL_FALL), source: true, transform: |value| value },
23 master_of_the_elements: bool { provenance: "Master of the Elements enables its spender window.", gate: params.talent_picked(TALENT::MASTER_OF_THE_ELEMENTS), source: true, transform: |value| value },
24 arc_discharge: bool { provenance: "Arc Discharge enables its overload rider.", gate: params.talent_picked(TALENT::ARC_DISCHARGE), source: true, transform: |value| value },
25 unlimited_power: bool { provenance: "Unlimited Power enables haste stacking.", gate: params.talent_picked(TALENT::UNLIMITED_POWER), source: true, transform: |value| value },
26 lightning_rod_mult: f64 { provenance: "Lightning Rod effect damage fraction.", gate: params.talent_picked(TALENT::LIGHTNING_ROD), source: effect_fraction(EFFECT::LIGHTNING_ROD_PERCENT), transform: |value| value },
27 summon_storm_elemental: bool { provenance: "Fury of the Storms plus Primal Elementalist enables the primal Storm Elemental.", gate: params.talent_picked(TALENT::FURY_OF_THE_STORMS) && params.talent_picked(TALENT::PRIMAL_ELEMENTALIST), source: true, transform: |value| value },
28 summon_fire_elemental: bool { provenance: "Call of Fire plus Primal Elementalist enables the primal Fire Elemental.", gate: params.talent_picked(TALENT::CALL_OF_FIRE) && params.talent_picked(TALENT::PRIMAL_ELEMENTALIST), source: true, transform: |value| value },
29 tww3_stormbringer_2pc: bool { provenance: "`TWW3` Stormbringer two-piece grants Tempest on Ascendance (`sc_shaman.cpp:11141`).", gate: params.set_bonus_auras.contains(&SET_BONUS::TWW3_STORMBRINGER_2PC), source: true, transform: |value| value },
30 tww3_stormbringer_4pc: bool { provenance: "TWW3 Stormbringer four-piece enables its tier rider.", gate: params.set_bonus_auras.contains(&SET_BONUS::TWW3_STORMBRINGER_4PC), source: true, transform: |value| value },
31 mid1_2pc: bool { provenance: "MID1 Elemental two-piece enables its tier rider.", gate: params.set_bonus_auras.contains(&SET_BONUS::MID1_ELEMENTAL_2PC), source: true, transform: |value| value },
32 mid1_4pc: bool { provenance: "MID1 Elemental four-piece enables its tier rider.", gate: params.set_bonus_auras.contains(&SET_BONUS::MID1_ELEMENTAL_4PC), source: true, transform: |value| value },
33 }
34 accessor pub(super) fn elemental_config(ctx);
35 register pub(super) fn register_elemental_config(built, params) -> ();
36 prepare {
37 let effect_fraction = |effect| params.game_data.effect_percent(effect);
38 }
39 auras {}
40 finish |cfg| { built.state.set_spec_config(cfg); }
41}
42
43fn tempest_chance_on_blast(params: &HandlerParams<'_>) -> f64 {
44 let data = ¶ms.game_data;
45 let tempest = gated(params.talent_picked(TALENT::TEMPEST_TALENT), || {
46 data.effect_base_points(EFFECT::TEMPEST_TALENT_CHANCE) / HUNDRED / HUNDRED
47 });
48 let awakening = gated(params.talent_picked(TALENT::AWAKENING_STORMS), || {
49 data.effect_base_points(EFFECT::AWAKENING_STORMS_CHANCE) / HUNDRED / HUNDRED
50 });
51 let tempest_per_point = tempest + awakening;
52
53 if tempest_per_point > 0.0 {
54 1.0 - (1.0 - tempest_per_point).powf(ELEMENTAL_BLAST_COST)
55 } else {
56 0.0
57 }
58}