summaryrefslogtreecommitdiff
path: root/src/sim/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/lib')
-rw-r--r--src/sim/lib/force.rs76
-rw-r--r--src/sim/lib/mod.rs1
2 files changed, 77 insertions, 0 deletions
diff --git a/src/sim/lib/force.rs b/src/sim/lib/force.rs
new file mode 100644
index 0000000..50b5c70
--- /dev/null
+++ b/src/sim/lib/force.rs
@@ -0,0 +1,76 @@
+use glam::Vec2;
+use rand::random_range;
+
+use crate::sim::{
+ cell::{
+ cell::Cell,
+ materials::{MaterialId, fire::FireCellView},
+ },
+ cell_sim::world::World,
+ particle_sim::{ParticleManager, particle::Particle},
+ rb_sim::RbSimManager,
+};
+
+pub fn apply_explosion(
+ centre: Vec2,
+ radius: i32,
+ force_offset: Vec2,
+ force_multiplier: f32,
+ next_seqno: u64,
+ particle_manager: &mut ParticleManager,
+ world: &mut World,
+ rbsm: &mut RbSimManager,
+) {
+ let get_vel = |pos: Vec2| {
+ let d = pos.distance(centre);
+ if d < 0.001 {
+ return Vec2::ZERO;
+ }
+ let dir = (pos - centre) / d;
+ let falloff = 1.0 - (d / radius as f32);
+ return (force_offset + dir) * force_multiplier * random_range(0.5..1.5) * falloff;
+ };
+
+ // cell grid
+ for x in -radius..radius {
+ for y in -radius..radius {
+ if x.pow(2) + y.pow(2) < radius.pow(2) {
+ // if there's a cell, convert it to a particle
+ let pos = Vec2::new(centre.x + x as f32, centre.y + y as f32);
+ let ipos = pos.round().as_ivec2();
+ if let Some(cell) = world.get_cell_from_game_position(ipos.x, ipos.y) {
+ let mut fire = Cell::from_material(MaterialId::Fire);
+ fire.set_ticks_lived(300);
+ fire.match_parity(next_seqno);
+
+ if cell.material == MaterialId::Void && random_range(0.0..1.0) > 0.5 {
+ if random_range(0.0..1.0) > 0.1 {
+ world.set_cell_from_game_position(ipos.x, ipos.y, fire, false);
+ } else {
+ let vel = get_vel(pos);
+ particle_manager.particles.push(Particle::new(
+ pos,
+ vel,
+ MaterialId::Fire,
+ 1.0,
+ ));
+ }
+ } else {
+ world.set_cell_from_game_position(ipos.x, ipos.y, fire, false);
+ if random_range(0.0..1.0) > 0.6 {
+ let vel = get_vel(pos);
+ particle_manager.particles.push(Particle::new(
+ pos,
+ vel,
+ cell.material,
+ 5.0,
+ ));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // rigidbodies
+}
diff --git a/src/sim/lib/mod.rs b/src/sim/lib/mod.rs
index 1d802dc..a00d7e6 100644
--- a/src/sim/lib/mod.rs
+++ b/src/sim/lib/mod.rs
@@ -1 +1,2 @@
+pub mod force;
pub mod marching_squares;