diff --git a/pumpkin-codegen/src/block.rs b/pumpkin-codegen/src/block.rs index 4459f18e1..f00f723d8 100644 --- a/pumpkin-codegen/src/block.rs +++ b/pumpkin-codegen/src/block.rs @@ -67,6 +67,8 @@ fn property_group_name_from_derived_name(name: &str) -> String { enum PropertyType { /// The property is a simple boolean (`true`/`false`). Bool, + /// The property is an integer with an inclusive range. + Int { min: u8, max: u8 }, /// The property is an enum with a generated Rust type identified by `name`. Enum { name: String }, } @@ -211,6 +213,7 @@ impl ToTokens for BlockPropertyStruct { let key = Ident::new_raw(&entry.original_name, Span::call_site()); match &entry.property_type { PropertyType::Bool => quote! { pub #key: bool }, + PropertyType::Int { .. } => quote! { pub #key: u8 }, PropertyType::Enum { name } => { let value = Ident::new(name, Span::call_site()); quote! { pub #key: #value } @@ -229,6 +232,10 @@ impl ToTokens for BlockPropertyStruct { let field = Ident::new_raw(&entry.original_name, Span::call_site()); match &entry.property_type { PropertyType::Bool => quote! { (!self.#field as u16, 2) }, + PropertyType::Int { min, max } => { + let count = (max - min + 1) as u16; + quote! { ((self.#field - #min) as u16, #count) } + } PropertyType::Enum { name } => { let ty = Ident::new(name, Span::call_site()); quote! { (self.#field.to_index(), #ty::variant_count()) } @@ -251,6 +258,16 @@ impl ToTokens for BlockPropertyStruct { value == 0 } }, + PropertyType::Int { min, max } => { + let count = (max - min + 1) as u16; + quote! { + #field_name: { + let value = (index % #count) as u8; + index /= #count; + value + #min + } + } + } PropertyType::Enum { name } => { let enum_ident = Ident::new(name, Span::call_site()); quote! { @@ -272,6 +289,19 @@ impl ToTokens for BlockPropertyStruct { PropertyType::Bool => quote! { (#key_str, if self.#field { "true" } else { "false" }) }, + PropertyType::Int { min, max } => { + let mut arms = Vec::new(); + for i in *min..=*max { + let i_str = i.to_string(); + arms.push(quote! { #i => #i_str }); + } + quote! { + (#key_str, match self.#field { + #(#arms,)* + _ => unreachable!() + }) + } + } PropertyType::Enum { .. } => quote! { (#key_str, self.#field.to_value()) }, @@ -287,6 +317,21 @@ impl ToTokens for BlockPropertyStruct { block_props.#field_name = matches!(*value, "true") } }, + PropertyType::Int { min, max } => { + let mut arms = Vec::new(); + for i in *min..=*max { + let i_str = i.to_string(); + arms.push(quote! { #i_str => #i }); + } + quote! { + #key => { + block_props.#field_name = match *value { + #(#arms,)* + _ => #min, + } + } + } + } PropertyType::Enum { name } => { let enum_ident = Ident::new(name, Span::call_site()); quote! { @@ -596,6 +641,8 @@ pub struct Block { pub states: Vec, /// Experience points dropped when the block is mined, if any. pub experience: Option, + /// Calculated property descriptors for the block. + pub property_descriptors: Vec, } impl ToTokens for Block { @@ -638,6 +685,7 @@ impl ToTokens for Block { } else { quote! { None } }; + let property_descriptors = &self.property_descriptors; tokens.extend(quote! { Block { id: #id, @@ -650,6 +698,7 @@ impl ToTokens for Block { item_id: #item_id, default_state: &#default_state, states: &[#(#states),*], + properties: &[#(#property_descriptors),*], flammable: #flammable, loot_table: #loot_table, experience: #experience, @@ -800,15 +849,14 @@ pub fn build() -> TokenStream { let property = generated_property.to_property(); let renamed_property = property.enum_name.to_upper_camel_case(); - let property_type = if property.values.len() == 2 - && property.values.contains(&"true".to_string()) - && property.values.contains(&"false".to_string()) - { - PropertyType::Bool - } else { - PropertyType::Enum { - name: renamed_property.clone(), + let property_type = match &generated_property.property_type { + GeneratedPropertyType::Boolean => PropertyType::Bool, + GeneratedPropertyType::Int { min, max } => { + PropertyType::Int { min: *min, max: *max } } + GeneratedPropertyType::Enum { .. } => PropertyType::Enum { + name: renamed_property.clone(), + }, }; if let PropertyType::Enum { name } = &property_type { @@ -826,13 +874,35 @@ pub fn build() -> TokenStream { }); } + let mut multiplier = 1; + let mut property_descriptors = Vec::new(); + for hash in block.properties.iter().rev() { + let gen_prop = generated_prop_map.get(hash).unwrap(); + let variant_count = match &gen_prop.property_type { + GeneratedPropertyType::Boolean => 2, + GeneratedPropertyType::Int { min, max } => (max - min + 1) as u16, + GeneratedPropertyType::Enum { values } => values.len() as u16, + }; + property_descriptors.push(quote! { + PropertyDescriptor { + hash_key: #hash, + multiplier: #multiplier, + variant_count: #variant_count, + } + }); + multiplier *= variant_count; + } + let const_ident = format_ident!("{}", const_block_name_from_block_name(&block.name)); let name_str = &block.name; let id_lit = LitInt::new(&block.id.to_string(), Span::call_site()); let item_id = block.item_id; + let mut block_with_descriptors = block.clone(); + block_with_descriptors.property_descriptors = property_descriptors; + constants_list.push(quote! { - pub const #const_ident: Block = #block; + pub const #const_ident: Block = #block_with_descriptors; }); type_from_raw_id_array.push((block.id, quote! { &Self::#const_ident })); @@ -887,6 +957,15 @@ pub fn build() -> TokenStream { if val == 0 { "true" } else { "false" }.to_string(), ); } + PropertyType::Int { min, max } => { + let count = (*max - *min + 1) as u16; + let val = (temp_index % count) as u8; + temp_index /= count; + java_props_for_this_state.insert( + mapping.original_name.clone(), + (val + *min).to_string(), + ); + } PropertyType::Enum { name } => { let enum_info = property_enums.get(name).unwrap(); let count = enum_info.values.len() as u16; diff --git a/pumpkin-data/src/generated/block.rs b/pumpkin-data/src/generated/block.rs index 4209d3c75..b2a00ca52 100644 --- a/pumpkin-data/src/generated/block.rs +++ b/pumpkin-data/src/generated/block.rs @@ -502418,1061 +502418,6 @@ impl EnumVariants for HorizontalFacing { } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To1 { - L0, - L1, -} -impl EnumVariants for Integer0To1 { - fn variant_count() -> u16 { - 2u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To15 { - L0, - L1, - L2, - L3, - L4, - L5, - L6, - L7, - L8, - L9, - L10, - L11, - L12, - L13, - L14, - L15, -} -impl EnumVariants for Integer0To15 { - fn variant_count() -> u16 { - 16u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - Self::L6 => 6u16, - Self::L7 => 7u16, - Self::L8 => 8u16, - Self::L9 => 9u16, - Self::L10 => 10u16, - Self::L11 => 11u16, - Self::L12 => 12u16, - Self::L13 => 13u16, - Self::L14 => 14u16, - Self::L15 => 15u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - 6u16 => Self::L6, - 7u16 => Self::L7, - 8u16 => Self::L8, - 9u16 => Self::L9, - 10u16 => Self::L10, - 11u16 => Self::L11, - 12u16 => Self::L12, - 13u16 => Self::L13, - 14u16 => Self::L14, - 15u16 => Self::L15, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - Self::L8 => "8", - Self::L9 => "9", - Self::L10 => "10", - Self::L11 => "11", - Self::L12 => "12", - Self::L13 => "13", - Self::L14 => "14", - Self::L15 => "15", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - "8" => Self::L8, - "9" => Self::L9, - "10" => Self::L10, - "11" => Self::L11, - "12" => Self::L12, - "13" => Self::L13, - "14" => Self::L14, - "15" => Self::L15, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To2 { - L0, - L1, - L2, -} -impl EnumVariants for Integer0To2 { - fn variant_count() -> u16 { - 3u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To24 { - L0, - L1, - L2, - L3, - L4, - L5, - L6, - L7, - L8, - L9, - L10, - L11, - L12, - L13, - L14, - L15, - L16, - L17, - L18, - L19, - L20, - L21, - L22, - L23, - L24, -} -impl EnumVariants for Integer0To24 { - fn variant_count() -> u16 { - 25u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - Self::L6 => 6u16, - Self::L7 => 7u16, - Self::L8 => 8u16, - Self::L9 => 9u16, - Self::L10 => 10u16, - Self::L11 => 11u16, - Self::L12 => 12u16, - Self::L13 => 13u16, - Self::L14 => 14u16, - Self::L15 => 15u16, - Self::L16 => 16u16, - Self::L17 => 17u16, - Self::L18 => 18u16, - Self::L19 => 19u16, - Self::L20 => 20u16, - Self::L21 => 21u16, - Self::L22 => 22u16, - Self::L23 => 23u16, - Self::L24 => 24u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - 6u16 => Self::L6, - 7u16 => Self::L7, - 8u16 => Self::L8, - 9u16 => Self::L9, - 10u16 => Self::L10, - 11u16 => Self::L11, - 12u16 => Self::L12, - 13u16 => Self::L13, - 14u16 => Self::L14, - 15u16 => Self::L15, - 16u16 => Self::L16, - 17u16 => Self::L17, - 18u16 => Self::L18, - 19u16 => Self::L19, - 20u16 => Self::L20, - 21u16 => Self::L21, - 22u16 => Self::L22, - 23u16 => Self::L23, - 24u16 => Self::L24, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - Self::L8 => "8", - Self::L9 => "9", - Self::L10 => "10", - Self::L11 => "11", - Self::L12 => "12", - Self::L13 => "13", - Self::L14 => "14", - Self::L15 => "15", - Self::L16 => "16", - Self::L17 => "17", - Self::L18 => "18", - Self::L19 => "19", - Self::L20 => "20", - Self::L21 => "21", - Self::L22 => "22", - Self::L23 => "23", - Self::L24 => "24", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - "8" => Self::L8, - "9" => Self::L9, - "10" => Self::L10, - "11" => Self::L11, - "12" => Self::L12, - "13" => Self::L13, - "14" => Self::L14, - "15" => Self::L15, - "16" => Self::L16, - "17" => Self::L17, - "18" => Self::L18, - "19" => Self::L19, - "20" => Self::L20, - "21" => Self::L21, - "22" => Self::L22, - "23" => Self::L23, - "24" => Self::L24, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To25 { - L0, - L1, - L2, - L3, - L4, - L5, - L6, - L7, - L8, - L9, - L10, - L11, - L12, - L13, - L14, - L15, - L16, - L17, - L18, - L19, - L20, - L21, - L22, - L23, - L24, - L25, -} -impl EnumVariants for Integer0To25 { - fn variant_count() -> u16 { - 26u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - Self::L6 => 6u16, - Self::L7 => 7u16, - Self::L8 => 8u16, - Self::L9 => 9u16, - Self::L10 => 10u16, - Self::L11 => 11u16, - Self::L12 => 12u16, - Self::L13 => 13u16, - Self::L14 => 14u16, - Self::L15 => 15u16, - Self::L16 => 16u16, - Self::L17 => 17u16, - Self::L18 => 18u16, - Self::L19 => 19u16, - Self::L20 => 20u16, - Self::L21 => 21u16, - Self::L22 => 22u16, - Self::L23 => 23u16, - Self::L24 => 24u16, - Self::L25 => 25u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - 6u16 => Self::L6, - 7u16 => Self::L7, - 8u16 => Self::L8, - 9u16 => Self::L9, - 10u16 => Self::L10, - 11u16 => Self::L11, - 12u16 => Self::L12, - 13u16 => Self::L13, - 14u16 => Self::L14, - 15u16 => Self::L15, - 16u16 => Self::L16, - 17u16 => Self::L17, - 18u16 => Self::L18, - 19u16 => Self::L19, - 20u16 => Self::L20, - 21u16 => Self::L21, - 22u16 => Self::L22, - 23u16 => Self::L23, - 24u16 => Self::L24, - 25u16 => Self::L25, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - Self::L8 => "8", - Self::L9 => "9", - Self::L10 => "10", - Self::L11 => "11", - Self::L12 => "12", - Self::L13 => "13", - Self::L14 => "14", - Self::L15 => "15", - Self::L16 => "16", - Self::L17 => "17", - Self::L18 => "18", - Self::L19 => "19", - Self::L20 => "20", - Self::L21 => "21", - Self::L22 => "22", - Self::L23 => "23", - Self::L24 => "24", - Self::L25 => "25", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - "8" => Self::L8, - "9" => Self::L9, - "10" => Self::L10, - "11" => Self::L11, - "12" => Self::L12, - "13" => Self::L13, - "14" => Self::L14, - "15" => Self::L15, - "16" => Self::L16, - "17" => Self::L17, - "18" => Self::L18, - "19" => Self::L19, - "20" => Self::L20, - "21" => Self::L21, - "22" => Self::L22, - "23" => Self::L23, - "24" => Self::L24, - "25" => Self::L25, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To3 { - L0, - L1, - L2, - L3, -} -impl EnumVariants for Integer0To3 { - fn variant_count() -> u16 { - 4u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To4 { - L0, - L1, - L2, - L3, - L4, -} -impl EnumVariants for Integer0To4 { - fn variant_count() -> u16 { - 5u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To5 { - L0, - L1, - L2, - L3, - L4, - L5, -} -impl EnumVariants for Integer0To5 { - fn variant_count() -> u16 { - 6u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To6 { - L0, - L1, - L2, - L3, - L4, - L5, - L6, -} -impl EnumVariants for Integer0To6 { - fn variant_count() -> u16 { - 7u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - Self::L6 => 6u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - 6u16 => Self::L6, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To7 { - L0, - L1, - L2, - L3, - L4, - L5, - L6, - L7, -} -impl EnumVariants for Integer0To7 { - fn variant_count() -> u16 { - 8u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - Self::L6 => 6u16, - Self::L7 => 7u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - 6u16 => Self::L6, - 7u16 => Self::L7, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer0To8 { - L0, - L1, - L2, - L3, - L4, - L5, - L6, - L7, - L8, -} -impl EnumVariants for Integer0To8 { - fn variant_count() -> u16 { - 9u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L0 => 0u16, - Self::L1 => 1u16, - Self::L2 => 2u16, - Self::L3 => 3u16, - Self::L4 => 4u16, - Self::L5 => 5u16, - Self::L6 => 6u16, - Self::L7 => 7u16, - Self::L8 => 8u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L0, - 1u16 => Self::L1, - 2u16 => Self::L2, - 3u16 => Self::L3, - 4u16 => Self::L4, - 5u16 => Self::L5, - 6u16 => Self::L6, - 7u16 => Self::L7, - 8u16 => Self::L8, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L0 => "0", - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - Self::L8 => "8", - } - } - fn from_value(value: &str) -> Self { - match value { - "0" => Self::L0, - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - "8" => Self::L8, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer1To3 { - L1, - L2, - L3, -} -impl EnumVariants for Integer1To3 { - fn variant_count() -> u16 { - 3u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L1 => 0u16, - Self::L2 => 1u16, - Self::L3 => 2u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L1, - 1u16 => Self::L2, - 2u16 => Self::L3, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - } - } - fn from_value(value: &str) -> Self { - match value { - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer1To4 { - L1, - L2, - L3, - L4, -} -impl EnumVariants for Integer1To4 { - fn variant_count() -> u16 { - 4u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L1 => 0u16, - Self::L2 => 1u16, - Self::L3 => 2u16, - Self::L4 => 3u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L1, - 1u16 => Self::L2, - 2u16 => Self::L3, - 3u16 => Self::L4, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - } - } - fn from_value(value: &str) -> Self { - match value { - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer1To7 { - L1, - L2, - L3, - L4, - L5, - L6, - L7, -} -impl EnumVariants for Integer1To7 { - fn variant_count() -> u16 { - 7u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L1 => 0u16, - Self::L2 => 1u16, - Self::L3 => 2u16, - Self::L4 => 3u16, - Self::L5 => 4u16, - Self::L6 => 5u16, - Self::L7 => 6u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L1, - 1u16 => Self::L2, - 2u16 => Self::L3, - 3u16 => Self::L4, - 4u16 => Self::L5, - 5u16 => Self::L6, - 6u16 => Self::L7, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - } - } - fn from_value(value: &str) -> Self { - match value { - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Integer1To8 { - L1, - L2, - L3, - L4, - L5, - L6, - L7, - L8, -} -impl EnumVariants for Integer1To8 { - fn variant_count() -> u16 { - 8u16 - } - fn to_index(&self) -> u16 { - match self { - Self::L1 => 0u16, - Self::L2 => 1u16, - Self::L3 => 2u16, - Self::L4 => 3u16, - Self::L5 => 4u16, - Self::L6 => 5u16, - Self::L7 => 6u16, - Self::L8 => 7u16, - } - } - fn from_index(index: u16) -> Self { - match index { - 0u16 => Self::L1, - 1u16 => Self::L2, - 2u16 => Self::L3, - 3u16 => Self::L4, - 4u16 => Self::L5, - 5u16 => Self::L6, - 6u16 => Self::L7, - 7u16 => Self::L8, - _ => panic!("Invalid index: {index}"), - } - } - fn to_value(&self) -> &'static str { - match self { - Self::L1 => "1", - Self::L2 => "2", - Self::L3 => "3", - Self::L4 => "4", - Self::L5 => "5", - Self::L6 => "6", - Self::L7 => "7", - Self::L8 => "8", - } - } - fn from_value(value: &str) -> Self { - match value { - "1" => Self::L1, - "2" => Self::L2, - "3" => Self::L3, - "4" => Self::L4, - "5" => Self::L5, - "6" => Self::L6, - "7" => Self::L7, - "8" => Self::L8, - _ => panic!("Invalid value: {value}"), - } - } -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ModeComparator { Compare, Subtract, @@ -506206,7 +505151,7 @@ impl BlockProperties for VineLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct FireLikeProperties { - pub r#age: Integer0To15, + pub r#age: u8, pub r#east: bool, pub r#north: bool, pub r#south: bool, @@ -506221,7 +505166,7 @@ impl BlockProperties for FireLikeProperties { (!self.r#south as u16, 2), (!self.r#north as u16, 2), (!self.r#east as u16, 2), - (self.r#age.to_index(), Integer0To15::variant_count()), + (self.r#age as u16, 16u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -506258,9 +505203,9 @@ impl BlockProperties for FireLikeProperties { value == 0 }, r#age: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -506310,7 +505255,28 @@ impl BlockProperties for FireLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("age", self.r#age.to_value()), + ( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ("east", if self.r#east { "true" } else { "false" }), ("north", if self.r#north { "true" } else { "false" }), ("south", if self.r#south { "true" } else { "false" }), @@ -506330,7 +505296,27 @@ impl BlockProperties for FireLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "age" => block_props.r#age = Integer0To15::from_value(value), + "age" => { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "east" => block_props.r#east = matches!(*value, "true"), "north" => block_props.r#north = matches!(*value, "true"), "south" => block_props.r#south = matches!(*value, "true"), @@ -506901,7 +505887,7 @@ impl BlockProperties for CampfireLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct CandleLikeProperties { - pub r#candles: Integer1To4, + pub r#candles: u8, pub r#lit: bool, pub r#waterlogged: bool, } @@ -506910,7 +505896,7 @@ impl BlockProperties for CandleLikeProperties { let (index, _) = [ (!self.r#waterlogged as u16, 2), (!self.r#lit as u16, 2), - (self.r#candles.to_index(), Integer1To4::variant_count()), + ((self.r#candles - 1u8) as u16, 4u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -506932,9 +505918,9 @@ impl BlockProperties for CandleLikeProperties { value == 0 }, r#candles: { - let value = index % Integer1To4::variant_count(); - index /= Integer1To4::variant_count(); - Integer1To4::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value + 1u8 }, } } @@ -507003,7 +505989,16 @@ impl BlockProperties for CandleLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("candles", self.r#candles.to_value()), + ( + "candles", + match self.r#candles { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ("lit", if self.r#lit { "true" } else { "false" }), ( "waterlogged", @@ -507042,7 +506037,15 @@ impl BlockProperties for CandleLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "candles" => block_props.r#candles = Integer1To4::from_value(value), + "candles" => { + block_props.r#candles = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 1u8, + } + } "lit" => block_props.r#lit = matches!(*value, "true"), "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} @@ -508406,7 +507409,7 @@ impl BlockProperties for ComparatorLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct CalibratedSculkSensorLikeProperties { pub r#facing: HorizontalFacing, - pub r#power: Integer0To15, + pub r#power: u8, pub r#sculk_sensor_phase: SculkSensorPhase, pub r#waterlogged: bool, } @@ -508418,7 +507421,7 @@ impl BlockProperties for CalibratedSculkSensorLikeProperties { self.r#sculk_sensor_phase.to_index(), SculkSensorPhase::variant_count(), ), - (self.r#power.to_index(), Integer0To15::variant_count()), + (self.r#power as u16, 16u16), (self.r#facing.to_index(), HorizontalFacing::variant_count()), ] .iter() @@ -508441,9 +507444,9 @@ impl BlockProperties for CalibratedSculkSensorLikeProperties { SculkSensorPhase::from_index(value) }, r#power: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, r#facing: { let value = index % HorizontalFacing::variant_count(); @@ -508499,7 +507502,28 @@ impl BlockProperties for CalibratedSculkSensorLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("facing", self.r#facing.to_value()), - ("power", self.r#power.to_value()), + ( + "power", + match self.r#power { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ("sculk_sensor_phase", self.r#sculk_sensor_phase.to_value()), ( "waterlogged", @@ -508520,7 +507544,27 @@ impl BlockProperties for CalibratedSculkSensorLikeProperties { for (key, value) in props { match *key { "facing" => block_props.r#facing = HorizontalFacing::from_value(value), - "power" => block_props.r#power = Integer0To15::from_value(value), + "power" => { + block_props.r#power = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "sculk_sensor_phase" => { block_props.r#sculk_sensor_phase = SculkSensorPhase::from_value(value) } @@ -508533,7 +507577,7 @@ impl BlockProperties for CalibratedSculkSensorLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SculkSensorLikeProperties { - pub r#power: Integer0To15, + pub r#power: u8, pub r#sculk_sensor_phase: SculkSensorPhase, pub r#waterlogged: bool, } @@ -508545,7 +507589,7 @@ impl BlockProperties for SculkSensorLikeProperties { self.r#sculk_sensor_phase.to_index(), SculkSensorPhase::variant_count(), ), - (self.r#power.to_index(), Integer0To15::variant_count()), + (self.r#power as u16, 16u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -508567,9 +507611,9 @@ impl BlockProperties for SculkSensorLikeProperties { SculkSensorPhase::from_index(value) }, r#power: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -508619,7 +507663,28 @@ impl BlockProperties for SculkSensorLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("power", self.r#power.to_value()), + ( + "power", + match self.r#power { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ("sculk_sensor_phase", self.r#sculk_sensor_phase.to_value()), ( "waterlogged", @@ -508639,7 +507704,27 @@ impl BlockProperties for SculkSensorLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "power" => block_props.r#power = Integer0To15::from_value(value), + "power" => { + block_props.r#power = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "sculk_sensor_phase" => { block_props.r#sculk_sensor_phase = SculkSensorPhase::from_value(value) } @@ -509132,11 +508217,11 @@ impl BlockProperties for CrafterLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RespawnAnchorLikeProperties { - pub r#charges: Integer0To4, + pub r#charges: u8, } impl BlockProperties for RespawnAnchorLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#charges.to_index(), Integer0To4::variant_count())] + let (index, _) = [(self.r#charges as u16, 5u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -509147,9 +508232,9 @@ impl BlockProperties for RespawnAnchorLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#charges: { - let value = index % Integer0To4::variant_count(); - index /= Integer0To4::variant_count(); - Integer0To4::from_index(value) + let value = (index % 5u16) as u8; + index /= 5u16; + value }, } } @@ -509198,7 +508283,17 @@ impl BlockProperties for RespawnAnchorLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("charges", self.r#charges.to_value())] + vec![( + "charges", + match self.r#charges { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -509211,7 +508306,16 @@ impl BlockProperties for RespawnAnchorLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "charges" { block_props.r#charges = Integer0To4::from_value(value) } + if *key == "charges" { + block_props.r#charges = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 0u8, + } + } } block_props } @@ -509571,7 +508675,7 @@ impl BlockProperties for PointedDripstoneLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct OakLeavesLikeProperties { - pub r#distance: Integer1To7, + pub r#distance: u8, pub r#persistent: bool, pub r#waterlogged: bool, } @@ -509580,7 +508684,7 @@ impl BlockProperties for OakLeavesLikeProperties { let (index, _) = [ (!self.r#waterlogged as u16, 2), (!self.r#persistent as u16, 2), - (self.r#distance.to_index(), Integer1To7::variant_count()), + ((self.r#distance - 1u8) as u16, 7u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -509602,9 +508706,9 @@ impl BlockProperties for OakLeavesLikeProperties { value == 0 }, r#distance: { - let value = index % Integer1To7::variant_count(); - index /= Integer1To7::variant_count(); - Integer1To7::from_index(value) + let value = (index % 7u16) as u8; + index /= 7u16; + value + 1u8 }, } } @@ -509657,7 +508761,19 @@ impl BlockProperties for OakLeavesLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("distance", self.r#distance.to_value()), + ( + "distance", + match self.r#distance { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + _ => unreachable!(), + }, + ), ( "persistent", if self.r#persistent { "true" } else { "false" }, @@ -509683,7 +508799,18 @@ impl BlockProperties for OakLeavesLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "distance" => block_props.r#distance = Integer1To7::from_value(value), + "distance" => { + block_props.r#distance = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + _ => 1u8, + } + } "persistent" => block_props.r#persistent = matches!(*value, "true"), "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} @@ -509695,14 +508822,14 @@ impl BlockProperties for OakLeavesLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct OakHangingSignLikeProperties { pub r#attached: bool, - pub r#rotation: Integer0To15, + pub r#rotation: u8, pub r#waterlogged: bool, } impl BlockProperties for OakHangingSignLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#rotation.to_index(), Integer0To15::variant_count()), + (self.r#rotation as u16, 16u16), (!self.r#attached as u16, 2), ] .iter() @@ -509720,9 +508847,9 @@ impl BlockProperties for OakHangingSignLikeProperties { value == 0 }, r#rotation: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, r#attached: { let value = index % 2; @@ -509792,7 +508919,28 @@ impl BlockProperties for OakHangingSignLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("attached", if self.r#attached { "true" } else { "false" }), - ("rotation", self.r#rotation.to_value()), + ( + "rotation", + match self.r#rotation { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -509826,7 +508974,27 @@ impl BlockProperties for OakHangingSignLikeProperties { for (key, value) in props { match *key { "attached" => block_props.r#attached = matches!(*value, "true"), - "rotation" => block_props.r#rotation = Integer0To15::from_value(value), + "rotation" => { + block_props.r#rotation = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -510034,12 +509202,12 @@ impl BlockProperties for TestBlockLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct DaylightDetectorLikeProperties { pub r#inverted: bool, - pub r#power: Integer0To15, + pub r#power: u8, } impl BlockProperties for DaylightDetectorLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - (self.r#power.to_index(), Integer0To15::variant_count()), + (self.r#power as u16, 16u16), (!self.r#inverted as u16, 2), ] .iter() @@ -510052,9 +509220,9 @@ impl BlockProperties for DaylightDetectorLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#power: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, r#inverted: { let value = index % 2; @@ -510110,7 +509278,28 @@ impl BlockProperties for DaylightDetectorLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("inverted", if self.r#inverted { "true" } else { "false" }), - ("power", self.r#power.to_value()), + ( + "power", + match self.r#power { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -510126,7 +509315,27 @@ impl BlockProperties for DaylightDetectorLikeProperties { for (key, value) in props { match *key { "inverted" => block_props.r#inverted = matches!(*value, "true"), - "power" => block_props.r#power = Integer0To15::from_value(value), + "power" => { + block_props.r#power = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } _ => {} } } @@ -510135,11 +509344,11 @@ impl BlockProperties for DaylightDetectorLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SnowLikeProperties { - pub r#layers: Integer1To8, + pub r#layers: u8, } impl BlockProperties for SnowLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#layers.to_index(), Integer1To8::variant_count())] + let (index, _) = [((self.r#layers - 1u8) as u16, 8u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -510150,9 +509359,9 @@ impl BlockProperties for SnowLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#layers: { - let value = index % Integer1To8::variant_count(); - index /= Integer1To8::variant_count(); - Integer1To8::from_index(value) + let value = (index % 8u16) as u8; + index /= 8u16; + value + 1u8 }, } } @@ -510201,7 +509410,20 @@ impl BlockProperties for SnowLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("layers", self.r#layers.to_value())] + vec![( + "layers", + match self.r#layers { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -510214,7 +509436,19 @@ impl BlockProperties for SnowLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "layers" { block_props.r#layers = Integer1To8::from_value(value) } + if *key == "layers" { + block_props.r#layers = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + _ => 1u8, + } + } } block_props } @@ -510329,18 +509563,18 @@ impl BlockProperties for LanternLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct MangrovePropaguleLikeProperties { - pub r#age: Integer0To4, + pub r#age: u8, pub r#hanging: bool, - pub r#stage: Integer0To1, + pub r#stage: u8, pub r#waterlogged: bool, } impl BlockProperties for MangrovePropaguleLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#stage.to_index(), Integer0To1::variant_count()), + (self.r#stage as u16, 2u16), (!self.r#hanging as u16, 2), - (self.r#age.to_index(), Integer0To4::variant_count()), + (self.r#age as u16, 5u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -510357,9 +509591,9 @@ impl BlockProperties for MangrovePropaguleLikeProperties { value == 0 }, r#stage: { - let value = index % Integer0To1::variant_count(); - index /= Integer0To1::variant_count(); - Integer0To1::from_index(value) + let value = (index % 2u16) as u8; + index /= 2u16; + value }, r#hanging: { let value = index % 2; @@ -510367,9 +509601,9 @@ impl BlockProperties for MangrovePropaguleLikeProperties { value == 0 }, r#age: { - let value = index % Integer0To4::variant_count(); - index /= Integer0To4::variant_count(); - Integer0To4::from_index(value) + let value = (index % 5u16) as u8; + index /= 5u16; + value }, } } @@ -510419,9 +509653,26 @@ impl BlockProperties for MangrovePropaguleLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("age", self.r#age.to_value()), + ( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ("hanging", if self.r#hanging { "true" } else { "false" }), - ("stage", self.r#stage.to_value()), + ( + "stage", + match self.r#stage { + 0u8 => "0", + 1u8 => "1", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -510440,9 +509691,24 @@ impl BlockProperties for MangrovePropaguleLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "age" => block_props.r#age = Integer0To4::from_value(value), + "age" => { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 0u8, + } + } "hanging" => block_props.r#hanging = matches!(*value, "true"), - "stage" => block_props.r#stage = Integer0To1::from_value(value), + "stage" => { + block_props.r#stage = match *value { + "0" => 0u8, + "1" => 1u8, + _ => 0u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -510713,11 +509979,11 @@ impl BlockProperties for BellLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct FarmlandLikeProperties { - pub r#moisture: Integer0To7, + pub r#moisture: u8, } impl BlockProperties for FarmlandLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#moisture.to_index(), Integer0To7::variant_count())] + let (index, _) = [(self.r#moisture as u16, 8u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -510728,9 +509994,9 @@ impl BlockProperties for FarmlandLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#moisture: { - let value = index % Integer0To7::variant_count(); - index /= Integer0To7::variant_count(); - Integer0To7::from_index(value) + let value = (index % 8u16) as u8; + index /= 8u16; + value }, } } @@ -510779,7 +510045,20 @@ impl BlockProperties for FarmlandLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("moisture", self.r#moisture.to_value())] + vec![( + "moisture", + match self.r#moisture { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -510792,18 +510071,30 @@ impl BlockProperties for FarmlandLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "moisture" { block_props.r#moisture = Integer0To7::from_value(value) } + if *key == "moisture" { + block_props.r#moisture = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SuspiciousSandLikeProperties { - pub r#dusted: Integer0To3, + pub r#dusted: u8, } impl BlockProperties for SuspiciousSandLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#dusted.to_index(), Integer0To3::variant_count())] + let (index, _) = [(self.r#dusted as u16, 4u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -510814,9 +510105,9 @@ impl BlockProperties for SuspiciousSandLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#dusted: { - let value = index % Integer0To3::variant_count(); - index /= Integer0To3::variant_count(); - Integer0To3::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value }, } } @@ -510865,7 +510156,16 @@ impl BlockProperties for SuspiciousSandLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("dusted", self.r#dusted.to_value())] + vec![( + "dusted", + match self.r#dusted { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -510878,7 +510178,15 @@ impl BlockProperties for SuspiciousSandLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "dusted" { block_props.r#dusted = Integer0To3::from_value(value) } + if *key == "dusted" { + block_props.r#dusted = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + _ => 0u8, + } + } } block_props } @@ -512451,14 +511759,14 @@ impl BlockProperties for CopperGolemStatueLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct DriedGhastLikeProperties { pub r#facing: HorizontalFacing, - pub r#hydration: Integer0To3, + pub r#hydration: u8, pub r#waterlogged: bool, } impl BlockProperties for DriedGhastLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#hydration.to_index(), Integer0To3::variant_count()), + (self.r#hydration as u16, 4u16), (self.r#facing.to_index(), HorizontalFacing::variant_count()), ] .iter() @@ -512476,9 +511784,9 @@ impl BlockProperties for DriedGhastLikeProperties { value == 0 }, r#hydration: { - let value = index % Integer0To3::variant_count(); - index /= Integer0To3::variant_count(); - Integer0To3::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value }, r#facing: { let value = index % HorizontalFacing::variant_count(); @@ -512534,7 +511842,16 @@ impl BlockProperties for DriedGhastLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("facing", self.r#facing.to_value()), - ("hydration", self.r#hydration.to_value()), + ( + "hydration", + match self.r#hydration { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -512554,7 +511871,15 @@ impl BlockProperties for DriedGhastLikeProperties { for (key, value) in props { match *key { "facing" => block_props.r#facing = HorizontalFacing::from_value(value), - "hydration" => block_props.r#hydration = Integer0To3::from_value(value), + "hydration" => { + block_props.r#hydration = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + _ => 0u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -512678,14 +512003,14 @@ impl BlockProperties for SmallDripleafLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SeaPickleLikeProperties { - pub r#pickles: Integer1To4, + pub r#pickles: u8, pub r#waterlogged: bool, } impl BlockProperties for SeaPickleLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#pickles.to_index(), Integer1To4::variant_count()), + ((self.r#pickles - 1u8) as u16, 4u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -512702,9 +512027,9 @@ impl BlockProperties for SeaPickleLikeProperties { value == 0 }, r#pickles: { - let value = index % Integer1To4::variant_count(); - index /= Integer1To4::variant_count(); - Integer1To4::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value + 1u8 }, } } @@ -512754,7 +512079,16 @@ impl BlockProperties for SeaPickleLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("pickles", self.r#pickles.to_value()), + ( + "pickles", + match self.r#pickles { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -512773,7 +512107,15 @@ impl BlockProperties for SeaPickleLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "pickles" => block_props.r#pickles = Integer1To4::from_value(value), + "pickles" => { + block_props.r#pickles = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 1u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -512784,14 +512126,14 @@ impl BlockProperties for SeaPickleLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ScaffoldingLikeProperties { pub r#bottom: bool, - pub r#distance: Integer0To7, + pub r#distance: u8, pub r#waterlogged: bool, } impl BlockProperties for ScaffoldingLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#distance.to_index(), Integer0To7::variant_count()), + (self.r#distance as u16, 8u16), (!self.r#bottom as u16, 2), ] .iter() @@ -512809,9 +512151,9 @@ impl BlockProperties for ScaffoldingLikeProperties { value == 0 }, r#distance: { - let value = index % Integer0To7::variant_count(); - index /= Integer0To7::variant_count(); - Integer0To7::from_index(value) + let value = (index % 8u16) as u8; + index /= 8u16; + value }, r#bottom: { let value = index % 2; @@ -512867,7 +512209,20 @@ impl BlockProperties for ScaffoldingLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("bottom", if self.r#bottom { "true" } else { "false" }), - ("distance", self.r#distance.to_value()), + ( + "distance", + match self.r#distance { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -512887,7 +512242,19 @@ impl BlockProperties for ScaffoldingLikeProperties { for (key, value) in props { match *key { "bottom" => block_props.r#bottom = matches!(*value, "true"), - "distance" => block_props.r#distance = Integer0To7::from_value(value), + "distance" => { + block_props.r#distance = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + _ => 0u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -513008,14 +512375,14 @@ impl BlockProperties for IronChainLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct OakSignLikeProperties { - pub r#rotation: Integer0To15, + pub r#rotation: u8, pub r#waterlogged: bool, } impl BlockProperties for OakSignLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#rotation.to_index(), Integer0To15::variant_count()), + (self.r#rotation as u16, 16u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -513032,9 +512399,9 @@ impl BlockProperties for OakSignLikeProperties { value == 0 }, r#rotation: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -513098,7 +512465,28 @@ impl BlockProperties for OakSignLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("rotation", self.r#rotation.to_value()), + ( + "rotation", + match self.r#rotation { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -513131,7 +512519,27 @@ impl BlockProperties for OakSignLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "rotation" => block_props.r#rotation = Integer0To15::from_value(value), + "rotation" => { + block_props.r#rotation = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -513141,14 +512549,14 @@ impl BlockProperties for OakSignLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct LightLikeProperties { - pub r#level: Integer0To15, + pub r#level: u8, pub r#waterlogged: bool, } impl BlockProperties for LightLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#waterlogged as u16, 2), - (self.r#level.to_index(), Integer0To15::variant_count()), + (self.r#level as u16, 16u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -513165,9 +512573,9 @@ impl BlockProperties for LightLikeProperties { value == 0 }, r#level: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -513217,7 +512625,28 @@ impl BlockProperties for LightLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("level", self.r#level.to_value()), + ( + "level", + match self.r#level { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ( "waterlogged", if self.r#waterlogged { "true" } else { "false" }, @@ -513236,7 +512665,27 @@ impl BlockProperties for LightLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "level" => block_props.r#level = Integer0To15::from_value(value), + "level" => { + block_props.r#level = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "waterlogged" => block_props.r#waterlogged = matches!(*value, "true"), _ => {} } @@ -513375,11 +512824,11 @@ impl BlockProperties for PaleMossCarpetLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ComposterLikeProperties { - pub r#level: Integer0To8, + pub r#level: u8, } impl BlockProperties for ComposterLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#level.to_index(), Integer0To8::variant_count())] + let (index, _) = [(self.r#level as u16, 9u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -513390,9 +512839,9 @@ impl BlockProperties for ComposterLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#level: { - let value = index % Integer0To8::variant_count(); - index /= Integer0To8::variant_count(); - Integer0To8::from_index(value) + let value = (index % 9u16) as u8; + index /= 9u16; + value }, } } @@ -513441,7 +512890,21 @@ impl BlockProperties for ComposterLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("level", self.r#level.to_value())] + vec![( + "level", + match self.r#level { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -513454,7 +512917,20 @@ impl BlockProperties for ComposterLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "level" { block_props.r#level = Integer0To8::from_value(value) } + if *key == "level" { + block_props.r#level = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + _ => 0u8, + } + } } block_props } @@ -513580,16 +513056,16 @@ impl BlockProperties for CreakingHeartLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct BambooLikeProperties { - pub r#age: Integer0To1, + pub r#age: u8, pub r#leaves: BambooLeaves, - pub r#stage: Integer0To1, + pub r#stage: u8, } impl BlockProperties for BambooLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - (self.r#stage.to_index(), Integer0To1::variant_count()), + (self.r#stage as u16, 2u16), (self.r#leaves.to_index(), BambooLeaves::variant_count()), - (self.r#age.to_index(), Integer0To1::variant_count()), + (self.r#age as u16, 2u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -513601,9 +513077,9 @@ impl BlockProperties for BambooLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#stage: { - let value = index % Integer0To1::variant_count(); - index /= Integer0To1::variant_count(); - Integer0To1::from_index(value) + let value = (index % 2u16) as u8; + index /= 2u16; + value }, r#leaves: { let value = index % BambooLeaves::variant_count(); @@ -513611,9 +513087,9 @@ impl BlockProperties for BambooLikeProperties { BambooLeaves::from_index(value) }, r#age: { - let value = index % Integer0To1::variant_count(); - index /= Integer0To1::variant_count(); - Integer0To1::from_index(value) + let value = (index % 2u16) as u8; + index /= 2u16; + value }, } } @@ -513663,9 +513139,23 @@ impl BlockProperties for BambooLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("age", self.r#age.to_value()), + ( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + _ => unreachable!(), + }, + ), ("leaves", self.r#leaves.to_value()), - ("stage", self.r#stage.to_value()), + ( + "stage", + match self.r#stage { + 0u8 => "0", + 1u8 => "1", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -513680,9 +513170,21 @@ impl BlockProperties for BambooLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "age" => block_props.r#age = Integer0To1::from_value(value), + "age" => { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + _ => 0u8, + } + } "leaves" => block_props.r#leaves = BambooLeaves::from_value(value), - "stage" => block_props.r#stage = Integer0To1::from_value(value), + "stage" => { + block_props.r#stage = match *value { + "0" => 0u8, + "1" => 1u8, + _ => 0u8, + } + } _ => {} } } @@ -513691,7 +513193,7 @@ impl BlockProperties for BambooLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RepeaterLikeProperties { - pub r#delay: Integer1To4, + pub r#delay: u8, pub r#facing: HorizontalFacing, pub r#locked: bool, pub r#powered: bool, @@ -513702,7 +513204,7 @@ impl BlockProperties for RepeaterLikeProperties { (!self.r#powered as u16, 2), (!self.r#locked as u16, 2), (self.r#facing.to_index(), HorizontalFacing::variant_count()), - (self.r#delay.to_index(), Integer1To4::variant_count()), + ((self.r#delay - 1u8) as u16, 4u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -513729,9 +513231,9 @@ impl BlockProperties for RepeaterLikeProperties { HorizontalFacing::from_index(value) }, r#delay: { - let value = index % Integer1To4::variant_count(); - index /= Integer1To4::variant_count(); - Integer1To4::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value + 1u8 }, } } @@ -513781,7 +513283,16 @@ impl BlockProperties for RepeaterLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("delay", self.r#delay.to_value()), + ( + "delay", + match self.r#delay { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ("facing", self.r#facing.to_value()), ("locked", if self.r#locked { "true" } else { "false" }), ("powered", if self.r#powered { "true" } else { "false" }), @@ -513799,7 +513310,15 @@ impl BlockProperties for RepeaterLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "delay" => block_props.r#delay = Integer1To4::from_value(value), + "delay" => { + block_props.r#delay = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 1u8, + } + } "facing" => block_props.r#facing = HorizontalFacing::from_value(value), "locked" => block_props.r#locked = matches!(*value, "true"), "powered" => block_props.r#powered = matches!(*value, "true"), @@ -513990,12 +513509,12 @@ impl BlockProperties for WallTorchLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct BeeNestLikeProperties { pub r#facing: HorizontalFacing, - pub r#honey_level: Integer0To5, + pub r#honey_level: u8, } impl BlockProperties for BeeNestLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - (self.r#honey_level.to_index(), Integer0To5::variant_count()), + (self.r#honey_level as u16, 6u16), (self.r#facing.to_index(), HorizontalFacing::variant_count()), ] .iter() @@ -514008,9 +513527,9 @@ impl BlockProperties for BeeNestLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#honey_level: { - let value = index % Integer0To5::variant_count(); - index /= Integer0To5::variant_count(); - Integer0To5::from_index(value) + let value = (index % 6u16) as u8; + index /= 6u16; + value }, r#facing: { let value = index % HorizontalFacing::variant_count(); @@ -514066,7 +513585,18 @@ impl BlockProperties for BeeNestLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("facing", self.r#facing.to_value()), - ("honey_level", self.r#honey_level.to_value()), + ( + "honey_level", + match self.r#honey_level { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -514082,7 +513612,17 @@ impl BlockProperties for BeeNestLikeProperties { for (key, value) in props { match *key { "facing" => block_props.r#facing = HorizontalFacing::from_value(value), - "honey_level" => block_props.r#honey_level = Integer0To5::from_value(value), + "honey_level" => { + block_props.r#honey_level = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + _ => 0u8, + } + } _ => {} } } @@ -514528,15 +514068,12 @@ impl BlockProperties for LeverLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct PinkPetalsLikeProperties { pub r#facing: HorizontalFacing, - pub r#flower_amount: Integer1To4, + pub r#flower_amount: u8, } impl BlockProperties for PinkPetalsLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - ( - self.r#flower_amount.to_index(), - Integer1To4::variant_count(), - ), + ((self.r#flower_amount - 1u8) as u16, 4u16), (self.r#facing.to_index(), HorizontalFacing::variant_count()), ] .iter() @@ -514549,9 +514086,9 @@ impl BlockProperties for PinkPetalsLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#flower_amount: { - let value = index % Integer1To4::variant_count(); - index /= Integer1To4::variant_count(); - Integer1To4::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value + 1u8 }, r#facing: { let value = index % HorizontalFacing::variant_count(); @@ -514607,7 +514144,16 @@ impl BlockProperties for PinkPetalsLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("facing", self.r#facing.to_value()), - ("flower_amount", self.r#flower_amount.to_value()), + ( + "flower_amount", + match self.r#flower_amount { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -514623,7 +514169,15 @@ impl BlockProperties for PinkPetalsLikeProperties { for (key, value) in props { match *key { "facing" => block_props.r#facing = HorizontalFacing::from_value(value), - "flower_amount" => block_props.r#flower_amount = Integer1To4::from_value(value), + "flower_amount" => { + block_props.r#flower_amount = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 1u8, + } + } _ => {} } } @@ -514744,15 +514298,12 @@ impl BlockProperties for VaultLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct LeafLitterLikeProperties { pub r#facing: HorizontalFacing, - pub r#segment_amount: Integer1To4, + pub r#segment_amount: u8, } impl BlockProperties for LeafLitterLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - ( - self.r#segment_amount.to_index(), - Integer1To4::variant_count(), - ), + ((self.r#segment_amount - 1u8) as u16, 4u16), (self.r#facing.to_index(), HorizontalFacing::variant_count()), ] .iter() @@ -514765,9 +514316,9 @@ impl BlockProperties for LeafLitterLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#segment_amount: { - let value = index % Integer1To4::variant_count(); - index /= Integer1To4::variant_count(); - Integer1To4::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value + 1u8 }, r#facing: { let value = index % HorizontalFacing::variant_count(); @@ -514823,7 +514374,16 @@ impl BlockProperties for LeafLitterLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("facing", self.r#facing.to_value()), - ("segment_amount", self.r#segment_amount.to_value()), + ( + "segment_amount", + match self.r#segment_amount { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -514839,7 +514399,15 @@ impl BlockProperties for LeafLitterLikeProperties { for (key, value) in props { match *key { "facing" => block_props.r#facing = HorizontalFacing::from_value(value), - "segment_amount" => block_props.r#segment_amount = Integer1To4::from_value(value), + "segment_amount" => { + block_props.r#segment_amount = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 1u8, + } + } _ => {} } } @@ -514848,14 +514416,14 @@ impl BlockProperties for LeafLitterLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct CocoaLikeProperties { - pub r#age: Integer0To2, + pub r#age: u8, pub r#facing: HorizontalFacing, } impl BlockProperties for CocoaLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (self.r#facing.to_index(), HorizontalFacing::variant_count()), - (self.r#age.to_index(), Integer0To2::variant_count()), + (self.r#age as u16, 3u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -514872,9 +514440,9 @@ impl BlockProperties for CocoaLikeProperties { HorizontalFacing::from_index(value) }, r#age: { - let value = index % Integer0To2::variant_count(); - index /= Integer0To2::variant_count(); - Integer0To2::from_index(value) + let value = (index % 3u16) as u8; + index /= 3u16; + value }, } } @@ -514924,7 +514492,15 @@ impl BlockProperties for CocoaLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("age", self.r#age.to_value()), + ( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + _ => unreachable!(), + }, + ), ("facing", self.r#facing.to_value()), ] } @@ -514940,7 +514516,14 @@ impl BlockProperties for CocoaLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "age" => block_props.r#age = Integer0To2::from_value(value), + "age" => { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + _ => 0u8, + } + } "facing" => block_props.r#facing = HorizontalFacing::from_value(value), _ => {} } @@ -515058,11 +514641,11 @@ impl BlockProperties for SkeletonWallSkullLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SnifferEggLikeProperties { - pub r#hatch: Integer0To2, + pub r#hatch: u8, } impl BlockProperties for SnifferEggLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#hatch.to_index(), Integer0To2::variant_count())] + let (index, _) = [(self.r#hatch as u16, 3u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -515073,9 +514656,9 @@ impl BlockProperties for SnifferEggLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#hatch: { - let value = index % Integer0To2::variant_count(); - index /= Integer0To2::variant_count(); - Integer0To2::from_index(value) + let value = (index % 3u16) as u8; + index /= 3u16; + value }, } } @@ -515124,7 +514707,15 @@ impl BlockProperties for SnifferEggLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("hatch", self.r#hatch.to_value())] + vec![( + "hatch", + match self.r#hatch { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -515137,21 +514728,28 @@ impl BlockProperties for SnifferEggLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "hatch" { block_props.r#hatch = Integer0To2::from_value(value) } + if *key == "hatch" { + block_props.r#hatch = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct TurtleEggLikeProperties { - pub r#eggs: Integer1To4, - pub r#hatch: Integer0To2, + pub r#eggs: u8, + pub r#hatch: u8, } impl BlockProperties for TurtleEggLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - (self.r#hatch.to_index(), Integer0To2::variant_count()), - (self.r#eggs.to_index(), Integer1To4::variant_count()), + (self.r#hatch as u16, 3u16), + ((self.r#eggs - 1u8) as u16, 4u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -515163,14 +514761,14 @@ impl BlockProperties for TurtleEggLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#hatch: { - let value = index % Integer0To2::variant_count(); - index /= Integer0To2::variant_count(); - Integer0To2::from_index(value) + let value = (index % 3u16) as u8; + index /= 3u16; + value }, r#eggs: { - let value = index % Integer1To4::variant_count(); - index /= Integer1To4::variant_count(); - Integer1To4::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value + 1u8 }, } } @@ -515220,8 +514818,25 @@ impl BlockProperties for TurtleEggLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("eggs", self.r#eggs.to_value()), - ("hatch", self.r#hatch.to_value()), + ( + "eggs", + match self.r#eggs { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), + ( + "hatch", + match self.r#hatch { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -515236,8 +514851,23 @@ impl BlockProperties for TurtleEggLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "eggs" => block_props.r#eggs = Integer1To4::from_value(value), - "hatch" => block_props.r#hatch = Integer0To2::from_value(value), + "eggs" => { + block_props.r#eggs = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 1u8, + } + } + "hatch" => { + block_props.r#hatch = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + _ => 0u8, + } + } _ => {} } } @@ -515246,11 +514876,11 @@ impl BlockProperties for TurtleEggLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct WaterCauldronLikeProperties { - pub r#level: Integer1To3, + pub r#level: u8, } impl BlockProperties for WaterCauldronLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#level.to_index(), Integer1To3::variant_count())] + let (index, _) = [((self.r#level - 1u8) as u16, 3u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -515261,9 +514891,9 @@ impl BlockProperties for WaterCauldronLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#level: { - let value = index % Integer1To3::variant_count(); - index /= Integer1To3::variant_count(); - Integer1To3::from_index(value) + let value = (index % 3u16) as u8; + index /= 3u16; + value + 1u8 }, } } @@ -515312,7 +514942,15 @@ impl BlockProperties for WaterCauldronLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("level", self.r#level.to_value())] + vec![( + "level", + match self.r#level { + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -515325,7 +514963,14 @@ impl BlockProperties for WaterCauldronLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "level" { block_props.r#level = Integer1To3::from_value(value) } + if *key == "level" { + block_props.r#level = match *value { + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + _ => 1u8, + } + } } block_props } @@ -515334,7 +514979,7 @@ impl BlockProperties for WaterCauldronLikeProperties { pub struct RedstoneWireLikeProperties { pub r#east: EastRedstone, pub r#north: NorthRedstone, - pub r#power: Integer0To15, + pub r#power: u8, pub r#south: SouthRedstone, pub r#west: WestRedstone, } @@ -515343,7 +514988,7 @@ impl BlockProperties for RedstoneWireLikeProperties { let (index, _) = [ (self.r#west.to_index(), WestRedstone::variant_count()), (self.r#south.to_index(), SouthRedstone::variant_count()), - (self.r#power.to_index(), Integer0To15::variant_count()), + (self.r#power as u16, 16u16), (self.r#north.to_index(), NorthRedstone::variant_count()), (self.r#east.to_index(), EastRedstone::variant_count()), ] @@ -515367,9 +515012,9 @@ impl BlockProperties for RedstoneWireLikeProperties { SouthRedstone::from_index(value) }, r#power: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, r#north: { let value = index % NorthRedstone::variant_count(); @@ -515431,7 +515076,28 @@ impl BlockProperties for RedstoneWireLikeProperties { vec![ ("east", self.r#east.to_value()), ("north", self.r#north.to_value()), - ("power", self.r#power.to_value()), + ( + "power", + match self.r#power { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ("south", self.r#south.to_value()), ("west", self.r#west.to_value()), ] @@ -515450,7 +515116,27 @@ impl BlockProperties for RedstoneWireLikeProperties { match *key { "east" => block_props.r#east = EastRedstone::from_value(value), "north" => block_props.r#north = NorthRedstone::from_value(value), - "power" => block_props.r#power = Integer0To15::from_value(value), + "power" => { + block_props.r#power = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } "south" => block_props.r#south = SouthRedstone::from_value(value), "west" => block_props.r#west = WestRedstone::from_value(value), _ => {} @@ -515550,11 +515236,11 @@ impl BlockProperties for JukeboxLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct OakSaplingLikeProperties { - pub r#stage: Integer0To1, + pub r#stage: u8, } impl BlockProperties for OakSaplingLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#stage.to_index(), Integer0To1::variant_count())] + let (index, _) = [(self.r#stage as u16, 2u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -515565,9 +515251,9 @@ impl BlockProperties for OakSaplingLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#stage: { - let value = index % Integer0To1::variant_count(); - index /= Integer0To1::variant_count(); - Integer0To1::from_index(value) + let value = (index % 2u16) as u8; + index /= 2u16; + value }, } } @@ -515619,7 +515305,14 @@ impl BlockProperties for OakSaplingLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("stage", self.r#stage.to_value())] + vec![( + "stage", + match self.r#stage { + 0u8 => "0", + 1u8 => "1", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -515635,7 +515328,13 @@ impl BlockProperties for OakSaplingLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "stage" { block_props.r#stage = Integer0To1::from_value(value) } + if *key == "stage" { + block_props.r#stage = match *value { + "0" => 0u8, + "1" => 1u8, + _ => 0u8, + } + } } block_props } @@ -515643,14 +515342,14 @@ impl BlockProperties for OakSaplingLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct NoteBlockLikeProperties { pub r#instrument: NoteblockInstrument, - pub r#note: Integer0To24, + pub r#note: u8, pub r#powered: bool, } impl BlockProperties for NoteBlockLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#powered as u16, 2), - (self.r#note.to_index(), Integer0To24::variant_count()), + (self.r#note as u16, 25u16), ( self.r#instrument.to_index(), NoteblockInstrument::variant_count(), @@ -515671,9 +515370,9 @@ impl BlockProperties for NoteBlockLikeProperties { value == 0 }, r#note: { - let value = index % Integer0To24::variant_count(); - index /= Integer0To24::variant_count(); - Integer0To24::from_index(value) + let value = (index % 25u16) as u8; + index /= 25u16; + value }, r#instrument: { let value = index % NoteblockInstrument::variant_count(); @@ -515729,7 +515428,37 @@ impl BlockProperties for NoteBlockLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("instrument", self.r#instrument.to_value()), - ("note", self.r#note.to_value()), + ( + "note", + match self.r#note { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + 16u8 => "16", + 17u8 => "17", + 18u8 => "18", + 19u8 => "19", + 20u8 => "20", + 21u8 => "21", + 22u8 => "22", + 23u8 => "23", + 24u8 => "24", + _ => unreachable!(), + }, + ), ("powered", if self.r#powered { "true" } else { "false" }), ] } @@ -515746,7 +515475,36 @@ impl BlockProperties for NoteBlockLikeProperties { for (key, value) in props { match *key { "instrument" => block_props.r#instrument = NoteblockInstrument::from_value(value), - "note" => block_props.r#note = Integer0To24::from_value(value), + "note" => { + block_props.r#note = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + "16" => 16u8, + "17" => 17u8, + "18" => 18u8, + "19" => 19u8, + "20" => 20u8, + "21" => 21u8, + "22" => 22u8, + "23" => 23u8, + "24" => 24u8, + _ => 0u8, + } + } "powered" => block_props.r#powered = matches!(*value, "true"), _ => {} } @@ -515756,11 +515514,11 @@ impl BlockProperties for NoteBlockLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct WheatLikeProperties { - pub r#age: Integer0To7, + pub r#age: u8, } impl BlockProperties for WheatLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#age.to_index(), Integer0To7::variant_count())] + let (index, _) = [(self.r#age as u16, 8u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -515771,9 +515529,9 @@ impl BlockProperties for WheatLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#age: { - let value = index % Integer0To7::variant_count(); - index /= Integer0To7::variant_count(); - Integer0To7::from_index(value) + let value = (index % 8u16) as u8; + index /= 8u16; + value }, } } @@ -515822,7 +515580,20 @@ impl BlockProperties for WheatLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("age", self.r#age.to_value())] + vec![( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -515835,7 +515606,19 @@ impl BlockProperties for WheatLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "age" { block_props.r#age = Integer0To7::from_value(value) } + if *key == "age" { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + _ => 0u8, + } + } } block_props } @@ -516150,11 +515933,11 @@ impl BlockProperties for PaleOakWoodLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct WhiteBannerLikeProperties { - pub r#rotation: Integer0To15, + pub r#rotation: u8, } impl BlockProperties for WhiteBannerLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#rotation.to_index(), Integer0To15::variant_count())] + let (index, _) = [(self.r#rotation as u16, 16u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -516165,9 +515948,9 @@ impl BlockProperties for WhiteBannerLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#rotation: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -516234,7 +516017,28 @@ impl BlockProperties for WhiteBannerLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("rotation", self.r#rotation.to_value())] + vec![( + "rotation", + match self.r#rotation { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -516265,7 +516069,27 @@ impl BlockProperties for WhiteBannerLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "rotation" { block_props.r#rotation = Integer0To15::from_value(value) } + if *key == "rotation" { + block_props.r#rotation = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } } block_props } @@ -516273,12 +516097,12 @@ impl BlockProperties for WhiteBannerLikeProperties { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct SkeletonSkullLikeProperties { pub r#powered: bool, - pub r#rotation: Integer0To15, + pub r#rotation: u8, } impl BlockProperties for SkeletonSkullLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ - (self.r#rotation.to_index(), Integer0To15::variant_count()), + (self.r#rotation as u16, 16u16), (!self.r#powered as u16, 2), ] .iter() @@ -516291,9 +516115,9 @@ impl BlockProperties for SkeletonSkullLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#rotation: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, r#powered: { let value = index % 2; @@ -516352,7 +516176,28 @@ impl BlockProperties for SkeletonSkullLikeProperties { fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ ("powered", if self.r#powered { "true" } else { "false" }), - ("rotation", self.r#rotation.to_value()), + ( + "rotation", + match self.r#rotation { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + ), ] } #[allow(clippy::manual_range_patterns)] @@ -516371,7 +516216,27 @@ impl BlockProperties for SkeletonSkullLikeProperties { for (key, value) in props { match *key { "powered" => block_props.r#powered = matches!(*value, "true"), - "rotation" => block_props.r#rotation = Integer0To15::from_value(value), + "rotation" => { + block_props.r#rotation = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } _ => {} } } @@ -516487,11 +516352,11 @@ impl BlockProperties for TrialSpawnerLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct WaterLikeProperties { - pub r#level: Integer0To15, + pub r#level: u8, } impl BlockProperties for WaterLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#level.to_index(), Integer0To15::variant_count())] + let (index, _) = [(self.r#level as u16, 16u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -516502,9 +516367,9 @@ impl BlockProperties for WaterLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#level: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -516553,7 +516418,28 @@ impl BlockProperties for WaterLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("level", self.r#level.to_value())] + vec![( + "level", + match self.r#level { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -516566,18 +516452,38 @@ impl BlockProperties for WaterLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "level" { block_props.r#level = Integer0To15::from_value(value) } + if *key == "level" { + block_props.r#level = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct KelpLikeProperties { - pub r#age: Integer0To25, + pub r#age: u8, } impl BlockProperties for KelpLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#age.to_index(), Integer0To25::variant_count())] + let (index, _) = [(self.r#age as u16, 26u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -516588,9 +516494,9 @@ impl BlockProperties for KelpLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#age: { - let value = index % Integer0To25::variant_count(); - index /= Integer0To25::variant_count(); - Integer0To25::from_index(value) + let value = (index % 26u16) as u8; + index /= 26u16; + value }, } } @@ -516639,7 +516545,38 @@ impl BlockProperties for KelpLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("age", self.r#age.to_value())] + vec![( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + 16u8 => "16", + 17u8 => "17", + 18u8 => "18", + 19u8 => "19", + 20u8 => "20", + 21u8 => "21", + 22u8 => "22", + 23u8 => "23", + 24u8 => "24", + 25u8 => "25", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -516652,21 +516589,51 @@ impl BlockProperties for KelpLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "age" { block_props.r#age = Integer0To25::from_value(value) } + if *key == "age" { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + "16" => 16u8, + "17" => 17u8, + "18" => 18u8, + "19" => 19u8, + "20" => 20u8, + "21" => 21u8, + "22" => 22u8, + "23" => 23u8, + "24" => 24u8, + "25" => 25u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct CaveVinesLikeProperties { - pub r#age: Integer0To25, + pub r#age: u8, pub r#berries: bool, } impl BlockProperties for CaveVinesLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (!self.r#berries as u16, 2), - (self.r#age.to_index(), Integer0To25::variant_count()), + (self.r#age as u16, 26u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -516683,9 +516650,9 @@ impl BlockProperties for CaveVinesLikeProperties { value == 0 }, r#age: { - let value = index % Integer0To25::variant_count(); - index /= Integer0To25::variant_count(); - Integer0To25::from_index(value) + let value = (index % 26u16) as u8; + index /= 26u16; + value }, } } @@ -516735,7 +516702,38 @@ impl BlockProperties for CaveVinesLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("age", self.r#age.to_value()), + ( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + 16u8 => "16", + 17u8 => "17", + 18u8 => "18", + 19u8 => "19", + 20u8 => "20", + 21u8 => "21", + 22u8 => "22", + 23u8 => "23", + 24u8 => "24", + 25u8 => "25", + _ => unreachable!(), + }, + ), ("berries", if self.r#berries { "true" } else { "false" }), ] } @@ -516751,7 +516749,37 @@ impl BlockProperties for CaveVinesLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "age" => block_props.r#age = Integer0To25::from_value(value), + "age" => { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + "16" => 16u8, + "17" => 17u8, + "18" => 18u8, + "19" => 19u8, + "20" => 20u8, + "21" => 21u8, + "22" => 22u8, + "23" => 23u8, + "24" => 24u8, + "25" => 25u8, + _ => 0u8, + } + } "berries" => block_props.r#berries = matches!(*value, "true"), _ => {} } @@ -516761,11 +516789,11 @@ impl BlockProperties for CaveVinesLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct LightWeightedPressurePlateLikeProperties { - pub r#power: Integer0To15, + pub r#power: u8, } impl BlockProperties for LightWeightedPressurePlateLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#power.to_index(), Integer0To15::variant_count())] + let (index, _) = [(self.r#power as u16, 16u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -516776,9 +516804,9 @@ impl BlockProperties for LightWeightedPressurePlateLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#power: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -516827,7 +516855,28 @@ impl BlockProperties for LightWeightedPressurePlateLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("power", self.r#power.to_value())] + vec![( + "power", + match self.r#power { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -516840,7 +516889,27 @@ impl BlockProperties for LightWeightedPressurePlateLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "power" { block_props.r#power = Integer0To15::from_value(value) } + if *key == "power" { + block_props.r#power = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } } block_props } @@ -516933,11 +517002,11 @@ impl BlockProperties for StructureBlockLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct TorchflowerCropLikeProperties { - pub r#age: Integer0To1, + pub r#age: u8, } impl BlockProperties for TorchflowerCropLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#age.to_index(), Integer0To1::variant_count())] + let (index, _) = [(self.r#age as u16, 2u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -516948,9 +517017,9 @@ impl BlockProperties for TorchflowerCropLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#age: { - let value = index % Integer0To1::variant_count(); - index /= Integer0To1::variant_count(); - Integer0To1::from_index(value) + let value = (index % 2u16) as u8; + index /= 2u16; + value }, } } @@ -516999,7 +517068,14 @@ impl BlockProperties for TorchflowerCropLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("age", self.r#age.to_value())] + vec![( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -517012,18 +517088,24 @@ impl BlockProperties for TorchflowerCropLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "age" { block_props.r#age = Integer0To1::from_value(value) } + if *key == "age" { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct NetherWartLikeProperties { - pub r#age: Integer0To3, + pub r#age: u8, } impl BlockProperties for NetherWartLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#age.to_index(), Integer0To3::variant_count())] + let (index, _) = [(self.r#age as u16, 4u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -517034,9 +517116,9 @@ impl BlockProperties for NetherWartLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#age: { - let value = index % Integer0To3::variant_count(); - index /= Integer0To3::variant_count(); - Integer0To3::from_index(value) + let value = (index % 4u16) as u8; + index /= 4u16; + value }, } } @@ -517085,7 +517167,16 @@ impl BlockProperties for NetherWartLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("age", self.r#age.to_value())] + vec![( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -517098,21 +517189,29 @@ impl BlockProperties for NetherWartLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "age" { block_props.r#age = Integer0To3::from_value(value) } + if *key == "age" { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct PitcherCropLikeProperties { - pub r#age: Integer0To4, + pub r#age: u8, pub r#half: DoubleBlockHalf, } impl BlockProperties for PitcherCropLikeProperties { fn to_index(&self) -> u16 { let (index, _) = [ (self.r#half.to_index(), DoubleBlockHalf::variant_count()), - (self.r#age.to_index(), Integer0To4::variant_count()), + (self.r#age as u16, 5u16), ] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { @@ -517129,9 +517228,9 @@ impl BlockProperties for PitcherCropLikeProperties { DoubleBlockHalf::from_index(value) }, r#age: { - let value = index % Integer0To4::variant_count(); - index /= Integer0To4::variant_count(); - Integer0To4::from_index(value) + let value = (index % 5u16) as u8; + index /= 5u16; + value }, } } @@ -517181,7 +517280,17 @@ impl BlockProperties for PitcherCropLikeProperties { } fn to_props(&self) -> Vec<(&'static str, &'static str)> { vec![ - ("age", self.r#age.to_value()), + ( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + _ => unreachable!(), + }, + ), ("half", self.r#half.to_value()), ] } @@ -517197,7 +517306,16 @@ impl BlockProperties for PitcherCropLikeProperties { let mut block_props = Self::default(block); for (key, value) in props { match *key { - "age" => block_props.r#age = Integer0To4::from_value(value), + "age" => { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + _ => 0u8, + } + } "half" => block_props.r#half = DoubleBlockHalf::from_value(value), _ => {} } @@ -517327,11 +517445,11 @@ impl BlockProperties for BrewingStandLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct CakeLikeProperties { - pub r#bites: Integer0To6, + pub r#bites: u8, } impl BlockProperties for CakeLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#bites.to_index(), Integer0To6::variant_count())] + let (index, _) = [(self.r#bites as u16, 7u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -517342,9 +517460,9 @@ impl BlockProperties for CakeLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#bites: { - let value = index % Integer0To6::variant_count(); - index /= Integer0To6::variant_count(); - Integer0To6::from_index(value) + let value = (index % 7u16) as u8; + index /= 7u16; + value }, } } @@ -517393,7 +517511,19 @@ impl BlockProperties for CakeLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("bites", self.r#bites.to_value())] + vec![( + "bites", + match self.r#bites { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -517406,7 +517536,18 @@ impl BlockProperties for CakeLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "bites" { block_props.r#bites = Integer0To6::from_value(value) } + if *key == "bites" { + block_props.r#bites = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + _ => 0u8, + } + } } block_props } @@ -517795,11 +517936,11 @@ impl BlockProperties for CaveVinesPlantLikeProperties { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ChorusFlowerLikeProperties { - pub r#age: Integer0To5, + pub r#age: u8, } impl BlockProperties for ChorusFlowerLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#age.to_index(), Integer0To5::variant_count())] + let (index, _) = [(self.r#age as u16, 6u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -517810,9 +517951,9 @@ impl BlockProperties for ChorusFlowerLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#age: { - let value = index % Integer0To5::variant_count(); - index /= Integer0To5::variant_count(); - Integer0To5::from_index(value) + let value = (index % 6u16) as u8; + index /= 6u16; + value }, } } @@ -517861,7 +518002,18 @@ impl BlockProperties for ChorusFlowerLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("age", self.r#age.to_value())] + vec![( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -517874,18 +518026,28 @@ impl BlockProperties for ChorusFlowerLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "age" { block_props.r#age = Integer0To5::from_value(value) } + if *key == "age" { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + _ => 0u8, + } + } } block_props } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct CactusLikeProperties { - pub r#age: Integer0To15, + pub r#age: u8, } impl BlockProperties for CactusLikeProperties { fn to_index(&self) -> u16 { - let (index, _) = [(self.r#age.to_index(), Integer0To15::variant_count())] + let (index, _) = [(self.r#age as u16, 16u16)] .iter() .fold((0, 1), |(curr, mul), &(val, count)| { (curr + val * mul, mul * count) @@ -517896,9 +518058,9 @@ impl BlockProperties for CactusLikeProperties { fn from_index(mut index: u16) -> Self { Self { r#age: { - let value = index % Integer0To15::variant_count(); - index /= Integer0To15::variant_count(); - Integer0To15::from_index(value) + let value = (index % 16u16) as u8; + index /= 16u16; + value }, } } @@ -517947,7 +518109,28 @@ impl BlockProperties for CactusLikeProperties { Self::from_state_id(block.default_state.id, block) } fn to_props(&self) -> Vec<(&'static str, &'static str)> { - vec![("age", self.r#age.to_value())] + vec![( + "age", + match self.r#age { + 0u8 => "0", + 1u8 => "1", + 2u8 => "2", + 3u8 => "3", + 4u8 => "4", + 5u8 => "5", + 6u8 => "6", + 7u8 => "7", + 8u8 => "8", + 9u8 => "9", + 10u8 => "10", + 11u8 => "11", + 12u8 => "12", + 13u8 => "13", + 14u8 => "14", + 15u8 => "15", + _ => unreachable!(), + }, + )] } #[allow(clippy::manual_range_patterns)] fn from_props(props: &[(&str, &str)], block: &Block) -> Self { @@ -517960,7 +518143,27 @@ impl BlockProperties for CactusLikeProperties { } let mut block_props = Self::default(block); for (key, value) in props { - if *key == "age" { block_props.r#age = Integer0To15::from_value(value) } + if *key == "age" { + block_props.r#age = match *value { + "0" => 0u8, + "1" => 1u8, + "2" => 2u8, + "3" => 3u8, + "4" => 4u8, + "5" => 5u8, + "6" => 6u8, + "7" => 7u8, + "8" => 8u8, + "9" => 9u8, + "10" => 10u8, + "11" => 11u8, + "12" => 12u8, + "13" => 13u8, + "14" => 14u8, + "15" => 15u8, + _ => 0u8, + } + } } block_props } diff --git a/pumpkin-data/src/generated/data_component.rs b/pumpkin-data/src/generated/data_component.rs index 15edb3485..5e5411bf6 100644 --- a/pumpkin-data/src/generated/data_component.rs +++ b/pumpkin-data/src/generated/data_component.rs @@ -464,11 +464,4 @@ impl DataComponent { Self::ShulkerColor => "minecraft:shulker/color", } } - pub fn try_from_u8(v: u8) -> Option { - if v <= 106 { - Some(unsafe { std::mem::transmute::(v) }) - } else { - None - } - } } diff --git a/pumpkin-data/src/item_stack/mod.rs b/pumpkin-data/src/item_stack/mod.rs index a84bc9cc7..db1b03373 100644 --- a/pumpkin-data/src/item_stack/mod.rs +++ b/pumpkin-data/src/item_stack/mod.rs @@ -549,7 +549,7 @@ impl ItemStack { let patch_len = nbt.get_u32().ok()? as usize; for _ in 0..patch_len { let component_id_raw = nbt.get_u8().ok()?; - let id = DataComponent::try_from_u8(component_id_raw)?; + let id = DataComponent::try_from_id(component_id_raw)?; let is_present = nbt.get_bool().ok()?; if is_present { diff --git a/pumpkin-world/src/block/entities/daylight_detector.rs b/pumpkin-world/src/block/entities/daylight_detector.rs index d93689b52..ab79b1927 100644 --- a/pumpkin-world/src/block/entities/daylight_detector.rs +++ b/pumpkin-world/src/block/entities/daylight_detector.rs @@ -1,7 +1,7 @@ use std::pin::Pin; use std::sync::Arc; -use pumpkin_data::block_properties::{BlockProperties, EnumVariants, Integer0To15}; +use pumpkin_data::block_properties::BlockProperties; use pumpkin_nbt::compound::NbtCompound; use pumpkin_util::math::position::BlockPos; @@ -120,7 +120,7 @@ impl DaylightDetectorBlockEntity { power = (power as f32 * sun_angle_radians.cos()).round() as u8; } - let power = Integer0To15::from_index(power.clamp(0, 15).into()); + let power = power.clamp(0, 15); if power != props.power { props.power = power; let state = props.to_state_id(block); diff --git a/pumpkin-world/src/chunk/io/file_manager.rs b/pumpkin-world/src/chunk/io/file_manager.rs index ff0018bcd..bba5fadc6 100644 --- a/pumpkin-world/src/chunk/io/file_manager.rs +++ b/pumpkin-world/src/chunk/io/file_manager.rs @@ -22,24 +22,29 @@ use crate::{ use super::{ChunkSerializer, FileIO, LoadedData}; -/// A simple implementation of the `ChunkSerializer` trait -/// that load and save the data from a file in the disk -/// using parallelism and a cache for the files with ongoing IO operations. +/// A simple implementation of the `ChunkSerializer` trait that loads and saves data +/// to disk using parallelism and a lazy-loading cache keyed by file path. /// -/// It also avoid IO operations that could produce dataraces thanks to the -/// custom *`DashMap`*-like implementation. +/// ### Concurrency model +/// +/// * `file_locks` — one `Arc>` per on-disk file, created lazily. +/// All readers/writers for the same region file share this lock, so there +/// are never two concurrent writers for the same file. +/// * `watchers` — a ref-count per path. While a path has active watchers the +/// serializer is **not** evicted from the cache and the file is **not** +/// flushed to disk (the caller owns the flush lifecycle). +/// +/// ### Lock ordering (must never be violated to avoid deadlocks) +/// +/// 1. `file_locks` (outer) +/// 2. individual `RwLock` inside each loader (inner) +/// 3. `watchers` (independent — never held at the same time as either above) +/// +/// `watchers` is always acquired in its own critical section, after all +/// serializer locks are released, which keeps it strictly independent. pub struct ChunkFileManager> { - // Dashmap has rw-locks on shards, but we want per-serializer. - // - // Lock lookups need to be: - // - Relatively quick insertion / lookup as to not extraneously block other concurrent hashmap - // ops - // - Guarantee that there is only one serializer per file at a time - // - Lazily load files as to support point 1 - // - Allow for ease of usage (able to return the serializer from a function) file_locks: RwLock>>>, watchers: RwLock>, - chunk_config: S::ChunkConfig, } @@ -49,6 +54,7 @@ pub(crate) trait PathFromLevelFolder { struct ChunkSerializerLazyLoader> { path: PathBuf, + /// Initialised at most once; subsequent calls reuse the same Arc. internal: OnceCell>>, } @@ -60,21 +66,28 @@ impl> ChunkSerializerLazyLoader { } } - /// We can only remove this entry from the map if we are the only ones with a reference to it - /// IMPORTANT: This must be called within the write lock of the parent map + /// Returns `true` only when no outside caller still holds a clone of this + /// loader *or* the inner serializer. + /// + /// # Safety requirement + /// **Must be called while the write-lock on the parent `file_locks` map is + /// held.** That guarantees no new `Arc` clones can be issued while we + /// inspect the strong counts. fn can_remove(loader: &Arc) -> bool { + // The map itself holds 1 strong count; anything above that means an + // active caller still has a handle. if Arc::strong_count(loader) > 1 { return false; } match loader.internal.get() { - Some(arc) => { - // A strong count of 1 means it's only in the map - Arc::strong_count(arc) == 1 - } + // The loader holds 1 strong count; anything above that means + // a read/write guard is still live somewhere. + Some(arc) => Arc::strong_count(arc) == 1, None => true, } } + /// Returns the serializer, initialising it from disk on the first call. async fn get(&self) -> Result>, ChunkReadingError> { self.internal .get_or_try_init(|| async { @@ -86,30 +99,19 @@ impl> ChunkSerializerLazyLoader { } async fn read_from_disk(&self) -> Result { - trace!("Opening file from Disk: {}", self.path.display()); + trace!("Opening file from disk: {}", self.path.display()); - let file_bytes = tokio::fs::read(&self.path).await.map_err(|err| { - if err.kind() == std::io::ErrorKind::NotFound { - ChunkReadingError::ChunkNotExist - } else { - ChunkReadingError::IoError(err.kind()) - } - }); - - match file_bytes { + match tokio::fs::read(&self.path).await { Ok(bytes) => { let value = S::read(bytes.into())?; - trace!("Successfully read file from Disk: {}", self.path.display()); + trace!("Successfully read file from disk: {}", self.path.display()); Ok(value) } - Err(ChunkReadingError::ChunkNotExist) => { - trace!( - "Chunk not found, using default for: {}", - self.path.display() - ); + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + trace!("File not found, using default for: {}", self.path.display()); Ok(S::default()) } - Err(err) => Err(err), + Err(err) => Err(ChunkReadingError::IoError(err.kind())), } } } @@ -125,23 +127,63 @@ impl> ChunkFileManager { } impl> ChunkFileManager { + /// Returns the serializer for `path`, inserting a lazy-loader if absent. + /// + /// Uses an optimistic read-first pattern: in the common case (cache hit) + /// we never need a write-lock on the map. async fn get_serializer(&self, path: &Path) -> Result>, ChunkReadingError> { - // We get the entry from the DashMap and try to insert a new lock if it doesn't exist - // using dead-lock safe methods like `or_try_insert_with` + { + let locks = self.file_locks.read().await; + if let Some(loader) = locks.get(path) { + // Clone the Arc *before* releasing the lock so it stays alive. + let loader = loader.clone(); + drop(locks); + return loader.get().await; + } + } - // We use a lazy loader here to quickly make an insertion into the map without holding the - // lock for too long starving other threads - let loader = self.file_locks.read().await.get(path).cloned(); - if let Some(serializer_loader) = loader { - serializer_loader.get().await - } else { + let loader = { let mut locks = self.file_locks.write().await; - let loader = locks + locks .entry(path.into()) .or_insert_with(|| Arc::new(ChunkSerializerLazyLoader::new(path.into()))) - .clone(); - drop(locks); - loader.get().await + .clone() + // Write-lock dropped here — `loader.get()` may block on I/O and + // must not hold the map lock. + }; + + loader.get().await + } + + /// Attempt to evict the cached serializer for `path`. + /// + /// The entry is only removed when *both* conditions hold: + /// 1. No watcher still references the path. + /// 2. No other `Arc` clone is live (ensured via `can_remove`). + async fn maybe_evict(&self, path: &PathBuf) { + // Check watchers independently of file_locks to honour lock ordering. + let still_watched = { + let watchers = self.watchers.read().await; + watchers.get(path).is_some_and(|&c| c > 0) + }; + + if still_watched { + return; + } + + let mut locks = self.file_locks.write().await; + let removable = locks + .get(path) + .is_some_and(ChunkSerializerLazyLoader::can_remove); + + if removable { + locks.remove(path); + trace!("Evicted serializer cache for {}", path.display()); + } else { + trace!( + "Skipping eviction for {} — references still live", + path.display() + ); } } } @@ -159,16 +201,15 @@ where folder: &'a LevelFolder, chunks: &'a [Vector2], ) -> BoxFuture<'a, ()> { - let paths = chunks - .iter() - .map(|chunk| P::file_path(folder, &S::get_chunk_key(chunk))); Box::pin(async move { + let paths: Vec<_> = chunks + .iter() + .map(|c| P::file_path(folder, &S::get_chunk_key(c))) + .collect(); + let mut watchers = self.watchers.write().await; for path in paths { - watchers - .entry(path) - .and_modify(|count| *count += 1) - .or_insert(1); + *watchers.entry(path).or_insert(0) += 1; } }) } @@ -178,21 +219,19 @@ where folder: &'a LevelFolder, chunks: &'a [Vector2], ) -> BoxFuture<'a, ()> { - let paths = chunks - .iter() - .map(|chunk| P::file_path(folder, &S::get_chunk_key(chunk))); Box::pin(async move { + let paths: Vec<_> = chunks + .iter() + .map(|c| P::file_path(folder, &S::get_chunk_key(c))) + .collect(); + let mut watchers = self.watchers.write().await; - for path in paths { - if let std::collections::btree_map::Entry::Occupied(mut occupied) = - watchers.entry(path) - { - let count = occupied.get_mut(); + if let std::collections::btree_map::Entry::Occupied(mut e) = watchers.entry(path) { + let count = e.get_mut(); *count = count.saturating_sub(1); - if *count == 0 { - occupied.remove(); + e.remove(); } } } @@ -209,64 +248,63 @@ where &'a self, folder: &'a LevelFolder, chunk_coords: &'a [Vector2], - stream: tokio::sync::mpsc::Sender>, + stream: mpsc::Sender>, ) -> BoxFuture<'a, ()> { Box::pin(async move { + // Group requested chunk coords by their region file. let mut regions_chunks: BTreeMap>> = BTreeMap::new(); - for at in chunk_coords { - let key = S::get_chunk_key(at); - regions_chunks - .entry(key) - .and_modify(|chunks| chunks.push(*at)) - .or_insert(vec![*at]); + .entry(S::get_chunk_key(at)) + .or_default() + .push(*at); } - // we use a Sync Closure with an Async Block to execute the tasks concurrently - // Also improves File Cache utilizations. - let region_read_tasks = regions_chunks.into_iter().map(move |(file_name, chunks)| { + let region_tasks = regions_chunks.into_iter().map(|(file_name, chunks)| { let task_stream = stream.clone(); - async move { let path = P::file_path(folder, &file_name); + let chunk_serializer = match self.get_serializer(&path).await { - Ok(chunk_serializer) => chunk_serializer, + Ok(s) => s, Err(ChunkReadingError::ChunkNotExist) => { - unreachable!("Default Serializer must be created") + unreachable!("get_serializer always returns a default serializer") } Err(err) => { + // Best-effort: report the error for the first coord in the batch. let _ = task_stream.send(LoadedData::Error((chunks[0], err))).await; return; } }; + // A bounded channel of 1 keeps backpressure between the + // serializer and the caller without unbounded buffering. let (send, mut recv) = mpsc::channel::>(1); - let intermediary = async move { - // Note: 'task_stream' is captured and moved here + // Forward received chunks, wrapping them in `Arc`. + // Captured move is intentional — `task_stream` is consumed here. + let forward = async move { while let Some(data) = recv.recv().await { - let wrapped_data = data.map_loaded(|data| Arc::new(data)); - if task_stream.send(wrapped_data).await.is_err() { - // Stream is closed, so stop unneeded computation and io + let wrapped = data.map_loaded(Arc::new); + if task_stream.send(wrapped).await.is_err() { + // Receiver dropped; abort early to avoid wasted work. return; } } }; - // We need to hold the read lock only for the duration of get_chunks - // This minimizes the time we block other operations - let reader = async move { + // Hold the read lock only for the duration of `get_chunks`. + let read = async move { let serializer = chunk_serializer.read().await; serializer.get_chunks(chunks, send).await; }; - join!(intermediary, reader); + join!(forward, read); } }); - let _ = join_all(region_read_tasks).await; + join_all(region_tasks).await; }) } @@ -276,133 +314,115 @@ where chunks_data: Vec<(Vector2, Self::Data)>, ) -> BoxFuture<'a, Result<(), ChunkWritingError>> { Box::pin(async move { + // Group chunks by region file. let mut regions_chunks: BTreeMap> = BTreeMap::new(); - for (at, chunk) in chunks_data { - let key = S::get_chunk_key(&at); - - match regions_chunks.entry(key) { - std::collections::btree_map::Entry::Occupied(mut occupied) => { - occupied.get_mut().push(chunk); - } - std::collections::btree_map::Entry::Vacant(vacant) => { - vacant.insert(vec![chunk]); - } - } + regions_chunks + .entry(S::get_chunk_key(&at)) + .or_default() + .push(chunk); } - // we use a Sync Closure with an Async Block to execute the tasks in parallel - // with out waiting the future. Also it improve we File Cache utilizations. let tasks = regions_chunks .into_iter() - // The closure now needs `move` to capture `self` and `folder` by value - .map(move |(file_name, chunk_locks)| async move { + .map(|(file_name, chunk_locks)| async move { let path = P::file_path(folder, &file_name); - trace!("Updating data for file {}", path.display()); + trace!("Saving chunks into {}", path.display()); let chunk_serializer = match self.get_serializer(&path).await { - Ok(file) => Ok(file), + Ok(s) => s, Err(ChunkReadingError::ChunkNotExist) => { - unreachable!("Must be managed by the cache") + unreachable!("get_serializer always returns a default serializer") } Err(ChunkReadingError::IoError(err)) => { - error!("Error reading the data before write: {err}"); - Err(ChunkWritingError::IoError(err)) + error!("I/O error reading region before write: {err}"); + return Err(ChunkWritingError::IoError(err)); } - Err(_) => Err(ChunkWritingError::IoError(std::io::ErrorKind::Other)), - }?; + Err(_) => { + return Err(ChunkWritingError::IoError(std::io::ErrorKind::Other)); + } + }; - // Create a task for each chunk_lock - let update_tasks = chunk_locks.into_iter().map(|chunk_lock| { - let chunk_serializer = chunk_serializer.clone(); - async move { - let chunk = chunk_lock; - let chunk_is_dirty = chunk.is_dirty(); - // Edge case: this chunk is loaded while we were saving, mark it as cleaned since we are - // updating what we will write here + { + let mut writer = chunk_serializer.write().await; + for chunk in &chunk_locks { + // Atomically snapshot and clear the dirty flag before we + // write so that any mutation that races in *during* this + // serialisation round will mark dirty again correctly. + let was_dirty = chunk.is_dirty(); chunk.mark_dirty(false); - // We only need to update the chunk if it is dirty - if chunk_is_dirty { - let mut writer = chunk_serializer.write().await; - writer.update_chunk(&*chunk, &self.chunk_config).await?; + if was_dirty { + writer.update_chunk(&**chunk, &self.chunk_config).await?; } - Ok::<(), ChunkWritingError>(()) } - }); - // Run all update tasks concurrently and propagate any error - futures::future::try_join_all(update_tasks).await?; - trace!("Updated data for file {}", path.display()); + // Write-lock released here — flush can proceed under a read-lock. + } + trace!("Chunk data updated for {}", path.display()); + + // We check watchers *after* releasing the write-lock to honour + // lock ordering (serializer lock → watchers, never the reverse). let is_watched = { let watchers = self.watchers.read().await; - watchers.get(&path).is_some_and(|count| count != &0) + watchers.get(&path).is_some_and(|&c| c > 0) }; if !is_watched { - // With the modification done, we can drop the write lock but keep the read lock - // to avoid other threads to write/modify the data, but allow other threads to read it - let serializer = chunk_serializer.read().await; + // A read-lock suffices for `write()` since we have already + // applied all mutations above. + { + let serializer = chunk_serializer.read().await; + debug!("Flushing {} to disk", path.display()); + serializer + .write(&path) + .await + .map_err(|e| ChunkWritingError::IoError(e.kind()))?; + // Read-lock released here. + } - debug!("Writing file for {}", path.display()); - serializer - .write(&path) - .await - .map_err(|err| ChunkWritingError::IoError(err.kind()))?; - - // Remove lock - drop(serializer); - // Decrement strong count + // Drop our handle so `can_remove` may succeed. drop(chunk_serializer); - let should_remove = { - let watchers = self.watchers.read().await; - watchers.get(&path).is_none_or(|count| count == &0) - }; - - if should_remove { - let mut locks = self.file_locks.write().await; - - let can_remove = if let Some(loader) = locks.get(&path) { - ChunkSerializerLazyLoader::can_remove(loader) - } else { - true - }; - - if can_remove { - locks.remove(&path); - trace!("Removed lockfile cache {}", path.display()); - } else { - trace!("Wanted to remove lockfile cache {} but someone still holds a reference to it!", path.display()); - } - } + // Evict the cache entry when no longer needed. + self.maybe_evict(&path).await; } Ok(()) }); - //TODO: we need to handle the errors and return the result - // files to save - let _test: Vec> = join_all(tasks).await; - - Ok(()) + // Collect all region results; surface the first error encountered. + let results: Vec> = join_all(tasks).await; + results.into_iter().find(Result::is_err).unwrap_or(Ok(())) }) } + /// Blocks until all in-flight serialiser operations have completed by + /// acquiring (and immediately releasing) a write-lock on every cached + /// serialiser. + /// + /// This is a linearisation point: after this future resolves no mutation + /// started before the call is still running. fn block_and_await_ongoing_tasks(&self) -> BoxFuture<'_, ()> { Box::pin(async move { - //we need to block any other operation - let serializer_cache = self.file_locks.read().await; + // Snapshot the current set of loaders under a read-lock so we do + // not block new insertions longer than necessary. + let loaders: Vec>> = + { self.file_locks.read().await.values().cloned().collect() }; - // Acquire a write lock on all entries to verify they are complete - let _tasks = serializer_cache - .values() - .map(ChunkSerializerLazyLoader::can_remove); + // For each loader that has been initialised, acquire a write-lock + // and release it immediately. This guarantees that any concurrent + // read or write operation that was in progress has finished. + let drain_tasks = loaders.into_iter().map(|loader| async move { + if let Some(serializer_arc) = loader.internal.get() { + // Acquiring + immediately dropping the write-lock acts as a + // barrier: it can only succeed once all current lock holders + // have released their guards. + let _guard = serializer_arc.write().await; + } + }); - // We need to wait to ensure that all the locks are acquired - // so there is no **operation** ongoing - // TODO - // let _ = join_all(tasks); + join_all(drain_tasks).await; }) } } diff --git a/pumpkin-world/src/generation/feature/features/bamboo.rs b/pumpkin-world/src/generation/feature/features/bamboo.rs index 5f4369ec1..e8418e79d 100644 --- a/pumpkin-world/src/generation/feature/features/bamboo.rs +++ b/pumpkin-world/src/generation/feature/features/bamboo.rs @@ -1,6 +1,6 @@ use pumpkin_data::{ Block, BlockState, - block_properties::{BambooLeaves, BambooLikeProperties, BlockProperties, Integer0To1}, + block_properties::{BambooLeaves, BambooLikeProperties, BlockProperties}, tag, }; use pumpkin_util::{ @@ -60,13 +60,13 @@ impl BambooFeature { if bpos.0.y - pos.0.y >= 3 { let mut props = BambooLikeProperties::default(&Block::BAMBOO); props.leaves = BambooLeaves::Large; - props.stage = Integer0To1::L1; + props.stage = 1; chunk.set_block_state( &bpos.0, BlockState::from_id(props.to_state_id(&Block::BAMBOO)), ); - props.stage = Integer0To1::L0; + props.stage = 0; chunk.set_block_state( &bpos.down().0, diff --git a/pumpkin-world/src/generation/feature/features/chorus_plant.rs b/pumpkin-world/src/generation/feature/features/chorus_plant.rs index eff4cb39f..97c611027 100644 --- a/pumpkin-world/src/generation/feature/features/chorus_plant.rs +++ b/pumpkin-world/src/generation/feature/features/chorus_plant.rs @@ -1,7 +1,7 @@ use pumpkin_data::{ Block, BlockDirection, block_properties::{ - BlockProperties, BrownMushroomBlockLikeProperties, ChorusFlowerLikeProperties, Integer0To5, + BlockProperties, BrownMushroomBlockLikeProperties, ChorusFlowerLikeProperties, }, tag, }; @@ -100,9 +100,7 @@ fn set_chorus_plant(chunk: &mut T, pos: &BlockPos) { /// Places a dead chorus flower (age 5) at `pos`. fn place_dead_flower(chunk: &mut T, pos: &BlockPos) { - let props = ChorusFlowerLikeProperties { - age: Integer0To5::L5, - }; + let props = ChorusFlowerLikeProperties { age: 5 }; let state_id = props.to_state_id(&Block::CHORUS_FLOWER); chunk.set_block_state(&pos.0, pumpkin_data::BlockState::from_id(state_id)); } diff --git a/pumpkin-world/src/generation/feature/features/coral/mod.rs b/pumpkin-world/src/generation/feature/features/coral/mod.rs index aca8cc411..27b3e01e9 100644 --- a/pumpkin-world/src/generation/feature/features/coral/mod.rs +++ b/pumpkin-world/src/generation/feature/features/coral/mod.rs @@ -1,7 +1,7 @@ use crate::generation::proto_chunk::GenerationCache; use pumpkin_data::{ Block, BlockDirection, BlockState, - block_properties::{BlockProperties, EnumVariants, Integer1To4, SeaPickleLikeProperties}, + block_properties::{BlockProperties, EnumVariants, SeaPickleLikeProperties}, tag, }; use pumpkin_util::{ @@ -38,7 +38,7 @@ impl CoralFeature { ); } else if random.next_f32() < 0.05 { let mut props = SeaPickleLikeProperties::default(&Block::SEA_PICKLE); - props.pickles = Integer1To4::from_index(random.next_bounded_i32(4) as u16); // TODO: vanilla adds + 1, but this can crash + props.pickles = (random.next_bounded_i32(4) as u8) + 1; chunk.set_block_state( &pos.0, BlockState::from_id(props.to_state_id(&Block::SEA_PICKLE)), diff --git a/pumpkin-world/src/generation/feature/features/sea_pickle.rs b/pumpkin-world/src/generation/feature/features/sea_pickle.rs index c82adc166..baa837947 100644 --- a/pumpkin-world/src/generation/feature/features/sea_pickle.rs +++ b/pumpkin-world/src/generation/feature/features/sea_pickle.rs @@ -1,7 +1,7 @@ use crate::generation::proto_chunk::GenerationCache; use pumpkin_data::{ Block, BlockState, - block_properties::{BlockProperties, EnumVariants, Integer1To4, SeaPickleLikeProperties}, + block_properties::{BlockProperties, SeaPickleLikeProperties}, }; use pumpkin_util::{ math::{int_provider::IntProvider, position::BlockPos}, @@ -32,7 +32,7 @@ impl SeaPickleFeature { continue; } let mut props = SeaPickleLikeProperties::default(&Block::SEA_PICKLE); - props.pickles = Integer1To4::from_index(random.next_bounded_i32(4) as u16); // TODO: vanilla adds + 1, but this can crash + props.pickles = (random.next_bounded_i32(4) as u8) + 1; let pos = BlockPos::new(pos.0.x + x, y, pos.0.z + z); chunk.set_block_state( &pos.0, diff --git a/pumpkin-world/src/lib.rs b/pumpkin-world/src/lib.rs index 3961fa2ac..c3b2c4df0 100644 --- a/pumpkin-world/src/lib.rs +++ b/pumpkin-world/src/lib.rs @@ -14,7 +14,6 @@ pub mod generation; pub mod inventory; pub mod level; pub mod lighting; -pub mod lock; pub mod poi; pub mod tick; pub mod world; diff --git a/pumpkin-world/src/lock/anvil.rs b/pumpkin-world/src/lock/anvil.rs deleted file mode 100644 index 029a7d75d..000000000 --- a/pumpkin-world/src/lock/anvil.rs +++ /dev/null @@ -1,38 +0,0 @@ -use super::{LevelLocker, LockError}; - -use std::{ - fs::{File, TryLockError}, - io::Write, - path::Path, -}; - -pub struct AnvilLevelLocker { - _locked_file: File, -} - -const SESSION_LOCK_FILE_NAME: &str = "session.lock"; - -const SNOWMAN: &[u8] = "☃".as_bytes(); - -impl LevelLocker for AnvilLevelLocker { - fn lock(folder: &Path) -> Result { - std::fs::create_dir_all(folder).map_err(|_| LockError::FailedWrite)?; - let file_path = folder.join(SESSION_LOCK_FILE_NAME); - let mut file = File::options() - .create(true) - .truncate(false) - .write(true) - .open(file_path) - .unwrap(); - // im not joking, mojang writes a snowman into the lock file - file.write_all(SNOWMAN) - .map_err(|_| LockError::FailedWrite)?; - file.try_lock().map_err(|e| match e { - TryLockError::WouldBlock => { - LockError::AlreadyLocked(SESSION_LOCK_FILE_NAME.to_string()) - } - TryLockError::Error(io_err) => LockError::Error(io_err), - })?; - Ok(Self { _locked_file: file }) - } -} diff --git a/pumpkin-world/src/lock/mod.rs b/pumpkin-world/src/lock/mod.rs deleted file mode 100644 index 608ba855b..000000000 --- a/pumpkin-world/src/lock/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::path::Path; - -use thiserror::Error; - -pub mod anvil; - -// Gets unlocked when dropped -pub trait LevelLocker: Send + Sync { - fn lock(folder: &Path) -> Result; -} - -#[derive(Error, Debug)] -pub enum LockError { - #[error("Oh no, Level is already locked by {0}")] - AlreadyLocked(String), - #[error("{0}")] - Error(std::io::Error), - #[error("Failed to write into lock file")] - FailedWrite, -} diff --git a/pumpkin/src/block/blocks/cake.rs b/pumpkin/src/block/blocks/cake.rs index a84e534a9..6d273827d 100644 --- a/pumpkin/src/block/blocks/cake.rs +++ b/pumpkin/src/block/blocks/cake.rs @@ -12,7 +12,7 @@ use crate::{ use pumpkin_data::item::Item; use pumpkin_data::{ Block, - block_properties::{BlockProperties, CakeLikeProperties, EnumVariants, Integer0To6}, + block_properties::{BlockProperties, CakeLikeProperties}, sound::{Sound, SoundCategory}, }; use pumpkin_macros::pumpkin_block; @@ -52,9 +52,9 @@ impl CakeBlock { } let mut properties = CakeLikeProperties::from_state_id(state_id, block); - match properties.bites.to_index() { + match properties.bites { 0..=5 => { - properties.bites = Integer0To6::from_index(properties.bites.to_index() + 1); + properties.bites += 1; world .set_block_state( location, @@ -107,7 +107,7 @@ impl BlockBehaviour for CakeBlock { drop(item_lock); match item.id { id if (Item::CANDLE.id..=Item::BLACK_CANDLE.id).contains(&id) => { - if properties.bites.to_index() != 0 { + if properties.bites != 0 { return Self::consume_if_hungry( args.world, args.player, diff --git a/pumpkin/src/block/blocks/candles.rs b/pumpkin/src/block/blocks/candles.rs index 9ce16ef5a..d806b3a90 100644 --- a/pumpkin/src/block/blocks/candles.rs +++ b/pumpkin/src/block/blocks/candles.rs @@ -1,7 +1,7 @@ use pumpkin_data::item::Item; use pumpkin_data::{ BlockDirection, - block_properties::{BlockProperties, CandleLikeProperties, EnumVariants, Integer1To4}, + block_properties::{BlockProperties, CandleLikeProperties}, entity::EntityPose, }; use pumpkin_macros::pumpkin_block_from_tag; @@ -33,8 +33,8 @@ impl BlockBehaviour for CandleBlock { && let BlockIsReplacing::Itself(state_id) = args.replacing { let mut properties = CandleLikeProperties::from_state_id(state_id, args.block); - if properties.candles.to_index() < 3 { - properties.candles = Integer1To4::from_index(properties.candles.to_index() + 1); + if properties.candles < 4 { + properties.candles += 1; } return properties.to_state_id(args.block); } @@ -63,9 +63,8 @@ impl BlockBehaviour for CandleBlock { { let was_lit = properties.lit; - if properties.candles.to_index() < 3 { - properties.candles = - Integer1To4::from_index(properties.candles.to_index() + 1); + if properties.candles < 4 { + properties.candles += 1; } properties.lit = was_lit; @@ -130,8 +129,7 @@ impl BlockBehaviour for CandleBlock { Box::pin(async move { let b = args.world.get_block(args.position).await; args.player.get_entity().pose.load() != EntityPose::Crouching - && CandleLikeProperties::from_state_id(args.state_id, args.block).candles - != Integer1To4::L4 + && CandleLikeProperties::from_state_id(args.state_id, args.block).candles != 4 && args.block.id == b.id }) } diff --git a/pumpkin/src/block/blocks/composter.rs b/pumpkin/src/block/blocks/composter.rs index 7b1f8a5ce..52f7dcab5 100644 --- a/pumpkin/src/block/blocks/composter.rs +++ b/pumpkin/src/block/blocks/composter.rs @@ -10,7 +10,7 @@ use crate::{ }; use pumpkin_data::{ Block, - block_properties::{BlockProperties, ComposterLikeProperties, EnumVariants, Integer0To8}, + block_properties::{BlockProperties, ComposterLikeProperties}, composter_increase_chance::get_composter_increase_chance_from_item_id, entity::EntityType, item::Item, @@ -31,7 +31,7 @@ impl BlockBehaviour for ComposterBlock { Box::pin(async move { let state_id = args.world.get_block_state_id(args.position).await; let props = ComposterLikeProperties::from_state_id(state_id, args.block); - if props.get_level() == 8 { + if props.level == 8 { self.clear_composter(args.world, args.position, state_id, args.block) .await; } @@ -47,7 +47,7 @@ impl BlockBehaviour for ComposterBlock { Box::pin(async move { let state_id = args.world.get_block_state_id(args.position).await; let props = ComposterLikeProperties::from_state_id(state_id, args.block); - let level = props.get_level(); + let level = props.level; // Check if the composter is full if level == 8 { @@ -93,7 +93,7 @@ impl BlockBehaviour for ComposterBlock { Box::pin(async move { let state_id = args.world.get_block_state_id(args.position).await; let props = ComposterLikeProperties::from_state_id(state_id, args.block); - let level = props.get_level(); + let level = props.level; if level == 7 { self.update_level_composter( args.world, @@ -113,7 +113,7 @@ impl BlockBehaviour for ComposterBlock { ) -> BlockFuture<'a, Option> { Box::pin(async move { let props = ComposterLikeProperties::from_state_id(args.state.id, args.block); - Some(props.get_level()) + Some(props.level) }) } } @@ -128,7 +128,7 @@ impl ComposterBlock { level: u8, ) { let mut props = ComposterLikeProperties::from_state_id(state_id, block); - props.set_level(level); + props.level = level; world .set_block_state(location, props.to_state_id(block), BlockFlags::NOTIFY_ALL) .await; @@ -167,17 +167,3 @@ impl ComposterBlock { world.spawn_entity(Arc::new(item_entity)).await; } } - -pub trait ComposterPropertiesEx { - fn get_level(&self) -> u8; - fn set_level(&mut self, level: u8); -} - -impl ComposterPropertiesEx for ComposterLikeProperties { - fn get_level(&self) -> u8 { - self.level.to_index() as u8 - } - fn set_level(&mut self, level: u8) { - self.level = Integer0To8::from_index(u16::from(level)); - } -} diff --git a/pumpkin/src/block/blocks/farmland.rs b/pumpkin/src/block/blocks/farmland.rs index 5872df710..a760205b7 100644 --- a/pumpkin/src/block/blocks/farmland.rs +++ b/pumpkin/src/block/blocks/farmland.rs @@ -11,9 +11,7 @@ use crate::world::World; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::BlockProperties; -use pumpkin_data::block_properties::EnumVariants; use pumpkin_data::block_properties::FarmlandLikeProperties; -use pumpkin_data::block_properties::Integer0To7; use pumpkin_data::tag; use pumpkin_data::tag::Taggable; use pumpkin_macros::pumpkin_block; @@ -77,7 +75,7 @@ impl BlockBehaviour for FarmlandBlock { // TODO: add rain check. Remember to check which one is most optimized. if is_water_nearby(args.world, args.position).await { let mut props = FarmlandProperties::default(args.block); - props.moisture = Integer0To7::L7; + props.moisture = 7; args.world .set_block_state( args.position, @@ -88,7 +86,7 @@ impl BlockBehaviour for FarmlandBlock { } else { let state_id = args.world.get_block_state_id(args.position).await; let mut props = FarmlandProperties::from_state_id(state_id, args.block); - if props.moisture == Integer0To7::L0 { + if props.moisture == 0 { if !args .world .get_block(&args.position.up()) @@ -105,7 +103,7 @@ impl BlockBehaviour for FarmlandBlock { .await; } } else { - props.moisture = Integer0To7::from_index(props.moisture.to_index() - 1); + props.moisture -= 1; args.world .set_block_state( args.position, diff --git a/pumpkin/src/block/blocks/fire/fire.rs b/pumpkin/src/block/blocks/fire/fire.rs index 15f16176d..b1a6bc957 100644 --- a/pumpkin/src/block/blocks/fire/fire.rs +++ b/pumpkin/src/block/blocks/fire/fire.rs @@ -1,5 +1,5 @@ use pumpkin_data::biome::Biome; -use pumpkin_data::block_properties::{BlockProperties, EnumVariants, HorizontalAxis}; +use pumpkin_data::block_properties::{BlockProperties, HorizontalAxis}; use pumpkin_data::dimension::Dimension; use pumpkin_data::fluid::Fluid; use pumpkin_data::tag::{self, Taggable}; @@ -152,7 +152,7 @@ impl FireBlock { ) } - async fn try_spreading_fire(&self, world: &Arc, pos: &BlockPos, chance: i32, age: u16) { + async fn try_spreading_fire(&self, world: &Arc, pos: &BlockPos, chance: i32, age: u8) { let block = world.get_block(pos).await; let odds = Self::get_burn_odds(block); if rand::rng().random_range(0..chance) < odds { @@ -160,12 +160,12 @@ impl FireBlock { if rand::rng().random_range(0..(age + 10) as i32) < 5 && !Self::is_near_rain(world.as_ref(), pos) { - let new_age = (age + (rand::rng().random_range(0..5) / 4)).min(15); + let new_age = (age + (rand::rng().random_range(0..5) / 4)).min(15) as u8; let state_id = self .get_state_for_position(world.as_ref(), &Block::FIRE, pos) .await; let mut fire_props = FireProperties::from_state_id(state_id, &Block::FIRE); - fire_props.age = EnumVariants::from_index(new_age); + fire_props.age = new_age; let new_state_id = fire_props.to_state_id(&Block::FIRE); world .set_block_state(pos, new_state_id, BlockFlags::NOTIFY_NEIGHBORS) @@ -244,7 +244,7 @@ impl BlockBehaviour for FireBlock { .get_state_for_position(args.world, &Block::FIRE, args.position) .await; let mut fire_props = FireProperties::from_state_id(fire_state_id, &Block::FIRE); - fire_props.age = EnumVariants::from_index(old_fire_props.age.to_index()); + fire_props.age = old_fire_props.age; return fire_props.to_state_id(&Block::FIRE); } Block::AIR.default_state.id @@ -323,7 +323,7 @@ impl BlockBehaviour for FireBlock { }; let mut fire_props = FireProperties::from_state_id(block_state.id, &Block::FIRE); - let age = fire_props.age.to_index(); + let age = fire_props.age; // Check if rain should extinguish the fire if !infiniburn && Self::is_near_rain(world.as_ref(), pos) { @@ -341,10 +341,10 @@ impl BlockBehaviour for FireBlock { } // Increment age - let random = rand::rng().random_range(0..3) / 2; + let random = (rand::rng().random_range(0..3) / 2) as u8; let new_age = (age + random).min(15); if new_age != age { - fire_props.age = EnumVariants::from_index(new_age); + fire_props.age = new_age; let new_state_id = fire_props.to_state_id(&Block::FIRE); world .set_block_state(pos, new_state_id, BlockFlags::NOTIFY_NEIGHBORS) @@ -481,14 +481,15 @@ impl BlockBehaviour for FireBlock { && rand::rng().random_range(0..rate) <= odds && !Self::is_near_rain(world.as_ref(), &offset_pos) { - let spread_age = - (new_age + rand::rng().random_range(0..5) / 4).min(15); + let spread_age = (new_age + rand::rng().random_range(0..5) / 4) + .min(15) + as u8; let fire_state_id = self .get_state_for_position(world.as_ref(), block, &offset_pos) .await; let mut new_fire_props = FireProperties::from_state_id(fire_state_id, &Block::FIRE); - new_fire_props.age = EnumVariants::from_index(spread_age); + new_fire_props.age = spread_age; world .set_block_state( diff --git a/pumpkin/src/block/blocks/note.rs b/pumpkin/src/block/blocks/note.rs index d0f94972d..eba56b3c6 100644 --- a/pumpkin/src/block/blocks/note.rs +++ b/pumpkin/src/block/blocks/note.rs @@ -7,7 +7,7 @@ use pumpkin_data::block_properties::{Axis, NoteblockInstrument}; use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::{ Block, - block_properties::{BlockProperties, EnumVariants, Integer0To24, NoteBlockLikeProperties}, + block_properties::{BlockProperties, NoteBlockLikeProperties}, }; use pumpkin_macros::pumpkin_block; use pumpkin_util::math::position::BlockPos; @@ -85,13 +85,7 @@ impl BlockBehaviour for NoteBlock { Box::pin(async move { let block_state = args.world.get_block_state(args.position).await; let mut note_props = NoteBlockLikeProperties::from_state_id(block_state.id, args.block); - let next_index = note_props.note.to_index() + 1; - // Increment and check if max - note_props.note = if next_index >= Integer0To24::variant_count() { - Integer0To24::from_index(0) - } else { - Integer0To24::from_index(next_index) - }; + note_props.note = (note_props.note + 1) % 25; args.world .set_block_state( args.position, @@ -125,7 +119,7 @@ impl BlockBehaviour for NoteBlock { let instrument = note_props.instrument; let pitch = if is_base_block(instrument) { // checks if can be pitched - Self::get_note_pitch(note_props.note.to_index()) + Self::get_note_pitch(u16::from(note_props.note)) } else { 1.0 // default pitch }; diff --git a/pumpkin/src/block/blocks/plant/bamboo.rs b/pumpkin/src/block/blocks/plant/bamboo.rs index 87f0eec29..6053302eb 100644 --- a/pumpkin/src/block/blocks/plant/bamboo.rs +++ b/pumpkin/src/block/blocks/plant/bamboo.rs @@ -1,8 +1,6 @@ use std::sync::Arc; -use pumpkin_data::block_properties::{ - BambooLeaves, BambooLikeProperties, BlockProperties, EnumVariants, Integer0To1, -}; +use pumpkin_data::block_properties::{BambooLeaves, BambooLikeProperties, BlockProperties}; use pumpkin_data::item::Item; use pumpkin_data::tag::Block::MINECRAFT_SUPPORTS_BAMBOO; use pumpkin_data::tag::Taggable; @@ -44,8 +42,8 @@ impl BlockBehaviour for BambooBlock { } else if block_below == &Block::BAMBOO { let props_below = BambooLikeProperties::from_state_id(state_id_below, block_below); - if props_below.age.to_index() > 0 { - props.age = Integer0To1::L1; + if props_below.age > 0 { + props.age = 1; } } else { let (block_above, state_id_above) = @@ -119,10 +117,10 @@ impl BlockBehaviour for BambooBlock { let neighbor_props = BambooLikeProperties::from_state_id(args.neighbor_state_id, neighbor_block); let mut props = BambooLikeProperties::from_state_id(args.state_id, args.block); - if neighbor_props.age.to_index() > props.age.to_index() { + if neighbor_props.age > props.age { props.age = match props.age { - Integer0To1::L0 => Integer0To1::L1, - Integer0To1::L1 => Integer0To1::L0, + 0 => 1, + _ => 0, }; return props.to_state_id(args.block); } @@ -153,7 +151,7 @@ async fn update_leaves_and_grow(world: Arc, position: &BlockPos) { } let mut props = BambooLikeProperties::from_state_id(state_id, block); - if props.stage != Integer0To1::L0 { + if props.stage != 0 { return; } @@ -200,18 +198,11 @@ async fn update_leaves_and_grow(world: Arc, position: &BlockPos) { } } - props.age = if props.age != Integer0To1::L1 && block_two_below == &Block::BAMBOO { - Integer0To1::L0 - } else { - Integer0To1::L1 - }; + props.age = u8::from(!(props.age != 1 && block_two_below == &Block::BAMBOO)); - props.stage = - if (bamboo_count < 11 || rand::rng().random::() >= 0.25) && bamboo_count != 15 { - Integer0To1::L0 - } else { - Integer0To1::L1 - }; + props.stage = u8::from( + !((bamboo_count < 11 || rand::rng().random::() >= 0.25) && bamboo_count != 15), + ); world .set_block_state(&above_pos, props.to_state_id(block), BlockFlags::NOTIFY_ALL) @@ -265,7 +256,7 @@ async fn bone_meal(world: Arc, position: &BlockPos) { } let next_props = BambooLikeProperties::from_state_id(next_state.id, &Block::BAMBOO); - if next_props.stage == Integer0To1::L1 { + if next_props.stage == 1 { return; } diff --git a/pumpkin/src/block/blocks/plant/cactus.rs b/pumpkin/src/block/blocks/plant/cactus.rs index c8a8e138a..1a950f1d7 100644 --- a/pumpkin/src/block/blocks/plant/cactus.rs +++ b/pumpkin/src/block/blocks/plant/cactus.rs @@ -1,6 +1,4 @@ -use pumpkin_data::block_properties::{ - BlockProperties, CactusLikeProperties, EnumVariants, Integer0To15, -}; +use pumpkin_data::block_properties::{BlockProperties, CactusLikeProperties}; use pumpkin_data::damage::DamageType; use pumpkin_data::tag::Taggable; use pumpkin_data::{Block, BlockDirection, tag}; @@ -40,12 +38,12 @@ impl BlockBehaviour for CactusBlock { let mut i = 1; while args.world.get_block(&args.position.down_height(i)).await == &Block::CACTUS { i += 1; - if 1 == 3 && age == Integer0To15::L15 { + if 1 == 3 && age == 15 { return; } } - if age == Integer0To15::L8 && can_place_at(args.world.as_ref(), &block_up).await { + if age == 8 && can_place_at(args.world.as_ref(), &block_up).await { let d = if i >= 3 { 0.25 } else { 0.1 }; if rand::rng().random_range(0.0..1.0) <= d { args.world @@ -56,7 +54,7 @@ impl BlockBehaviour for CactusBlock { ) .await; } - } else if age == Integer0To15::L15 && i < 3 { + } else if age == 15 && i < 3 { args.world .set_block_state( &block_up, @@ -65,7 +63,7 @@ impl BlockBehaviour for CactusBlock { ) .await; let mut new_props = CactusLikeProperties::default(&Block::CACTUS); - new_props.age = Integer0To15::L0; + new_props.age = 0; args.world .set_block_state( args.position, @@ -77,8 +75,8 @@ impl BlockBehaviour for CactusBlock { .update_neighbor(args.position, &Block::CACTUS) .await; } - if age.to_index() < 15 { - props.age = Integer0To15::from_index(age.to_index() + 1); + if age < 15 { + props.age = age + 1; args.world .set_block_state( args.position, diff --git a/pumpkin/src/block/blocks/plant/crop/beetroot.rs b/pumpkin/src/block/blocks/plant/crop/beetroot.rs index fed58be93..454f7e115 100644 --- a/pumpkin/src/block/blocks/plant/crop/beetroot.rs +++ b/pumpkin/src/block/blocks/plant/crop/beetroot.rs @@ -1,7 +1,5 @@ use pumpkin_data::Block; -use pumpkin_data::block_properties::{ - BlockProperties, EnumVariants, Integer0To3, NetherWartLikeProperties, -}; +use pumpkin_data::block_properties::{BlockProperties, NetherWartLikeProperties}; use pumpkin_macros::pumpkin_block; use pumpkin_world::BlockStateId; use rand::RngExt; @@ -62,12 +60,12 @@ impl CropBlockBase for BeetrootBlock { fn get_age(&self, state: u16, block: &Block) -> i32 { let props = BeetrootProperties::from_state_id(state, block); - i32::from(props.age.to_index()) + i32::from(props.age) } fn state_with_age(&self, block: &Block, state: u16, age: i32) -> BlockStateId { let mut props = BeetrootProperties::from_state_id(state, block); - props.age = Integer0To3::from_index(age as u16); + props.age = age as u8; props.to_state_id(block) } } diff --git a/pumpkin/src/block/blocks/plant/crop/gourds/attached_stem.rs b/pumpkin/src/block/blocks/plant/crop/gourds/attached_stem.rs index 9e5a7b88e..cb540bb34 100644 --- a/pumpkin/src/block/blocks/plant/crop/gourds/attached_stem.rs +++ b/pumpkin/src/block/blocks/plant/crop/gourds/attached_stem.rs @@ -1,8 +1,6 @@ use pumpkin_data::{ Block, - block_properties::{ - BlockProperties, EnumVariants, Integer0To7, WallTorchLikeProperties, WheatLikeProperties, - }, + block_properties::{BlockProperties, WallTorchLikeProperties, WheatLikeProperties}, tag::{self, Taggable}, }; use pumpkin_util::math::position::BlockPos; @@ -63,7 +61,7 @@ impl BlockBehaviour for AttachedStemBlock { && args.neighbor_state_id != Self::get_gourd(args.block).default_state.id { let mut props = StemProperties::default(Self::get_stem(args.block)); - props.age = Integer0To7::from_index(7); + props.age = 7; return props.to_state_id(Self::get_stem(args.block)); } ::get_state_for_neighbor_update( diff --git a/pumpkin/src/block/blocks/plant/crop/gourds/stem.rs b/pumpkin/src/block/blocks/plant/crop/gourds/stem.rs index a5e4e0ae1..6b2799be8 100644 --- a/pumpkin/src/block/blocks/plant/crop/gourds/stem.rs +++ b/pumpkin/src/block/blocks/plant/crop/gourds/stem.rs @@ -5,9 +5,7 @@ use crate::block::{ }; use pumpkin_data::{ Block, BlockDirection, - block_properties::{ - BlockProperties, EnumVariants, Integer0To7, WallTorchLikeProperties, WheatLikeProperties, - }, + block_properties::{BlockProperties, WallTorchLikeProperties, WheatLikeProperties}, tag, tag::Taggable, }; @@ -35,7 +33,7 @@ impl BlockMetadata for StemBlock { impl StemBlock { fn state_with_age(block: &Block, state: u16, age: i32) -> BlockStateId { let mut props = StemProperties::from_state_id(state, block); - props.age = Integer0To7::from_index(age as u16); + props.age = age as u8; props.to_state_id(block) } @@ -88,7 +86,7 @@ impl BlockBehaviour for StemBlock { if rand::rng().random_range(0..=(25.0 / f).floor() as i32) == 0 { let (block, state) = args.world.get_block_and_state_id(args.position).await; let props = StemProperties::from_state_id(state, block); - let age = i32::from(props.age.to_index()); + let age = i32::from(props.age); if age < 7 { args.world .set_block_state( diff --git a/pumpkin/src/block/blocks/plant/crop/mod.rs b/pumpkin/src/block/blocks/plant/crop/mod.rs index 48596e175..c5c91c9aa 100644 --- a/pumpkin/src/block/blocks/plant/crop/mod.rs +++ b/pumpkin/src/block/blocks/plant/crop/mod.rs @@ -3,9 +3,7 @@ use std::sync::Arc; use pumpkin_data::{ Block, BlockDirection::{East, North, South, West}, - block_properties::{ - BlockProperties, EnumVariants, FarmlandLikeProperties, Integer0To7, WheatLikeProperties, - }, + block_properties::{BlockProperties, FarmlandLikeProperties, WheatLikeProperties}, }; use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use pumpkin_world::{ @@ -43,12 +41,12 @@ trait CropBlockBase: PlantBlockBase { fn get_age(&self, state: u16, block: &Block) -> i32 { let props = CropProperties::from_state_id(state, block); - i32::from(props.age.to_index()) + i32::from(props.age) } fn state_with_age(&self, block: &Block, state: u16, age: i32) -> BlockStateId { let mut props = CropProperties::from_state_id(state, block); - props.age = Integer0To7::from_index(age as u16); + props.age = age as u8; props.to_state_id(block) } @@ -98,7 +96,7 @@ pub async fn get_available_moisture(world: &Arc, pos: &BlockPos, block: & if block == &Block::FARMLAND { local_moisture = 1.0; let props = FarmlandProperties::from_state_id(block_state, block); - if props.moisture != Integer0To7::L0 { + if props.moisture != 0 { local_moisture = 3.0; } } diff --git a/pumpkin/src/block/blocks/plant/crop/nether_wart.rs b/pumpkin/src/block/blocks/plant/crop/nether_wart.rs index 677432b8d..51e01445b 100644 --- a/pumpkin/src/block/blocks/plant/crop/nether_wart.rs +++ b/pumpkin/src/block/blocks/plant/crop/nether_wart.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use pumpkin_data::{ Block, - block_properties::{BlockProperties, EnumVariants, Integer0To3, NetherWartLikeProperties}, + block_properties::{BlockProperties, NetherWartLikeProperties}, tag::{self, Taggable}, }; use pumpkin_macros::pumpkin_block; @@ -75,12 +75,12 @@ impl CropBlockBase for NetherWartBlock { fn get_age(&self, state: u16, block: &Block) -> i32 { let props = NetherWartLikeProperties::from_state_id(state, block); - i32::from(props.age.to_index()) + i32::from(props.age) } fn state_with_age(&self, block: &Block, state: u16, age: i32) -> BlockStateId { let mut props = NetherWartLikeProperties::from_state_id(state, block); - props.age = Integer0To3::from_index(age as u16); + props.age = age as u8; props.to_state_id(block) } diff --git a/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs b/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs index 8af36eee4..c7aa858e6 100644 --- a/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs +++ b/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs @@ -11,7 +11,7 @@ use crate::{ }; use pumpkin_data::{ Block, - block_properties::{BlockProperties, EnumVariants, Integer0To3, NetherWartLikeProperties}, + block_properties::{BlockProperties, NetherWartLikeProperties}, damage::DamageType, entity::EntityType, item::Item, @@ -35,9 +35,9 @@ impl BlockBehaviour for SweetBerryBushBlock { let state_id = args.world.get_block_state_id(args.position).await; let mut props = NetherWartLikeProperties::from_state_id(state_id, args.block); match props.age { - Integer0To3::L2 | Integer0To3::L3 => { - let index = props.age.to_index() as u8; - props.age = Integer0To3::L1; + 2 | 3 => { + let index = props.age; + props.age = 1; let count: u8 = rand::rng().random_range((index - 1)..=(index)); for _ in 0..count { args.world @@ -68,9 +68,7 @@ impl BlockBehaviour for SweetBerryBushBlock { Box::pin(async move { let state_id = args.world.get_block_state_id(args.position).await; let props = NetherWartLikeProperties::from_state_id(state_id, &Block::SWEET_BERRY_BUSH); - if props.age != Integer0To3::L3 - && args.item_stack.lock().await.get_item() == &Item::BONE_MEAL - { + if props.age != 3 && args.item_stack.lock().await.get_item() == &Item::BONE_MEAL { BlockActionResult::Pass } else { BlockActionResult::PassToDefaultBlockAction @@ -123,7 +121,7 @@ impl BlockBehaviour for SweetBerryBushBlock { let state_id = args.world.get_block_state_id(args.position).await; let props = NetherWartLikeProperties::from_state_id(state_id, args.block); - if props.age == Integer0To3::L0 { + if props.age == 0 { return; } @@ -177,12 +175,12 @@ impl CropBlockBase for SweetBerryBushBlock { fn get_age(&self, state: u16, block: &Block) -> i32 { let props = NetherWartLikeProperties::from_state_id(state, block); - i32::from(props.age.to_index()) + i32::from(props.age) } fn state_with_age(&self, block: &Block, state: u16, age: i32) -> BlockStateId { let mut props = NetherWartLikeProperties::from_state_id(state, block); - props.age = Integer0To3::from_index(age as u16); + props.age = age as u8; props.to_state_id(block) } diff --git a/pumpkin/src/block/blocks/plant/crop/torch_flower.rs b/pumpkin/src/block/blocks/plant/crop/torch_flower.rs index eb5815fc3..9a0b30cfa 100644 --- a/pumpkin/src/block/blocks/plant/crop/torch_flower.rs +++ b/pumpkin/src/block/blocks/plant/crop/torch_flower.rs @@ -1,7 +1,5 @@ use pumpkin_data::Block; -use pumpkin_data::block_properties::{ - BlockProperties, EnumVariants, Integer0To1, TorchflowerCropLikeProperties, -}; +use pumpkin_data::block_properties::{BlockProperties, TorchflowerCropLikeProperties}; use pumpkin_macros::pumpkin_block; use pumpkin_world::BlockStateId; use rand::RngExt; @@ -62,13 +60,13 @@ impl CropBlockBase for TorchFlowerBlock { fn get_age(&self, state: u16, block: &Block) -> i32 { let props = TorchFlowerProperties::from_state_id(state, block); - i32::from(props.age.to_index()) + i32::from(props.age) } fn state_with_age(&self, block: &Block, state: u16, age: i32) -> BlockStateId { if age == 1 { let mut properties = TorchFlowerProperties::from_state_id(state, block); - properties.age = Integer0To1::L1; + properties.age = 1; properties.to_state_id(block) } else { Block::TORCHFLOWER.default_state.id diff --git a/pumpkin/src/block/blocks/plant/kelp.rs b/pumpkin/src/block/blocks/plant/kelp.rs index 099d3c307..bb93b8421 100644 --- a/pumpkin/src/block/blocks/plant/kelp.rs +++ b/pumpkin/src/block/blocks/plant/kelp.rs @@ -93,7 +93,7 @@ impl PlantBlockBase for KelpBlock { WaterLikeProperties::from_state_id(replacing_block_state.id, replacing_block); //Only allow placing kelp on either full water or downward flowing water - if water_props.level as u8 != 0 && water_props.level as u8 != 8 { + if water_props.level != 0 && water_props.level != 8 { return false; } } else { diff --git a/pumpkin/src/block/blocks/plant/sapling.rs b/pumpkin/src/block/blocks/plant/sapling.rs index d50e08852..12c547279 100644 --- a/pumpkin/src/block/blocks/plant/sapling.rs +++ b/pumpkin/src/block/blocks/plant/sapling.rs @@ -1,4 +1,4 @@ -use pumpkin_data::block_properties::{BlockProperties, Integer0To1}; +use pumpkin_data::block_properties::BlockProperties; use pumpkin_macros::pumpkin_block_from_tag; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; @@ -20,8 +20,8 @@ impl SaplingBlock { async fn generate(&self, world: &Arc, pos: &BlockPos) { let (block, state) = world.get_block_and_state_id(pos).await; let mut props = SaplingProperties::from_state_id(state, block); - if props.stage == Integer0To1::L0 { - props.stage = Integer0To1::L1; + if props.stage == 0 { + props.stage = 1; world .set_block_state(pos, props.to_state_id(block), BlockFlags::NOTIFY_ALL) .await; diff --git a/pumpkin/src/block/blocks/plant/sea_pickles.rs b/pumpkin/src/block/blocks/plant/sea_pickles.rs index b35c1ea25..995572583 100644 --- a/pumpkin/src/block/blocks/plant/sea_pickles.rs +++ b/pumpkin/src/block/blocks/plant/sea_pickles.rs @@ -6,7 +6,7 @@ use crate::block::{ }; use crate::block::{BlockFuture, BlockIsReplacing}; use crate::entity::EntityBase; -use pumpkin_data::block_properties::{BlockProperties, Integer1To4}; +use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::entity::EntityPose; use pumpkin_data::item::Item; use pumpkin_data::tag::Taggable; @@ -73,12 +73,7 @@ impl BlockBehaviour for SeaPickleBlock { } let mut sea_pickle_prop = SeaPickleProperties::default(args.block); - sea_pickle_prop.pickles = match rand::rng().random_range(0..4) + 1 { - 1 => Integer1To4::L1, - 2 => Integer1To4::L2, - 3 => Integer1To4::L3, - _ => Integer1To4::L4, - }; + sea_pickle_prop.pickles = rand::rng().random_range(1..=4); args.world .set_block_state( &lv, @@ -98,7 +93,7 @@ impl BlockBehaviour for SeaPickleBlock { count += 1; } let mut sea_pickle_prop = SeaPickleProperties::default(args.block); - sea_pickle_prop.pickles = Integer1To4::L4; + sea_pickle_prop.pickles = 4; args.world .set_block_state( args.position, @@ -117,12 +112,8 @@ impl BlockBehaviour for SeaPickleBlock { && let BlockIsReplacing::Itself(state_id) = args.replacing { let mut sea_pickle_prop = SeaPickleProperties::from_state_id(state_id, args.block); - if sea_pickle_prop.pickles != Integer1To4::L4 { - sea_pickle_prop.pickles = match sea_pickle_prop.pickles { - Integer1To4::L1 => Integer1To4::L2, - Integer1To4::L2 => Integer1To4::L3, - _ => Integer1To4::L4, - }; + if sea_pickle_prop.pickles < 4 { + sea_pickle_prop.pickles += 1; } return sea_pickle_prop.to_state_id(args.block); } @@ -146,8 +137,7 @@ impl BlockBehaviour for SeaPickleBlock { fn can_update_at<'a>(&'a self, args: CanUpdateAtArgs<'a>) -> BlockFuture<'a, bool> { Box::pin(async move { args.player.get_entity().pose.load() != EntityPose::Crouching - && SeaPickleProperties::from_state_id(args.state_id, args.block).pickles - != Integer1To4::L4 + && SeaPickleProperties::from_state_id(args.state_id, args.block).pickles < 4 }) } diff --git a/pumpkin/src/block/blocks/plant/segmented.rs b/pumpkin/src/block/blocks/plant/segmented.rs index bec1013c9..47680a897 100644 --- a/pumpkin/src/block/blocks/plant/segmented.rs +++ b/pumpkin/src/block/blocks/plant/segmented.rs @@ -1,12 +1,12 @@ -use pumpkin_data::block_properties::{BlockProperties, HorizontalFacing, Integer1To4}; +use pumpkin_data::block_properties::{BlockProperties, HorizontalFacing}; use pumpkin_world::BlockStateId; use crate::block::{BlockBehaviour, BlockFuture, CanUpdateAtArgs}; use crate::block::{BlockIsReplacing, OnPlaceArgs}; pub trait SegmentProperties { - fn get_segment_amount(&self) -> Integer1To4; - fn set_segment_amount(&mut self, amount: Integer1To4); + fn get_segment_amount(&self) -> u8; + fn set_segment_amount(&mut self, amount: u8); fn get_facing(&self) -> HorizontalFacing; fn set_facing(&mut self, facing: HorizontalFacing); } @@ -14,11 +14,11 @@ pub trait SegmentProperties { macro_rules! impl_segment_properties { ($type:ty, $amount_field:ident) => { impl SegmentProperties for $type { - fn get_segment_amount(&self) -> Integer1To4 { + fn get_segment_amount(&self) -> u8 { self.$amount_field } - fn set_segment_amount(&mut self, amount: Integer1To4) { + fn set_segment_amount(&mut self, amount: u8) { self.$amount_field = amount; } @@ -46,28 +46,23 @@ pub trait Segmented: BlockBehaviour { type Properties: BlockProperties + SegmentProperties; fn can_add_segment(&self, props: &Self::Properties) -> bool { - let amount = props.get_segment_amount(); - matches!(amount, Integer1To4::L1 | Integer1To4::L2 | Integer1To4::L3) + props.get_segment_amount() < 4 } - fn get_next_segment_amount(&self, current: Integer1To4) -> Integer1To4 { - match current { - Integer1To4::L1 => Integer1To4::L2, - Integer1To4::L2 => Integer1To4::L3, - Integer1To4::L3 | Integer1To4::L4 => Integer1To4::L4, - } + fn get_next_segment_amount(&self, current: u8) -> u8 { + (current + 1).min(4) } fn get_facing_for_segment( &self, player_facing: HorizontalFacing, - segment_amount: Integer1To4, + segment_amount: u8, ) -> HorizontalFacing { let base_facing = match segment_amount { - Integer1To4::L1 => HorizontalFacing::South, - Integer1To4::L2 => HorizontalFacing::East, - Integer1To4::L3 => HorizontalFacing::North, - Integer1To4::L4 => HorizontalFacing::West, + 1 => HorizontalFacing::South, + 2 => HorizontalFacing::East, + 3 => HorizontalFacing::North, + _ => HorizontalFacing::West, }; match player_facing { @@ -102,8 +97,8 @@ pub trait Segmented: BlockBehaviour { // Set first segment orientation based on player direction let player_facing = args.player.living_entity.entity.get_horizontal_facing(); let mut props = Self::Properties::default(args.block); - props.set_segment_amount(Integer1To4::L1); - props.set_facing(self.get_facing_for_segment(player_facing, Integer1To4::L1)); + props.set_segment_amount(1); + props.set_facing(self.get_facing_for_segment(player_facing, 1)); props.to_state_id(args.block) } }) diff --git a/pumpkin/src/block/blocks/plant/sugar_cane.rs b/pumpkin/src/block/blocks/plant/sugar_cane.rs index 032fe4621..4412e7a0e 100644 --- a/pumpkin/src/block/blocks/plant/sugar_cane.rs +++ b/pumpkin/src/block/blocks/plant/sugar_cane.rs @@ -2,7 +2,7 @@ use pumpkin_data::block_properties::HorizontalFacing; use pumpkin_data::tag::Taggable; use pumpkin_data::{ Block, - block_properties::{BlockProperties, CactusLikeProperties, EnumVariants, Integer0To15}, + block_properties::{BlockProperties, CactusLikeProperties}, tag, }; use pumpkin_macros::pumpkin_block; @@ -43,13 +43,11 @@ impl BlockBehaviour for SugarCaneBlock { { let state_id = args.world.get_block_state(args.position).await.id; let age = CactusLikeProperties::from_state_id(state_id, args.block).age; - if age == Integer0To15::L15 { + if age == 15 { args.world .set_block_state(&args.position.up(), state_id, BlockFlags::empty()) .await; - let props = CactusLikeProperties { - age: Integer0To15::L0, - }; + let props = CactusLikeProperties { age: 0 }; args.world .set_block_state( args.position, @@ -58,9 +56,7 @@ impl BlockBehaviour for SugarCaneBlock { ) .await; } else { - let props = CactusLikeProperties { - age: Integer0To15::from_index(age.to_index() + 1), - }; + let props = CactusLikeProperties { age: age + 1 }; args.world .set_block_state( args.position, diff --git a/pumpkin/src/block/blocks/redstone/abstract_redstone_gate.rs b/pumpkin/src/block/blocks/redstone/abstract_redstone_gate.rs index 99a374e09..96e17562f 100644 --- a/pumpkin/src/block/blocks/redstone/abstract_redstone_gate.rs +++ b/pumpkin/src/block/blocks/redstone/abstract_redstone_gate.rs @@ -3,8 +3,8 @@ use std::sync::Arc; use pumpkin_data::{ Block, BlockDirection, BlockState, HorizontalFacingExt, block_properties::{ - BlockProperties, ComparatorLikeProperties, EnumVariants, HorizontalFacing, - RedstoneWireLikeProperties, RepeaterLikeProperties, + BlockProperties, ComparatorLikeProperties, HorizontalFacing, RedstoneWireLikeProperties, + RepeaterLikeProperties, }, }; use pumpkin_util::math::position::BlockPos; @@ -300,7 +300,7 @@ pub async fn get_power( } else { source_level.max(if source_block == &Block::REDSTONE_WIRE { let props = RedstoneWireLikeProperties::from_state_id(source_state.id, source_block); - props.power.to_index() as u8 + props.power } else { 0 }) diff --git a/pumpkin/src/block/blocks/redstone/daylight_detector.rs b/pumpkin/src/block/blocks/redstone/daylight_detector.rs index 51fee867a..f99153c0c 100644 --- a/pumpkin/src/block/blocks/redstone/daylight_detector.rs +++ b/pumpkin/src/block/blocks/redstone/daylight_detector.rs @@ -1,9 +1,6 @@ use std::sync::Arc; -use pumpkin_data::{ - Block, - block_properties::{BlockProperties, EnumVariants}, -}; +use pumpkin_data::{Block, block_properties::BlockProperties}; use pumpkin_macros::pumpkin_block; use pumpkin_util::math::position::BlockPos; use pumpkin_world::block::entities::daylight_detector::DaylightDetectorBlockEntity; @@ -61,7 +58,7 @@ impl BlockBehaviour for DaylightDetectorBlock { Box::pin(async move { let props = DaylightDetectorProperties::from_state_id(args.state.id, args.block); - props.power.to_index() as u8 + props.power }) } diff --git a/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs b/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs index 350b5ce6f..d384787d5 100644 --- a/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs +++ b/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs @@ -1,7 +1,4 @@ -use pumpkin_data::{ - Block, BlockDirection, BlockState, - block_properties::{BlockProperties, EnumVariants, Integer0To15}, -}; +use pumpkin_data::{Block, BlockDirection, BlockState, block_properties::BlockProperties}; use pumpkin_util::math::{boundingbox::BoundingBox, position::BlockPos}; use pumpkin_world::{BlockStateId, world::BlockFlags}; @@ -98,7 +95,7 @@ impl BlockBehaviour for WeightedPressurePlateBlock { impl PressurePlate for WeightedPressurePlateBlock { fn get_redstone_output(&self, block: &Block, state: BlockStateId) -> u8 { let props = PressurePlateProps::from_state_id(state, block); - props.power.to_index() as u8 + props.power } async fn calculate_redstone_output(&self, world: &World, block: &Block, pos: &BlockPos) -> u8 { @@ -129,7 +126,7 @@ impl PressurePlate for WeightedPressurePlateBlock { output: u8, ) -> pumpkin_world::BlockStateId { let mut props = PressurePlateProps::from_state_id(state.id, block); - props.power = Integer0To15::from_index(u16::from(output)); + props.power = output; props.to_state_id(block) } diff --git a/pumpkin/src/block/blocks/redstone/redstone_wire.rs b/pumpkin/src/block/blocks/redstone/redstone_wire.rs index 6f4c336d0..1d529ffd3 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_wire.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_wire.rs @@ -1,9 +1,8 @@ use std::sync::Arc; use pumpkin_data::block_properties::{ - BlockProperties, EastRedstone, EnumVariants, Integer0To15, NorthRedstone, - ObserverLikeProperties, RedstoneWireLikeProperties, RepeaterLikeProperties, SouthRedstone, - WestRedstone, + BlockProperties, EastRedstone, NorthRedstone, ObserverLikeProperties, + RedstoneWireLikeProperties, RepeaterLikeProperties, SouthRedstone, WestRedstone, }; use pumpkin_data::{Block, BlockDirection, BlockState, HorizontalFacingExt}; use pumpkin_macros::pumpkin_block; @@ -37,8 +36,7 @@ impl BlockBehaviour for RedstoneWireBlock { fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> { Box::pin(async move { let mut wire = RedstoneWireProperties::default(args.block); - wire.power = - Integer0To15::from_index(calculate_power(args.world, args.position).await.into()); + wire.power = calculate_power(args.world, args.position).await; wire = get_regulated_sides(wire, args.world, args.position).await; if is_dot(wire) { wire = make_cross(wire.power); @@ -89,8 +87,7 @@ impl BlockBehaviour for RedstoneWireBlock { } wire = get_regulated_sides(wire, args.world, args.position).await; - wire.power = - Integer0To15::from_index(calculate_power(args.world, args.position).await.into()); + wire.power = calculate_power(args.world, args.position).await; if is_cross(old_state) && new_side.is_none() { return wire.to_state_id(args.block); @@ -177,8 +174,8 @@ impl BlockBehaviour for RedstoneWireBlock { let state = args.world.get_block_state(args.position).await; let mut wire = RedstoneWireProperties::from_state_id(state.id, args.block); let new_power = calculate_power(args.world, args.position).await; - if wire.power.to_index() as u8 != new_power { - wire.power = Integer0To15::from_index(new_power.into()); + if wire.power != new_power { + wire.power = new_power; args.world .set_block_state( args.position, @@ -206,7 +203,7 @@ impl BlockBehaviour for RedstoneWireBlock { if args.direction == BlockDirection::Up || wire.is_side_connected(args.direction.opposite()) { - wire.power.to_index() as u8 + wire.power } else { 0 } @@ -222,7 +219,7 @@ impl BlockBehaviour for RedstoneWireBlock { if args.direction == BlockDirection::Up || wire.is_side_connected(args.direction.opposite()) { - wire.power.to_index() as u8 + wire.power } else { 0 } @@ -273,7 +270,7 @@ async fn on_use(wire: RedstoneWireProperties, world: &Arc, block_pos: &Bl } #[must_use] -pub const fn make_cross(power: Integer0To15) -> RedstoneWireProperties { +pub const fn make_cross(power: u8) -> RedstoneWireProperties { RedstoneWireProperties { north: NorthRedstone::Side, south: SouthRedstone::Side, @@ -529,7 +526,7 @@ async fn max_wire_power(wire_power: u8, world: &World, pos: BlockPos) -> u8 { let (block, block_state) = world.get_block_and_state(&pos).await; if block == &Block::REDSTONE_WIRE { let wire = RedstoneWireProperties::from_state_id(block_state.id, block); - wire_power.max(wire.power.to_index() as u8) + wire_power.max(wire.power) } else { wire_power } diff --git a/pumpkin/src/block/blocks/redstone/repeater.rs b/pumpkin/src/block/blocks/redstone/repeater.rs index 468feb604..648d3436f 100644 --- a/pumpkin/src/block/blocks/redstone/repeater.rs +++ b/pumpkin/src/block/blocks/redstone/repeater.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use pumpkin_data::{ Block, BlockDirection, BlockState, HorizontalFacingExt, - block_properties::{BlockProperties, EnumVariants, HorizontalFacing, Integer1To4}, + block_properties::{BlockProperties, HorizontalFacing}, }; use pumpkin_macros::pumpkin_block; use pumpkin_util::math::position::BlockPos; @@ -275,7 +275,7 @@ impl RedstoneGateBlock for RepeaterBlock { fn get_update_delay_internal(&self, state_id: BlockStateId, block: &Block) -> u8 { let props = RepeaterProperties::from_state_id(state_id, block); - (props.delay.to_index() as u8 + 1) * 2 + props.delay * 2 } } @@ -288,12 +288,7 @@ impl RepeaterBlock { block: &Block, ) { let mut props = props; - props.delay = match props.delay { - Integer1To4::L1 => Integer1To4::L2, - Integer1To4::L2 => Integer1To4::L3, - Integer1To4::L3 => Integer1To4::L4, - Integer1To4::L4 => Integer1To4::L1, - }; + props.delay = if props.delay == 4 { 1 } else { props.delay + 1 }; let state = props.to_state_id(block); world .set_block_state(&block_pos, state, BlockFlags::empty()) diff --git a/pumpkin/src/block/blocks/redstone/turbo.rs b/pumpkin/src/block/blocks/redstone/turbo.rs index fbccb5b57..2c4f33358 100644 --- a/pumpkin/src/block/blocks/redstone/turbo.rs +++ b/pumpkin/src/block/blocks/redstone/turbo.rs @@ -4,7 +4,7 @@ use pumpkin_data::{ Block, BlockDirection, BlockState, - block_properties::{BlockProperties, EnumVariants, Integer0To15, RedstoneWireLikeProperties}, + block_properties::{BlockProperties, RedstoneWireLikeProperties}, }; use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use pumpkin_world::world::BlockFlags; @@ -402,8 +402,8 @@ impl RedstoneWireTurbo { if wire_power > j { j = wire_power; } - if i.to_index() as u8 != j { - wire.power = Integer0To15::from_index(j.into()); + if i != j { + wire.power = j; world .set_block_state( &pos, @@ -419,7 +419,7 @@ impl RedstoneWireTurbo { let node = &self.nodes[upd.index]; let block = Block::from_state_id(node.state.id); if block == &Block::REDSTONE_WIRE { - (unwrap_wire(node.state).power.to_index() as u8).max(strength) + unwrap_wire(node.state).power.max(strength) } else { strength } diff --git a/pumpkin/src/block/blocks/signs.rs b/pumpkin/src/block/blocks/signs.rs index 284d89e8d..fd8e234a7 100644 --- a/pumpkin/src/block/blocks/signs.rs +++ b/pumpkin/src/block/blocks/signs.rs @@ -4,7 +4,6 @@ use std::sync::atomic::Ordering; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::EnumVariants; -use pumpkin_data::block_properties::Integer0To15; use pumpkin_data::tag::Taggable; use pumpkin_inventory::screen_handler::InventoryPlayer; use pumpkin_macros::pumpkin_block_from_tag; @@ -47,7 +46,7 @@ struct SupportInfo { struct SignPlacement { block_id: u16, facing: Option, - rotation: Option, + rotation: Option, attached: bool, } @@ -113,30 +112,21 @@ impl SignBlock { /// Calculates rotation for wall-hanging signs. fn calculate_wall_hanging_rotation( wall_dir: BlockDirection, - player_rot: Integer0To15, + player_rot: u8, is_sneaking: bool, - ) -> Integer0To15 { + ) -> u8 { if is_sneaking { return player_rot; } - let idx = player_rot.to_index(); match wall_dir { BlockDirection::North | BlockDirection::South => { // Snap to North-South axis (0 or 8) - if (4..12).contains(&idx) { - Integer0To15::from_index(8) - } else { - Integer0To15::from_index(0) - } + if (4..12).contains(&player_rot) { 8 } else { 0 } } BlockDirection::East | BlockDirection::West => { // Snap to East-West axis (4 or 12) - if (2..10).contains(&idx) { - Integer0To15::from_index(4) - } else { - Integer0To15::from_index(12) - } + if (2..10).contains(&player_rot) { 4 } else { 12 } } _ => player_rot, } @@ -205,7 +195,7 @@ impl SignBlock { args: &OnPlaceArgs, support: &SupportInfo, is_sneaking: bool, - ) -> (Option, Option, bool) { + ) -> (Option, Option, bool) { let wall_dir = if args.direction.is_horizontal() { args.direction } else { @@ -218,7 +208,7 @@ impl SignBlock { let player_rot = args.player.get_entity().get_flipped_rotation_16(); let rotation = Self::calculate_wall_hanging_rotation(wall_dir, player_rot, is_sneaking); - let is_angled = rotation.to_index() % 4 != 0; + let is_angled = rotation % 4 != 0; let attached = is_angled || is_sneaking; (Some(facing.to_string()), Some(rotation), attached) @@ -228,37 +218,29 @@ impl SignBlock { fn calculate_ceiling_orientation( args: &OnPlaceArgs, is_sneaking: bool, - ) -> (Option, Option, bool) { + ) -> (Option, Option, bool) { let rotation = if is_sneaking { args.player.get_entity().get_flipped_rotation_16() } else { // Snap to nearest cardinal - let index = args - .player - .get_entity() - .get_flipped_rotation_16() - .to_index(); - Integer0To15::from_index(((index + 2) / 4 * 4) % 16) + let index = args.player.get_entity().get_flipped_rotation_16(); + ((index + 2) / 4 * 4) % 16 }; - let is_angled = rotation.to_index() % 4 != 0; + let is_angled = rotation % 4 != 0; let attached = is_angled || is_sneaking; (None, Some(rotation), attached) } /// Calculates orientation for wall signs. - fn calculate_wall_orientation( - args: &OnPlaceArgs, - ) -> (Option, Option, bool) { + fn calculate_wall_orientation(args: &OnPlaceArgs) -> (Option, Option, bool) { let facing = args.direction.opposite().to_cardinal_direction().to_value(); (Some(facing.to_string()), None, false) } /// Calculates orientation for standing signs. - fn calculate_standing_orientation( - args: &OnPlaceArgs, - ) -> (Option, Option, bool) { + fn calculate_standing_orientation(args: &OnPlaceArgs) -> (Option, Option, bool) { let rotation = args.player.get_entity().get_flipped_rotation_16(); (None, Some(rotation), false) } @@ -279,7 +261,24 @@ impl SignBlock { if let Some(rotation) = placement.rotation && let Some(prop) = props.iter_mut().find(|(k, _)| *k == "rotation") { - prop.1 = rotation.to_value(); + prop.1 = match rotation { + 1 => "1", + 2 => "2", + 3 => "3", + 4 => "4", + 5 => "5", + 6 => "6", + 7 => "7", + 8 => "8", + 9 => "9", + 10 => "10", + 11 => "11", + 12 => "12", + 13 => "13", + 14 => "14", + 15 => "15", + _ => "0", + }; } if let Some(prop) = props.iter_mut().find(|(k, _)| *k == "attached") { @@ -596,7 +595,7 @@ async fn is_facing_front_text( if let Some(props) = block.properties(state_id) { let prop_map = props.to_props(); if let Some((_, val)) = prop_map.iter().find(|(k, _)| k == &"rotation") { - let r = Integer0To15::from_value(val); + let r = val.parse().unwrap_or(0); rotation = get_yaw_from_rotation_16(r); } else if let Some((_, val)) = prop_map.iter().find(|(k, _)| k == &"facing") { rotation = match &val[..] { @@ -618,10 +617,8 @@ async fn is_facing_front_text( diff.abs() <= 90.0 } -fn get_yaw_from_rotation_16(rotation: Integer0To15) -> f32 { - let index = rotation.to_index(); - - f32::from(index) * 22.5 +fn get_yaw_from_rotation_16(rotation: u8) -> f32 { + f32::from(rotation) * 22.5 } fn try_claim_sign( diff --git a/pumpkin/src/block/blocks/snow.rs b/pumpkin/src/block/blocks/snow.rs index 0bf18789f..ffe1ad782 100644 --- a/pumpkin/src/block/blocks/snow.rs +++ b/pumpkin/src/block/blocks/snow.rs @@ -1,9 +1,5 @@ use pumpkin_data::block_properties::BlockProperties; -use pumpkin_data::{ - Block, BlockDirection, - block_properties::{Integer1To8, SnowLikeProperties}, - item::Item, -}; +use pumpkin_data::{Block, BlockDirection, block_properties::SnowLikeProperties, item::Item}; use pumpkin_macros::pumpkin_block; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{ @@ -27,7 +23,7 @@ impl BlockBehaviour for LayeredSnowBlock { return Block::AIR.default_state.id; } let mut props = SnowLikeProperties::default(args.block); - props.layers = Integer1To8::L1; + props.layers = 1; props.to_state_id(&Block::SNOW) }) } @@ -58,25 +54,17 @@ impl BlockBehaviour for LayeredSnowBlock { } let mut props = SnowLikeProperties::from_state_id(state_id, &Block::SNOW); - props.layers = match props.layers { - Integer1To8::L1 => Integer1To8::L2, - Integer1To8::L2 => Integer1To8::L3, - Integer1To8::L3 => Integer1To8::L4, - Integer1To8::L4 => Integer1To8::L5, - Integer1To8::L5 => Integer1To8::L6, - Integer1To8::L6 => Integer1To8::L7, - Integer1To8::L7 => Integer1To8::L8, - Integer1To8::L8 => { - args.world - .set_block_state( - pos, - Block::SNOW_BLOCK.default_state.id, - BlockFlags::NOTIFY_ALL, - ) - .await; - return BlockActionResult::Success; - } - }; + if props.layers >= 8 { + args.world + .set_block_state( + pos, + Block::SNOW_BLOCK.default_state.id, + BlockFlags::NOTIFY_ALL, + ) + .await; + return BlockActionResult::Success; + } + props.layers += 1; let state_id = props.to_state_id(&Block::SNOW); args.world diff --git a/pumpkin/src/block/mod.rs b/pumpkin/src/block/mod.rs index 96489687d..4f9aaf753 100644 --- a/pumpkin/src/block/mod.rs +++ b/pumpkin/src/block/mod.rs @@ -1,4 +1,3 @@ -use pumpkin_data::block_properties::Integer0To15; use pumpkin_data::{Block, BlockState}; use pumpkin_util::math::position::BlockPos; @@ -465,7 +464,7 @@ pub async fn calc_block_breaking( #[derive(PartialEq, Eq, Debug)] pub enum BlockIsReplacing { Itself(BlockStateId), - Water(Integer0To15), + Water(u8), Other, None, } @@ -473,10 +472,10 @@ pub enum BlockIsReplacing { impl BlockIsReplacing { #[must_use] /// Returns true if the block was a water source block. - pub fn water_source(&self) -> bool { + pub const fn water_source(&self) -> bool { match self { // Level 0 means the water is a source block - Self::Water(level) => *level == Integer0To15::L0, + Self::Water(level) => *level == 0, _ => false, } } diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index f21b248e5..e1b49ee3e 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -15,7 +15,7 @@ use living::LivingEntity; use player::Player; use pumpkin_data::BlockState; use pumpkin_data::biome::Biome; -use pumpkin_data::block_properties::{EnumVariants, Integer0To15, blocks_movement}; +use pumpkin_data::block_properties::blocks_movement; use pumpkin_data::data_component_impl::EquipmentSlot; use pumpkin_data::dimension::Dimension; use pumpkin_data::entity::EntityStatus; @@ -2082,33 +2082,14 @@ impl Entity { } } - pub fn get_rotation_16(&self) -> Integer0To15 { + pub fn get_rotation_16(&self) -> u8 { let adjusted_yaw = self.yaw.load().rem_euclid(360.0); - let index = (adjusted_yaw / 22.5).round() as u16 % 16; - - Integer0To15::from_index(index) + ((adjusted_yaw / 22.5).round() as u8) % 16 } - pub fn get_flipped_rotation_16(&self) -> Integer0To15 { - match self.get_rotation_16() { - Integer0To15::L0 => Integer0To15::L8, - Integer0To15::L1 => Integer0To15::L9, - Integer0To15::L2 => Integer0To15::L10, - Integer0To15::L3 => Integer0To15::L11, - Integer0To15::L4 => Integer0To15::L12, - Integer0To15::L5 => Integer0To15::L13, - Integer0To15::L6 => Integer0To15::L14, - Integer0To15::L7 => Integer0To15::L15, - Integer0To15::L8 => Integer0To15::L0, - Integer0To15::L9 => Integer0To15::L1, - Integer0To15::L10 => Integer0To15::L2, - Integer0To15::L11 => Integer0To15::L3, - Integer0To15::L12 => Integer0To15::L4, - Integer0To15::L13 => Integer0To15::L5, - Integer0To15::L14 => Integer0To15::L6, - Integer0To15::L15 => Integer0To15::L7, - } + pub fn get_flipped_rotation_16(&self) -> u8 { + (self.get_rotation_16() + 8) % 16 } pub fn get_facing(&self) -> Facing { diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index df7407066..6ad7cad2c 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -29,7 +29,7 @@ use tracing::{debug, warn}; use uuid::Uuid; use pumpkin_data::attributes::Attributes; -use pumpkin_data::block_properties::{BlockProperties, EnumVariants, HorizontalFacing}; +use pumpkin_data::block_properties::{BlockProperties, HorizontalFacing}; use pumpkin_data::damage::DamageType; use pumpkin_data::data_component_impl::{AttributeModifiersImpl, Operation}; use pumpkin_data::data_component_impl::{EquipmentSlot, EquippableImpl, ToolImpl, WeaponImpl}; @@ -1106,10 +1106,8 @@ impl Player { // Handle respawn anchor (Nether) if block == &Block::RESPAWN_ANCHOR { - use pumpkin_data::block_properties::Integer0To4; - let anchor_props = AnchorProperties::from_state_id(state_id, block); - let charges = anchor_props.charges.to_index(); + let charges = anchor_props.charges; // Anchor needs at least 1 charge to work if charges == 0 { @@ -1121,7 +1119,7 @@ impl Player { // Decrement charges after successful respawn position found let new_charges = charges - 1; let mut new_props = anchor_props; - new_props.charges = Integer0To4::from_index(new_charges); + new_props.charges = new_charges; world .set_block_state( pos, diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index e9fa278cf..95f31b038 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -31,8 +31,6 @@ use pumpkin_protocol::java::client::play::{CChangeDifficulty, CTabList}; use pumpkin_protocol::{ClientPacket, java::client::config::CPluginMessage}; use pumpkin_util::Difficulty; use pumpkin_util::text::TextComponent; -use pumpkin_world::lock::LevelLocker; -use pumpkin_world::lock::anvil::AnvilLevelLocker; use pumpkin_world::world_info::anvil::{ AnvilLevelInfo, LEVEL_DAT_BACKUP_FILE_NAME, LEVEL_DAT_FILE_NAME, }; @@ -124,9 +122,6 @@ pub struct Server { // world stuff which maybe should be put into a struct pub level_info: Arc>, world_info_writer: Arc, - // Gets unlocked when dropped - // TODO: Make this a trait - _locker: Arc>, } impl Server { @@ -167,16 +162,6 @@ impl Server { fs::copy(dat_path, backup_path).unwrap(); } } - let locker = match AnvilLevelLocker::lock(&world_path) { - Ok(l) => Some(l), - Err(err) => { - warn!( - "Could not lock the level file. Data corruption is possible if the world is accessed by multiple processes simultaneously. Error: {err}" - ); - None - } - }; - let level_info = level_info.unwrap_or_else(|err| { warn!("Failed to get level_info, using default instead: {err}"); let default_data = LevelData::default(basic_config.seed); @@ -254,7 +239,6 @@ impl Server { mojang_public_keys: ArcSwap::from_pointee(Vec::new()), world_info_writer: Arc::new(AnvilLevelInfo), level_info, - _locker: Arc::new(locker), }; let server = Arc::new(server);