2024-01-09 11:34:54 -08:00

81 lines
1.9 KiB
Rust

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<GameShipHandle, Ship>,
/// Ships indexed by the system they're in.
/// A ship must always be in exactly one system.
system_ship_table: HashMap<content::SystemHandle, Vec<GameShipHandle>>,
/// Systems indexed by which ships they contain.
/// A ship must always be in exactly one system.
ship_system_table: HashMap<GameShipHandle, content::SystemHandle>,
}
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<Item = &Ship> {
self.ships.values()
}
}