Skip to main content

wowlab_engine_combat/state/
aura_state.rs

1use wowlab_types::sim::{ActorId, SimTime};
2
3use super::CombatInstance;
4
5#[rustfmt::skip]
6pub(crate) use wowlab_engine_domain::dbc::AuraState;
7
8const WOUNDED_20_THRESHOLD: f64 = 0.20;
9const WOUNDED_25_THRESHOLD: f64 = 0.25;
10const WOUNDED_35_THRESHOLD: f64 = 0.35;
11const WOUNDED_50_THRESHOLD: f64 = 0.50;
12const HEALTHY_75_THRESHOLD: f64 = 0.75;
13const HEALTHY_80_THRESHOLD: f64 = 0.80;
14
15impl CombatInstance {
16    /// Resolve health-derived and aura-granted state for either friendly or hostile actors.
17    #[must_use]
18    pub fn has_aura_state(
19        &self,
20        program: &crate::state::CombatProgram,
21        actor: ActorId,
22        required: AuraState,
23        now: SimTime,
24    ) -> bool {
25        let health = self.actor_health_fraction(program, actor, now);
26        let health_state = match required {
27            AuraState::Wounded20 => health.is_some_and(|value| value < WOUNDED_20_THRESHOLD),
28            AuraState::Wounded25 => health.is_some_and(|value| value < WOUNDED_25_THRESHOLD),
29            AuraState::Wounded35 => health.is_some_and(|value| value < WOUNDED_35_THRESHOLD),
30            AuraState::Wounded50 => health.is_some_and(|value| value < WOUNDED_50_THRESHOLD),
31            AuraState::Healthy75 => health.is_some_and(|value| value > HEALTHY_75_THRESHOLD),
32            AuraState::WoundHealth20OrAbove80 => health.is_some_and(|value| {
33                !(WOUNDED_20_THRESHOLD..=HEALTHY_80_THRESHOLD).contains(&value)
34            }),
35            AuraState::WoundHealth35OrAbove80 => health.is_some_and(|value| {
36                !(WOUNDED_35_THRESHOLD..=HEALTHY_80_THRESHOLD).contains(&value)
37            }),
38            _ => false,
39        };
40
41        if health_state {
42            return true;
43        }
44
45        program
46            .effects
47            .aura_state_auras(actor, required)
48            .iter()
49            .any(|entry| {
50                self.buffer
51                    .aura_at(entry.handle)
52                    .is_active(now.as_secs_f64())
53            })
54    }
55}
56
57#[cfg(test)]
58mod tests;