Added outfit space calculations
parent
19fd1a91f2
commit
0de278cb03
|
@ -1,5 +1,7 @@
|
||||||
[gun."blaster"]
|
[gun."blaster"]
|
||||||
|
|
||||||
|
space.weapon = 10
|
||||||
|
|
||||||
# Angle of fire cone
|
# Angle of fire cone
|
||||||
# Smaller angle = more accurate
|
# Smaller angle = more accurate
|
||||||
spread = 2
|
spread = 2
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
[outfit."plasma engines"]
|
[outfit."plasma engines"]
|
||||||
|
|
||||||
|
space.engine = 20
|
||||||
|
|
||||||
engine.thrust = 100
|
engine.thrust = 100
|
||||||
engine.flare_texture = "flare::ion"
|
engine.flare_texture = "flare::ion"
|
||||||
steering.power = 20
|
steering.power = 20
|
||||||
|
|
|
@ -6,6 +6,11 @@ hull = 200
|
||||||
linear_drag = 0.2
|
linear_drag = 0.2
|
||||||
angular_drag = 0.2
|
angular_drag = 0.2
|
||||||
|
|
||||||
|
|
||||||
|
space.outfit = 200
|
||||||
|
space.engine = 50
|
||||||
|
space.weapon = 50
|
||||||
|
|
||||||
engines = [{ x = 0.0, y = -1.05, size = 50.0 }]
|
engines = [{ x = 0.0, y = -1.05, size = 50.0 }]
|
||||||
guns = [{ x = 0.0, y = 1 }, { x = 0.1, y = 0.80 }, { x = -0.1, y = 0.80 }]
|
guns = [{ x = 0.0, y = 1 }, { x = 0.1, y = 0.80 }, { x = -0.1, y = 0.80 }]
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,9 @@ use toml;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
pub use handle::{FactionHandle, TextureHandle};
|
pub use handle::{FactionHandle, TextureHandle};
|
||||||
pub use part::{EnginePoint, Faction, Gun, GunPoint, Outfit, Relationship, Ship, System, Texture};
|
pub use part::{
|
||||||
|
EnginePoint, Faction, Gun, GunPoint, Outfit, OutfitSpace, Relationship, Ship, System, Texture,
|
||||||
|
};
|
||||||
|
|
||||||
mod syntax {
|
mod syntax {
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
|
|
|
@ -5,7 +5,10 @@ use cgmath::Deg;
|
||||||
|
|
||||||
use crate::{handle::TextureHandle, Content};
|
use crate::{handle::TextureHandle, Content};
|
||||||
|
|
||||||
|
use super::OutfitSpace;
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
|
use super::super::shared;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
// Raw serde syntax structs.
|
// Raw serde syntax structs.
|
||||||
// These are never seen by code outside this crate.
|
// These are never seen by code outside this crate.
|
||||||
|
@ -16,6 +19,7 @@ pub(crate) mod syntax {
|
||||||
pub spread: f32,
|
pub spread: f32,
|
||||||
pub rate: f32,
|
pub rate: f32,
|
||||||
pub rate_rng: f32,
|
pub rate_rng: f32,
|
||||||
|
pub space: shared::syntax::OutfitSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -53,6 +57,9 @@ pub struct Gun {
|
||||||
/// Random variation of projectile delay, in seconds.
|
/// Random variation of projectile delay, in seconds.
|
||||||
/// Each shot waits (rate += rate_rng).
|
/// Each shot waits (rate += rate_rng).
|
||||||
pub rate_rng: f32,
|
pub rate_rng: f32,
|
||||||
|
|
||||||
|
/// How much space this gun uses
|
||||||
|
pub space: OutfitSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a projectile that a [`Gun`] produces.
|
/// Represents a projectile that a [`Gun`] produces.
|
||||||
|
@ -98,6 +105,7 @@ impl crate::Build for Gun {
|
||||||
|
|
||||||
ct.guns.push(Self {
|
ct.guns.push(Self {
|
||||||
name: gun_name,
|
name: gun_name,
|
||||||
|
space: gun.space.into(),
|
||||||
spread: Deg(gun.spread),
|
spread: Deg(gun.spread),
|
||||||
rate: gun.rate,
|
rate: gun.rate,
|
||||||
rate_rng: gun.rate_rng,
|
rate_rng: gun.rate_rng,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
pub mod faction;
|
pub mod faction;
|
||||||
pub mod gun;
|
pub mod gun;
|
||||||
pub mod outfit;
|
pub mod outfit;
|
||||||
|
mod shared;
|
||||||
pub mod ship;
|
pub mod ship;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
pub mod texture;
|
pub mod texture;
|
||||||
|
@ -10,6 +11,7 @@ pub mod texture;
|
||||||
pub use faction::{Faction, Relationship};
|
pub use faction::{Faction, Relationship};
|
||||||
pub use gun::{Gun, Projectile};
|
pub use gun::{Gun, Projectile};
|
||||||
pub use outfit::Outfit;
|
pub use outfit::Outfit;
|
||||||
|
pub use shared::OutfitSpace;
|
||||||
pub use ship::{EnginePoint, GunPoint, Ship};
|
pub use ship::{EnginePoint, GunPoint, Ship};
|
||||||
pub use system::{Object, System};
|
pub use system::{Object, System};
|
||||||
pub use texture::Texture;
|
pub use texture::Texture;
|
||||||
|
|
|
@ -4,7 +4,10 @@ use anyhow::{bail, Result};
|
||||||
|
|
||||||
use crate::{handle::TextureHandle, Content};
|
use crate::{handle::TextureHandle, Content};
|
||||||
|
|
||||||
|
use super::OutfitSpace;
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
|
use super::super::shared;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
// Raw serde syntax structs.
|
// Raw serde syntax structs.
|
||||||
// These are never seen by code outside this crate.
|
// These are never seen by code outside this crate.
|
||||||
|
@ -13,6 +16,7 @@ pub(crate) mod syntax {
|
||||||
pub struct Outfit {
|
pub struct Outfit {
|
||||||
pub engine: Option<Engine>,
|
pub engine: Option<Engine>,
|
||||||
pub steering: Option<Steering>,
|
pub steering: Option<Steering>,
|
||||||
|
pub space: shared::syntax::OutfitSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -43,6 +47,9 @@ pub struct Outfit {
|
||||||
/// Its location and size is determined by a ship's
|
/// Its location and size is determined by a ship's
|
||||||
/// engine points.
|
/// engine points.
|
||||||
pub engine_flare_texture: Option<TextureHandle>,
|
pub engine_flare_texture: Option<TextureHandle>,
|
||||||
|
|
||||||
|
/// How much space this outfit requires
|
||||||
|
pub space: OutfitSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Build for Outfit {
|
impl crate::Build for Outfit {
|
||||||
|
@ -55,6 +62,7 @@ impl crate::Build for Outfit {
|
||||||
engine_thrust: 0.0,
|
engine_thrust: 0.0,
|
||||||
steer_power: 0.0,
|
steer_power: 0.0,
|
||||||
engine_flare_texture: None,
|
engine_flare_texture: None,
|
||||||
|
space: OutfitSpace::from(outfit.space),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Engine stats
|
// Engine stats
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
pub(crate) mod syntax {
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct OutfitSpace {
|
||||||
|
pub outfit: Option<u32>,
|
||||||
|
pub weapon: Option<u32>,
|
||||||
|
pub engine: Option<u32>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents outfit space, either that available in a ship
|
||||||
|
/// or that used by an outfit.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct OutfitSpace {
|
||||||
|
/// Total available outfit space.
|
||||||
|
/// This should be greater than weapon and engine.
|
||||||
|
pub outfit: u32,
|
||||||
|
|
||||||
|
/// Space for weapons
|
||||||
|
pub weapon: u32,
|
||||||
|
|
||||||
|
/// Space for engine
|
||||||
|
pub engine: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutfitSpace {
|
||||||
|
/// Make a new, zero OutfitSpace
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
outfit: 0,
|
||||||
|
weapon: 0,
|
||||||
|
engine: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Does this outfit contain `smaller`?
|
||||||
|
pub fn can_contain(&self, smaller: Self) -> bool {
|
||||||
|
self.outfit >= (smaller.outfit + smaller.weapon + smaller.engine)
|
||||||
|
&& self.weapon >= smaller.weapon
|
||||||
|
&& self.engine >= smaller.engine
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free outfit space
|
||||||
|
pub fn free(&mut self, rhs: &Self) {
|
||||||
|
self.outfit += rhs.outfit + rhs.weapon + rhs.engine;
|
||||||
|
self.weapon += rhs.weapon;
|
||||||
|
self.engine += rhs.engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Occupy outfit space
|
||||||
|
pub fn occupy(&mut self, rhs: &Self) {
|
||||||
|
self.outfit -= rhs.outfit + rhs.weapon + rhs.engine;
|
||||||
|
self.weapon -= rhs.weapon;
|
||||||
|
self.engine -= rhs.engine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<syntax::OutfitSpace> for OutfitSpace {
|
||||||
|
fn from(value: syntax::OutfitSpace) -> Self {
|
||||||
|
Self {
|
||||||
|
outfit: value.outfit.unwrap_or(0),
|
||||||
|
engine: value.engine.unwrap_or(0),
|
||||||
|
weapon: value.weapon.unwrap_or(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,12 @@ use nalgebra::{point, Point};
|
||||||
|
|
||||||
use crate::{handle::TextureHandle, Content};
|
use crate::{handle::TextureHandle, Content};
|
||||||
|
|
||||||
|
use super::OutfitSpace;
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
|
use super::super::shared;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
// Raw serde syntax structs.
|
// Raw serde syntax structs.
|
||||||
// These are never seen by code outside this crate.
|
// These are never seen by code outside this crate.
|
||||||
|
|
||||||
|
@ -22,6 +26,7 @@ pub(crate) mod syntax {
|
||||||
pub collision: Collision,
|
pub collision: Collision,
|
||||||
pub angular_drag: f32,
|
pub angular_drag: f32,
|
||||||
pub linear_drag: f32,
|
pub linear_drag: f32,
|
||||||
|
pub space: shared::syntax::OutfitSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -86,6 +91,9 @@ pub struct Ship {
|
||||||
|
|
||||||
/// Reduction in velocity over time
|
/// Reduction in velocity over time
|
||||||
pub linear_drag: f32,
|
pub linear_drag: f32,
|
||||||
|
|
||||||
|
/// Outfit space in this ship
|
||||||
|
pub space: OutfitSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collision shape for this ship
|
/// Collision shape for this ship
|
||||||
|
@ -138,6 +146,7 @@ impl crate::Build for Ship {
|
||||||
name: ship_name,
|
name: ship_name,
|
||||||
sprite_texture: th,
|
sprite_texture: th,
|
||||||
mass: ship.mass,
|
mass: ship.mass,
|
||||||
|
space: OutfitSpace::from(ship.space),
|
||||||
angular_drag: ship.angular_drag,
|
angular_drag: ship.angular_drag,
|
||||||
linear_drag: ship.linear_drag,
|
linear_drag: ship.linear_drag,
|
||||||
size,
|
size,
|
||||||
|
|
|
@ -53,7 +53,6 @@ impl Game {
|
||||||
let mut o2 = outfits::ShipOutfits::new(&ct.ships[0]);
|
let mut o2 = outfits::ShipOutfits::new(&ct.ships[0]);
|
||||||
o2.add(ct.outfits[0].clone());
|
o2.add(ct.outfits[0].clone());
|
||||||
o2.add_gun(ct.guns[0].clone());
|
o2.add_gun(ct.guns[0].clone());
|
||||||
println!("{:?}", o2);
|
|
||||||
let h3 = physics.add_ship(
|
let h3 = physics.add_ship(
|
||||||
&ct.ships[0],
|
&ct.ships[0],
|
||||||
o2,
|
o2,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use cgmath::{Deg, Point3};
|
use cgmath::{Deg, Point3};
|
||||||
use content::TextureHandle;
|
use content::{OutfitSpace, TextureHandle};
|
||||||
|
|
||||||
use crate::{content, render::SubSprite};
|
use crate::{content, render::SubSprite};
|
||||||
|
|
||||||
|
@ -67,6 +67,9 @@ impl OutfitStatSum {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ShipOutfits {
|
pub struct ShipOutfits {
|
||||||
pub stats: OutfitStatSum,
|
pub stats: OutfitStatSum,
|
||||||
|
pub total_space: OutfitSpace,
|
||||||
|
|
||||||
|
available_space: OutfitSpace,
|
||||||
outfits: Vec<content::Outfit>,
|
outfits: Vec<content::Outfit>,
|
||||||
guns: Vec<ShipGun>,
|
guns: Vec<ShipGun>,
|
||||||
enginepoints: Vec<content::EnginePoint>,
|
enginepoints: Vec<content::EnginePoint>,
|
||||||
|
@ -83,16 +86,30 @@ impl<'a> ShipOutfits {
|
||||||
stats: OutfitStatSum::new(),
|
stats: OutfitStatSum::new(),
|
||||||
outfits: Vec::new(),
|
outfits: Vec::new(),
|
||||||
guns: Vec::new(),
|
guns: Vec::new(),
|
||||||
|
available_space: content.space.clone(),
|
||||||
|
total_space: content.space.clone(),
|
||||||
enginepoints: content.engines.clone(),
|
enginepoints: content.engines.clone(),
|
||||||
gunpoints: content.guns.clone(),
|
gunpoints: content.guns.clone(),
|
||||||
engine_flare_sprites: vec![],
|
engine_flare_sprites: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Does this outfit set contain the specified outfit?
|
||||||
|
pub fn contains_outfit(&self, o: &content::Outfit) -> bool {
|
||||||
|
match self.outfits.iter().position(|x| x.name == o.name) {
|
||||||
|
Some(_) => true,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add an outfit to this ship.
|
/// Add an outfit to this ship.
|
||||||
/// Returns true on success, and false on failure
|
/// Returns true on success, and false on failure
|
||||||
/// TODO: failure reason enum
|
/// TODO: failure reason enum
|
||||||
pub fn add(&mut self, o: content::Outfit) -> bool {
|
pub fn add(&mut self, o: content::Outfit) -> bool {
|
||||||
|
if !self.available_space.can_contain(o.space) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.available_space.occupy(&o.space);
|
||||||
self.stats.add(&o);
|
self.stats.add(&o);
|
||||||
self.outfits.push(o);
|
self.outfits.push(o);
|
||||||
self.update_engine_flares();
|
self.update_engine_flares();
|
||||||
|
@ -100,10 +117,13 @@ impl<'a> ShipOutfits {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: is outfit in set?
|
/// TODO: is outfit in set?
|
||||||
/// TODO: don't remove nonexisting outfit
|
|
||||||
pub fn remove(&mut self, o: content::Outfit) {
|
pub fn remove(&mut self, o: content::Outfit) {
|
||||||
self.outfits
|
let i = match self.outfits.iter().position(|x| x.name == o.name) {
|
||||||
.remove(self.outfits.iter().position(|x| x.name == o.name).unwrap());
|
Some(i) => i,
|
||||||
|
None => panic!("Removed non-existing outfit"),
|
||||||
|
};
|
||||||
|
self.available_space.free(&o.space);
|
||||||
|
self.outfits.remove(i);
|
||||||
self.stats.remove(&o);
|
self.stats.remove(&o);
|
||||||
self.update_engine_flares();
|
self.update_engine_flares();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue