Skip to main content

nil_core/resources/
workforce.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use crate::city::Stability;
5use crate::infrastructure::building::BuildingLevel;
6use derive_more::{Deref, From, Into};
7use nil_num::impl_mul_ceil;
8use nil_num::ops::MulCeil;
9use serde::{Deserialize, Serialize};
10use std::cmp::Ordering;
11use std::num::NonZeroU32;
12use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
13
14/// Workforce is a special resource used to construct buildings and recruit troops.
15/// The amount generated per round will always be equal to the level of the relevant building.
16///
17/// Unlike other resources, workforce should never accumulate for the next round.
18/// Anything that is not used should be discarded.
19#[derive(
20  Clone, Copy, Debug, Deref, From, Into, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize,
21)]
22#[into(u32, f64)]
23pub struct Workforce(u32);
24
25impl Workforce {
26  #[inline]
27  pub const fn new(value: u32) -> Self {
28    Self(value)
29  }
30}
31
32impl From<BuildingLevel> for Workforce {
33  fn from(value: BuildingLevel) -> Self {
34    Workforce(u32::from(value))
35  }
36}
37
38impl From<f64> for Workforce {
39  fn from(value: f64) -> Self {
40    debug_assert!(value.is_finite());
41    Self::new(value as u32)
42  }
43}
44
45impl PartialEq<u32> for Workforce {
46  fn eq(&self, other: &u32) -> bool {
47    self.0.eq(other)
48  }
49}
50
51impl PartialOrd<u32> for Workforce {
52  fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
53    self.0.partial_cmp(other)
54  }
55}
56
57impl Add for Workforce {
58  type Output = Workforce;
59
60  fn add(self, rhs: Self) -> Self::Output {
61    Self(self.0.saturating_add(rhs.0))
62  }
63}
64
65impl AddAssign for Workforce {
66  fn add_assign(&mut self, rhs: Self) {
67    *self = *self + rhs;
68  }
69}
70
71impl Sub for Workforce {
72  type Output = Workforce;
73
74  fn sub(self, rhs: Self) -> Self::Output {
75    Self(self.0.saturating_sub(rhs.0))
76  }
77}
78
79impl SubAssign for Workforce {
80  fn sub_assign(&mut self, rhs: Self) {
81    *self = *self - rhs;
82  }
83}
84
85impl Mul for Workforce {
86  type Output = Workforce;
87
88  fn mul(self, rhs: Workforce) -> Self::Output {
89    Self(self.0.saturating_mul(rhs.0))
90  }
91}
92
93impl Mul<u32> for Workforce {
94  type Output = Workforce;
95
96  fn mul(self, rhs: u32) -> Self::Output {
97    Self(self.0.saturating_mul(rhs))
98  }
99}
100
101impl Mul<f64> for Workforce {
102  type Output = f64;
103
104  fn mul(self, rhs: f64) -> Self::Output {
105    f64::from(self.0) * rhs
106  }
107}
108
109impl Mul<NonZeroU32> for Workforce {
110  type Output = Workforce;
111
112  fn mul(self, rhs: NonZeroU32) -> Self::Output {
113    self * rhs.get()
114  }
115}
116
117impl Mul<Stability> for Workforce {
118  type Output = Workforce;
119
120  fn mul(self, rhs: Stability) -> Self::Output {
121    Self::from(self.mul_ceil(*rhs))
122  }
123}
124
125impl MulAssign for Workforce {
126  fn mul_assign(&mut self, rhs: Self) {
127    *self = *self * rhs;
128  }
129}
130
131impl MulAssign<Stability> for Workforce {
132  fn mul_assign(&mut self, rhs: Stability) {
133    *self = *self * rhs;
134  }
135}
136
137impl_mul_ceil!(Workforce);