use std::time::Instant; use super::OutfitSet; use galactica_content as content; #[derive(Debug)] pub struct Ship { // Metadata values pub ct_handle: content::ShipHandle, pub faction: content::FactionHandle, pub outfits: OutfitSet, // State values // TODO: unified ship stats struct, like space pub hull: f32, pub shields: f32, // Utility values /// The last time this ship was damaged pub last_hit: Instant, } impl Ship { pub fn new( ct: &content::Content, ct_handle: content::ShipHandle, faction: content::FactionHandle, outfits: OutfitSet, ) -> Self { let s = ct.get_ship(ct_handle); let shields = outfits.get_shield_strength(); Ship { ct_handle, faction, outfits, last_hit: Instant::now(), // Initial stats hull: s.hull, shields, } } /// If this ship is dead, it will be removed from the game. pub fn is_dead(&self) -> bool { self.hull <= 0.0 } /// Hit this ship with the given amount of damage pub fn apply_damage(&mut self, mut d: f32) { if self.is_dead() { return; } if self.shields >= d { self.shields -= d } else { d -= self.shields; self.shields = 0.0; self.hull = 0f32.max(self.hull - d); } self.last_hit = Instant::now(); } /// Update this ship's state by `t` seconds pub fn step(&mut self, t: f32) { let time_since = self.last_hit.elapsed().as_secs_f32(); if self.shields != self.outfits.get_shield_strength() { for g in self.outfits.iter_shield_generators() { if time_since >= g.delay { self.shields += g.generation * t; if self.shields > self.outfits.get_shield_strength() { self.shields = self.outfits.get_shield_strength(); break; } } } } } }