summaryrefslogtreecommitdiff
path: root/src/sim/entity/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/entity/mod.rs')
-rw-r--r--src/sim/entity/mod.rs155
1 files changed, 133 insertions, 22 deletions
diff --git a/src/sim/entity/mod.rs b/src/sim/entity/mod.rs
index ab10ea8..b648f1d 100644
--- a/src/sim/entity/mod.rs
+++ b/src/sim/entity/mod.rs
@@ -1,28 +1,139 @@
-// use glam::{IVec2, Vec2};
-// use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
+use glam::{IVec2, Vec2};
+use rapier2d::{
+ dynamics::{RigidBody, RigidBodyBuilder, RigidBodyHandle},
+ geometry::{Collider, ColliderHandle},
+};
-// use crate::sim::cell::cell::Cell;
+use crate::{
+ config::CELLS_TO_METRES,
+ sim::{
+ cell::{cell::Cell, materials::MaterialId},
+ lib::marching_squares::Marchable,
+ rb_manager::RbManager,
+ sim_manager::SimManager,
+ },
+};
-// pub struct EntityCells {
-// pub size: IVec2,
-// pub cells: Vec<Cell>,
-// }
-// pub trait EntityBehaviour {
-// fn update (&mut self) -> ();
-// }
+pub mod entities;
-// pub struct Entity {
-// pub rb_h: Option<RigidBodyHandle>,
-// pub collider_h: Option<ColliderHandle>,
-// pub cells: EntityCells,
-// pub behaviour:
-// }
+pub struct EntityCells {
+ pub size: IVec2,
+ pub cells: Vec<Cell>,
+}
-// impl Entity {
-// pub fn position(&self, rbsm:) -> Vec2 {
+impl EntityCells {
+ #[inline]
+ pub fn get_cell_at_local_position(&self, pos: IVec2) -> Cell {
+ self.cells[pos.x as usize + pos.y as usize * self.size.x as usize]
+ }
+ #[inline]
+ pub fn set_cell_at_local_position(&mut self, pos: IVec2, cell: Cell) {
+ self.cells[pos.x as usize + pos.y as usize * self.size.x as usize] = cell;
+ }
+}
-// }
-// pub fn destroy(&mut self) -> {
+impl Marchable for EntityCells {
+ fn occupied(&self, pos: IVec2) -> bool {
+ if pos.x < 0 || pos.x >= self.size.x || pos.y < 0 || pos.y >= self.size.y {
+ false
+ } else {
+ self.get_cell_at_local_position(pos).material != MaterialId::Void
+ }
+ }
+ fn size(&self) -> IVec2 {
+ self.size
+ }
+}
-// }
-// }
+pub trait EntityBehaviour {
+ fn update(&mut self, sim: &mut SimManager, delta_time: f32) -> ();
+ fn physics_update(&mut self, sim: &mut SimManager, delta_time: f32) -> ();
+}
+
+pub struct EntityDef {
+ pub position: Vec2,
+ pub rb: Option<RigidBody>,
+ pub collider: Option<Collider>,
+ pub cells: Option<EntityCells>,
+ pub behaviour: Option<Box<dyn EntityBehaviour>>,
+}
+
+impl EntityDef {
+ pub fn from_cells(
+ position: Vec2,
+ cells: EntityCells,
+ behaviour: Option<Box<dyn EntityBehaviour>>,
+ ) -> Self {
+ let rb = RigidBodyBuilder::dynamic()
+ .translation(position / CELLS_TO_METRES)
+ .build();
+
+ let collider = RbManager::convex_hull_collider_from_marchable(&cells, None).build();
+
+ EntityDef {
+ position,
+ rb: Some(rb),
+ collider: Some(collider),
+ cells: Some(cells),
+ behaviour,
+ }
+ }
+}
+
+pub struct Entity {
+ 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))> {
+ self.rb_h
+ .map(|rb_h| {
+ sim.rb_manager
+ .physics_manager
+ .rigid_body_set
+ .get(rb_h)
+ .map(|rb| {
+ (
+ rb.translation() * CELLS_TO_METRES,
+ (rb.rotation().cos(), rb.rotation().sin()),
+ )
+ })
+ })
+ .flatten()
+ }
+
+ // TODO use drop?
+ pub fn destroy(&mut self, sim: &mut SimManager) -> () {}
+
+ pub fn update(&mut self, sim: &mut SimManager, delta_time: f32) -> () {
+ if let Some(behaviour) = &mut self.behaviour {
+ behaviour.update(sim, delta_time);
+ }
+ }
+
+ pub fn physics_update(&mut self, sim: &mut SimManager, delta_time: f32) -> () {
+ if let Some(behaviour) = &mut self.behaviour {
+ behaviour.physics_update(sim, delta_time);
+ }
+ }
+
+ pub fn new(
+ id: u32,
+ rb_h: Option<RigidBodyHandle>,
+ collider_h: Option<ColliderHandle>,
+ cells: Option<EntityCells>,
+ behaviour: Option<Box<dyn EntityBehaviour>>,
+ ) -> Self {
+ Entity {
+ id,
+ rb_h,
+ collider_h,
+ cells,
+ behaviour,
+ }
+ }
+}