From 8ec3ece500211bb21f15904b73d0f1182a7cb7c7 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 9 Jan 2024 11:34:54 -0800 Subject: [PATCH] Added system logic --- crates/gameobject/src/gamedata.rs | 49 +++++++++++++++++++++---- crates/gameobject/src/handles.rs | 30 ++++++++++++++- crates/gameobject/src/projectile.rs | 20 ---------- crates/gameobject/src/ship/outfitset.rs | 4 +- crates/gameobject/src/ship/ship.rs | 17 ++++++++- 5 files changed, 88 insertions(+), 32 deletions(-) delete mode 100644 crates/gameobject/src/projectile.rs diff --git a/crates/gameobject/src/gamedata.rs b/crates/gameobject/src/gamedata.rs index 5252564..fd47b06 100644 --- a/crates/gameobject/src/gamedata.rs +++ b/crates/gameobject/src/gamedata.rs @@ -5,21 +5,33 @@ use crate::{ ship::Ship, ship::{OutfitSet, ShipPersonality}, }; -use content::ShipHandle; 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. + /// 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() -> Self { + 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(), } @@ -29,19 +41,40 @@ impl GameData { pub fn create_ship( &mut self, ct: &content::Content, - ship: ShipHandle, + ship: content::ShipHandle, faction: content::FactionHandle, personality: ShipPersonality, outfits: OutfitSet, + system: &content::SystemHandle, ) -> GameShipHandle { - let handle = GameShipHandle { index: self.index }; + let handle = GameShipHandle { + index: self.index, + content: ship, + }; self.index += 1; - self.ships - .insert(handle, Ship::new(ct, ship, faction, personality, outfits)); + + 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() + } } diff --git a/crates/gameobject/src/handles.rs b/crates/gameobject/src/handles.rs index 80ede15..7e8800a 100644 --- a/crates/gameobject/src/handles.rs +++ b/crates/gameobject/src/handles.rs @@ -1,5 +1,33 @@ +use std::hash::Hash; + +use galactica_content::ShipHandle; + /// A lightweight representation of a ship in the galaxy -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy)] pub struct GameShipHandle { + /// This ship's unique index pub(crate) index: u64, + + /// This ship's content handle + /// (technically redundant, but this greatly simplifies code) + pub(crate) content: ShipHandle, +} + +impl GameShipHandle { + pub fn content_handle(&self) -> ShipHandle { + self.content + } +} + +impl Hash for GameShipHandle { + fn hash(&self, state: &mut H) { + self.index.hash(state) + } +} + +impl Eq for GameShipHandle {} +impl PartialEq for GameShipHandle { + fn eq(&self, other: &Self) -> bool { + self.index.eq(&other.index) + } } diff --git a/crates/gameobject/src/projectile.rs b/crates/gameobject/src/projectile.rs deleted file mode 100644 index b9d05e8..0000000 --- a/crates/gameobject/src/projectile.rs +++ /dev/null @@ -1,20 +0,0 @@ -use galactica_content as content; - -// TODO: remove. projectiles only exist in physics - -#[derive(Debug)] -pub struct Projectile { - pub content: content::Projectile, - pub lifetime: f32, - pub faction: content::FactionHandle, -} - -impl Projectile { - pub fn tick(&mut self, t: f32) { - self.lifetime -= t; - } - - pub fn is_expired(&self) -> bool { - return self.lifetime < 0.0; - } -} diff --git a/crates/gameobject/src/ship/outfitset.rs b/crates/gameobject/src/ship/outfitset.rs index d614a28..ba4d6f5 100644 --- a/crates/gameobject/src/ship/outfitset.rs +++ b/crates/gameobject/src/ship/outfitset.rs @@ -29,7 +29,7 @@ pub enum OutfitRemoveResult { } /// A simple data class, used to keep track of delayed shield generators -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct ShieldGenerator { pub outfit: OutfitHandle, pub delay: f32, @@ -37,7 +37,7 @@ pub(crate) struct ShieldGenerator { } /// This struct keeps track of a ship's outfit loadout. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct OutfitSet { /// What outfits does this statsum contain? outfits: HashMap, diff --git a/crates/gameobject/src/ship/ship.rs b/crates/gameobject/src/ship/ship.rs index 4cdf1a5..d0fb0d1 100644 --- a/crates/gameobject/src/ship/ship.rs +++ b/crates/gameobject/src/ship/ship.rs @@ -1,11 +1,14 @@ 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, @@ -25,6 +28,7 @@ pub struct Ship { impl Ship { pub(crate) fn new( ct: &content::Content, + handle: GameShipHandle, ct_handle: content::ShipHandle, faction: content::FactionHandle, personality: ShipPersonality, @@ -33,6 +37,7 @@ impl Ship { let s = ct.get_ship(ct_handle); let shields = outfits.get_shield_strength(); Ship { + handle, ct_handle, faction, outfits, @@ -84,10 +89,20 @@ impl Ship { // 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 { - return self.hull; + self.hull } /// Get this ship's current shields.