summaryrefslogtreecommitdiff
path: root/src/sim/cell_sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/cell_sim')
-rw-r--r--src/sim/cell_sim/chunk.rs9
-rw-r--r--src/sim/cell_sim/sim.rs32
2 files changed, 26 insertions, 15 deletions
diff --git a/src/sim/cell_sim/chunk.rs b/src/sim/cell_sim/chunk.rs
index c7d619b..85d2c09 100644
--- a/src/sim/cell_sim/chunk.rs
+++ b/src/sim/cell_sim/chunk.rs
@@ -1,7 +1,10 @@
use crate::{
config::{CELLS_IN_CHUNK, CHUNK_SIZE},
sim::{
- cell::{cell::Cell, materials::MaterialId},
+ cell::{
+ cell::Cell,
+ materials::{MaterialForm, MaterialId},
+ },
lib::marching_squares::Marchable,
},
};
@@ -36,7 +39,9 @@ impl Marchable for Chunk {
if x < 0 || x >= CHUNK_SIZE || y < 0 || y >= CHUNK_SIZE {
false
} else {
- self.get_cell_at_local_position(x as u8, y as u8).material != MaterialId::Void
+ // we only build a path for solid cells or settled powder cells
+ let cell = self.get_cell_at_local_position(x as u8, y as u8);
+ cell.material.def().form == MaterialForm::Solid || cell.settled() > 4
}
}
fn size(&self) -> (i32, i32) {
diff --git a/src/sim/cell_sim/sim.rs b/src/sim/cell_sim/sim.rs
index 8831bb4..4b9f05f 100644
--- a/src/sim/cell_sim/sim.rs
+++ b/src/sim/cell_sim/sim.rs
@@ -5,14 +5,10 @@ use rand::{Rng, SeedableRng, rngs::SmallRng};
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use crate::{
- config::{CELLS_IN_CHUNK, CHUNK_SIZE},
+ config::CHUNK_SIZE,
sim::{
- cell::{
- cell::Cell,
- materials::{MaterialDef, MaterialId},
- },
+ cell::{cell::Cell, materials::MaterialDef},
cell_sim::{chunk::Chunk, world::World},
- rb_sim::{RbSimManager, rb_entity::RbEntity},
},
};
@@ -87,6 +83,7 @@ pub struct UpdateCtx<'a, 'b, 'c> {
pub material: &'c MaterialDef,
pub rng: &'c mut dyn Rng,
+ swapped: bool,
}
impl UpdateCtx<'_, '_, '_> {
@@ -99,8 +96,8 @@ impl UpdateCtx<'_, '_, '_> {
pub fn set_cell(&mut self, dx: i32, dy: i32, cell: Cell) {
// cannot move out of the neighbourhood, but also cannot move to the edge of the neighbourhood
// as this would wake a chunk outside of the neighbourhood
- debug_assert!(dx > -15 && dx < 15);
- debug_assert!(dy > -15 && dy < 15);
+ debug_assert!(dx > -CHUNK_SIZE + 1 && dx < CHUNK_SIZE - 1);
+ debug_assert!(dy > -CHUNK_SIZE + 1 && dy < CHUNK_SIZE - 1);
let x = self.x + dx;
let y = self.y + dy;
set_cell(self.chunks, x, y, cell);
@@ -113,10 +110,14 @@ impl UpdateCtx<'_, '_, '_> {
pub fn candidates_swap(&mut self, candidates: &[(i32, i32)]) -> bool {
for &(dx, dy) in candidates {
- let candidate_cell = self.get_cell(dx, dy);
- if candidate_cell.is_some_and(|c| c.material.def().density < self.material.density) {
- self.set_cell(0, 0, candidate_cell.unwrap());
+ if let Some(mut candidate_cell) = self.get_cell(dx, dy)
+ && candidate_cell.material.def().density < self.material.density
+ {
+ candidate_cell.reset_settled();
+ self.cell.reset_settled();
+ self.set_cell(0, 0, candidate_cell);
self.set_cell(dx, dy, *self.cell);
+ self.swapped = true;
return true;
}
}
@@ -145,8 +146,6 @@ pub fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) {
&& cell.parity() == seqno_parity
{
cell.flip_parity();
- // apply the flipped parity in case the sim target doesn't
- set_cell(chunks, x, y, cell);
let mut update_ctx = UpdateCtx {
chunks,
@@ -160,9 +159,16 @@ pub fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) {
// TODO this is platform-dependent, will break for multiplayer
rng: &mut rng,
+ swapped: false,
};
update(&mut update_ctx);
+
+ if !update_ctx.swapped {
+ // the cell didn't move, so it's more settled, and we also need to update its state for parity
+ cell.increment_settled();
+ set_cell(chunks, x, y, cell);
+ }
}
}
}