Skip to main content

steel_core/player/
sleep_state.rs

1/// Vanilla sleep-counter cap and "slept long enough" threshold.
2pub(super) const SLEEP_DURATION: i32 = 100;
3/// Vanilla wake-animation duration.
4const WAKE_UP_DURATION: i32 = 10;
5
6#[derive(Debug, Clone, Copy)]
7pub(super) struct PlayerSleepState {
8    sleep_counter: i32,
9}
10
11impl PlayerSleepState {
12    #[must_use]
13    pub(super) const fn new() -> Self {
14        Self { sleep_counter: 0 }
15    }
16
17    #[must_use]
18    pub(super) const fn sleep_counter(self) -> i32 {
19        self.sleep_counter
20    }
21
22    pub(super) const fn set_sleep_counter(&mut self, sleep_counter: i32) {
23        self.sleep_counter = sleep_counter;
24    }
25
26    pub(super) const fn tick_sleep_counter(&mut self, is_sleeping: bool) {
27        if is_sleeping {
28            self.sleep_counter += 1;
29            if self.sleep_counter > SLEEP_DURATION {
30                self.sleep_counter = SLEEP_DURATION;
31            }
32        } else if self.sleep_counter > 0 {
33            self.sleep_counter += 1;
34            if self.sleep_counter >= SLEEP_DURATION + WAKE_UP_DURATION {
35                self.sleep_counter = 0;
36            }
37        }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::PlayerSleepState;
44
45    #[test]
46    fn sleep_counter_matches_vanilla_wake_animation_window() {
47        let mut state = PlayerSleepState::new();
48
49        state.set_sleep_counter(99);
50        state.tick_sleep_counter(true);
51        state.tick_sleep_counter(true);
52        assert_eq!(state.sleep_counter(), 100);
53
54        state.tick_sleep_counter(false);
55        assert_eq!(state.sleep_counter(), 101);
56
57        for _ in 0..9 {
58            state.tick_sleep_counter(false);
59        }
60        assert_eq!(state.sleep_counter(), 0);
61    }
62}