summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/cell.rs9
-rw-r--r--src/sim/cell_manager/chunk.rs31
-rw-r--r--src/sim/cell_manager/manager.rs35
-rw-r--r--src/sim/cell_manager/sim.rs101
-rw-r--r--src/sim/lib/force.rs5
5 files changed, 37 insertions, 144 deletions
diff --git a/src/sim/cell.rs b/src/sim/cell.rs
index d12255e..ca0b969 100644
--- a/src/sim/cell.rs
+++ b/src/sim/cell.rs
@@ -4,6 +4,8 @@ use crate::{config::SETTLED_THRESOHLD, content::materials::MaterialId};
pub struct Cell {
pub material: MaterialId,
pub flags: u8,
+ // TODO move this to a per-chunk hashmap
+ pub data: u16,
}
impl Cell {
@@ -73,9 +75,14 @@ impl Cell {
Cell {
material: MaterialId::Void,
flags: 0,
+ data: 0,
}
}
pub fn from_material(material: MaterialId) -> Cell {
- Cell { material, flags: 0 }
+ Cell {
+ material,
+ flags: 0,
+ data: 0,
+ }
}
}
diff --git a/src/sim/cell_manager/chunk.rs b/src/sim/cell_manager/chunk.rs
index 3bf1e9f..463242d 100644
--- a/src/sim/cell_manager/chunk.rs
+++ b/src/sim/cell_manager/chunk.rs
@@ -1,16 +1,13 @@
-use fxhash::FxHashMap;
use glam::IVec2;
use crate::{
config::{CELLS_IN_CHUNK, CHUNK_SIZE},
content::materials::MaterialForm,
- sim::{cell::Cell, entity::EntityId, lib::marching_squares::Marchable},
+ sim::{cell::Cell, lib::marching_squares::Marchable},
};
pub struct Chunk {
pub cells: Box<[Cell; CELLS_IN_CHUNK]>,
- pub cell_data: FxHashMap<usize, u16>,
- pub cell_entity: FxHashMap<usize, EntityId>,
pub sleeping: bool,
pub needs_texture_update: bool,
}
@@ -25,35 +22,9 @@ impl Chunk {
self.cells[x as usize + y as usize * CHUNK_SIZE as usize] = cell;
}
- #[inline]
- pub fn get_data_at_local_position(&self, x: u8, y: u8) -> Option<u16> {
- self.cell_data
- .get(&(x as usize + y as usize * CHUNK_SIZE as usize))
- .copied()
- }
- #[inline]
- pub fn set_data_at_local_position(&mut self, x: u8, y: u8, data: u16) {
- self.cell_data
- .insert(x as usize + y as usize * CHUNK_SIZE as usize, data);
- }
-
- #[inline]
- pub fn get_entity_at_local_position(&self, x: u8, y: u8) -> Option<EntityId> {
- self.cell_entity
- .get(&(x as usize + y as usize * CHUNK_SIZE as usize))
- .copied()
- }
- #[inline]
- pub fn set_entity_at_local_position(&mut self, x: u8, y: u8, entity_id: EntityId) {
- self.cell_entity
- .insert(x as usize + y as usize * CHUNK_SIZE as usize, entity_id);
- }
-
pub fn void() -> Self {
Chunk {
cells: Box::new([Cell::void(); CELLS_IN_CHUNK]),
- cell_data: FxHashMap::default(),
- cell_entity: FxHashMap::default(),
sleeping: true,
needs_texture_update: true,
}
diff --git a/src/sim/cell_manager/manager.rs b/src/sim/cell_manager/manager.rs
index 12cc1b7..6fa5f37 100644
--- a/src/sim/cell_manager/manager.rs
+++ b/src/sim/cell_manager/manager.rs
@@ -5,7 +5,6 @@ use crate::{
sim::{
cell::Cell,
cell_manager::{chunk::Chunk, sim::sim_tick},
- entity::EntityId,
},
};
@@ -46,40 +45,6 @@ impl CellManager {
}
}
- // VERY EXPENSIVE
- pub fn get_data_from_game_position(&self, x: i32, y: i32) -> Option<u16> {
- let ((cx, cy), (dx, dy)) = CellManager::split_game_position(x, y);
- self.chunk_position_to_chunk_idx
- .get(&(cx, cy))
- .map(|&idx| self.chunks[idx].get_data_at_local_position(dx, dy))
- .flatten()
- }
-
- // VERY EXPENSIVE
- pub fn set_data_from_game_position(&mut self, x: i32, y: i32, data: u16) {
- let ((cx, cy), (dx, dy)) = CellManager::split_game_position(x, y);
- if let Some(&idx) = self.chunk_position_to_chunk_idx.get(&(cx, cy)) {
- self.chunks[idx].set_data_at_local_position(dx, dy, data);
- }
- }
-
- // VERY EXPENSIVE
- pub fn get_entity_from_game_position(&self, x: i32, y: i32) -> Option<EntityId> {
- let ((cx, cy), (dx, dy)) = CellManager::split_game_position(x, y);
- self.chunk_position_to_chunk_idx
- .get(&(cx, cy))
- .map(|&idx| self.chunks[idx].get_entity_at_local_position(dx, dy))
- .flatten()
- }
-
- // VERY EXPENSIVE
- pub fn set_entity_from_game_position(&mut self, x: i32, y: i32, entity_id: EntityId) {
- let ((cx, cy), (dx, dy)) = CellManager::split_game_position(x, y);
- if let Some(&idx) = self.chunk_position_to_chunk_idx.get(&(cx, cy)) {
- self.chunks[idx].set_entity_at_local_position(dx, dy, entity_id);
- }
- }
-
pub fn insert(&mut self, x: i32, y: i32, chunk: Chunk) {
self.chunk_position_to_chunk_idx
.insert((x, y), self.chunks.len());
diff --git a/src/sim/cell_manager/sim.rs b/src/sim/cell_manager/sim.rs
index 5e369a9..ffa253b 100644
--- a/src/sim/cell_manager/sim.rs
+++ b/src/sim/cell_manager/sim.rs
@@ -10,7 +10,6 @@ use crate::{
sim::{
cell::Cell,
cell_manager::{chunk::Chunk, manager::CellManager},
- entity::EntityId,
},
};
@@ -53,10 +52,9 @@ fn neighbourhood_index(x: i8, y: i8) -> usize {
(x + 1 + (y + 1) * 3) as usize
}
-fn internal_get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option<Cell> {
+fn get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option<Cell> {
let dcx = x.div_euclid(CHUNK_SIZE);
let dcy = y.div_euclid(CHUNK_SIZE);
- // optimized path to save on the rem calls
if dcx != 0 || dcy != 0 {
// in a different chunk
let nc_x = x.rem_euclid(CHUNK_SIZE) as u8;
@@ -72,56 +70,6 @@ fn internal_get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option
}
}
-fn internal_get_cell_data(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option<u16> {
- let dcx = x.div_euclid(CHUNK_SIZE);
- let dcy = y.div_euclid(CHUNK_SIZE);
- if dcx != 0 || dcy != 0 {
- // in a different chunk
- let nc_x = x.rem_euclid(CHUNK_SIZE) as u8;
- let nc_y = y.rem_euclid(CHUNK_SIZE) as u8;
-
- chunks[neighbourhood_index(dcx as i8, dcy as i8)]
- .as_ref()
- .map(|chunk| chunk.get_data_at_local_position(nc_x, nc_y))
- .flatten()
- } else {
- chunks[4]
- .as_ref()
- .map(|target| target.get_data_at_local_position(x as u8, y as u8))
- .flatten()
- }
-}
-
-fn internal_set_cell_data(chunks: &mut [Option<&mut Chunk>; 9], x: i32, y: i32, data: u16) {
- let dcx = x.div_euclid(CHUNK_SIZE);
- let dcy = y.div_euclid(CHUNK_SIZE);
- let nc_x = x.rem_euclid(CHUNK_SIZE) as u8;
- let nc_y = y.rem_euclid(CHUNK_SIZE) as u8;
- if let Some(chunk) = &mut chunks[neighbourhood_index(dcx as i8, dcy as i8)] {
- chunk.set_data_at_local_position(nc_x, nc_y, data);
- }
-}
-
-fn internal_get_cell_entity(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option<EntityId> {
- let dcx = x.div_euclid(CHUNK_SIZE);
- let dcy = y.div_euclid(CHUNK_SIZE);
- if dcx != 0 || dcy != 0 {
- // in a different chunk
- let nc_x = x.rem_euclid(CHUNK_SIZE) as u8;
- let nc_y = y.rem_euclid(CHUNK_SIZE) as u8;
-
- chunks[neighbourhood_index(dcx as i8, dcy as i8)]
- .as_ref()
- .map(|chunk| chunk.get_entity_at_local_position(nc_x, nc_y))
- .flatten()
- } else {
- chunks[4]
- .as_ref()
- .map(|target| target.get_entity_at_local_position(x as u8, y as u8))
- .flatten()
- }
-}
-
fn adjacent_chunks(x: u8, y: u8) -> Vec<usize> {
if x == 0 {
if y == 0 {
@@ -185,14 +133,29 @@ fn internal_set_cell(chunks: &mut [Option<&mut Chunk>; 9], x: i32, y: i32, cell:
let cy = y.div_euclid(CHUNK_SIZE);
let lx = x.rem_euclid(CHUNK_SIZE) as u8;
let ly = y.rem_euclid(CHUNK_SIZE) as u8;
- if let Some(chunk) = &mut chunks[neighbourhood_index(cx as i8, cy as i8)] {
- chunk.set_cell_at_local_position(lx, ly, cell);
- chunk.needs_texture_update = true;
- chunk.sleeping = false;
- // if we're at the boundaries of the chunk, wake the adjacent chunk(s)
- for idx in adjacent_chunks(lx, ly) {
- if let Some(chunk) = chunks[idx].as_mut() {
- chunk.sleeping = false;
+ if cx != 0 || cy != 0 {
+ // in a different chunk
+ if let Some(chunk) = &mut chunks[neighbourhood_index(cx as i8, cy as i8)] {
+ chunk.set_cell_at_local_position(lx, ly, cell);
+ chunk.needs_texture_update = true;
+ chunk.sleeping = false;
+ // if we're at the boundaries of the chunk, wake the adjacent chunk(s)
+ for idx in adjacent_chunks(lx, ly) {
+ if let Some(chunk) = chunks[idx].as_mut() {
+ chunk.sleeping = false;
+ }
+ }
+ }
+ } else {
+ if let Some(target) = &mut chunks[4] {
+ target.set_cell_at_local_position(x as u8, y as u8, cell);
+ target.needs_texture_update = true;
+ target.sleeping = false;
+ // if we're at the boundaries of the chunk, wake the adjacent chunk(s)
+ for idx in adjacent_chunks(lx, ly) {
+ if let Some(chunk) = chunks[idx].as_mut() {
+ chunk.sleeping = false;
+ }
}
}
}
@@ -227,7 +190,7 @@ impl UpdateCtx<'_, '_, '_> {
pub fn get_cell(&self, dx: i32, dy: i32) -> Option<Cell> {
let x = self.x + dx;
let y = self.y + dy;
- internal_get_cell(self.chunks, x, y)
+ get_cell(self.chunks, x, y)
}
pub fn set_cell(&mut self, dx: i32, dy: i32, cell: Cell) {
@@ -240,18 +203,6 @@ impl UpdateCtx<'_, '_, '_> {
internal_set_cell(self.chunks, x, y, cell);
}
- pub fn get_cell_data(&self, dx: i32, dy: i32) -> Option<u16> {
- let x = self.x + dx;
- let y = self.y + dy;
- internal_get_cell_data(self.chunks, x, y)
- }
-
- pub fn set_cell_data(&mut self, dx: i32, dy: i32, data: u16) {
- let x = self.x + dx;
- let y = self.y + dy;
- internal_set_cell_data(self.chunks, x, y, data);
- }
-
pub fn swap_or_settle(&mut self, candidates: &[(i32, i32)]) -> PostUpdateAction {
for &(dx, dy) in candidates {
if let Some(mut candidate_cell) = self.get_cell(dx, dy)
@@ -284,7 +235,7 @@ fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) {
(CHUNK_SIZE) - i - 1
};
- let mut cell = internal_get_cell(chunks, x, y).unwrap();
+ let mut cell = get_cell(chunks, x, y).unwrap();
let material = cell.material.def();
if let Some(update) = material.sim_update
diff --git a/src/sim/lib/force.rs b/src/sim/lib/force.rs
index fd164f1..e99817c 100644
--- a/src/sim/lib/force.rs
+++ b/src/sim/lib/force.rs
@@ -4,7 +4,7 @@ use rapier2d::{dynamics::RigidBodyHandle, parry::bounding_volume::Aabb, pipeline
use crate::{
config::CELLS_TO_METRES,
- content::materials::{MaterialForm, MaterialId},
+ content::materials::{MaterialForm, MaterialId, fire::FireCellView},
sim::{cell::Cell, lib::ray::AwDda, particle_manager::particle::Particle, sim_manager::SimCtx},
};
@@ -34,8 +34,7 @@ pub fn apply_explosion(
let ipos = pos.round().as_ivec2();
if let Some(cell) = ctx.cell_manager.get_cell_from_game_position(ipos.x, ipos.y) {
let mut fire = Cell::from_material(MaterialId::Fire);
- ctx.cell_manager
- .set_data_from_game_position(ipos.x, ipos.y, 300);
+ fire.set_ticks_lived(300);
fire.match_parity(ctx.cell_manager.seqno);
if cell.material == MaterialId::Void && random_range(0.0..1.0) > 0.5 {