Merged guns and outfits
parent
7b264c7c3e
commit
0095a23dd6
|
@ -1,37 +0,0 @@
|
||||||
[gun."blaster"]
|
|
||||||
|
|
||||||
space.weapon = 10
|
|
||||||
|
|
||||||
# Average delay between shots
|
|
||||||
rate = 0.2
|
|
||||||
# Random rate variation (each cooldown is +- this)
|
|
||||||
rate_rng = 0.1
|
|
||||||
|
|
||||||
# TODO: apply force to ship on fire
|
|
||||||
projectile.sprite = "projectile::blaster"
|
|
||||||
# Height of projectile in game units
|
|
||||||
projectile.size = 6
|
|
||||||
projectile.size_rng = 0.0
|
|
||||||
# Speed of projectile, in game units/second
|
|
||||||
projectile.speed = 300
|
|
||||||
projectile.speed_rng = 10.0
|
|
||||||
# Lifetime of projectile, in seconds
|
|
||||||
projectile.lifetime = 2.0
|
|
||||||
projectile.lifetime_rng = 0.2
|
|
||||||
projectile.damage = 10.0
|
|
||||||
# Random variation of firing angle.
|
|
||||||
# If this is 0, the projectile always goes straight.
|
|
||||||
# If this is 10, projectiles will form a cone of 10 degrees
|
|
||||||
# ( 5 degrees on each side )
|
|
||||||
projectile.angle_rng = 2
|
|
||||||
# How much force this projectile will apply to an object it hits
|
|
||||||
projectile.force = 0.0
|
|
||||||
|
|
||||||
projectile.collider.ball.radius = 2.0
|
|
||||||
|
|
||||||
projectile.impact_effect = "blaster impact"
|
|
||||||
|
|
||||||
projectile.expire_effect.sprite = "particle::blaster"
|
|
||||||
projectile.expire_effect.lifetime = "inherit"
|
|
||||||
projectile.expire_effect.size = 3.0
|
|
||||||
projectile.expire_effect.velocity_scale_parent = 1.0
|
|
|
@ -14,3 +14,42 @@ space.outfit = 5
|
||||||
shield.generation = 10
|
shield.generation = 10
|
||||||
shield.strength = 500
|
shield.strength = 500
|
||||||
shield.delay = 2.0
|
shield.delay = 2.0
|
||||||
|
|
||||||
|
|
||||||
|
[outfit."blaster"]
|
||||||
|
|
||||||
|
space.weapon = 10
|
||||||
|
|
||||||
|
# Average delay between shots
|
||||||
|
gun.rate = 0.2
|
||||||
|
# Random rate variation (each cooldown is +- this)
|
||||||
|
gun.rate_rng = 0.1
|
||||||
|
|
||||||
|
# TODO: apply force to ship on fire
|
||||||
|
gun.projectile.sprite = "projectile::blaster"
|
||||||
|
# Height of projectile in game units
|
||||||
|
gun.projectile.size = 6
|
||||||
|
gun.projectile.size_rng = 0.0
|
||||||
|
# Speed of projectile, in game units/second
|
||||||
|
gun.projectile.speed = 300
|
||||||
|
gun.projectile.speed_rng = 10.0
|
||||||
|
# Lifetime of projectile, in seconds
|
||||||
|
gun.projectile.lifetime = 2.0
|
||||||
|
gun.projectile.lifetime_rng = 0.2
|
||||||
|
gun.projectile.damage = 10.0
|
||||||
|
# Random variation of firing angle.
|
||||||
|
# If this is 0, the projectile always goes straight.
|
||||||
|
# If this is 10, projectiles will form a cone of 10 degrees
|
||||||
|
# ( 5 degrees on each side )
|
||||||
|
gun.projectile.angle_rng = 2
|
||||||
|
# How much force this projectile will apply to an object it hits
|
||||||
|
gun.projectile.force = 0.0
|
||||||
|
|
||||||
|
gun.projectile.collider.ball.radius = 2.0
|
||||||
|
|
||||||
|
gun.projectile.impact_effect = "blaster impact"
|
||||||
|
|
||||||
|
gun.projectile.expire_effect.sprite = "particle::blaster"
|
||||||
|
gun.projectile.expire_effect.lifetime = "inherit"
|
||||||
|
gun.projectile.expire_effect.size = 3.0
|
||||||
|
gun.projectile.expire_effect.velocity_scale_parent = 1.0
|
||||||
|
|
|
@ -28,11 +28,10 @@ mod syntax {
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{collections::HashMap, fmt::Display, hash::Hash};
|
use std::{collections::HashMap, fmt::Display, hash::Hash};
|
||||||
|
|
||||||
use crate::part::{effect, faction, gun, outfit, ship, sprite, system};
|
use crate::part::{effect, faction, outfit, ship, sprite, system};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Root {
|
pub struct Root {
|
||||||
pub gun: Option<HashMap<String, gun::syntax::Gun>>,
|
|
||||||
pub ship: Option<HashMap<String, ship::syntax::Ship>>,
|
pub ship: Option<HashMap<String, ship::syntax::Ship>>,
|
||||||
pub system: Option<HashMap<String, system::syntax::System>>,
|
pub system: Option<HashMap<String, system::syntax::System>>,
|
||||||
pub outfit: Option<HashMap<String, outfit::syntax::Outfit>>,
|
pub outfit: Option<HashMap<String, outfit::syntax::Outfit>>,
|
||||||
|
@ -69,7 +68,6 @@ mod syntax {
|
||||||
impl Root {
|
impl Root {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
gun: None,
|
|
||||||
ship: None,
|
ship: None,
|
||||||
system: None,
|
system: None,
|
||||||
outfit: None,
|
outfit: None,
|
||||||
|
@ -80,7 +78,6 @@ mod syntax {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge(&mut self, other: Root) -> Result<()> {
|
pub fn merge(&mut self, other: Root) -> Result<()> {
|
||||||
merge_hashmap(&mut self.gun, other.gun).with_context(|| "while merging guns")?;
|
|
||||||
merge_hashmap(&mut self.ship, other.ship).with_context(|| "while merging ships")?;
|
merge_hashmap(&mut self.ship, other.ship).with_context(|| "while merging ships")?;
|
||||||
merge_hashmap(&mut self.system, other.system)
|
merge_hashmap(&mut self.system, other.system)
|
||||||
.with_context(|| "while merging systems")?;
|
.with_context(|| "while merging systems")?;
|
||||||
|
@ -241,9 +238,6 @@ impl Content {
|
||||||
if root.ship.is_some() {
|
if root.ship.is_some() {
|
||||||
part::ship::Ship::build(root.ship.take().unwrap(), &mut build_context, &mut content)?;
|
part::ship::Ship::build(root.ship.take().unwrap(), &mut build_context, &mut content)?;
|
||||||
}
|
}
|
||||||
if root.gun.is_some() {
|
|
||||||
part::gun::Gun::build(root.gun.take().unwrap(), &mut build_context, &mut content)?;
|
|
||||||
}
|
|
||||||
if root.outfit.is_some() {
|
if root.outfit.is_some() {
|
||||||
part::outfit::Outfit::build(
|
part::outfit::Outfit::build(
|
||||||
root.outfit.take().unwrap(),
|
root.outfit.take().unwrap(),
|
||||||
|
|
|
@ -1,186 +0,0 @@
|
||||||
use anyhow::{bail, Context, Result};
|
|
||||||
use cgmath::{Deg, Rad};
|
|
||||||
use serde::Deserialize;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::{handle::SpriteHandle, Content};
|
|
||||||
|
|
||||||
use crate::{ContentBuildContext, EffectHandle, OutfitSpace};
|
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
|
||||||
use crate::part::effect;
|
|
||||||
use crate::part::outfitspace;
|
|
||||||
use serde::Deserialize;
|
|
||||||
// Raw serde syntax structs.
|
|
||||||
// These are never seen by code outside this crate.
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct Gun {
|
|
||||||
pub projectile: Projectile,
|
|
||||||
pub rate: f32,
|
|
||||||
pub rate_rng: f32,
|
|
||||||
pub space: outfitspace::syntax::OutfitSpace,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct Projectile {
|
|
||||||
pub sprite: String,
|
|
||||||
pub size: f32,
|
|
||||||
pub size_rng: f32,
|
|
||||||
pub speed: f32,
|
|
||||||
pub speed_rng: f32,
|
|
||||||
pub lifetime: f32,
|
|
||||||
pub lifetime_rng: f32,
|
|
||||||
pub damage: f32,
|
|
||||||
pub angle_rng: f32,
|
|
||||||
pub impact_effect: Option<effect::syntax::EffectReference>,
|
|
||||||
pub expire_effect: Option<effect::syntax::EffectReference>,
|
|
||||||
pub collider: super::ProjectileCollider,
|
|
||||||
pub force: f32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines a projectile's collider
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
|
||||||
pub enum ProjectileCollider {
|
|
||||||
/// A ball collider
|
|
||||||
#[serde(rename = "ball")]
|
|
||||||
Ball(BallCollider),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A simple ball-shaped collider, centered at the object's position
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
|
||||||
pub struct BallCollider {
|
|
||||||
/// The radius of this ball
|
|
||||||
pub radius: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a gun outfit.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Gun {
|
|
||||||
/// The name of this gun
|
|
||||||
pub name: String,
|
|
||||||
|
|
||||||
/// The projectile this gun produces
|
|
||||||
pub projectile: Projectile,
|
|
||||||
|
|
||||||
/// Average delay between projectiles, in seconds.
|
|
||||||
pub rate: f32,
|
|
||||||
|
|
||||||
/// Random variation of projectile delay, in seconds.
|
|
||||||
/// Each shot waits (rate += rate_rng).
|
|
||||||
pub rate_rng: f32,
|
|
||||||
|
|
||||||
/// How much space this gun uses
|
|
||||||
pub space: OutfitSpace,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a projectile that a [`Gun`] produces.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Projectile {
|
|
||||||
/// The projectile sprite
|
|
||||||
pub sprite: SpriteHandle,
|
|
||||||
|
|
||||||
/// The average size of this projectile
|
|
||||||
/// (height in game units)
|
|
||||||
pub size: f32,
|
|
||||||
/// Random size variation
|
|
||||||
pub size_rng: f32,
|
|
||||||
|
|
||||||
/// The speed of this projectile, in game units / second
|
|
||||||
pub speed: f32,
|
|
||||||
/// Random speed variation
|
|
||||||
pub speed_rng: f32,
|
|
||||||
|
|
||||||
/// The lifespan of this projectile.
|
|
||||||
/// It will vanish if it lives this long without hitting anything.
|
|
||||||
pub lifetime: f32,
|
|
||||||
/// Random lifetime variation
|
|
||||||
pub lifetime_rng: f32,
|
|
||||||
|
|
||||||
/// The damage this projectile does
|
|
||||||
pub damage: f32,
|
|
||||||
|
|
||||||
/// The force this projectile applies
|
|
||||||
pub force: f32,
|
|
||||||
|
|
||||||
/// The angle variation of this projectile.
|
|
||||||
/// Projectiles can be off center up to
|
|
||||||
/// `spread / 2` degrees in both directions.
|
|
||||||
///
|
|
||||||
/// (Forming a "fire cone" of `spread` degrees)
|
|
||||||
pub angle_rng: Rad<f32>,
|
|
||||||
|
|
||||||
/// The particle this projectile will spawn when it hits something
|
|
||||||
pub impact_effect: Option<EffectHandle>,
|
|
||||||
|
|
||||||
/// The particle this projectile will spawn when it expires
|
|
||||||
pub expire_effect: Option<EffectHandle>,
|
|
||||||
|
|
||||||
/// Collider parameters for this projectile
|
|
||||||
pub collider: ProjectileCollider,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl crate::Build for Gun {
|
|
||||||
type InputSyntaxType = HashMap<String, syntax::Gun>;
|
|
||||||
|
|
||||||
fn build(
|
|
||||||
gun: Self::InputSyntaxType,
|
|
||||||
build_context: &mut ContentBuildContext,
|
|
||||||
content: &mut Content,
|
|
||||||
) -> Result<()> {
|
|
||||||
for (gun_name, gun) in gun {
|
|
||||||
let projectile_sprite_handle = match content.sprite_index.get(&gun.projectile.sprite) {
|
|
||||||
None => bail!(
|
|
||||||
"projectile sprite `{}` doesn't exist in gun `{}`",
|
|
||||||
gun.projectile.sprite,
|
|
||||||
gun_name,
|
|
||||||
),
|
|
||||||
Some(t) => *t,
|
|
||||||
};
|
|
||||||
|
|
||||||
let impact_effect = match gun.projectile.impact_effect {
|
|
||||||
Some(e) => Some(
|
|
||||||
e.to_handle(build_context, content)
|
|
||||||
.with_context(|| format!("while loading gun `{}`", gun_name))?,
|
|
||||||
),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let expire_effect = match gun.projectile.expire_effect {
|
|
||||||
Some(e) => Some(
|
|
||||||
e.to_handle(build_context, content)
|
|
||||||
.with_context(|| format!("while loading gun `{}`", gun_name))?,
|
|
||||||
),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
content.guns.push(Self {
|
|
||||||
name: gun_name,
|
|
||||||
space: gun.space.into(),
|
|
||||||
rate: gun.rate,
|
|
||||||
rate_rng: gun.rate_rng,
|
|
||||||
projectile: Projectile {
|
|
||||||
force: gun.projectile.force,
|
|
||||||
sprite: projectile_sprite_handle,
|
|
||||||
size: gun.projectile.size,
|
|
||||||
size_rng: gun.projectile.size_rng,
|
|
||||||
speed: gun.projectile.speed,
|
|
||||||
speed_rng: gun.projectile.speed_rng,
|
|
||||||
lifetime: gun.projectile.lifetime,
|
|
||||||
lifetime_rng: gun.projectile.lifetime_rng,
|
|
||||||
damage: gun.projectile.damage,
|
|
||||||
|
|
||||||
// Divide by 2, so the angle matches the angle of the fire cone.
|
|
||||||
// This should ALWAYS be done in the content parser.
|
|
||||||
angle_rng: Deg(gun.projectile.angle_rng / 2.0).into(),
|
|
||||||
impact_effect,
|
|
||||||
expire_effect,
|
|
||||||
collider: gun.projectile.collider,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
pub(crate) mod effect;
|
pub(crate) mod effect;
|
||||||
pub(crate) mod faction;
|
pub(crate) mod faction;
|
||||||
pub(crate) mod gun;
|
|
||||||
pub(crate) mod outfit;
|
pub(crate) mod outfit;
|
||||||
pub(crate) mod outfitspace;
|
pub(crate) mod outfitspace;
|
||||||
pub(crate) mod ship;
|
pub(crate) mod ship;
|
||||||
|
@ -11,8 +10,7 @@ pub(crate) mod system;
|
||||||
|
|
||||||
pub use effect::Effect;
|
pub use effect::Effect;
|
||||||
pub use faction::{Faction, Relationship};
|
pub use faction::{Faction, Relationship};
|
||||||
pub use gun::{Gun, Projectile, ProjectileCollider};
|
pub use outfit::{Gun, Outfit, Projectile, ProjectileCollider};
|
||||||
pub use outfit::Outfit;
|
|
||||||
pub use outfitspace::OutfitSpace;
|
pub use outfitspace::OutfitSpace;
|
||||||
pub use ship::{
|
pub use ship::{
|
||||||
CollapseEffectSpawner, CollapseEvent, EffectCollapseEvent, EnginePoint, GunPoint, Ship,
|
CollapseEffectSpawner, CollapseEvent, EffectCollapseEvent, EnginePoint, GunPoint, Ship,
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
|
use cgmath::Rad;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{handle::SpriteHandle, Content, ContentBuildContext, OutfitHandle, OutfitSpace};
|
use crate::{
|
||||||
|
handle::SpriteHandle, Content, ContentBuildContext, EffectHandle, OutfitHandle, OutfitSpace,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
use crate::part::outfitspace;
|
use crate::{effect, part::outfitspace, ContentBuildContext};
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
use cgmath::Deg;
|
||||||
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 +22,7 @@ pub(crate) mod syntax {
|
||||||
pub steering: Option<Steering>,
|
pub steering: Option<Steering>,
|
||||||
pub space: outfitspace::syntax::OutfitSpace,
|
pub space: outfitspace::syntax::OutfitSpace,
|
||||||
pub shield: Option<Shield>,
|
pub shield: Option<Shield>,
|
||||||
|
pub gun: Option<Gun>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -36,6 +43,79 @@ pub(crate) mod syntax {
|
||||||
pub struct Steering {
|
pub struct Steering {
|
||||||
pub power: f32,
|
pub power: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Gun {
|
||||||
|
pub projectile: Projectile,
|
||||||
|
pub rate: f32,
|
||||||
|
pub rate_rng: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Gun {
|
||||||
|
pub fn build(
|
||||||
|
self,
|
||||||
|
build_context: &mut ContentBuildContext,
|
||||||
|
content: &mut crate::Content,
|
||||||
|
) -> Result<super::Gun> {
|
||||||
|
let projectile_sprite_handle = match content.sprite_index.get(&self.projectile.sprite) {
|
||||||
|
None => bail!(
|
||||||
|
"projectile sprite `{}` doesn't exist",
|
||||||
|
self.projectile.sprite,
|
||||||
|
),
|
||||||
|
Some(t) => *t,
|
||||||
|
};
|
||||||
|
|
||||||
|
let impact_effect = match self.projectile.impact_effect {
|
||||||
|
Some(e) => Some(e.to_handle(build_context, content)?),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let expire_effect = match self.projectile.expire_effect {
|
||||||
|
Some(e) => Some(e.to_handle(build_context, content)?),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(super::Gun {
|
||||||
|
rate: self.rate,
|
||||||
|
rate_rng: self.rate_rng.unwrap_or(0.0),
|
||||||
|
projectile: super::Projectile {
|
||||||
|
force: self.projectile.force,
|
||||||
|
sprite: projectile_sprite_handle,
|
||||||
|
size: self.projectile.size,
|
||||||
|
size_rng: self.projectile.size_rng,
|
||||||
|
speed: self.projectile.speed,
|
||||||
|
speed_rng: self.projectile.speed_rng,
|
||||||
|
lifetime: self.projectile.lifetime,
|
||||||
|
lifetime_rng: self.projectile.lifetime_rng,
|
||||||
|
damage: self.projectile.damage,
|
||||||
|
|
||||||
|
// Divide by 2, so the angle matches the angle of the fire cone.
|
||||||
|
// This should ALWAYS be done in the content parser.
|
||||||
|
angle_rng: Deg(self.projectile.angle_rng / 2.0).into(),
|
||||||
|
impact_effect,
|
||||||
|
expire_effect,
|
||||||
|
collider: self.projectile.collider,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Projectile {
|
||||||
|
pub sprite: String,
|
||||||
|
pub size: f32,
|
||||||
|
pub size_rng: f32,
|
||||||
|
pub speed: f32,
|
||||||
|
pub speed_rng: f32,
|
||||||
|
pub lifetime: f32,
|
||||||
|
pub lifetime_rng: f32,
|
||||||
|
pub damage: f32,
|
||||||
|
pub angle_rng: f32,
|
||||||
|
pub impact_effect: Option<effect::syntax::EffectReference>,
|
||||||
|
pub expire_effect: Option<effect::syntax::EffectReference>,
|
||||||
|
pub collider: super::ProjectileCollider,
|
||||||
|
pub force: f32,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an outfit that may be attached to a ship.
|
/// Represents an outfit that may be attached to a ship.
|
||||||
|
@ -69,6 +149,82 @@ pub struct Outfit {
|
||||||
|
|
||||||
/// Wait this many seconds after taking damage before regenerating shields
|
/// Wait this many seconds after taking damage before regenerating shields
|
||||||
pub shield_delay: f32,
|
pub shield_delay: f32,
|
||||||
|
|
||||||
|
/// This outfit's gun stats.
|
||||||
|
/// If this is some, this outfit requires a gun point.
|
||||||
|
pub gun: Option<Gun>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines a projectile's collider
|
||||||
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
pub enum ProjectileCollider {
|
||||||
|
/// A ball collider
|
||||||
|
#[serde(rename = "ball")]
|
||||||
|
Ball(BallCollider),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A simple ball-shaped collider, centered at the object's position
|
||||||
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
pub struct BallCollider {
|
||||||
|
/// The radius of this ball
|
||||||
|
pub radius: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents gun stats of an outfit.
|
||||||
|
/// If an outfit has this value, it requires a gun point.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Gun {
|
||||||
|
/// The projectile this gun produces
|
||||||
|
pub projectile: Projectile,
|
||||||
|
|
||||||
|
/// Average delay between projectiles, in seconds.
|
||||||
|
pub rate: f32,
|
||||||
|
|
||||||
|
/// Random variation of projectile delay, in seconds.
|
||||||
|
/// Each shot waits (rate += rate_rng).
|
||||||
|
pub rate_rng: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a projectile that a [`Gun`] produces.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Projectile {
|
||||||
|
/// The projectile sprite
|
||||||
|
pub sprite: SpriteHandle,
|
||||||
|
|
||||||
|
/// The average size of this projectile
|
||||||
|
/// (height in game units)
|
||||||
|
pub size: f32,
|
||||||
|
/// Random size variation
|
||||||
|
pub size_rng: f32,
|
||||||
|
|
||||||
|
/// The speed of this projectile, in game units / second
|
||||||
|
pub speed: f32,
|
||||||
|
/// Random speed variation
|
||||||
|
pub speed_rng: f32,
|
||||||
|
|
||||||
|
/// The lifespan of this projectile.
|
||||||
|
/// It will vanish if it lives this long without hitting anything.
|
||||||
|
pub lifetime: f32,
|
||||||
|
/// Random lifetime variation
|
||||||
|
pub lifetime_rng: f32,
|
||||||
|
|
||||||
|
/// The damage this projectile does
|
||||||
|
pub damage: f32,
|
||||||
|
|
||||||
|
/// The force this projectile applies
|
||||||
|
pub force: f32,
|
||||||
|
|
||||||
|
/// The angle variation of this projectile.
|
||||||
|
pub angle_rng: Rad<f32>,
|
||||||
|
|
||||||
|
/// The particle this projectile will spawn when it hits something
|
||||||
|
pub impact_effect: Option<EffectHandle>,
|
||||||
|
|
||||||
|
/// The particle this projectile will spawn when it expires
|
||||||
|
pub expire_effect: Option<EffectHandle>,
|
||||||
|
|
||||||
|
/// Collider parameters for this projectile
|
||||||
|
pub collider: ProjectileCollider,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Build for Outfit {
|
impl crate::Build for Outfit {
|
||||||
|
@ -76,7 +232,7 @@ impl crate::Build for Outfit {
|
||||||
|
|
||||||
fn build(
|
fn build(
|
||||||
outfits: Self::InputSyntaxType,
|
outfits: Self::InputSyntaxType,
|
||||||
_build_context: &mut ContentBuildContext,
|
build_context: &mut ContentBuildContext,
|
||||||
content: &mut Content,
|
content: &mut Content,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (outfit_name, outfit) in outfits {
|
for (outfit_name, outfit) in outfits {
|
||||||
|
@ -84,7 +240,16 @@ impl crate::Build for Outfit {
|
||||||
index: content.outfits.len(),
|
index: content.outfits.len(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let gun = match outfit.gun {
|
||||||
|
None => None,
|
||||||
|
Some(g) => Some(
|
||||||
|
g.build(build_context, content)
|
||||||
|
.with_context(|| format!("in outfit {}", outfit_name))?,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
let mut o = Self {
|
let mut o = Self {
|
||||||
|
gun,
|
||||||
handle,
|
handle,
|
||||||
name: outfit_name.clone(),
|
name: outfit_name.clone(),
|
||||||
engine_thrust: 0.0,
|
engine_thrust: 0.0,
|
||||||
|
|
Loading…
Reference in New Issue