use std::collections::HashMap; use crate::{ handles::GameShipHandle, ship::Ship, ship::{OutfitSet, ShipPersonality}, }; use galactica_content as content; /// Keeps track of all objects in the galaxy. /// This struct does NO physics, it keeps track of data exclusively. #[derive(Debug)] pub struct GameData { /// Universal counter. /// Used to create unique handles for game objects. index: u64, /// All ships in the galaxy ships: HashMap, /// Ships indexed by the system they're in. /// A ship must always be in exactly one system. system_ship_table: HashMap>, /// Systems indexed by which ships they contain. /// A ship must always be in exactly one system. ship_system_table: HashMap, } impl GameData { pub fn new(ct: &content::Content) -> Self { Self { system_ship_table: ct.iter_systems().map(|s| (s, Vec::new())).collect(), ship_system_table: HashMap::new(), index: 0, ships: HashMap::new(), } } /// Spawn a ship pub fn create_ship( &mut self, ct: &content::Content, ship: content::ShipHandle, faction: content::FactionHandle, personality: ShipPersonality, outfits: OutfitSet, system: &content::SystemHandle, ) -> GameShipHandle { let handle = GameShipHandle { index: self.index, content: ship, }; self.index += 1; self.ships.insert( handle, Ship::new(ct, handle, ship, faction, personality, outfits), ); self.system_ship_table.get_mut(system).unwrap().push(handle); self.ship_system_table.insert(handle, *system); return handle; } } // Public getters impl GameData { pub fn get_ship(&self, handle: GameShipHandle) -> Option<&Ship> { self.ships.get(&handle) } pub fn get_ship_mut(&mut self, handle: GameShipHandle) -> Option<&mut Ship> { self.ships.get_mut(&handle) } pub fn iter_ships(&self) -> impl Iterator { self.ships.values() } }