Added gun content

master
Mark 2023-12-27 20:13:39 -08:00
parent aff7b3801f
commit c09974ba67
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
6 changed files with 113 additions and 39 deletions

2
assets

@ -1 +1 @@
Subproject commit e4972a4daff7bac077fb2d32c298e3d6af46da91 Subproject commit 5a444ca5c63aac4b4aca4866684859c08972f9e7

5
content/guns.toml Normal file
View File

@ -0,0 +1,5 @@
[gun."blaster"]
projectile.sprite = "projectile::blaster"
projectile.size = 100
projectile.speed = 300
projectile.lifetime = 2.0

59
src/content/gun.rs Normal file
View File

@ -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<Vec<Self>> {
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);
}
}

View File

@ -1,8 +1,10 @@
#![allow(dead_code)] #![allow(dead_code)]
mod gun;
mod ship; mod ship;
mod system; mod system;
pub use ship::{Engine, Gun, Ship}; pub use gun::{Gun, Projectile};
pub use ship::{Engine, Ship, ShipGun};
pub use system::{Object, System}; pub use system::{Object, System};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
@ -12,13 +14,15 @@ use toml;
use walkdir::WalkDir; use walkdir::WalkDir;
mod syntax { mod syntax {
use super::{ship, system, HashMap}; use super::HashMap;
use super::{gun, ship, system};
use serde::Deserialize; use serde::Deserialize;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Root { pub struct Root {
pub ship: HashMap<String, ship::syntax::Ship>, pub gun: Option<HashMap<String, gun::syntax::Gun>>,
pub system: HashMap<String, system::syntax::System>, pub ship: Option<HashMap<String, ship::syntax::Ship>>,
pub system: Option<HashMap<String, system::syntax::System>>,
} }
} }
@ -33,6 +37,25 @@ trait Build {
pub struct Content { pub struct Content {
pub systems: Vec<system::System>, pub systems: Vec<system::System>,
pub ships: Vec<ship::Ship>, pub ships: Vec<ship::Ship>,
pub guns: Vec<gun::Gun>,
}
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 { impl Content {
@ -44,34 +67,9 @@ impl Content {
} }
fn add_root(&mut self, root: syntax::Root) -> Result<()> { fn add_root(&mut self, root: syntax::Root) -> Result<()> {
let mut p = ship::Ship::build(&root)?; quick_name_dup_check!(self.systems, root, system::System::build);
for s in &self.ships { quick_name_dup_check!(self.guns, root, gun::Gun::build);
for o in &p { quick_name_dup_check!(self.ships, root, ship::Ship::build);
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);
return Ok(()); return Ok(());
} }
@ -79,6 +77,7 @@ impl Content {
let mut content = Self { let mut content = Self {
systems: Vec::new(), systems: Vec::new(),
ships: Vec::new(), ships: Vec::new(),
guns: Vec::new(),
}; };
for e in WalkDir::new(path).into_iter().filter_map(|e| e.ok()) { for e in WalkDir::new(path).into_iter().filter_map(|e| e.ok()) {

View File

@ -37,7 +37,7 @@ pub struct Ship {
pub sprite: String, pub sprite: String,
pub size: f32, pub size: f32,
pub engines: Vec<Engine>, pub engines: Vec<Engine>,
pub guns: Vec<Gun>, pub guns: Vec<ShipGun>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -47,7 +47,7 @@ pub struct Engine {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Gun { pub struct ShipGun {
pub pos: Point2<f32>, pub pos: Point2<f32>,
pub cooldown: f32, pub cooldown: f32,
pub active_cooldown: f32, pub active_cooldown: f32,
@ -55,8 +55,14 @@ pub struct Gun {
impl super::Build for Ship { impl super::Build for Ship {
fn build(root: &super::syntax::Root) -> Result<Vec<Self>> { fn build(root: &super::syntax::Root) -> Result<Vec<Self>> {
let ship = if let Some(ship) = &root.ship {
ship
} else {
return Ok(vec![]);
};
let mut out = Vec::new(); let mut out = Vec::new();
for (ship_name, ship) in &root.ship { for (ship_name, ship) in ship {
out.push(Self { out.push(Self {
name: ship_name.to_owned(), name: ship_name.to_owned(),
sprite: ship.sprite.to_owned(), sprite: ship.sprite.to_owned(),
@ -72,7 +78,7 @@ impl super::Build for Ship {
guns: ship guns: ship
.guns .guns
.iter() .iter()
.map(|e| Gun { .map(|e| ShipGun {
pos: Point2 { x: e.x, y: e.y }, pos: Point2 { x: e.x, y: e.y },
cooldown: 0.2, cooldown: 0.2,
active_cooldown: 0.0, active_cooldown: 0.0,

View File

@ -157,9 +157,14 @@ fn resolve_position(
impl super::Build for System { impl super::Build for System {
fn build(root: &super::syntax::Root) -> Result<Vec<Self>> { fn build(root: &super::syntax::Root) -> Result<Vec<Self>> {
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(); let mut objects = Vec::new();
for (label, obj) in &system.object { for (label, obj) in &system.object {