use serde::{Deserialize, Serialize};
const HUNGER_THRESHOLD: u8 = 100;
const CRANKY_THRESHOLD: u8 = 50;
const TOILET_THRESHOLD: u8 = 50;
const SICK_HUNGER_THRESHOLD: u8 = 150;
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq)]
pub struct Vitals {
hp: Stat,
hunger: Stat,
happiness: Stat,
comfort: Stat,
}
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
pub struct Stat(u8);
impl Stat {
pub fn modify(&mut self, level: i8) {
if level.is_negative() {
self.0 = self.0.saturating_sub(level.wrapping_abs() as u8);
} else {
self.0 = self.0.saturating_add(level.wrapping_abs() as u8);
}
}
pub fn get(&self) -> u8 {
self.0
}
pub fn is_zero(&self) -> bool {
self.0 == 0
}
}
impl Default for Vitals {
fn default() -> Vitals {
Vitals {
hp: Stat(100),
hunger: Stat(50),
happiness: Stat(100),
comfort: Stat(100),
}
}
}
impl Vitals {
pub fn hp(&self) -> u8 {
self.hp.get()
}
pub fn modify_hunger(&mut self, level: i8) {
if !self.is_cranky() {
self.hunger.modify(level);
}
}
pub fn modify_happiness(&mut self, level: i8) {
self.happiness.modify(level);
}
pub fn modify_comfort(&mut self, level: i8) {
self.comfort.modify(level);
}
pub fn modify_hp(&mut self, level: i8) {
self.hp.modify(level);
}
pub fn is_sick(&self) -> bool {
self.hunger.get() >= SICK_HUNGER_THRESHOLD || self.happiness.is_zero()
}
pub fn is_alive(&self) -> bool {
!self.hp.is_zero()
}
pub fn is_cranky(&self) -> bool {
self.happiness.get() <= CRANKY_THRESHOLD
}
pub fn is_poop(&self) -> bool {
self.comfort.is_zero()
}
pub fn needs_food(&self) -> bool {
self.hunger.get() >= HUNGER_THRESHOLD
}
pub fn needs_toilet(&self) -> bool {
self.comfort.get() <= TOILET_THRESHOLD
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stat_modify() {
let mut stat = Stat(3);
stat.modify(-4);
assert_eq!(stat.get(), 0);
stat = Stat(4);
stat.modify(1);
assert_eq!(stat.get(), 5);
}
}