diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-22 17:52:57 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-22 17:52:57 -0700 |
| commit | 020a67107b0fb78f053fa9f45205c093dfbaaeb3 (patch) | |
| tree | 1e970cba6f94e053db284a8394b9a9790a359f77 /src/sim/entity | |
| parent | bdad89910dcf3a56790dba60ed1f0db679432323 (diff) | |
entity behavour, grenades
Diffstat (limited to 'src/sim/entity')
| -rw-r--r-- | src/sim/entity/entities/entity_grenade.rs | 64 | ||||
| -rw-r--r-- | src/sim/entity/entities/mod.rs | 1 | ||||
| -rw-r--r-- | src/sim/entity/mod.rs | 85 |
3 files changed, 130 insertions, 20 deletions
diff --git a/src/sim/entity/entities/entity_grenade.rs b/src/sim/entity/entities/entity_grenade.rs new file mode 100644 index 0000000..eead416 --- /dev/null +++ b/src/sim/entity/entities/entity_grenade.rs @@ -0,0 +1,64 @@ +use glam::{IVec2, Vec2}; + +use crate::sim::{ + cell::{cell::Cell, materials::MaterialId}, + entity::{EntityBehaviour, EntityCells, EntityDef, EntityUpdateCtx, SimCtx}, + lib::force::apply_explosion, +}; + +struct GrenadeEntityBehaviour { + pub fuse: f32, +} + +impl EntityBehaviour for GrenadeEntityBehaviour { + fn physics_update( + &mut self, + _update_ctx: &mut EntityUpdateCtx, + _ctx: &mut SimCtx, + _delta_time: f32, + ) -> () { + } + fn update( + &mut self, + update_ctx: &mut EntityUpdateCtx, + ctx: &mut SimCtx, + delta_time: f32, + ) -> () { + self.fuse -= delta_time; + if self.fuse <= 0.0 { + apply_explosion( + ctx, + update_ctx.entity_data.transform(ctx).unwrap().0, + 15, + Vec2::new(0.0, -0.6), + 200.0, + ); + update_ctx.deferred_destroy(update_ctx.entity_data.id); + } + } +} + +pub fn entity_grenade_def(position: Vec2, fuse: f32) -> EntityDef { + let w = 3; + let h = 3; + let mut raw_cells = vec![Cell::void(); (w * h) as usize]; + + for x in 0..w { + for y in 0..h { + let cell_idx = x + y * w; + raw_cells[cell_idx as usize] = Cell::from_material(MaterialId::Wood); + raw_cells[cell_idx as usize].set_entity(true); + } + } + + let entity_cells = EntityCells { + cells: raw_cells, + size: IVec2::new(w, h), + }; + + EntityDef::from_cells( + position, + entity_cells, + Some(Box::new(GrenadeEntityBehaviour { fuse })), + ) +} diff --git a/src/sim/entity/entities/mod.rs b/src/sim/entity/entities/mod.rs index 449b068..e78eb89 100644 --- a/src/sim/entity/entities/mod.rs +++ b/src/sim/entity/entities/mod.rs @@ -1 +1,2 @@ pub mod entity_cube; +pub mod entity_grenade; diff --git a/src/sim/entity/mod.rs b/src/sim/entity/mod.rs index b648f1d..c6c350e 100644 --- a/src/sim/entity/mod.rs +++ b/src/sim/entity/mod.rs @@ -10,7 +10,7 @@ use crate::{ cell::{cell::Cell, materials::MaterialId}, lib::marching_squares::Marchable, rb_manager::RbManager, - sim_manager::SimManager, + sim_manager::SimCtx, }, }; @@ -46,12 +46,17 @@ impl Marchable for EntityCells { } pub trait EntityBehaviour { - fn update(&mut self, sim: &mut SimManager, delta_time: f32) -> (); - fn physics_update(&mut self, sim: &mut SimManager, delta_time: f32) -> (); + fn update(&mut self, update_ctx: &mut EntityUpdateCtx, ctx: &mut SimCtx, delta_time: f32) + -> (); + fn physics_update( + &mut self, + update_ctx: &mut EntityUpdateCtx, + ctx: &mut SimCtx, + delta_time: f32, + ) -> (); } pub struct EntityDef { - pub position: Vec2, pub rb: Option<RigidBody>, pub collider: Option<Collider>, pub cells: Option<EntityCells>, @@ -71,7 +76,6 @@ impl EntityDef { let collider = RbManager::convex_hull_collider_from_marchable(&cells, None).build(); EntityDef { - position, rb: Some(rb), collider: Some(collider), cells: Some(cells), @@ -80,19 +84,44 @@ impl EntityDef { } } -pub struct Entity { +pub struct EntityData { pub id: u32, pub rb_h: Option<RigidBodyHandle>, pub collider_h: Option<ColliderHandle>, pub cells: Option<EntityCells>, - behaviour: Option<Box<dyn EntityBehaviour>>, } -impl Entity { - pub fn transform(&self, sim: &SimManager) -> Option<(Vec2, (f32, f32))> { +pub struct EntityUpdateResult { + pub deferred_destructions: Vec<u32>, +} + +pub struct EntityUpdateCtx<'a> { + pub entity_data: &'a mut EntityData, + deferred_destructions: Vec<u32>, +} + +impl<'a> EntityUpdateCtx<'a> { + pub fn from_entity_data(entity_data: &'a mut EntityData) -> Self { + EntityUpdateCtx { + entity_data, + deferred_destructions: Vec::new(), + } + } + pub fn deferred_destroy(&mut self, entity_id: u32) { + self.deferred_destructions.push(entity_id); + } + pub fn to_result(self) -> EntityUpdateResult { + EntityUpdateResult { + deferred_destructions: self.deferred_destructions, + } + } +} + +impl EntityData { + pub fn transform(&self, ctx: &SimCtx) -> Option<(Vec2, (f32, f32))> { self.rb_h .map(|rb_h| { - sim.rb_manager + ctx.rb_manager .physics_manager .rigid_body_set .get(rb_h) @@ -105,20 +134,34 @@ impl Entity { }) .flatten() } +} - // TODO use drop? - pub fn destroy(&mut self, sim: &mut SimManager) -> () {} +pub struct Entity { + pub data: EntityData, + behaviour: Option<Box<dyn EntityBehaviour>>, +} - pub fn update(&mut self, sim: &mut SimManager, delta_time: f32) -> () { +impl Entity { + pub fn update(&mut self, ctx: &mut SimCtx, delta_time: f32) -> Option<EntityUpdateResult> { if let Some(behaviour) = &mut self.behaviour { - behaviour.update(sim, delta_time); + let mut ectx = EntityUpdateCtx::from_entity_data(&mut self.data); + behaviour.update(&mut ectx, ctx, delta_time); + return Some(ectx.to_result()); } + None } - pub fn physics_update(&mut self, sim: &mut SimManager, delta_time: f32) -> () { + pub fn physics_update( + &mut self, + ctx: &mut SimCtx, + delta_time: f32, + ) -> Option<EntityUpdateResult> { if let Some(behaviour) = &mut self.behaviour { - behaviour.physics_update(sim, delta_time); + let mut ectx = EntityUpdateCtx::from_entity_data(&mut self.data); + behaviour.physics_update(&mut ectx, ctx, delta_time); + return Some(ectx.to_result()); } + None } pub fn new( @@ -129,10 +172,12 @@ impl Entity { behaviour: Option<Box<dyn EntityBehaviour>>, ) -> Self { Entity { - id, - rb_h, - collider_h, - cells, + data: EntityData { + id, + rb_h, + collider_h, + cells, + }, behaviour, } } |
