diff --git a/pumpkin-data/build/block.rs b/pumpkin-data/build/block.rs index 5bac54fbf..890eccf0a 100644 --- a/pumpkin-data/build/block.rs +++ b/pumpkin-data/build/block.rs @@ -182,14 +182,12 @@ impl ToTokens for BlockPropertyStruct { let field_name = Ident::new_raw(&entry.original_name, Span::call_site()); match &entry.property_type { PropertyType::Bool => quote! { - index += !self.#field_name as u16 * multiplier; - multiplier *= 2; + (!self.#field_name as u16, 2) }, PropertyType::Enum { name } => { let enum_ident = Ident::new(name, Span::call_site()); quote! { - index += self.#field_name.to_index() * multiplier; - multiplier *= #enum_ident::variant_count(); + (self.#field_name.to_index(), #enum_ident::variant_count()) } } } @@ -230,10 +228,10 @@ impl ToTokens for BlockPropertyStruct { let field_name = Ident::new_raw(&entry.original_name, Span::call_site()); match &entry.property_type { PropertyType::Bool => quote! { - props.push((#key.to_string(), self.#field_name.to_string())); + (#key.to_string(), self.#field_name.to_string()), }, PropertyType::Enum { name: _ } => quote! { - props.push((#key.to_string(), self.#field_name.to_value().to_string())); + (#key.to_string(), self.#field_name.to_value().to_string()), }, } }); @@ -265,11 +263,12 @@ impl ToTokens for BlockPropertyStruct { } impl BlockProperties for #name { - #[allow(unused_assignments)] fn to_index(&self) -> u16 { - let mut index = 0; - let mut multiplier = 1; - #(#to_index_body)* + let (index, _) = [#(#to_index_body),*] + .iter() + .fold((0, 1), |(current_index, multiplier), &(value, count)| { + (current_index + value * multiplier, multiplier * count) + }); index } @@ -311,13 +310,10 @@ impl ToTokens for BlockPropertyStruct { Self::from_state_id(block.default_state.id, block) } - #[allow(clippy::vec_init_then_push)] - fn to_props(&self) -> Vec<(String, String)> { - let mut props = vec![]; - #(#to_props_values)* - props + fn to_props(&self) -> HashMap { + HashMap::from([#(#to_props_values)*]) } - fn from_props(props: Vec<(&str, &str)>, block: &Block) -> Self { + fn from_props(props: HashMap<&str, &str>, block: &Block) -> Self { if ![#(#block_ids),*].contains(&block.id) { panic!("{} is not a valid block for {}", &block.name, #struct_name); } @@ -847,6 +843,8 @@ pub(crate) fn build() -> TokenStream { use pumpkin_util::loot_table::*; use pumpkin_util::math::experience::Experience; use pumpkin_util::math::vector3::Vector3; + use std::collections::HashMap; + #[derive(Clone, Copy, Debug)] pub struct BlockProperty { @@ -871,10 +869,10 @@ pub(crate) fn build() -> TokenStream { fn default(block: &Block) -> Self where Self: Sized; // Convert properties to a `Vec` of `(name, value)` - fn to_props(&self) -> Vec<(String, String)>; + fn to_props(&self) -> HashMap; // Convert properties to a block state, and add them onto the default state. - fn from_props(props: Vec<(&str, &str)>, block: &Block) -> Self where Self: Sized; + fn from_props(props: HashMap<&str, &str>, block: &Block) -> Self where Self: Sized; } pub trait EnumVariants { @@ -986,7 +984,7 @@ pub(crate) fn build() -> TokenStream { } #[doc = r" Get the properties of the block."] - pub fn from_properties(&self, props: Vec<(&str, &str)>) -> Option> { + pub fn from_properties(&self, props: HashMap<&str, &str>) -> Option> { match self.id { #block_properties_from_props_and_name _ => None diff --git a/pumpkin-data/build/fluid.rs b/pumpkin-data/build/fluid.rs index 883c3ebf9..bb8ff92e5 100644 --- a/pumpkin-data/build/fluid.rs +++ b/pumpkin-data/build/fluid.rs @@ -173,7 +173,7 @@ impl ToTokens for FluidPropertyStruct { let key2 = Ident::new_raw(&entry.original_name, Span::call_site()); quote! { - props.push((#key.to_string(), self.#key2.to_value().to_string())); + (#key.to_string(), self.#key2.to_value().to_string()), } }); @@ -255,13 +255,8 @@ impl ToTokens for FluidPropertyStruct { Self::from_state_id(fluid.default_state_index, fluid) } - #[allow(clippy::vec_init_then_push)] fn to_props(&self) -> Vec<(String, String)> { - let mut props = vec![]; - - #(#to_props_values)* - - props + vec![#(#to_props_values)*] } fn from_props(props: Vec<(String, String)>, fluid: &Fluid) -> Self { diff --git a/pumpkin-world/src/block/mod.rs b/pumpkin-world/src/block/mod.rs index 6b4a0d8ab..e29fa759a 100644 --- a/pumpkin-world/src/block/mod.rs +++ b/pumpkin-world/src/block/mod.rs @@ -27,11 +27,11 @@ impl BlockStateCodec { let mut state_id = block.default_state.id; if let Some(properties) = &self.properties { - let properties_vec: Vec<(&str, &str)> = properties + let props = properties .iter() - .map(|(key, value)| (key.as_str(), value.as_str())) + .map(|(k, v)| (k.as_str(), v.as_str())) .collect(); - let block_properties = block.from_properties(properties_vec).unwrap(); + let block_properties = block.from_properties(props).unwrap(); state_id = block_properties.to_state_id(&block); } diff --git a/pumpkin-world/src/chunk/palette.rs b/pumpkin-world/src/chunk/palette.rs index a54b1fe9e..f7680352d 100644 --- a/pumpkin-world/src/chunk/palette.rs +++ b/pumpkin-world/src/chunk/palette.rs @@ -439,18 +439,7 @@ impl BlockPalette { BlockStateCodec { name: block.name.into(), - properties: { - if let Some(properties) = block.properties(registry_id) { - let props = properties.to_props(); - let mut props_map = HashMap::new(); - for prop in props { - props_map.insert(prop.0.clone(), prop.1.clone()); - } - Some(props_map) - } else { - None - } - }, + properties: block.properties(registry_id).map(|p| p.to_props()), } } } diff --git a/pumpkin-world/src/generation/feature/features/coral/mod.rs b/pumpkin-world/src/generation/feature/features/coral/mod.rs index af3cc4f5c..42d755860 100644 --- a/pumpkin-world/src/generation/feature/features/coral/mod.rs +++ b/pumpkin-world/src/generation/feature/features/coral/mod.rs @@ -62,7 +62,7 @@ impl CoralFeature { .to_props(); let facing = dir.to_facing(); // Set the right Axis - let props_vec: Vec<(&str, &str)> = original_props + let props = original_props .iter() .map(|(key, value)| { if key == "facing" { @@ -76,7 +76,7 @@ impl CoralFeature { &dir_pos.0, &get_state_by_state_id( wall_coral - .from_properties(props_vec) + .from_properties(props) .unwrap() .to_state_id(&wall_coral), ) diff --git a/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs b/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs index 34d573dfc..dedc0cf33 100644 --- a/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs +++ b/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs @@ -163,7 +163,7 @@ impl FancyTrunkPlacer { let original_props = &block.properties(trunk_provider.id).unwrap().to_props(); let axis = axis.to_value(); // Set the right Axis - let props_vec: Vec<(&str, &str)> = original_props + let props = original_props .iter() .map(|(key, value)| { if key == "axis" { @@ -173,10 +173,7 @@ impl FancyTrunkPlacer { } }) .collect(); - let state = block - .from_properties(props_vec) - .unwrap() - .to_state_id(&block); + let state = block.from_properties(props).unwrap().to_state_id(&block); if chunk.chunk_pos == block_pos_2.chunk_and_chunk_relative_position().0 { chunk.set_block_state( &block_pos_2.0, diff --git a/pumpkin/src/block/loot.rs b/pumpkin/src/block/loot.rs index 3e379fd7b..8e84b850c 100644 --- a/pumpkin/src/block/loot.rs +++ b/pumpkin/src/block/loot.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use pumpkin_data::{Block, BlockState, block_properties::get_block_by_state_id, item::Item}; use pumpkin_util::{ loot_table::{ @@ -169,13 +171,21 @@ impl LootConditionExt for LootCondition { properties, } => { if let Some(state) = ¶ms.block_state { - let props = - Block::properties(&get_block_by_state_id(state.id).unwrap(), state.id) - .map_or_else(Vec::new, |props| props.to_props()); + let block_actual_properties: HashMap = match Block::properties( + &get_block_by_state_id(state.id).unwrap(), + state.id, + ) { + Some(props_data) => props_data.to_props(), // Assuming to_props() returns HashMap + None => { + return properties.is_empty(); + } + }; - return properties - .iter() - .all(|(key, value)| props.iter().any(|(k, v)| k == key && v == value)); + return properties.iter().all(|&(expected_key, expected_value)| { + block_actual_properties.get(expected_key).is_some_and( + |actual_value_string| actual_value_string.as_str() == expected_value, + ) + }); } false } diff --git a/pumpkin/src/item/items/bucket.rs b/pumpkin/src/item/items/bucket.rs index a592a686c..f86617828 100644 --- a/pumpkin/src/item/items/bucket.rs +++ b/pumpkin/src/item/items/bucket.rs @@ -79,16 +79,18 @@ fn waterlogged_check(block: &Block, state: &BlockState) -> Option { fn set_waterlogged(block: &Block, state: &BlockState, waterlogged: bool) -> u16 { let original_props = &block.properties(state.id).unwrap().to_props(); - let mut props_vec: Vec<(&str, &str)> = Vec::with_capacity(original_props.len()); let waterlogged = waterlogged.to_string(); - for (key, value) in original_props { - if key == "waterlogged" { - props_vec.push((key.as_str(), &waterlogged)); - } else { - props_vec.push((key.as_str(), value.as_str())); - } - } - block.from_properties(props_vec).unwrap().to_state_id(block) + let props = original_props + .iter() + .map(|(key, value)| { + if key == "waterlogged" { + ("waterlogged", waterlogged.as_str()) + } else { + (key.as_str(), value.as_str()) + } + }) + .collect(); + block.from_properties(props).unwrap().to_state_id(block) } #[async_trait] diff --git a/pumpkin/src/item/items/ender_eye.rs b/pumpkin/src/item/items/ender_eye.rs index 789185604..58d9c6de1 100644 --- a/pumpkin/src/item/items/ender_eye.rs +++ b/pumpkin/src/item/items/ender_eye.rs @@ -34,16 +34,20 @@ impl PumpkinItem for EnderEyeItem { let world = player.world().await; let state_id = world.get_block_state_id(&location).await; - let original_props = &block.properties(state_id).unwrap().to_props(); - let mut props_vec: Vec<(&str, &str)> = Vec::with_capacity(original_props.len()); - for (key, value) in original_props { - if key == "eye" { - props_vec.push((key.as_str(), "true")); - } else { - props_vec.push((key.as_str(), value.as_str())); - } - } - let new_state_id = block.from_properties(props_vec).unwrap().to_state_id(block); + let original_props = block.properties(state_id).unwrap().to_props(); + + let props = original_props + .iter() + .map(|(key, value)| { + if key == "eye" { + (key.as_str(), "true") + } else { + (key.as_str(), value.as_str()) + } + }) + .collect(); + + let new_state_id = block.from_properties(props).unwrap().to_state_id(block); world .set_block_state(&location, new_state_id, BlockFlags::empty()) .await; diff --git a/pumpkin/src/item/items/ignite/ignition.rs b/pumpkin/src/item/items/ignite/ignition.rs index d7fcf3877..c10275059 100644 --- a/pumpkin/src/item/items/ignite/ignition.rs +++ b/pumpkin/src/item/items/ignite/ignition.rs @@ -67,18 +67,18 @@ async fn get_ignite_result(block: &Block, world: &Arc, location: &BlockPo None => return None, }; - let mut props_vec: Vec<(&str, &str)> = Vec::with_capacity(original_props.len()); - for (key, _value) in &original_props { - if key == "extinguished" { - // campfire - props_vec.push((key.as_str(), "true")); - } else if key == "lit" { - // candles - props_vec.push((key.as_str(), "true")); - } - } + let props = original_props + .iter() + .filter_map(|(key, _value)| { + match key.as_str() { + "extinguished" => Some(("extinguished", "true")), + "lit" => Some(("lit", "true")), + _ => None, // Discard other keys + } + }) + .collect(); - let new_state_id = block.from_properties(props_vec).unwrap().to_state_id(block); + let new_state_id = block.from_properties(props).unwrap().to_state_id(block); (new_state_id != state_id).then_some(new_state_id) } diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index ad4c24b3b..8aa1331f4 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -1185,22 +1185,6 @@ impl World { let position = chunk.read().await.position; - #[cfg(debug_assertions)] - if position == (0, 0).into() { - use pumpkin_protocol::client::play::CChunkData; - let binding = chunk.read().await; - let packet = CChunkData(&binding); - let mut test = Vec::new(); - packet.write_packet_data(&mut test).unwrap(); - let len = test.len(); - log::debug!( - "Chunk packet size: {}B {}KB {}MB", - len, - len / 1024, - len / (1024 * 1024) - ); - } - let (world, chunk) = if level.is_chunk_watched(&position) { (world.clone(), chunk) } else { @@ -1523,7 +1507,7 @@ impl World { for player in players.values() { player.send_system_message(&event.join_message).await; } - log::info!("{}", event.join_message.clone().to_pretty_console()); + log::info!("{}", event.join_message.to_pretty_console()); } }); Ok(()) @@ -1575,7 +1559,7 @@ impl World { for player in players.values() { player.send_system_message(&event.leave_message).await; } - log::info!("{}", event.leave_message.clone().to_pretty_console()); + log::info!("{}", event.leave_message.to_pretty_console()); } } }