wowlab_engine_domain/dbc/passives/
targeting.rs1use wowlab_types::numeric::f64_to_i32_saturating_round;
2
3use super::{
4 ModifierFold, ModifierPropertyKind, PassiveQuery, effect_targets_spell,
5 fold_flat_pct_modifiers, modified_effect_base_points, modifier_property_kind,
6 passive_integral_value,
7};
8
9#[must_use]
11pub fn passive_chain_targets(query: PassiveQuery<'_>, initial: i32) -> i32 {
12 passive_integral_value(query, initial, ModifierPropertyKind::ChainTargets)
13}
14
15fn passive_targeting_value(
16 query: PassiveQuery<'_>,
17 initial: f64,
18 property: ModifierPropertyKind,
19) -> f64 {
20 let PassiveQuery {
21 passives,
22 spell: target,
23 } = query;
24
25 fold_flat_pct_modifiers(
26 passives,
27 initial,
28 ModifierFold::FlatAndPercent,
29 |source, ranks, modifier| {
30 if modifier_property_kind(modifier) != Some(property)
31 || !effect_targets_spell(modifier, source, target)
32 {
33 return None;
34 }
35
36 Some(
37 modified_effect_base_points(
38 PassiveQuery {
39 passives,
40 spell: source,
41 },
42 modifier.index,
43 modifier.base_points,
44 ) * ranks,
45 )
46 },
47 )
48 .max(0.0)
49}
50
51macro_rules! passive_targeting_wrappers {
52 ($($(#[$meta:meta])* $method:ident => $property:ident),+ $(,)?) => {
53 $(
54 $(#[$meta])*
55 #[must_use]
56 pub fn $method(query: PassiveQuery<'_>, initial: f64) -> f64 {
57 passive_targeting_value(query, initial, ModifierPropertyKind::$property)
58 }
59 )+
60 };
61}
62
63passive_targeting_wrappers! {
64 passive_hostile_max_range => Range,
66 passive_radius => Radius,
68 passive_chain_target_range => ChainTargetRange,
70}
71
72#[must_use]
74pub fn passive_max_targets(query: PassiveQuery<'_>, initial: i32) -> i32 {
75 f64_to_i32_saturating_round(passive_targeting_value(
76 query,
77 f64::from(initial),
78 ModifierPropertyKind::MaxTargets,
79 ))
80}
81
82#[must_use]
84pub fn passive_chain_multiplier(query: PassiveQuery<'_>, initial: f64) -> f64 {
85 let PassiveQuery {
86 passives,
87 spell: target,
88 } = query;
89 let normalized = if initial > 0.0 { initial } else { 1.0 };
90
91 fold_flat_pct_modifiers(
92 passives,
93 normalized,
94 ModifierFold::FlatAndPercent,
95 |source, ranks, modifier| {
96 if modifier_property_kind(modifier) != Some(ModifierPropertyKind::ChainMultiplier)
97 || !effect_targets_spell(modifier, source, target)
98 {
99 return None;
100 }
101
102 Some(modifier.base_points * ranks)
103 },
104 )
105 .max(0.0)
106}