wowlab_engine_combat/state/defs/
drivers.rs1use wowlab_engine_domain::rotation::WeaponImbueSlotHandle;
2
3use super::{BuffEffect, CastHookFn, HookView, LocalAuraIdx, LocalRppmIdx, LocalSpellIdx};
4
5#[derive(Clone, Copy, Debug, PartialEq)]
7#[must_use]
8pub(crate) struct ResourceThresholdTrigger {
9 pub resource_type: wowlab_types::combat::ResourceType,
10 pub threshold: f64,
11 pub spell_local: LocalSpellIdx,
12}
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16#[must_use]
17pub struct WeaponEnchantBinding {
18 pub enchantment_id: u32,
19 pub buff_spell_id: u32,
20}
21
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24#[must_use]
25pub(crate) struct ResolvedWeaponEnchantBinding {
26 pub(crate) rppm: LocalRppmIdx,
27 pub(crate) buff_aura: LocalAuraIdx,
28}
29
30#[derive(Clone, Copy, Debug, Eq, PartialEq)]
32#[must_use]
33pub(crate) struct WeaponImbueBinding {
34 pub spell_id: u32,
35 pub key: &'static str,
36}
37
38#[derive(Clone, Copy, Debug, Eq, PartialEq)]
40#[must_use]
41pub(crate) struct ResolvedWeaponImbueBinding {
42 pub spell_local: LocalSpellIdx,
43 pub slot: WeaponImbueSlotHandle,
44}
45
46#[derive(Clone, Copy, Debug)]
48#[must_use]
49pub struct DriverSpellModifier {
50 pub(crate) driver_spell_id: u32,
51 pub(crate) spells: &'static [u32],
52 pub(crate) resolve: DriverSpellModifierFn,
53}
54
55#[derive(Clone, Copy, Debug)]
59#[must_use]
60pub struct PassiveDriverEffect {
61 pub(crate) driver_spell_id: u32,
62 pub(crate) effect: BuffEffect,
63}
64
65impl PassiveDriverEffect {
66 pub const fn new(driver_spell_id: u32, effect: BuffEffect) -> Self {
67 Self {
68 driver_spell_id,
69 effect,
70 }
71 }
72}
73
74#[derive(Clone, Copy, Debug)]
78#[must_use]
79pub struct PeriodicDriver {
80 pub(crate) driver_spell_id: u32,
81 pub(crate) tick_interval_ms: std::num::NonZeroU32,
82 pub(crate) triggered_duration_ms: Option<std::num::NonZeroU32>,
83 pub(crate) hasted_ticks: bool,
84 pub(crate) tick: CastHookFn,
85}
86
87impl PeriodicDriver {
88 pub const fn new(driver_spell_id: u32, tick_interval_ms: u32, tick: CastHookFn) -> Self {
94 let Some(tick_interval_ms) = std::num::NonZeroU32::new(tick_interval_ms) else {
95 panic!("periodic driver tick interval must be non-zero");
96 };
97
98 Self {
99 driver_spell_id,
100 tick_interval_ms,
101 triggered_duration_ms: None,
102 hasted_ticks: false,
103 tick,
104 }
105 }
106
107 pub const fn hasted(mut self) -> Self {
108 self.hasted_ticks = true;
109
110 self
111 }
112
113 pub const fn triggered_for(mut self, duration_ms: u32) -> Self {
119 let Some(duration_ms) = std::num::NonZeroU32::new(duration_ms) else {
120 panic!("triggered periodic driver duration must be non-zero");
121 };
122
123 self.triggered_duration_ms = Some(duration_ms);
124
125 self
126 }
127}
128
129pub(crate) type DriverSpellModifierFn = fn(HookView<'_>) -> DriverSpellModifierResult;
130
131#[derive(Clone, Copy, Debug, PartialEq)]
133#[must_use]
134pub struct DriverSpellModifierResult {
135 pub damage_mult: f64,
136 pub target_damage_mult: f64,
137 pub crit_chance_pct: f64,
138 pub crit_damage_mult: f64,
139}
140
141impl DriverSpellModifierResult {
142 pub const fn damage_mult(damage_mult: f64) -> Self {
143 Self {
144 damage_mult,
145 target_damage_mult: 1.0,
146 crit_chance_pct: 0.0,
147 crit_damage_mult: 1.0,
148 }
149 }
150
151 pub const fn crit_chance(crit_chance_pct: f64) -> Self {
152 Self {
153 damage_mult: 1.0,
154 target_damage_mult: 1.0,
155 crit_chance_pct,
156 crit_damage_mult: 1.0,
157 }
158 }
159}
160
161impl Default for DriverSpellModifierResult {
162 fn default() -> Self {
163 Self {
164 damage_mult: 1.0,
165 target_damage_mult: 1.0,
166 crit_chance_pct: 0.0,
167 crit_damage_mult: 1.0,
168 }
169 }
170}
171
172impl DriverSpellModifier {
173 pub const fn new(
174 driver_spell_id: u32,
175 spells: &'static [u32],
176 resolve: DriverSpellModifierFn,
177 ) -> Self {
178 Self {
179 driver_spell_id,
180 spells,
181 resolve,
182 }
183 }
184}