From c09974ba67200bacd251ccdc2db9dbb33915264c Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 27 Dec 2023 20:13:39 -0800 Subject: [PATCH] Added gun content --- assets | 2 +- content/guns.toml | 5 ++++ src/content/gun.rs | 59 ++++++++++++++++++++++++++++++++++++++++ src/content/mod.rs | 63 +++++++++++++++++++++---------------------- src/content/ship.rs | 14 +++++++--- src/content/system.rs | 9 +++++-- 6 files changed, 113 insertions(+), 39 deletions(-) create mode 100644 content/guns.toml create mode 100644 src/content/gun.rs diff --git a/assets b/assets index e4972a4..5a444ca 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e4972a4daff7bac077fb2d32c298e3d6af46da91 +Subproject commit 5a444ca5c63aac4b4aca4866684859c08972f9e7 diff --git a/content/guns.toml b/content/guns.toml new file mode 100644 index 0000000..e2f2f38 --- /dev/null +++ b/content/guns.toml @@ -0,0 +1,5 @@ +[gun."blaster"] +projectile.sprite = "projectile::blaster" +projectile.size = 100 +projectile.speed = 300 +projectile.lifetime = 2.0 diff --git a/src/content/gun.rs b/src/content/gun.rs new file mode 100644 index 0000000..8a58d6c --- /dev/null +++ b/src/content/gun.rs @@ -0,0 +1,59 @@ +use anyhow::Result; + +pub(super) mod syntax { + use serde::Deserialize; + // Raw serde syntax structs. + // These are never seen by code outside this crate. + + #[derive(Debug, Deserialize)] + pub struct Gun { + pub projectile: Projectile, + } + + #[derive(Debug, Deserialize)] + pub struct Projectile { + pub sprite: String, + pub size: f32, + pub speed: f32, + pub lifetime: f32, + } +} + +#[derive(Debug, Clone)] +pub struct Gun { + pub name: String, + pub projectile: Projectile, +} + +#[derive(Debug, Clone)] +pub struct Projectile { + pub sprite: String, + pub size: f32, + pub speed: f32, + pub lifetime: f32, +} + +impl super::Build for Gun { + fn build(root: &super::syntax::Root) -> Result> { + let gun = if let Some(gun) = &root.gun { + gun + } else { + return Ok(vec![]); + }; + + let mut out = Vec::new(); + for (gun_name, gun) in gun { + out.push(Self { + name: gun_name.to_owned(), + projectile: Projectile { + sprite: gun.projectile.sprite.to_owned(), + size: gun.projectile.size, + speed: gun.projectile.speed, + lifetime: gun.projectile.lifetime, + }, + }); + } + + return Ok(out); + } +} diff --git a/src/content/mod.rs b/src/content/mod.rs index 373e408..95d62e0 100644 --- a/src/content/mod.rs +++ b/src/content/mod.rs @@ -1,8 +1,10 @@ #![allow(dead_code)] +mod gun; mod ship; mod system; -pub use ship::{Engine, Gun, Ship}; +pub use gun::{Gun, Projectile}; +pub use ship::{Engine, Ship, ShipGun}; pub use system::{Object, System}; use anyhow::{bail, Context, Result}; @@ -12,13 +14,15 @@ use toml; use walkdir::WalkDir; mod syntax { - use super::{ship, system, HashMap}; + use super::HashMap; + use super::{gun, ship, system}; use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct Root { - pub ship: HashMap, - pub system: HashMap, + pub gun: Option>, + pub ship: Option>, + pub system: Option>, } } @@ -33,6 +37,25 @@ trait Build { pub struct Content { pub systems: Vec, pub ships: Vec, + pub guns: Vec, +} + +macro_rules! quick_name_dup_check { + ($array:expr, $root:ident, $build:expr) => {{ + let mut p = $build(&$root)?; + for s in &$array { + for o in &p { + if s.name == o.name { + bail!( + "Error parsing content: duplicate ship names `{}` and `{}`", + s.name, + o.name + ) + } + } + } + $array.append(&mut p); + }}; } impl Content { @@ -44,34 +67,9 @@ impl Content { } fn add_root(&mut self, root: syntax::Root) -> Result<()> { - let mut p = ship::Ship::build(&root)?; - for s in &self.ships { - for o in &p { - if s.name == o.name { - bail!( - "Error parsing content: duplicate ship names {} and {}", - s.name, - o.name - ) - } - } - } - self.ships.append(&mut p); - - let mut p = system::System::build(&root)?; - for s in &self.systems { - for o in &p { - if s.name == o.name { - bail!( - "Error parsing content: duplicate system names {} and {}", - s.name, - o.name - ) - } - } - } - self.systems.append(&mut p); - + quick_name_dup_check!(self.systems, root, system::System::build); + quick_name_dup_check!(self.guns, root, gun::Gun::build); + quick_name_dup_check!(self.ships, root, ship::Ship::build); return Ok(()); } @@ -79,6 +77,7 @@ impl Content { let mut content = Self { systems: Vec::new(), ships: Vec::new(), + guns: Vec::new(), }; for e in WalkDir::new(path).into_iter().filter_map(|e| e.ok()) { diff --git a/src/content/ship.rs b/src/content/ship.rs index 1fe8a74..1ca6482 100644 --- a/src/content/ship.rs +++ b/src/content/ship.rs @@ -37,7 +37,7 @@ pub struct Ship { pub sprite: String, pub size: f32, pub engines: Vec, - pub guns: Vec, + pub guns: Vec, } #[derive(Debug, Clone)] @@ -47,7 +47,7 @@ pub struct Engine { } #[derive(Debug, Clone)] -pub struct Gun { +pub struct ShipGun { pub pos: Point2, pub cooldown: f32, pub active_cooldown: f32, @@ -55,8 +55,14 @@ pub struct Gun { impl super::Build for Ship { fn build(root: &super::syntax::Root) -> Result> { + let ship = if let Some(ship) = &root.ship { + ship + } else { + return Ok(vec![]); + }; + let mut out = Vec::new(); - for (ship_name, ship) in &root.ship { + for (ship_name, ship) in ship { out.push(Self { name: ship_name.to_owned(), sprite: ship.sprite.to_owned(), @@ -72,7 +78,7 @@ impl super::Build for Ship { guns: ship .guns .iter() - .map(|e| Gun { + .map(|e| ShipGun { pos: Point2 { x: e.x, y: e.y }, cooldown: 0.2, active_cooldown: 0.0, diff --git a/src/content/system.rs b/src/content/system.rs index df98cb6..14555e4 100644 --- a/src/content/system.rs +++ b/src/content/system.rs @@ -157,9 +157,14 @@ fn resolve_position( impl super::Build for System { fn build(root: &super::syntax::Root) -> Result> { - let mut out = Vec::new(); + let system = if let Some(system) = &root.system { + system + } else { + return Ok(vec![]); + }; - for (system_name, system) in &root.system { + let mut out = Vec::new(); + for (system_name, system) in system { let mut objects = Vec::new(); for (label, obj) in &system.object {