Galactica/src/game/outfits.rs
2023-12-30 16:57:03 -08:00

127 lines
2.6 KiB
Rust

use cgmath::{Deg, Point3};
use crate::{content, render::SubSprite};
/// Represents a gun attached to a specific ship at a certain gunpoint.
pub struct ShipGun {
pub kind: content::Gun,
pub cooldown: f32,
pub point: usize,
}
impl ShipGun {
pub fn new(kind: &content::Gun, point: usize) -> Self {
Self {
kind: kind.clone(),
point,
cooldown: 0.0,
}
}
}
/// Represents a specific outfit attached to a specific ship
pub enum ShipOutfit {
Gun(ShipGun),
Engine(content::Engine),
}
impl ShipOutfit {
pub fn gun(&mut self) -> Option<&mut ShipGun> {
match self {
Self::Gun(g) => Some(g),
_ => None,
}
}
pub fn engine(&self) -> Option<&content::Engine> {
match self {
Self::Engine(e) => Some(e),
_ => None,
}
}
}
pub struct ShipOutfits {
outfits: Vec<ShipOutfit>,
enginepoints: Vec<content::EnginePoint>,
gunpoints: Vec<content::GunPoint>,
// Minor performance optimization, since we
// rarely need to re-compute these.
engine_flare_sprites: Vec<SubSprite>,
}
impl<'a> ShipOutfits {
pub fn new(content: &content::Ship) -> Self {
Self {
outfits: Vec::new(),
enginepoints: content.engines.clone(),
gunpoints: content.guns.clone(),
engine_flare_sprites: vec![],
}
}
pub fn add(&mut self, o: ShipOutfit) {
self.outfits.push(o);
self.update_engine_flares();
}
pub fn iter_guns(&mut self) -> impl Iterator<Item = &mut ShipGun> {
self.outfits
.iter_mut()
.map(|x| x.gun())
.filter(|x| x.is_some())
.map(|x| x.unwrap())
}
pub fn iter_guns_points(&mut self) -> impl Iterator<Item = (&mut ShipGun, &content::GunPoint)> {
self.outfits
.iter_mut()
.map(|x| x.gun())
.filter(|x| x.is_some())
.map(|x| x.unwrap())
.map(|x| (&self.gunpoints[x.point], x))
.map(|(a, b)| (b, a))
}
pub fn iter_engines(&self) -> impl Iterator<Item = &content::Engine> {
self.outfits
.iter()
.map(|x| x.engine())
.filter(|x| x.is_some())
.map(|x| x.unwrap())
}
pub fn iter_enginepoints(&self) -> impl Iterator<Item = &content::EnginePoint> {
self.enginepoints.iter()
}
pub fn update_engine_flares(&mut self) {
// TODO: better way to pick flare texture
self.engine_flare_sprites.clear();
let t = if let Some(e) = self.iter_engines().next() {
e.flare_sprite_texture
} else {
return;
};
self.engine_flare_sprites = self
.iter_enginepoints()
.map(|p| SubSprite {
pos: Point3 {
x: p.pos.x,
y: p.pos.y,
z: 1.0,
},
texture: t,
angle: Deg(0.0),
size: p.size,
})
.collect();
}
pub fn get_engine_flares(&self) -> Vec<SubSprite> {
return self.engine_flare_sprites.clone();
}
}