summaryrefslogtreecommitdiff
path: root/src/sim/sim.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/sim.rs')
-rw-r--r--src/sim/sim.rs65
1 files changed, 35 insertions, 30 deletions
diff --git a/src/sim/sim.rs b/src/sim/sim.rs
index 4c6d908..84c3126 100644
--- a/src/sim/sim.rs
+++ b/src/sim/sim.rs
@@ -1,6 +1,7 @@
use std::marker::PhantomData;
use fxhash::FxHashMap;
+use rand::{Rng, SeedableRng, rngs::SmallRng};
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use crate::{
@@ -30,17 +31,6 @@ impl<'a> ChunkAccess<'a> {
unsafe impl Sync for ChunkAccess<'_> {}
-pub struct UpdateCtx<'a, 'b, 'c> {
- pub chunks: &'a mut [Option<&'b mut Chunk>; 9],
- pub seqno: u64,
- pub seqno_parity: u8,
-
- pub x: i32,
- pub y: i32,
- pub cell: &'c mut Cell,
- pub material: &'c MaterialDef,
-}
-
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);
@@ -74,17 +64,28 @@ pub fn set_cell(chunks: &mut [Option<&mut Chunk>; 9], x: i32, y: i32, cell: Cell
if let Some(chunk) = &mut chunks[(dcx + 1 + (dcy + 1) * 3) as usize] {
chunk.set_cell_at_local_position(nc_x, nc_y, cell);
chunk.needs_texture_update = true;
- 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;
}
}
}
+pub struct UpdateCtx<'a, 'b, 'c> {
+ pub chunks: &'a mut [Option<&'b mut Chunk>; 9],
+ pub seqno: u64,
+ pub seqno_parity: u8,
+
+ pub x: i32,
+ pub y: i32,
+ pub cell: &'c mut Cell,
+ pub material: &'c MaterialDef,
+
+ pub rng: &'c mut dyn Rng,
+}
+
impl UpdateCtx<'_, '_, '_> {
pub fn get_cell(&self, dx: i32, dy: i32) -> Option<Cell> {
let x = self.x + dx;
@@ -92,7 +93,7 @@ impl UpdateCtx<'_, '_, '_> {
get_cell(self.chunks, x, y)
}
- fn set_cell(&mut self, dx: i32, dy: i32, cell: Cell) {
+ 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);
@@ -122,8 +123,8 @@ impl UpdateCtx<'_, '_, '_> {
pub fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) {
puffin::profile_function!();
- // scan bottom to top to enable contiguous falling
let seqno_parity = (seqno as u8) & 0b1;
+ let mut rng = SmallRng::seed_from_u64(seqno);
if chunks[4].is_some() {
for y in (0..CHUNK_SIZE).rev() {
@@ -135,24 +136,28 @@ pub fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) {
};
let mut cell = get_cell(chunks, x, y).unwrap();
- if cell.flags & 0b1 == seqno_parity {
- // flip the parity bit
- // TODO if the cell doesn't move this doesn't stay
- cell.flags = cell.flags ^ 0b1;
- let material = cell.material.def();
+ let material = cell.material.def();
+
+ if let Some(update) = material.sim_update {
+ if 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,
+ seqno,
+ seqno_parity,
- let mut update_ctx = UpdateCtx {
- chunks,
- seqno,
- seqno_parity,
+ x,
+ y,
+ cell: &mut cell,
+ material,
- x,
- y,
- cell: &mut cell,
- material,
- };
+ // TODO this is platform-dependent, will break for multiplayer
+ rng: &mut rng,
+ };
- if let Some(update) = material.sim_update {
update(&mut update_ctx);
}
}