Skip to main content

wowlab_engine_combat/builder/aura_builder/effects/
stats.rs

1use super::{
2    AuraDefinitionDraft, AuraSubtypeKind, BuffEffect, BuilderError, EffectLookup, aura_subtype_is,
3    aura_subtype_is_any, effect_parts,
4};
5
6fn apply_primary_stat_effect(
7    mut aura: AuraDefinitionDraft,
8    lookup: EffectLookup<'_>,
9) -> Result<AuraDefinitionDraft, BuilderError> {
10    let (data, idx, spell_id, effect_index) = effect_parts(lookup);
11    let subtype = data.effect_aura(idx, effect_index);
12    let value = data.base_points(idx, effect_index);
13    let effect = if aura_subtype_is(subtype, AuraSubtypeKind::ModVersatilityPercent) {
14        Some(BuffEffect::Versatility(value))
15    } else if aura_subtype_is(
16        subtype,
17        AuraSubtypeKind::OverrideSpellPowerByAttackPowerPercent,
18    ) {
19        Some(BuffEffect::OverrideSpellPowerByAttackPowerPercent(value))
20    } else if aura_subtype_is(
21        subtype,
22        AuraSubtypeKind::OverrideAttackPowerBySpellPowerPercent,
23    ) {
24        Some(BuffEffect::OverrideAttackPowerBySpellPowerPercent(value))
25    } else if aura_subtype_is(subtype, AuraSubtypeKind::ModBonusStatPercent) {
26        wowlab_engine_domain::dbc::StatModifierKind::try_from(
27            data.effect_misc_value_0(idx, effect_index),
28        )
29        .ok()
30        .map(|stat| BuffEffect::BonusStatPercent {
31            percent: value,
32            stat,
33        })
34    } else if aura_subtype_is(subtype, AuraSubtypeKind::HasteAll) {
35        Some(BuffEffect::HasteMultFromEffect {
36            percent: value,
37            source_spell_id: spell_id,
38            effect_index,
39        })
40    } else if aura_subtype_is(subtype, AuraSubtypeKind::ModAllCritChance) {
41        Some(BuffEffect::CritFromEffect {
42            percent: value,
43            source_spell_id: spell_id,
44            effect_index,
45        })
46    } else if aura_subtype_is(subtype, AuraSubtypeKind::ModAutoAttackCritChance) {
47        Some(BuffEffect::AutoAttackCritChance(value))
48    } else if aura_subtype_is(subtype, AuraSubtypeKind::ModCritChanceVersusTargetHealth) {
49        Some(BuffEffect::CritChanceVersusTargetHealth {
50            percent: value,
51            threshold_pct: f64::from(data.effect_misc_value_1(idx, effect_index)),
52        })
53    } else if aura_subtype_is(subtype, AuraSubtypeKind::ModMasteryPercent) {
54        Some(BuffEffect::Mastery(value))
55    } else {
56        None
57    };
58
59    if let Some(effect) = effect {
60        aura = aura.push_effect(effect)?;
61    }
62
63    Ok(aura)
64}
65
66fn apply_resource_stat_effect(
67    mut aura: AuraDefinitionDraft,
68    lookup: EffectLookup<'_>,
69) -> Result<AuraDefinitionDraft, BuilderError> {
70    let (data, idx, spell_id, effect_index) = effect_parts(lookup);
71    let subtype = data.effect_aura(idx, effect_index);
72    let value = data.base_points(idx, effect_index);
73
74    if aura_subtype_is(subtype, AuraSubtypeKind::ModPowerRegenPercent) {
75        aura = aura.push_effect(BuffEffect::RegenPercent(value))?;
76    }
77
78    if aura_subtype_is(subtype, AuraSubtypeKind::ModRageGeneratedFromAutoAttacks) {
79        aura = aura.push_effect(BuffEffect::RageGainMult(value))?;
80    }
81
82    if aura_subtype_is(subtype, AuraSubtypeKind::ModPowerRegen) {
83        let resource_type = data.effect_misc_value_0(idx, effect_index);
84        let resource_type = u8::try_from(resource_type)
85            .ok()
86            .and_then(|value| wowlab_types::combat::ResourceType::try_from(value).ok())
87            .ok_or(crate::builder::BuilderErrorKind::MissingSpellData {
88                spell_id,
89                field: "mod_power_regen.resource_type",
90            })?;
91
92        aura = aura.push_effect(BuffEffect::ResourceRegenPerFiveSeconds(
93            value,
94            resource_type,
95        ))?;
96    }
97
98    if aura_subtype_is(subtype, AuraSubtypeKind::ModManaCostPercent) {
99        aura = aura.push_effect(BuffEffect::ResourceCostPercent(
100            value,
101            wowlab_types::combat::ResourceType::Mana,
102        ))?;
103    }
104
105    Ok(aura)
106}
107
108pub(in crate::builder::aura_builder) fn apply_active_stat_effect(
109    mut aura: AuraDefinitionDraft,
110    lookup: EffectLookup<'_>,
111) -> Result<AuraDefinitionDraft, BuilderError> {
112    let (data, idx, spell_id, effect_index) = effect_parts(lookup);
113    let subtype = data.effect_aura(idx, effect_index);
114
115    if aura_subtype_is_any(
116        subtype,
117        &[
118            AuraSubtypeKind::AllowCastingWhileMovingLabel,
119            AuraSubtypeKind::CastWhileMovingWhitelist,
120            AuraSubtypeKind::CastWhileMoving,
121        ],
122    ) {
123        aura = aura.push_effect(BuffEffect::CastWhileMovingFromEffect {
124            source_spell_id: spell_id,
125            effect_index,
126        })?;
127    }
128
129    let aura = apply_primary_stat_effect(aura, lookup)?;
130
131    apply_resource_stat_effect(aura, lookup)
132}