wowlab_engine_combat/state/
damage.rs1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3#[must_use]
4pub struct DamageEffectRef {
5 pub spell_id: u32,
6 pub effect_index: u8,
7}
8
9impl DamageEffectRef {
10 #[inline]
11 pub const fn new(spell_id: u32, effect_index: u8) -> Self {
12 Self {
13 spell_id,
14 effect_index,
15 }
16 }
17}
18
19#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
21#[non_exhaustive]
22#[must_use]
23pub enum WeaponApType {
24 #[default]
25 MainHand,
26 OffHand,
27 Both,
29 None,
30}
31
32#[derive(Clone, Copy, Debug, Default)]
44#[non_exhaustive]
45#[must_use]
46pub enum RuntimeDamageDef {
47 #[default]
48 None,
49 Flat(f64),
50 ApCoefficient {
51 coef: f64,
52 is_physical: bool,
53 ap_type: WeaponApType,
54 },
55 SpCoefficient {
56 coef: f64,
57 is_physical: bool,
58 },
59 Weapon {
60 multiplier: f64,
61 flat_bonus: f64,
62 normalized: bool,
63 is_physical: bool,
64 hand: WeaponApType,
65 },
66}
67
68impl RuntimeDamageDef {
69 #[inline]
71 pub fn scaled(self, mult: f64) -> Self {
72 match self {
73 Self::None => Self::None,
74 Self::Flat(amount) => Self::Flat(amount * mult),
75 Self::ApCoefficient {
76 coef,
77 is_physical,
78 ap_type,
79 } => Self::ApCoefficient {
80 coef: coef * mult,
81 is_physical,
82 ap_type,
83 },
84 Self::SpCoefficient { coef, is_physical } => Self::SpCoefficient {
85 coef: coef * mult,
86 is_physical,
87 },
88 Self::Weapon {
89 multiplier,
90 flat_bonus,
91 normalized,
92 is_physical,
93 hand,
94 } => Self::Weapon {
95 multiplier: multiplier * mult,
96 flat_bonus: flat_bonus * mult,
97 normalized,
98 is_physical,
99 hand,
100 },
101 }
102 }
103}
104
105pub(crate) fn resolved_damage_base_points(
106 def: wowlab_engine_gamedata::ResolvedDamageDef,
107 multiplier: f64,
108) -> f64 {
109 use wowlab_engine_gamedata::ResolvedDamageKind;
110
111 if matches!(def.kind, ResolvedDamageKind::Ap | ResolvedDamageKind::Sp) {
112 def.base_points * multiplier
113 } else {
114 0.0
115 }
116}
117
118pub(crate) const MAX_CDR_EFFECTS: usize = 4;
119
120#[derive(Clone, Copy, Debug, Eq, PartialEq)]
122#[non_exhaustive]
123pub enum DamageSource {
124 Player,
125 Pet,
126 Guardian,
127}
128
129#[derive(Clone, Copy, Debug, PartialEq)]
131pub struct DamageReplication {
132 pub fraction: f64,
133 pub effect: DamageEffectRef,
134 pub source: DamageSource,
135 pub source_spells: &'static [u32],
137 pub include_magic: bool,
139 pub include_indirect: bool,
141 pub include_primary: bool,
143 pub max_targets: u8,
145 pub reduced_targets: u8,
147}
148
149#[derive(Clone, Copy, Debug, Eq, PartialEq)]
151#[non_exhaustive]
152pub enum DamageTransferTiming {
153 PreMitigationSplit,
155 PostMitigationShare,
157}
158
159#[derive(Clone, Copy, Debug, PartialEq)]
161pub struct DamageTransfer {
162 pub fraction: f64,
163 pub schools: wowlab_engine_domain::dbc::SpellSchoolMask,
164 pub timing: DamageTransferTiming,
165}
166
167#[derive(Clone, Copy, Debug, Eq, PartialEq)]
169#[non_exhaustive]
170pub enum ActiveSpellGate {
171 IgnoreAuraState,
173 DisableAbilities,
175}
176
177#[derive(Clone, Copy, Debug, Eq, PartialEq)]
179#[non_exhaustive]
180pub enum HealthThresholdDirection {
181 Above,
182 Below,
183}
184
185#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
187#[repr(transparent)]
188#[must_use]
189#[cfg(test)]
190pub(crate) struct HitFlags(u8);
191
192#[cfg(test)]
193impl HitFlags {
194 pub(crate) const PHYSICAL: u8 = 1 << 0;
195 pub(crate) const PET: u8 = 1 << 1;
196 pub(crate) const CRIT: u8 = 1 << 3;
197
198 #[inline]
199 pub(crate) const fn from_bits(b: u8) -> Self {
200 Self(b)
201 }
202
203 #[inline]
204 #[must_use]
205 pub(crate) const fn bits(self) -> u8 {
206 self.0
207 }
208
209 #[inline]
210 #[must_use]
211 pub(crate) const fn contains(self, mask: u8) -> bool {
212 (self.0 & mask) != 0
213 }
214}
215
216#[cfg(test)]
217#[path = "damage/tests.rs"]
218mod tests;