wowlab_engine_combat/systems/cooldowns/
categories.rs1use super::{CombatInstance, Event, LocalSpellIdx, SimTime, SpellData, project_members};
2
3pub(super) fn start_one_charge_category(
4 program: &crate::state::CombatProgram,
5 state: &mut CombatInstance,
6 spell: &SpellData,
7 members: &[LocalSpellIdx],
8 recharge_ms: u32,
9 now: SimTime,
10) {
11 let Some(_) = spell
12 .cooldown
13 .charge_category
14 .filter(|_| !spell.is_charged())
15 else {
16 return;
17 };
18
19 if recharge_ms == 0 {
20 return;
21 }
22
23 let ready_at = state.runtime.pools.charge_category_ready_at.start_for(
24 members.first().copied().unwrap_or_else(|| {
25 debug_assert!(false, "charge category has no finalized members");
26
27 LocalSpellIdx::new(0)
28 }),
29 now,
30 SimTime::from_millis(recharge_ms),
31 );
32
33 for member in members.iter().copied() {
34 state
35 .runtime
36 .pools
37 .charge_category_ready_at
38 .start(member, ready_at);
39 state.schedule(Event::CooldownReady {
40 t: ready_at,
41 spell: program.scheduled_spell(member),
42 });
43 }
44
45 project_members(program, state, members);
46}
47
48pub(super) fn start_regular_category(
49 program: &crate::state::CombatProgram,
50 state: &mut CombatInstance,
51 spell_local: LocalSpellIdx,
52 spell: &SpellData,
53 category_cooldown_ms: u32,
54 now: SimTime,
55) {
56 let Some(_) = spell.cooldown.cooldown_category else {
57 return;
58 };
59
60 if category_cooldown_ms == 0 {
61 return;
62 }
63
64 let ready_at = state.runtime.pools.cooldown_category_ready_at.start_for(
65 spell_local,
66 now,
67 SimTime::from_millis(category_cooldown_ms),
68 );
69 let members: &[LocalSpellIdx] = program
70 .cooldown_category_members
71 .get(spell_local.as_usize())
72 .map_or(&[], Box::as_ref);
73
74 for member in members.iter().copied() {
75 state
76 .runtime
77 .pools
78 .cooldown_category_ready_at
79 .start(member, ready_at);
80 state.schedule(Event::CooldownReady {
81 t: ready_at,
82 spell: program.scheduled_spell(member),
83 });
84 }
85
86 project_members(program, state, members);
87}