Skip to main content

wowlab_engine_domain/dbc/
live_modifier.rs

1//! Classification of the DBC effects the generic live-aura path folds into a damage modifier.
2//!
3//! One classifier serves two consumers, so neither can drift from the other.
4//! The aura builder lowers each match into a `BuffEffect`.
5//! The manifest audit rejects content re-declaring a modifier the generic path owns.
6
7use crate::dbc::semantics::{
8    AuraSubtypeKind, ModifierOperation, ModifierPropertyKind, aura_subtype_is_any,
9    aura_subtype_modifier, modifier_property_is,
10};
11
12/// A damage modifier the generic live-aura path derives from a single DBC effect.
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14#[non_exhaustive]
15pub enum LiveDamageModifierKind {
16    /// Percent modifier on a spell's direct amount.
17    SpellDirectAmount,
18    /// Percent modifier on a spell's periodic amount.
19    SpellPeriodicAmount,
20    /// Flat or percent modifier on a spell's critical chance.
21    SpellCritChance,
22    /// Percent modifier on a spell's critical bonus multiplier.
23    SpellCritDamage,
24    /// Target-scoped modifier on damage taken from the caster's spells.
25    DamageTakenFromCasterSpells,
26}
27
28/// The damage modifier the generic live-aura path folds from one DBC effect, if any.
29///
30/// `subtype` is the raw `EffectAura` value and `property` the raw `EffectMiscValue_0`.
31#[must_use]
32pub fn live_damage_modifier(subtype: i32, property: i32) -> Option<LiveDamageModifierKind> {
33    if aura_subtype_is_any(
34        subtype,
35        &[
36            AuraSubtypeKind::ModDamageTakenFromCasterSpells,
37            AuraSubtypeKind::ModDamageTakenFromCasterSpellsLabel,
38        ],
39    ) {
40        return Some(LiveDamageModifierKind::DamageTakenFromCasterSpells);
41    }
42
43    let (operation, _) = aura_subtype_modifier(subtype)?;
44    let is_percent = operation == ModifierOperation::Percent;
45
46    if modifier_property_is(property, ModifierPropertyKind::CritChance) {
47        return Some(LiveDamageModifierKind::SpellCritChance);
48    }
49
50    if !is_percent {
51        return None;
52    }
53
54    if modifier_property_is(property, ModifierPropertyKind::CritDamage) {
55        return Some(LiveDamageModifierKind::SpellCritDamage);
56    }
57
58    if modifier_property_is(property, ModifierPropertyKind::GenericDamage) {
59        return Some(LiveDamageModifierKind::SpellDirectAmount);
60    }
61
62    if modifier_property_is(property, ModifierPropertyKind::PeriodicAmount) {
63        return Some(LiveDamageModifierKind::SpellPeriodicAmount);
64    }
65
66    None
67}
68
69#[cfg(test)]
70mod tests;