Skip to main content

wowlab_engine_gamedata/game_data/
passive_access.rs

1//! Passive-modifier access to resolved game data.
2
3use wowlab_types::sim::SpellIdx;
4
5use super::ResolvedGameData;
6
7impl ResolvedGameData {
8    /// Static damage multiplier for a spell from passive spec/class auras; `1.0` when none apply.
9    #[must_use]
10    pub fn passive_damage_mult(&self, spell_id: SpellIdx, is_periodic: bool) -> f64 {
11        let map = if is_periodic {
12            &self.inner.passives.periodic_damage_mult
13        } else {
14            &self.inner.passives.direct_damage_mult
15        };
16
17        map.get(&spell_id).copied().unwrap_or(1.0)
18    }
19
20    /// Flat direct-damage spell modifier evaluated with live mastery points.
21    #[must_use]
22    pub fn passive_direct_damage_flat(&self, spell_id: SpellIdx, mastery_points: f64) -> f64 {
23        self.inner
24            .passives
25            .direct_damage_flat
26            .get(&spell_id)
27            .copied()
28            .unwrap_or(0.0)
29            + self
30                .inner
31                .passives
32                .direct_damage_flat_mastery
33                .get(&spell_id)
34                .copied()
35                .unwrap_or(0.0)
36                * mastery_points
37    }
38
39    /// Static flat crit-chance bonus (percent points) for a spell from passive spec/class auras; `0.0` when none apply.
40    #[must_use]
41    pub fn passive_crit_chance(&self, spell_id: SpellIdx) -> f64 {
42        self.inner
43            .passives
44            .crit_chance_bonus
45            .get(&spell_id)
46            .copied()
47            .unwrap_or(0.0)
48    }
49
50    /// Static crit-chance multiplier for a spell from passive spec/class auras; `1.0` when none apply.
51    #[must_use]
52    pub fn passive_crit_chance_mult(&self, spell_id: SpellIdx) -> f64 {
53        self.inner
54            .passives
55            .crit_chance_mult
56            .get(&spell_id)
57            .copied()
58            .unwrap_or(1.0)
59    }
60
61    /// Static crit-damage bonus (percent points) for a spell from passive spec/class auras; `0.0` when none apply.
62    #[must_use]
63    pub fn passive_crit_damage_bonus(&self, spell_id: SpellIdx) -> f64 {
64        self.inner
65            .passives
66            .crit_damage_bonus
67            .get(&spell_id)
68            .copied()
69            .unwrap_or(0.0)
70    }
71
72    /// Player-wide crit-damage terms scaled by the caster's own crit chance, as `(DBC school mask, percent points)`.
73    #[must_use]
74    pub fn crit_damage_per_crit_chance(&self) -> &[(i32, f64)] {
75        &self.inner.passives.crit_damage_per_crit_chance
76    }
77
78    /// Crit-bonus percent points of the caster's own crit chance for a spell; `0.0` when none apply.
79    #[must_use]
80    pub fn crit_bonus_per_crit_chance(&self, spell_id: SpellIdx) -> f64 {
81        self.inner
82            .passives
83            .crit_bonus_per_crit_chance
84            .get(&spell_id)
85            .copied()
86            .unwrap_or(0.0)
87    }
88
89    /// Static auto-attack damage multiplier from passive spec/class auras.
90    #[must_use]
91    pub fn auto_attack_damage_mult(&self) -> f64 {
92        self.inner.passives.auto_attack_damage_mult
93    }
94
95    /// Static pet damage multiplier from passive spec/class auras.
96    #[must_use]
97    pub fn pet_damage_mult(&self) -> f64 {
98        self.inner.passives.pet_damage_mult
99    }
100
101    /// Static guardian damage multiplier from passive spec/class auras.
102    #[must_use]
103    pub fn guardian_damage_mult(&self) -> f64 {
104        self.inner.passives.guardian_damage_mult
105    }
106
107    /// Aura-382 multiplier for attack power inherited by `npc_id`.
108    #[must_use]
109    pub fn pet_attack_power_inheritance_mult(&self, npc_id: u32) -> f64 {
110        self.inner
111            .passives
112            .pet_attack_power_inheritance
113            .get(&npc_id)
114            .copied()
115            .unwrap_or(1.0)
116    }
117
118    /// Aura-382 multiplier for spell power inherited by `npc_id`.
119    #[must_use]
120    pub fn pet_spell_power_inheritance_mult(&self, npc_id: u32) -> f64 {
121        self.inner
122            .passives
123            .pet_spell_power_inheritance
124            .get(&npc_id)
125            .copied()
126            .unwrap_or(1.0)
127    }
128
129    /// Whether `spell_id` is a baseline spec-granted spell (known without being talented).
130    #[must_use]
131    pub fn is_specialization_spell(&self, spell_id: SpellIdx) -> bool {
132        self.inner.spells.specialization.contains(&spell_id)
133    }
134
135    /// Whether `spell_id` was folded into the static per-spell passive modifier maps (live aura resolution must skip these to avoid double-applying).
136    #[must_use]
137    pub fn is_folded_passive(&self, spell_id: SpellIdx) -> bool {
138        self.inner.passives.folded_spells.contains(&spell_id)
139    }
140
141    /// Passive spell ids whose modifier effects were folded into static spell values.
142    #[must_use]
143    pub fn folded_passive_spells(&self) -> &[SpellIdx] {
144        &self.inner.passives.folded_spells
145    }
146
147    /// Damage-taken debuffs the class applies to its own target for the whole encounter.
148    ///
149    /// They are derived from the baseline class passives that describe them (Mystic Touch, Chaos Brand).
150    #[must_use]
151    pub fn class_target_debuffs(&self) -> &[SpellIdx] {
152        &self.inner.passives.class_target_debuffs
153    }
154}