From d6664b9b5a9a3aab500b547e4d7448a8bc4ad416 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Sun, 23 Aug 2026 01:07:07 -0700 Subject: allow entity damage --- src/sim/sim_manager/mod.rs | 61 +++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 19 deletions(-) (limited to 'src/sim/sim_manager') diff --git a/src/sim/sim_manager/mod.rs b/src/sim/sim_manager/mod.rs index 805d152..1a16cfd 100644 --- a/src/sim/sim_manager/mod.rs +++ b/src/sim/sim_manager/mod.rs @@ -6,7 +6,6 @@ use glam::IVec2; use crate::{ Config, config::{PHYSICS_DELTA_TIME, PHYSICS_FPS, SIM_FPS}, - content::materials::MaterialId, sim::{ cell::cell::Cell, cell_manager::manager::CellManager, @@ -130,28 +129,51 @@ impl SimManager { // TODO optimize for (entity_id, cells_written) in cells_written_by_entity { let entity = self.entities.get_mut(&entity_id).unwrap(); + let entity_cells = entity.data.cells.as_mut().unwrap(); + let mut should_update_entity = false; + for (lx, ly, x, y) in cells_written { // update the entity - // TODO we should skip cells that weren't changed? // TODO optimize let new_local_cell = self.cell_manager.get_cell_from_game_position(x, y).unwrap(); - if new_local_cell.material != MaterialId::Void && !new_local_cell.entity() { - panic!( - "Someone swapped into this entity's cell! ({x}, {y}, {m:#?}, {f})", - m = new_local_cell.material, - f = new_local_cell.flags - ); - } - if let Some(cells) = &mut entity.data.cells { - cells.set_cell_at_local_position( - IVec2::new(lx as i32, ly as i32), - new_local_cell, - ); + if !new_local_cell.entity_integrated() { + // this means that the entity changed in some way, so we should recompute its shape + // TODO wait N frames to debounce this + should_update_entity = true; } + // we do this unconditionally because it's cheaper than checking if it actually needs to be updated + // and because we don't have a good way to track changes to cell state + entity_cells + .set_cell_at_local_position(IVec2::new(lx as i32, ly as i32), new_local_cell); + // update the world + // TODO optimize self.cell_manager .set_cell_from_game_position(x, y, Cell::void(), false); } + + if should_update_entity { + if let Some(new_collider) = entity.compute_collider() { + self.rb_manager.physics_manager.collider_set.remove( + entity.data.collider_h.unwrap(), + &mut self.rb_manager.physics_manager.island_manager, + &mut self.rb_manager.physics_manager.rigid_body_set, + true, + ); + + let new_handle = self + .rb_manager + .physics_manager + .collider_set + .insert_with_parent( + new_collider, + entity.data.rb_h.unwrap(), + &mut self.rb_manager.physics_manager.rigid_body_set, + ); + + entity.data.collider_h = Some(new_handle); + } + } } } @@ -165,15 +187,16 @@ impl SimManager { particle_manager: &mut self.particle_manager, }; if let Some(entity) = entity - && let Some(result) = entity.physics_update(&mut ctx, delta_time) { - for d in result.deferred_destructions { - self.destroy_entity(d); - } + && let Some(result) = entity.physics_update(&mut ctx, delta_time) + { + for d in result.deferred_destructions { + self.destroy_entity(d); } + } } // before we move the rigidbodies, upsert the current terrain state - // TODO use the chunk sleeping, and make this range dynamic + // TODO make this range dynamic for cx in -5..5 { for cy in -5..5 { if let Some(chunk) = self -- cgit v1.3.1