wowlab_engine_combat/builder/aura_builder/effects/
stats.rs1use 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}