From cf283323fccf0261083072675d2e6a1424bae348 Mon Sep 17 00:00:00 2001 From: DaniD3v Date: Mon, 26 Aug 2024 13:47:56 +0200 Subject: [PATCH] `BlockId` refactor. Moved `BlockId` to it's own file. Prefixed all of the `block_registry` types with Registry to avoid confusion. Made stuff that should not be public private. --- .../src/client/play/c_chunk_data.rs | 12 +-- pumpkin-world/src/block/block_id.rs | 58 +++++++++++++ pumpkin-world/src/block/block_registry.rs | 81 ++++--------------- pumpkin-world/src/block/mod.rs | 8 +- pumpkin-world/src/chunk.rs | 2 +- pumpkin/src/client/player_packet.rs | 2 +- 6 files changed, 82 insertions(+), 81 deletions(-) create mode 100644 pumpkin-world/src/block/block_id.rs diff --git a/pumpkin-protocol/src/client/play/c_chunk_data.rs b/pumpkin-protocol/src/client/play/c_chunk_data.rs index 0f4ea20ff..0c640c85c 100644 --- a/pumpkin-protocol/src/client/play/c_chunk_data.rs +++ b/pumpkin-protocol/src/client/play/c_chunk_data.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt}; use itertools::Itertools; use pumpkin_macros::packet; -use pumpkin_world::{block::block_registry::BlockId, chunk::ChunkData, DIRECT_PALETTE_BITS}; +use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS}; #[packet(0x27)] pub struct CChunkData<'a>(pub &'a ChunkData); @@ -23,15 +23,7 @@ impl<'a> ClientPacket for CChunkData<'a> { let mut data_buf = ByteBuffer::empty(); self.0.blocks.iter_subchunks().for_each(|chunk| { - let block_count = chunk - .iter() - .dedup() - .filter(|block| { - !block.is_air() - && **block != BlockId::from_id(12959) - && **block != BlockId::from_id(12958) - }) - .count() as i16; + let block_count = chunk.iter().dedup().filter(|block| !block.is_air()).count() as i16; // Block count data_buf.put_i16(block_count); //// Block states diff --git a/pumpkin-world/src/block/block_id.rs b/pumpkin-world/src/block/block_id.rs new file mode 100644 index 000000000..80380842c --- /dev/null +++ b/pumpkin-world/src/block/block_id.rs @@ -0,0 +1,58 @@ +use std::collections::HashMap; + +use serde::Deserialize; + +use super::block_registry::BLOCKS; +use crate::level::WorldError; + +// 0 is air -> reasonable default +#[derive(Default, Deserialize, Debug, Hash, Clone, Copy, PartialEq, Eq)] +#[serde(transparent)] +pub struct BlockId { + data: u16, +} + +impl BlockId { + pub const AIR: Self = Self::from_id(0); + + pub fn new( + text_id: &str, + properties: Option<&HashMap>, + ) -> Result { + let mut block_states = BLOCKS + .get(text_id) + .ok_or(WorldError::BlockIdentifierNotFound)? + .states + .iter(); + + let block_state = match properties { + Some(properties) => match block_states.find(|state| &state.properties == properties) { + Some(state) => state, + None => return Err(WorldError::BlockStateIdNotFound), + }, + None => block_states + .find(|state| state.is_default) + .expect("Every Block should have at least 1 default state"), + }; + + Ok(block_state.id) + } + + pub const fn from_id(id: u16) -> Self { + // TODO: add check if the id is actually valid + Self { data: id } + } + + pub fn is_air(&self) -> bool { + self.data == 0 || self.data == 12959 || self.data == 12958 + } + + pub fn get_id(&self) -> u16 { + self.data + } + + /// An i32 is the way mojang internally represents their Blocks + pub fn get_id_mojang_repr(&self) -> i32 { + self.data as i32 + } +} diff --git a/pumpkin-world/src/block/block_registry.rs b/pumpkin-world/src/block/block_registry.rs index e5df4d15a..c6c9b96f4 100644 --- a/pumpkin-world/src/block/block_registry.rs +++ b/pumpkin-world/src/block/block_registry.rs @@ -3,101 +3,50 @@ use std::collections::HashMap; use lazy_static::lazy_static; use serde::Deserialize; -use crate::level::WorldError; +use super::block_id::BlockId; -const BLOCKS_JSON: &str = include_str!("../../assets/blocks.json"); - -// 0 is air -> reasonable default -#[derive(Default, Deserialize, Debug, Hash, Clone, Copy, PartialEq, Eq)] -#[serde(transparent)] -pub struct BlockId { - data: u16, -} - -impl BlockId { - pub fn new( - block_id: &str, - properties: Option<&HashMap>, - ) -> Result { - let mut block_states = BLOCKS - .get(block_id) - .ok_or(WorldError::BlockIdentifierNotFound)? - .states - .iter(); - - let block_state = match properties { - Some(properties) => match block_states.find(|state| &state.properties == properties) { - Some(state) => state, - None => return Err(WorldError::BlockStateIdNotFound), - }, - None => block_states - .find(|state| state.is_default) - .expect("Every Block should have at least 1 default state"), - }; - - Ok(block_state.id) - } - - pub fn from_id(id: u16) -> Self { - // TODO: add check if the id is actually valid - Self { data: id } - } - - pub fn is_air(&self) -> bool { - self.data == 0 - } - - pub fn get_id(&self) -> u16 { - self.data - } - - /// An i32 is the way mojang internally represents their Blocks - pub fn get_id_mojang_repr(&self) -> i32 { - self.data as i32 - } +lazy_static! { + pub static ref BLOCKS: HashMap = + serde_json::from_str(include_str!("../../assets/blocks.json")) + .expect("Could not parse block.json registry."); } #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] -pub struct BlockDefinition { +pub struct RegistryBlockDefinition { /// e.g. minecraft:door or minecraft:button #[serde(rename = "type")] - category: String, + pub category: String, /// Specifies the variant of the blocks category. /// e.g. minecraft:iron_door has the variant iron #[serde(rename = "block_set_type")] - variant: Option, + pub variant: Option, } /// One possible state of a Block. /// This could e.g. be an extended piston facing left. #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] -pub struct BlockState { - id: BlockId, +pub struct RegistryBlockState { + pub id: BlockId, /// Whether this is the default state of the Block #[serde(default, rename = "default")] - is_default: bool, + pub is_default: bool, /// The propertise active for this `BlockState`. #[serde(default)] - properties: HashMap, + pub properties: HashMap, } /// A fully-fledged block definition. /// Stores the category, variant, all of the possible states and all of the possible properties. #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] -pub struct BlockType { - definition: BlockDefinition, - states: Vec, +pub struct RegistryBlockType { + pub definition: RegistryBlockDefinition, + pub states: Vec, // TODO is this safe to remove? It's currently not used in the Project. @lukas0008 @Snowiiii /// A list of valid property keys/values for a block. #[serde(default, rename = "properties")] valid_properties: HashMap>, } - -lazy_static! { - pub static ref BLOCKS: HashMap = - serde_json::from_str(BLOCKS_JSON).expect("Could not parse block.json registry."); -} diff --git a/pumpkin-world/src/block/mod.rs b/pumpkin-world/src/block/mod.rs index 1009f9fe3..59dc8a083 100644 --- a/pumpkin-world/src/block/mod.rs +++ b/pumpkin-world/src/block/mod.rs @@ -1,9 +1,11 @@ +use crate::vector3::Vector3; use num_derive::FromPrimitive; -use crate::vector3::Vector3; +pub mod block_id; +mod block_registry; + +pub use block_id::BlockId; -pub mod block_registry; -pub use block_registry::BLOCKS; #[derive(FromPrimitive)] pub enum BlockFace { Bottom = 0, diff --git a/pumpkin-world/src/chunk.rs b/pumpkin-world/src/chunk.rs index 3952c770e..677990594 100644 --- a/pumpkin-world/src/chunk.rs +++ b/pumpkin-world/src/chunk.rs @@ -6,7 +6,7 @@ use fastnbt::LongArray; use serde::{Deserialize, Serialize}; use crate::{ - block::block_registry::BlockId, + block::BlockId, coordinates::{ChunkCoordinates, ChunkRelativeBlockCoordinates, Height}, level::WorldError, WORLD_HEIGHT, diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 3ce92017d..13b077af0 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -25,7 +25,7 @@ use pumpkin_protocol::{ SUseItemOn, Status, }, }; -use pumpkin_world::block::{block_registry::BlockId, BlockFace}; +use pumpkin_world::block::{BlockFace, BlockId}; use pumpkin_world::global_registry; use super::PlayerConfig;