127 lines
2.6 KiB
Rust
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();
|
|
}
|
|
}
|