diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index 34f8980a..fa275bb1 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -168,10 +168,7 @@ impl ByteBuffer { /// some, then it also calls the `write` closure. pub fn put_option(&mut self, val: &Option, write: impl FnOnce(&mut Self, &T)) { self.put_bool(val.is_some()); - match val { - Some(v) => write(self, v), - None => {} - } + if let Some(v) = val { write(self, v) } } pub fn get_list(&mut self, val: impl Fn(&mut Self) -> T) -> Vec { diff --git a/pumpkin-world/src/chunk.rs b/pumpkin-world/src/chunk.rs index 70869857..c3fe94ff 100644 --- a/pumpkin-world/src/chunk.rs +++ b/pumpkin-world/src/chunk.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use fastnbt::LongArray; -use crate::{level::WorldError, WORLD_HEIGHT}; +use crate::{level::WorldError, vector3::Vector3, WORLD_HEIGHT, WORLD_Y_START_AT}; pub struct ChunkData { pub blocks: Box<[i32; 16 * 16 * WORLD_HEIGHT]>, @@ -110,4 +110,21 @@ impl ChunkData { heightmaps: chunk_data.heightmaps, }) } + /// Sets the given block in the chunk, returning the old block + pub fn set_block(&mut self, at: Vector3, block_id: i32) -> Result { + let x = at.x - self.position.0 * 16; + let z = at.z - self.position.1 * 16; + let y = at.y - WORLD_Y_START_AT; + if !(0..16).contains(&x) + || !(0..16).contains(&z) + || !(0..(WORLD_HEIGHT as i32)).contains(&y) + { + return Err(WorldError::BlockOutsideChunk); + } + + Ok(std::mem::replace( + &mut self.blocks[(y * 16 * 16 + z * 16 + x) as usize], + block_id, + )) + } } diff --git a/pumpkin-world/src/level.rs b/pumpkin-world/src/level.rs index 96dbfb5a..3ccff077 100644 --- a/pumpkin-world/src/level.rs +++ b/pumpkin-world/src/level.rs @@ -36,6 +36,8 @@ pub enum WorldError { ErrorDeserializingChunk(String), #[error("The requested block state id does not exist")] BlockStateIdNotFound, + #[error("The block is not inside of the chunk")] + BlockOutsideChunk, } #[derive(Error, Debug)]