diff --git a/codegen/src/entity_metadata.rs b/codegen/src/entity_metadata.rs index 3e016b59d..5874075b3 100644 --- a/codegen/src/entity_metadata.rs +++ b/codegen/src/entity_metadata.rs @@ -4,6 +4,7 @@ use proc_macro2::Span; use quote::quote; use std::collections::HashMap; use syn::braced; +use syn::parenthesized; use syn::parse::{Parse, ParseBuffer}; use syn::Error; use syn::Lit; @@ -72,6 +73,7 @@ struct Entry { ty: EntryType, name: Ident, index: u8, + default: Option, } impl Parse for Entry { @@ -80,6 +82,13 @@ impl Parse for Entry { let _ = input.parse::()?; let ty = input.parse()?; + let paren; + parenthesized!(paren in input); + let default = match paren.parse() { + Ok(val) => Some(val), + Err(_) => None, + }; + let _ = input.parse::()?; let index = match input.parse::()? { @@ -89,7 +98,12 @@ impl Parse for Entry { let _ = input.parse::()?; - Ok(Self { ty, name, index }) + Ok(Self { + ty, + name, + index, + default, + }) } } @@ -136,6 +150,7 @@ impl EntryType { } } +#[allow(clippy::cognitive_complexity)] // FIXME: clean this function up pub fn entity_metadata(input: TokenStream) -> TokenStream { let input: EntityMetadata = syn::parse_macro_input!(input); @@ -143,6 +158,7 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { let mut enum_variants = vec![]; let mut to_raw_metadata_arms = vec![]; + let mut to_full_raw_metadata_arms = vec![]; let enum_ident = input.ident.clone(); @@ -154,10 +170,13 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { let mut struct_fields = vec![]; let mut struct_impl = vec![]; let mut to_raw_metadata = vec![]; + let mut to_full_raw_metadata = vec![]; let mut new_fn_parameters = vec![]; let mut new_fn_contents = vec![]; + let mut default_entries = vec![]; + for entry in entries { let entry_ident = entry.name; let ty_enum = entry.ty; @@ -200,6 +219,9 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { self.#is_dirty_ident = false; } }); + to_full_raw_metadata.push(quote! { + #set_expr + }); new_fn_parameters.push(quote! { #entry_ident: #ty_ident @@ -212,7 +234,16 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { to_raw_metadata_arms.push(quote! { #enum_ident::#variant_ident(meta) => meta.to_raw_metadata(), - }) + }); + + to_full_raw_metadata_arms.push(quote! { + #enum_ident::#variant_ident(meta) => meta.to_full_raw_metadata(), + }); + + default_entries.push(match entry.default { + Some(default) => quote! { #entry_ident: #default, #is_dirty_ident: false, }, + None => quote! { #entry_ident: Default::default(), #is_dirty_ident: false, }, + }); } struct_impl.push(quote! { @@ -227,10 +258,16 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { #(#to_raw_metadata)* meta } + + fn to_full_raw_metadata(&self) -> EntityMetadata { + let mut meta = EntityMetadata::new(); + #(#to_full_raw_metadata)* + meta + } }); structs.push(quote! { - #[derive(Clone, Debug, Default)] + #[derive(Clone, Debug)] pub struct #variant_ident { #(#struct_fields)* } @@ -238,6 +275,14 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { impl #variant_ident { #(#struct_impl)* } + + impl Default for #variant_ident { + fn default() -> Self { + Self { + #(#default_entries)* + } + } + } }); enum_variants.push(quote! { @@ -257,6 +302,12 @@ pub fn entity_metadata(input: TokenStream) -> TokenStream { #(#to_raw_metadata_arms)* } } + + pub fn to_full_raw_metadata(&self) -> EntityMetadata { + match self { + #(#to_full_raw_metadata_arms)* + } + } } #(#structs)* diff --git a/server/src/entity/broadcast.rs b/server/src/entity/broadcast.rs index 9e3c39086..950b5700f 100644 --- a/server/src/entity/broadcast.rs +++ b/server/src/entity/broadcast.rs @@ -103,7 +103,7 @@ impl<'a> System<'a> for EntitySendSystem { // Send metadata. let entity_metadata = PacketEntityMetadata { entity_id: request.entity.id() as i32, - metadata: metadata.to_raw_metadata(), + metadata: metadata.to_full_raw_metadata(), }; send_packet_to_player(network, entity_metadata); diff --git a/server/src/entity/metadata.rs b/server/src/entity/metadata.rs index 65120218e..a65fec79f 100644 --- a/server/src/entity/metadata.rs +++ b/server/src/entity/metadata.rs @@ -26,26 +26,26 @@ bitflags! { entity_metadata! { Metadata, Entity { - bit_mask: u8 = 0, - air: VarInt = 1, - silent: bool = 4, - no_gravity: bool = 5, + bit_mask: u8() = 0, + air: VarInt() = 1, + silent: bool() = 4, + no_gravity: bool() = 5, }, Item: Entity { - item: Slot = 6, + item: Slot() = 6, }, Living: Entity { - hand_states: u8 = 6, - health: f32 = 7, - potion_effect_color: VarInt = 8, - potion_effect_ambient: bool = 9, - arrows: VarInt = 10, + hand_states: u8() = 6, + health: f32(1.0) = 7, + potion_effect_color: VarInt() = 8, + potion_effect_ambient: bool() = 9, + arrows: VarInt() = 10, }, Player: Living { - additional_hearts: f32 = 11, - score: VarInt = 12, - displayed_skin_parts: u8 = 13, - main_hand: u8 = 14, + additional_hearts: f32() = 11, + score: VarInt() = 12, + displayed_skin_parts: u8() = 13, + main_hand: u8() = 14, }, }