Skip to main content

wowlab_engine_content/hooks/beast_mastery_hunter/
config.rs

1use wowlab_engine_combat::{
2    BuffEffect, CombatSystemDraft, DamageEffectRef, DamageReplication, DamageSource,
3};
4use wowlab_engine_domain::dbc::ResolvedGameDataEffectExt as _;
5use wowlab_engine_ports::HandlerParams;
6use wowlab_types::constants::HUNDRED;
7
8use crate::generated::specs::beast_mastery_hunter::{
9    AURA_BEAST_CLEAVE, DAMAGE_EFFECT, EFFECT, SET_BONUS,
10};
11
12#[derive(Clone, Copy, Debug, Default)]
13pub(super) struct BeastMasteryConfig {
14    pub(super) mid2_extra_stomp_mult: f64,
15    pub(super) mid2_cobra_fang: bool,
16    pub(super) cobra_fang_cleave_per_stack: f64,
17    pub(super) cobra_fang_primary_per_stack: f64,
18}
19
20fn target_count(value: f64) -> Result<u8, wowlab_engine_ports::EngineError> {
21    if !value.is_finite()
22        || value < 0.0
23        || value > f64::from(u8::MAX)
24        || value.fract().abs() > f64::EPSILON
25    {
26        return Err(wowlab_engine_ports::EngineError::spec_construction(
27            "Beast Cleave reduced-target count must be an integer from 0 through 255",
28        ));
29    }
30
31    Ok(wowlab_types::numeric::f64_to_u8_saturating_trunc(value))
32}
33
34pub(super) fn register_beast_cleave(
35    built: &mut CombatSystemDraft,
36    params: &HandlerParams<'_>,
37) -> Result<(), wowlab_engine_ports::EngineError> {
38    let data = &params.game_data;
39    let fraction = data.require_effect_base_points(EFFECT::BEAST_CLEAVE_FRACTION)? / HUNDRED;
40    let reduced_targets =
41        target_count(data.require_effect_base_points(EFFECT::BEAST_CLEAVE_REDUCED_TARGETS)?)?;
42
43    for (name, effect) in [
44        ("bm_stampede_damage", DAMAGE_EFFECT::STAMPEDE_DAMAGE),
45        ("bm_stampede_geometry", DAMAGE_EFFECT::STAMPEDE_GEOMETRY),
46    ] {
47        built.register_damage_effect_identity(name, effect);
48    }
49
50    built.set_aura_effect(
51        AURA_BEAST_CLEAVE,
52        BuffEffect::DamageReplication(DamageReplication {
53            fraction,
54            effect: DamageEffectRef::new(
55                EFFECT::BEAST_CLEAVE_DAMAGE.0,
56                EFFECT::BEAST_CLEAVE_DAMAGE.1,
57            ),
58            source: DamageSource::Pet,
59            source_spells: &[],
60            include_magic: false,
61            include_indirect: false,
62            include_primary: false,
63            max_targets: 0,
64            reduced_targets,
65        }),
66    );
67
68    built.set_spec_config(BeastMasteryConfig {
69        mid2_extra_stomp_mult: if params.set_bonus_auras.contains(&SET_BONUS::MID2_BM_2PC) {
70            data.require_effect_base_points(EFFECT::MID2_BM_2PC_EFFECTIVENESS)? / HUNDRED
71        } else {
72            0.0
73        },
74        mid2_cobra_fang: params.set_bonus_auras.contains(&SET_BONUS::MID2_BM_4PC),
75        cobra_fang_cleave_per_stack: data
76            .require_effect_base_points(EFFECT::COBRA_FANG_CLEAVE_PCT)?
77            / HUNDRED,
78        cobra_fang_primary_per_stack: data
79            .require_effect_base_points(EFFECT::COBRA_FANG_PRIMARY_PCT)?
80            / HUNDRED,
81    });
82
83    Ok(())
84}