wowlab_engine_combat/context/hook/
proc_counters.rs1use crate::context::HookCtx;
2
3pub(super) fn add(ctx: &mut HookCtx<'_>, binding: crate::ProcCounterBinding, amount: u32) -> u32 {
4 let count = get(ctx, binding).saturating_add(amount);
5
6 if let Some(slot) = ctx
7 .instance
8 .runtime
9 .procs
10 .proc_counters
11 .get_mut(binding.as_usize())
12 {
13 *slot = count;
14 }
15
16 count
17}
18
19pub(super) fn reset(ctx: &mut HookCtx<'_>, binding: crate::ProcCounterBinding) {
20 if let Some(slot) = ctx
21 .instance
22 .runtime
23 .procs
24 .proc_counters
25 .get_mut(binding.as_usize())
26 {
27 *slot = 0;
28 }
29}
30
31pub(super) fn get(ctx: &HookCtx<'_>, binding: crate::ProcCounterBinding) -> u32 {
32 ctx.instance
33 .runtime
34 .procs
35 .proc_counters
36 .get(binding.as_usize())
37 .copied()
38 .unwrap_or(0)
39}
40
41pub(super) fn mark_once(
42 ctx: &mut HookCtx<'_>,
43 binding: crate::ProcCounterBinding,
44 flags: u32,
45) -> bool {
46 if flags == 0 {
47 return false;
48 }
49
50 let current = get(ctx, binding);
51
52 if current & flags != 0 {
53 return false;
54 }
55
56 if let Some(slot) = ctx
57 .instance
58 .runtime
59 .procs
60 .proc_counters
61 .get_mut(binding.as_usize())
62 {
63 *slot = current | flags;
64 }
65
66 true
67}
68
69pub(super) fn consume(
70 ctx: &mut HookCtx<'_>,
71 binding: crate::ProcCounterBinding,
72 amount: u32,
73) -> u32 {
74 let remaining = get(ctx, binding).saturating_sub(amount);
75
76 if remaining == 0 {
77 reset(ctx, binding);
78 } else if let Some(slot) = ctx
79 .instance
80 .runtime
81 .procs
82 .proc_counters
83 .get_mut(binding.as_usize())
84 {
85 *slot = remaining;
86 }
87
88 remaining
89}
90
91pub(super) fn advance(
92 ctx: &mut HookCtx<'_>,
93 binding: crate::ProcCounterBinding,
94 amount: u32,
95 threshold: u32,
96) -> bool {
97 if threshold == 0 {
98 return false;
99 }
100
101 let count = add(ctx, binding, amount);
102
103 if count >= threshold {
104 reset(ctx, binding);
105
106 true
107 } else {
108 false
109 }
110}