Compare commits

...

3 Commits

Author SHA1 Message Date
Mark 1c3f64a132
Updated TODO 2024-01-08 21:04:37 -08:00
Mark fef43d8744
Minor cleanup 2024-01-08 21:02:02 -08:00
Mark 10682db347
Added shields & indicator 2024-01-08 20:43:58 -08:00
21 changed files with 148 additions and 70 deletions

11
TODO.md
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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);
} }

View File

@ -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(),
}); });
} }

View File

@ -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 {

View File

@ -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)

View File

@ -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.

View File

@ -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;
}
}
}
}
}
} }

View File

@ -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,
// };
//}
} }

View File

@ -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

View 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};

View File

@ -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();

View File

@ -65,12 +65,12 @@ fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
global_data.window_scale.x global_data.window_scale.x
) - in.center; ) - in.center;
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
// Clockwise angle between zero_vector and fragment location // Clockwise angle between zero_vector and fragment location
let frag_angle = atan2( let frag_angle = atan2(

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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)?))
} }