use std::collections::HashMap; use anyhow::{bail, Result}; use crate::{handle::SpriteHandle, Content, OutfitSpace}; pub(crate) mod syntax { use crate::part::shared; use serde::Deserialize; // Raw serde syntax structs. // These are never seen by code outside this crate. #[derive(Debug, Deserialize)] pub struct Outfit { pub engine: Option, pub steering: Option, pub space: shared::syntax::OutfitSpace, } #[derive(Debug, Deserialize)] pub struct Engine { pub thrust: f32, pub flare_sprite: String, } #[derive(Debug, Deserialize)] pub struct Steering { pub power: f32, } } /// Represents an outfit that may be attached to a ship. #[derive(Debug, Clone)] pub struct Outfit { /// The name of this outfit pub name: String, /// How much engine thrust this outfit produces pub engine_thrust: f32, /// How much steering power this outfit provids pub steer_power: f32, /// The engine flare sprite this outfit creates. /// Its location and size is determined by a ship's /// engine points. pub engine_flare_sprite: Option, /// How much space this outfit requires pub space: OutfitSpace, } impl crate::Build for Outfit { type InputSyntaxType = HashMap; fn build(outfits: Self::InputSyntaxType, ct: &mut Content) -> Result<()> { for (outfit_name, outfit) in outfits { let mut o = Self { name: outfit_name.clone(), engine_thrust: 0.0, steer_power: 0.0, engine_flare_sprite: None, space: OutfitSpace::from(outfit.space), }; // Engine stats if let Some(engine) = outfit.engine { let th = match ct.sprite_index.get(&engine.flare_sprite) { None => bail!( "In outfit `{}`: flare sprite `{}` doesn't exist", outfit_name, engine.flare_sprite ), Some(t) => *t, }; o.engine_thrust = engine.thrust; o.engine_flare_sprite = Some(th); } // Steering stats if let Some(steer) = outfit.steering { o.steer_power = steer.power; } ct.outfits.push(o); } return Ok(()); } }