2023-12-30 10:58:17 -08:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
use anyhow::{bail, Result};
|
2023-12-27 19:51:58 -08:00
|
|
|
use cgmath::Point2;
|
2023-12-30 10:58:17 -08:00
|
|
|
use nalgebra::{point, Point};
|
|
|
|
|
|
|
|
use crate::{Content, TextureHandle};
|
2023-12-27 19:51:58 -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 Ship {
|
2023-12-30 11:25:51 -08:00
|
|
|
pub sprite_texture: String,
|
2023-12-27 19:51:58 -08:00
|
|
|
pub size: f32,
|
|
|
|
pub engines: Vec<Engine>,
|
|
|
|
pub guns: Vec<Gun>,
|
2023-12-29 12:21:56 -08:00
|
|
|
pub hull: f32,
|
2023-12-30 11:07:20 -08:00
|
|
|
pub mass: f32,
|
2023-12-30 10:58:17 -08:00
|
|
|
pub collision: Collision,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct Collision {
|
|
|
|
pub points: Vec<[f32; 2]>,
|
|
|
|
pub indices: Vec<[u32; 2]>,
|
2023-12-27 19:51:58 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct Engine {
|
|
|
|
pub x: f32,
|
|
|
|
pub y: f32,
|
|
|
|
pub size: f32,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct Gun {
|
|
|
|
pub x: f32,
|
|
|
|
pub y: f32,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Processed data structs.
|
|
|
|
// These are exported.
|
|
|
|
|
2023-12-29 15:46:09 -08:00
|
|
|
/// Represents a ship chassis.
|
2023-12-27 19:51:58 -08:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Ship {
|
2023-12-29 15:46:09 -08:00
|
|
|
/// This ship's name
|
2023-12-27 19:51:58 -08:00
|
|
|
pub name: String,
|
2023-12-29 15:46:09 -08:00
|
|
|
|
|
|
|
/// This ship's sprite
|
2023-12-30 11:25:51 -08:00
|
|
|
pub sprite_texture: TextureHandle,
|
2023-12-29 15:46:09 -08:00
|
|
|
|
|
|
|
/// The size of this ship.
|
|
|
|
/// Measured as unrotated height,
|
|
|
|
/// in terms of game units.
|
2023-12-27 19:51:58 -08:00
|
|
|
pub size: f32,
|
2023-12-29 15:46:09 -08:00
|
|
|
|
2023-12-30 11:07:20 -08:00
|
|
|
/// The mass of this ship
|
|
|
|
pub mass: f32,
|
|
|
|
|
2023-12-29 15:46:09 -08:00
|
|
|
/// Engine points on this ship.
|
|
|
|
/// This is where engine flares are drawn.
|
2023-12-28 17:04:41 -08:00
|
|
|
pub engines: Vec<EnginePoint>,
|
2023-12-29 15:46:09 -08:00
|
|
|
|
|
|
|
/// Gun points on this ship.
|
|
|
|
/// A gun outfit can be mounted on each.
|
2023-12-28 17:04:41 -08:00
|
|
|
pub guns: Vec<GunPoint>,
|
2023-12-29 15:46:09 -08:00
|
|
|
|
|
|
|
/// This ship's hull strength
|
2023-12-29 12:21:56 -08:00
|
|
|
pub hull: f32,
|
2023-12-30 10:58:17 -08:00
|
|
|
|
|
|
|
/// Collision shape for this ship
|
|
|
|
pub collision: Collision,
|
|
|
|
|
|
|
|
/// Remove later
|
|
|
|
pub aspect: f32,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Collision shape for this ship
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Collision {
|
|
|
|
pub points: Vec<Point<f32, 2>>,
|
|
|
|
pub indices: Vec<[u32; 2]>,
|
2023-12-27 19:51:58 -08:00
|
|
|
}
|
|
|
|
|
2023-12-29 15:46:09 -08:00
|
|
|
/// An engine point on a ship.
|
|
|
|
/// This is where flares are drawn.
|
2023-12-27 19:51:58 -08:00
|
|
|
#[derive(Debug, Clone)]
|
2023-12-28 17:04:41 -08:00
|
|
|
pub struct EnginePoint {
|
2023-12-29 15:46:09 -08:00
|
|
|
/// This engine point's position, in game units,
|
|
|
|
/// relative to the ship's center.
|
2023-12-27 19:51:58 -08:00
|
|
|
pub pos: Point2<f32>,
|
2023-12-29 15:46:09 -08:00
|
|
|
|
|
|
|
/// The size of the flare that should be drawn
|
|
|
|
/// at this point, measured as height in game units.
|
2023-12-27 19:51:58 -08:00
|
|
|
pub size: f32,
|
|
|
|
}
|
|
|
|
|
2023-12-29 15:46:09 -08:00
|
|
|
/// A gun point on a ship.
|
2023-12-27 19:51:58 -08:00
|
|
|
#[derive(Debug, Clone)]
|
2023-12-28 17:04:41 -08:00
|
|
|
pub struct GunPoint {
|
2023-12-29 15:46:09 -08:00
|
|
|
/// This gun point's position, in game units,
|
|
|
|
/// relative to the ship's center.
|
2023-12-27 19:51:58 -08:00
|
|
|
pub pos: Point2<f32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl super::Build for Ship {
|
2023-12-30 10:58:17 -08:00
|
|
|
type InputSyntax = HashMap<String, syntax::Ship>;
|
|
|
|
|
|
|
|
fn build(ship: Self::InputSyntax, ct: &mut Content) -> Result<()> {
|
2023-12-27 20:13:39 -08:00
|
|
|
for (ship_name, ship) in ship {
|
2023-12-30 11:25:51 -08:00
|
|
|
let th = match ct.texture_index.get(&ship.sprite_texture) {
|
2023-12-30 10:58:17 -08:00
|
|
|
None => bail!(
|
|
|
|
"In ship `{}`: texture `{}` doesn't exist",
|
|
|
|
ship_name,
|
2023-12-30 11:25:51 -08:00
|
|
|
ship.sprite_texture
|
2023-12-30 10:58:17 -08:00
|
|
|
),
|
|
|
|
Some(t) => *t,
|
|
|
|
};
|
|
|
|
|
2023-12-30 11:07:20 -08:00
|
|
|
let size = ship.size;
|
|
|
|
let aspect = th.aspect;
|
|
|
|
|
2023-12-30 10:58:17 -08:00
|
|
|
ct.ships.push(Self {
|
|
|
|
aspect,
|
2023-12-30 11:07:20 -08:00
|
|
|
name: ship_name,
|
2023-12-30 11:25:51 -08:00
|
|
|
sprite_texture: th,
|
2023-12-30 11:07:20 -08:00
|
|
|
mass: ship.mass,
|
2023-12-28 20:19:33 -08:00
|
|
|
size,
|
2023-12-29 12:21:56 -08:00
|
|
|
hull: ship.hull,
|
2023-12-27 19:51:58 -08:00
|
|
|
engines: ship
|
|
|
|
.engines
|
|
|
|
.iter()
|
2023-12-28 17:04:41 -08:00
|
|
|
.map(|e| EnginePoint {
|
2023-12-28 20:19:33 -08:00
|
|
|
pos: Point2 {
|
2023-12-30 10:58:17 -08:00
|
|
|
x: e.x * size * aspect / 2.0,
|
|
|
|
y: e.y * size / 2.0,
|
2023-12-28 20:19:33 -08:00
|
|
|
},
|
2023-12-27 19:51:58 -08:00
|
|
|
size: e.size,
|
|
|
|
})
|
|
|
|
.collect(),
|
|
|
|
guns: ship
|
|
|
|
.guns
|
|
|
|
.iter()
|
2023-12-28 17:04:41 -08:00
|
|
|
.map(|e| GunPoint {
|
2023-12-28 20:19:33 -08:00
|
|
|
pos: Point2 {
|
2023-12-30 10:58:17 -08:00
|
|
|
x: e.x * size * aspect / 2.0,
|
|
|
|
y: e.y * size / 2.0,
|
2023-12-28 20:19:33 -08:00
|
|
|
},
|
2023-12-27 19:51:58 -08:00
|
|
|
})
|
|
|
|
.collect(),
|
2023-12-30 10:58:17 -08:00
|
|
|
collision: Collision {
|
|
|
|
indices: ship.collision.indices.clone(),
|
|
|
|
points: ship
|
|
|
|
.collision
|
|
|
|
.points
|
|
|
|
.iter()
|
|
|
|
.map(|x| point![x[0] * (size / 2.0) * aspect, x[1] * size / 2.0])
|
|
|
|
.collect(),
|
|
|
|
},
|
2023-12-27 19:51:58 -08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-12-30 10:58:17 -08:00
|
|
|
return Ok(());
|
2023-12-27 19:51:58 -08:00
|
|
|
}
|
|
|
|
}
|