112 lines
2.4 KiB
Rust
Raw Normal View History

2023-12-27 20:13:39 -08:00
use anyhow::Result;
2023-12-28 17:04:41 -08:00
use cgmath::Deg;
2023-12-27 20:13:39 -08:00
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,
2023-12-28 17:04:41 -08:00
pub spread: f32,
pub rate: f32,
pub rate_rng: f32,
2023-12-27 20:13:39 -08:00
}
#[derive(Debug, Deserialize)]
pub struct Projectile {
pub sprite: String,
pub size: f32,
2023-12-28 17:04:41 -08:00
pub size_rng: f32,
2023-12-27 20:13:39 -08:00
pub speed: f32,
2023-12-28 17:04:41 -08:00
pub speed_rng: f32,
2023-12-27 20:13:39 -08:00
pub lifetime: f32,
2023-12-28 17:04:41 -08:00
pub lifetime_rng: f32,
pub damage: f32,
2023-12-27 20:13:39 -08:00
}
}
2023-12-29 15:46:09 -08:00
/// Represents a gun outfit.
2023-12-27 20:13:39 -08:00
#[derive(Debug, Clone)]
pub struct Gun {
2023-12-29 15:46:09 -08:00
/// The name of this gun
2023-12-27 20:13:39 -08:00
pub name: String,
2023-12-29 15:46:09 -08:00
/// The projectile this gun produces
2023-12-27 20:13:39 -08:00
pub projectile: Projectile,
2023-12-29 15:46:09 -08:00
/// The accuracy of this gun.
/// Projectiles can be off center up to
/// `spread / 2` degrees in both directions.
///
/// (Forming a "fire cone" of `spread` degrees)
2023-12-28 17:04:41 -08:00
pub spread: Deg<f32>,
2023-12-29 15:46:09 -08:00
/// Average delay between projectiles, in seconds.
2023-12-28 17:04:41 -08:00
pub rate: f32,
2023-12-29 15:46:09 -08:00
/// Random variation of projectile delay, in seconds.
/// Each shot waits (rate += rate_rng).
2023-12-28 17:04:41 -08:00
pub rate_rng: f32,
2023-12-27 20:13:39 -08:00
}
2023-12-29 15:46:09 -08:00
/// Represents a projectile that a [`Gun`] produces.
2023-12-27 20:13:39 -08:00
#[derive(Debug, Clone)]
pub struct Projectile {
2023-12-29 15:46:09 -08:00
/// The projectile sprite
2023-12-27 20:13:39 -08:00
pub sprite: String,
2023-12-29 15:46:09 -08:00
/// The average size of this projectile
/// (height in game units)
2023-12-27 20:13:39 -08:00
pub size: f32,
2023-12-29 15:46:09 -08:00
/// Random size variation
2023-12-28 17:04:41 -08:00
pub size_rng: f32,
2023-12-29 15:46:09 -08:00
/// The speed of this projectile, in game units / second
2023-12-27 20:13:39 -08:00
pub speed: f32,
2023-12-29 15:46:09 -08:00
/// Random speed variation
2023-12-28 17:04:41 -08:00
pub speed_rng: f32,
2023-12-29 15:46:09 -08:00
/// The lifespan of this projectile.
/// It will vanish if it lives this long without hitting anything.
2023-12-27 20:13:39 -08:00
pub lifetime: f32,
2023-12-29 15:46:09 -08:00
/// Random lifetime variation
2023-12-28 17:04:41 -08:00
pub lifetime_rng: f32,
2023-12-29 15:46:09 -08:00
/// The damage this projectile does
pub damage: f32,
2023-12-27 20:13:39 -08:00
}
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(),
2023-12-28 17:04:41 -08:00
spread: Deg(gun.spread),
rate: gun.rate,
rate_rng: gun.rate_rng,
2023-12-27 20:13:39 -08:00
projectile: Projectile {
sprite: gun.projectile.sprite.to_owned(),
size: gun.projectile.size,
2023-12-28 17:04:41 -08:00
size_rng: gun.projectile.size_rng,
2023-12-27 20:13:39 -08:00
speed: gun.projectile.speed,
2023-12-28 17:04:41 -08:00
speed_rng: gun.projectile.speed_rng,
2023-12-27 20:13:39 -08:00
lifetime: gun.projectile.lifetime,
2023-12-28 17:04:41 -08:00
lifetime_rng: gun.projectile.lifetime_rng,
damage: gun.projectile.damage,
2023-12-27 20:13:39 -08:00
},
});
}
return Ok(out);
}
}