1use crate::pool::{MaxPoolLessThanMin, Pool};
7use bevy::prelude::Component;
8use core::fmt::{Display, Formatter};
9use core::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
10use derive_more::{Add, AddAssign, Sub, SubAssign};
11
12pub mod life {
14 use bevy::reflect::Reflect;
15
16 use crate::pool::RegeneratingPool;
17
18 use super::*;
19
20 #[derive(Debug, Clone, PartialEq, Component, Reflect)]
25 pub struct LifePool {
26 current: Life,
28 max: Life,
30 pub regen_per_second: Life,
32 }
33
34 impl LifePool {
35 pub fn new(current: Life, max: Life, regen_per_second: Life) -> Self {
41 assert!(current <= max);
42 assert!(current >= LifePool::MIN);
43 assert!(max >= LifePool::MIN);
44 Self {
45 current,
46 max,
47 regen_per_second,
48 }
49 }
50 }
51
52 #[derive(
56 Debug, Clone, Copy, PartialEq, PartialOrd, Default, Add, Sub, AddAssign, SubAssign, Reflect,
57 )]
58 pub struct Life(pub f32);
59
60 impl Mul<f32> for Life {
61 type Output = Life;
62
63 fn mul(self, rhs: f32) -> Life {
64 Life(self.0 * rhs)
65 }
66 }
67
68 impl Mul<Life> for f32 {
69 type Output = Life;
70
71 fn mul(self, rhs: Life) -> Life {
72 Life(self * rhs.0)
73 }
74 }
75
76 impl Div<f32> for Life {
77 type Output = Life;
78
79 fn div(self, rhs: f32) -> Life {
80 Life(self.0 / rhs)
81 }
82 }
83
84 impl Div<Life> for Life {
85 type Output = f32;
86
87 fn div(self, rhs: Life) -> f32 {
88 self.0 / rhs.0
89 }
90 }
91
92 impl Pool for LifePool {
93 type Quantity = Life;
94 const MIN: Life = Life(0.);
95
96 fn current(&self) -> Self::Quantity {
97 self.current
98 }
99
100 fn set_current(&mut self, new_quantity: Self::Quantity) -> Self::Quantity {
101 let actual_value = Life(new_quantity.0.clamp(0., self.max.0));
102 self.current = actual_value;
103 self.current
104 }
105
106 fn max(&self) -> Self::Quantity {
107 self.max
108 }
109
110 fn set_max(&mut self, new_max: Self::Quantity) -> Result<(), MaxPoolLessThanMin> {
111 if new_max < Self::MIN {
112 Err(MaxPoolLessThanMin)
113 } else {
114 self.max = new_max;
115 self.set_current(self.current);
116 Ok(())
117 }
118 }
119 }
120
121 impl RegeneratingPool for LifePool {
122 fn regen_per_second(&self) -> Self::Quantity {
123 self.regen_per_second
124 }
125
126 fn set_regen_per_second(&mut self, new_regen_per_second: Self::Quantity) {
127 self.regen_per_second = new_regen_per_second;
128 }
129
130 fn regenerate(&mut self, delta_time: std::time::Duration) {
131 self.set_current(self.current + self.regen_per_second * delta_time.as_secs_f32());
132 }
133 }
134
135 impl Add<Life> for LifePool {
136 type Output = Self;
137
138 fn add(mut self, rhs: Life) -> Self::Output {
139 self.set_current(self.current + rhs);
140 self
141 }
142 }
143
144 impl Sub<Life> for LifePool {
145 type Output = Self;
146
147 fn sub(mut self, rhs: Life) -> Self::Output {
148 self.set_current(self.current - rhs);
149 self
150 }
151 }
152
153 impl AddAssign<Life> for LifePool {
154 fn add_assign(&mut self, rhs: Life) {
155 self.set_current(self.current + rhs);
156 }
157 }
158
159 impl SubAssign<Life> for LifePool {
160 fn sub_assign(&mut self, rhs: Life) {
161 self.set_current(self.current - rhs);
162 }
163 }
164
165 impl Display for Life {
166 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
167 write!(f, "{}", self.0)
168 }
169 }
170
171 impl Display for LifePool {
172 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
173 write!(f, "{}/{}", self.current, self.max)
174 }
175 }
176}
177
178pub mod mana {
180 use bevy::reflect::Reflect;
181
182 use crate::pool::RegeneratingPool;
183
184 use super::*;
185
186 #[derive(Debug, Clone, PartialEq, Component, Reflect)]
191 pub struct ManaPool {
192 current: Mana,
194 max: Mana,
196 pub regen_per_second: Mana,
198 }
199
200 impl ManaPool {
201 pub fn new(current: Mana, max: Mana, regen_per_second: Mana) -> Self {
207 assert!(current <= max);
208 assert!(current >= ManaPool::MIN);
209 assert!(max >= ManaPool::MIN);
210 Self {
211 current,
212 max,
213 regen_per_second,
214 }
215 }
216 }
217
218 #[derive(
222 Debug, Clone, Copy, PartialEq, PartialOrd, Default, Add, Sub, AddAssign, SubAssign, Reflect,
223 )]
224 pub struct Mana(pub f32);
225
226 impl Mul<f32> for Mana {
227 type Output = Mana;
228
229 fn mul(self, rhs: f32) -> Mana {
230 Mana(self.0 * rhs)
231 }
232 }
233
234 impl Mul<Mana> for f32 {
235 type Output = Mana;
236
237 fn mul(self, rhs: Mana) -> Mana {
238 Mana(self * rhs.0)
239 }
240 }
241
242 impl Div<f32> for Mana {
243 type Output = Mana;
244
245 fn div(self, rhs: f32) -> Mana {
246 Mana(self.0 / rhs)
247 }
248 }
249
250 impl Div<Mana> for Mana {
251 type Output = f32;
252
253 fn div(self, rhs: Mana) -> f32 {
254 self.0 / rhs.0
255 }
256 }
257
258 impl Pool for ManaPool {
259 type Quantity = Mana;
260 const MIN: Mana = Mana(0.);
261
262 fn current(&self) -> Self::Quantity {
263 self.current
264 }
265
266 fn set_current(&mut self, new_quantity: Self::Quantity) -> Self::Quantity {
267 let actual_value = Mana(new_quantity.0.clamp(0., self.max.0));
268 self.current = actual_value;
269 self.current
270 }
271
272 fn max(&self) -> Self::Quantity {
273 self.max
274 }
275
276 fn set_max(&mut self, new_max: Self::Quantity) -> Result<(), MaxPoolLessThanMin> {
277 if new_max < Self::MIN {
278 Err(MaxPoolLessThanMin)
279 } else {
280 self.max = new_max;
281 self.set_current(self.current);
282 Ok(())
283 }
284 }
285 }
286
287 impl RegeneratingPool for ManaPool {
288 fn regen_per_second(&self) -> Self::Quantity {
289 self.regen_per_second
290 }
291
292 fn set_regen_per_second(&mut self, new_regen_per_second: Self::Quantity) {
293 self.regen_per_second = new_regen_per_second;
294 }
295
296 fn regenerate(&mut self, delta_time: std::time::Duration) {
297 self.set_current(self.current + self.regen_per_second * delta_time.as_secs_f32());
298 }
299 }
300
301 impl Add<Mana> for ManaPool {
302 type Output = Self;
303
304 fn add(mut self, rhs: Mana) -> Self::Output {
305 self.set_current(self.current + rhs);
306 self
307 }
308 }
309
310 impl Sub<Mana> for ManaPool {
311 type Output = Self;
312
313 fn sub(mut self, rhs: Mana) -> Self::Output {
314 self.set_current(self.current - rhs);
315 self
316 }
317 }
318
319 impl AddAssign<Mana> for ManaPool {
320 fn add_assign(&mut self, rhs: Mana) {
321 self.set_current(self.current + rhs);
322 }
323 }
324
325 impl SubAssign<Mana> for ManaPool {
326 fn sub_assign(&mut self, rhs: Mana) {
327 self.set_current(self.current - rhs);
328 }
329 }
330
331 impl Display for Mana {
332 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
333 write!(f, "{}", self.0)
334 }
335 }
336
337 impl Display for ManaPool {
338 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
339 write!(f, "{}/{}", self.current, self.max)
340 }
341 }
342}