Skip to main content

lotus_shared/
time.rs

1//! Spielzeit-Darstellung, die zwischen Scripts und Engine geteilt wird.
2//!
3//! In-game time representation shared between scripts and the engine.
4
5#[cfg(feature = "bevy")]
6use bevy::{
7    prelude::{ReflectResource, Resource},
8    reflect::Reflect,
9};
10
11/// Aktuelle Simulationszeit basierend auf Unix-Mikrosekunden-Zeitstempeln.
12///
13/// Current simulation time based on Unix microsecond timestamps.
14#[cfg_attr(feature = "bevy", derive(Resource, Reflect, Debug, Clone, Copy))]
15#[cfg_attr(feature = "bevy", reflect(Resource))]
16pub struct GameTime {
17    #[cfg(feature = "engine")]
18    speed_multiplier: f32,
19    time_unix_micros: i64,
20}
21
22impl GameTime {
23    /// Gibt die aktuelle Zeit als Unix-Mikrosekunden zurück.
24    ///
25    /// Returns the current time as Unix microseconds.
26    pub fn time_unix_micros(&self) -> i64 {
27        self.time_unix_micros
28    }
29}
30
31#[cfg(feature = "engine")]
32mod _engine {
33    use time::PrimitiveDateTime;
34
35    use super::*;
36
37    const MICROS_IN_DAY: i64 = 86_400_000_000;
38
39    impl GameTime {
40        /// Erhöht die Simulationszeit um die angegebene Sekundenanzahl.
41        ///
42        /// Advances the simulation time by the given number of seconds.
43        pub fn increase(&mut self, seconds: f32) {
44            self.time_unix_micros += (seconds * 1_000_000.0 * self.speed_multiplier).round() as i64;
45        }
46
47        /// Gibt Tage seit der Frühlings-Tagundnachtgleiche 2024 zurück.
48        ///
49        /// Returns days since the vernal equinox of 2024.
50        pub fn days_since_vernal_equinox_24(&self) -> f64 {
51            let diff = self.time_unix_micros - 1_710_975_600_000_000;
52            diff as f64 / 86_400_000_000.0
53        }
54
55        /// Setzt die Simulationszeit aus Datum und Uhrzeit.
56        ///
57        /// Sets the simulation time from a calendar date and time.
58        pub fn set_time(&mut self, time: PrimitiveDateTime) {
59            self.time_unix_micros = (time.assume_utc().unix_timestamp_nanos() / 1_000) as i64;
60        }
61
62        /// Gibt den aktuellen Simulationsgeschwindigkeitsfaktor zurück.
63        ///
64        /// Returns the current simulation speed multiplier.
65        pub fn speed_multiplier(&self) -> f32 {
66            self.speed_multiplier
67        }
68
69        /// Setzt den Simulationsgeschwindigkeitsfaktor.
70        ///
71        /// Sets the simulation speed multiplier.
72        pub fn set_speed_multiplier(&mut self, speed_multiplier: f32) {
73            self.speed_multiplier = speed_multiplier;
74        }
75
76        /// Gibt die Tageszeit normalisiert auf 0–1 zurück.
77        ///
78        /// Returns the time of day normalized to 0-1
79        pub fn day_time(&self) -> f32 {
80            (self.time_unix_micros % MICROS_IN_DAY) as f32 / MICROS_IN_DAY as f32
81        }
82
83        /// Gibt den Wochentag zurück; 0 = Montag.
84        ///
85        /// Returns the day of the week, 0 = Monday
86        pub fn day_of_week(&self) -> u8 {
87            ((self.time_unix_micros / MICROS_IN_DAY + 3) % 7) as u8
88        }
89    }
90}
91
92#[cfg(feature = "time")]
93mod _time {
94    use time::{Date, Duration, PrimitiveDateTime, Time};
95
96    use super::*;
97
98    impl GameTime {
99        /// Wandelt die Simulationszeit in ein [`PrimitiveDateTime`] um.
100        ///
101        /// Converts the simulation time to a [`PrimitiveDateTime`].
102        pub fn primitive_date_time(&self) -> PrimitiveDateTime {
103            PrimitiveDateTime::new(
104                Date::from_calendar_date(1970, time::Month::January, 1).unwrap(),
105                Time::from_hms(0, 0, 0).unwrap(),
106            ) + Duration::new(
107                self.time_unix_micros / 1_000_000,
108                (self.time_unix_micros % 1_000_000 * 1_000) as i32,
109            )
110        }
111    }
112}
113
114impl GameTime {
115    /// Erstellt eine Spielzeit aus Unix-Mikrosekunden.
116    ///
117    /// Creates a game time from Unix microseconds.
118    pub fn from_unix_micros(unix_micros: i64) -> Self {
119        Self {
120            #[cfg(feature = "engine")]
121            speed_multiplier: 1.0,
122            time_unix_micros: unix_micros,
123        }
124    }
125}
126
127#[cfg(feature = "engine")]
128impl Default for GameTime {
129    fn default() -> Self {
130        Self {
131            speed_multiplier: 1.0,
132            time_unix_micros: 1_746_957_625_000_000,
133        }
134    }
135}