wowlab_engine_application/audit/data_values/
resources.rs1use wowlab_manifest_schema::{ResourceSection, SecondaryResourceSection};
4
5use super::{AuditSink, DATA_EPS};
6
7fn warn_if_drift(
8 literal: f64,
9 resolved: f64,
10 sink: &mut AuditSink,
11 message: impl FnOnce() -> String,
12) {
13 if (literal - resolved).abs() > DATA_EPS {
14 sink.warning(message());
15 }
16}
17
18pub(super) fn check_resource_values(
19 resource: &ResourceSection,
20 power_types: &[wowlab_types::data::PowerTypeFlat],
21 sink: &mut AuditSink,
22) {
23 let Some(power) = power_types
24 .iter()
25 .find(|power| power.power_type_enum == i32::from(resource.type_id))
26 else {
27 return;
28 };
29
30 if let Some(max) = resource.max {
31 warn_if_drift(max, f64::from(power.max_base_power), sink, || {
32 format!(
33 "resource {} max={max} != power_types max_base_power={}",
34 resource.name, power.max_base_power
35 )
36 });
37 }
38
39 if let Some(regen) = resource.regen {
40 warn_if_drift(regen, f64::from(power.regen_combat), sink, || {
41 format!(
42 "resource {} regen={regen} != power_types regen_combat={}",
43 resource.name, power.regen_combat
44 )
45 });
46 }
47
48 if let Some(start) = resource.starts_at {
49 warn_if_drift(start, f64::from(power.default_power), sink, || {
50 format!(
51 "resource {} starts_at={start} != power_types default_power={}",
52 resource.name, power.default_power
53 )
54 });
55 }
56}
57
58pub(super) fn check_secondary_resource_values(
59 resource: &SecondaryResourceSection,
60 power_types: &[wowlab_types::data::PowerTypeFlat],
61 sink: &mut AuditSink,
62) {
63 let Some(power) = power_types
64 .iter()
65 .find(|power| power.power_type_enum == i32::from(resource.type_id))
66 else {
67 return;
68 };
69
70 if let Some(max) = resource.max {
71 warn_if_drift(max, f64::from(power.max_base_power), sink, || {
72 format!(
73 "secondary_resource {} max={max} != power_types max_base_power={}",
74 resource.name, power.max_base_power
75 )
76 });
77 }
78}