Skip to main content

wowlab_engine_domain/dbc/
effect_lookup.rs

1use wowlab_engine_gamedata::ResolvedGameData;
2use wowlab_types::sim::EffectRef;
3
4/// Read-only resolved-data view for one spell effect.
5#[derive(Clone, Copy, Debug)]
6pub struct EffectLookup<'a> {
7    pub data: &'a ResolvedGameData,
8    pub effect: EffectRef,
9}
10
11impl<'a> EffectLookup<'a> {
12    #[inline]
13    #[must_use]
14    pub const fn new(data: &'a ResolvedGameData, effect: EffectRef) -> Self {
15        Self { data, effect }
16    }
17
18    #[inline]
19    #[must_use]
20    pub fn effect_type(self) -> i32 {
21        self.data
22            .effect_type(self.effect.spell, self.effect.effect_index)
23    }
24
25    #[inline]
26    #[must_use]
27    pub fn effect_aura(self) -> i32 {
28        self.data
29            .effect_aura(self.effect.spell, self.effect.effect_index)
30    }
31
32    #[inline]
33    #[must_use]
34    pub fn effect_misc_value_0(self) -> i32 {
35        self.data
36            .effect_misc_value_0(self.effect.spell, self.effect.effect_index)
37    }
38
39    #[inline]
40    #[must_use]
41    pub fn effect_misc_value_1(self) -> i32 {
42        self.data
43            .effect_misc_value_1(self.effect.spell, self.effect.effect_index)
44    }
45
46    #[inline]
47    #[must_use]
48    pub fn effect_attributes(self) -> i32 {
49        self.data
50            .effect_attributes(self.effect.spell, self.effect.effect_index)
51    }
52
53    #[inline]
54    #[must_use]
55    pub fn base_points(self) -> f64 {
56        self.data
57            .base_points(self.effect.spell, self.effect.effect_index)
58    }
59
60    #[inline]
61    #[must_use]
62    pub fn ap_coef(self) -> f64 {
63        self.data
64            .ap_coef(self.effect.spell, self.effect.effect_index)
65    }
66
67    #[inline]
68    #[must_use]
69    pub fn sp_coef(self) -> f64 {
70        self.data
71            .sp_coef(self.effect.spell, self.effect.effect_index)
72    }
73
74    #[inline]
75    #[must_use]
76    pub fn coefficient(self) -> f64 {
77        self.data
78            .coefficient(self.effect.spell, self.effect.effect_index)
79    }
80
81    #[inline]
82    #[must_use]
83    pub fn amplitude(self) -> f64 {
84        self.data
85            .amplitude(self.effect.spell, self.effect.effect_index)
86    }
87
88    #[inline]
89    #[must_use]
90    pub fn period(self) -> f64 {
91        self.data
92            .period(self.effect.spell, self.effect.effect_index)
93    }
94
95    #[inline]
96    #[must_use]
97    pub fn scaling_class(self) -> i32 {
98        self.data
99            .scaling_class(self.effect.spell, self.effect.effect_index)
100    }
101
102    #[inline]
103    #[must_use]
104    pub fn trigger_spell(self) -> Option<wowlab_types::sim::SpellIdx> {
105        self.data
106            .trigger_spell(self.effect.spell, self.effect.effect_index)
107    }
108}
109
110/// Effect-coordinate access for code that has resolved data but no combat hook context.
111pub trait ResolvedGameDataEffectExt {
112    #[must_use]
113    fn effect_lookup(&self, effect: impl Into<EffectRef>) -> EffectLookup<'_>;
114
115    #[must_use]
116    fn effect_base_points(&self, effect: impl Into<EffectRef>) -> f64 {
117        self.effect_lookup(effect).base_points()
118    }
119
120    /// Resolve required base points while preserving the populated-data missing-effect error.
121    ///
122    /// # Errors
123    ///
124    /// Returns an error when populated data does not contain the requested effect.
125    fn require_effect_base_points(
126        &self,
127        effect: impl Into<EffectRef>,
128    ) -> Result<f64, wowlab_engine_gamedata::GameDataError>;
129
130    /// Resolve required points-per-resource while preserving the populated-data missing-effect error.
131    ///
132    /// # Errors
133    ///
134    /// Returns an error when populated data does not contain the requested effect.
135    fn require_effect_points_per_resource(
136        &self,
137        effect: impl Into<EffectRef>,
138    ) -> Result<f64, wowlab_engine_gamedata::GameDataError>;
139
140    #[must_use]
141    fn resolved_effect_points(&self, effect: impl Into<EffectRef>, mastery_points: f64) -> f64;
142
143    #[must_use]
144    fn effect_percent(&self, effect: impl Into<EffectRef>) -> f64 {
145        self.effect_base_points(effect) / wowlab_types::constants::HUNDRED
146    }
147
148    #[must_use]
149    fn effect_ap_coefficient(&self, effect: impl Into<EffectRef>) -> f64 {
150        self.effect_lookup(effect).ap_coef()
151    }
152
153    #[must_use]
154    fn effect_sp_coefficient(&self, effect: impl Into<EffectRef>) -> f64 {
155        self.effect_lookup(effect).sp_coef()
156    }
157}
158
159impl ResolvedGameDataEffectExt for ResolvedGameData {
160    fn effect_lookup(&self, effect: impl Into<EffectRef>) -> EffectLookup<'_> {
161        EffectLookup::new(self, effect.into())
162    }
163
164    fn resolved_effect_points(&self, effect: impl Into<EffectRef>, mastery_points: f64) -> f64 {
165        let effect = effect.into();
166
167        self.effect_points(effect.spell, effect.effect_index, mastery_points)
168    }
169
170    fn require_effect_base_points(
171        &self,
172        effect: impl Into<EffectRef>,
173    ) -> Result<f64, wowlab_engine_gamedata::GameDataError> {
174        let effect = effect.into();
175
176        self.require_base_points(effect.spell, effect.effect_index)
177    }
178
179    fn require_effect_points_per_resource(
180        &self,
181        effect: impl Into<EffectRef>,
182    ) -> Result<f64, wowlab_engine_gamedata::GameDataError> {
183        let effect = effect.into();
184
185        self.require_points_per_resource(effect.spell, effect.effect_index)
186    }
187}
188
189#[cfg(test)]
190#[path = "effect_lookup/tests.rs"]
191mod tests;