use std::time::Duration; use anyhow::Result; use engine::prelude::*; use super::statistics::*; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct CharacterStatus { pub current_health: Health, pub current_mana: Mana, pub last_tick: Option, } impl CharacterStatus { pub fn new_full(stats: &Statistics) -> Self { CharacterStatus { current_health: stats.health, current_mana: stats.mana, last_tick: None, } } pub fn regen_tick(&mut self, stats: &Statistics) { if !self.is_dead() { self.add_health(stats.health_regeneration.raw(), stats); self.add_mana(stats.mana_regeneration.raw(), stats); } } pub fn use_ability(&mut self, cost: f32) -> bool { self.use_mana(cost) } pub fn add_health(&mut self, health: impl Into, stats: &Statistics) { let health_bonus = health.into(); self.current_health = if self.current_health + health_bonus > stats.health { stats.health } else { self.current_health + health_bonus } } pub fn add_mana(&mut self, mana: impl Into, stats: &Statistics) { let mana_bonus = mana.into(); self.current_mana = if self.current_mana + mana_bonus > stats.mana { stats.mana } else { self.current_mana + mana_bonus } } pub fn apply_damage(&mut self, cost: f32) -> bool { self.reduce_health(cost) } // returns false if there isn't enough mana left, otherwise true fn use_mana(&mut self, mana: impl Into) -> bool { let mana = mana.into(); if mana > self.current_mana { return false; } self.current_mana = self.current_mana - mana; true } // returns false if there isn't enough health present fn reduce_health(&mut self, health: impl Into) -> bool { let health = health.into(); if health > self.current_health { self.current_health = Health::from(0.0); return false; } self.current_health = self.current_health - health; true } pub fn is_dead(&self) -> bool { self.current_health == Health::from(0.0) } } impl EntityComponent for CharacterStatus { fn enable(&mut self, _scene: &mut Scene) -> Result<()> { self.last_tick = None; Ok(()) } fn name(&self) -> &str { Self::debug_name() } } impl ComponentDebug for CharacterStatus { fn debug_name() -> &'static str { "CharacterStatus" } }