Skip to main content

wowlab_engine_combat/context/hook/
mod.rs

1//! Public capabilities available to combat hooks.
2
3use wowlab_engine_domain::pool::SpellGate;
4use wowlab_types::sim::{ActorId, EnemyIdx, SimTime};
5
6use super::{DamageOutcome, FreeActionSource};
7use crate::{
8    DamageActionId, DamageEffectId, DamageFlags, ImpactEvent,
9    state::{
10        CastHookFn, GroundEffectId, GuardianHandle, GuardianSpec, LocalAuraIdx, LocalRppmIdx,
11        LocalSpellIdx, LocalThresholdIdx, ResourceGainSource, SwingHand,
12    },
13};
14
15mod ground_effects;
16mod guardians;
17mod proc_counters;
18mod resources;
19mod rppm;
20mod spells;
21
22/// Aura lifecycle and aura-owned accumulator operations.
23pub trait AuraOps {
24    fn with_resolved_target(&mut self, target: EnemyIdx, apply: impl FnOnce(&mut Self));
25    fn now(&self) -> SimTime;
26    fn apply_aura(&mut self, local: LocalAuraIdx);
27    fn apply_owner_aura(&mut self, local: LocalAuraIdx);
28    fn apply_aura_with_duration(&mut self, local: LocalAuraIdx, duration_ms: u32);
29    fn apply_aura_with_rolling_multiplier(&mut self, local: LocalAuraIdx, multiplier: f64);
30    fn apply_pet_aura_with_duration(&mut self, local: LocalAuraIdx, duration_ms: u32);
31    fn apply_aura_n(&mut self, local: LocalAuraIdx, n: i32);
32    fn add_aura_stack(&mut self, local: LocalAuraIdx);
33    fn add_owner_aura_stack(&mut self, local: LocalAuraIdx);
34    fn add_residual_damage(&mut self, local: LocalAuraIdx, amount: f64);
35    fn residual_damage_remaining(&self, local: LocalAuraIdx) -> f64;
36    fn accumulate_damage(&mut self, local: LocalAuraIdx, amount: f64);
37    fn accumulate_owner_damage(&mut self, local: LocalAuraIdx, amount: f64);
38    fn take_accumulated_damage(&mut self, local: LocalAuraIdx) -> f64;
39    fn expire_aura(&mut self, local: LocalAuraIdx);
40    fn expire_owner_aura(&mut self, local: LocalAuraIdx);
41    fn consume_aura(&mut self, local: LocalAuraIdx) -> bool;
42    fn consume_aura_stack(&mut self, local: LocalAuraIdx) -> bool;
43    fn consume_owner_aura_stack(&mut self, local: LocalAuraIdx) -> bool;
44    fn consume_aura_stacks(&mut self, local: LocalAuraIdx, count: i32) -> i32;
45    fn refresh_aura_snapshot_multiplier(&mut self, local: LocalAuraIdx, multiplier: f64) -> bool;
46    fn extend_aura(&mut self, local: LocalAuraIdx, ms: u32);
47    fn reduce_aura(&mut self, local: LocalAuraIdx, ms: u32);
48    fn is_aura_active(&self, local: LocalAuraIdx) -> bool;
49    fn is_owner_aura_active(&self, local: LocalAuraIdx) -> bool;
50    fn aura_stacks(&self, local: LocalAuraIdx) -> i32;
51    fn aura_remaining_ms(&self, local: LocalAuraIdx) -> Option<u32>;
52    fn flat_periodic_damage_remaining(&self, local: LocalAuraIdx) -> Option<f64>;
53}
54
55/// Damage calculation and impact operations.
56pub trait DamageOps {
57    fn deal_damage_ap(&mut self, action: DamageActionId, coef: f64, flags: DamageFlags);
58    fn deal_damage_ap_result(
59        &mut self,
60        action: DamageActionId,
61        coef: f64,
62        flags: DamageFlags,
63    ) -> DamageOutcome;
64    fn deal_damage_from_result(
65        &mut self,
66        action: DamageActionId,
67        parent: DamageOutcome,
68        multiplier: f64,
69        flags: DamageFlags,
70    ) -> DamageOutcome;
71    fn deal_profiled_damage_ap(
72        &mut self,
73        action: DamageActionId,
74        profile: DamageActionId,
75        coef: f64,
76        flags: DamageFlags,
77    );
78    fn haste_multiplier(&self) -> f64;
79    fn deal_damage_ap_to_target(
80        &mut self,
81        target: EnemyIdx,
82        action: DamageActionId,
83        coef: f64,
84        flags: DamageFlags,
85    );
86    fn deal_damage_ap_if_positive(
87        &mut self,
88        action: DamageActionId,
89        coefficient: f64,
90        flags: DamageFlags,
91    );
92    fn deal_effect_damage_ap(
93        &mut self,
94        effect: DamageEffectId,
95        multiplier: f64,
96        flags: DamageFlags,
97    );
98    fn deal_effect_damage_ap_with_geometry(
99        &mut self,
100        effect: DamageEffectId,
101        geometry_effect: DamageEffectId,
102        multiplier: f64,
103        flags: DamageFlags,
104    );
105    fn deal_effect_damage_sp_with_geometry(
106        &mut self,
107        effect: DamageEffectId,
108        geometry_effect: DamageEffectId,
109        multiplier: f64,
110        flags: DamageFlags,
111    );
112    fn deal_physical_damage_ap_if_positive(&mut self, action: DamageActionId, coefficient: f64);
113    fn deal_pet_damage_ap(&mut self, action: DamageActionId, coefficient: f64);
114    fn deal_pet_damage_ap_with_inheritance(
115        &mut self,
116        action: DamageActionId,
117        coefficient: f64,
118        inheritance_multiplier: f64,
119    );
120    fn deal_physical_pet_damage_ap(&mut self, action: DamageActionId, coefficient: f64);
121    fn deal_damage_sp(&mut self, action: DamageActionId, coef: f64, flags: DamageFlags);
122    fn deal_damage_sp_to_target(
123        &mut self,
124        target: EnemyIdx,
125        action: DamageActionId,
126        coef: f64,
127        flags: DamageFlags,
128    );
129    fn deal_profiled_damage_sp(
130        &mut self,
131        action: DamageActionId,
132        profile: DamageActionId,
133        coef: f64,
134        flags: DamageFlags,
135    );
136    fn deal_damage_flat(&mut self, action: DamageActionId, amount: f64);
137    fn deal_resolved_damage(&mut self, action: DamageActionId, amount: f64);
138    fn deal_triggered_damage(
139        &mut self,
140        effect: DamageEffectId,
141        multiplier: f64,
142        flags: DamageFlags,
143    ) -> bool;
144    fn deal_item_damage_sp(&mut self, action: DamageActionId);
145    fn deal_hook_flat_damage(&mut self, action: DamageActionId) -> bool;
146    fn effect_base_points(&self, effect: DamageEffectId) -> f64;
147    fn effect_points(&self, effect: DamageEffectId) -> f64;
148    fn effect_percent(&self, effect: DamageEffectId) -> f64;
149    fn effect_ap_coefficient(&self, effect: DamageEffectId) -> f64;
150    fn effect_sp_coefficient(&self, effect: DamageEffectId) -> f64;
151    fn effect_period_ms(&self, effect: DamageEffectId) -> u32;
152    fn action_proc_chance(&self, action: DamageActionId) -> f64;
153    fn action_gcd_ms(&self, action: DamageActionId) -> u32;
154    fn action_aura_duration_ms(&self, action: DamageActionId) -> u32;
155    fn action_aura_tick_ms(&self, action: DamageActionId) -> u32;
156    fn action_secondary_gain(&self, action: DamageActionId) -> f64;
157    fn action_hook_scalar(&self, action: DamageActionId) -> Option<f64>;
158    fn action_passive_direct_damage_mult(&self, action: DamageActionId) -> f64;
159    fn action_is_melee(&self, action: DamageActionId) -> bool;
160    fn action_has_direct_damage(&self, action: DamageActionId) -> bool;
161    fn action_requires_main_hand(&self, action: DamageActionId) -> bool;
162    fn action_requires_off_hand(&self, action: DamageActionId) -> bool;
163    fn action_suppresses_caster_procs(&self, action: DamageActionId) -> bool;
164    fn impact_has_label(&self, impact: ImpactEvent, label: i32) -> bool;
165    fn impact_is_physical(&self, impact: ImpactEvent) -> bool;
166    fn impact_is_nature(&self, impact: ImpactEvent) -> bool;
167    fn impact_generates_primary_resource(&self, impact: ImpactEvent) -> bool;
168    fn effect_affects_impact(&self, effect: DamageEffectId, impact: ImpactEvent) -> bool;
169    fn target_health_fraction(&self) -> f64;
170    fn player_swing_period_ms(&self, hand: SwingHand) -> Option<u32>;
171}
172
173/// Spell cooldown, charge, and cast-gate operations.
174pub trait CooldownOps {
175    fn spend_spell_charge(&mut self, spell: LocalSpellIdx) -> bool;
176    fn reduce_cooldown(&mut self, spell: LocalSpellIdx, amount_ms: u32);
177    fn reset_cooldown(&mut self, spell: LocalSpellIdx);
178    fn start_cooldown(&mut self, spell: LocalSpellIdx);
179    fn set_spell_gate(&mut self, spell: LocalSpellIdx, gate: SpellGate, available: bool);
180    fn grant_charges(&mut self, spell: LocalSpellIdx, amount: u8);
181    fn spell_cooldown_ms(&self, spell: LocalSpellIdx) -> u32;
182    fn spell_cooldown_remaining_ms(&self, spell: LocalSpellIdx) -> u32;
183    fn spell_ready(&self, spell: LocalSpellIdx) -> bool;
184    fn spell_current_charges(&self, spell: LocalSpellIdx) -> i32;
185}
186
187/// Player and persistent-pet resource operations.
188pub trait ResourceOps {
189    fn gain_resource(&mut self, amount: f64) -> f64;
190    fn gain_resource_from(&mut self, amount: f64, source: ResourceGainSource) -> f64;
191    fn gain_unmodified_resource_from(&mut self, amount: f64, source: ResourceGainSource) -> f64;
192    fn gain_secondary_resource(&mut self, amount: f64) -> f64;
193    fn gain_secondary_resource_from(&mut self, amount: f64, source: ResourceGainSource) -> f64;
194    fn primary_pet_resource(&self) -> Option<crate::PetResourceBinding>;
195    fn gain_pet_resource(&mut self, binding: crate::PetResourceBinding, amount: f64) -> f64;
196    fn spend_secondary_resource(&mut self, amount: f64) -> bool;
197    fn spend_all_secondary_resource(&mut self, cost: f64) -> f64;
198    fn secondary_resource(&self) -> f64;
199    fn primary_resource(&self) -> f64;
200    fn primary_resource_max(&self) -> f64;
201    fn primary_resource_fraction(&self) -> f64;
202    fn spell_resource_cost(&self, spell: LocalSpellIdx) -> f64;
203    fn last_primary_spent(&self) -> f64;
204    fn last_optional_primary_spent(&self) -> f64;
205    fn last_secondary_spent(&self) -> f64;
206}
207
208/// Deterministic proc rolls, attempt tracking, and driver counters.
209pub trait ProcOps {
210    fn roll_rppm(&mut self, idx: LocalRppmIdx) -> bool;
211    fn roll_threshold(&mut self, idx: LocalThresholdIdx, increment_scale: f64) -> bool;
212    fn roll_system_rppm(&mut self, binding: crate::SystemRppmBinding) -> bool;
213    fn proc_category_ready(&self, binding: crate::ProcCategoryBinding) -> bool;
214    fn start_proc_category_cooldown(&mut self, binding: crate::ProcCategoryBinding);
215    fn roll_accumulating_proc(
216        &mut self,
217        binding: crate::ProcCounterBinding,
218        chance_per_attempt: f64,
219    ) -> bool;
220    fn roll_attempt_proc(
221        &mut self,
222        binding: crate::ProcCounterBinding,
223        chance_for_attempt: impl FnOnce(u32) -> f64,
224    ) -> bool;
225    fn add_proc_counter(&mut self, binding: crate::ProcCounterBinding, amount: u32) -> u32;
226    fn reset_proc_counter(&mut self, binding: crate::ProcCounterBinding);
227    fn proc_counter(&self, binding: crate::ProcCounterBinding) -> u32;
228    fn mark_proc_flags_once(&mut self, binding: crate::ProcCounterBinding, flags: u32) -> bool;
229    fn consume_proc_counter(&mut self, binding: crate::ProcCounterBinding, amount: u32) -> u32;
230    fn advance_proc_counter_by(
231        &mut self,
232        binding: crate::ProcCounterBinding,
233        amount: u32,
234        threshold: u32,
235    ) -> bool;
236    fn advance_proc_counter(&mut self, binding: crate::ProcCounterBinding, threshold: u32) -> bool;
237}
238
239/// Delayed hook, periodic-driver, and ground-effect scheduling.
240pub trait SchedulingOps {
241    fn dispatch_free_action(&mut self, spell: LocalSpellIdx, source: FreeActionSource) -> bool;
242    fn dispatch_proc_spell(
243        &mut self,
244        spell: LocalSpellIdx,
245        proc_driver: crate::RppmBinding,
246        affected: ActorId,
247    ) -> bool;
248    fn schedule_hook(&mut self, delay_ms: u32, hook: CastHookFn);
249    fn trigger_periodic_driver(&mut self, driver: crate::PeriodicDriverBinding) -> bool;
250    fn trigger_periodic_driver_for(
251        &mut self,
252        driver: crate::PeriodicDriverBinding,
253        duration_ms: u32,
254    ) -> bool;
255    fn schedule_ground_effect(&mut self, effect: GroundEffectId) -> bool;
256}
257
258/// Temporary guardian lifecycle and command operations.
259pub trait GuardianOps {
260    /// Summons one guardian from the finalized specification.
261    ///
262    /// # Errors
263    ///
264    /// Returns an error when no runtime guardian slot is available.
265    fn summon_guardian(
266        &mut self,
267        spec: GuardianSpec,
268    ) -> Result<GuardianHandle, crate::GuardianSummonError>;
269    fn active_guardian_count(&self, tag: u32) -> usize;
270    fn extend_guardians(&mut self, tag: u32, amount_ms: u32);
271    fn command_guardians(&mut self, tag: u32, ability_index: usize) -> usize;
272    fn dismiss_guardians(&mut self, tag: u32, count: usize) -> usize;
273}