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 }