From 79d2f91deb250d0dfebd95889893db0bef16fad6 Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Sun, 27 Oct 2024 22:45:51 +0100 Subject: [PATCH] Chunk: Use Air if block is not found So currently we trough an error and don't load the entire chunk if a block is not found in the registry, Which is often the case when loading worlds from older or newer version than Currently supported. So now we will just not load the not founded blocks and load blocks which we found --- pumpkin-world/src/block/block_registry.rs | 14 +++++--------- pumpkin-world/src/block/block_state.rs | 11 +++++------ pumpkin-world/src/chunk/mod.rs | 12 ++++++------ pumpkin/src/client/player_packet.rs | 4 +--- pumpkin/src/world/mod.rs | 9 +++------ 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/pumpkin-world/src/block/block_registry.rs b/pumpkin-world/src/block/block_registry.rs index d3d78317..0bc2d31a 100644 --- a/pumpkin-world/src/block/block_registry.rs +++ b/pumpkin-world/src/block/block_registry.rs @@ -74,28 +74,24 @@ struct Shape { #[derive(Default, Copy, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] #[serde(transparent)] -pub struct BlockId { - pub data: u16, -} +pub struct BlockId(pub u16); impl BlockId { pub fn is_air(&self) -> bool { - self.data == 0 || self.data == 12959 || self.data == 12958 + self.0 == 0 || self.0 == 12959 || self.0 == 12958 } pub fn get_id_mojang_repr(&self) -> i32 { - self.data as i32 + self.0 as i32 } pub fn get_id(&self) -> u16 { - self.data + self.0 } } impl From for BlockId { fn from(value: BlockState) -> Self { - Self { - data: value.get_id(), - } + Self(value.get_id()) } } diff --git a/pumpkin-world/src/block/block_state.rs b/pumpkin-world/src/block/block_state.rs index a2adafea..0c783428 100644 --- a/pumpkin-world/src/block/block_state.rs +++ b/pumpkin-world/src/block/block_state.rs @@ -11,8 +11,9 @@ impl BlockState { pub const AIR: BlockState = BlockState { state_id: 0 }; pub fn new(registry_id: &str) -> Result { - let block_registry = - get_block(registry_id).ok_or(BlockStateError::BlockIdentifierNotFound)?; + let block_registry = get_block(registry_id).ok_or( + BlockStateError::BlockIdentifierNotFound(registry_id.to_string()), + )?; Ok(Self { state_id: block_registry.default_state_id, }) @@ -29,8 +30,6 @@ impl BlockState { #[derive(Error, Debug)] pub enum BlockStateError { - #[error("The requested block identifier does not exist")] - BlockIdentifierNotFound, - #[error("The requested block state id does not exist")] - BlockStateIdNotFound, + #[error("The requested block identifier does not exist {0}")] + BlockIdentifierNotFound(String), } diff --git a/pumpkin-world/src/chunk/mod.rs b/pumpkin-world/src/chunk/mod.rs index bec11d55..49cfd909 100644 --- a/pumpkin-world/src/chunk/mod.rs +++ b/pumpkin-world/src/chunk/mod.rs @@ -246,11 +246,11 @@ impl ChunkData { .palette .iter() .map(|entry| match BlockState::new(&entry.name) { - Err(e) => Err(e), - Ok(state) => Ok(state.into()), + // Block not found, Often the case when World has an newer or older version then block registry + Err(_) => BlockState::AIR, + Ok(state) => state, }) - .collect::, _>>() - .map_err(ChunkParsingError::BlockStateError)?; + .collect::>(); let block_data = match block_states.data { None => { @@ -275,7 +275,7 @@ impl ChunkData { 'block_loop: for block in block_data.iter() { for i in 0..blocks_in_pallete { let index = (block >> (i * block_bit_size)) & mask; - let block = palette[index as usize]; + let block = &palette[index as usize]; // TODO allow indexing blocks directly so we can just use block_index and save some time? // this is fine because we initalized the heightmap of `blocks` @@ -286,7 +286,7 @@ impl ChunkData { y: Height::from_absolute((block_index / CHUNK_AREA) as u16), x: (block_index % 16).into(), }, - block, + BlockId(block.get_id()), ); block_index += 1; diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index d5b865c7..8f24b436 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -621,9 +621,7 @@ impl Player { world .set_block( WorldPosition(location.0 + face.to_offset()), - BlockId { - data: block.default_state_id, - }, + BlockId(block.default_state_id), ) .await; } diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 7add9bea..3a2c1801 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -534,11 +534,8 @@ impl World { let chunk = self.receive_chunk(chunk_coordinate).await; chunk.write().await.blocks.set_block(relative, block_id); - self.broadcast_packet_all(&CBlockUpdate::new( - &position, - i32::from(block_id.data).into(), - )) - .await; + self.broadcast_packet_all(&CBlockUpdate::new(&position, i32::from(block_id.0).into())) + .await; } // Stream the chunks (don't collect them and then do stuff with them) @@ -557,7 +554,7 @@ impl World { } pub async fn break_block(&self, position: WorldPosition) { - self.set_block(position, BlockId { data: 0 }).await; + self.set_block(position, BlockId(0)).await; self.broadcast_packet_all(&CWorldEvent::new(2001, &position, 11, false)) .await;