steel_core/world/
sleep_status.rs1use crate::{
2 entity::{Entity, LivingEntity},
3 player::Player,
4};
5
6#[derive(Debug, Clone, Copy, Default)]
7pub(super) struct SleepStatus {
8 active_players: i32,
9 sleeping_players: i32,
10}
11
12impl SleepStatus {
13 #[must_use]
14 pub(super) fn are_enough_sleeping(self, sleep_percentage_needed: i32) -> bool {
15 self.sleeping_players >= self.sleepers_needed(sleep_percentage_needed)
16 }
17
18 #[must_use]
19 pub(super) fn sleepers_needed(self, sleep_percentage_needed: i32) -> i32 {
20 let sleepers =
21 ((self.active_players as f32 * sleep_percentage_needed as f32) / 100.0).ceil() as i32;
22 sleepers.max(1)
23 }
24
25 pub(super) const fn remove_all_sleepers(&mut self) {
26 self.sleeping_players = 0;
27 }
28
29 #[must_use]
30 pub(super) const fn amount_sleeping(self) -> i32 {
31 self.sleeping_players
32 }
33
34 pub(super) fn add_player(&mut self, player: &Player) {
35 if player.is_spectator() {
36 return;
37 }
38 self.active_players += 1;
39 if player.is_sleeping() {
40 self.sleeping_players += 1;
41 }
42 }
43
44 pub(super) const fn update(&mut self, updated: Self) -> bool {
45 let old_active_players = self.active_players;
46 let old_sleeping_players = self.sleeping_players;
47 *self = updated;
48
49 (old_sleeping_players > 0 || self.sleeping_players > 0)
50 && (old_active_players != self.active_players
51 || old_sleeping_players != self.sleeping_players)
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::SleepStatus;
58
59 #[test]
60 fn sleepers_needed_matches_vanilla_percentage_rule() {
61 let status = SleepStatus {
62 active_players: 3,
63 sleeping_players: 0,
64 };
65
66 assert_eq!(status.sleepers_needed(0), 1);
67 assert_eq!(status.sleepers_needed(1), 1);
68 assert_eq!(status.sleepers_needed(50), 2);
69 assert_eq!(status.sleepers_needed(100), 3);
70 assert_eq!(status.sleepers_needed(101), 4);
71 }
72}