From 1b9e1f2877cfdb761d2d4a160be06747ecc5d299 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 8 Jan 2024 23:05:07 -0800 Subject: [PATCH] Added more gameobject infrastructure --- crates/gameobject/src/gamedata.rs | 47 +++++++++++++++++++ crates/gameobject/src/handles.rs | 5 ++ crates/gameobject/src/lib.rs | 9 ++-- crates/gameobject/src/ship/mod.rs | 2 + crates/gameobject/src/ship/personality.rs | 14 ++++++ crates/gameobject/src/ship/ship.rs | 57 +++++++++++++++++++---- 6 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 crates/gameobject/src/gamedata.rs create mode 100644 crates/gameobject/src/handles.rs create mode 100644 crates/gameobject/src/ship/personality.rs diff --git a/crates/gameobject/src/gamedata.rs b/crates/gameobject/src/gamedata.rs new file mode 100644 index 0000000..5252564 --- /dev/null +++ b/crates/gameobject/src/gamedata.rs @@ -0,0 +1,47 @@ +use std::collections::HashMap; + +use crate::{ + handles::GameShipHandle, + 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. +pub struct GameData { + // Universal counter. + // Used to create unique handles for game objects. + index: u64, + ships: HashMap, +} + +impl GameData { + pub fn new() -> Self { + Self { + index: 0, + ships: HashMap::new(), + } + } + + /// Spawn a ship + pub fn create_ship( + &mut self, + ct: &content::Content, + ship: ShipHandle, + faction: content::FactionHandle, + personality: ShipPersonality, + outfits: OutfitSet, + ) -> GameShipHandle { + let handle = GameShipHandle { index: self.index }; + self.index += 1; + self.ships + .insert(handle, Ship::new(ct, ship, faction, personality, outfits)); + return handle; + } + + pub fn get_ship(&self, handle: GameShipHandle) -> Option<&Ship> { + self.ships.get(&handle) + } +} diff --git a/crates/gameobject/src/handles.rs b/crates/gameobject/src/handles.rs new file mode 100644 index 0000000..80ede15 --- /dev/null +++ b/crates/gameobject/src/handles.rs @@ -0,0 +1,5 @@ +/// A lightweight representation of a ship in the galaxy +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct GameShipHandle { + pub(crate) index: u64, +} diff --git a/crates/gameobject/src/lib.rs b/crates/gameobject/src/lib.rs index 003dfcd..71ba7dd 100644 --- a/crates/gameobject/src/lib.rs +++ b/crates/gameobject/src/lib.rs @@ -4,10 +4,11 @@ //! of every ship in the game, but it has no understanding of physics. //! That is done in `galactica_world`. -mod projectile; -mod ship; +mod gamedata; +mod handles; +pub mod ship; mod system; -pub use projectile::Projectile; -pub use ship::Ship; +pub use gamedata::*; +pub use handles::*; pub use system::{System, SystemObject}; diff --git a/crates/gameobject/src/ship/mod.rs b/crates/gameobject/src/ship/mod.rs index 9f8e1c6..e1b4d54 100644 --- a/crates/gameobject/src/ship/mod.rs +++ b/crates/gameobject/src/ship/mod.rs @@ -1,5 +1,7 @@ mod outfitset; +mod personality; mod ship; pub use outfitset::*; +pub use personality::*; pub use ship::*; diff --git a/crates/gameobject/src/ship/personality.rs b/crates/gameobject/src/ship/personality.rs new file mode 100644 index 0000000..031d8b5 --- /dev/null +++ b/crates/gameobject/src/ship/personality.rs @@ -0,0 +1,14 @@ +/// Computer-controlled ship behavior variants. +/// This is just a list, actual physics-aware +/// behaviors are implemented in [`galactica-behavior`] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ShipPersonality { + /// This ship is controlled by a player + Player, + + /// Does nothing + Dummy, + + /// Points and shoots towards the nearest enemy + Point, +} diff --git a/crates/gameobject/src/ship/ship.rs b/crates/gameobject/src/ship/ship.rs index 5f76f08..4cdf1a5 100644 --- a/crates/gameobject/src/ship/ship.rs +++ b/crates/gameobject/src/ship/ship.rs @@ -1,30 +1,33 @@ use std::time::Instant; -use super::OutfitSet; +use super::{OutfitSet, ShipPersonality}; use galactica_content as content; #[derive(Debug)] pub struct Ship { // Metadata values - pub ct_handle: content::ShipHandle, - pub faction: content::FactionHandle, - pub outfits: OutfitSet, + ct_handle: content::ShipHandle, + faction: content::FactionHandle, + outfits: OutfitSet, + + personality: ShipPersonality, // State values - // TODO: unified ship stats struct, like space - pub hull: f32, - pub shields: f32, + // TODO: unified ship stats struct, like outfit space + hull: f32, + shields: f32, // Utility values /// The last time this ship was damaged - pub last_hit: Instant, + last_hit: Instant, } impl Ship { - pub fn new( + pub(crate) fn new( ct: &content::Content, ct_handle: content::ShipHandle, faction: content::FactionHandle, + personality: ShipPersonality, outfits: OutfitSet, ) -> Self { let s = ct.get_ship(ct_handle); @@ -33,6 +36,7 @@ impl Ship { ct_handle, faction, outfits, + personality, last_hit: Instant::now(), // Initial stats @@ -77,3 +81,38 @@ impl Ship { } } } + +// Misc getters, so internal state is untouchable +impl Ship { + /// Get this ship's current hull. + /// Use content handle to get maximum hull + pub fn get_hull(&self) -> f32 { + return 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 + } +}