Compare commits
3 Commits
861c1ce8e6
...
1c3f64a132
Author | SHA1 | Date |
---|---|---|
Mark | 1c3f64a132 | |
Mark | fef43d8744 | |
Mark | 10682db347 |
11
TODO.md
11
TODO.md
|
@ -1,5 +1,4 @@
|
||||||
## Specific Jobs
|
## Specific Jobs
|
||||||
- UI: health, shield, fuel, heat, energy bars
|
|
||||||
- UI: text arranger
|
- UI: text arranger
|
||||||
- Sound system
|
- Sound system
|
||||||
- Ship death debris
|
- Ship death debris
|
||||||
|
@ -14,9 +13,10 @@
|
||||||
- Better loading
|
- Better loading
|
||||||
- incremental?
|
- incremental?
|
||||||
- Higher texture limit (16 x 8096 x 8096 isn't enough)
|
- Higher texture limit (16 x 8096 x 8096 isn't enough)
|
||||||
- GPU limits? (texture size, texture number)
|
- GPU limits? (texture size, texture number, particle/sprite limits)
|
||||||
- Particles when a ship is damaged (events)
|
- Particles when a ship is damaged (events)
|
||||||
- Sticky radar
|
- Sticky radar
|
||||||
|
- Clean up world and objects
|
||||||
|
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@
|
||||||
- Orbiting debris (asteroids)
|
- Orbiting debris (asteroids)
|
||||||
- Collectibles (flotsam)
|
- Collectibles (flotsam)
|
||||||
- UI
|
- UI
|
||||||
- health, shields (cpu by tinyskia?)
|
|
||||||
- loading screen, menus
|
- loading screen, menus
|
||||||
- Indicators (planet names, enemy ship stats)
|
- Indicators (planet names, enemy ship stats)
|
||||||
- Landable planets
|
- Landable planets
|
||||||
|
@ -109,6 +108,7 @@
|
||||||
- Trade
|
- Trade
|
||||||
- Missions
|
- Missions
|
||||||
- Procedural suns
|
- Procedural suns
|
||||||
|
- Heat and energy
|
||||||
|
|
||||||
## Camera
|
## Camera
|
||||||
- Shake/wobble on heavy hits?
|
- Shake/wobble on heavy hits?
|
||||||
|
@ -126,6 +126,8 @@
|
||||||
- Nova dust parallax
|
- Nova dust parallax
|
||||||
- Engine flare ease in/out
|
- Engine flare ease in/out
|
||||||
- Lens flare
|
- Lens flare
|
||||||
|
- Clustered starfield
|
||||||
|
- Redesign UI
|
||||||
|
|
||||||
## Write and Document
|
## Write and Document
|
||||||
- Parallax
|
- Parallax
|
||||||
|
@ -141,7 +143,7 @@
|
||||||
- Handles
|
- Handles
|
||||||
- Content specification and pipeline
|
- Content specification and pipeline
|
||||||
- How packer and optimizations work, and why
|
- How packer and optimizations work, and why
|
||||||
- How big should sprites be? (resize existing)
|
- How big should sprite resolutions be? How about frame rate?
|
||||||
- Naming: atlas, sprite, image, frame, texture
|
- Naming: atlas, sprite, image, frame, texture
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,4 +160,5 @@
|
||||||
- Find your wreckage when you die (dark souls/HK)
|
- Find your wreckage when you die (dark souls/HK)
|
||||||
- Lose some outfits, lose ship? Real risk for going out! (HK does this well)
|
- Lose some outfits, lose ship? Real risk for going out! (HK does this well)
|
||||||
- Damage to ship subsystems
|
- Damage to ship subsystems
|
||||||
|
- Soft and highly armored ship points
|
||||||
- Repair your own ship
|
- Repair your own ship
|
|
@ -103,7 +103,5 @@ fade_rng = 0.1
|
||||||
# TODO:
|
# TODO:
|
||||||
# effect probabilities & variants
|
# effect probabilities & variants
|
||||||
# multiple particles in one effect
|
# multiple particles in one effect
|
||||||
# fade
|
|
||||||
# document: effect vs particle
|
# document: effect vs particle
|
||||||
# sprite lifetime/fps variation (and effects inherit lifetime later)
|
# sprite lifetime/fps variation (and effects inherit lifetime later)
|
||||||
# universal effect creator
|
|
||||||
|
|
|
@ -5,3 +5,12 @@ space.engine = 20
|
||||||
engine.thrust = 100
|
engine.thrust = 100
|
||||||
engine.flare_sprite = "flare::ion"
|
engine.flare_sprite = "flare::ion"
|
||||||
steering.power = 20
|
steering.power = 20
|
||||||
|
|
||||||
|
|
||||||
|
[outfit."shield generator"]
|
||||||
|
|
||||||
|
space.outfit = 5
|
||||||
|
|
||||||
|
shield.generation = 10
|
||||||
|
shield.strength = 500
|
||||||
|
shield.delay = 2.0
|
||||||
|
|
|
@ -7,7 +7,6 @@ linear_drag = 0.2
|
||||||
angular_drag = 0.2
|
angular_drag = 0.2
|
||||||
|
|
||||||
# TODO: disable
|
# TODO: disable
|
||||||
# TODO: damage effects
|
|
||||||
|
|
||||||
space.outfit = 200
|
space.outfit = 200
|
||||||
space.engine = 50
|
space.engine = 50
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use cgmath::Deg;
|
use cgmath::{Deg, Rad};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ pub struct Projectile {
|
||||||
/// `spread / 2` degrees in both directions.
|
/// `spread / 2` degrees in both directions.
|
||||||
///
|
///
|
||||||
/// (Forming a "fire cone" of `spread` degrees)
|
/// (Forming a "fire cone" of `spread` degrees)
|
||||||
pub angle_rng: Deg<f32>,
|
pub angle_rng: Rad<f32>,
|
||||||
|
|
||||||
/// The particle this projectile will spawn when it hits something
|
/// The particle this projectile will spawn when it hits something
|
||||||
pub impact_effect: Option<EffectHandle>,
|
pub impact_effect: Option<EffectHandle>,
|
||||||
|
@ -173,7 +173,7 @@ impl crate::Build for Gun {
|
||||||
|
|
||||||
// Divide by 2, so the angle matches the angle of the fire cone.
|
// Divide by 2, so the angle matches the angle of the fire cone.
|
||||||
// This should ALWAYS be done in the content parser.
|
// This should ALWAYS be done in the content parser.
|
||||||
angle_rng: Deg(gun.projectile.angle_rng / 2.0),
|
angle_rng: Deg(gun.projectile.angle_rng / 2.0).into(),
|
||||||
impact_effect,
|
impact_effect,
|
||||||
expire_effect,
|
expire_effect,
|
||||||
collider: gun.projectile.collider,
|
collider: gun.projectile.collider,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
use crate::{handle::SpriteHandle, Content, ContentBuildContext, OutfitSpace};
|
use crate::{handle::SpriteHandle, Content, ContentBuildContext, OutfitHandle, OutfitSpace};
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
use crate::part::outfitspace;
|
use crate::part::outfitspace;
|
||||||
|
@ -15,6 +15,15 @@ pub(crate) mod syntax {
|
||||||
pub engine: Option<Engine>,
|
pub engine: Option<Engine>,
|
||||||
pub steering: Option<Steering>,
|
pub steering: Option<Steering>,
|
||||||
pub space: outfitspace::syntax::OutfitSpace,
|
pub space: outfitspace::syntax::OutfitSpace,
|
||||||
|
pub shield: Option<Shield>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Shield {
|
||||||
|
pub strength: Option<f32>,
|
||||||
|
pub generation: Option<f32>,
|
||||||
|
pub delay: Option<f32>,
|
||||||
|
// more stats: permiability, shield armor, ramp, etc
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -32,6 +41,12 @@ pub(crate) mod syntax {
|
||||||
/// Represents an outfit that may be attached to a ship.
|
/// Represents an outfit that may be attached to a ship.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Outfit {
|
pub struct Outfit {
|
||||||
|
/// How much space this outfit requires
|
||||||
|
pub space: OutfitSpace,
|
||||||
|
|
||||||
|
/// This outfit's handle
|
||||||
|
pub handle: OutfitHandle,
|
||||||
|
|
||||||
/// The name of this outfit
|
/// The name of this outfit
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
|
@ -46,8 +61,14 @@ pub struct Outfit {
|
||||||
/// engine points.
|
/// engine points.
|
||||||
pub engine_flare_sprite: Option<SpriteHandle>,
|
pub engine_flare_sprite: Option<SpriteHandle>,
|
||||||
|
|
||||||
/// How much space this outfit requires
|
/// Shield hit points
|
||||||
pub space: OutfitSpace,
|
pub shield_strength: f32,
|
||||||
|
|
||||||
|
/// Shield regeneration rate, per second
|
||||||
|
pub shield_generation: f32,
|
||||||
|
|
||||||
|
/// Wait this many seconds after taking damage before regenerating shields
|
||||||
|
pub shield_delay: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Build for Outfit {
|
impl crate::Build for Outfit {
|
||||||
|
@ -59,12 +80,20 @@ impl crate::Build for Outfit {
|
||||||
content: &mut Content,
|
content: &mut Content,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (outfit_name, outfit) in outfits {
|
for (outfit_name, outfit) in outfits {
|
||||||
|
let handle = OutfitHandle {
|
||||||
|
index: content.outfits.len(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut o = Self {
|
let mut o = Self {
|
||||||
|
handle,
|
||||||
name: outfit_name.clone(),
|
name: outfit_name.clone(),
|
||||||
engine_thrust: 0.0,
|
engine_thrust: 0.0,
|
||||||
steer_power: 0.0,
|
steer_power: 0.0,
|
||||||
engine_flare_sprite: None,
|
engine_flare_sprite: None,
|
||||||
space: OutfitSpace::from(outfit.space),
|
space: OutfitSpace::from(outfit.space),
|
||||||
|
shield_delay: 0.0,
|
||||||
|
shield_generation: 0.0,
|
||||||
|
shield_strength: 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Engine stats
|
// Engine stats
|
||||||
|
@ -86,6 +115,13 @@ impl crate::Build for Outfit {
|
||||||
o.steer_power = steer.power;
|
o.steer_power = steer.power;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shield stats
|
||||||
|
if let Some(shield) = outfit.shield {
|
||||||
|
o.shield_delay = shield.delay.unwrap_or(0.0);
|
||||||
|
o.shield_generation = shield.generation.unwrap_or(0.0);
|
||||||
|
o.shield_strength = shield.strength.unwrap_or(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
content.outfits.push(o);
|
content.outfits.push(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use cgmath::{Deg, Point3};
|
use cgmath::{Deg, Point3, Rad};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use crate::{handle::SpriteHandle, util::Polar, Content, ContentBuildContext};
|
use crate::{handle::SpriteHandle, util::Polar, Content, ContentBuildContext};
|
||||||
|
@ -106,8 +106,8 @@ pub struct Object {
|
||||||
/// relative to the system's center (0, 0).
|
/// relative to the system's center (0, 0).
|
||||||
pub position: Point3<f32>,
|
pub position: Point3<f32>,
|
||||||
|
|
||||||
/// This object's sprite's angle, in degrees.
|
/// This object's sprite's angle.
|
||||||
pub angle: Deg<f32>,
|
pub angle: Rad<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function for resolve_position, never called on its own.
|
/// Helper function for resolve_position, never called on its own.
|
||||||
|
@ -162,7 +162,7 @@ fn resolve_position(
|
||||||
let plane = Polar {
|
let plane = Polar {
|
||||||
center: (r.x, r.y).into(),
|
center: (r.x, r.y).into(),
|
||||||
radius: p.radius,
|
radius: p.radius,
|
||||||
angle: Deg(p.angle),
|
angle: Deg(p.angle).into(),
|
||||||
}
|
}
|
||||||
.to_cartesian();
|
.to_cartesian();
|
||||||
Ok(Point3 {
|
Ok(Point3 {
|
||||||
|
@ -203,7 +203,7 @@ impl crate::Build for System {
|
||||||
position: resolve_position(&system.object, &obj, cycle_detector)
|
position: resolve_position(&system.object, &obj, cycle_detector)
|
||||||
.with_context(|| format!("In object {:#?}", label))?,
|
.with_context(|| format!("In object {:#?}", label))?,
|
||||||
size: obj.size,
|
size: obj.size,
|
||||||
angle: Deg(obj.angle.unwrap_or(0.0)),
|
angle: Deg(obj.angle.unwrap_or(0.0)).into(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use cgmath::{Angle, Deg, Point2, Vector2};
|
use cgmath::{Angle, Point2, Rad, Vector2};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Polar {
|
pub struct Polar {
|
||||||
pub center: Point2<f32>,
|
pub center: Point2<f32>,
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
pub angle: Deg<f32>,
|
pub angle: Rad<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Polar {
|
impl Polar {
|
||||||
|
|
|
@ -38,6 +38,7 @@ impl Game {
|
||||||
|
|
||||||
let mut o1 = object::OutfitSet::new(ss);
|
let mut o1 = object::OutfitSet::new(ss);
|
||||||
o1.add(&ct, content::OutfitHandle { index: 0 });
|
o1.add(&ct, content::OutfitHandle { index: 0 });
|
||||||
|
o1.add(&ct, content::OutfitHandle { index: 1 });
|
||||||
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
||||||
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
||||||
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
||||||
|
@ -64,7 +65,7 @@ impl Game {
|
||||||
|
|
||||||
let mut o1 = object::OutfitSet::new(ss);
|
let mut o1 = object::OutfitSet::new(ss);
|
||||||
o1.add(&ct, content::OutfitHandle { index: 0 });
|
o1.add(&ct, content::OutfitHandle { index: 0 });
|
||||||
//o1.add_gun(&ct, content::GunHandle { index: 0 });
|
o1.add_gun(&ct, content::GunHandle { index: 0 });
|
||||||
|
|
||||||
let s = object::Ship::new(
|
let s = object::Ship::new(
|
||||||
&ct,
|
&ct,
|
||||||
|
@ -161,7 +162,6 @@ impl Game {
|
||||||
self.input.v_scroll = 0.0;
|
self.input.v_scroll = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Camera physics
|
|
||||||
let r = self
|
let r = self
|
||||||
.world
|
.world
|
||||||
.get_ship_mut(&self.player)
|
.get_ship_mut(&self.player)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use content::{EnginePoint, SpriteHandle};
|
use content::{EnginePoint, OutfitHandle, SpriteHandle};
|
||||||
use galactica_content as content;
|
use galactica_content as content;
|
||||||
|
|
||||||
/// Represents a gun attached to a specific ship at a certain gunpoint.
|
/// Represents a gun attached to a specific ship at a certain gunpoint.
|
||||||
|
@ -33,6 +33,10 @@ pub struct OutfitStatSum {
|
||||||
pub engine_thrust: f32,
|
pub engine_thrust: f32,
|
||||||
pub steer_power: f32,
|
pub steer_power: f32,
|
||||||
pub engine_flare_sprites: Vec<content::SpriteHandle>,
|
pub engine_flare_sprites: Vec<content::SpriteHandle>,
|
||||||
|
pub shield_strength: f32,
|
||||||
|
|
||||||
|
// Delay, generation
|
||||||
|
pub shield_generators: Vec<(OutfitHandle, f32, f32)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutfitStatSum {
|
impl OutfitStatSum {
|
||||||
|
@ -41,6 +45,8 @@ impl OutfitStatSum {
|
||||||
engine_thrust: 0.0,
|
engine_thrust: 0.0,
|
||||||
steer_power: 0.0,
|
steer_power: 0.0,
|
||||||
engine_flare_sprites: Vec::new(),
|
engine_flare_sprites: Vec::new(),
|
||||||
|
shield_strength: 0.0,
|
||||||
|
shield_generators: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +56,9 @@ impl OutfitStatSum {
|
||||||
self.engine_flare_sprites.push(t);
|
self.engine_flare_sprites.push(t);
|
||||||
};
|
};
|
||||||
self.steer_power += o.steer_power;
|
self.steer_power += o.steer_power;
|
||||||
|
self.shield_strength += o.shield_strength;
|
||||||
|
self.shield_generators
|
||||||
|
.push((o.handle, o.shield_delay, o.shield_generation));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, o: &content::Outfit) {
|
pub fn remove(&mut self, o: &content::Outfit) {
|
||||||
|
@ -63,6 +72,16 @@ impl OutfitStatSum {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.steer_power -= o.steer_power;
|
self.steer_power -= o.steer_power;
|
||||||
|
self.shield_strength -= o.shield_strength;
|
||||||
|
{
|
||||||
|
// Assume such an index exists
|
||||||
|
let index = self
|
||||||
|
.shield_generators
|
||||||
|
.iter()
|
||||||
|
.position(|(h, _, _)| *h == o.handle)
|
||||||
|
.unwrap();
|
||||||
|
self.shield_generators.remove(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +137,6 @@ impl<'a> OutfitSet {
|
||||||
self.available_space.occupy(&outfit.space);
|
self.available_space.occupy(&outfit.space);
|
||||||
self.stats.add(&outfit);
|
self.stats.add(&outfit);
|
||||||
self.outfits.push(o);
|
self.outfits.push(o);
|
||||||
//self.update_engine_flares();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,8 +149,6 @@ impl<'a> OutfitSet {
|
||||||
};
|
};
|
||||||
self.available_space.free(&outfit.space);
|
self.available_space.free(&outfit.space);
|
||||||
self.outfits.remove(i);
|
self.outfits.remove(i);
|
||||||
self.stats.remove(&outfit);
|
|
||||||
//self.update_engine_flares();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a gun to this outfit set.
|
/// Add a gun to this outfit set.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use crate::{OutfitSet, Projectile};
|
use crate::{OutfitSet, Projectile};
|
||||||
use galactica_content as content;
|
use galactica_content as content;
|
||||||
|
@ -8,10 +9,12 @@ pub struct Ship {
|
||||||
pub handle: content::ShipHandle,
|
pub handle: content::ShipHandle,
|
||||||
pub faction: content::FactionHandle,
|
pub faction: content::FactionHandle,
|
||||||
pub outfits: OutfitSet,
|
pub outfits: OutfitSet,
|
||||||
|
pub last_hit: Instant,
|
||||||
|
|
||||||
// TODO: unified ship stats struct, like space
|
// TODO: unified ship stats struct, like space
|
||||||
// TODO: unified outfit stats struct: check
|
// TODO: unified outfit stats struct: check
|
||||||
pub hull: f32,
|
pub hull: f32,
|
||||||
|
pub shields: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ship {
|
impl Ship {
|
||||||
|
@ -22,11 +25,14 @@ impl Ship {
|
||||||
outfits: OutfitSet,
|
outfits: OutfitSet,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let s = ct.get_ship(handle);
|
let s = ct.get_ship(handle);
|
||||||
|
let shields = outfits.stat_sum().shield_strength;
|
||||||
Ship {
|
Ship {
|
||||||
handle: handle,
|
handle: handle,
|
||||||
faction,
|
faction,
|
||||||
outfits,
|
outfits,
|
||||||
hull: s.hull,
|
hull: s.hull,
|
||||||
|
shields,
|
||||||
|
last_hit: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +47,19 @@ impl Ship {
|
||||||
let r = f.relationships.get(&p.faction).unwrap();
|
let r = f.relationships.get(&p.faction).unwrap();
|
||||||
match r {
|
match r {
|
||||||
content::Relationship::Hostile => {
|
content::Relationship::Hostile => {
|
||||||
|
let mut d = p.content.damage;
|
||||||
if self.is_dead() {
|
if self.is_dead() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
self.hull -= p.content.damage;
|
if self.shields >= d {
|
||||||
|
self.shields -= d
|
||||||
|
} else {
|
||||||
|
d -= self.shields;
|
||||||
|
self.shields = 0.0;
|
||||||
|
self.hull -= d;
|
||||||
|
}
|
||||||
|
self.last_hit = Instant::now();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_ => return false,
|
_ => return false,
|
||||||
|
@ -79,4 +94,19 @@ impl Ship {
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn step(&mut self, t: f32) {
|
||||||
|
let time_since = self.last_hit.elapsed().as_secs_f32();
|
||||||
|
if self.shields != self.outfits.stat_sum().shield_strength {
|
||||||
|
for (_, d, g) in &self.outfits.stat_sum().shield_generators {
|
||||||
|
if time_since >= *d {
|
||||||
|
self.shields += g * t;
|
||||||
|
if self.shields > self.outfits.stat_sum().shield_strength {
|
||||||
|
self.shields = self.outfits.stat_sum().shield_strength;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use cgmath::{Deg, Point3};
|
use cgmath::{Point3, Rad};
|
||||||
|
|
||||||
use galactica_content as content;
|
use galactica_content as content;
|
||||||
|
|
||||||
|
@ -6,17 +6,5 @@ pub struct SystemObject {
|
||||||
pub sprite: content::SpriteHandle,
|
pub sprite: content::SpriteHandle,
|
||||||
pub pos: Point3<f32>,
|
pub pos: Point3<f32>,
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
pub angle: Deg<f32>,
|
pub angle: Rad<f32>,
|
||||||
}
|
|
||||||
|
|
||||||
impl SystemObject {
|
|
||||||
//pub(crate) fn get_sprite(&self) -> ObjectSprite {
|
|
||||||
// return ObjectSprite {
|
|
||||||
// sprite: self.sprite,
|
|
||||||
// pos: self.pos,
|
|
||||||
// angle: self.angle,
|
|
||||||
// size: self.size,
|
|
||||||
// children: None,
|
|
||||||
// };
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: article
|
// TODO: article
|
||||||
// TODO: rework texturearray
|
|
||||||
// TODO: reasonable sprite sizes
|
|
||||||
// TODO: consistent naming
|
|
||||||
// TODO: parallelize
|
// TODO: parallelize
|
||||||
|
// TODO: consistent naming (document)
|
||||||
// spriteatlas: the big images
|
// spriteatlas: the big images
|
||||||
// texture: the same, what we load to wgpu
|
// texture: the same, what we load to wgpu
|
||||||
// image: a single file
|
// image: a single file
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
//! This crate creates texture atlases from an asset tree.
|
//! This crate creates texture atlases from an asset tree.
|
||||||
//! The main interface for this crate is ... TODO
|
|
||||||
|
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use walkdir::WalkDir;
|
||||||
// TODO: dynamic packing (for plugins)
|
// TODO: dynamic packing (for plugins)
|
||||||
// TODO: standalone cli (galactica should ask to run this)
|
// TODO: standalone cli (galactica should ask to run this)
|
||||||
// TODO: randomly assign sprites to textures, for efficiency
|
// TODO: randomly assign sprites to textures, for efficiency
|
||||||
// TODO: group images by use case
|
// TODO: group images by use case (dynamic loading algorithm)
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
|
||||||
let bar_width = in.stroke; // Width of filled bar
|
let bar_width = in.stroke; // Width of filled bar
|
||||||
let bar_radius = in.diameter / 2.0 - bar_width / 2.0; // Middle radius of the bar
|
let bar_radius = in.diameter / 2.0 - bar_width / 2.0; // Middle radius of the bar
|
||||||
let angle = in.angle - floor(in.angle / 6.283) * 6.28318; // Sanely handle large angles (fmod(angle, 2pi))
|
let angle = clamp(0.001, 6.28318 + 0.001, in.angle); // Sanely handle extreme angles
|
||||||
let zero_vector = vec2(0.0, 1.0); // Draw bar clockwise from this vector
|
let zero_vector = vec2(0.0, 1.0); // Draw bar clockwise from this vector
|
||||||
let frag_radius = distance(vec2(0.0, 0.0), p); // Radius of this fragment
|
let frag_radius = distance(vec2(0.0, 0.0), p); // Radius of this fragment
|
||||||
let feather = 2.0; // Size of feather, in logical pixels
|
let feather = 2.0; // Size of feather, in logical pixels
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! GPUState routines for drawing HUD elements
|
//! GPUState routines for drawing HUD elements
|
||||||
|
|
||||||
|
use std::f32::consts::TAU;
|
||||||
|
|
||||||
use cgmath::{Deg, InnerSpace, Point2, Rad, Vector2};
|
use cgmath::{Deg, InnerSpace, Point2, Rad, Vector2};
|
||||||
use galactica_world::util;
|
use galactica_world::util;
|
||||||
|
|
||||||
|
@ -96,9 +98,7 @@ impl GPUState {
|
||||||
if size < 2.0 {
|
if size < 2.0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let angle: Deg<f32> = util::rigidbody_rotation(r)
|
let angle = util::rigidbody_rotation(r).angle(Vector2 { x: 0.0, y: 1.0 });
|
||||||
.angle(Vector2 { x: 0.0, y: 1.0 })
|
|
||||||
.into();
|
|
||||||
let f = state.content.get_faction(s.ship.faction).color;
|
let f = state.content.get_faction(s.ship.faction).color;
|
||||||
let f = [f[0], f[1], f[2], 1.0];
|
let f = [f[0], f[1], f[2], 1.0];
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ impl GPUState {
|
||||||
bytemuck::cast_slice(&[UiInstance {
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwC.to_int(),
|
anchor: PositionAnchor::NwC.to_int(),
|
||||||
position: position.into(),
|
position: position.into(),
|
||||||
angle: -Rad::from(angle).0, // TODO: consistent angles
|
angle: -angle.0, // TODO: consistent angles
|
||||||
size,
|
size,
|
||||||
color: f.into(),
|
color: f.into(),
|
||||||
sprite_index: ship_sprite.get_index(),
|
sprite_index: ship_sprite.get_index(),
|
||||||
|
@ -264,6 +264,12 @@ impl GPUState {
|
||||||
panic!("UI limit exceeded!")
|
panic!("UI limit exceeded!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (s, _) = state.world.get_ship_body(*state.player).unwrap();
|
||||||
|
let max_shields = s.ship.outfits.stat_sum().shield_strength;
|
||||||
|
let current_shields = s.ship.shields;
|
||||||
|
let current_hull = s.ship.hull;
|
||||||
|
let max_hull = state.content.get_ship(s.ship.handle).hull;
|
||||||
|
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.vertex_buffers.ui.instances,
|
&self.vertex_buffers.ui.instances,
|
||||||
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
@ -286,7 +292,6 @@ impl GPUState {
|
||||||
panic!("Radialbar limit exceeded!")
|
panic!("Radialbar limit exceeded!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: counters for each buffer, remove arrays
|
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.vertex_buffers.radialbar.instances,
|
&self.vertex_buffers.radialbar.instances,
|
||||||
RadialBarInstance::SIZE * self.vertex_buffers.radialbar_counter,
|
RadialBarInstance::SIZE * self.vertex_buffers.radialbar_counter,
|
||||||
|
@ -296,7 +301,7 @@ impl GPUState {
|
||||||
diameter: 182.0,
|
diameter: 182.0,
|
||||||
stroke: 5.0,
|
stroke: 5.0,
|
||||||
color: [0.3, 0.6, 0.8, 1.0],
|
color: [0.3, 0.6, 0.8, 1.0],
|
||||||
angle: -state.current_time / 2.0,
|
angle: (current_shields / max_shields) * TAU,
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
self.vertex_buffers.radialbar_counter += 1;
|
self.vertex_buffers.radialbar_counter += 1;
|
||||||
|
@ -310,7 +315,7 @@ impl GPUState {
|
||||||
diameter: 166.0,
|
diameter: 166.0,
|
||||||
stroke: 5.0,
|
stroke: 5.0,
|
||||||
color: [0.8, 0.7, 0.5, 1.0],
|
color: [0.8, 0.7, 0.5, 1.0],
|
||||||
angle: state.current_time / 5.0,
|
angle: (current_hull / max_hull) * TAU,
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
self.vertex_buffers.radialbar_counter += 1;
|
self.vertex_buffers.radialbar_counter += 1;
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl GPUState {
|
||||||
self.vertex_buffers.object_counter += 1;
|
self.vertex_buffers.object_counter += 1;
|
||||||
|
|
||||||
// Draw engine flares if necessary
|
// Draw engine flares if necessary
|
||||||
if s.controls.thrust {
|
if s.controls.thrust && !s.ship.is_dead() {
|
||||||
for f in s.ship.outfits.iter_enginepoints() {
|
for f in s.ship.outfits.iter_enginepoints() {
|
||||||
let flare = match s.ship.outfits.get_flare_sprite() {
|
let flare = match s.ship.outfits.get_flare_sprite() {
|
||||||
None => continue,
|
None => continue,
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub struct RenderState<'a> {
|
||||||
/// The world state to render
|
/// The world state to render
|
||||||
pub world: &'a World,
|
pub world: &'a World,
|
||||||
|
|
||||||
// TODO: handle overflow
|
// TODO: handle overflow. is it a problem?
|
||||||
/// The current time, in seconds
|
/// The current time, in seconds
|
||||||
pub current_time: f32,
|
pub current_time: f32,
|
||||||
|
|
||||||
|
|
|
@ -216,6 +216,8 @@ impl ShipWorldObject {
|
||||||
.step(&self.ship, ct, particles, rigid_body, collider, t);
|
.step(&self.ship, ct, particles, rigid_body, collider, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.ship.step(t);
|
||||||
|
|
||||||
let ship_content = ct.get_ship(self.ship.handle);
|
let ship_content = ct.get_ship(self.ship.handle);
|
||||||
let ship_pos = util::rigidbody_position(&rigid_body);
|
let ship_pos = util::rigidbody_position(&rigid_body);
|
||||||
let ship_rot = util::rigidbody_rotation(rigid_body);
|
let ship_rot = util::rigidbody_rotation(rigid_body);
|
||||||
|
|
|
@ -166,9 +166,7 @@ impl<'a> World {
|
||||||
.get(projectile.rigid_body)
|
.get(projectile.rigid_body)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let pos = util::rigidbody_position(pr);
|
let pos = util::rigidbody_position(pr);
|
||||||
let angle: Deg<f32> = util::rigidbody_rotation(pr)
|
let angle = util::rigidbody_rotation(pr).angle(Vector2 { x: 1.0, y: 0.0 });
|
||||||
.angle(Vector2 { x: 1.0, y: 0.0 })
|
|
||||||
.into();
|
|
||||||
|
|
||||||
match &projectile.projectile.content.impact_effect {
|
match &projectile.projectile.content.impact_effect {
|
||||||
None => {}
|
None => {}
|
||||||
|
@ -182,7 +180,7 @@ impl<'a> World {
|
||||||
particles.push(ParticleBuilder::from_content(
|
particles.push(ParticleBuilder::from_content(
|
||||||
effect,
|
effect,
|
||||||
pos,
|
pos,
|
||||||
Rad::from(-angle),
|
-angle,
|
||||||
parent_velocity,
|
parent_velocity,
|
||||||
Vector2 {
|
Vector2 {
|
||||||
x: target_velocity.x,
|
x: target_velocity.x,
|
||||||
|
@ -323,9 +321,7 @@ impl<'a> World {
|
||||||
let x = ct.get_effect(*x);
|
let x = ct.get_effect(*x);
|
||||||
let pos = util::rigidbody_position(&pr);
|
let pos = util::rigidbody_position(&pr);
|
||||||
let vel = util::rigidbody_velocity(&pr);
|
let vel = util::rigidbody_velocity(&pr);
|
||||||
let angle: Deg<f32> = util::rigidbody_rotation(&pr)
|
let angle = util::rigidbody_rotation(&pr).angle(Vector2 { x: 1.0, y: 0.0 });
|
||||||
.angle(Vector2 { x: 1.0, y: 0.0 })
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let velocity = {
|
let velocity = {
|
||||||
let a = rng
|
let a = rng
|
||||||
|
@ -339,7 +335,7 @@ impl<'a> World {
|
||||||
particles.push(ParticleBuilder::from_content(
|
particles.push(ParticleBuilder::from_content(
|
||||||
x,
|
x,
|
||||||
pos,
|
pos,
|
||||||
Rad::from(-angle),
|
-angle,
|
||||||
velocity,
|
velocity,
|
||||||
Vector2::zero(),
|
Vector2::zero(),
|
||||||
));
|
));
|
||||||
|
@ -368,7 +364,6 @@ impl<'a> World {
|
||||||
&self,
|
&self,
|
||||||
s: ShipPhysicsHandle,
|
s: ShipPhysicsHandle,
|
||||||
) -> Option<(&objects::ShipWorldObject, &RigidBody)> {
|
) -> Option<(&objects::ShipWorldObject, &RigidBody)> {
|
||||||
// TODO: handle dead handles
|
|
||||||
Some((self.ships.get(&s.1)?, self.wrapper.rigid_body_set.get(s.0)?))
|
Some((self.ships.get(&s.1)?, self.wrapper.rigid_body_set.get(s.0)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue