use std::time::Instant; use crate::GameShipHandle; use super::{OutfitSet, ShipPersonality}; use galactica_content as content; #[derive(Debug)] pub struct Ship { // Metadata values handle: GameShipHandle, ct_handle: content::ShipHandle, faction: content::FactionHandle, outfits: OutfitSet, personality: ShipPersonality, // State values // TODO: unified ship stats struct, like outfit space hull: f32, shields: f32, // Utility values /// The last time this ship was damaged last_hit: Instant, } impl Ship { pub(crate) fn new( ct: &content::Content, handle: GameShipHandle, ct_handle: content::ShipHandle, faction: content::FactionHandle, personality: ShipPersonality, outfits: OutfitSet, ) -> Self { let s = ct.get_ship(ct_handle); let shields = outfits.get_shield_strength(); Ship { handle, ct_handle, faction, outfits, personality, 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; } } } } } } // Misc getters, so internal state is untouchable impl Ship { /// Get a handle to this ship game object pub fn get_handle(&self) -> GameShipHandle { self.handle } /// Get a handle to this ship's content pub fn get_content(&self) -> content::ShipHandle { self.ct_handle } /// Get this ship's current hull. /// Use content handle to get maximum hull pub fn get_hull(&self) -> f32 { self.hull } /// Get this ship's current shields. /// Use get_outfits() for maximum shields pub fn get_shields(&self) -> f32 { self.shields } /// Get all outfits on this ship pub fn get_outfits(&self) -> &OutfitSet { &self.outfits } /// Get this ship's personality pub fn get_personality(&self) -> ShipPersonality { self.personality } /// Get this ship's faction pub fn get_faction(&self) -> content::FactionHandle { self.faction } /// Get this ship's content handle pub fn get_ship(&self) -> content::ShipHandle { self.ct_handle } }