Skip to main content

banished_core/
calendar.rs

1//! The game's calendar: the year, and the time since the year began.
2//!
3//! A year is 3,600 seconds of game time, with twelve months of 300 seconds.
4//!
5//! ```
6//! use banished_core::calendar::Calendar;
7//! use banished_core::scheduler::ticks;
8//!
9//! let mut calendar = Calendar::default();
10//! calendar.advance(ticks(3600.0));
11//! assert_eq!(calendar.year, 2);
12//! ```
13//!
14//! Original: `FUN_14009bfd0` (set-up), `FUN_14009b850` (update).
15// The calendar object is at Game/Game +0x128.
16use crate::scheduler::{seconds, ticks};
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19/// The year, and the game time since it began.
20pub struct Calendar {
21    /// The year, from 1.
22    pub year: u32,
23    // +0x08
24    /// The game time since the year began, in ticks. It is integer time, not a sum of rounded
25    /// float steps.
26    pub elapsed: i64,
27    // +0x10; DAT_14017895c
28    /// The length of a year: 3,600 seconds.
29    pub year_ticks: i64,
30}
31
32impl Default for Calendar {
33    fn default() -> Self {
34        Self {
35            year: 1,
36            elapsed: 0,
37            year_ticks: ticks(3600.0),
38        }
39    }
40}
41
42impl Calendar {
43    /// Add `delta` ticks. When a year is complete, the year goes up by one. Like the original, it
44    /// subtracts at most one year per call, even for a very large `delta`.
45    ///
46    /// Original: `FUN_14009b850` (inline calendar update).
47    pub fn advance(&mut self, delta: i64) {
48        self.elapsed += delta;
49        if self.elapsed >= self.year_ticks {
50            self.year = self.year.wrapping_add(1);
51            self.elapsed -= self.year_ticks;
52        }
53    }
54
55    /// The time since the year began, in seconds.
56    pub fn seconds(&self) -> f32 {
57        seconds(self.elapsed)
58    }
59}