summaryrefslogtreecommitdiff
path: root/src/sim/sim_manager/mod.rs
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-08-23 01:07:07 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-08-23 01:07:07 -0700
commitd6664b9b5a9a3aab500b547e4d7448a8bc4ad416 (patch)
tree688d30258e1e3b06d038ab40ea9c3d3a561c6426 /src/sim/sim_manager/mod.rs
parent260d5b0056f1a7177bcc98316592811577a0a565 (diff)
allow entity damage
Diffstat (limited to 'src/sim/sim_manager/mod.rs')
-rw-r--r--src/sim/sim_manager/mod.rs61
1 files changed, 42 insertions, 19 deletions
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