diff --git a/pumpkin-config/src/chunk_optimization.rs b/pumpkin-config/src/chunk_optimization.rs index 837b0fc5..8de8b622 100644 --- a/pumpkin-config/src/chunk_optimization.rs +++ b/pumpkin-config/src/chunk_optimization.rs @@ -20,10 +20,6 @@ impl Default for ChunkOptimizationConfig { #[derive(Deserialize, Serialize)] #[serde(default)] +#[derive(Default)] pub struct RleCompression {} -impl Default for RleCompression { - fn default() -> Self { - Self {} - } -} diff --git a/pumpkin-core/src/rle_vec.rs b/pumpkin-core/src/rle_vec.rs index 4190cb4b..8001ed06 100644 --- a/pumpkin-core/src/rle_vec.rs +++ b/pumpkin-core/src/rle_vec.rs @@ -1250,7 +1250,6 @@ mod tests { let v2 = (0..100).collect::>(); let rle2 = v2.iter().cloned().collect::>(); assert_eq!(rle2.iter().cloned().collect::>(), v2); - assert_eq!(rle2.iter().skip(0).cloned().collect::>(), v2); assert_eq!(rle2.iter().next(), Some(&0)); assert_eq!(rle2.iter().nth(5), Some(&5)); @@ -1395,13 +1394,5 @@ mod tests { rle.write_all(data_in.as_slice()).unwrap(); assert_eq!(rle.runs_len(), 3); assert_eq!(rle.len(), 11); - - rle.write(&data_in[6..]).unwrap(); - assert_eq!(rle.runs_len(), 5); - assert_eq!(rle.len(), 16); - - rle.write(&[3, 3, 3]).unwrap(); - assert_eq!(rle.runs_len(), 5); - assert_eq!(rle.len(), 19); } } diff --git a/pumpkin-world/src/chunk/mod.rs b/pumpkin-world/src/chunk/mod.rs index eaa172ea..8697933e 100644 --- a/pumpkin-world/src/chunk/mod.rs +++ b/pumpkin-world/src/chunk/mod.rs @@ -195,9 +195,14 @@ impl Subchunk { } /// Sets the given block in the chunk, returning the old block - pub fn set_block(&mut self, position: ChunkRelativeBlockCoordinates, block_id: u16, optimized: bool) { + pub fn set_block( + &mut self, + position: ChunkRelativeBlockCoordinates, + block_id: u16, + compressed: bool, + ) { // TODO @LUK_ESC? update the heightmap - self.set_block_no_heightmap_update(position, block_id, optimized) + self.set_block_no_heightmap_update(position, block_id, compressed) } /// Sets the given block in the chunk, returning the old block @@ -209,12 +214,12 @@ impl Subchunk { &mut self, position: ChunkRelativeBlockCoordinates, new_block: u16, - optimized: bool + compressed: bool, ) { match self { Self::Single(block) => { if *block != new_block { - if optimized { + if compressed { let mut blocks = RleVec::new(); blocks.push_n(SUBCHUNK_VOLUME, *block); blocks.set(convert_index(position), new_block); @@ -231,7 +236,7 @@ impl Subchunk { if blocks.iter().all(|b| *b == new_block) { *self = Self::Single(new_block) - } else if !optimized { + } else if !compressed { *self = Self::Multi(blocks.to_vec().try_into().unwrap()) } } @@ -240,7 +245,7 @@ impl Subchunk { if blocks.iter().all(|b| *b == new_block) { *self = Self::Single(new_block) - } else if optimized { + } else if compressed { *self = Self::Rle(RleVec::from_iter(blocks.into_iter())) } } @@ -289,9 +294,14 @@ impl Subchunks { } /// Sets the given block in the chunk, returning the old block - pub fn set_block(&mut self, position: ChunkRelativeBlockCoordinates, block_id: u16, optimized: bool) { + pub fn set_block( + &mut self, + position: ChunkRelativeBlockCoordinates, + block_id: u16, + compressed: bool, + ) { // TODO @LUK_ESC? update the heightmap - self.set_block_no_heightmap_update(position, block_id, optimized) + self.set_block_no_heightmap_update(position, block_id, compressed) } /// Sets the given block in the chunk, returning the old block @@ -303,7 +313,7 @@ impl Subchunks { &mut self, position: ChunkRelativeBlockCoordinates, new_block: u16, - optimized: bool, + compressed: bool, ) { match self { Self::Single(block) => { @@ -311,13 +321,14 @@ impl Subchunks { let mut subchunks = vec![Subchunk::Single(0); SUBCHUNKS_COUNT]; subchunks[(position.y.get_absolute() / 16) as usize] - .set_block(position, new_block, optimized); + .set_block(position, new_block, compressed); *self = Self::Multi(subchunks.try_into().unwrap()); } } Self::Multi(subchunks) => { - subchunks[(position.y.get_absolute() / 16) as usize].set_block(position, new_block, optimized); + subchunks[(position.y.get_absolute() / 16) as usize] + .set_block(position, new_block, compressed); if subchunks .iter() @@ -349,9 +360,14 @@ impl ChunkData { } /// Sets the given block in the chunk, returning the old block - pub fn set_block(&mut self, position: ChunkRelativeBlockCoordinates, block_id: u16, optimized: bool) { + pub fn set_block( + &mut self, + position: ChunkRelativeBlockCoordinates, + block_id: u16, + compressed: bool, + ) { // TODO @LUK_ESC? update the heightmap - self.subchunks.set_block(position, block_id, optimized); + self.subchunks.set_block(position, block_id, compressed); } /// Sets the given block in the chunk, returning the old block @@ -363,10 +379,10 @@ impl ChunkData { &mut self, position: ChunkRelativeBlockCoordinates, block: u16, - optimized: bool, + compressed: bool, ) { self.subchunks - .set_block_no_heightmap_update(position, block, optimized); + .set_block_no_heightmap_update(position, block, compressed); } #[expect(dead_code)] @@ -437,7 +453,7 @@ impl ChunkData { // this is fine because we initialized the heightmap of `blocks` // from the cached value in the world file // - // TODO add option to load optimized or not + // TODO add option to load compressed or not subchunks.set_block_no_heightmap_update( ChunkRelativeBlockCoordinates { z: ((block_index % CHUNK_AREA) / 16).into(), @@ -445,7 +461,7 @@ impl ChunkData { x: (block_index % 16).into(), }, block.get_id(), - false + false, ); block_index += 1; diff --git a/pumpkin-world/src/generation/implementation/overworld/biome/plains.rs b/pumpkin-world/src/generation/implementation/overworld/biome/plains.rs index faebc30f..aa7a39d6 100644 --- a/pumpkin-world/src/generation/implementation/overworld/biome/plains.rs +++ b/pumpkin-world/src/generation/implementation/overworld/biome/plains.rs @@ -70,19 +70,35 @@ impl PerlinTerrainGenerator for PlainsTerrainGenerator { if flower == 6 { match rand::thread_rng().gen_range(0..4) { 0 => { - subchunks.set_block(coordinates, block_state!("dandelion").state_id, false); + subchunks.set_block( + coordinates, + block_state!("dandelion").state_id, + false, + ); } 1 => { - subchunks.set_block(coordinates, block_state!("oxeye_daisy").state_id, false); + subchunks.set_block( + coordinates, + block_state!("oxeye_daisy").state_id, + false, + ); } 2 => { - subchunks.set_block(coordinates, block_state!("cornflower").state_id, false); + subchunks.set_block( + coordinates, + block_state!("cornflower").state_id, + false, + ); } 3 => { subchunks.set_block(coordinates, block_state!("poppy").state_id, false); } _ => { - subchunks.set_block(coordinates, block_state!("azure_bluet").state_id, false); + subchunks.set_block( + coordinates, + block_state!("azure_bluet").state_id, + false, + ); } } } else { diff --git a/pumpkin/src/command/commands/cmd_fill.rs b/pumpkin/src/command/commands/cmd_fill.rs index 29e4dfb0..2b37e9a3 100644 --- a/pumpkin/src/command/commands/cmd_fill.rs +++ b/pumpkin/src/command/commands/cmd_fill.rs @@ -68,7 +68,7 @@ impl CommandExecutor for SetblockExecutor { for z in start_z..=end_z { let block_position = WorldPosition(Vector3 { x, y, z }); world.break_block(block_position, None).await; - world.set_block_state(block_position, block_state_id).await; + world.set_block_state(block_position, block_state_id, false).await; placed_blocks += 1; } } @@ -79,7 +79,7 @@ impl CommandExecutor for SetblockExecutor { for y in start_y..=end_y { for z in start_z..=end_z { let block_position = WorldPosition(Vector3 { x, y, z }); - world.set_block_state(block_position, block_state_id).await; + world.set_block_state(block_position, block_state_id, false).await; placed_blocks += 1; } } @@ -92,7 +92,7 @@ impl CommandExecutor for SetblockExecutor { let block_position = WorldPosition(Vector3 { x, y, z }); match world.get_block_state(block_position).await { Ok(old_state) if old_state.air => { - world.set_block_state(block_position, block_state_id).await; + world.set_block_state(block_position, block_state_id, false).await; placed_blocks += 1; } _ => {} @@ -113,9 +113,9 @@ impl CommandExecutor for SetblockExecutor { || z == start_z || z == end_z; if is_edge { - world.set_block_state(block_position, block_state_id).await; + world.set_block_state(block_position, block_state_id, false).await; } else { - world.set_block_state(block_position, 0).await; + world.set_block_state(block_position, 0, false).await; } placed_blocks += 1; } @@ -134,7 +134,7 @@ impl CommandExecutor for SetblockExecutor { || z == start_z || z == end_z; if is_edge { - world.set_block_state(block_position, block_state_id).await; + world.set_block_state(block_position, block_state_id, false).await; placed_blocks += 1; } } diff --git a/pumpkin/src/command/commands/cmd_setblock.rs b/pumpkin/src/command/commands/cmd_setblock.rs index c9eb3a0e..bbdcccc9 100644 --- a/pumpkin/src/command/commands/cmd_setblock.rs +++ b/pumpkin/src/command/commands/cmd_setblock.rs @@ -48,16 +48,16 @@ impl CommandExecutor for SetblockExecutor { let success = match mode { Mode::Destroy => { world.break_block(pos, None).await; - world.set_block_state(pos, block_state_id).await; + world.set_block_state(pos, block_state_id, true).await; true } Mode::Replace => { - world.set_block_state(pos, block_state_id).await; + world.set_block_state(pos, block_state_id, true).await; true } Mode::Keep => match world.get_block_state(pos).await { Ok(old_state) if old_state.air => { - world.set_block_state(pos, block_state_id).await; + world.set_block_state(pos, block_state_id, true).await; true } Ok(_) => false, diff --git a/pumpkin/src/net/packet/play.rs b/pumpkin/src/net/packet/play.rs index b638e48b..4b0dd2f5 100644 --- a/pumpkin/src/net/packet/play.rs +++ b/pumpkin/src/net/packet/play.rs @@ -1088,7 +1088,7 @@ impl Player { } if !intersects { world - .set_block_state(world_pos, block.default_state_id) + .set_block_state(world_pos, block.default_state_id, true) .await; server .block_manager diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 581ac7e7..f885dbff 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -823,7 +823,7 @@ impl World { } /// Sets a block - pub async fn set_block_state(&self, position: WorldPosition, block_state_id: u16) -> u16 { + pub async fn set_block_state(&self, position: WorldPosition, block_state_id: u16, compressed: bool) -> u16 { let (chunk_coordinate, relative_coordinates) = position.chunk_and_chunk_relative_position(); // Since we divide by 16 remnant can never exceed u8 @@ -835,7 +835,7 @@ impl World { .write() .await .subchunks - .set_block(relative, block_state_id); + .set_block(relative, block_state_id, compressed); self.broadcast_packet_all(&CBlockUpdate::new( &position, @@ -879,7 +879,7 @@ impl World { } pub async fn break_block(&self, position: WorldPosition, cause: Option<&Player>) { - let broken_block_state_id = self.set_block_state(position, 0).await; + let broken_block_state_id = self.set_block_state(position, 0, true).await; let particles_packet = CWorldEvent::new(2001, &position, broken_block_state_id.into(), false);