summaryrefslogtreecommitdiff
path: root/src/sim/particle_manager/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/particle_manager/mod.rs')
-rw-r--r--src/sim/particle_manager/mod.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/sim/particle_manager/mod.rs b/src/sim/particle_manager/mod.rs
new file mode 100644
index 0000000..e5e47eb
--- /dev/null
+++ b/src/sim/particle_manager/mod.rs
@@ -0,0 +1,85 @@
+use crate::{
+ config::PIXELS_TO_METRES,
+ sim::{
+ cell::{cell::Cell, materials::MaterialForm},
+ cell_manager::manager::CellManager,
+ lib::ray::AwDda,
+ particle_manager::particle::Particle,
+ },
+};
+
+pub mod particle;
+
+pub struct ParticleManager {
+ pub particles: Vec<Particle>,
+}
+
+const PARTICLE_GRAVITY: f32 = 9.81 * PIXELS_TO_METRES;
+
+impl ParticleManager {
+ pub fn tick(&mut self, world: &mut CellManager, delta_time: f32) {
+ puffin::profile_function!();
+ let mut i = 0;
+ 'outer: while i < self.particles.len() {
+ let p = &mut self.particles[i];
+
+ p.life -= delta_time;
+ if p.life <= 0.0 {
+ self.particles.swap_remove(i);
+ continue 'outer;
+ }
+
+ p.velocity.y += PARTICLE_GRAVITY * delta_time;
+ let dt_velocity = p.velocity * delta_time;
+
+ let mut dda = AwDda::new(p.position, p.position + dt_velocity);
+
+ if let Some(mut prev) = dda.next() {
+ if let Some(cell) = world.get_cell_from_game_position(prev.x, prev.y)
+ && [
+ MaterialForm::Solid,
+ MaterialForm::Powder,
+ MaterialForm::Liquid,
+ ]
+ .contains(&cell.material.def().form)
+ {
+ // the particle is already inside a collider, we should just kill it
+ self.particles.swap_remove(i);
+ continue 'outer;
+ }
+
+ for next in dda {
+ if let Some(cell) = world.get_cell_from_game_position(next.x, next.y)
+ && [
+ MaterialForm::Solid,
+ MaterialForm::Powder,
+ MaterialForm::Liquid,
+ ]
+ .contains(&cell.material.def().form)
+ {
+ // write ourselves to the board
+ world.set_cell_from_game_position(
+ prev.x,
+ prev.y,
+ Cell::from_material(p.material),
+ false,
+ );
+ self.particles.swap_remove(i);
+ continue 'outer;
+ }
+ prev = next;
+ }
+ }
+
+ // no collision, just move
+ p.position += dt_velocity;
+ i += 1;
+ }
+ }
+
+ pub fn new() -> Self {
+ ParticleManager {
+ particles: Vec::new(),
+ }
+ }
+}