feat: more item work

This commit is contained in:
Alexander Medvedev 2026-09-02 16:46:58 +02:00
parent 4e614c9eeb
commit 3a3ba2c873
110 changed files with 5501 additions and 817 deletions

View File

@ -85288,7 +85288,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const APPLE : Self = Self { id : 878 , registry_key : "minecraft:apple" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:tags\t\x04tags\x08\x02\x11minecraft:is_food\0\n\x0Fitem_properties\x08\x0Ecreative_group\0\x01\x04foil\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x05apple\0\0\x01\x0Fstacked_by_data\0\x03\x0Cuse_duration@\x03\x0Bframe_count\x02\x03\x06damage\0\x01\rhand_equipped\0\x08\x10enchantable_slot\x04none\x03\x0Emax_stack_size\x80\x01\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x01\x12hidden_in_commands\x02\x03\x11enchantable_value\0\x01\x0Eshould_despawn\x01\x03\ruse_animation\x02\x03\x11creative_category\x04\x01\x0Eallow_off_hand\0\x05\x0Cmining_speed\0\0\x80?\0\n\x16minecraft:display_name\x08\x05value\x0Fitem.apple.name\0\t\titem_tags\x08\x02\x11minecraft:is_food\n\x17minecraft:use_animation\x08\x05value\x03eat\0\n\x0Eminecraft:food\n\x11using_converts_to\0\x03\tnutrition\x08\x01\x0Ecan_always_eat\0\x05\x13saturation_modifier\x9A\x99\x99>\0\n\x17minecraft:use_modifiers\x01\x0Femit_vibrations\x01\x08\x0Bstart_using\x06always\x05\x11movement_modifier33\xB3>\x05\x0Cuse_duration\xCD\xCC\xCC?\0\0\0" } ; pub const APPLE : Self = Self { id : 878 , registry_key : "minecraft:apple" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Fitem_properties\x03\x06damage\0\x05\x0Cmining_speed\0\0\x80?\x03\ruse_animation\x02\x01\rhand_equipped\0\x03\x11enchantable_value\0\x03\x11creative_category\x04\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x05apple\0\0\x08\x0Ecreative_group\0\x01\x0Eliquid_clipped\0\x01\x17can_destroy_in_creative\x01\x03\x0Bframe_count\x02\x01\x0Fstacked_by_data\0\x08\x10enchantable_slot\x04none\x01\x12hidden_in_commands\x02\x03\x0Emax_stack_size\x80\x01\x01\x0Eallow_off_hand\0\x01\x04foil\0\x03\x0Cuse_duration@\0\n\x0Eminecraft:food\x05\x13saturation_modifier\x9A\x99\x99>\n\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x03\tnutrition\x08\0\t\titem_tags\x08\x02\x11minecraft:is_food\n\x17minecraft:use_modifiers\x01\x0Femit_vibrations\x01\x05\x0Cuse_duration\xCD\xCC\xCC?\x08\x0Bstart_using\x06always\x05\x11movement_modifier33\xB3>\0\n\x17minecraft:use_animation\x08\x05value\x03eat\0\n\x0Eminecraft:tags\t\x04tags\x08\x02\x11minecraft:is_food\0\n\x16minecraft:display_name\x08\x05value\x0Fitem.apple.name\0\0\0" } ;
pub const ARCHER_POTTERY_SHERD: Self = Self { pub const ARCHER_POTTERY_SHERD: Self = Self {
id: 671, id: 671,
registry_key: "minecraft:archer_pottery_sherd", registry_key: "minecraft:archer_pottery_sherd",
@ -85373,7 +85373,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BAKED_POTATO : Self = Self { id : 281 , registry_key : "minecraft:baked_potato" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\x03\tnutrition\n\x03\rcooldown_time\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x19?\x03\ron_use_action\x01\x08\x11using_converts_to\0\0\0\0" } ; pub const BAKED_POTATO : Self = Self { id : 281 , registry_key : "minecraft:baked_potato" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\x11using_converts_to\0\x03\ron_use_action\x01\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x19?\x03\rcooldown_time\0\x03\tnutrition\n\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const BALLOON: Self = Self { pub const BALLOON: Self = Self {
id: 612, id: 612,
registry_key: "minecraft:balloon", registry_key: "minecraft:balloon",
@ -85626,7 +85626,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BEEF : Self = Self { id : 273 , registry_key : "minecraft:beef" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x06\x01\x0Ecan_always_eat\0\x05\x13saturation_modifier\x9A\x99\x99>\x03\ron_use_action\x01\x08\x11using_converts_to\0\x08\rcooldown_type\0\x03\rcooldown_time\0\0\0\0" } ; pub const BEEF : Self = Self { id : 273 , registry_key : "minecraft:beef" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\x11using_converts_to\0\x03\ron_use_action\x01\x05\x13saturation_modifier\x9A\x99\x99>\x03\tnutrition\x06\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const BEEHIVE: Self = Self { pub const BEEHIVE: Self = Self {
id: -219, id: -219,
registry_key: "minecraft:beehive", registry_key: "minecraft:beehive",
@ -85634,9 +85634,9 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BEETROOT : Self = Self { id : 285 , registry_key : "minecraft:beetroot" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x03\ron_use_action\x01\x08\x11using_converts_to\0\x05\x13saturation_modifier\x9A\x99\x19?\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x02\0\0\0" } ; pub const BEETROOT : Self = Self { id : 285 , registry_key : "minecraft:beetroot" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\rcooldown_type\0\x08\x11using_converts_to\0\x03\tnutrition\x02\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x05\x13saturation_modifier\x9A\x99\x19?\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const BEETROOT_SEEDS : Self = Self { id : 295 , registry_key : "minecraft:beetroot_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\rplant_at_face\x02up\t\x08plant_at\x08\x02\x12minecraft:farmland\x08\x0Bcrop_result\x12minecraft:beetroot\x01\x1Aplant_at_any_solid_surface\0\0\0\0" } ; pub const BEETROOT_SEEDS : Self = Self { id : 295 , registry_key : "minecraft:beetroot_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x01\x1Aplant_at_any_solid_surface\0\x08\x0Bcrop_result\x12minecraft:beetroot\x08\rplant_at_face\x02up\t\x08plant_at\x08\x02\x12minecraft:farmland\0\0\0" } ;
pub const BEETROOT_SOUP : Self = Self { id : 286 , registry_key : "minecraft:beetroot_soup" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x05\x13saturation_modifier\x9A\x99\x19?\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x08\rcooldown_type\0\x03\ron_use_action\x01\x03\tnutrition\x0C\x08\x11using_converts_to\x04bowl\0\x03\x16minecraft:use_duration@\x03\x18minecraft:max_stack_size\x02\0\0" } ; pub const BEETROOT_SOUP : Self = Self { id : 286 , registry_key : "minecraft:beetroot_soup" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\x03\tnutrition\x0C\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x19?\x08\x11using_converts_to\x04bowl\0\x03\x16minecraft:use_duration@\x03\x18minecraft:max_stack_size\x02\0\0" } ;
pub const BELL: Self = Self { pub const BELL: Self = Self {
id: -206, id: -206,
registry_key: "minecraft:bell", registry_key: "minecraft:bell",
@ -85798,7 +85798,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BLACK_BUNDLE : Self = Self { id : 857 , registry_key : "minecraft:black_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x16minecraft:storage_item\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\x03\tmax_slots\x80\x01\0\t\titem_tags\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x01\x17can_destroy_in_creative\x01\x03\x11enchantable_value\0\x03\x0Emax_stack_size\x02\x03\x11creative_category\x06\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Cbundle_black\x08\x10bundle_open_back\x16bundle_black_open_back\x08\x11bundle_open_front\x17bundle_black_open_front\0\0\x03\x06damage\0\x01\x0Fstacked_by_data\0\x03\x0Bframe_count\x02\x03\x0Cuse_duration\0\x01\x0Eliquid_clipped\0\x03\ruse_animation\0\x01\x12hidden_in_commands\x02\x08\x10enchantable_slot\x04none\x01\x0Eallow_off_hand\0\x01\rhand_equipped\0\x05\x0Cmining_speed\0\0\x80?\x08\x0Ecreative_group\0\x01\x04foil\0\x01\x0Eshould_despawn\x01\0\0\0" } ; pub const BLACK_BUNDLE : Self = Self { id : 857 , registry_key : "minecraft:black_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x0Fitem_properties\x05\x0Cmining_speed\0\0\x80?\x01\x0Eliquid_clipped\0\x01\x0Fstacked_by_data\0\x01\x04foil\0\x01\x12hidden_in_commands\x02\x03\x11creative_category\x06\x03\x11enchantable_value\0\x01\rhand_equipped\0\x03\x06damage\0\x03\x0Emax_stack_size\x02\x03\ruse_animation\0\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x17bundle_black_open_front\x08\x07default\x0Cbundle_black\x08\x10bundle_open_back\x16bundle_black_open_back\0\0\x01\x0Eshould_despawn\x01\x03\x0Bframe_count\x02\x01\x0Eallow_off_hand\0\x03\x0Cuse_duration\0\x08\x10enchantable_slot\x04none\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\0\t\titem_tags\0\0\0\0" } ;
pub const BLACK_CANDLE: Self = Self { pub const BLACK_CANDLE: Self = Self {
id: -428, id: -428,
registry_key: "minecraft:black_candle", registry_key: "minecraft:black_candle",
@ -85974,7 +85974,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BLUE_BUNDLE : Self = Self { id : 858 , registry_key : "minecraft:blue_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\t\rallowed_items\0\0\0\n\x0Fitem_properties\x01\x0Eliquid_clipped\0\x01\x04foil\0\x03\x0Cuse_duration\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x15bundle_blue_open_back\x08\x07default\x0Bbundle_blue\x08\x11bundle_open_front\x16bundle_blue_open_front\0\0\x01\x17can_destroy_in_creative\x01\x03\x0Bframe_count\x02\x01\x0Eshould_despawn\x01\x03\x11enchantable_value\0\x01\x0Eallow_off_hand\0\x03\x11creative_category\x06\x05\x0Cmining_speed\0\0\x80?\x01\rhand_equipped\0\x03\ruse_animation\0\x01\x12hidden_in_commands\x02\x01\x0Fstacked_by_data\0\x08\x10enchantable_slot\x04none\x08\x0Ecreative_group\0\x03\x06damage\0\x03\x0Emax_stack_size\x02\0\0\0" } ; pub const BLUE_BUNDLE : Self = Self { id : 858 , registry_key : "minecraft:blue_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\t\titem_tags\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x0Fitem_properties\x01\x0Eshould_despawn\x01\x03\x06damage\0\x01\x0Eallow_off_hand\0\x03\x11enchantable_value\0\x01\x0Eliquid_clipped\0\x03\ruse_animation\0\x03\x11creative_category\x06\x01\x0Fstacked_by_data\0\x03\x0Emax_stack_size\x02\x01\x17can_destroy_in_creative\x01\x01\x04foil\0\x03\x0Bframe_count\x02\x01\rhand_equipped\0\x08\x10enchantable_slot\x04none\x01\x12hidden_in_commands\x02\x05\x0Cmining_speed\0\0\x80?\x03\x0Cuse_duration\0\x08\x0Ecreative_group\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bbundle_blue\x08\x10bundle_open_back\x15bundle_blue_open_back\x08\x11bundle_open_front\x16bundle_blue_open_front\0\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ;
pub const BLUE_CANDLE: Self = Self { pub const BLUE_CANDLE: Self = Self {
id: -424, id: -424,
registry_key: "minecraft:blue_candle", registry_key: "minecraft:blue_candle",
@ -86213,8 +86213,8 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BREAD : Self = Self { id : 261 , registry_key : "minecraft:bread" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\tnutrition\n\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x08\rcooldown_type\0\x03\ron_use_action\x01\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x19?\x01\x0Ecan_always_eat\0\0\0\0" } ; pub const BREAD : Self = Self { id : 261 , registry_key : "minecraft:bread" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x03\tnutrition\n\x03\ron_use_action\x01\x08\rcooldown_type\0\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x19?\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const BREEZE_ROD : Self = Self { id : 874 , registry_key : "minecraft:breeze_rod" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x17minecraft:hand_equipped\x01\x05value\x01\0\t\titem_tags\0\0\n\x0Fitem_properties\x01\x0Eliquid_clipped\0\x08\x0Ecreative_group\0\x03\x0Emax_stack_size\x80\x01\x05\x0Cmining_speed\0\0\x80?\x01\x0Fstacked_by_data\0\x03\x0Cuse_duration\0\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\nbreeze_rod\0\0\x03\x11enchantable_value\0\x03\x06damage\0\x01\x04foil\0\x01\x12hidden_in_commands\x02\x01\x0Eallow_off_hand\0\x03\ruse_animation\0\x03\x11creative_category\x08\x08\x10enchantable_slot\x04none\x01\x17can_destroy_in_creative\x01\x01\rhand_equipped\x01\x03\x0Bframe_count\x02\0\n\x16minecraft:display_name\x08\x05value\x14item.breeze_rod.name\0\0\0" } ; pub const BREEZE_ROD : Self = Self { id : 874 , registry_key : "minecraft:breeze_rod" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x17minecraft:hand_equipped\x01\x05value\x01\0\t\titem_tags\0\0\n\x0Fitem_properties\x08\x10enchantable_slot\x04none\x03\x11enchantable_value\0\x01\x0Eallow_off_hand\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x01\x04foil\0\x01\x12hidden_in_commands\x02\x01\rhand_equipped\x01\x03\x0Bframe_count\x02\x03\x11creative_category\x08\x01\x0Eshould_despawn\x01\x03\x0Cuse_duration\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\nbreeze_rod\0\0\x03\x0Emax_stack_size\x80\x01\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x03\x06damage\0\x08\x0Ecreative_group\0\0\n\x16minecraft:display_name\x08\x05value\x14item.breeze_rod.name\0\0\0" } ;
pub const BREEZE_SPAWN_EGG: Self = Self { pub const BREEZE_SPAWN_EGG: Self = Self {
id: 506, id: 506,
registry_key: "minecraft:breeze_spawn_egg", registry_key: "minecraft:breeze_spawn_egg",
@ -86278,7 +86278,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BROWN_BUNDLE : Self = Self { id : 859 , registry_key : "minecraft:brown_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\t\titem_tags\0\0\n\x0Fitem_properties\x01\x0Eshould_despawn\x01\x03\x0Emax_stack_size\x02\x01\x17can_destroy_in_creative\x01\x03\x0Cuse_duration\0\x08\x0Ecreative_group\0\x01\x12hidden_in_commands\x02\x01\x0Eallow_off_hand\0\x03\x06damage\0\x01\x04foil\0\x08\x10enchantable_slot\x04none\x01\x0Eliquid_clipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x16bundle_brown_open_back\x08\x11bundle_open_front\x17bundle_brown_open_front\x08\x07default\x0Cbundle_brown\0\0\x03\x0Bframe_count\x02\x03\x11creative_category\x06\x01\x0Fstacked_by_data\0\x03\x11enchantable_value\0\x05\x0Cmining_speed\0\0\x80?\x03\ruse_animation\0\x01\rhand_equipped\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\0\0" } ; pub const BROWN_BUNDLE : Self = Self { id : 859 , registry_key : "minecraft:brown_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Fitem_properties\x01\x0Fstacked_by_data\0\x03\x06damage\0\x01\x04foil\0\x03\x0Bframe_count\x02\x01\x0Eliquid_clipped\0\x01\x12hidden_in_commands\x02\x01\rhand_equipped\0\x03\x0Cuse_duration\0\x01\x17can_destroy_in_creative\x01\x01\x0Eshould_despawn\x01\x05\x0Cmining_speed\0\0\x80?\x01\x0Eallow_off_hand\0\x03\ruse_animation\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x16bundle_brown_open_back\x08\x11bundle_open_front\x17bundle_brown_open_front\x08\x07default\x0Cbundle_brown\0\0\x03\x11creative_category\x06\x08\x10enchantable_slot\x04none\x03\x11enchantable_value\0\x03\x0Emax_stack_size\x02\x08\x0Ecreative_group\0\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\t\titem_tags\0\0\0\0" } ;
pub const BROWN_CANDLE: Self = Self { pub const BROWN_CANDLE: Self = Self {
id: -425, id: -425,
registry_key: "minecraft:brown_candle", registry_key: "minecraft:brown_candle",
@ -86454,7 +86454,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const BUNDLE : Self = Self { id : 860 , registry_key : "minecraft:bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\t\titem_tags\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\0\n\x0Fitem_properties\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x10bundle_open_back\x08\x07default\x06bundle\x08\x11bundle_open_front\x11bundle_open_front\0\0\x03\x0Bframe_count\x02\x01\x0Eliquid_clipped\0\x03\ruse_animation\0\x01\x0Eallow_off_hand\0\x03\x11creative_category\x06\x08\x0Ecreative_group\0\x03\x11enchantable_value\0\x01\x12hidden_in_commands\x02\x03\x0Cuse_duration\0\x03\x0Emax_stack_size\x02\x03\x06damage\0\x01\rhand_equipped\0\x01\x0Eshould_despawn\x01\x01\x0Fstacked_by_data\0\x01\x17can_destroy_in_creative\x01\x08\x10enchantable_slot\x04none\x01\x04foil\0\x05\x0Cmining_speed\0\0\x80?\0\0\0" } ; pub const BUNDLE : Self = Self { id : 860 , registry_key : "minecraft:bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x11bundle_open_front\x08\x10bundle_open_back\x10bundle_open_back\x08\x07default\x06bundle\0\0\x03\ruse_animation\0\x08\x0Ecreative_group\0\x03\x06damage\0\x03\x0Bframe_count\x02\x03\x0Emax_stack_size\x02\x03\x0Cuse_duration\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Fstacked_by_data\0\x01\x0Eshould_despawn\x01\x01\x12hidden_in_commands\x02\x01\x0Eallow_off_hand\0\x08\x10enchantable_slot\x04none\x01\x17can_destroy_in_creative\x01\x03\x11creative_category\x06\x01\x04foil\0\x01\rhand_equipped\0\x03\x11enchantable_value\0\x01\x0Eliquid_clipped\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\0\0\0" } ;
pub const BURN_POTTERY_SHERD: Self = Self { pub const BURN_POTTERY_SHERD: Self = Self {
id: 675, id: 675,
registry_key: "minecraft:burn_pottery_sherd", registry_key: "minecraft:burn_pottery_sherd",
@ -86518,7 +86518,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const CAMERA : Self = Self { id : 607 , registry_key : "minecraft:camera" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x10minecraft:camera\x05\x10picture_duration\0\0\x80?\x05\x14shutter_screen_ratio\0\0\0?\x05\x10shutter_duration\xCD\xCCL>\x05\x13black_bars_duration\xCD\xCCL>\x05\x17black_bars_screen_ratio\n\xD7\xA3=\x05\x13slide_away_duration\xCD\xCCL>\0\x08\x0Fminecraft:block\x10minecraft:camera\x03\x16minecraft:use_duration\xC0\x9A\x0C\0\0" } ; pub const CAMERA : Self = Self { id : 607 , registry_key : "minecraft:camera" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x10minecraft:camera\x05\x10picture_duration\0\0\x80?\x05\x10shutter_duration\xCD\xCCL>\x05\x17black_bars_screen_ratio\n\xD7\xA3=\x05\x13slide_away_duration\xCD\xCCL>\x05\x13black_bars_duration\xCD\xCCL>\x05\x14shutter_screen_ratio\0\0\0?\0\x03\x16minecraft:use_duration\xC0\x9A\x0C\x08\x0Fminecraft:block\x10minecraft:camera\0\0" } ;
pub const CAMPFIRE: Self = Self { pub const CAMPFIRE: Self = Self {
id: 601, id: 601,
registry_key: "minecraft:campfire", registry_key: "minecraft:campfire",
@ -86547,7 +86547,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const CARROT : Self = Self { id : 279 , registry_key : "minecraft:carrot" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\x05\x13saturation_modifier\x9A\x99\x19?\x08\rcooldown_type\0\x03\rcooldown_time\0\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x06\0\x03\x16minecraft:use_duration@\n\x0Eminecraft:seed\t\x08plant_at\x08\x02\x12minecraft:farmland\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x11minecraft:carrots\x01\x1Aplant_at_any_solid_surface\0\0\0\0" } ; pub const CARROT : Self = Self { id : 279 , registry_key : "minecraft:carrot" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:seed\x01\x1Aplant_at_any_solid_surface\0\x08\x0Bcrop_result\x11minecraft:carrots\x08\rplant_at_face\x02up\t\x08plant_at\x08\x02\x12minecraft:farmland\0\n\x0Eminecraft:food\x05\x13saturation_modifier\x9A\x99\x19?\x03\tnutrition\x06\x08\x11using_converts_to\0\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\rcooldown_type\0\x03\ron_use_action\x01\0\0\0" } ;
pub const CARROT_ON_A_STICK: Self = Self { pub const CARROT_ON_A_STICK: Self = Self {
id: 527, id: 527,
registry_key: "minecraft:carrot_on_a_stick", registry_key: "minecraft:carrot_on_a_stick",
@ -86849,7 +86849,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const CHICKEN : Self = Self { id : 275 , registry_key : "minecraft:chicken" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\tnutrition\x04\x03\ron_use_action\x01\x08\rcooldown_type\0\x03\rcooldown_time\0\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x99>\t\x07effects\n\x02\x08\rdescriptionId\rpotion.hunger\x03\x02id\"\x08\x04name\x06hunger\x05\x06chance\x9A\x99\x99>\x03\tamplifier\0\x03\x08duration<\0\x01\x0Ecan_always_eat\0\0\x03\x16minecraft:use_duration@\0\0" } ; pub const CHICKEN : Self = Self { id : 275 , registry_key : "minecraft:chicken" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x03\tnutrition\x04\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x99>\x08\x11using_converts_to\0\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\t\x07effects\n\x02\x03\x08duration<\x03\x02id\"\x05\x06chance\x9A\x99\x99>\x03\tamplifier\0\x08\x04name\x06hunger\x08\rdescriptionId\rpotion.hunger\0\x08\rcooldown_type\0\0\0\0" } ;
pub const CHICKEN_SPAWN_EGG: Self = Self { pub const CHICKEN_SPAWN_EGG: Self = Self {
id: 439, id: 439,
registry_key: "minecraft:chicken_spawn_egg", registry_key: "minecraft:chicken_spawn_egg",
@ -86969,7 +86969,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const CHORUS_FRUIT : Self = Self { id : 568 , registry_key : "minecraft:chorus_fruit" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\rcooldown_time(\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x99>\x03\tnutrition\x08\x03\ron_use_action\0\x01\x0Ecan_always_eat\x01\x08\x11using_converts_to\0\x08\rcooldown_type\x0Bchorusfruit\0\x03\x16minecraft:use_duration@\0\0" } ; pub const CHORUS_FRUIT : Self = Self { id : 568 , registry_key : "minecraft:chorus_fruit" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\tnutrition\x08\x08\rcooldown_type\x0Bchorusfruit\x03\ron_use_action\0\x08\x11using_converts_to\0\x03\rcooldown_time(\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x99>\x01\x0Ecan_always_eat\x01\0\0\0" } ;
pub const CHORUS_PLANT: Self = Self { pub const CHORUS_PLANT: Self = Self {
id: 240, id: 240,
registry_key: "minecraft:chorus_plant", registry_key: "minecraft:chorus_plant",
@ -87194,7 +87194,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const COD : Self = Self { id : 264 , registry_key : "minecraft:cod" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\rcooldown_time\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x04\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ; pub const COD : Self = Self { id : 264 , registry_key : "minecraft:cod" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x08\rcooldown_type\0\x08\x11using_converts_to\0\x05\x13saturation_modifier\xCD\xCC\xCC=\x03\rcooldown_time\0\x03\tnutrition\x04\0\x01\x19minecraft:stacked_by_data\x01\0\0" } ;
pub const COD_BUCKET: Self = Self { pub const COD_BUCKET: Self = Self {
id: 367, id: 367,
registry_key: "minecraft:cod_bucket", registry_key: "minecraft:cod_bucket",
@ -87321,14 +87321,14 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const COOKED_BEEF : Self = Self { id : 274 , registry_key : "minecraft:cooked_beef" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\rcooldown_time\0\x05\x13saturation_modifier\xCD\xCCL?\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x03\tnutrition\x10\0\0\0" } ; pub const COOKED_BEEF : Self = Self { id : 274 , registry_key : "minecraft:cooked_beef" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x03\tnutrition\x10\x03\rcooldown_time\0\x08\rcooldown_type\0\x05\x13saturation_modifier\xCD\xCCL?\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const COOKED_CHICKEN : Self = Self { id : 276 , registry_key : "minecraft:cooked_chicken" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x19?\x08\x11using_converts_to\0\x03\ron_use_action\x01\x08\rcooldown_type\0\x03\tnutrition\x0C\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x16minecraft:use_duration@\0\0" } ; pub const COOKED_CHICKEN : Self = Self { id : 276 , registry_key : "minecraft:cooked_chicken" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\rcooldown_type\0\x03\tnutrition\x0C\x05\x13saturation_modifier\x9A\x99\x19?\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\x03\ron_use_action\x01\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const COOKED_COD : Self = Self { id : 268 , registry_key : "minecraft:cooked_cod" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x08\x11using_converts_to\0\x05\x13saturation_modifier\x9A\x99\x19?\x08\rcooldown_type\0\x03\rcooldown_time\0\x03\tnutrition\n\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ; pub const COOKED_COD : Self = Self { id : 268 , registry_key : "minecraft:cooked_cod" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\tnutrition\n\x03\ron_use_action\x01\x08\x11using_converts_to\0\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x19?\0\x01\x19minecraft:stacked_by_data\x01\0\0" } ;
pub const COOKED_MUTTON : Self = Self { id : 561 , registry_key : "minecraft:cooked_mutton" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\rcooldown_time\0\x05\x13saturation_modifier\xCD\xCCL?\x03\tnutrition\x0C\x01\x0Ecan_always_eat\0\x03\ron_use_action\x01\x08\x11using_converts_to\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x16minecraft:use_duration@\0\0" } ; pub const COOKED_MUTTON : Self = Self { id : 561 , registry_key : "minecraft:cooked_mutton" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCCL?\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x03\rcooldown_time\0\x03\tnutrition\x0C\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const COOKED_PORKCHOP : Self = Self { id : 263 , registry_key : "minecraft:cooked_porkchop" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x08\x11using_converts_to\0\x03\ron_use_action\x01\x03\rcooldown_time\0\x05\x13saturation_modifier\xCD\xCCL?\x03\tnutrition\x10\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x16minecraft:use_duration@\0\0" } ; pub const COOKED_PORKCHOP : Self = Self { id : 263 , registry_key : "minecraft:cooked_porkchop" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\rcooldown_time\0\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\xCD\xCCL?\x03\tnutrition\x10\x03\ron_use_action\x01\0\0\0" } ;
pub const COOKED_RABBIT : Self = Self { id : 289 , registry_key : "minecraft:cooked_rabbit" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x19?\x03\tnutrition\n\0\x03\x16minecraft:use_duration@\0\0" } ; pub const COOKED_RABBIT : Self = Self { id : 289 , registry_key : "minecraft:cooked_rabbit" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x19?\x03\rcooldown_time\0\x03\tnutrition\n\0\0\0" } ;
pub const COOKED_SALMON : Self = Self { id : 269 , registry_key : "minecraft:cooked_salmon" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\x11using_converts_to\0\x03\ron_use_action\x01\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x05\x13saturation_modifier\xCD\xCCL?\x03\tnutrition\x0C\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\0\0" } ; pub const COOKED_SALMON : Self = Self { id : 269 , registry_key : "minecraft:cooked_salmon" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x08\x11using_converts_to\0\x05\x13saturation_modifier\xCD\xCCL?\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x03\tnutrition\x0C\x03\ron_use_action\x01\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ;
pub const COOKIE : Self = Self { id : 271 , registry_key : "minecraft:cookie" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x05\x13saturation_modifier\xCD\xCC\xCC=\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x03\ron_use_action\x01\x03\rcooldown_time\0\x03\tnutrition\x04\x08\rcooldown_type\0\0\x03\x16minecraft:use_duration@\0\0" } ; pub const COOKIE : Self = Self { id : 271 , registry_key : "minecraft:cookie" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\rcooldown_time\0\x08\rcooldown_type\0\x05\x13saturation_modifier\xCD\xCC\xCC=\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x03\tnutrition\x04\x01\x0Ecan_always_eat\0\0\0\0" } ;
pub const COPPER_AXE: Self = Self { pub const COPPER_AXE: Self = Self {
id: 750, id: 750,
registry_key: "minecraft:copper_axe", registry_key: "minecraft:copper_axe",
@ -87490,7 +87490,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const COPPER_SPEAR : Self = Self { id : 850 , registry_key : "minecraft:copper_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x17minecraft:hand_equipped\x01\x05value\x01\0\t\titem_tags\x08\x04\x15minecraft:copper_tier\x12minecraft:is_spear\n\x12minecraft:cooldown\x08\x04type\x06attack\x08\x08category\x05spear\x05\x08duration\x9A\x99Y?\0\n\x15minecraft:enchantable\x01\x05value\r\x08\x04slot\x0Bmelee_spear\0\n\x10minecraft:damage\x02\x05value\x02\0\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\x05\rhitbox_margin\0\0\x80>\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x16minecraft:copper_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x16minecraft:copper_ingot\0\0\0\n\x18minecraft:swing_duration\x05\x05value\x9A\x99Y?\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03min\0\x03\x03max\xC8\x01\0\x03\x0Emax_durability\xFC\x02\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\x05\x0Fdamage_modifier\0\0\0\0\n\x14knockback_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_duration\xA5\0\x05\tmin_speed33\xA3@\0\n\x11damage_conditions\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\xFA\0\0\x05\x11damage_multiplier\x85\xEBQ?\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_durationP\0\x05\tmin_speed\0\0@A\0\x02\x05delay\r\0\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Citem.copper_spear.attack_hit\x08\x0Battack_miss\x1Ditem.copper_spear.attack_miss\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x15minecraft:copper_tier\x12minecraft:is_spear\0\n\x0Fitem_properties\x01\x0Eallow_off_hand\0\x03\x0Emax_stack_size\x02\x08\x0Ecreative_group\0\x08\x10enchantable_slot\x0Bmelee_spear\x01\x0Fstacked_by_data\0\x01\rhand_equipped\x01\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Ccopper_spear\0\0\x03\x0Bframe_count\x02\x05\x0Cmining_speed\0\0\x80?\x01\x12hidden_in_commands\x02\x03\ruse_animation\0\x03\x11enchantable_value\x1A\x01\x0Eliquid_clipped\0\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x04foil\0\x03\x06damage\x04\x01\x17can_destroy_in_creative\x01\x03\x11creative_category\x06\0\n\x17minecraft:use_modifiers\x08\x0Bstart_sound\x15item.copper_spear.use\x08\x0Bstart_using\x06always\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x05\x11movement_modifier\0\0\x80?\0\n\x16minecraft:display_name\x08\x05value\x16item.copper_spear.name\0\0\0" } ; pub const COPPER_SPEAR : Self = Self { id : 850 , registry_key : "minecraft:copper_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x16minecraft:display_name\x08\x05value\x16item.copper_spear.name\0\n\x10minecraft:damage\x02\x05value\x02\0\0\n\x17minecraft:use_modifiers\x08\x0Bstart_using\x06always\x08\x0Bstart_sound\x15item.copper_spear.use\x05\x0Cuse_duration\0\xA0\x8CG\x05\x11movement_modifier\0\0\x80?\x01\x0Femit_vibrations\0\0\n\x15minecraft:enchantable\x01\x05value\r\x08\x04slot\x0Bmelee_spear\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x05\rhitbox_margin\0\0\x80>\0\n\x0Fitem_properties\x03\x11creative_category\x06\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Ccopper_spear\0\0\x01\x04foil\0\x01\x0Eshould_despawn\x01\x03\x11enchantable_value\x1A\x01\x17can_destroy_in_creative\x01\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x0Fstacked_by_data\0\x03\x0Bframe_count\x02\x01\x0Eallow_off_hand\0\x03\x06damage\x04\x03\x0Emax_stack_size\x02\x01\rhand_equipped\x01\x01\x12hidden_in_commands\x02\x08\x10enchantable_slot\x0Bmelee_spear\x01\x0Eliquid_clipped\0\x03\ruse_animation\0\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\0\n\x12minecraft:cooldown\x08\x08category\x05spear\x05\x08duration\x9A\x99Y?\x08\x04type\x06attack\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\x05\x0Fdamage_modifier\0\0\0\0\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed\0\0@A\x02\x0Cmax_durationP\0\0\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\x05\rhitbox_margin\0\0\x80>\n\x11damage_conditions\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\xFA\0\0\x05\x11damage_multiplier\x85\xEBQ?\x02\x05delay\r\0\n\x14knockback_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_duration\xA5\0\x05\tmin_speed33\xA3@\0\0\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Citem.copper_spear.attack_hit\x08\x0Battack_miss\x1Ditem.copper_spear.attack_miss\0\n\x14minecraft:durability\x03\x0Emax_durability\xFC\x02\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x16minecraft:copper_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\t\x05items\n\x02\x08\x04name\x16minecraft:copper_ingot\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\0\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x15minecraft:copper_tier\x12minecraft:is_spear\0\t\titem_tags\x08\x04\x15minecraft:copper_tier\x12minecraft:is_spear\n\x18minecraft:swing_duration\x05\x05value\x9A\x99Y?\0\0\0" } ;
pub const COPPER_SWORD: Self = Self { pub const COPPER_SWORD: Self = Self {
id: 747, id: 747,
registry_key: "minecraft:copper_sword", registry_key: "minecraft:copper_sword",
@ -87855,7 +87855,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const CYAN_BUNDLE : Self = Self { id : 861 , registry_key : "minecraft:cyan_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x0Fitem_properties\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Fstacked_by_data\0\x03\x0Bframe_count\x02\x01\rhand_equipped\0\x01\x0Eliquid_clipped\0\x03\ruse_animation\0\x03\x0Emax_stack_size\x02\x01\x17can_destroy_in_creative\x01\x03\x06damage\0\x08\x10enchantable_slot\x04none\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bbundle_cyan\x08\x10bundle_open_back\x15bundle_cyan_open_back\x08\x11bundle_open_front\x16bundle_cyan_open_front\0\0\x01\x0Eshould_despawn\x01\x03\x11enchantable_value\0\x03\x11creative_category\x06\x01\x04foil\0\x01\x12hidden_in_commands\x02\x01\x0Eallow_off_hand\0\x03\x0Cuse_duration\0\0\t\titem_tags\0\0\0\0" } ; pub const CYAN_BUNDLE : Self = Self { id : 861 , registry_key : "minecraft:cyan_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x08\x10enchantable_slot\x04none\x03\x11enchantable_value\0\x01\x0Eallow_off_hand\0\x01\x04foil\0\x01\x0Eshould_despawn\x01\x01\x0Fstacked_by_data\0\x03\x0Emax_stack_size\x02\x03\x11creative_category\x06\x08\x0Ecreative_group\0\x01\x17can_destroy_in_creative\x01\x05\x0Cmining_speed\0\0\x80?\x01\x12hidden_in_commands\x02\x03\x06damage\0\x03\ruse_animation\0\x03\x0Cuse_duration\0\x01\x0Eliquid_clipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x16bundle_cyan_open_front\x08\x10bundle_open_back\x15bundle_cyan_open_back\x08\x07default\x0Bbundle_cyan\0\0\x01\rhand_equipped\0\x03\x0Bframe_count\x02\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\t\titem_tags\0\0\0\0" } ;
pub const CYAN_CANDLE: Self = Self { pub const CYAN_CANDLE: Self = Self {
id: -422, id: -422,
registry_key: "minecraft:cyan_candle", registry_key: "minecraft:cyan_candle",
@ -88577,7 +88577,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const DIAMOND_SPEAR : Self = Self { id : 851 , registry_key : "minecraft:diamond_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\x08\x06\x16minecraft:diamond_tier\x1Dminecraft:transformable_items\x12minecraft:is_spear\n\x19minecraft:piercing_weapon\x05\rhitbox_margin\0\0\x80>\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\0\n\x10minecraft:damage\x02\x05value\x04\0\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x17minecraft:diamond_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x11minecraft:diamond\0\0\0\n\x18minecraft:swing_duration\x05\x05valueff\x86?\0\n\x0Fitem_properties\x01\x17can_destroy_in_creative\x01\x03\x06damage\x08\x01\x0Eshould_despawn\x01\x03\x0Emax_stack_size\x02\x03\x0Cuse_duration\x80\xE4\xAF\x01\x03\x11enchantable_value\x14\x03\x11creative_category\x06\x01\x04foil\0\x08\x10enchantable_slot\x0Bmelee_spear\x03\x0Bframe_count\x02\x01\x12hidden_in_commands\x02\x05\x0Cmining_speed\0\0\x80?\n\x0Eminecraft:icon\n\x08textures\x08\x07default\rdiamond_spear\0\0\x03\ruse_animation\0\x01\rhand_equipped\x01\x08\x0Ecreative_group\0\x01\x0Eallow_off_hand\0\x01\x0Eliquid_clipped\0\x01\x0Fstacked_by_data\0\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x11damage_conditions\x05\tmin_speed\0\0\0\0\x02\x0Cmax_duration\xC8\0\x05\x12min_relative_speed33\x93@\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x02\x05delay\n\0\x05\x0Fdamage_modifier\0\0\0\0\x05\x11damage_multiplier\x9A\x99\x89?\n\x14knockback_conditions\x02\x0Cmax_duration\x82\0\x05\tmin_speed33\xA3@\x05\x12min_relative_speed\0\0\0\0\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_duration<\0\x05\tmin_speed\0\0 A\0\x05\rhitbox_margin\0\0\x80>\0\0\n\x15minecraft:enchantable\x01\x05value\n\x08\x04slot\x0Bmelee_spear\0\n\x12minecraft:cooldown\x08\x08category\x05spear\x08\x04type\x06attack\x05\x08durationff\x86?\0\n\x0Eminecraft:tags\t\x04tags\x08\x06\x16minecraft:diamond_tier\x1Dminecraft:transformable_items\x12minecraft:is_spear\0\n\x17minecraft:use_modifiers\x08\x0Bstart_using\x06always\x08\x0Bstart_sound\x16item.diamond_spear.use\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x05\x11movement_modifier\0\0\x80?\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\x03\x0Emax_durability\xB0\x18\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x16minecraft:display_name\x08\x05value\x17item.diamond_spear.name\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:swing_sounds\x08\x0Battack_miss\x1Eitem.diamond_spear.attack_miss\x08\nattack_hit\x1Ditem.diamond_spear.attack_hit\0\0\0" } ; pub const DIAMOND_SPEAR : Self = Self { id : 851 , registry_key : "minecraft:diamond_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x14minecraft:durability\n\rdamage_chance\x03\x03min\0\x03\x03max\xC8\x01\0\x03\x0Emax_durability\xB0\x18\0\n\x18minecraft:swing_duration\x05\x05valueff\x86?\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\0\n\x12minecraft:cooldown\x08\x08category\x05spear\x05\x08durationff\x86?\x08\x04type\x06attack\0\n\x16minecraft:swing_sounds\x08\x0Battack_miss\x1Eitem.diamond_spear.attack_miss\x08\nattack_hit\x1Ditem.diamond_spear.attack_hit\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x17minecraft:diamond_spear\0\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x11minecraft:diamond\0\0\0\n\x10minecraft:damage\x02\x05value\x04\0\0\n\x0Eminecraft:tags\t\x04tags\x08\x06\x16minecraft:diamond_tier\x1Dminecraft:transformable_items\x12minecraft:is_spear\0\n\x0Fitem_properties\x03\x0Bframe_count\x02\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\rdiamond_spear\0\0\x03\x11enchantable_value\x14\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x0Eallow_off_hand\0\x03\x06damage\x08\x01\x04foil\0\x01\rhand_equipped\x01\x01\x0Eliquid_clipped\0\x01\x0Fstacked_by_data\0\x03\x11creative_category\x06\x01\x12hidden_in_commands\x02\x03\ruse_animation\0\x01\x17can_destroy_in_creative\x01\x08\x10enchantable_slot\x0Bmelee_spear\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\x03\x0Emax_stack_size\x02\0\t\titem_tags\x08\x06\x16minecraft:diamond_tier\x1Dminecraft:transformable_items\x12minecraft:is_spear\n\x17minecraft:use_modifiers\x08\x0Bstart_sound\x16item.diamond_spear.use\x08\x0Bstart_using\x06always\x05\x11movement_modifier\0\0\x80?\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\0\n\x15minecraft:enchantable\x08\x04slot\x0Bmelee_spear\x01\x05value\n\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x11damage_conditions\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\xC8\0\x05\tmin_speed\0\0\0\0\0\x05\x11damage_multiplier\x9A\x99\x89?\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\n\x13dismount_conditions\x05\tmin_speed\0\0 A\x02\x0Cmax_duration<\0\x05\x12min_relative_speed\0\0\0\0\0\x05\x0Fdamage_modifier\0\0\0\0\n\x14knockback_conditions\x02\x0Cmax_duration\x82\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\x02\x05delay\n\0\x05\rhitbox_margin\0\0\x80>\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:display_name\x08\x05value\x17item.diamond_spear.name\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\0\0" } ;
pub const DIAMOND_SWORD: Self = Self { pub const DIAMOND_SWORD: Self = Self {
id: 318, id: 318,
registry_key: "minecraft:diamond_sword", registry_key: "minecraft:diamond_sword",
@ -88732,7 +88732,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const DRIED_KELP : Self = Self { id : 270 , registry_key : "minecraft:dried_kelp" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\ron_use_action\x01\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\x08\rcooldown_type\0\x03\rcooldown_time\0\x03\tnutrition\x02\x05\x13saturation_modifier\xCD\xCC\xCC=\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x16minecraft:use_duration \0\0" } ; pub const DRIED_KELP : Self = Self { id : 270 , registry_key : "minecraft:dried_kelp" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\rcooldown_time\0\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\x03\tnutrition\x02\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x16minecraft:use_duration \0\0" } ;
pub const DRIED_KELP_BLOCK: Self = Self { pub const DRIED_KELP_BLOCK: Self = Self {
id: -139, id: -139,
registry_key: "minecraft:dried_kelp_block", registry_key: "minecraft:dried_kelp_block",
@ -89678,7 +89678,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const ENCHANTED_GOLDEN_APPLE : Self = Self { id : 259 , registry_key : "minecraft:enchanted_golden_apple" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x01\x0Eminecraft:foil\x01\n\x0Eminecraft:food\x01\x0Ecan_always_eat\x01\x03\tnutrition\x08\x03\ron_use_action\x01\x08\x11using_converts_to\0\x08\rcooldown_type\0\t\x07effects\n\x08\x08\x04name\x0Cregeneration\x03\x08duration<\x03\tamplifier\x02\x05\x06chance\0\0\x80?\x03\x02id\x14\x08\rdescriptionId\x13potion.regeneration\0\x03\x02id,\x03\x08duration\xF0\x01\x03\tamplifier\x06\x05\x06chance\0\0\x80?\x08\rdescriptionId\x11potion.absorption\x08\x04name\nabsorption\0\x08\x04name\nresistance\x08\rdescriptionId\x11potion.resistance\x03\x08duration\xD8\x04\x03\tamplifier\0\x03\x02id\x16\x05\x06chance\0\0\x80?\0\x08\x04name\x0Ffire_resistance\x03\x02id\x18\x08\rdescriptionId\x15potion.fireResistance\x03\x08duration\xD8\x04\x05\x06chance\0\0\x80?\x03\tamplifier\0\0\x05\x13saturation_modifier\x9A\x99\x99?\x03\rcooldown_time\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ; pub const ENCHANTED_GOLDEN_APPLE : Self = Self { id : 259 , registry_key : "minecraft:enchanted_golden_apple" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x01\x0Eminecraft:foil\x01\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\rcooldown_time\0\x08\x11using_converts_to\0\t\x07effects\n\x08\x05\x06chance\0\0\x80?\x03\tamplifier\x02\x03\x08duration<\x03\x02id\x14\x08\x04name\x0Cregeneration\x08\rdescriptionId\x13potion.regeneration\0\x08\rdescriptionId\x11potion.absorption\x03\x02id,\x03\tamplifier\x06\x08\x04name\nabsorption\x05\x06chance\0\0\x80?\x03\x08duration\xF0\x01\0\x08\x04name\nresistance\x03\tamplifier\0\x03\x08duration\xD8\x04\x05\x06chance\0\0\x80?\x03\x02id\x16\x08\rdescriptionId\x11potion.resistance\0\x08\x04name\x0Ffire_resistance\x03\tamplifier\0\x03\x08duration\xD8\x04\x08\rdescriptionId\x15potion.fireResistance\x03\x02id\x18\x05\x06chance\0\0\x80?\0\x01\x0Ecan_always_eat\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\rcooldown_type\0\x03\ron_use_action\x01\x03\tnutrition\x08\x05\x13saturation_modifier\x9A\x99\x99?\0\0\0" } ;
pub const ENCHANTING_TABLE: Self = Self { pub const ENCHANTING_TABLE: Self = Self {
id: 116, id: 116,
registry_key: "minecraft:enchanting_table", registry_key: "minecraft:enchanting_table",
@ -90253,7 +90253,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const GLOW_BERRIES : Self = Self { id : 879 , registry_key : "minecraft:glow_berries" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x01\x1Aplant_at_any_solid_surface\x01\x08\x0Bcrop_result\x14minecraft:cave_vines\t\x08plant_at\x08\x04\ncave_vines\x1Ccave_vines_head_with_berries\x08\rplant_at_face\x04down\0\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\rcooldown_time\0\x08\rcooldown_type\0\x03\ron_use_action\x01\x03\tnutrition\x04\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x99>\x01\x0Ecan_always_eat\0\0\0\0" } ; pub const GLOW_BERRIES : Self = Self { id : 879 , registry_key : "minecraft:glow_berries" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x03\tnutrition\x04\x05\x13saturation_modifier\x9A\x99\x99>\0\n\x0Eminecraft:seed\t\x08plant_at\x08\x04\ncave_vines\x1Ccave_vines_head_with_berries\x01\x1Aplant_at_any_solid_surface\x01\x08\x0Bcrop_result\x14minecraft:cave_vines\x08\rplant_at_face\x04down\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const GLOW_FRAME: Self = Self { pub const GLOW_FRAME: Self = Self {
id: 636, id: 636,
registry_key: "minecraft:glow_frame", registry_key: "minecraft:glow_frame",
@ -90352,7 +90352,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const GOLDEN_APPLE : Self = Self { id : 258 , registry_key : "minecraft:golden_apple" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\x01\t\x07effects\n\x04\x03\tamplifier\x02\x05\x06chance\0\0\x80?\x03\x02id\x14\x08\x04name\x0Cregeneration\x08\rdescriptionId\x13potion.regeneration\x03\x08duration\n\0\x08\rdescriptionId\x11potion.absorption\x03\x08duration\xF0\x01\x05\x06chance\0\0\x80?\x03\x02id,\x03\tamplifier\0\x08\x04name\nabsorption\0\x05\x13saturation_modifier\x9A\x99\x99?\x08\rcooldown_type\0\x08\x11using_converts_to\0\x03\ron_use_action\x01\x03\rcooldown_time\0\x03\tnutrition\x08\0\0\0" } ; pub const GOLDEN_APPLE : Self = Self { id : 258 , registry_key : "minecraft:golden_apple" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\x01\x19minecraft:stacked_by_data\x01\n\x0Eminecraft:food\x08\rcooldown_type\0\x03\tnutrition\x08\x03\rcooldown_time\0\x01\x0Ecan_always_eat\x01\t\x07effects\n\x04\x03\tamplifier\x02\x03\x08duration\n\x08\x04name\x0Cregeneration\x05\x06chance\0\0\x80?\x08\rdescriptionId\x13potion.regeneration\x03\x02id\x14\0\x08\rdescriptionId\x11potion.absorption\x03\tamplifier\0\x03\x08duration\xF0\x01\x08\x04name\nabsorption\x03\x02id,\x05\x06chance\0\0\x80?\0\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x05\x13saturation_modifier\x9A\x99\x99?\0\0\0" } ;
pub const GOLDEN_AXE: Self = Self { pub const GOLDEN_AXE: Self = Self {
id: 328, id: 328,
registry_key: "minecraft:golden_axe", registry_key: "minecraft:golden_axe",
@ -90367,7 +90367,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const GOLDEN_CARROT : Self = Self { id : 283 , registry_key : "minecraft:golden_carrot" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x03\tnutrition\x0C\x05\x13saturation_modifier\x9A\x99\x99?\x03\rcooldown_time\0\x08\rcooldown_type\0\0\x03\x16minecraft:use_duration@\0\0" } ; pub const GOLDEN_CARROT : Self = Self { id : 283 , registry_key : "minecraft:golden_carrot" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\tnutrition\x0C\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x99?\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const GOLDEN_CHESTPLATE: Self = Self { pub const GOLDEN_CHESTPLATE: Self = Self {
id: 355, id: 355,
registry_key: "minecraft:golden_chestplate", registry_key: "minecraft:golden_chestplate",
@ -90438,7 +90438,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const GOLDEN_SPEAR : Self = Self { id : 852 , registry_key : "minecraft:golden_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\x08\x04\x15minecraft:golden_tier\x12minecraft:is_spear\n\x12minecraft:cooldown\x08\x08category\x05spear\x05\x08duration33s?\x08\x04type\x06attack\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x15minecraft:golden_tier\x12minecraft:is_spear\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x11damage_conditions\x05\x12min_relative_speed33\x93@\x05\tmin_speed\0\0\0\0\x02\x0Cmax_duration\x13\x01\0\x05\rhitbox_margin\0\0\x80>\n\x14knockback_conditions\x05\tmin_speed33\xA3@\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_duration\xAA\0\0\x05\x0Fdamage_modifier\0\0\0\0\n\x13dismount_conditions\x02\x0Cmax_durationF\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed\0\0PA\0\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\x05\x11damage_multiplier333?\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x02\x05delay\x0E\0\0\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x16minecraft:golden_spear\0\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x14minecraft:gold_ingot\0\0\0\n\x16minecraft:display_name\x08\x05value\x16item.golden_spear.name\0\n\x10minecraft:damage\x02\x05value\x01\0\0\n\x0Fitem_properties\x01\x0Fstacked_by_data\0\x08\x0Ecreative_group\0\x08\x10enchantable_slot\x0Bmelee_spear\x03\x11enchantable_value,\x01\x04foil\0\x01\x0Eallow_off_hand\0\x03\ruse_animation\0\x01\x0Eliquid_clipped\0\x03\x0Bframe_count\x02\x03\x06damage\x02\x03\x0Emax_stack_size\x02\x01\x0Eshould_despawn\x01\x03\x0Cuse_duration\x80\xE4\xAF\x01\x03\x11creative_category\x06\x01\rhand_equipped\x01\x01\x12hidden_in_commands\x02\n\x0Eminecraft:icon\n\x08textures\x08\x07default\ngold_spear\0\0\x05\x0Cmining_speed\0\0\x80?\x01\x17can_destroy_in_creative\x01\0\n\x17minecraft:use_modifiers\x08\x0Bstart_sound\x15item.golden_spear.use\x08\x0Bstart_using\x06always\x05\x11movement_modifier\0\0\x80?\x01\x0Femit_vibrations\0\x05\x0Cuse_duration\0\xA0\x8CG\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Citem.golden_spear.attack_hit\x08\x0Battack_miss\x1Ditem.golden_spear.attack_miss\0\n\x14minecraft:durability\x03\x0Emax_durability<\n\rdamage_chance\x03\x03min\0\x03\x03max\xC8\x01\0\0\n\x15minecraft:enchantable\x08\x04slot\x0Bmelee_spear\x01\x05value\x16\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x18minecraft:swing_duration\x05\x05value33s?\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\0\0" } ; pub const GOLDEN_SPEAR : Self = Self { id : 852 , registry_key : "minecraft:golden_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Citem.golden_spear.attack_hit\x08\x0Battack_miss\x1Ditem.golden_spear.attack_miss\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x16minecraft:golden_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x14minecraft:gold_ingot\0\0\0\n\x0Fitem_properties\x01\rhand_equipped\x01\x03\x06damage\x02\x03\x0Emax_stack_size\x02\x03\ruse_animation\0\x01\x0Eshould_despawn\x01\x01\x17can_destroy_in_creative\x01\x01\x0Eallow_off_hand\0\x05\x0Cmining_speed\0\0\x80?\x08\x0Ecreative_group\0\x01\x12hidden_in_commands\x02\x08\x10enchantable_slot\x0Bmelee_spear\x03\x0Cuse_duration\x80\xE4\xAF\x01\x03\x11creative_category\x06\x03\x0Bframe_count\x02\x03\x11enchantable_value,\x01\x04foil\0\x01\x0Fstacked_by_data\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\ngold_spear\0\0\x01\x0Eliquid_clipped\0\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\x03\x0Emax_durability<\0\t\titem_tags\x08\x04\x15minecraft:golden_tier\x12minecraft:is_spear\n\x17minecraft:use_modifiers\x08\x0Bstart_using\x06always\x08\x0Bstart_sound\x15item.golden_spear.use\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x05\x11movement_modifier\0\0\x80?\0\n\x10minecraft:damage\x02\x05value\x01\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x18minecraft:swing_duration\x05\x05value33s?\0\n\x19minecraft:piercing_weapon\x05\rhitbox_margin\0\0\x80>\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\0\n\x16minecraft:display_name\x08\x05value\x16item.golden_spear.name\0\n\x15minecraft:enchantable\x01\x05value\x16\x08\x04slot\x0Bmelee_spear\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x15minecraft:golden_tier\x12minecraft:is_spear\0\n\x12minecraft:cooldown\x08\x04type\x06attack\x05\x08duration33s?\x08\x08category\x05spear\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\x05\x0Fdamage_modifier\0\0\0\0\n\x14knockback_conditions\x02\x0Cmax_duration\xAA\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\0\x05\x11damage_multiplier333?\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_durationF\0\x05\tmin_speed\0\0PA\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x02\x05delay\x0E\0\x05\rhitbox_margin\0\0\x80>\n\x11damage_conditions\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\x13\x01\x05\tmin_speed\0\0\0\0\0\0\0\0\0" } ;
pub const GOLDEN_SWORD: Self = Self { pub const GOLDEN_SWORD: Self = Self {
id: 325, id: 325,
registry_key: "minecraft:golden_sword", registry_key: "minecraft:golden_sword",
@ -90502,7 +90502,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const GRAY_BUNDLE : Self = Self { id : 862 , registry_key : "minecraft:gray_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x0Fitem_properties\x03\x06damage\0\x08\x0Ecreative_group\0\x03\x0Bframe_count\x02\x03\x0Emax_stack_size\x02\x01\x04foil\0\x08\x10enchantable_slot\x04none\x01\rhand_equipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bbundle_gray\x08\x10bundle_open_back\x15bundle_gray_open_back\x08\x11bundle_open_front\x16bundle_gray_open_front\0\0\x03\x11creative_category\x06\x01\x0Eliquid_clipped\0\x01\x0Eshould_despawn\x01\x01\x17can_destroy_in_creative\x01\x03\x11enchantable_value\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eallow_off_hand\0\x01\x12hidden_in_commands\x02\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x03\x0Cuse_duration\0\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ; pub const GRAY_BUNDLE : Self = Self { id : 862 , registry_key : "minecraft:gray_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\t\titem_tags\0\0\n\x0Fitem_properties\x05\x0Cmining_speed\0\0\x80?\x01\rhand_equipped\0\x03\ruse_animation\0\x01\x12hidden_in_commands\x02\x03\x06damage\0\x03\x0Bframe_count\x02\x03\x11creative_category\x06\x08\x0Ecreative_group\0\x01\x0Eliquid_clipped\0\x03\x0Cuse_duration\0\x08\x10enchantable_slot\x04none\x01\x0Eshould_despawn\x01\x01\x04foil\0\x01\x0Eallow_off_hand\0\x03\x11enchantable_value\0\x03\x0Emax_stack_size\x02\x01\x0Fstacked_by_data\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bbundle_gray\x08\x10bundle_open_back\x15bundle_gray_open_back\x08\x11bundle_open_front\x16bundle_gray_open_front\0\0\x01\x17can_destroy_in_creative\x01\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ;
pub const GRAY_CANDLE: Self = Self { pub const GRAY_CANDLE: Self = Self {
id: -420, id: -420,
registry_key: "minecraft:gray_candle", registry_key: "minecraft:gray_candle",
@ -90601,7 +90601,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const GREEN_BUNDLE : Self = Self { id : 863 , registry_key : "minecraft:green_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x0Fitem_properties\x01\x12hidden_in_commands\x02\x03\x11creative_category\x06\x03\x0Cuse_duration\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x16bundle_green_open_back\x08\x07default\x0Cbundle_green\x08\x11bundle_open_front\x17bundle_green_open_front\0\0\x03\ruse_animation\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eliquid_clipped\0\x03\x06damage\0\x08\x10enchantable_slot\x04none\x01\x17can_destroy_in_creative\x01\x03\x0Bframe_count\x02\x01\x0Eshould_despawn\x01\x01\rhand_equipped\0\x08\x0Ecreative_group\0\x01\x0Fstacked_by_data\0\x03\x0Emax_stack_size\x02\x01\x04foil\0\x01\x0Eallow_off_hand\0\x03\x11enchantable_value\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ; pub const GREEN_BUNDLE : Self = Self { id : 863 , registry_key : "minecraft:green_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x03\x11enchantable_value\0\x01\rhand_equipped\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eallow_off_hand\0\x01\x17can_destroy_in_creative\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Cbundle_green\x08\x10bundle_open_back\x16bundle_green_open_back\x08\x11bundle_open_front\x17bundle_green_open_front\0\0\x01\x0Eshould_despawn\x01\x01\x0Fstacked_by_data\0\x03\x06damage\0\x03\x0Cuse_duration\0\x08\x10enchantable_slot\x04none\x08\x0Ecreative_group\0\x03\ruse_animation\0\x03\x0Bframe_count\x02\x03\x0Emax_stack_size\x02\x01\x0Eliquid_clipped\0\x03\x11creative_category\x06\x01\x04foil\0\x01\x12hidden_in_commands\x02\0\t\titem_tags\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\0\0" } ;
pub const GREEN_CANDLE: Self = Self { pub const GREEN_CANDLE: Self = Self {
id: -426, id: -426,
registry_key: "minecraft:green_candle", registry_key: "minecraft:green_candle",
@ -91064,7 +91064,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const HONEY_BOTTLE : Self = Self { id : 604 , registry_key : "minecraft:honey_bottle" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_durationP\x03\x18minecraft:max_stack_size \n\x0Eminecraft:food\x08\rcooldown_type\0\x03\ron_use_action\x01\x01\x0Ecan_always_eat\x01\x05\x13saturation_modifier\xCD\xCC\xCC=\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x03\tnutrition\x0C\t\x0Eremove_effects\x03\x02&\x08\x11using_converts_to\x0Cglass_bottle\0\0\0" } ; pub const HONEY_BOTTLE : Self = Self { id : 604 , registry_key : "minecraft:honey_bottle" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\x11using_converts_to\x0Cglass_bottle\x08\rcooldown_type\0\x05\x13saturation_modifier\xCD\xCC\xCC=\x03\rcooldown_time\0\t\x0Eremove_effects\x03\x02&\x01\x0Ecan_always_eat\x01\x03\tnutrition\x0C\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x18minecraft:max_stack_size \x03\x16minecraft:use_durationP\0\0" } ;
pub const HONEYCOMB: Self = Self { pub const HONEYCOMB: Self = Self {
id: 603, id: 603,
registry_key: "minecraft:honeycomb", registry_key: "minecraft:honeycomb",
@ -91366,7 +91366,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const IRON_SPEAR : Self = Self { id : 853 , registry_key : "minecraft:iron_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x12minecraft:cooldown\x05\x08duration33s?\x08\x08category\x05spear\x08\x04type\x06attack\0\n\x14minecraft:durability\x03\x0Emax_durability\xF4\x03\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\0\n\x18minecraft:swing_duration\x05\x05value33s?\0\n\x10minecraft:damage\x02\x05value\x03\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Aitem.iron_spear.attack_hit\x08\x0Battack_miss\x1Bitem.iron_spear.attack_miss\0\t\titem_tags\x08\x04\x13minecraft:iron_tier\x12minecraft:is_spear\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\x02\x05delay\x0C\0\x05\rhitbox_margin\0\0\x80>\x05\x0Fdamage_modifier\0\0\0\0\x05\x11damage_multiplier33s?\n\x14knockback_conditions\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\x02\x0Cmax_duration\x87\0\0\n\x11damage_conditions\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\xE1\0\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\n\x13dismount_conditions\x02\x0Cmax_duration2\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed\0\x000A\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\0\0\n\x16minecraft:display_name\x08\x05value\x14item.iron_spear.name\0\n\x15minecraft:enchantable\x08\x04slot\x0Bmelee_spear\x01\x05value\x0E\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x13minecraft:iron_tier\x12minecraft:is_spear\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x05\rhitbox_margin\0\0\x80>\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x14minecraft:iron_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\t\x05items\n\x02\x08\x04name\x14minecraft:iron_ingot\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\0\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x17minecraft:use_modifiers\x01\x0Femit_vibrations\0\x08\x0Bstart_using\x06always\x08\x0Bstart_sound\x13item.iron_spear.use\x05\x0Cuse_duration\0\xA0\x8CG\x05\x11movement_modifier\0\0\x80?\0\n\x0Fitem_properties\x01\x0Fstacked_by_data\0\x01\x0Eallow_off_hand\0\x08\x10enchantable_slot\x0Bmelee_spear\x03\x11enchantable_value\x1C\x03\x06damage\x06\x01\x0Eliquid_clipped\0\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x17can_destroy_in_creative\x01\x03\x0Emax_stack_size\x02\x03\x0Bframe_count\x02\x01\x12hidden_in_commands\x02\x03\x11creative_category\x06\x05\x0Cmining_speed\0\0\x80?\x01\x0Eshould_despawn\x01\x01\x04foil\0\x01\rhand_equipped\x01\x03\ruse_animation\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\niron_spear\0\0\x08\x0Ecreative_group\0\0\0\0" } ; pub const IRON_SPEAR : Self = Self { id : 853 , registry_key : "minecraft:iron_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:swing_duration\x05\x05value33s?\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x16minecraft:display_name\x08\x05value\x14item.iron_spear.name\0\n\x10minecraft:damage\x02\x05value\x03\0\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Aitem.iron_spear.attack_hit\x08\x0Battack_miss\x1Bitem.iron_spear.attack_miss\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x11damage_conditions\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\xE1\0\x05\tmin_speed\0\0\0\0\0\n\x14knockback_conditions\x02\x0Cmax_duration\x87\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\0\x02\x05delay\x0C\0\x05\rhitbox_margin\0\0\x80>\x05\x11damage_multiplier33s?\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed\0\x000A\x02\x0Cmax_duration2\0\0\x05\x0Fdamage_modifier\0\0\0\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\0\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x14minecraft:iron_spear\0\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x14minecraft:iron_ingot\0\0\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x13minecraft:iron_tier\x12minecraft:is_spear\0\t\titem_tags\x08\x04\x13minecraft:iron_tier\x12minecraft:is_spear\n\x15minecraft:enchantable\x01\x05value\x0E\x08\x04slot\x0Bmelee_spear\0\n\x12minecraft:cooldown\x08\x08category\x05spear\x05\x08duration33s?\x08\x04type\x06attack\0\n\x14minecraft:durability\x03\x0Emax_durability\xF4\x03\n\rdamage_chance\x03\x03min\0\x03\x03max\xC8\x01\0\0\n\x0Fitem_properties\x08\x10enchantable_slot\x0Bmelee_spear\x08\x0Ecreative_group\0\x01\rhand_equipped\x01\x03\x0Emax_stack_size\x02\x01\x04foil\0\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x03\x11creative_category\x06\x05\x0Cmining_speed\0\0\x80?\n\x0Eminecraft:icon\n\x08textures\x08\x07default\niron_spear\0\0\x01\x0Eshould_despawn\x01\x03\x11enchantable_value\x1C\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x0Eallow_off_hand\0\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x03\x06damage\x06\x01\x12hidden_in_commands\x02\x03\x0Bframe_count\x02\0\n\x19minecraft:piercing_weapon\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\x05\rhitbox_margin\0\0\x80>\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x17minecraft:use_modifiers\x08\x0Bstart_using\x06always\x05\x0Cuse_duration\0\xA0\x8CG\x08\x0Bstart_sound\x13item.iron_spear.use\x01\x0Femit_vibrations\0\x05\x11movement_modifier\0\0\x80?\0\0\0" } ;
pub const IRON_SWORD: Self = Self { pub const IRON_SWORD: Self = Self {
id: 309, id: 309,
registry_key: "minecraft:iron_sword", registry_key: "minecraft:iron_sword",
@ -91948,7 +91948,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const LIGHT_BLUE_BUNDLE : Self = Self { id : 864 , registry_key : "minecraft:light_blue_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x0Fitem_properties\x01\x0Eshould_despawn\x01\x08\x0Ecreative_group\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x1Bbundle_light_blue_open_back\x08\x11bundle_open_front\x1Cbundle_light_blue_open_front\x08\x07default\x11bundle_light_blue\0\0\x08\x10enchantable_slot\x04none\x01\x0Eliquid_clipped\0\x01\x04foil\0\x01\x12hidden_in_commands\x02\x03\x11enchantable_value\0\x01\x17can_destroy_in_creative\x01\x03\x0Emax_stack_size\x02\x03\x0Bframe_count\x02\x03\ruse_animation\0\x01\rhand_equipped\0\x01\x0Eallow_off_hand\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Fstacked_by_data\0\x03\x0Cuse_duration\0\x03\x11creative_category\x06\x03\x06damage\0\0\t\titem_tags\0\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\0\0" } ; pub const LIGHT_BLUE_BUNDLE : Self = Self { id : 864 , registry_key : "minecraft:light_blue_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\t\titem_tags\0\0\n\x0Fitem_properties\x03\ruse_animation\0\x03\x06damage\0\x01\x12hidden_in_commands\x02\x03\x0Bframe_count\x02\x03\x0Cuse_duration\0\x01\x17can_destroy_in_creative\x01\x03\x11enchantable_value\0\x03\x11creative_category\x06\x08\x0Ecreative_group\0\x01\x0Eshould_despawn\x01\x01\x0Eliquid_clipped\0\x01\x0Eallow_off_hand\0\x01\x04foil\0\x08\x10enchantable_slot\x04none\x01\x0Fstacked_by_data\0\x05\x0Cmining_speed\0\0\x80?\x03\x0Emax_stack_size\x02\x01\rhand_equipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x1Bbundle_light_blue_open_back\x08\x11bundle_open_front\x1Cbundle_light_blue_open_front\x08\x07default\x11bundle_light_blue\0\0\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ;
pub const LIGHT_BLUE_CANDLE: Self = Self { pub const LIGHT_BLUE_CANDLE: Self = Self {
id: -416, id: -416,
registry_key: "minecraft:light_blue_candle", registry_key: "minecraft:light_blue_candle",
@ -92047,7 +92047,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const LIGHT_GRAY_BUNDLE : Self = Self { id : 865 , registry_key : "minecraft:light_gray_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\t\titem_tags\0\0\n\x0Fitem_properties\x01\x04foil\0\x03\ruse_animation\0\x03\x0Cuse_duration\0\x01\rhand_equipped\0\x01\x0Eallow_off_hand\0\x08\x10enchantable_slot\x04none\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x1Bbundle_light_gray_open_back\x08\x11bundle_open_front\x1Cbundle_light_gray_open_front\x08\x07default\x11bundle_light_gray\0\0\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\x01\x0Eliquid_clipped\0\x03\x06damage\0\x03\x0Bframe_count\x02\x05\x0Cmining_speed\0\0\x80?\x03\x11creative_category\x06\x03\x0Emax_stack_size\x02\x03\x11enchantable_value\0\x01\x0Fstacked_by_data\0\x01\x12hidden_in_commands\x02\x01\x0Eshould_despawn\x01\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\0\0" } ; pub const LIGHT_GRAY_BUNDLE : Self = Self { id : 865 , registry_key : "minecraft:light_gray_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x0Fitem_properties\x05\x0Cmining_speed\0\0\x80?\x08\x10enchantable_slot\x04none\x03\x11enchantable_value\0\x03\x06damage\0\x01\x0Eliquid_clipped\0\x01\x0Eshould_despawn\x01\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x03\x0Cuse_duration\0\x01\x0Eallow_off_hand\0\x03\x11creative_category\x06\x08\x0Ecreative_group\0\x01\x12hidden_in_commands\x02\x03\x0Bframe_count\x02\x01\rhand_equipped\0\x03\x0Emax_stack_size\x02\x01\x17can_destroy_in_creative\x01\x01\x04foil\0\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x1Cbundle_light_gray_open_front\x08\x10bundle_open_back\x1Bbundle_light_gray_open_back\x08\x07default\x11bundle_light_gray\0\0\0\0\0" } ;
pub const LIGHT_GRAY_CANDLE: Self = Self { pub const LIGHT_GRAY_CANDLE: Self = Self {
id: -421, id: -421,
registry_key: "minecraft:light_gray_candle", registry_key: "minecraft:light_gray_candle",
@ -92167,7 +92167,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const LIME_BUNDLE : Self = Self { id : 866 , registry_key : "minecraft:lime_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\0\n\x0Fitem_properties\x03\x0Cuse_duration\0\x03\ruse_animation\0\x01\x12hidden_in_commands\x02\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x15bundle_lime_open_back\x08\x11bundle_open_front\x16bundle_lime_open_front\x08\x07default\x0Bbundle_lime\0\0\x03\x06damage\0\x01\x0Fstacked_by_data\0\x03\x0Bframe_count\x02\x01\x0Eshould_despawn\x01\x01\x04foil\0\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x03\x11enchantable_value\0\x03\x0Emax_stack_size\x02\x01\x0Eallow_off_hand\0\x03\x11creative_category\x06\x01\rhand_equipped\0\x08\x10enchantable_slot\x04none\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\0\t\titem_tags\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\0\0" } ; pub const LIME_BUNDLE : Self = Self { id : 866 , registry_key : "minecraft:lime_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x0Fitem_properties\x03\x11enchantable_value\0\x03\x0Cuse_duration\0\x03\x11creative_category\x06\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x16bundle_lime_open_front\x08\x07default\x0Bbundle_lime\x08\x10bundle_open_back\x15bundle_lime_open_back\0\0\x01\x0Eliquid_clipped\0\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x03\x0Emax_stack_size\x02\x03\x06damage\0\x01\x04foil\0\x01\rhand_equipped\0\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eallow_off_hand\0\x03\x0Bframe_count\x02\x08\x10enchantable_slot\x04none\x01\x12hidden_in_commands\x02\0\t\titem_tags\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ;
pub const LIME_CANDLE: Self = Self { pub const LIME_CANDLE: Self = Self {
id: -418, id: -418,
registry_key: "minecraft:lime_candle", registry_key: "minecraft:lime_candle",
@ -92371,7 +92371,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const MAGENTA_BUNDLE : Self = Self { id : 867 , registry_key : "minecraft:magenta_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x0Fitem_properties\x08\x0Ecreative_group\0\x01\x17can_destroy_in_creative\x01\x01\x12hidden_in_commands\x02\x01\rhand_equipped\0\x01\x0Eshould_despawn\x01\x08\x10enchantable_slot\x04none\x05\x0Cmining_speed\0\0\x80?\x03\x11enchantable_value\0\x03\ruse_animation\0\x01\x0Eallow_off_hand\0\x03\x0Cuse_duration\0\x01\x0Eliquid_clipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x19bundle_magenta_open_front\x08\x07default\x0Ebundle_magenta\x08\x10bundle_open_back\x18bundle_magenta_open_back\0\0\x03\x06damage\0\x01\x04foil\0\x03\x11creative_category\x06\x03\x0Emax_stack_size\x02\x01\x0Fstacked_by_data\0\x03\x0Bframe_count\x02\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\0\t\titem_tags\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\0\0" } ; pub const MAGENTA_BUNDLE : Self = Self { id : 867 , registry_key : "minecraft:magenta_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\t\titem_tags\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x0Fitem_properties\x05\x0Cmining_speed\0\0\x80?\x01\rhand_equipped\0\x01\x17can_destroy_in_creative\x01\x03\x06damage\0\x01\x12hidden_in_commands\x02\x01\x0Eallow_off_hand\0\x01\x0Eliquid_clipped\0\x03\x0Cuse_duration\0\x03\x0Emax_stack_size\x02\x03\x0Bframe_count\x02\x01\x0Eshould_despawn\x01\x08\x0Ecreative_group\0\x01\x0Fstacked_by_data\0\x01\x04foil\0\x03\ruse_animation\0\x03\x11creative_category\x06\x08\x10enchantable_slot\x04none\x03\x11enchantable_value\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x18bundle_magenta_open_back\x08\x11bundle_open_front\x19bundle_magenta_open_front\x08\x07default\x0Ebundle_magenta\0\0\0\0\0" } ;
pub const MAGENTA_CANDLE: Self = Self { pub const MAGENTA_CANDLE: Self = Self {
id: -415, id: -415,
registry_key: "minecraft:magenta_candle", registry_key: "minecraft:magenta_candle",
@ -92673,8 +92673,8 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const MELON_SEEDS : Self = Self { id : 293 , registry_key : "minecraft:melon_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\x0Bcrop_result\x14minecraft:melon_stem\t\x08plant_at\x08\x02\x12minecraft:farmland\x01\x1Aplant_at_any_solid_surface\0\x08\rplant_at_face\x02up\0\0\0" } ; pub const MELON_SEEDS : Self = Self { id : 293 , registry_key : "minecraft:melon_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\t\x08plant_at\x08\x02\x12minecraft:farmland\x08\x0Bcrop_result\x14minecraft:melon_stem\x01\x1Aplant_at_any_solid_surface\0\x08\rplant_at_face\x02up\0\0\0" } ;
pub const MELON_SLICE : Self = Self { id : 272 , registry_key : "minecraft:melon_slice" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x99>\x08\rcooldown_type\0\x08\x11using_converts_to\0\x03\tnutrition\x04\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\0\x03\x16minecraft:use_duration@\0\0" } ; pub const MELON_SLICE : Self = Self { id : 272 , registry_key : "minecraft:melon_slice" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\tnutrition\x04\x05\x13saturation_modifier\x9A\x99\x99>\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x03\ron_use_action\x01\x08\x11using_converts_to\0\0\0\0" } ;
pub const MELON_STEM: Self = Self { pub const MELON_STEM: Self = Self {
id: 105, id: 105,
registry_key: "minecraft:melon_stem", registry_key: "minecraft:melon_stem",
@ -92892,7 +92892,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const MUSHROOM_STEW : Self = Self { id : 260 , registry_key : "minecraft:mushroom_stew" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\rcooldown_type\0\x08\x11using_converts_to\x04bowl\x03\rcooldown_time\0\x03\ron_use_action\x01\x03\tnutrition\x0C\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x19?\x01\x0Ecan_always_eat\0\0\x03\x16minecraft:use_duration@\x03\x18minecraft:max_stack_size\x02\0\0" } ; pub const MUSHROOM_STEW : Self = Self { id : 260 , registry_key : "minecraft:mushroom_stew" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x18minecraft:max_stack_size\x02\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x03\tnutrition\x0C\x05\x13saturation_modifier\x9A\x99\x19?\x03\rcooldown_time\0\x08\x11using_converts_to\x04bowl\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const MUSIC_DISC_11: Self = Self { pub const MUSIC_DISC_11: Self = Self {
id: 554, id: 554,
registry_key: "minecraft:music_disc_11", registry_key: "minecraft:music_disc_11",
@ -93047,7 +93047,7 @@ impl BedrockItem {
component_based: true, component_based: true,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const MUTTON : Self = Self { id : 560 , registry_key : "minecraft:mutton" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\tnutrition\x04\x08\x11using_converts_to\0\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x99>\x03\rcooldown_time\0\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\0\0\0" } ; pub const MUTTON : Self = Self { id : 560 , registry_key : "minecraft:mutton" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\rcooldown_type\0\x03\tnutrition\x04\x05\x13saturation_modifier\x9A\x99\x99>\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x03\ron_use_action\x01\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\0\0\0" } ;
pub const MYCELIUM: Self = Self { pub const MYCELIUM: Self = Self {
id: 110, id: 110,
registry_key: "minecraft:mycelium", registry_key: "minecraft:mycelium",
@ -93139,7 +93139,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const NETHER_WART : Self = Self { id : 294 , registry_key : "minecraft:nether_wart" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\x0Bcrop_result\x15minecraft:nether_wart\x08\rplant_at_face\x02up\t\x08plant_at\x08\x02\tsoul_sand\x01\x1Aplant_at_any_solid_surface\0\0\0\0" } ; pub const NETHER_WART : Self = Self { id : 294 , registry_key : "minecraft:nether_wart" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\t\x08plant_at\x08\x02\tsoul_sand\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x15minecraft:nether_wart\x01\x1Aplant_at_any_solid_surface\0\0\0\0" } ;
pub const NETHER_WART_BLOCK: Self = Self { pub const NETHER_WART_BLOCK: Self = Self {
id: 214, id: 214,
registry_key: "minecraft:nether_wart_block", registry_key: "minecraft:nether_wart_block",
@ -93245,7 +93245,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const NETHERITE_SPEAR : Self = Self { id : 854 , registry_key : "minecraft:netherite_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x15minecraft:enchantable\x01\x05value\x0F\x08\x04slot\x0Bmelee_spear\0\n\x12minecraft:cooldown\x08\x04type\x06attack\x08\x08category\x05spear\x05\x08duration33\x93?\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\n\x14knockback_conditions\x02\x0Cmax_durationn\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\0\x05\x11damage_multiplier\x9A\x99\x99?\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_duration2\0\x05\tmin_speed\0\0\x10A\0\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\n\x11damage_conditions\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\x02\x0Cmax_duration\xAF\0\0\x02\x05delay\x08\0\x05\x0Fdamage_modifier\0\0\0\0\0\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x19minecraft:netherite_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04name\x19minecraft:netherite_ingot\0\0\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x16minecraft:display_name\x08\x05value\x19item.netherite_spear.name\0\n\x10minecraft:damage\x02\x05value\x05\0\0\n\x18minecraft:fire_resistant\x01\x05value\x01\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x18minecraft:netherite_tier\x12minecraft:is_spear\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\x05\rhitbox_margin\0\0\x80>\0\t\titem_tags\x08\x04\x18minecraft:netherite_tier\x12minecraft:is_spear\n\x16minecraft:swing_sounds\x08\x0Battack_miss item.netherite_spear.attack_miss\x08\nattack_hit\x1Fitem.netherite_spear.attack_hit\0\n\x0Fitem_properties\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x01\rhand_equipped\x01\x03\x06damage\n\x08\x10enchantable_slot\x0Bmelee_spear\x03\ruse_animation\0\x03\x0Emax_stack_size\x02\x01\x12hidden_in_commands\x02\x03\x11enchantable_value\x1E\x01\x0Fstacked_by_data\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Fnetherite_spear\0\0\x01\x0Eallow_off_hand\0\x03\x0Bframe_count\x02\x03\x11creative_category\x06\x01\x0Eshould_despawn\x01\x08\x0Ecreative_group\0\x01\x04foil\0\x05\x0Cmining_speed\0\0\x80?\x03\x0Cuse_duration\x80\xE4\xAF\x01\0\n\x17minecraft:use_modifiers\x08\x0Bstart_sound\x18item.netherite_spear.use\x08\x0Bstart_using\x06always\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x05\x11movement_modifier\0\0\x80?\0\n\x14minecraft:durability\x03\x0Emax_durability\xDC\x1F\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\0\n\x18minecraft:swing_duration\x05\x05value33\x93?\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\0\0" } ; pub const NETHERITE_SPEAR : Self = Self { id : 854 , registry_key : "minecraft:netherite_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x0Fitem_properties\x01\x04foil\0\x01\x0Eallow_off_hand\0\x05\x0Cmining_speed\0\0\x80?\x03\x06damage\n\x03\x0Emax_stack_size\x02\x01\x0Eshould_despawn\x01\x01\x17can_destroy_in_creative\x01\x08\x10enchantable_slot\x0Bmelee_spear\x01\x0Fstacked_by_data\0\x03\x0Cuse_duration\x80\xE4\xAF\x01\x03\x11creative_category\x06\x03\x11enchantable_value\x1E\x01\rhand_equipped\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Fnetherite_spear\0\0\x03\ruse_animation\0\x08\x0Ecreative_group\0\x03\x0Bframe_count\x02\x01\x0Eliquid_clipped\0\x01\x12hidden_in_commands\x02\0\n\x16minecraft:display_name\x08\x05value\x19item.netherite_spear.name\0\n\x18minecraft:swing_duration\x05\x05value33\x93?\0\n\x15minecraft:enchantable\x01\x05value\x0F\x08\x04slot\x0Bmelee_spear\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x11damage_conditions\x02\x0Cmax_duration\xAF\0\x05\x12min_relative_speed33\x93@\x05\tmin_speed\0\0\0\0\0\x05\x0Fdamage_modifier\0\0\0\0\n\x13dismount_conditions\x02\x0Cmax_duration2\0\x05\tmin_speed\0\0\x10A\x05\x12min_relative_speed\0\0\0\0\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x05\x11damage_multiplier\x9A\x99\x99?\n\x14knockback_conditions\x02\x0Cmax_durationn\0\x05\tmin_speed33\xA3@\x05\x12min_relative_speed\0\0\0\0\0\x05\rhitbox_margin\0\0\x80>\x02\x05delay\x08\0\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\0\0\n\x18minecraft:fire_resistant\x01\x05value\x01\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x16minecraft:swing_sounds\x08\x0Battack_miss item.netherite_spear.attack_miss\x08\nattack_hit\x1Fitem.netherite_spear.attack_hit\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x18minecraft:netherite_tier\x12minecraft:is_spear\0\n\x10minecraft:damage\x02\x05value\x05\0\0\t\titem_tags\x08\x04\x18minecraft:netherite_tier\x12minecraft:is_spear\n\x12minecraft:cooldown\x08\x08category\x05spear\x08\x04type\x06attack\x05\x08duration33\x93?\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03min\0\x03\x03max\xC8\x01\0\x03\x0Emax_durability\xDC\x1F\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\t\x05items\n\x02\x08\x04name\x19minecraft:netherite_spear\0\x08\rrepair_amount)context.other->query.remaining_durability\0\t\x05items\n\x02\x08\x04name\x19minecraft:netherite_ingot\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\0\0\n\x17minecraft:use_modifiers\x08\x0Bstart_sound\x18item.netherite_spear.use\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x05\x11movement_modifier\0\0\x80?\x08\x0Bstart_using\x06always\0\n\x19minecraft:piercing_weapon\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\0\0\0" } ;
pub const NETHERITE_SWORD: Self = Self { pub const NETHERITE_SWORD: Self = Self {
id: 617, id: 617,
registry_key: "minecraft:netherite_sword", registry_key: "minecraft:netherite_sword",
@ -93442,7 +93442,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const OMINOUS_TRIAL_KEY : Self = Self { id : 875 , registry_key : "minecraft:ominous_trial_key" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x0Fitem_properties\x01\x17can_destroy_in_creative\x01\x01\rhand_equipped\0\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\x03\x0Bframe_count\x02\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x11ominous_trial_key\0\0\x03\ruse_animation\0\x03\x0Cuse_duration\0\x03\x11enchantable_value\0\x01\x0Fstacked_by_data\0\x01\x0Eliquid_clipped\0\x01\x12hidden_in_commands\x02\x08\x10enchantable_slot\x04none\x01\x0Eallow_off_hand\0\x03\x0Emax_stack_size\x80\x01\x01\x0Eshould_despawn\x01\x03\x11creative_category\x08\x01\x04foil\0\x03\x06damage\0\0\n\x16minecraft:display_name\x08\x05value\x1Bitem.ominous_trial_key.name\0\0\0" } ; pub const OMINOUS_TRIAL_KEY : Self = Self { id : 875 , registry_key : "minecraft:ominous_trial_key" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x16minecraft:display_name\x08\x05value\x1Bitem.ominous_trial_key.name\0\n\x0Fitem_properties\x01\x0Fstacked_by_data\0\x03\x06damage\0\x03\x0Cuse_duration\0\x03\x0Emax_stack_size\x80\x01\x01\x17can_destroy_in_creative\x01\x03\x11enchantable_value\0\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\x08\x10enchantable_slot\x04none\x03\x11creative_category\x08\x01\x12hidden_in_commands\x02\x01\x0Eliquid_clipped\0\x01\x0Eshould_despawn\x01\x01\x0Eallow_off_hand\0\x01\x04foil\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x11ominous_trial_key\0\0\x03\ruse_animation\0\x03\x0Bframe_count\x02\x01\rhand_equipped\0\0\0\0" } ;
pub const OPEN_EYEBLOSSOM: Self = Self { pub const OPEN_EYEBLOSSOM: Self = Self {
id: -1018, id: -1018,
registry_key: "minecraft:open_eyeblossom", registry_key: "minecraft:open_eyeblossom",
@ -93450,7 +93450,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const ORANGE_BUNDLE : Self = Self { id : 868 , registry_key : "minecraft:orange_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x0Fitem_properties\x08\x10enchantable_slot\x04none\x08\x0Ecreative_group\0\x05\x0Cmining_speed\0\0\x80?\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x17bundle_orange_open_back\x08\x11bundle_open_front\x18bundle_orange_open_front\x08\x07default\rbundle_orange\0\0\x01\x0Fstacked_by_data\0\x03\x11creative_category\x06\x01\x17can_destroy_in_creative\x01\x01\x0Eshould_despawn\x01\x01\x12hidden_in_commands\x02\x03\x06damage\0\x03\x0Bframe_count\x02\x03\x0Cuse_duration\0\x03\x11enchantable_value\0\x01\rhand_equipped\0\x03\ruse_animation\0\x01\x0Eallow_off_hand\0\x01\x0Eliquid_clipped\0\x03\x0Emax_stack_size\x02\x01\x04foil\0\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\t\titem_tags\0\0\0\0" } ; pub const ORANGE_BUNDLE : Self = Self { id : 868 , registry_key : "minecraft:orange_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x0Fitem_properties\x01\x04foil\0\x03\x0Emax_stack_size\x02\x03\x06damage\0\x01\x12hidden_in_commands\x02\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x17bundle_orange_open_back\x08\x11bundle_open_front\x18bundle_orange_open_front\x08\x07default\rbundle_orange\0\0\x03\x0Cuse_duration\0\x08\x10enchantable_slot\x04none\x03\ruse_animation\0\x08\x0Ecreative_group\0\x01\rhand_equipped\0\x03\x11enchantable_value\0\x01\x0Eallow_off_hand\0\x03\x0Bframe_count\x02\x01\x0Fstacked_by_data\0\x01\x0Eliquid_clipped\0\x05\x0Cmining_speed\0\0\x80?\x01\x17can_destroy_in_creative\x01\x03\x11creative_category\x06\x01\x0Eshould_despawn\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\t\titem_tags\0\0\0\0" } ;
pub const ORANGE_CANDLE: Self = Self { pub const ORANGE_CANDLE: Self = Self {
id: -414, id: -414,
registry_key: "minecraft:orange_candle", registry_key: "minecraft:orange_candle",
@ -93983,7 +93983,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const PINK_BUNDLE : Self = Self { id : 869 , registry_key : "minecraft:pink_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x0Fitem_properties\x01\x04foil\0\x08\x10enchantable_slot\x04none\x03\x0Emax_stack_size\x02\x01\x0Eallow_off_hand\0\x03\x11enchantable_value\0\x01\x12hidden_in_commands\x02\x05\x0Cmining_speed\0\0\x80?\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x03\x0Cuse_duration\0\x03\x06damage\0\x08\x0Ecreative_group\0\x03\x0Bframe_count\x02\n\x0Eminecraft:icon\n\x08textures\x08\x11bundle_open_front\x16bundle_pink_open_front\x08\x10bundle_open_back\x15bundle_pink_open_back\x08\x07default\x0Bbundle_pink\0\0\x03\x11creative_category\x06\x01\x0Eliquid_clipped\0\x01\x0Eshould_despawn\x01\x01\x17can_destroy_in_creative\x01\x01\rhand_equipped\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\t\titem_tags\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\0\0" } ; pub const PINK_BUNDLE : Self = Self { id : 869 , registry_key : "minecraft:pink_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x03\x0Bframe_count\x02\x01\x0Eallow_off_hand\0\x03\x06damage\0\x08\x10enchantable_slot\x04none\x01\x0Fstacked_by_data\0\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\x01\rhand_equipped\0\x03\ruse_animation\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eshould_despawn\x01\x01\x04foil\0\x03\x11creative_category\x06\x03\x0Emax_stack_size\x02\x01\x12hidden_in_commands\x02\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x15bundle_pink_open_back\x08\x11bundle_open_front\x16bundle_pink_open_front\x08\x07default\x0Bbundle_pink\0\0\x03\x11enchantable_value\0\x01\x0Eliquid_clipped\0\x03\x0Cuse_duration\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\0\0" } ;
pub const PINK_CANDLE: Self = Self { pub const PINK_CANDLE: Self = Self {
id: -419, id: -419,
registry_key: "minecraft:pink_candle", registry_key: "minecraft:pink_candle",
@ -94124,7 +94124,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const PITCHER_POD : Self = Self { id : 297 , registry_key : "minecraft:pitcher_pod" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\x0Bcrop_result\x16minecraft:pitcher_crop\x01\x1Aplant_at_any_solid_surface\0\t\x08plant_at\x08\x02\x12minecraft:farmland\x08\rplant_at_face\x02up\0\0\0" } ; pub const PITCHER_POD : Self = Self { id : 297 , registry_key : "minecraft:pitcher_pod" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x01\x1Aplant_at_any_solid_surface\0\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x16minecraft:pitcher_crop\t\x08plant_at\x08\x02\x12minecraft:farmland\0\0\0" } ;
pub const PLANKS: Self = Self { pub const PLANKS: Self = Self {
id: 814, id: 814,
registry_key: "minecraft:planks", registry_key: "minecraft:planks",
@ -94160,7 +94160,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const POISONOUS_POTATO : Self = Self { id : 282 , registry_key : "minecraft:poisonous_potato" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x08\rcooldown_type\0\x03\tnutrition\x04\x05\x13saturation_modifier\x9A\x99\x99>\t\x07effects\n\x02\x03\x02id&\x08\x04name\x06poison\x03\x08duration\n\x03\tamplifier\0\x05\x06chance\x9A\x99\x19?\x08\rdescriptionId\rpotion.poison\0\0\x03\x16minecraft:use_duration@\0\0" } ; pub const POISONOUS_POTATO : Self = Self { id : 282 , registry_key : "minecraft:poisonous_potato" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x07effects\n\x02\x03\tamplifier\0\x03\x08duration\n\x08\x04name\x06poison\x03\x02id&\x08\rdescriptionId\rpotion.poison\x05\x06chance\x9A\x99\x19?\0\x08\rcooldown_type\0\x08\x11using_converts_to\0\x03\rcooldown_time\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x04\x01\x0Ecan_always_eat\0\x03\ron_use_action\x01\x05\x13saturation_modifier\x9A\x99\x99>\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const POLAR_BEAR_SPAWN_EGG: Self = Self { pub const POLAR_BEAR_SPAWN_EGG: Self = Self {
id: 477, id: 477,
registry_key: "minecraft:polar_bear_spawn_egg", registry_key: "minecraft:polar_bear_spawn_egg",
@ -94637,7 +94637,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const PORKCHOP : Self = Self { id : 262 , registry_key : "minecraft:porkchop" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\rcooldown_type\0\x08\x11using_converts_to\0\x03\ron_use_action\x01\x03\tnutrition\x06\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x99>\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\0\0\0" } ; pub const PORKCHOP : Self = Self { id : 262 , registry_key : "minecraft:porkchop" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x06\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x99>\x03\ron_use_action\x01\x08\rcooldown_type\0\x08\x11using_converts_to\0\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const PORTAL: Self = Self { pub const PORTAL: Self = Self {
id: 90, id: 90,
registry_key: "minecraft:portal", registry_key: "minecraft:portal",
@ -94645,7 +94645,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const POTATO : Self = Self { id : 280 , registry_key : "minecraft:potato" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:seed\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x12minecraft:potatoes\x01\x1Aplant_at_any_solid_surface\0\t\x08plant_at\x08\x02\x12minecraft:farmland\0\n\x0Eminecraft:food\x03\rcooldown_time\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x03\tnutrition\x02\x05\x13saturation_modifier\x9A\x99\x99>\x03\ron_use_action\x01\x01\x0Ecan_always_eat\0\0\0\0" } ; pub const POTATO : Self = Self { id : 280 , registry_key : "minecraft:potato" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\ron_use_action\x01\x03\rcooldown_time\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x99>\x08\x11using_converts_to\0\x03\tnutrition\x02\0\n\x0Eminecraft:seed\x01\x1Aplant_at_any_solid_surface\0\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x12minecraft:potatoes\t\x08plant_at\x08\x02\x12minecraft:farmland\0\0\0" } ;
pub const POTATOES: Self = Self { pub const POTATOES: Self = Self {
id: 142, id: 142,
registry_key: "minecraft:potatoes", registry_key: "minecraft:potatoes",
@ -94779,7 +94779,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const PUFFERFISH : Self = Self { id : 267 , registry_key : "minecraft:pufferfish" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x03\tnutrition\x02\x08\rcooldown_type\0\t\x07effects\n\x06\x03\tamplifier\x02\x08\x04name\x06poison\x08\rdescriptionId\rpotion.poison\x03\x02id&\x05\x06chance\0\0\x80?\x03\x08durationx\0\x03\x08duration\x1E\x03\tamplifier\0\x03\x02id\x12\x08\x04name\x06nausea\x08\rdescriptionId\x10potion.confusion\x05\x06chance\0\0\x80?\0\x08\rdescriptionId\rpotion.hunger\x03\x08duration\x1E\x05\x06chance\0\0\x80?\x03\x02id\"\x08\x04name\x06hunger\x03\tamplifier\x04\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\0\x01\x19minecraft:stacked_by_data\x01\0\0" } ; pub const PUFFERFISH : Self = Self { id : 267 , registry_key : "minecraft:pufferfish" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x03\tnutrition\x02\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\t\x07effects\n\x06\x03\x08durationx\x08\rdescriptionId\rpotion.poison\x03\tamplifier\x02\x03\x02id&\x05\x06chance\0\0\x80?\x08\x04name\x06poison\0\x03\tamplifier\0\x03\x02id\x12\x08\x04name\x06nausea\x05\x06chance\0\0\x80?\x08\rdescriptionId\x10potion.confusion\x03\x08duration\x1E\0\x03\x08duration\x1E\x03\x02id\"\x05\x06chance\0\0\x80?\x03\tamplifier\x04\x08\rdescriptionId\rpotion.hunger\x08\x04name\x06hunger\0\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ;
pub const PUFFERFISH_BUCKET: Self = Self { pub const PUFFERFISH_BUCKET: Self = Self {
id: 370, id: 370,
registry_key: "minecraft:pufferfish_bucket", registry_key: "minecraft:pufferfish_bucket",
@ -94801,8 +94801,8 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const PUMPKIN_PIE : Self = Self { id : 284 , registry_key : "minecraft:pumpkin_pie" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\rcooldown_type\0\x08\x11using_converts_to\0\x05\x13saturation_modifier\x9A\x99\x99>\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x03\tnutrition\x10\x03\ron_use_action\x01\0\0\0" } ; pub const PUMPKIN_PIE : Self = Self { id : 284 , registry_key : "minecraft:pumpkin_pie" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\x11using_converts_to\0\x08\rcooldown_type\0\x03\tnutrition\x10\x03\ron_use_action\x01\x03\rcooldown_time\0\x05\x13saturation_modifier\x9A\x99\x99>\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const PUMPKIN_SEEDS : Self = Self { id : 292 , registry_key : "minecraft:pumpkin_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x01\x1Aplant_at_any_solid_surface\0\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x16minecraft:pumpkin_stem\t\x08plant_at\x08\x02\x12minecraft:farmland\0\0\0" } ; pub const PUMPKIN_SEEDS : Self = Self { id : 292 , registry_key : "minecraft:pumpkin_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\t\x08plant_at\x08\x02\x12minecraft:farmland\x01\x1Aplant_at_any_solid_surface\0\x08\x0Bcrop_result\x16minecraft:pumpkin_stem\x08\rplant_at_face\x02up\0\0\0" } ;
pub const PUMPKIN_STEM: Self = Self { pub const PUMPKIN_STEM: Self = Self {
id: 104, id: 104,
registry_key: "minecraft:pumpkin_stem", registry_key: "minecraft:pumpkin_stem",
@ -94810,7 +94810,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const PURPLE_BUNDLE : Self = Self { id : 870 , registry_key : "minecraft:purple_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\0\t\titem_tags\0\0\n\x0Fitem_properties\x03\x0Bframe_count\x02\x03\x11creative_category\x06\x01\x12hidden_in_commands\x02\x01\x0Eliquid_clipped\0\x01\x0Eshould_despawn\x01\x01\x17can_destroy_in_creative\x01\x03\x0Cuse_duration\0\x01\x0Eallow_off_hand\0\x03\x06damage\0\x03\x11enchantable_value\0\x03\ruse_animation\0\x01\rhand_equipped\0\x08\x10enchantable_slot\x04none\x08\x0Ecreative_group\0\x03\x0Emax_stack_size\x02\x05\x0Cmining_speed\0\0\x80?\n\x0Eminecraft:icon\n\x08textures\x08\x07default\rbundle_purple\x08\x10bundle_open_back\x17bundle_purple_open_back\x08\x11bundle_open_front\x18bundle_purple_open_front\0\0\x01\x04foil\0\x01\x0Fstacked_by_data\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\0\0" } ; pub const PURPLE_BUNDLE : Self = Self { id : 870 , registry_key : "minecraft:purple_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x0Fitem_properties\x01\x0Fstacked_by_data\0\x08\x10enchantable_slot\x04none\x03\x11creative_category\x06\x01\x0Eallow_off_hand\0\x01\x0Eliquid_clipped\0\x01\x12hidden_in_commands\x02\x01\rhand_equipped\0\x01\x04foil\0\x08\x0Ecreative_group\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x17bundle_purple_open_back\x08\x11bundle_open_front\x18bundle_purple_open_front\x08\x07default\rbundle_purple\0\0\x03\x0Bframe_count\x02\x01\x17can_destroy_in_creative\x01\x03\x0Emax_stack_size\x02\x01\x0Eshould_despawn\x01\x03\ruse_animation\0\x05\x0Cmining_speed\0\0\x80?\x03\x0Cuse_duration\0\x03\x06damage\0\x03\x11enchantable_value\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\0\0" } ;
pub const PURPLE_CANDLE: Self = Self { pub const PURPLE_CANDLE: Self = Self {
id: -423, id: -423,
registry_key: "minecraft:purple_candle", registry_key: "minecraft:purple_candle",
@ -95000,7 +95000,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const RABBIT : Self = Self { id : 288 , registry_key : "minecraft:rabbit" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\x11using_converts_to\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x99>\x03\tnutrition\x06\x03\rcooldown_time\0\x03\ron_use_action\x01\0\0\0" } ; pub const RABBIT : Self = Self { id : 288 , registry_key : "minecraft:rabbit" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\ron_use_action\x01\x08\rcooldown_type\0\x03\tnutrition\x06\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\x9A\x99\x99>\x03\rcooldown_time\0\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\0\x03\x16minecraft:use_duration@\0\0" } ;
pub const RABBIT_FOOT: Self = Self { pub const RABBIT_FOOT: Self = Self {
id: 538, id: 538,
registry_key: "minecraft:rabbit_foot", registry_key: "minecraft:rabbit_foot",
@ -95022,7 +95022,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const RABBIT_STEW : Self = Self { id : 290 , registry_key : "minecraft:rabbit_stew" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x18minecraft:max_stack_size\x02\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x08\x11using_converts_to\x04bowl\x03\tnutrition\x14\x03\ron_use_action\x01\x05\x13saturation_modifier\x9A\x99\x19?\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\0\0" } ; pub const RABBIT_STEW : Self = Self { id : 290 , registry_key : "minecraft:rabbit_stew" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x05\x13saturation_modifier\x9A\x99\x19?\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x14\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\x08\rcooldown_type\0\x03\ron_use_action\x01\x08\x11using_converts_to\x04bowl\0\x03\x18minecraft:max_stack_size\x02\0\0" } ;
pub const RAIL: Self = Self { pub const RAIL: Self = Self {
id: 66, id: 66,
registry_key: "minecraft:rail", registry_key: "minecraft:rail",
@ -95100,7 +95100,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const RED_BUNDLE : Self = Self { id : 871 , registry_key : "minecraft:red_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\t\titem_tags\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x0Fitem_properties\x08\x10enchantable_slot\x04none\x03\x0Emax_stack_size\x02\x03\x06damage\0\x03\ruse_animation\0\x01\x0Eshould_despawn\x01\x03\x0Cuse_duration\0\x01\x17can_destroy_in_creative\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\nbundle_red\x08\x10bundle_open_back\x14bundle_red_open_back\x08\x11bundle_open_front\x15bundle_red_open_front\0\0\x01\x0Eliquid_clipped\0\x01\x04foil\0\x03\x0Bframe_count\x02\x08\x0Ecreative_group\0\x01\x0Eallow_off_hand\0\x01\x12hidden_in_commands\x02\x05\x0Cmining_speed\0\0\x80?\x03\x11enchantable_value\0\x03\x11creative_category\x06\x01\x0Fstacked_by_data\0\x01\rhand_equipped\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\0\0" } ; pub const RED_BUNDLE : Self = Self { id : 871 , registry_key : "minecraft:red_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\t\titem_tags\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x03\x11enchantable_value\0\x01\x12hidden_in_commands\x02\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x14bundle_red_open_back\x08\x11bundle_open_front\x15bundle_red_open_front\x08\x07default\nbundle_red\0\0\x01\x0Eallow_off_hand\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eliquid_clipped\0\x01\x0Eshould_despawn\x01\x08\x10enchantable_slot\x04none\x01\x0Fstacked_by_data\0\x01\x04foil\0\x01\x17can_destroy_in_creative\x01\x03\x06damage\0\x03\x11creative_category\x06\x03\x0Emax_stack_size\x02\x03\x0Cuse_duration\0\x03\x0Bframe_count\x02\x03\ruse_animation\0\x08\x0Ecreative_group\0\x01\rhand_equipped\0\0\0\0" } ;
pub const RED_CANDLE: Self = Self { pub const RED_CANDLE: Self = Self {
id: -427, id: -427,
registry_key: "minecraft:red_candle", registry_key: "minecraft:red_candle",
@ -95458,7 +95458,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const ROTTEN_FLESH : Self = Self { id : 277 , registry_key : "minecraft:rotten_flesh" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x05\x13saturation_modifier\xCD\xCC\xCC=\t\x07effects\n\x02\x03\x02id\"\x08\x04name\x06hunger\x03\tamplifier\0\x05\x06chance\xCD\xCCL?\x08\rdescriptionId\rpotion.hunger\x03\x08duration<\0\x03\tnutrition\x08\x08\x11using_converts_to\0\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\rcooldown_time\0\x03\ron_use_action\x01\0\x03\x16minecraft:use_duration@\0\0" } ; pub const ROTTEN_FLESH : Self = Self { id : 277 , registry_key : "minecraft:rotten_flesh" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x08\rcooldown_type\0\x03\tnutrition\x08\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x01\x0Ecan_always_eat\0\t\x07effects\n\x02\x05\x06chance\xCD\xCCL?\x08\rdescriptionId\rpotion.hunger\x03\x02id\"\x03\x08duration<\x08\x04name\x06hunger\x03\tamplifier\0\0\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\x03\rcooldown_time\0\0\0\0" } ;
pub const SADDLE: Self = Self { pub const SADDLE: Self = Self {
id: 374, id: 374,
registry_key: "minecraft:saddle", registry_key: "minecraft:saddle",
@ -95466,7 +95466,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const SALMON : Self = Self { id : 265 , registry_key : "minecraft:salmon" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x05\x13saturation_modifier\xCD\xCC\xCC=\x01\x0Ecan_always_eat\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\x03\rcooldown_time\0\x03\tnutrition\x04\x03\ron_use_action\x01\x08\rcooldown_type\0\0\x03\x16minecraft:use_duration@\x01\x19minecraft:stacked_by_data\x01\0\0" } ; pub const SALMON : Self = Self { id : 265 , registry_key : "minecraft:salmon" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\xCD\xCC\xCC=\x03\ron_use_action\x01\x08\rcooldown_type\0\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\x03\tnutrition\x04\x03\rcooldown_time\0\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ;
pub const SALMON_BUCKET: Self = Self { pub const SALMON_BUCKET: Self = Self {
id: 368, id: 368,
registry_key: "minecraft:salmon_bucket", registry_key: "minecraft:salmon_bucket",
@ -96027,7 +96027,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const SPIDER_EYE : Self = Self { id : 278 , registry_key : "minecraft:spider_eye" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\tnutrition\x04\x01\x0Ecan_always_eat\0\x08\x11using_converts_to\0\x08\rcooldown_type\0\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCCL?\x03\rcooldown_time\0\t\x07effects\n\x02\x03\tamplifier\0\x03\x08duration\n\x05\x06chance\0\0\x80?\x08\rdescriptionId\rpotion.poison\x03\x02id&\x08\x04name\x06poison\0\0\x03\x16minecraft:use_duration@\0\0" } ; pub const SPIDER_EYE : Self = Self { id : 278 , registry_key : "minecraft:spider_eye" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x01\x0Ecan_always_eat\0\x03\tnutrition\x04\x03\rcooldown_time\0\t\x07effects\n\x02\x03\x08duration\n\x08\x04name\x06poison\x03\tamplifier\0\x03\x02id&\x08\rdescriptionId\rpotion.poison\x05\x06chance\0\0\x80?\0\x03\ron_use_action\x01\x08\rcooldown_type\0\x05\x13saturation_modifier\xCD\xCCL?\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\x11using_converts_to\0\0\0\0" } ;
pub const SPIDER_SPAWN_EGG: Self = Self { pub const SPIDER_SPAWN_EGG: Self = Self {
id: 450, id: 450,
registry_key: "minecraft:spider_spawn_egg", registry_key: "minecraft:spider_spawn_egg",
@ -96392,7 +96392,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const STONE_SPEAR : Self = Self { id : 855 , registry_key : "minecraft:stone_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\x03\x0Emax_durability\x84\x02\0\n\x12minecraft:cooldown\x05\x08duration\0\0@?\x08\x04type\x06attack\x08\x08category\x05spear\0\n\x16minecraft:display_name\x08\x05value\x15item.stone_spear.name\0\t\titem_tags\x08\x04\x14minecraft:stone_tier\x12minecraft:is_spear\n\x0Eminecraft:tags\t\x04tags\x08\x04\x14minecraft:stone_tier\x12minecraft:is_spear\0\n\x17minecraft:use_modifiers\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x08\x0Bstart_sound\x14item.stone_spear.use\x05\x11movement_modifier\0\0\x80?\x08\x0Bstart_using\x06always\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Bitem.stone_spear.attack_hit\x08\x0Battack_miss\x1Citem.stone_spear.attack_miss\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x10minecraft:damage\x02\x05value\x02\0\0\n\x19minecraft:piercing_weapon\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\x05\rhitbox_margin\0\0\x80>\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\0\n\x0Fitem_properties\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\x03\x0Bframe_count\x02\x01\x0Eliquid_clipped\0\x03\ruse_animation\0\x01\x0Fstacked_by_data\0\x03\x11creative_category\x06\x01\x12hidden_in_commands\x02\x01\x04foil\0\x03\x0Emax_stack_size\x02\x03\x11enchantable_value\n\x08\x10enchantable_slot\x0Bmelee_spear\x03\x06damage\x04\x05\x0Cmining_speed\0\0\x80?\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bstone_spear\0\0\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x0Eshould_despawn\x01\x01\x0Eallow_off_hand\0\x01\rhand_equipped\x01\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x15minecraft:stone_spear\0\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04tags,q.all_tags('minecraft:stone_tool_materials')\0\0\0\n\x18minecraft:swing_duration\x05\x05value\0\0@?\0\n\x15minecraft:enchantable\x01\x05value\x05\x08\x04slot\x0Bmelee_spear\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\x02\x05delay\x0E\0\x05\x0Fdamage_modifier\0\0\0\0\x05\x11damage_multiplier\x85\xEBQ?\x05\rhitbox_margin\0\0\x80>\n\x11damage_conditions\x02\x0Cmax_duration\x13\x01\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\0\n\x14knockback_conditions\x02\x0Cmax_duration\xB4\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\n\x13dismount_conditions\x02\x0Cmax_durationZ\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed\0\0PA\0\0\0\0\0" } ; pub const STONE_SPEAR : Self = Self { id : 855 , registry_key : "minecraft:stone_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x15minecraft:stone_spear\0\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04tags,q.all_tags('minecraft:stone_tool_materials')\0\0\0\n\x17minecraft:use_modifiers\x05\x11movement_modifier\0\0\x80?\x08\x0Bstart_using\x06always\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\x08\x0Bstart_sound\x14item.stone_spear.use\0\n\x19minecraft:piercing_weapon\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\x03\x0Emax_durability\x84\x02\0\n\x0Fitem_properties\x03\x11creative_category\x06\x01\rhand_equipped\x01\x03\x0Emax_stack_size\x02\x01\x0Eallow_off_hand\0\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x03\x0Bframe_count\x02\x08\x0Ecreative_group\0\x01\x0Fstacked_by_data\0\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\x04foil\0\x03\ruse_animation\0\x05\x0Cmining_speed\0\0\x80?\x08\x10enchantable_slot\x0Bmelee_spear\x01\x12hidden_in_commands\x02\x03\x11enchantable_value\n\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bstone_spear\0\0\x03\x06damage\x04\x01\x0Eshould_despawn\x01\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\t\titem_tags\x08\x04\x14minecraft:stone_tier\x12minecraft:is_spear\n\x10minecraft:damage\x02\x05value\x02\0\0\n\x16minecraft:display_name\x08\x05value\x15item.stone_spear.name\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_durationZ\0\x05\tmin_speed\0\0PA\0\x05\x0Fdamage_modifier\0\0\0\0\n\x14knockback_conditions\x02\x0Cmax_duration\xB4\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\0\x05\x11damage_multiplier\x85\xEBQ?\x05\rhitbox_margin\0\0\x80>\x02\x05delay\x0E\0\n\x11damage_conditions\x02\x0Cmax_duration\x13\x01\x05\x12min_relative_speed33\x93@\x05\tmin_speed\0\0\0\0\0\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\0\0\n\x15minecraft:enchantable\x08\x04slot\x0Bmelee_spear\x01\x05value\x05\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x18minecraft:swing_duration\x05\x05value\0\0@?\0\n\x12minecraft:cooldown\x08\x04type\x06attack\x05\x08duration\0\0@?\x08\x08category\x05spear\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Bitem.stone_spear.attack_hit\x08\x0Battack_miss\x1Citem.stone_spear.attack_miss\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x14minecraft:stone_tier\x12minecraft:is_spear\0\0\0" } ;
pub const STONE_STAIRS: Self = Self { pub const STONE_STAIRS: Self = Self {
id: 67, id: 67,
registry_key: "minecraft:stone_stairs", registry_key: "minecraft:stone_stairs",
@ -96771,8 +96771,8 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const SUSPICIOUS_STEW : Self = Self { id : 602 , registry_key : "minecraft:suspicious_stew" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x08\rcooldown_type\0\x08\x11using_converts_to\x04bowl\x05\x13saturation_modifier\x9A\x99\x19?\x01\x0Ecan_always_eat\x01\x03\rcooldown_time\0\x03\tnutrition\x0C\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x03\ron_use_action\x02\0\x03\x16minecraft:use_duration@\x03\x18minecraft:max_stack_size\x02\0\0" } ; pub const SUSPICIOUS_STEW : Self = Self { id : 602 , registry_key : "minecraft:suspicious_stew" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\rcooldown_time\0\x03\tnutrition\x0C\x01\x0Ecan_always_eat\x01\x03\ron_use_action\x02\x05\x13saturation_modifier\x9A\x99\x19?\x08\rcooldown_type\0\x08\x11using_converts_to\x04bowl\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\x03\x18minecraft:max_stack_size\x02\x03\x16minecraft:use_duration@\0\0" } ;
pub const SWEET_BERRIES : Self = Self { id : 287 , registry_key : "minecraft:sweet_berries" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\rcooldown_type\0\x05\x13saturation_modifier\x9A\x99\x99>\x03\tnutrition\x04\x08\x11using_converts_to\0\x03\rcooldown_time\0\x03\ron_use_action\x01\x01\x0Ecan_always_eat\0\0\n\x0Eminecraft:seed\x08\rplant_at_face\x02up\t\x08plant_at\x08\x14\x08farmland\x05grass\x04dirt\x0Bcoarse_dirt\x06podzol\nmoss_block\x08mycelium\x03mud\x14muddy_mangrove_roots\x0Fdirt_with_roots\x08\x0Bcrop_result\x1Aminecraft:sweet_berry_bush\x01\x1Aplant_at_any_solid_surface\0\0\x03\x16minecraft:use_duration@\0\0" } ; pub const SWEET_BERRIES : Self = Self { id : 287 , registry_key : "minecraft:sweet_berries" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x05\x13saturation_modifier\x9A\x99\x99>\x01\x0Ecan_always_eat\0\x03\ron_use_action\x01\x08\x11using_converts_to\0\x03\tnutrition\x04\x03\rcooldown_time\0\x08\rcooldown_type\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\0\n\x0Eminecraft:seed\t\x08plant_at\x08\x14\x08farmland\x05grass\x04dirt\x0Bcoarse_dirt\x06podzol\nmoss_block\x08mycelium\x03mud\x14muddy_mangrove_roots\x0Fdirt_with_roots\x01\x1Aplant_at_any_solid_surface\0\x08\x0Bcrop_result\x1Aminecraft:sweet_berry_bush\x08\rplant_at_face\x02up\0\0\0" } ;
pub const SWEET_BERRY_BUSH: Self = Self { pub const SWEET_BERRY_BUSH: Self = Self {
id: -207, id: -207,
registry_key: "minecraft:sweet_berry_bush", registry_key: "minecraft:sweet_berry_bush",
@ -96871,7 +96871,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const TORCHFLOWER_SEEDS : Self = Self { id : 296 , registry_key : "minecraft:torchflower_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\t\x08plant_at\x08\x02\x12minecraft:farmland\x08\rplant_at_face\x02up\x01\x1Aplant_at_any_solid_surface\0\x08\x0Bcrop_result\x1Aminecraft:torchflower_crop\0\0\0" } ; pub const TORCHFLOWER_SEEDS : Self = Self { id : 296 , registry_key : "minecraft:torchflower_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\x0Bcrop_result\x1Aminecraft:torchflower_crop\t\x08plant_at\x08\x02\x12minecraft:farmland\x08\rplant_at_face\x02up\x01\x1Aplant_at_any_solid_surface\0\0\0\0" } ;
pub const TOTEM_OF_UNDYING: Self = Self { pub const TOTEM_OF_UNDYING: Self = Self {
id: 578, id: 578,
registry_key: "minecraft:totem_of_undying", registry_key: "minecraft:totem_of_undying",
@ -96900,7 +96900,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const TRIAL_KEY : Self = Self { id : 876 , registry_key : "minecraft:trial_key" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Fitem_properties\x08\x0Ecreative_group\0\x01\x0Fstacked_by_data\0\x01\x17can_destroy_in_creative\x01\x01\x0Eliquid_clipped\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eallow_off_hand\0\x03\x0Bframe_count\x02\x03\x0Cuse_duration\0\x03\x06damage\0\x03\x0Emax_stack_size\x80\x01\x08\x10enchantable_slot\x04none\x01\x12hidden_in_commands\x02\x03\ruse_animation\0\x01\x04foil\0\x03\x11enchantable_value\0\x01\rhand_equipped\0\x03\x11creative_category\x08\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\ttrial_key\0\0\0\t\titem_tags\0\0\n\x16minecraft:display_name\x08\x05value\x13item.trial_key.name\0\0\0" } ; pub const TRIAL_KEY : Self = Self { id : 876 , registry_key : "minecraft:trial_key" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Fitem_properties\x01\x04foil\0\x03\x0Bframe_count\x02\x08\x10enchantable_slot\x04none\x01\x0Eshould_despawn\x01\x01\x12hidden_in_commands\x02\x03\x0Emax_stack_size\x80\x01\x03\x0Cuse_duration\0\x03\x06damage\0\x03\x11enchantable_value\0\x01\rhand_equipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\ttrial_key\0\0\x03\x11creative_category\x08\x01\x0Eliquid_clipped\0\x05\x0Cmining_speed\0\0\x80?\x01\x17can_destroy_in_creative\x01\x03\ruse_animation\0\x01\x0Fstacked_by_data\0\x08\x0Ecreative_group\0\x01\x0Eallow_off_hand\0\0\t\titem_tags\0\0\n\x16minecraft:display_name\x08\x05value\x13item.trial_key.name\0\0\0" } ;
pub const TRIAL_SPAWNER: Self = Self { pub const TRIAL_SPAWNER: Self = Self {
id: -315, id: -315,
registry_key: "minecraft:trial_spawner", registry_key: "minecraft:trial_spawner",
@ -96929,7 +96929,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const TROPICAL_FISH : Self = Self { id : 266 , registry_key : "minecraft:tropical_fish" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\x03\x16minecraft:use_duration@\n\x0Eminecraft:food\x03\tnutrition\x02\x01\x0Ecan_always_eat\0\x08\rcooldown_type\0\x03\ron_use_action\x01\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\x03\rcooldown_time\0\0\x01\x19minecraft:stacked_by_data\x01\0\0" } ; pub const TROPICAL_FISH : Self = Self { id : 266 , registry_key : "minecraft:tropical_fish" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:food\x03\tnutrition\x02\x01\x0Ecan_always_eat\0\x03\rcooldown_time\0\t\x0Con_use_range\x05\x06\0\0\0A\0\0\0A\0\0\0A\x08\rcooldown_type\0\x03\ron_use_action\x01\x05\x13saturation_modifier\xCD\xCC\xCC=\x08\x11using_converts_to\0\0\x01\x19minecraft:stacked_by_data\x01\x03\x16minecraft:use_duration@\0\0" } ;
pub const TROPICAL_FISH_BUCKET: Self = Self { pub const TROPICAL_FISH_BUCKET: Self = Self {
id: 369, id: 369,
registry_key: "minecraft:tropical_fish_bucket", registry_key: "minecraft:tropical_fish_bucket",
@ -97980,8 +97980,8 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const WHEAT_SEEDS : Self = Self { id : 291 , registry_key : "minecraft:wheat_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\x0Bcrop_result\x0Fminecraft:wheat\x08\rplant_at_face\x02up\x01\x1Aplant_at_any_solid_surface\0\t\x08plant_at\x08\x02\x12minecraft:farmland\0\0\0" } ; pub const WHEAT_SEEDS : Self = Self { id : 291 , registry_key : "minecraft:wheat_seeds" , version : BedrockItemVersion :: Legacy , component_based : false , definition_components : b"\n\0\n\ncomponents\n\x0Eminecraft:seed\x08\rplant_at_face\x02up\x08\x0Bcrop_result\x0Fminecraft:wheat\x01\x1Aplant_at_any_solid_surface\0\t\x08plant_at\x08\x02\x12minecraft:farmland\0\0\0" } ;
pub const WHITE_BUNDLE : Self = Self { id : 872 , registry_key : "minecraft:white_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x03\ruse_animation\0\x01\x0Eshould_despawn\x01\x01\x0Fstacked_by_data\0\x01\x17can_destroy_in_creative\x01\x03\x0Bframe_count\x02\x01\rhand_equipped\0\x01\x12hidden_in_commands\x02\x08\x0Ecreative_group\0\x03\x0Cuse_duration\0\x08\x10enchantable_slot\x04none\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x16bundle_white_open_back\x08\x11bundle_open_front\x17bundle_white_open_front\x08\x07default\x0Cbundle_white\0\0\x03\x0Emax_stack_size\x02\x03\x11creative_category\x06\x03\x06damage\0\x01\x0Eliquid_clipped\0\x01\x04foil\0\x03\x11enchantable_value\0\x05\x0Cmining_speed\0\0\x80?\x01\x0Eallow_off_hand\0\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\x03\tmax_slots\x80\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\t\rallowed_items\0\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\t\titem_tags\0\0\0\0" } ; pub const WHITE_BUNDLE : Self = Self { id : 872 , registry_key : "minecraft:white_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\n\x0Fitem_properties\x01\x0Eliquid_clipped\0\x01\x04foil\0\x01\rhand_equipped\0\x01\x0Eallow_off_hand\0\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x16bundle_white_open_back\x08\x11bundle_open_front\x17bundle_white_open_front\x08\x07default\x0Cbundle_white\0\0\x01\x0Fstacked_by_data\0\x03\x11enchantable_value\0\x01\x12hidden_in_commands\x02\x05\x0Cmining_speed\0\0\x80?\x08\x10enchantable_slot\x04none\x03\x0Bframe_count\x02\x03\x0Emax_stack_size\x02\x03\x0Cuse_duration\0\x03\x11creative_category\x06\x01\x0Eshould_despawn\x01\x03\ruse_animation\0\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\x03\x06damage\0\0\t\titem_tags\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\x03\tmax_slots\x80\x01\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\0\0" } ;
pub const WHITE_CANDLE: Self = Self { pub const WHITE_CANDLE: Self = Self {
id: -413, id: -413,
registry_key: "minecraft:white_candle", registry_key: "minecraft:white_candle",
@ -98101,7 +98101,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const WIND_CHARGE : Self = Self { id : 877 , registry_key : "minecraft:wind_charge" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Fitem_properties\x01\rhand_equipped\0\x01\x0Eshould_despawn\x01\x03\x0Bframe_count\x02\x08\x0Ecreative_group\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bwind_charge\0\0\x03\x11enchantable_value\0\x08\x10enchantable_slot\x04none\x01\x0Fstacked_by_data\0\x03\ruse_animation\0\x03\x11creative_category\x06\x01\x17can_destroy_in_creative\x01\x03\x06damage\0\x01\x04foil\0\x03\x0Cuse_duration\0\x05\x0Cmining_speed\0\0\x80?\x03\x0Emax_stack_size\x80\x01\x01\x12hidden_in_commands\x02\x01\x0Eliquid_clipped\0\x01\x0Eallow_off_hand\0\0\t\titem_tags\0\0\n\x12minecraft:cooldown\x08\x04type\x03use\x08\x08category\x0Bwind_charge\x05\x08duration\0\0\0?\0\n\x16minecraft:display_name\x08\x05value\x15item.wind_charge.name\0\n\x14minecraft:projectile\x08\x11projectile_entity\"minecraft:wind_charge_projectile<>\x05\x16minimum_critical_power\0\0\0\0\0\n\x13minecraft:throwable\x05\x12launch_power_scale\0\0\xC0?\x01\x12do_swing_animation\x01\x05\x11max_draw_duration\0\0\0\0\x05\x11min_draw_duration\0\0\0\0\x05\x10max_launch_power\0\0\xC0?\x01\x1Cscale_power_by_draw_duration\0\0\0\0" } ; pub const WIND_CHARGE : Self = Self { id : 877 , registry_key : "minecraft:wind_charge" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x0Fitem_properties\x03\x11enchantable_value\0\x03\x0Emax_stack_size\x80\x01\x01\x17can_destroy_in_creative\x01\x01\x0Eshould_despawn\x01\x01\x0Fstacked_by_data\0\x08\x0Ecreative_group\0\x03\x0Bframe_count\x02\x01\x0Eallow_off_hand\0\x03\x06damage\0\x03\x11creative_category\x06\x03\x0Cuse_duration\0\x01\rhand_equipped\0\x01\x04foil\0\x01\x12hidden_in_commands\x02\x01\x0Eliquid_clipped\0\x05\x0Cmining_speed\0\0\x80?\x03\ruse_animation\0\x08\x10enchantable_slot\x04none\n\x0Eminecraft:icon\n\x08textures\x08\x07default\x0Bwind_charge\0\0\0\n\x14minecraft:projectile\x08\x11projectile_entity\"minecraft:wind_charge_projectile<>\x05\x16minimum_critical_power\0\0\0\0\0\n\x12minecraft:cooldown\x08\x08category\x0Bwind_charge\x05\x08duration\0\0\0?\x08\x04type\x03use\0\n\x13minecraft:throwable\x05\x10max_launch_power\0\0\xC0?\x01\x12do_swing_animation\x01\x05\x12launch_power_scale\0\0\xC0?\x05\x11min_draw_duration\0\0\0\0\x01\x1Cscale_power_by_draw_duration\0\x05\x11max_draw_duration\0\0\0\0\0\n\x16minecraft:display_name\x08\x05value\x15item.wind_charge.name\0\t\titem_tags\0\0\0\0" } ;
pub const WITCH_SPAWN_EGG: Self = Self { pub const WITCH_SPAWN_EGG: Self = Self {
id: 456, id: 456,
registry_key: "minecraft:witch_spawn_egg", registry_key: "minecraft:witch_spawn_egg",
@ -98214,7 +98214,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const WOODEN_SPEAR : Self = Self { id : 856 , registry_key : "minecraft:wooden_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x16minecraft:display_name\x08\x05value\x16item.wooden_spear.name\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x15minecraft:wooden_tier\x12minecraft:is_spear\0\n\x18minecraft:swing_duration\x05\x05valueff&?\0\n\x17minecraft:use_modifiers\x05\x11movement_modifier\0\0\x80?\x05\x0Cuse_duration\0\xA0\x8CG\x08\x0Bstart_sound\x15item.wooden_spear.use\x08\x0Bstart_using\x06always\x01\x0Femit_vibrations\0\0\n\x15minecraft:enchantable\x01\x05value\x0F\x08\x04slot\x0Bmelee_spear\0\n\x0Fitem_properties\x01\x04foil\0\x01\x0Fstacked_by_data\0\x08\x10enchantable_slot\x0Bmelee_spear\x03\x11creative_category\x06\x03\ruse_animation\0\x03\x11enchantable_value\x1E\x01\x0Eallow_off_hand\0\x08\x0Ecreative_group\0\x03\x0Emax_stack_size\x02\x03\x0Cuse_duration\x80\xE4\xAF\x01\x01\rhand_equipped\x01\x01\x12hidden_in_commands\x02\x03\x0Bframe_count\x02\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\nwood_spear\0\0\x05\x0Cmining_speed\0\0\x80?\x01\x17can_destroy_in_creative\x01\x03\x06damage\x02\x01\x0Eliquid_clipped\0\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x12minecraft:cooldown\x05\x08durationff&?\x08\x04type\x06attack\x08\x08category\x05spear\0\n\x14minecraft:durability\n\rdamage_chance\x03\x03min\0\x03\x03max\xC8\x01\0\x03\x0Emax_durabilityx\0\n\x10minecraft:damage\x02\x05value\x01\0\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\n\x13dismount_conditions\x02\x0Cmax_durationd\0\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed\0\0`A\0\n\x14knockback_conditions\x02\x0Cmax_duration\xC8\0\x05\tmin_speed33\xA3@\x05\x12min_relative_speed\0\0\0\0\0\x05\x0Fdamage_modifier\0\0\0\0\n\x11damage_conditions\x02\x0Cmax_duration,\x01\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\0\x02\x05delay\x0F\0\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\x05\x11damage_multiplier333?\x05\rhitbox_margin\0\0\x80>\n\x0Ecreative_reach\x05\x03max\0\0\xF0@\x05\x03min\0\0\0@\0\0\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x16minecraft:wooden_spear\0\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\t\x05items\n\x02\x08\x04tags\x1Eq.all_tags('minecraft:planks')\0\0\0\n\x19minecraft:piercing_weapon\x05\rhitbox_margin\0\0\x80>\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\0\n\x16minecraft:swing_sounds\x08\nattack_hit\x1Citem.wooden_spear.attack_hit\x08\x0Battack_miss\x1Ditem.wooden_spear.attack_miss\0\n\x0Eminecraft:fuel\x05\x08duration\0\0 A\0\t\titem_tags\x08\x04\x15minecraft:wooden_tier\x12minecraft:is_spear\0\0" } ; pub const WOODEN_SPEAR : Self = Self { id : 856 , registry_key : "minecraft:wooden_spear" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x12minecraft:cooldown\x05\x08durationff&?\x08\x04type\x06attack\x08\x08category\x05spear\0\n\x16minecraft:display_name\x08\x05value\x16item.wooden_spear.name\0\n\x0Eminecraft:fuel\x05\x08duration\0\0 A\0\n\x17minecraft:use_modifiers\x05\x11movement_modifier\0\0\x80?\x08\x0Bstart_using\x06always\x08\x0Bstart_sound\x15item.wooden_spear.use\x05\x0Cuse_duration\0\xA0\x8CG\x01\x0Femit_vibrations\0\0\n\x17minecraft:hand_equipped\x01\x05value\x01\0\n\x10minecraft:damage\x02\x05value\x01\0\0\n\x16minecraft:swing_sounds\x08\x0Battack_miss\x1Ditem.wooden_spear.attack_miss\x08\nattack_hit\x1Citem.wooden_spear.attack_hit\0\n\x19minecraft:piercing_weapon\n\x05reach\x05\x03max\0\0\x90@\x05\x03min\0\0\0@\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\x05\rhitbox_margin\0\0\x80>\0\n\x0Fitem_properties\x01\rhand_equipped\x01\x01\x0Eallow_off_hand\0\x01\x0Eshould_despawn\x01\n\x0Eminecraft:icon\n\x08textures\x08\x07default\nwood_spear\0\0\x03\x06damage\x02\x01\x0Eliquid_clipped\0\x03\x11creative_category\x06\x01\x04foil\0\x03\x0Emax_stack_size\x02\x03\x11enchantable_value\x1E\x03\x0Bframe_count\x02\x08\x10enchantable_slot\x0Bmelee_spear\x08\x0Ecreative_group\0\x03\ruse_animation\0\x01\x0Fstacked_by_data\0\x01\x17can_destroy_in_creative\x01\x05\x0Cmining_speed\0\0\x80?\x01\x12hidden_in_commands\x02\x03\x0Cuse_duration\x80\xE4\xAF\x01\0\n\x15minecraft:enchantable\x08\x04slot\x0Bmelee_spear\x01\x05value\x0F\0\n\x18minecraft:kinetic_weapon\n\x18minecraft:kinetic_weapon\x05\rhitbox_margin\0\0\x80>\n\x05reach\x05\x03min\0\0\0@\x05\x03max\0\0\x90@\0\n\x11damage_conditions\x02\x0Cmax_duration,\x01\x05\tmin_speed\0\0\0\0\x05\x12min_relative_speed33\x93@\0\x02\x05delay\x0F\0\n\x0Ecreative_reach\x05\x03min\0\0\0@\x05\x03max\0\0\xF0@\0\x05\x11damage_multiplier333?\n\x13dismount_conditions\x05\x12min_relative_speed\0\0\0\0\x02\x0Cmax_durationd\0\x05\tmin_speed\0\0`A\0\n\x14knockback_conditions\x05\x12min_relative_speed\0\0\0\0\x05\tmin_speed33\xA3@\x02\x0Cmax_duration\xC8\0\0\x05\x0Fdamage_modifier\0\0\0\0\0\0\n\x0Eminecraft:tags\t\x04tags\x08\x04\x15minecraft:wooden_tier\x12minecraft:is_spear\0\n\x18minecraft:swing_duration\x05\x05valueff&?\0\n\x14minecraft:durability\x03\x0Emax_durabilityx\n\rdamage_chance\x03\x03max\xC8\x01\x03\x03min\0\0\0\n\x14minecraft:repairable\t\x0Crepair_items\n\x04\x08\rrepair_amount)context.other->query.remaining_durability\t\x05items\n\x02\x08\x04name\x16minecraft:wooden_spear\0\0\t\x05items\n\x02\x08\x04tags\x1Eq.all_tags('minecraft:planks')\0\x08\rrepair_amount\x1Bquery.max_durability * 0.25\0\0\t\titem_tags\x08\x04\x15minecraft:wooden_tier\x12minecraft:is_spear\n\x18minecraft:max_stack_size\x01\x05value\x01\0\0\0" } ;
pub const WOODEN_SWORD: Self = Self { pub const WOODEN_SWORD: Self = Self {
id: 310, id: 310,
registry_key: "minecraft:wooden_sword", registry_key: "minecraft:wooden_sword",
@ -98243,7 +98243,7 @@ impl BedrockItem {
component_based: false, component_based: false,
definition_components: b"\n\0\0", definition_components: b"\n\0\0",
}; };
pub const YELLOW_BUNDLE : Self = Self { id : 873 , registry_key : "minecraft:yellow_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\t\titem_tags\0\0\n\x0Fitem_properties\x01\x0Eallow_off_hand\0\x01\x17can_destroy_in_creative\x01\x08\x0Ecreative_group\0\x01\rhand_equipped\0\x01\x0Fstacked_by_data\0\x05\x0Cmining_speed\0\0\x80?\x03\x06damage\0\x03\ruse_animation\0\x03\x0Emax_stack_size\x02\x03\x0Cuse_duration\0\x03\x0Bframe_count\x02\x01\x12hidden_in_commands\x02\x03\x11enchantable_value\0\x03\x11creative_category\x06\x08\x10enchantable_slot\x04none\x01\x04foil\0\x01\x0Eshould_despawn\x01\x01\x0Eliquid_clipped\0\n\x0Eminecraft:icon\n\x08textures\x08\x07default\rbundle_yellow\x08\x10bundle_open_back\x17bundle_yellow_open_back\x08\x11bundle_open_front\x18bundle_yellow_open_front\0\0\0\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x16minecraft:storage_item\x01\x1Aallow_nested_storage_items\x01\t\rallowed_items\0\0\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\x03\tmax_slots\x80\x01\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\0\0" } ; pub const YELLOW_BUNDLE : Self = Self { id : 873 , registry_key : "minecraft:yellow_bundle" , version : BedrockItemVersion :: DataDriven , component_based : true , definition_components : b"\n\0\n\ncomponents\n!minecraft:storage_weight_modifier\x03\x16weight_in_storage_item\x08\0\n\x0Fitem_properties\x03\ruse_animation\0\x03\x0Bframe_count\x02\x05\x0Cmining_speed\0\0\x80?\n\x0Eminecraft:icon\n\x08textures\x08\x10bundle_open_back\x17bundle_yellow_open_back\x08\x11bundle_open_front\x18bundle_yellow_open_front\x08\x07default\rbundle_yellow\0\0\x03\x0Cuse_duration\0\x01\x0Eshould_despawn\x01\x01\x17can_destroy_in_creative\x01\x03\x11creative_category\x06\x08\x0Ecreative_group\0\x01\x12hidden_in_commands\x02\x03\x06damage\0\x01\x04foil\0\x03\x0Emax_stack_size\x02\x01\rhand_equipped\0\x08\x10enchantable_slot\x04none\x01\x0Eliquid_clipped\0\x01\x0Fstacked_by_data\0\x03\x11enchantable_value\0\x01\x0Eallow_off_hand\0\0\n\x1Cminecraft:bundle_interaction\x03\x12num_viewable_slots\x18\0\n\x1Eminecraft:storage_weight_limit\x03\x10max_weight_limit\x80\x01\0\t\titem_tags\0\0\n\x16minecraft:storage_item\t\rallowed_items\0\0\x03\tmax_slots\x80\x01\x01\x1Aallow_nested_storage_items\x01\t\x0Cbanned_items\n\x04\x08\x04name\x15minecraft:shulker_box\0\x08\x04name\x1Cminecraft:undyed_shulker_box\0\0\n\x18minecraft:max_stack_size\x01\x05value\x01\0\0\0" } ;
pub const YELLOW_CANDLE: Self = Self { pub const YELLOW_CANDLE: Self = Self {
id: -417, id: -417,
registry_key: "minecraft:yellow_candle", registry_key: "minecraft:yellow_candle",

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -245,6 +245,14 @@ impl ItemStack {
} }
} }
pub fn remove_data_component(&mut self, to_remove_id: DataComponent) {
if let Some((_, c)) = self.patch.iter_mut().find(|(id, _)| *id == to_remove_id) {
*c = None;
} else {
self.patch.push((to_remove_id, None));
}
}
pub fn add_lore(&mut self, line: pumpkin_util::text::TextComponent) { pub fn add_lore(&mut self, line: pumpkin_util::text::TextComponent) {
let mut lines = self let mut lines = self
.get_data_component::<crate::data_component_impl::LoreImpl>() .get_data_component::<crate::data_component_impl::LoreImpl>()

View File

@ -10,6 +10,7 @@ use pumpkin_data::data_component_impl::{MapIdImpl, MapPostProcessingImpl};
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack; use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::screen::WindowType; use pumpkin_data::screen::WindowType;
use pumpkin_data::statistic::StatisticCategory;
use pumpkin_protocol::java::server::play::SlotActionType; use pumpkin_protocol::java::server::play::SlotActionType;
use pumpkin_world::inventory::Inventory; use pumpkin_world::inventory::Inventory;
use pumpkin_world::inventory::SimpleInventory; use pumpkin_world::inventory::SimpleInventory;
@ -146,7 +147,7 @@ impl ScreenHandler for CartographyTableScreenHandler {
} }
} }
fn quick_move(&mut self, _player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack { fn quick_move(&mut self, player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack {
let mut clicked = ItemStack::EMPTY.clone(); let mut clicked = ItemStack::EMPTY.clone();
let slot = self.get_behaviour().slots.get(slot_index as usize).cloned(); let slot = self.get_behaviour().slots.get(slot_index as usize).cloned();
@ -159,8 +160,9 @@ impl ScreenHandler for CartographyTableScreenHandler {
return ItemStack::EMPTY.clone(); return ItemStack::EMPTY.clone();
} }
slot.on_quick_move_crafted(stack.clone(), clicked.clone()); slot.on_quick_move_crafted(stack.clone(), clicked.clone());
self.input_inventory.remove_stack_specific(0, 1); let mut taken_stack = clicked.clone();
self.input_inventory.remove_stack_specific(1, 1); taken_stack.set_count(clicked.item_count - stack.item_count);
slot.on_take_item(player, &taken_stack);
} else if slot_index != 1 && slot_index != 0 { } else if slot_index != 1 && slot_index != 0 {
if is_map_item(&stack) { if is_map_item(&stack) {
if !self.insert_item(&mut stack, 0, 1, false) { if !self.insert_item(&mut stack, 0, 1, false) {
@ -358,7 +360,12 @@ impl Slot for CartographyResultSlot {
false false
} }
fn on_take_item(&self, _player: &dyn InventoryPlayer, _stack: &ItemStack) { fn on_take_item(&self, player: &dyn InventoryPlayer, stack: &ItemStack) {
player.increment_stat(
StatisticCategory::Crafted,
stack.item.id as i32,
stack.item_count as i32,
);
self.input_inventory.remove_stack_specific(0, 1); self.input_inventory.remove_stack_specific(0, 1);
self.input_inventory.remove_stack_specific(1, 1); self.input_inventory.remove_stack_specific(1, 1);
self.mark_dirty(); self.mark_dirty();

View File

@ -224,7 +224,9 @@ impl ScreenHandler for FurnaceLikeScreenHandler {
return ItemStack::EMPTY.clone(); return ItemStack::EMPTY.clone();
} }
slot.on_take_item(player, &stack); let mut taken_stack = clicked.clone();
taken_stack.set_count(clicked.item_count - stack.item_count);
slot.on_take_item(player, &taken_stack);
} }
clicked clicked

View File

@ -13,6 +13,7 @@ use pumpkin_data::dye_color::DyeColor;
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack; use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::screen::WindowType; use pumpkin_data::screen::WindowType;
use pumpkin_data::statistic::StatisticCategory;
use pumpkin_data::tag::{BannerPattern, RegistryKey, get_tag_values}; use pumpkin_data::tag::{BannerPattern, RegistryKey, get_tag_values};
use pumpkin_protocol::java::server::play::SlotActionType; use pumpkin_protocol::java::server::play::SlotActionType;
use pumpkin_world::block::entities::PropertyDelegate; use pumpkin_world::block::entities::PropertyDelegate;
@ -294,7 +295,7 @@ impl ScreenHandler for LoomScreenHandler {
} }
} }
fn quick_move(&mut self, _player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack { fn quick_move(&mut self, player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack {
let mut stack = ItemStack::EMPTY.clone(); let mut stack = ItemStack::EMPTY.clone();
let slot = self.get_behaviour().slots.get(slot_index as usize).cloned(); let slot = self.get_behaviour().slots.get(slot_index as usize).cloned();
@ -308,8 +309,9 @@ impl ScreenHandler for LoomScreenHandler {
return ItemStack::EMPTY.clone(); return ItemStack::EMPTY.clone();
} }
slot.on_quick_move_crafted(slot_stack.clone(), stack.clone()); slot.on_quick_move_crafted(slot_stack.clone(), stack.clone());
self.input_inventory.remove_stack_specific(0, 1); let mut taken_stack = stack.clone();
self.input_inventory.remove_stack_specific(1, 1); taken_stack.set_count(stack.item_count - slot_stack.item_count);
slot.on_take_item(player, &taken_stack);
} }
std::cmp::Ordering::Less => { std::cmp::Ordering::Less => {
if !self.insert_item(&mut slot_stack, 4, 40, false) { if !self.insert_item(&mut slot_stack, 4, 40, false) {
@ -469,7 +471,12 @@ impl Slot for LoomResultSlot {
false false
} }
fn on_take_item(&self, _player: &dyn InventoryPlayer, _stack: &ItemStack) { fn on_take_item(&self, player: &dyn InventoryPlayer, stack: &ItemStack) {
player.increment_stat(
StatisticCategory::Crafted,
stack.item.id as i32,
stack.item_count as i32,
);
self.input_inventory.remove_stack_specific(0, 1); self.input_inventory.remove_stack_specific(0, 1);
self.input_inventory.remove_stack_specific(1, 1); self.input_inventory.remove_stack_specific(1, 1);
if self.input_inventory.get_stack(0).is_empty() if self.input_inventory.get_stack(0).is_empty()

View File

@ -152,7 +152,7 @@ impl ScreenHandler for SmithingTableScreenHandler {
} }
} }
fn quick_move(&mut self, _player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack { fn quick_move(&mut self, player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack {
let mut stack = ItemStack::EMPTY.clone(); let mut stack = ItemStack::EMPTY.clone();
let slot = self.get_behaviour().slots.get(slot_index as usize).cloned(); let slot = self.get_behaviour().slots.get(slot_index as usize).cloned();
@ -167,9 +167,9 @@ impl ScreenHandler for SmithingTableScreenHandler {
return ItemStack::EMPTY.clone(); return ItemStack::EMPTY.clone();
} }
slot.on_quick_move_crafted(slot_stack.clone(), stack.clone()); slot.on_quick_move_crafted(slot_stack.clone(), stack.clone());
self.input_inventory.remove_stack_specific(0, 1); let mut taken_stack = stack.clone();
self.input_inventory.remove_stack_specific(1, 1); taken_stack.set_count(stack.item_count - slot_stack.item_count);
self.input_inventory.remove_stack_specific(2, 1); slot.on_take_item(player, &taken_stack);
} }
std::cmp::Ordering::Less => { std::cmp::Ordering::Less => {
// From input slots to player inventory // From input slots to player inventory

View File

@ -113,7 +113,7 @@ impl ScreenHandler for StonecutterScreenHandler {
} }
} }
fn quick_move(&mut self, _player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack { fn quick_move(&mut self, player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack {
let mut stack = ItemStack::EMPTY.clone(); let mut stack = ItemStack::EMPTY.clone();
let slot = self.get_behaviour().slots.get(slot_index as usize).cloned(); let slot = self.get_behaviour().slots.get(slot_index as usize).cloned();
@ -138,7 +138,13 @@ impl ScreenHandler for StonecutterScreenHandler {
if slot_stack.is_empty() { if slot_stack.is_empty() {
slot.set_stack(ItemStack::EMPTY.clone()); slot.set_stack(ItemStack::EMPTY.clone());
} else { } else {
slot.set_stack(slot_stack); slot.set_stack(slot_stack.clone());
}
if slot_index == 1 {
let mut taken_stack = stack.clone();
taken_stack.set_count(stack.item_count - slot_stack.item_count);
slot.on_take_item(player, &taken_stack);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/// Conditions required for an entry or pool to be eligible for loot generation. /// Conditions required for an entry or pool to be eligible for loot generation.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] #[derive(Clone, Copy, Debug, PartialEq, Default)]
pub enum LootCondition { pub enum LootCondition {
#[default] #[default]
None, None,
@ -10,6 +10,15 @@ pub enum LootCondition {
NoSilkTouchOrShears, NoSilkTouchOrShears,
SurvivesExplosion, SurvivesExplosion,
KilledByPlayer, KilledByPlayer,
RandomChance {
chance: f32,
},
RandomChanceWithEnchantedBonus {
unenchanted_chance: f32,
enchanted_chance_base: f32,
enchanted_chance_per_level_above_first: f32,
},
AllOf(&'static [Self]),
} }
/// Bonus count formulas when tools have fortune or looting enchantments. /// Bonus count formulas when tools have fortune or looting enchantments.

View File

@ -10,7 +10,7 @@ use crate::block::entities::campfire::CampfireBlockEntity;
use crate::{ use crate::{
block::{ block::{
BlockBehaviour, BlockIsReplacing, GetStateForNeighborUpdateArgs, OnEntityCollisionArgs, BlockBehaviour, BlockIsReplacing, GetStateForNeighborUpdateArgs, OnEntityCollisionArgs,
OnPlaceArgs, PathComputationType, PlacedArgs, OnPlaceArgs, PathComputationType, PlacedArgs, UseWithItemArgs, registry::BlockActionResult,
}, },
entity::EntityBase, entity::EntityBase,
}; };
@ -27,6 +27,34 @@ impl BlockBehaviour for CampfireBlock {
} }
} }
fn use_with_item(&self, args: UseWithItemArgs<'_>) -> BlockActionResult {
let state = args.world.get_block_state(args.position);
if !CampfireLikeProperties::from_state_id(state.id).lit {
return BlockActionResult::PassToDefaultBlockAction;
}
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(campfire) = block_entity.as_any().downcast_ref::<CampfireBlockEntity>()
{
let is_food = args
.item_stack
.get_data_component::<pumpkin_data::data_component_impl::FoodImpl>()
.is_some();
if is_food && campfire.add_item(args.item_stack) {
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::InteractWithCampfire as i32,
1,
);
args.item_stack
.decrement_unless_creative(args.player.gamemode.load(), 1);
return BlockActionResult::Success;
}
}
BlockActionResult::PassToDefaultBlockAction
}
// TODO: cooking food on campfire (CampfireBlockEntity) // TODO: cooking food on campfire (CampfireBlockEntity)
fn on_entity_collision(&self, args: OnEntityCollisionArgs<'_>) { fn on_entity_collision(&self, args: OnEntityCollisionArgs<'_>) {
{ {

View File

@ -8,6 +8,7 @@ use pumpkin_data::block_properties::WaterCauldronLikeProperties;
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack; use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_data::tag::Taggable;
use pumpkin_data::{Block, BlockId, BlockState}; use pumpkin_data::{Block, BlockId, BlockState};
use pumpkin_world::world::BlockFlags; use pumpkin_world::world::BlockFlags;
@ -67,7 +68,6 @@ impl BlockBehaviour for CauldronBlock {
let block_id = args.block.id; let block_id = args.block.id;
let gamemode = args.player.gamemode.load(); let gamemode = args.player.gamemode.load();
// Filling empty cauldron with buckets
if block_id == BlockId::CAULDRON { if block_id == BlockId::CAULDRON {
if item_id == Item::WATER_BUCKET.id { if item_id == Item::WATER_BUCKET.id {
if !fire_cauldron_change( if !fire_cauldron_change(
@ -92,6 +92,11 @@ impl BlockBehaviour for CauldronBlock {
); );
args.item_stack.decrement_unless_creative(gamemode, 1); args.item_stack.decrement_unless_creative(gamemode, 1);
give_item_or_drop(args.player, args.world, &Item::BUCKET); give_item_or_drop(args.player, args.world, &Item::BUCKET);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::FillCauldron as i32,
1,
);
return BlockActionResult::Success; return BlockActionResult::Success;
} else if item_id == Item::LAVA_BUCKET.id { } else if item_id == Item::LAVA_BUCKET.id {
args.world.set_block_state( args.world.set_block_state(
@ -106,6 +111,11 @@ impl BlockBehaviour for CauldronBlock {
); );
args.item_stack.decrement_unless_creative(gamemode, 1); args.item_stack.decrement_unless_creative(gamemode, 1);
give_item_or_drop(args.player, args.world, &Item::BUCKET); give_item_or_drop(args.player, args.world, &Item::BUCKET);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::FillCauldron as i32,
1,
);
return BlockActionResult::Success; return BlockActionResult::Success;
} else if item_id == Item::POWDER_SNOW_BUCKET.id { } else if item_id == Item::POWDER_SNOW_BUCKET.id {
let state_id = Block::POWDER_SNOW_CAULDRON let state_id = Block::POWDER_SNOW_CAULDRON
@ -120,6 +130,11 @@ impl BlockBehaviour for CauldronBlock {
); );
args.item_stack.decrement_unless_creative(gamemode, 1); args.item_stack.decrement_unless_creative(gamemode, 1);
give_item_or_drop(args.player, args.world, &Item::BUCKET); give_item_or_drop(args.player, args.world, &Item::BUCKET);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::FillCauldron as i32,
1,
);
return BlockActionResult::Success; return BlockActionResult::Success;
} else if item_id == Item::POTION.id { } else if item_id == Item::POTION.id {
let state_id = Block::WATER_CAULDRON let state_id = Block::WATER_CAULDRON
@ -134,11 +149,15 @@ impl BlockBehaviour for CauldronBlock {
); );
args.item_stack.decrement_unless_creative(gamemode, 1); args.item_stack.decrement_unless_creative(gamemode, 1);
give_item_or_drop(args.player, args.world, &Item::GLASS_BOTTLE); give_item_or_drop(args.player, args.world, &Item::GLASS_BOTTLE);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::UseCauldron as i32,
1,
);
return BlockActionResult::Success; return BlockActionResult::Success;
} }
} }
// Collecting fluid from full cauldrons into empty bucket
if item_id == Item::BUCKET.id { if item_id == Item::BUCKET.id {
let state_id = args.world.get_block_state_id(args.position); let state_id = args.world.get_block_state_id(args.position);
let (filled_item, sound) = if block_id == BlockId::WATER_CAULDRON { let (filled_item, sound) = if block_id == BlockId::WATER_CAULDRON {
@ -174,32 +193,190 @@ impl BlockBehaviour for CauldronBlock {
.play_sound(sound, SoundCategory::Blocks, &args.position.to_f64()); .play_sound(sound, SoundCategory::Blocks, &args.position.to_f64());
args.item_stack.decrement_unless_creative(gamemode, 1); args.item_stack.decrement_unless_creative(gamemode, 1);
give_item_or_drop(args.player, args.world, result_item); give_item_or_drop(args.player, args.world, result_item);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::UseCauldron as i32,
1,
);
return BlockActionResult::Success; return BlockActionResult::Success;
} }
} }
// Adding water bottle to non-full water cauldron if block_id == BlockId::WATER_CAULDRON {
if block_id == BlockId::WATER_CAULDRON && item_id == Item::POTION.id {
let state_id = args.world.get_block_state_id(args.position); let state_id = args.world.get_block_state_id(args.position);
let props = WaterCauldronLikeProperties::from_state_id(state_id); let props = WaterCauldronLikeProperties::from_state_id(state_id);
if props.level < 3 { if props.level > 0 {
let next_level_str = match props.level { if item_id == Item::POTION.id && props.level < 3 {
1 => "2", let next_level_str = match props.level {
_ => "3", 1 => "2",
}; _ => "3",
let new_state_id = Block::WATER_CAULDRON };
.from_properties(&[("level", next_level_str)]) let new_state_id = Block::WATER_CAULDRON
.to_state_id(&Block::WATER_CAULDRON); .from_properties(&[("level", next_level_str)])
args.world .to_state_id(&Block::WATER_CAULDRON);
.set_block_state(args.position, new_state_id, BlockFlags::NOTIFY_ALL); args.world
args.world.play_sound( .set_block_state(args.position, new_state_id, BlockFlags::NOTIFY_ALL);
Sound::ItemBottleEmpty, args.world.play_sound(
SoundCategory::Blocks, Sound::ItemBottleEmpty,
&args.position.to_f64(), SoundCategory::Blocks,
); &args.position.to_f64(),
args.item_stack.decrement_unless_creative(gamemode, 1); );
give_item_or_drop(args.player, args.world, &Item::GLASS_BOTTLE); args.item_stack.decrement_unless_creative(gamemode, 1);
return BlockActionResult::Success; give_item_or_drop(args.player, args.world, &Item::GLASS_BOTTLE);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::UseCauldron as i32,
1,
);
return BlockActionResult::Success;
}
if item_id == Item::GLASS_BOTTLE.id {
let next_level = props.level - 1;
if next_level > 0 {
let next_level_str = match next_level {
2 => "2",
_ => "1",
};
let new_state_id = Block::WATER_CAULDRON
.from_properties(&[("level", next_level_str)])
.to_state_id(&Block::WATER_CAULDRON);
args.world.set_block_state(
args.position,
new_state_id,
BlockFlags::NOTIFY_ALL,
);
} else {
args.world.set_block_state(
args.position,
Block::CAULDRON.default_state.id,
BlockFlags::NOTIFY_ALL,
);
}
args.world.play_sound(
Sound::ItemBottleFill,
SoundCategory::Blocks,
&args.position.to_f64(),
);
args.item_stack.decrement_unless_creative(gamemode, 1);
give_item_or_drop(args.player, args.world, &Item::POTION);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::UseCauldron as i32,
1,
);
return BlockActionResult::Success;
}
if args
.item_stack
.item
.has_tag(&pumpkin_data::tag::Item::MINECRAFT_SHULKER_BOXES)
&& args.item_stack.item.id != Item::SHULKER_BOX.id
{
let next_level = props.level - 1;
if next_level > 0 {
let next_level_str = match next_level {
2 => "2",
_ => "1",
};
let new_state_id = Block::WATER_CAULDRON
.from_properties(&[("level", next_level_str)])
.to_state_id(&Block::WATER_CAULDRON);
args.world.set_block_state(
args.position,
new_state_id,
BlockFlags::NOTIFY_ALL,
);
} else {
args.world.set_block_state(
args.position,
Block::CAULDRON.default_state.id,
BlockFlags::NOTIFY_ALL,
);
}
args.item_stack.item = &Item::SHULKER_BOX;
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::CleanShulkerBox as i32,
1,
);
return BlockActionResult::Success;
}
if args
.item_stack
.get_data_component::<pumpkin_data::data_component_impl::BannerPatternsImpl>()
.is_some()
{
let next_level = props.level - 1;
if next_level > 0 {
let next_level_str = match next_level {
2 => "2",
_ => "1",
};
let new_state_id = Block::WATER_CAULDRON
.from_properties(&[("level", next_level_str)])
.to_state_id(&Block::WATER_CAULDRON);
args.world.set_block_state(
args.position,
new_state_id,
BlockFlags::NOTIFY_ALL,
);
} else {
args.world.set_block_state(
args.position,
Block::CAULDRON.default_state.id,
BlockFlags::NOTIFY_ALL,
);
}
args.item_stack.remove_data_component(
pumpkin_data::data_component::DataComponent::BannerPatterns,
);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::CleanBanner as i32,
1,
);
return BlockActionResult::Success;
}
if args
.item_stack
.get_data_component::<pumpkin_data::data_component_impl::DyedColorImpl>()
.is_some()
{
let next_level = props.level - 1;
if next_level > 0 {
let next_level_str = match next_level {
2 => "2",
_ => "1",
};
let new_state_id = Block::WATER_CAULDRON
.from_properties(&[("level", next_level_str)])
.to_state_id(&Block::WATER_CAULDRON);
args.world.set_block_state(
args.position,
new_state_id,
BlockFlags::NOTIFY_ALL,
);
} else {
args.world.set_block_state(
args.position,
Block::CAULDRON.default_state.id,
BlockFlags::NOTIFY_ALL,
);
}
args.item_stack.remove_data_component(
pumpkin_data::data_component::DataComponent::DyedColor,
);
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::CleanArmor as i32,
1,
);
return BlockActionResult::Success;
}
} }
} }

View File

@ -166,9 +166,14 @@ fn get_chest_comparator_output(args: &GetComparatorOutputArgs<'_>) -> Option<u8>
} }
fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult { fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult {
let stat = if args.block.id == Block::TRAPPED_CHEST.id {
pumpkin_data::statistic::CustomStatistic::TriggerTrappedChest
} else {
pumpkin_data::statistic::CustomStatistic::OpenChest
};
args.player.increment_stat( args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom, pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::OpenChest as i32, stat as i32,
1, 1,
); );
let state = args.world.get_block_state_id(args.position); let state = args.world.get_block_state_id(args.position);

View File

@ -1,15 +1,18 @@
use crate::{ use crate::{
block::{ block::{
BlockBehaviour, BlockMetadata, GetStateForNeighborUpdateArgs, OnScheduledTickArgs, BlockBehaviour, BlockMetadata, GetStateForNeighborUpdateArgs, OnPlaceArgs,
PlacedArgs, OnScheduledTickArgs, PlacedArgs,
}, },
entity::falling::FallingEntity, entity::falling::FallingEntity,
}; };
use pumpkin_data::{ use pumpkin_data::{
Block, BlockId, BlockState, BlockStateId, Block, BlockDirection, BlockId, BlockState, BlockStateId,
tag::{self, Taggable}, tag::{self, Taggable},
}; };
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::tick::TickPriority; use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockAccessor;
pub struct FallingBlock; pub struct FallingBlock;
impl FallingBlock { impl FallingBlock {
@ -20,27 +23,80 @@ impl FallingBlock {
|| state.is_liquid() || state.is_liquid()
|| state.replaceable() || state.replaceable()
} }
#[must_use]
pub fn touches_liquid(world: &dyn BlockAccessor, pos: &BlockPos) -> bool {
for dir in BlockDirection::all() {
if dir == BlockDirection::Down {
continue;
}
let neighbor = world.get_block_state(&pos.offset(dir.to_offset()));
if neighbor.is_liquid() {
return true;
}
}
false
}
} }
impl BlockMetadata for FallingBlock { impl BlockMetadata for FallingBlock {
fn ids() -> Box<[BlockId]> { fn ids() -> Box<[BlockId]> {
[BlockId::GRAVEL, BlockId::SAND, BlockId::RED_SAND].into() [
BlockId::GRAVEL,
BlockId::SAND,
BlockId::RED_SAND,
BlockId::SUSPICIOUS_SAND,
BlockId::SUSPICIOUS_GRAVEL,
BlockId::WHITE_CONCRETE_POWDER,
BlockId::ORANGE_CONCRETE_POWDER,
BlockId::MAGENTA_CONCRETE_POWDER,
BlockId::LIGHT_BLUE_CONCRETE_POWDER,
BlockId::YELLOW_CONCRETE_POWDER,
BlockId::LIME_CONCRETE_POWDER,
BlockId::PINK_CONCRETE_POWDER,
BlockId::GRAY_CONCRETE_POWDER,
BlockId::LIGHT_GRAY_CONCRETE_POWDER,
BlockId::CYAN_CONCRETE_POWDER,
BlockId::PURPLE_CONCRETE_POWDER,
BlockId::BLUE_CONCRETE_POWDER,
BlockId::BROWN_CONCRETE_POWDER,
BlockId::GREEN_CONCRETE_POWDER,
BlockId::RED_CONCRETE_POWDER,
BlockId::BLACK_CONCRETE_POWDER,
]
.into()
} }
} }
impl BlockBehaviour for FallingBlock { impl BlockBehaviour for FallingBlock {
fn placed(&self, args: PlacedArgs<'_>) { fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
if args.block.has_tag(&tag::Block::MINECRAFT_CONCRETE_POWDERS)
&& Self::touches_liquid(args.world, args.position)
&& let Some(name) = args.block.name.strip_suffix("_powder")
&& let Some(concrete) = Block::from_name(name)
{ {
// TODO: make delay configurable return concrete.default_state.id;
args.world
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
} }
args.block.default_state.id
} }
fn placed(&self, args: PlacedArgs<'_>) {
args.world
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
}
fn get_state_for_neighbor_update( fn get_state_for_neighbor_update(
&self, &self,
args: GetStateForNeighborUpdateArgs<'_>, args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId { ) -> BlockStateId {
// TODO: make delay configurable if args.block.has_tag(&tag::Block::MINECRAFT_CONCRETE_POWDERS)
&& Self::touches_liquid(args.world, args.position)
&& let Some(name) = args.block.name.strip_suffix("_powder")
&& let Some(concrete) = Block::from_name(name)
{
return concrete.default_state.id;
}
args.world args.world
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal); .schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
args.state_id args.state_id

View File

@ -22,6 +22,11 @@ impl BlockBehaviour for FlowerPotBlock {
Block::from_id(potted_block_id).default_state.id, Block::from_id(potted_block_id).default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
); );
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::PotFlower as i32,
1,
);
} }
return BlockActionResult::Success; return BlockActionResult::Success;
} else if potted_block_id != BlockId::AIR { } else if potted_block_id != BlockId::AIR {

View File

@ -1,10 +1,8 @@
use pumpkin_data::BlockStateId; use pumpkin_data::block_properties::{
use pumpkin_data::{ DoubleBlockHalf, GrassBlockLikeProperties, TallSeagrassLikeProperties,
Block, BlockState,
block_properties::{DoubleBlockHalf, GrassBlockLikeProperties, TallSeagrassLikeProperties},
tag::{self, Taggable},
}; };
use pumpkin_macros::pumpkin_block; use pumpkin_data::tag::{self, Taggable};
use pumpkin_data::{Block, BlockDirection, BlockId, BlockState, BlockStateId};
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use pumpkin_util::random::{RandomGenerator, RandomImpl, xoroshiro128::Xoroshiro}; use pumpkin_util::random::{RandomGenerator, RandomImpl, xoroshiro128::Xoroshiro};
use pumpkin_world::generation::feature::{ use pumpkin_world::generation::feature::{
@ -15,13 +13,28 @@ use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockFlags; use pumpkin_world::world::BlockFlags;
use rand::RngExt; use rand::RngExt;
use crate::block::{BlockBehaviour, GetStateForNeighborUpdateArgs}; use crate::block::{BlockBehaviour, BlockMetadata, GetStateForNeighborUpdateArgs, OnPlaceArgs};
#[pumpkin_block("minecraft:grass_block")]
pub struct GrassBlock; pub struct GrassBlock;
impl BlockMetadata for GrassBlock {
fn ids() -> Box<[BlockId]> {
[BlockId::GRASS_BLOCK, BlockId::MYCELIUM, BlockId::PODZOL].into()
}
}
impl BlockBehaviour for GrassBlock { impl BlockBehaviour for GrassBlock {
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let block_above = args.world.get_block(&args.position.up());
let mut props = GrassBlockLikeProperties::from_state_id(args.block.default_state.id);
props.snowy = block_above.has_tag(&tag::Block::MINECRAFT_SNOW);
props.to_state_id(args.block)
}
fn is_valid_bonemeal_target(&self, args: crate::block::BonemealArgs<'_>) -> bool { fn is_valid_bonemeal_target(&self, args: crate::block::BonemealArgs<'_>) -> bool {
if args.block != &Block::GRASS_BLOCK {
return false;
}
let above = args.position.up(); let above = args.position.up();
args.world.is_in_height_limit(above.0.y) args.world.is_in_height_limit(above.0.y)
&& args.world.is_loaded(&above) && args.world.is_loaded(&above)
@ -33,6 +46,10 @@ impl BlockBehaviour for GrassBlock {
const ATTEMPTS_PER_STEP: i32 = 16; const ATTEMPTS_PER_STEP: i32 = 16;
const FLOWER_CHANCE: i32 = 8; const FLOWER_CHANCE: i32 = 8;
if args.block != &Block::GRASS_BLOCK {
return;
}
let origin = args.position.up(); let origin = args.position.up();
for attempt in 0..SPREAD_ATTEMPTS { for attempt in 0..SPREAD_ATTEMPTS {
let mut target = origin; let mut target = origin;
@ -108,15 +125,17 @@ impl BlockBehaviour for GrassBlock {
&self, &self,
args: GetStateForNeighborUpdateArgs<'_>, args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId { ) -> BlockStateId {
let block_above = args.world.get_block(&args.position.up()); if args.direction == BlockDirection::Up {
let mut props = GrassBlockLikeProperties::from_state_id(args.state_id); let block_above = args.world.get_block(args.neighbor_position);
let should_be_snowy = block_above.has_tag(&tag::Block::MINECRAFT_SNOW); let mut props = GrassBlockLikeProperties::from_state_id(args.state_id);
if props.snowy == should_be_snowy { let should_be_snowy = block_above.has_tag(&tag::Block::MINECRAFT_SNOW);
return args.state_id; if props.snowy == should_be_snowy {
return args.state_id;
}
props.snowy = should_be_snowy;
return props.to_state_id(args.block);
} }
props.snowy = should_be_snowy; args.state_id
props.to_state_id(&Block::GRASS_BLOCK)
} }
} }

View File

@ -0,0 +1,29 @@
use pumpkin_macros::pumpkin_block;
use crate::block::{
BlockBehaviour, OnLandedUponArgs, PathComputationType, UpdateEntityMovementAfterFallOnArgs,
stop_vertical_movement_after_fall,
};
#[pumpkin_block("minecraft:honey_block")]
pub struct HoneyBlock;
impl BlockBehaviour for HoneyBlock {
fn on_landed_upon(&self, args: OnLandedUponArgs<'_>) {
if let Some(living) = args.entity.get_living_entity() {
living.handle_fall_damage(args.entity, args.fall_distance, 0.2);
}
}
fn update_entity_movement_after_fall_on(&self, args: UpdateEntityMovementAfterFallOnArgs<'_>) {
stop_vertical_movement_after_fall(args.entity);
}
fn is_pathfindable(
&self,
_state: &pumpkin_data::BlockState,
_computation_type: PathComputationType,
) -> bool {
false
}
}

View File

@ -9,8 +9,10 @@ use pumpkin_world::{
world::{BlockAccessor, BlockFlags}, world::{BlockAccessor, BlockFlags},
}; };
use crate::block::blocks::plant::mangrove_propagule::MangrovePropaguleBlock;
use crate::block::{ use crate::block::{
BlockBehaviour, GetStateForNeighborUpdateArgs, OnPlaceArgs, OnScheduledTickArgs, RandomTickArgs, BlockBehaviour, BonemealArgs, GetStateForNeighborUpdateArgs, OnPlaceArgs, OnScheduledTickArgs,
RandomTickArgs,
}; };
pub const DECAY_DISTANCE: u8 = 7; pub const DECAY_DISTANCE: u8 = 7;
@ -103,4 +105,23 @@ impl BlockBehaviour for LeavesBlock {
.break_block(args.position, None, BlockFlags::empty()); .break_block(args.position, None, BlockFlags::empty());
} }
} }
fn is_valid_bonemeal_target(&self, args: BonemealArgs<'_>) -> bool {
args.block == &Block::MANGROVE_LEAVES
&& args.world.get_block_state(&args.position.down()).is_air()
}
fn is_bonemeal_success(&self, args: BonemealArgs<'_>) -> bool {
args.block == &Block::MANGROVE_LEAVES
}
fn perform_bonemeal(&self, args: BonemealArgs<'_>) {
if args.block == &Block::MANGROVE_LEAVES {
args.world.set_block_state(
&args.position.down(),
MangrovePropaguleBlock::create_new_hanging_propagule(0),
BlockFlags::NOTIFY_ALL,
);
}
}
} }

View File

@ -0,0 +1,65 @@
use pumpkin_data::BlockStateId;
use pumpkin_data::block_properties::LightLikeProperties;
use pumpkin_data::fluid::Fluid;
use pumpkin_macros::pumpkin_block;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockFlags;
use crate::block::registry::BlockActionResult;
use crate::block::{
BlockBehaviour, BlockIsReplacing, CanUpdateAtArgs, GetStateForNeighborUpdateArgs,
NormalUseArgs, OnPlaceArgs,
};
#[pumpkin_block("minecraft:light")]
pub struct LightBlock;
impl BlockBehaviour for LightBlock {
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let mut props = if let BlockIsReplacing::Itself(state_id) = args.replacing {
let mut p = LightLikeProperties::from_state_id(state_id);
p.level = (p.level + 1) % 16;
p
} else {
LightLikeProperties::default(args.block)
};
props.waterlogged = args.replacing.water_source();
props.to_state_id(args.block)
}
fn can_update_at(&self, args: CanUpdateAtArgs<'_>) -> bool {
args.player.gamemode.load() == pumpkin_util::GameMode::Creative
}
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
if args.player.gamemode.load() == pumpkin_util::GameMode::Creative {
let state_id = args.world.get_block_state_id(args.position);
let mut props = LightLikeProperties::from_state_id(state_id);
props.level = (props.level + 1) % 16;
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
BlockActionResult::SuccessServer
} else {
BlockActionResult::Consume
}
}
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
let props = LightLikeProperties::from_state_id(args.state_id);
if props.waterlogged {
args.world.schedule_fluid_tick(
&Fluid::WATER,
*args.position,
Fluid::WATER.flow_speed as u8,
TickPriority::Normal,
);
}
args.state_id
}
}

View File

@ -40,9 +40,13 @@ pub mod barrier;
pub mod chain; pub mod chain;
pub mod glass_panes; pub mod glass_panes;
pub mod glazed_terracotta; pub mod glazed_terracotta;
pub mod honey;
pub mod iron_bars; pub mod iron_bars;
pub mod scaffolding;
pub mod slabs; pub mod slabs;
pub mod stairs; pub mod stairs;
pub mod structure_void;
pub mod tinted_glass;
pub mod walls; pub mod walls;
pub mod weathering_copper; pub mod weathering_copper;
@ -66,6 +70,7 @@ pub mod candle_cakes;
pub mod candles; pub mod candles;
pub mod fire; pub mod fire;
pub mod lanterns; pub mod lanterns;
pub mod light;
pub mod magma; pub mod magma;
pub mod torches; pub mod torches;
@ -92,10 +97,12 @@ pub mod falling;
pub mod grass_block; pub mod grass_block;
pub mod ice; pub mod ice;
pub mod infested; pub mod infested;
pub mod mud;
pub mod nylium; pub mod nylium;
pub mod powder_snow; pub mod powder_snow;
pub mod rooted_dirt; pub mod rooted_dirt;
pub mod snow; pub mod snow;
pub mod soul_sand;
pub mod sponge; pub mod sponge;
// Entities, hazards & misc gameplay blocks // Entities, hazards & misc gameplay blocks
@ -125,6 +132,7 @@ pub mod loom;
pub mod smithing_table; pub mod smithing_table;
pub mod sniffer_egg; pub mod sniffer_egg;
pub mod structure_block; pub mod structure_block;
pub mod test_block;
pub mod trial_spawner; pub mod trial_spawner;
pub mod turtle_egg; pub mod turtle_egg;
pub mod vault; pub mod vault;

View File

@ -0,0 +1,16 @@
use pumpkin_macros::pumpkin_block;
use crate::block::{BlockBehaviour, PathComputationType};
#[pumpkin_block("minecraft:mud")]
pub struct MudBlock;
impl BlockBehaviour for MudBlock {
fn is_pathfindable(
&self,
_state: &pumpkin_data::BlockState,
_computation_type: PathComputationType,
) -> bool {
false
}
}

View File

@ -0,0 +1,69 @@
use pumpkin_data::tag::Taggable;
use pumpkin_data::{BlockId, BlockStateId, tag};
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::world::BlockAccessor;
use crate::block::blocks::plant::PlantBlockBase;
use crate::block::blocks::plant::sapling::SaplingBlock;
use crate::block::{
BlockBehaviour, BlockMetadata, BonemealArgs, CanPlaceAtArgs, GetStateForNeighborUpdateArgs,
PathComputationType,
};
pub struct AzaleaBlock;
impl BlockMetadata for AzaleaBlock {
fn ids() -> Box<[BlockId]> {
[BlockId::AZALEA, BlockId::FLOWERING_AZALEA].into()
}
}
impl BlockBehaviour for AzaleaBlock {
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
<Self as PlantBlockBase>::get_state_for_neighbor_update(
self,
args.world,
args.position,
args.state_id,
)
}
fn is_valid_bonemeal_target(&self, _args: BonemealArgs<'_>) -> bool {
true
}
fn is_bonemeal_success(&self, _args: BonemealArgs<'_>) -> bool {
rand::random::<f32>() < 0.45
}
fn perform_bonemeal(&self, args: BonemealArgs<'_>) {
SaplingBlock::advance_tree(args.world, args.position, args.block, args.state_id, true);
}
fn is_pathfindable(
&self,
_state: &pumpkin_data::BlockState,
_computation_type: PathComputationType,
) -> bool {
false
}
}
impl PlantBlockBase for AzaleaBlock {
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(pos);
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_AZALEA)
|| block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_VEGETATION)
}
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
self.can_plant_on_top(block_accessor, &block_pos.down())
}
}

View File

@ -0,0 +1,126 @@
use pumpkin_data::block_properties::{CaveVinesLikeProperties, CaveVinesPlantLikeProperties};
use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::{Block, BlockDirection, BlockId, BlockStateId};
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::world::{BlockAccessor, BlockFlags};
use crate::block::registry::BlockActionResult;
use crate::block::{
BlockBehaviour, BlockMetadata, BonemealArgs, CanPlaceAtArgs, GetStateForNeighborUpdateArgs,
NormalUseArgs, PlacedArgs,
};
pub struct CaveVinesBlock;
impl BlockMetadata for CaveVinesBlock {
fn ids() -> Box<[BlockId]> {
[BlockId::CAVE_VINES, BlockId::CAVE_VINES_PLANT].into()
}
}
impl CaveVinesBlock {
#[must_use]
pub fn can_survive(world: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_pos = pos.up();
let (support_block, support_state) = world.get_block_and_state(&support_pos);
if support_block == &Block::CAVE_VINES || support_block == &Block::CAVE_VINES_PLANT {
return true;
}
support_state.is_side_solid(BlockDirection::Down) && support_block.is_solid()
}
}
impl BlockBehaviour for CaveVinesBlock {
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
Self::can_survive(args.block_accessor, args.position)
}
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
if !Self::can_survive(args.world, args.position) {
return Block::AIR.default_state.id;
}
args.state_id
}
fn placed(&self, args: PlacedArgs<'_>) {
let support_pos = args.position.up();
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::CAVE_VINES {
let support_state_id = args.world.get_block_state_id(&support_pos);
let support_props = CaveVinesLikeProperties::from_state_id(support_state_id);
let mut plant_props = CaveVinesPlantLikeProperties::default(&Block::CAVE_VINES_PLANT);
plant_props.berries = support_props.berries;
args.world.set_block_state(
&support_pos,
plant_props.to_state_id(&Block::CAVE_VINES_PLANT),
BlockFlags::empty(),
);
}
}
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
let state_id = args.world.get_block_state_id(args.position);
if args.block == &Block::CAVE_VINES {
let mut props = CaveVinesLikeProperties::from_state_id(state_id);
if props.berries {
props.berries = false;
args.world
.drop_stack(args.position, ItemStack::new(1, &Item::GLOW_BERRIES));
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
return BlockActionResult::SuccessServer;
}
} else if args.block == &Block::CAVE_VINES_PLANT {
let mut props = CaveVinesPlantLikeProperties::from_state_id(state_id);
if props.berries {
props.berries = false;
args.world
.drop_stack(args.position, ItemStack::new(1, &Item::GLOW_BERRIES));
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
return BlockActionResult::SuccessServer;
}
}
BlockActionResult::Pass
}
fn is_valid_bonemeal_target(&self, args: BonemealArgs<'_>) -> bool {
if args.block == &Block::CAVE_VINES {
!CaveVinesLikeProperties::from_state_id(args.state_id).berries
} else if args.block == &Block::CAVE_VINES_PLANT {
!CaveVinesPlantLikeProperties::from_state_id(args.state_id).berries
} else {
false
}
}
fn perform_bonemeal(&self, args: BonemealArgs<'_>) {
if args.block == &Block::CAVE_VINES {
let mut props = CaveVinesLikeProperties::from_state_id(args.state_id);
props.berries = true;
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
} else if args.block == &Block::CAVE_VINES_PLANT {
let mut props = CaveVinesPlantLikeProperties::from_state_id(args.state_id);
props.berries = true;
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
}
}
}

View File

@ -19,6 +19,7 @@ pub mod beetroot;
pub mod carrot; pub mod carrot;
pub mod gourds; pub mod gourds;
pub mod nether_wart; pub mod nether_wart;
pub mod pitcher_crop;
pub mod potatoes; pub mod potatoes;
pub mod sweet_berry_bush; pub mod sweet_berry_bush;
pub mod torch_flower; pub mod torch_flower;
@ -76,8 +77,6 @@ trait CropBlockBase: PlantBlockBase {
} }
} }
} }
//TODO add impl for light level
} }
pub fn get_available_moisture(world: &World, pos: &BlockPos, block: &Block) -> f32 { pub fn get_available_moisture(world: &World, pos: &BlockPos, block: &Block) -> f32 {

View File

@ -0,0 +1,145 @@
use pumpkin_data::block_properties::{DoubleBlockHalf, PitcherCropLikeProperties};
use pumpkin_data::{Block, BlockStateId, tag, tag::Taggable};
use pumpkin_macros::pumpkin_block;
use pumpkin_world::world::{BlockAccessor, BlockFlags};
use crate::block::{
BlockBehaviour, BonemealArgs, CanPlaceAtArgs, GetStateForNeighborUpdateArgs, OnPlaceArgs,
RandomTickArgs,
};
pub const MAX_AGE: u8 = 4;
#[pumpkin_block("minecraft:pitcher_crop")]
pub struct PitcherCropBlock;
impl PitcherCropBlock {
#[must_use]
pub fn can_survive(
world: &dyn BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
props: &PitcherCropLikeProperties,
) -> bool {
let below = world.get_block(&pos.down());
if props.half == DoubleBlockHalf::Lower {
below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CROPS) || below == &Block::FARMLAND
} else {
below == &Block::PITCHER_CROP
}
}
}
impl BlockBehaviour for PitcherCropBlock {
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
let props = PitcherCropLikeProperties::from_state_id(args.state.id);
Self::can_survive(args.block_accessor, args.position, &props)
}
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let mut props = PitcherCropLikeProperties::default(args.block);
props.age = 0;
props.half = DoubleBlockHalf::Lower;
props.to_state_id(args.block)
}
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
let props = PitcherCropLikeProperties::from_state_id(args.state_id);
if !Self::can_survive(args.world, args.position, &props) {
return Block::AIR.default_state.id;
}
if props.half == DoubleBlockHalf::Lower && props.age >= 3 {
let above = args.world.get_block(&args.position.up());
if above != &Block::PITCHER_CROP {
return Block::AIR.default_state.id;
}
} else if props.half == DoubleBlockHalf::Upper {
let below = args.world.get_block(&args.position.down());
if below != &Block::PITCHER_CROP {
return Block::AIR.default_state.id;
}
}
args.state_id
}
fn random_tick(&self, args: RandomTickArgs<'_>) {
let state_id = args.world.get_block_state_id(args.position);
let mut props = PitcherCropLikeProperties::from_state_id(state_id);
if props.half == DoubleBlockHalf::Lower && props.age < MAX_AGE {
let next_age = props.age + 1;
if next_age >= 3 {
let above_pos = args.position.up();
let above_state = args.world.get_block_state(&above_pos);
if !above_state.is_air()
&& Block::from_state_id(above_state.id) != &Block::PITCHER_CROP
{
return;
}
}
props.age = next_age;
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
if next_age >= 3 {
let mut upper_props = props;
upper_props.half = DoubleBlockHalf::Upper;
args.world.set_block_state(
&args.position.up(),
upper_props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
}
}
}
fn is_valid_bonemeal_target(&self, args: BonemealArgs<'_>) -> bool {
let props = PitcherCropLikeProperties::from_state_id(args.state_id);
if props.half == DoubleBlockHalf::Lower {
props.age < MAX_AGE
} else {
let lower_state = args.world.get_block_state_id(&args.position.down());
let lower_props = PitcherCropLikeProperties::from_state_id(lower_state);
lower_props.age < MAX_AGE
}
}
fn perform_bonemeal(&self, args: BonemealArgs<'_>) {
let props = PitcherCropLikeProperties::from_state_id(args.state_id);
let (lower_pos, lower_props) = if props.half == DoubleBlockHalf::Lower {
(*args.position, props)
} else {
(
args.position.down(),
PitcherCropLikeProperties::from_state_id(
args.world.get_block_state_id(&args.position.down()),
),
)
};
if lower_props.age < MAX_AGE {
let next_age = lower_props.age + 1;
let mut new_lower = lower_props;
new_lower.age = next_age;
args.world.set_block_state(
&lower_pos,
new_lower.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
if next_age >= 3 {
let mut upper_props = new_lower;
upper_props.half = DoubleBlockHalf::Upper;
args.world.set_block_state(
&lower_pos.up(),
upper_props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
}
}
}
}

View File

@ -0,0 +1,54 @@
use pumpkin_data::block_properties::MangroveRootsLikeProperties as HangingRootsLikeProperties;
use pumpkin_data::fluid::Fluid;
use pumpkin_data::{Block, BlockDirection, BlockStateId};
use pumpkin_macros::pumpkin_block;
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockAccessor;
use crate::block::{BlockBehaviour, CanPlaceAtArgs, GetStateForNeighborUpdateArgs, OnPlaceArgs};
#[pumpkin_block("minecraft:hanging_roots")]
pub struct HangingRootsBlock;
impl HangingRootsBlock {
#[must_use]
pub fn can_survive(world: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let above_pos = pos.up();
let (above_block, above_state) = world.get_block_and_state(&above_pos);
above_state.is_side_solid(BlockDirection::Down) && above_block.is_solid()
}
}
impl BlockBehaviour for HangingRootsBlock {
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
Self::can_survive(args.block_accessor, args.position)
}
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let mut props = HangingRootsLikeProperties::default(args.block);
props.waterlogged = args.replacing.water_source();
props.to_state_id(args.block)
}
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
if !Self::can_survive(args.world, args.position) {
return Block::AIR.default_state.id;
}
let props = HangingRootsLikeProperties::from_state_id(args.state_id);
if props.waterlogged {
args.world.schedule_fluid_tick(
&Fluid::WATER,
*args.position,
Fluid::WATER.flow_speed as u8,
TickPriority::Normal,
);
}
args.state_id
}
}

View File

@ -2,6 +2,7 @@ use pumpkin_data::{Block, BlockStateId, tag, tag::Taggable};
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use pumpkin_world::world::BlockAccessor; use pumpkin_world::world::BlockAccessor;
pub mod azalea;
pub mod bamboo; pub mod bamboo;
pub mod bamboo_sapling; pub mod bamboo_sapling;
pub mod big_dripleaf; pub mod big_dripleaf;
@ -9,6 +10,7 @@ pub mod big_dripleaf_stem;
pub mod bush; pub mod bush;
pub mod cactus; pub mod cactus;
pub mod cactus_flower; pub mod cactus_flower;
pub mod cave_vines;
pub mod chorus_flower; pub mod chorus_flower;
pub mod chorus_plant; pub mod chorus_plant;
pub mod cocoa; pub mod cocoa;
@ -18,6 +20,7 @@ pub mod eyeblossom;
pub mod flower; pub mod flower;
pub mod flowerbed; pub mod flowerbed;
pub mod fungus; pub mod fungus;
pub mod hanging_roots;
pub mod kelp; pub mod kelp;
pub mod leaf_litter; pub mod leaf_litter;
pub mod lily_pad; pub mod lily_pad;

View File

@ -1,12 +1,7 @@
use pumpkin_data::tag::Taggable; use pumpkin_data::tag::Taggable;
use pumpkin_data::{Block, BlockId, BlockStateId, tag}; use pumpkin_data::{Block, BlockId, BlockStateId, tag};
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::world::BlockAccessor;
use crate::block::{ use crate::block::{BlockBehaviour, BlockMetadata, CanPlaceAtArgs, GetStateForNeighborUpdateArgs};
BlockBehaviour, BlockMetadata, CanPlaceAtArgs, GetStateForNeighborUpdateArgs,
blocks::plant::PlantBlockBase,
};
pub struct RootsBlock; pub struct RootsBlock;
@ -18,33 +13,27 @@ impl BlockMetadata for RootsBlock {
impl BlockBehaviour for RootsBlock { impl BlockBehaviour for RootsBlock {
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool { fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position) let block_below = args.block_accessor.get_block(&args.position.down());
} if args.block == &Block::WARPED_ROOTS {
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
<Self as PlantBlockBase>::get_state_for_neighbor_update(
self,
args.world,
args.position,
args.state_id,
)
}
}
impl PlantBlockBase for RootsBlock {
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(pos);
if block_below == &Block::WARPED_ROOTS {
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_WARPED_ROOTS) block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_WARPED_ROOTS)
} else { } else {
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CRIMSON_ROOTS) block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CRIMSON_ROOTS)
} }
} }
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool { fn get_state_for_neighbor_update(
self.can_plant_on_top(block_accessor, &block_pos.down()) &self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
let block_below = args.world.get_block(&args.position.down());
let can_survive = if args.block == &Block::WARPED_ROOTS {
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_WARPED_ROOTS)
} else {
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CRIMSON_ROOTS)
};
if !can_survive {
return Block::AIR.default_state.id;
}
args.state_id
} }
} }

View File

@ -5,7 +5,7 @@ use crate::block::entities::bell::BellBlockEntity;
use crate::block::registry::BlockActionResult; use crate::block::registry::BlockActionResult;
use crate::block::{ use crate::block::{
BlockBehaviour, BlockHitResult, BrokenArgs, CanPlaceAtArgs, NormalUseArgs, BlockBehaviour, BlockHitResult, BrokenArgs, CanPlaceAtArgs, NormalUseArgs,
OnNeighborUpdateArgs, OnPlaceArgs, PathComputationType, PlacedArgs, OnNeighborUpdateArgs, OnPlaceArgs, OnProjectileHitArgs, PathComputationType, PlacedArgs,
}; };
use crate::world::World; use crate::world::World;
use pumpkin_data::block_properties::HorizontalFacing; use pumpkin_data::block_properties::HorizontalFacing;
@ -215,6 +215,28 @@ impl BlockBehaviour for BellBlock {
} }
} }
fn on_projectile_hit(&self, args: OnProjectileHitArgs<'_>) {
let player = args
.projectile
.get_owner_id()
.and_then(|id| args.world.get_player_by_id(id));
if ring_bell(
*args.position,
args.world,
None,
player
.as_ref()
.map(|p| p.clone() as Arc<dyn crate::entity::EntityBase>),
) && let Some(player) = player
{
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::BellRing as i32,
1,
);
}
}
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool { fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
false false
} }

View File

@ -75,12 +75,20 @@ impl BlockBehaviour for ButtonBlock {
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) { fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let state = args.world.get_block_state(args.position); let state = args.world.get_block_state(args.position);
let mut props = ButtonLikeProperties::from_state_id(state.id); let mut props = ButtonLikeProperties::from_state_id(state.id);
props.powered = false; if props.powered {
args.world.set_block_state( props.powered = false;
args.position, args.world.set_block_state(
props.to_state_id(args.block), args.position,
BlockFlags::NOTIFY_ALL, props.to_state_id(args.block),
); BlockFlags::NOTIFY_ALL,
);
Self::update_neighbors(args.world, args.position, props);
args.world.play_block_sound(
get_sound(args.block, false),
SoundCategory::Blocks,
*args.position,
);
}
} }
fn emits_redstone_power(&self, _args: EmitsRedstonePowerArgs<'_>) -> bool { fn emits_redstone_power(&self, _args: EmitsRedstonePowerArgs<'_>) -> bool {

View File

@ -4,7 +4,8 @@ use crate::block::blocks::weathering_copper::{
get_first, get_next, get_previous, get_weather_state, get_first, get_next, get_previous, get_weather_state,
}; };
use crate::block::{ use crate::block::{
BlockBehaviour, BlockMetadata, OnNeighborUpdateArgs, OnPlaceArgs, RandomTickArgs, BlockBehaviour, BlockMetadata, GetComparatorOutputArgs, OnNeighborUpdateArgs, OnPlaceArgs,
RandomTickArgs,
}; };
use pumpkin_data::BlockId; use pumpkin_data::BlockId;
use pumpkin_data::BlockStateId; use pumpkin_data::BlockStateId;
@ -102,4 +103,9 @@ impl BlockBehaviour for CopperBulbBlock {
fn random_tick(&self, args: RandomTickArgs<'_>) { fn random_tick(&self, args: RandomTickArgs<'_>) {
change_over_time(args.world, args.position, args.block); change_over_time(args.world, args.position, args.block);
} }
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
let props = CopperBulbLikeProperties::from_state_id(args.state.id);
if props.lit { Some(15) } else { Some(0) }
}
} }

View File

@ -127,6 +127,11 @@ impl BlockBehaviour for DispenserBlock {
if let Some(block_entity) = args.world.get_block_entity(args.position) if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.get_inventory() && let Some(inventory) = block_entity.get_inventory()
{ {
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::InspectDispenser as i32,
1,
);
args.player args.player
.open_handled_screen(&DispenserScreenFactory(inventory), Some(*args.position)); .open_handled_screen(&DispenserScreenFactory(inventory), Some(*args.position));
} }

View File

@ -89,6 +89,11 @@ impl BlockBehaviour for DropperBlock {
if let Some(block_entity) = args.world.get_block_entity(args.position) if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.get_inventory() && let Some(inventory) = block_entity.get_inventory()
{ {
args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::InspectDropper as i32,
1,
);
args.player args.player
.open_handled_screen(&DropperScreenFactory(inventory), Some(*args.position)); .open_handled_screen(&DropperScreenFactory(inventory), Some(*args.position));
} }

View File

@ -2,7 +2,7 @@ use std::sync::Arc;
use crate::block::{ use crate::block::{
BlockBehaviour, EmitsRedstonePowerArgs, GetRedstonePowerArgs, OnPlaceArgs, OnScheduledTickArgs, BlockBehaviour, EmitsRedstonePowerArgs, GetRedstonePowerArgs, OnPlaceArgs, OnScheduledTickArgs,
PathComputationType, OnStateReplacedArgs, PathComputationType,
}; };
use crate::world::World; use crate::world::World;
use pumpkin_data::block_properties::LightningRodLikeProperties; use pumpkin_data::block_properties::LightningRodLikeProperties;
@ -74,6 +74,16 @@ impl BlockBehaviour for LightningRodBlock {
props.to_state_id(args.block), props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
); );
Self::update_neighbors(args.world, args.position, props);
}
}
fn on_state_replaced(&self, args: OnStateReplacedArgs<'_>) {
if !args.moved {
let props = LightningRodLikeProperties::from_state_id(args.old_state_id);
if props.powered {
Self::update_neighbors(args.world, args.position, props);
}
} }
} }

View File

@ -43,6 +43,7 @@ impl BlockBehaviour for ObserverBlock {
args.world args.world
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal); .schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
} }
Self::update_neighbors(args.world, args.block, args.position, props);
} }
fn get_state_for_neighbor_update( fn get_state_for_neighbor_update(

View File

@ -1,6 +1,32 @@
use pumpkin_data::block_properties::TargetProperties;
use pumpkin_data::entity::EntityType;
use pumpkin_macros::pumpkin_block; use pumpkin_macros::pumpkin_block;
use pumpkin_util::math::vector3::Vector3;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockFlags;
use crate::block::{BlockBehaviour, EmitsRedstonePowerArgs}; use crate::block::{
BlockBehaviour, EmitsRedstonePowerArgs, GetRedstonePowerArgs, OnPlaceArgs, OnProjectileHitArgs,
OnScheduledTickArgs, OnStateReplacedArgs,
};
fn get_redstone_strength(hit_pos: &Vector3<f64>) -> u8 {
let dist_x = ((hit_pos.x - hit_pos.x.floor()) - 0.5).abs();
let dist_y = ((hit_pos.y - hit_pos.y.floor()) - 0.5).abs();
let dist_z = ((hit_pos.z - hit_pos.z.floor()) - 0.5).abs();
let distance = if dist_x >= dist_y && dist_x >= dist_z {
dist_y.max(dist_z)
} else if dist_y >= dist_z {
dist_x.max(dist_z)
} else {
dist_x.max(dist_y)
};
let norm = ((0.5 - distance) / 0.5).clamp(0.0, 1.0);
let power = (15.0 * norm).ceil() as u8;
power.clamp(1, 15)
}
#[pumpkin_block("minecraft:target")] #[pumpkin_block("minecraft:target")]
pub struct TargetBlock; pub struct TargetBlock;
@ -9,4 +35,77 @@ impl BlockBehaviour for TargetBlock {
fn emits_redstone_power(&self, _args: EmitsRedstonePowerArgs<'_>) -> bool { fn emits_redstone_power(&self, _args: EmitsRedstonePowerArgs<'_>) -> bool {
true true
} }
fn get_weak_redstone_power(&self, args: GetRedstonePowerArgs<'_>) -> u8 {
let props = TargetProperties::from_state_id(args.state.id);
props.r#power
}
fn get_strong_redstone_power(&self, args: GetRedstonePowerArgs<'_>) -> u8 {
let props = TargetProperties::from_state_id(args.state.id);
props.r#power
}
fn on_projectile_hit(&self, args: OnProjectileHitArgs<'_>) {
if let Some(owner_id) = args.projectile.get_owner_id()
&& let Some(player) = args.world.get_player_by_id(owner_id)
{
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::TargetHit as i32,
1,
);
}
if !args
.world
.is_block_tick_scheduled(args.position, args.block)
{
let power = get_redstone_strength(args.hit_pos);
let mut props = TargetProperties::from_state_id(args.state.id);
props.r#power = power;
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
let entity_type = args.projectile.get_entity().entity_type;
let delay = if entity_type == &EntityType::ARROW
|| entity_type == &EntityType::SPECTRAL_ARROW
{
20
} else {
8
};
args.world
.schedule_block_tick(args.block, *args.position, delay, TickPriority::Normal);
}
}
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let state_id = args.world.get_block_state_id(args.position);
let mut props = TargetProperties::from_state_id(state_id);
if props.r#power != 0 {
props.r#power = 0;
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
}
}
fn on_state_replaced(&self, args: OnStateReplacedArgs<'_>) {
if !args.moved {
let props = TargetProperties::from_state_id(args.old_state_id);
if props.r#power > 0 {
args.world.update_neighbors(args.position, None);
}
}
}
fn on_place(&self, args: OnPlaceArgs<'_>) -> pumpkin_data::BlockStateId {
let mut props = TargetProperties::default(args.block);
props.r#power = 0;
props.to_state_id(args.block)
}
} }

View File

@ -0,0 +1,82 @@
use pumpkin_data::block_properties::ScaffoldingLikeProperties;
use pumpkin_data::fluid::Fluid;
use pumpkin_data::{Block, BlockDirection, BlockStateId};
use pumpkin_macros::pumpkin_block;
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockAccessor;
use crate::block::{BlockBehaviour, CanPlaceAtArgs, GetStateForNeighborUpdateArgs, OnPlaceArgs};
#[pumpkin_block("minecraft:scaffolding")]
pub struct ScaffoldingBlock;
impl ScaffoldingBlock {
#[must_use]
pub fn get_distance(world: &dyn BlockAccessor, pos: &BlockPos) -> u8 {
let below_pos = pos.down();
let (below_block, below_state) = world.get_block_and_state(&below_pos);
if below_block == &Block::SCAFFOLDING {
return ScaffoldingLikeProperties::from_state_id(below_state.id).distance;
} else if below_state.is_side_solid(BlockDirection::Up) && below_block.is_solid() {
return 0;
}
let mut min_dist = 7u8;
for dir in BlockDirection::horizontal() {
let neighbor_pos = pos.offset(dir.to_offset());
let (neighbor_block, neighbor_state) = world.get_block_and_state(&neighbor_pos);
if neighbor_block == &Block::SCAFFOLDING {
let dist = ScaffoldingLikeProperties::from_state_id(neighbor_state.id).distance;
min_dist = min_dist.min(dist.saturating_add(1));
if min_dist == 1 {
break;
}
}
}
min_dist.min(7)
}
#[must_use]
pub fn is_bottom(world: &dyn BlockAccessor, pos: &BlockPos, distance: u8) -> bool {
distance > 0 && world.get_block(&pos.down()) != &Block::SCAFFOLDING
}
}
impl BlockBehaviour for ScaffoldingBlock {
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
Self::get_distance(args.block_accessor, args.position) < 7
}
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let distance = Self::get_distance(args.world, args.position);
let mut props = ScaffoldingLikeProperties::default(args.block);
props.distance = distance;
props.bottom = Self::is_bottom(args.world, args.position, distance);
props.waterlogged = args.replacing.water_source();
props.to_state_id(args.block)
}
fn get_state_for_neighbor_update(
&self,
args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId {
let props = ScaffoldingLikeProperties::from_state_id(args.state_id);
if props.waterlogged {
args.world.schedule_fluid_tick(
&Fluid::WATER,
*args.position,
Fluid::WATER.flow_speed as u8,
TickPriority::Normal,
);
}
let distance = Self::get_distance(args.world, args.position);
if distance == 7 {
return Block::AIR.default_state.id;
}
let mut new_props = props;
new_props.distance = distance;
new_props.bottom = Self::is_bottom(args.world, args.position, distance);
new_props.to_state_id(args.block)
}
}

View File

@ -1,31 +1,39 @@
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use crate::block::{ use crate::block::{
BlockBehaviour, BlockIsReplacing, BlockMetadata, CanPlaceAtArgs, CanUpdateAtArgs, BlockBehaviour, BlockIsReplacing, BlockMetadata, BonemealArgs, CanPlaceAtArgs, CanUpdateAtArgs,
GetStateForNeighborUpdateArgs, OnPlaceArgs, UseWithItemArgs, registry::BlockActionResult, GetStateForNeighborUpdateArgs, OnPlaceArgs, UseWithItemArgs, registry::BlockActionResult,
}; };
use crate::entity::{EntityBase, player::Player}; use crate::entity::{EntityBase, player::Player};
use pumpkin_data::fluid::Fluid;
use pumpkin_data::{ use pumpkin_data::{
Block, BlockDirection, BlockId, BlockStateId, FacingExt, Block, BlockDirection, BlockId, BlockStateId, FacingExt,
block_properties::GlowLichenLikeProperties, item::Item, block_properties::GlowLichenLikeProperties,
}; };
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::{BlockAccessor, BlockFlags}; use pumpkin_world::world::{BlockAccessor, BlockFlags};
pub struct SculkVeinBlock; pub struct MultifaceBlock;
impl BlockMetadata for SculkVeinBlock { impl BlockMetadata for MultifaceBlock {
fn ids() -> Box<[BlockId]> { fn ids() -> Box<[BlockId]> {
[BlockId::SCULK_VEIN].into() [
BlockId::SCULK_VEIN,
BlockId::GLOW_LICHEN,
BlockId::RESIN_CLUMP,
]
.into()
} }
} }
impl BlockBehaviour for SculkVeinBlock { impl BlockBehaviour for MultifaceBlock {
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId { fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
if let BlockIsReplacing::Itself(state_id) = args.replacing { if let BlockIsReplacing::Itself(state_id) = args.replacing {
let (Some(direction), _) = get_attach_direction( let (Some(direction), _) = get_attach_direction(
args.world, args.world,
args.position, args.position,
args.block,
Some(args.player), Some(args.player),
args.direction, args.direction,
true, true,
@ -40,6 +48,7 @@ impl BlockBehaviour for SculkVeinBlock {
let (Some(direction), _) = get_attach_direction( let (Some(direction), _) = get_attach_direction(
args.world, args.world,
args.position, args.position,
args.block,
Some(args.player), Some(args.player),
args.direction, args.direction,
false, false,
@ -56,6 +65,7 @@ impl BlockBehaviour for SculkVeinBlock {
get_attach_direction( get_attach_direction(
args.block_accessor, args.block_accessor,
args.position, args.position,
args.block,
args.player, args.player,
args.direction.unwrap_or(BlockDirection::Down), args.direction.unwrap_or(BlockDirection::Down),
false, false,
@ -68,6 +78,7 @@ impl BlockBehaviour for SculkVeinBlock {
get_attach_direction( get_attach_direction(
args.world, args.world,
args.position, args.position,
args.block,
Some(args.player), Some(args.player),
args.direction, args.direction,
true, true,
@ -81,8 +92,16 @@ impl BlockBehaviour for SculkVeinBlock {
args: GetStateForNeighborUpdateArgs<'_>, args: GetStateForNeighborUpdateArgs<'_>,
) -> BlockStateId { ) -> BlockStateId {
let old_props = GlowLichenLikeProperties::from_state_id(args.state_id); let old_props = GlowLichenLikeProperties::from_state_id(args.state_id);
let mut new_directions = active_directions(old_props); if old_props.waterlogged {
args.world.schedule_fluid_tick(
&Fluid::WATER,
*args.position,
Fluid::WATER.flow_speed as u8,
TickPriority::Normal,
);
}
let mut new_directions = active_directions(old_props);
let support = args let support = args
.world .world
.get_block(&args.position.offset(args.direction.to_offset())); .get_block(&args.position.offset(args.direction.to_offset()));
@ -97,48 +116,76 @@ impl BlockBehaviour for SculkVeinBlock {
for dir in new_directions { for dir in new_directions {
set_face(&mut new_props, dir); set_face(&mut new_props, dir);
} }
new_props.waterlogged = old_props.waterlogged;
new_props.to_state_id(args.block) new_props.to_state_id(args.block)
} }
fn use_with_item(&self, args: UseWithItemArgs<'_>) -> BlockActionResult { fn use_with_item(&self, args: UseWithItemArgs<'_>) -> BlockActionResult {
{ if args.item_stack.item.id != args.block.id.as_u16() {
if args.item_stack.item.id != Item::SCULK_VEIN.id { return BlockActionResult::Pass;
return BlockActionResult::Pass;
}
let state = args.world.get_block_state(args.position);
let mut props = GlowLichenLikeProperties::from_state_id(state.id);
let (Some(accurate_dir), _) = get_attach_direction(
args.world.as_ref(),
args.position,
Some(args.player),
*args.hit.face,
true,
) else {
return BlockActionResult::Fail;
};
set_face(&mut props, accurate_dir);
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
BlockActionResult::Consume
} }
let state = args.world.get_block_state(args.position);
let mut props = GlowLichenLikeProperties::from_state_id(state.id);
let (Some(accurate_dir), _) = get_attach_direction(
args.world.as_ref(),
args.position,
args.block,
Some(args.player),
*args.hit.face,
true,
) else {
return BlockActionResult::Fail;
};
set_face(&mut props, accurate_dir);
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
BlockActionResult::Consume
}
fn is_valid_bonemeal_target(&self, args: BonemealArgs<'_>) -> bool {
if args.block != &Block::GLOW_LICHEN {
return false;
}
let props = GlowLichenLikeProperties::from_state_id(args.state_id);
let active = active_directions(props);
active.len() < 6
}
fn perform_bonemeal(&self, args: BonemealArgs<'_>) {
if args.block != &Block::GLOW_LICHEN {
return;
}
let mut props = GlowLichenLikeProperties::from_state_id(args.state_id);
for dir in BlockDirection::all() {
let support = args.world.get_block(&args.position.offset(dir.to_offset()));
if is_solid_face(support) {
set_face(&mut props, dir);
}
}
args.world.set_block_state(
args.position,
props.to_state_id(args.block),
BlockFlags::NOTIFY_ALL,
);
} }
} }
fn get_attach_direction( fn get_attach_direction(
block_accessor: &dyn BlockAccessor, block_accessor: &dyn BlockAccessor,
block_pos: &BlockPos, block_pos: &BlockPos,
target_block: &Block,
player_wrapper: Option<&Player>, player_wrapper: Option<&Player>,
click_direction: BlockDirection, click_direction: BlockDirection,
replacing: bool, replacing: bool,
) -> (Option<BlockDirection>, bool) { ) -> (Option<BlockDirection>, bool) {
let clicked_block = block_accessor.get_block(&block_pos.offset(click_direction.to_offset())); let clicked_block = block_accessor.get_block(&block_pos.offset(click_direction.to_offset()));
if !replacing && clicked_block == &Block::SCULK_VEIN { if !replacing && clicked_block == target_block {
return (None, false); return (None, false);
} }
@ -147,7 +194,7 @@ fn get_attach_direction(
} }
let (replacing_block, replacing_block_state) = block_accessor.get_block_and_state(block_pos); let (replacing_block, replacing_block_state) = block_accessor.get_block_and_state(block_pos);
let already_active = if replacing_block == &Block::SCULK_VEIN { let already_active = if replacing_block == target_block {
active_directions(GlowLichenLikeProperties::from_state_id( active_directions(GlowLichenLikeProperties::from_state_id(
replacing_block_state.id, replacing_block_state.id,
)) ))

View File

@ -1,9 +1,12 @@
use pumpkin_data::block_properties::AcaciaShelfLikeProperties; use pumpkin_data::block_properties::AcaciaShelfLikeProperties;
use pumpkin_data::{BlockState, BlockStateId}; use pumpkin_data::{BlockState, BlockStateId};
use pumpkin_macros::pumpkin_block_from_tag; use pumpkin_macros::pumpkin_block_from_tag;
use pumpkin_world::inventory::Inventory;
use crate::block::entities::shelf::ShelfBlockEntity; use crate::block::entities::shelf::ShelfBlockEntity;
use crate::block::{BlockBehaviour, OnPlaceArgs, PathComputationType, PlacedArgs}; use crate::block::{
BlockBehaviour, GetComparatorOutputArgs, OnPlaceArgs, PathComputationType, PlacedArgs,
};
use crate::entity::EntityBase; use crate::entity::EntityBase;
use std::sync::Arc; use std::sync::Arc;
@ -14,7 +17,6 @@ impl BlockBehaviour for ShelfBlock {
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId { fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let mut properties = AcaciaShelfLikeProperties::default(args.block); let mut properties = AcaciaShelfLikeProperties::default(args.block);
// Face in the opposite direction the player is facing
properties.facing = args.player.get_entity().get_horizontal_facing().opposite(); properties.facing = args.player.get_entity().get_horizontal_facing().opposite();
properties.to_state_id(args.block) properties.to_state_id(args.block)
@ -27,6 +29,19 @@ impl BlockBehaviour for ShelfBlock {
} }
} }
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(shelf) = block_entity.as_any().downcast_ref::<ShelfBlockEntity>()
{
let b0 = u8::from(!shelf.get_stack(0).is_empty());
let b1 = u8::from(!shelf.get_stack(1).is_empty());
let b2 = u8::from(!shelf.get_stack(2).is_empty());
Some(b0 | (b1 << 1) | (b2 << 2))
} else {
None
}
}
fn is_pathfindable(&self, state: &BlockState, computation_type: PathComputationType) -> bool { fn is_pathfindable(&self, state: &BlockState, computation_type: PathComputationType) -> bool {
computation_type == PathComputationType::Water && state.is_waterlogged() computation_type == PathComputationType::Water && state.is_waterlogged()
} }

View File

@ -0,0 +1,16 @@
use pumpkin_macros::pumpkin_block;
use crate::block::{BlockBehaviour, PathComputationType};
#[pumpkin_block("minecraft:soul_sand")]
pub struct SoulSandBlock;
impl BlockBehaviour for SoulSandBlock {
fn is_pathfindable(
&self,
_state: &pumpkin_data::BlockState,
_computation_type: PathComputationType,
) -> bool {
false
}
}

View File

@ -1,7 +1,8 @@
use crate::block::registry::BlockActionResult; use crate::block::registry::BlockActionResult;
use crate::block::{BlockBehaviour, NormalUseArgs, PathComputationType}; use crate::block::{BlockBehaviour, NormalUseArgs, OnPlaceArgs, PathComputationType};
use pumpkin_data::{BlockState, translation}; use pumpkin_data::block_properties::WallTorchLikeProperties;
use pumpkin_data::{BlockState, BlockStateId, translation};
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{ use pumpkin_inventory::screen_handler::{
InventoryPlayer, ScreenHandlerFactory, SharedScreenHandler, InventoryPlayer, ScreenHandlerFactory, SharedScreenHandler,
@ -17,6 +18,17 @@ use pumpkin_inventory::stonecutter_screen_handler::StonecutterScreenHandler;
pub struct StonecutterBlock; pub struct StonecutterBlock;
impl BlockBehaviour for StonecutterBlock { impl BlockBehaviour for StonecutterBlock {
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let mut props = WallTorchLikeProperties::default(args.block);
props.facing = args
.player
.living_entity
.entity
.get_horizontal_facing()
.opposite();
props.to_state_id(args.block)
}
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult { fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
args.player.increment_stat( args.player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom, pumpkin_data::statistic::StatisticCategory::Custom,

View File

@ -0,0 +1,8 @@
use pumpkin_macros::pumpkin_block;
use crate::block::BlockBehaviour;
#[pumpkin_block("minecraft:structure_void")]
pub struct StructureVoidBlock;
impl BlockBehaviour for StructureVoidBlock {}

View File

@ -0,0 +1,57 @@
use std::sync::Arc;
use pumpkin_macros::pumpkin_block;
use pumpkin_util::{GameMode, PermissionLvl};
use crate::block::entities::test_block::TestBlockBlockEntity;
use crate::block::entities::test_instance_block::TestInstanceBlockBlockEntity;
use crate::block::registry::BlockActionResult;
use crate::block::{BlockBehaviour, NormalUseArgs, PlacedArgs};
#[pumpkin_block("minecraft:test_block")]
pub struct TestBlock;
impl BlockBehaviour for TestBlock {
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
if args.player.permission_lvl.load() < PermissionLvl::Two {
return BlockActionResult::Pass;
}
if args.player.gamemode.load() != GameMode::Creative {
return BlockActionResult::Pass;
}
let Some(block_entity) = args.world.get_block_entity(args.position) else {
return BlockActionResult::Pass;
};
args.world.update_block_entity(&block_entity);
BlockActionResult::SuccessServer
}
fn placed(&self, args: PlacedArgs<'_>) {
let entity = TestBlockBlockEntity::new(*args.position);
args.world.add_block_entity(Arc::new(entity));
}
}
#[pumpkin_block("minecraft:test_instance_block")]
pub struct TestInstanceBlock;
impl BlockBehaviour for TestInstanceBlock {
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
if args.player.permission_lvl.load() < PermissionLvl::Two {
return BlockActionResult::Pass;
}
if args.player.gamemode.load() != GameMode::Creative {
return BlockActionResult::Pass;
}
let Some(block_entity) = args.world.get_block_entity(args.position) else {
return BlockActionResult::Pass;
};
args.world.update_block_entity(&block_entity);
BlockActionResult::SuccessServer
}
fn placed(&self, args: PlacedArgs<'_>) {
let entity = TestInstanceBlockBlockEntity::new(*args.position);
args.world.add_block_entity(Arc::new(entity));
}
}

View File

@ -0,0 +1,8 @@
use pumpkin_macros::pumpkin_block;
use crate::block::BlockBehaviour;
#[pumpkin_block("minecraft:tinted_glass")]
pub struct TintedGlassBlock;
impl BlockBehaviour for TintedGlassBlock {}

View File

@ -234,16 +234,32 @@ impl BlockEntity for BeaconBlockEntity {
self.position self.position
} }
fn from_nbt(nbt: &NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
where where
Self: Sized, Self: Sized,
{ {
// Aligning to strict vanilla NBT tags let primary = nbt
let primary = nbt.get_int("primary_effect").unwrap_or(-1); .get_string("primary_effect")
let secondary = nbt.get_int("secondary_effect").unwrap_or(-1); .and_then(|s| {
let levels = nbt.get_int("Levels").unwrap_or(0); // Vanilla uses capital L StatusEffect::from_minecraft_name(s)
.or_else(|| StatusEffect::from_name(s))
.map(|e| e.id as i32)
})
.or_else(|| nbt.get_int("primary_effect"))
.unwrap_or(-1);
let secondary = nbt
.get_string("secondary_effect")
.and_then(|s| {
StatusEffect::from_minecraft_name(s)
.or_else(|| StatusEffect::from_name(s))
.map(|e| e.id as i32)
})
.or_else(|| nbt.get_int("secondary_effect"))
.unwrap_or(-1);
let levels = nbt.get_int("Levels").unwrap_or(0);
let custom_name = nbt let custom_name = nbt
.get_string("CustomName") .get_string("CustomName")
.or_else(|| nbt.get_string("custom_name"))
.map(std::string::ToString::to_string); .map(std::string::ToString::to_string);
let lock_key = nbt.get_string("Lock").map(std::string::ToString::to_string); let lock_key = nbt.get_string("Lock").map(std::string::ToString::to_string);
@ -261,14 +277,22 @@ impl BlockEntity for BeaconBlockEntity {
} }
fn write_nbt(&self, nbt: &mut NbtCompound) { fn write_nbt(&self, nbt: &mut NbtCompound) {
nbt.put_int( let primary = self.primary_effect.load(Ordering::Relaxed);
"primary_effect", if primary >= 0 {
self.primary_effect.load(Ordering::Relaxed), if let Some(eff) = <StatusEffect as IDSetContent>::from_id(primary as u16) {
); nbt.put_string("primary_effect", eff.minecraft_name.to_string());
nbt.put_int( } else {
"secondary_effect", nbt.put_int("primary_effect", primary);
self.secondary_effect.load(Ordering::Relaxed), }
); }
let secondary = self.secondary_effect.load(Ordering::Relaxed);
if secondary >= 0 {
if let Some(eff) = <StatusEffect as IDSetContent>::from_id(secondary as u16) {
nbt.put_string("secondary_effect", eff.minecraft_name.to_string());
} else {
nbt.put_int("secondary_effect", secondary);
}
}
nbt.put_int("Levels", self.levels.load(Ordering::Relaxed)); nbt.put_int("Levels", self.levels.load(Ordering::Relaxed));
if let Some(name) = &*self if let Some(name) = &*self
@ -301,14 +325,22 @@ impl BlockEntity for BeaconBlockEntity {
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new(); let mut nbt = NbtCompound::new();
nbt.put_int( let primary = self.primary_effect.load(Ordering::Relaxed);
"primary_effect", if primary >= 0 {
self.primary_effect.load(Ordering::Relaxed), if let Some(eff) = <StatusEffect as IDSetContent>::from_id(primary as u16) {
); nbt.put_string("primary_effect", eff.minecraft_name.to_string());
nbt.put_int( } else {
"secondary_effect", nbt.put_int("primary_effect", primary);
self.secondary_effect.load(Ordering::Relaxed), }
); }
let secondary = self.secondary_effect.load(Ordering::Relaxed);
if secondary >= 0 {
if let Some(eff) = <StatusEffect as IDSetContent>::from_id(secondary as u16) {
nbt.put_string("secondary_effect", eff.minecraft_name.to_string());
} else {
nbt.put_int("secondary_effect", secondary);
}
}
nbt.put_int("Levels", self.levels.load(Ordering::Relaxed)); nbt.put_int("Levels", self.levels.load(Ordering::Relaxed));
if let Ok(name) = self.custom_name.try_lock() if let Ok(name) = self.custom_name.try_lock()
&& let Some(ref name) = *name && let Some(ref name) = *name

View File

@ -23,14 +23,24 @@ impl BlockEntity for BeehiveBlockEntity {
where where
Self: Sized, Self: Sized,
{ {
let bees = nbt.get_list("Bees").map(<[_]>::to_vec); let bees = nbt
let flower_pos = nbt.get_compound("FlowerPos").map(|c| { .get_list("bees")
BlockPos::new( .or_else(|| nbt.get_list("Bees"))
c.get_int("X").unwrap_or(0), .map(<[_]>::to_vec);
c.get_int("Y").unwrap_or(0), let flower_pos = nbt
c.get_int("Z").unwrap_or(0), .get_int_array("flower_pos")
) .and_then(|arr| (arr.len() == 3).then(|| BlockPos::new(arr[0], arr[1], arr[2])))
}); .or_else(|| {
nbt.get_compound("flower_pos")
.or_else(|| nbt.get_compound("FlowerPos"))
.map(|c| {
BlockPos::new(
c.get_int("X").or_else(|| c.get_int("x")).unwrap_or(0),
c.get_int("Y").or_else(|| c.get_int("y")).unwrap_or(0),
c.get_int("Z").or_else(|| c.get_int("z")).unwrap_or(0),
)
})
});
Self { Self {
position, position,
bees: Mutex::new(bees), bees: Mutex::new(bees),
@ -42,16 +52,15 @@ impl BlockEntity for BeehiveBlockEntity {
if let Ok(b) = self.bees.lock() if let Ok(b) = self.bees.lock()
&& let Some(b) = b.as_ref() && let Some(b) = b.as_ref()
{ {
nbt.put_list("Bees", b.clone()); nbt.put_list("bees", b.clone());
} }
if let Ok(fp) = self.flower_pos.lock() if let Ok(fp) = self.flower_pos.lock()
&& let Some(fp) = fp.as_ref() && let Some(fp) = fp.as_ref()
{ {
let mut fp_nbt = NbtCompound::new(); nbt.put(
fp_nbt.put_int("X", fp.0.x); "flower_pos",
fp_nbt.put_int("Y", fp.0.y); pumpkin_nbt::tag::NbtTag::IntArray(vec![fp.0.x, fp.0.y, fp.0.z]),
fp_nbt.put_int("Z", fp.0.z); );
nbt.put_compound("FlowerPos", fp_nbt);
} }
} }
@ -60,16 +69,15 @@ impl BlockEntity for BeehiveBlockEntity {
if let Ok(bees) = self.bees.try_lock() if let Ok(bees) = self.bees.try_lock()
&& let Some(ref b) = *bees && let Some(ref b) = *bees
{ {
nbt.put_list("Bees", b.clone()); nbt.put_list("bees", b.clone());
} }
if let Ok(flower_pos) = self.flower_pos.try_lock() if let Ok(flower_pos) = self.flower_pos.try_lock()
&& let Some(ref fp) = *flower_pos && let Some(ref fp) = *flower_pos
{ {
let mut fp_nbt = NbtCompound::new(); nbt.put(
fp_nbt.put_int("X", fp.0.x); "flower_pos",
fp_nbt.put_int("Y", fp.0.y); pumpkin_nbt::tag::NbtTag::IntArray(vec![fp.0.x, fp.0.y, fp.0.z]),
fp_nbt.put_int("Z", fp.0.z); );
nbt.put_compound("FlowerPos", fp_nbt);
} }
Some(nbt) Some(nbt)
} }

View File

@ -356,10 +356,18 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity {
let mut entity = Self::new(position); let mut entity = Self::new(position);
// Load brew time / fuel if present in NBT // Load brew time / fuel if present in NBT
if let Some(bt) = nbt.get_int("BrewTime") { if let Some(bt) = nbt
.get_short("BrewTime")
.map(i32::from)
.or_else(|| nbt.get_int("BrewTime"))
{
entity.brew_time.store(bt, Ordering::Relaxed); entity.brew_time.store(bt, Ordering::Relaxed);
} }
if let Some(f) = nbt.get_int("Fuel") { if let Some(f) = nbt
.get_byte("Fuel")
.map(i32::from)
.or_else(|| nbt.get_int("Fuel"))
{
entity.fuel.store(f, Ordering::Relaxed); entity.fuel.store(f, Ordering::Relaxed);
} }
@ -400,8 +408,8 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity {
fn write_nbt(&self, nbt: &mut NbtCompound) { fn write_nbt(&self, nbt: &mut NbtCompound) {
// Persist brew state // Persist brew state
nbt.put_int("BrewTime", self.brew_time.load(Ordering::Relaxed)); nbt.put_short("BrewTime", self.brew_time.load(Ordering::Relaxed) as i16);
nbt.put_int("Fuel", self.fuel.load(Ordering::Relaxed)); nbt.put_byte("Fuel", self.fuel.load(Ordering::Relaxed) as i8);
// Save inventory contents to NBT // Save inventory contents to NBT
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
@ -413,8 +421,8 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity {
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new(); let mut nbt = NbtCompound::new();
nbt.put_int("BrewTime", self.brew_time.load(Ordering::Relaxed)); nbt.put_short("BrewTime", self.brew_time.load(Ordering::Relaxed) as i16);
nbt.put_int("Fuel", self.fuel.load(Ordering::Relaxed)); nbt.put_byte("Fuel", self.fuel.load(Ordering::Relaxed) as i8);
if let Ok(items) = self.items.try_read() { if let Ok(items) = self.items.try_read() {
sync_write_items_to_nbt(&*items, &mut nbt); sync_write_items_to_nbt(&*items, &mut nbt);
} }

View File

@ -8,7 +8,9 @@ pub struct BrushableBlockBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub item: Mutex<Option<ItemStack>>, pub item: Mutex<Option<ItemStack>>,
pub hits: Mutex<i32>, pub hits: Mutex<i32>,
pub direction: Mutex<u8>, pub hit_direction: Mutex<Option<u8>>,
pub loot_table: Mutex<Option<String>>,
pub loot_table_seed: Mutex<i64>,
} }
impl BlockEntity for BrushableBlockBlockEntity { impl BlockEntity for BrushableBlockBlockEntity {
@ -28,28 +30,48 @@ impl BlockEntity for BrushableBlockBlockEntity {
.get_compound("item") .get_compound("item")
.and_then(ItemStack::read_item_stack); .and_then(ItemStack::read_item_stack);
let hits = nbt.get_int("hits").unwrap_or(0); let hits = nbt.get_int("hits").unwrap_or(0);
let direction = nbt.get_byte("direction").unwrap_or(0) as u8; let hit_direction = nbt
.get_byte("hit_direction")
.or_else(|| nbt.get_byte("direction"))
.map(|b| b as u8);
let loot_table = nbt.get_string("LootTable").map(ToString::to_string);
let loot_table_seed = nbt.get_long("LootTableSeed").unwrap_or(0);
Self { Self {
position, position,
item: Mutex::new(item), item: Mutex::new(item),
hits: Mutex::new(hits), hits: Mutex::new(hits),
direction: Mutex::new(direction), hit_direction: Mutex::new(hit_direction),
loot_table: Mutex::new(loot_table),
loot_table_seed: Mutex::new(loot_table_seed),
} }
} }
fn write_nbt(&self, nbt: &mut NbtCompound) { fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(item) = self.item.lock() if let Ok(loot_table) = self.loot_table.lock()
&& let Some(table) = loot_table.as_ref()
{
nbt.put_string("LootTable", table.clone());
if let Ok(seed) = self.loot_table_seed.lock()
&& *seed != 0
{
nbt.put_long("LootTableSeed", *seed);
}
} else if let Ok(item) = self.item.lock()
&& let Some(it) = item.as_ref() && let Some(it) = item.as_ref()
{ {
let mut it_nbt = NbtCompound::new(); let mut it_nbt = NbtCompound::new();
it.write_item_stack(&mut it_nbt); it.write_item_stack(&mut it_nbt);
nbt.put_compound("item", it_nbt); nbt.put_compound("item", it_nbt);
} }
if let Ok(hits) = self.hits.lock() { if let Ok(hits) = self.hits.lock()
&& *hits != 0
{
nbt.put_int("hits", *hits); nbt.put_int("hits", *hits);
} }
if let Ok(direction) = self.direction.lock() { if let Ok(direction) = self.hit_direction.lock()
nbt.put_byte("direction", *direction as i8); && let Some(dir) = *direction
{
nbt.put_byte("hit_direction", dir as i8);
} }
} }
@ -62,8 +84,11 @@ impl BlockEntity for BrushableBlockBlockEntity {
it.write_item_stack(&mut it_nbt); it.write_item_stack(&mut it_nbt);
nbt.put_compound("item", it_nbt); nbt.put_compound("item", it_nbt);
} }
nbt.put_int("hits", *self.hits.try_lock().ok()?); if let Ok(direction) = self.hit_direction.try_lock()
nbt.put_byte("direction", *self.direction.try_lock().ok()? as i8); && let Some(dir) = *direction
{
nbt.put_byte("hit_direction", dir as i8);
}
Some(nbt) Some(nbt)
} }
@ -80,7 +105,9 @@ impl BrushableBlockBlockEntity {
position, position,
item: Mutex::new(None), item: Mutex::new(None),
hits: Mutex::new(0), hits: Mutex::new(0),
direction: Mutex::new(0), hit_direction: Mutex::new(None),
loot_table: Mutex::new(None),
loot_table_seed: Mutex::new(0),
} }
} }
} }

View File

@ -90,6 +90,23 @@ impl BlockEntity for CampfireBlockEntity {
nbt.put("CookingTotalTimes", NbtTag::IntArray(total_times)); nbt.put("CookingTotalTimes", NbtTag::IntArray(total_times));
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new();
let mut list = Vec::new();
for (i, item_mutex) in self.items.iter().enumerate() {
if let Ok(stack) = item_mutex.try_lock()
&& !stack.is_empty()
{
let mut item_nbt = NbtCompound::new();
item_nbt.put_byte("Slot", i as i8);
stack.write_item_stack(&mut item_nbt);
list.push(NbtTag::Compound(item_nbt));
}
}
nbt.put_list("Items", list);
Some(nbt)
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
@ -106,4 +123,17 @@ impl CampfireBlockEntity {
cooking_total_times: [Mutex::new(0), Mutex::new(0), Mutex::new(0), Mutex::new(0)], cooking_total_times: [Mutex::new(0), Mutex::new(0), Mutex::new(0), Mutex::new(0)],
} }
} }
pub fn add_item(&self, item: &ItemStack) -> bool {
for slot in &self.items {
if let Ok(mut stack) = slot.lock()
&& stack.is_empty()
{
*stack = item.clone();
stack.item_count = 1;
return true;
}
}
false
}
} }

View File

@ -1,10 +1,12 @@
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::sync::Mutex;
use super::BlockEntity; use super::BlockEntity;
pub struct CopperGolemStatueBlockEntity { pub struct CopperGolemStatueBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub custom_name: Mutex<Option<String>>,
} }
impl BlockEntity for CopperGolemStatueBlockEntity { impl BlockEntity for CopperGolemStatueBlockEntity {
@ -16,14 +18,37 @@ impl BlockEntity for CopperGolemStatueBlockEntity {
self.position self.position
} }
fn from_nbt(_nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
where where
Self: Sized, Self: Sized,
{ {
Self { position } let custom_name = nbt
.get_string("custom_name")
.or_else(|| nbt.get_string("CustomName"))
.map(ToString::to_string);
Self {
position,
custom_name: Mutex::new(custom_name),
}
} }
fn write_nbt(&self, _nbt: &mut NbtCompound) {} fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(name) = self.custom_name.lock()
&& let Some(name) = name.as_ref()
{
nbt.put_string("custom_name", name.clone());
}
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new();
if let Ok(name) = self.custom_name.try_lock()
&& let Some(ref name) = *name
{
nbt.put_string("custom_name", name.clone());
}
Some(nbt)
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
@ -34,6 +59,9 @@ impl CopperGolemStatueBlockEntity {
pub const ID: &'static str = "minecraft:copper_golem_statue"; pub const ID: &'static str = "minecraft:copper_golem_statue";
#[must_use] #[must_use]
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { position } Self {
position,
custom_name: Mutex::new(None),
}
} }
} }

View File

@ -29,8 +29,15 @@ impl BlockEntity for CreakingHeartBlockEntity {
Self: Sized, Self: Sized,
{ {
let creaking_uuid = nbt let creaking_uuid = nbt
.get_string("creaking_uuid") .get_uuid("creaking")
.and_then(|uuid_str| Uuid::parse_str(uuid_str).ok()); .or_else(|| {
nbt.get_string("creaking")
.and_then(|uuid_str| Uuid::parse_str(uuid_str).ok())
})
.or_else(|| {
nbt.get_string("creaking_uuid")
.and_then(|uuid_str| Uuid::parse_str(uuid_str).ok())
});
Self { Self {
position, position,
creaking_uuid: AtomicCell::new(creaking_uuid), creaking_uuid: AtomicCell::new(creaking_uuid),
@ -39,10 +46,18 @@ impl BlockEntity for CreakingHeartBlockEntity {
fn write_nbt(&self, nbt: &mut NbtCompound) { fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Some(uuid) = self.creaking_uuid.load() { if let Some(uuid) = self.creaking_uuid.load() {
nbt.put_string("creaking_uuid", uuid.to_string()); nbt.put_uuid("creaking", uuid);
} }
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new();
if let Some(uuid) = self.creaking_uuid.load() {
nbt.put_uuid("creaking", uuid);
}
Some(nbt)
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }

View File

@ -35,17 +35,18 @@ impl BlockEntity for EndGatewayBlockEntity {
let age = nbt.get_long("Age").unwrap_or(0); let age = nbt.get_long("Age").unwrap_or(0);
let exact_teleport = nbt.get_bool("ExactTeleport").unwrap_or(false); let exact_teleport = nbt.get_bool("ExactTeleport").unwrap_or(false);
let exit_portal = nbt let exit_portal = nbt
.get_compound("ExitPortal") .get_int_array("exit_portal")
.map(|c| { .and_then(|arr| (arr.len() == 3).then(|| BlockPos::new(arr[0], arr[1], arr[2])))
BlockPos::new(
c.get_int("X").unwrap_or(0),
c.get_int("Y").unwrap_or(0),
c.get_int("Z").unwrap_or(0),
)
})
.or_else(|| { .or_else(|| {
nbt.get_int_array("exit_portal") nbt.get_compound("exit_portal")
.and_then(|arr| (arr.len() == 3).then(|| BlockPos::new(arr[0], arr[1], arr[2]))) .or_else(|| nbt.get_compound("ExitPortal"))
.map(|c| {
BlockPos::new(
c.get_int("X").or_else(|| c.get_int("x")).unwrap_or(0),
c.get_int("Y").or_else(|| c.get_int("y")).unwrap_or(0),
c.get_int("Z").or_else(|| c.get_int("z")).unwrap_or(0),
)
})
}); });
Self { Self {
position, position,
@ -68,11 +69,10 @@ impl BlockEntity for EndGatewayBlockEntity {
if let Ok(exit_portal) = self.exit_portal.lock() if let Ok(exit_portal) = self.exit_portal.lock()
&& let Some(exit) = exit_portal.as_ref() && let Some(exit) = exit_portal.as_ref()
{ {
let mut exit_nbt = NbtCompound::new(); nbt.put(
exit_nbt.put_int("X", exit.0.x); "exit_portal",
exit_nbt.put_int("Y", exit.0.y); pumpkin_nbt::tag::NbtTag::IntArray(vec![exit.0.x, exit.0.y, exit.0.z]),
exit_nbt.put_int("Z", exit.0.z); );
nbt.put_compound("ExitPortal", exit_nbt);
} }
} }
@ -87,11 +87,10 @@ impl BlockEntity for EndGatewayBlockEntity {
if let Ok(exit_portal) = self.exit_portal.try_lock() if let Ok(exit_portal) = self.exit_portal.try_lock()
&& let Some(ref exit) = *exit_portal && let Some(ref exit) = *exit_portal
{ {
let mut exit_nbt = NbtCompound::new(); nbt.put(
exit_nbt.put_int("X", exit.0.x); "exit_portal",
exit_nbt.put_int("Y", exit.0.y); pumpkin_nbt::tag::NbtTag::IntArray(vec![exit.0.x, exit.0.y, exit.0.z]),
exit_nbt.put_int("Z", exit.0.z); );
nbt.put_compound("ExitPortal", exit_nbt);
} }
Some(nbt) Some(nbt)
} }

View File

@ -1,10 +1,12 @@
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::sync::atomic::{AtomicI32, Ordering};
use super::BlockEntity; use super::BlockEntity;
pub struct PotentSulfurBlockEntity { pub struct PotentSulfurBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub waiting_countdown: AtomicI32,
} }
impl BlockEntity for PotentSulfurBlockEntity { impl BlockEntity for PotentSulfurBlockEntity {
@ -16,14 +18,23 @@ impl BlockEntity for PotentSulfurBlockEntity {
self.position self.position
} }
fn from_nbt(_nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
where where
Self: Sized, Self: Sized,
{ {
Self { position } let countdown = nbt.get_int("countdown").unwrap_or(-1);
Self {
position,
waiting_countdown: AtomicI32::new(countdown),
}
} }
fn write_nbt(&self, _nbt: &mut NbtCompound) {} fn write_nbt(&self, nbt: &mut NbtCompound) {
let countdown = self.waiting_countdown.load(Ordering::Relaxed);
if countdown != -1 {
nbt.put_int("countdown", countdown);
}
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
@ -34,6 +45,9 @@ impl PotentSulfurBlockEntity {
pub const ID: &'static str = "minecraft:potent_sulfur"; pub const ID: &'static str = "minecraft:potent_sulfur";
#[must_use] #[must_use]
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { position } Self {
position,
waiting_countdown: AtomicI32::new(-1),
}
} }
} }

View File

@ -12,21 +12,27 @@ use std::sync::atomic::{AtomicBool, Ordering};
pub struct ShelfBlockEntity { pub struct ShelfBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub items: RwLock<[ItemStack; Self::INVENTORY_SIZE]>, pub items: RwLock<[ItemStack; Self::INVENTORY_SIZE]>,
pub align_items_to_bottom: AtomicBool,
pub dirty: AtomicBool, pub dirty: AtomicBool,
} }
impl BlockEntity for ShelfBlockEntity { impl BlockEntity for ShelfBlockEntity {
fn write_nbt(&self, nbt: &mut NbtCompound) { fn write_nbt(&self, nbt: &mut NbtCompound) {
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
if self.align_items_to_bottom.load(Ordering::Relaxed) {
nbt.put_bool("align_items_to_bottom", true);
}
} }
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
where where
Self: Sized, Self: Sized,
{ {
let align_items_to_bottom = nbt.get_bool("align_items_to_bottom").unwrap_or(false);
let mut shelf = Self { let mut shelf = Self {
position, position,
items: RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), items: RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())),
align_items_to_bottom: AtomicBool::new(align_items_to_bottom),
dirty: AtomicBool::new(false), dirty: AtomicBool::new(false),
}; };
@ -66,6 +72,9 @@ impl BlockEntity for ShelfBlockEntity {
if let Ok(items) = self.items.try_read() { if let Ok(items) = self.items.try_read() {
sync_write_items_to_nbt(items.as_slice(), &mut nbt); sync_write_items_to_nbt(items.as_slice(), &mut nbt);
} }
if self.align_items_to_bottom.load(Ordering::Relaxed) {
nbt.put_bool("align_items_to_bottom", true);
}
Some(nbt) Some(nbt)
} }
@ -83,6 +92,7 @@ impl ShelfBlockEntity {
Self { Self {
position, position,
items: RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), items: RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())),
align_items_to_bottom: AtomicBool::new(false),
dirty: AtomicBool::new(false), dirty: AtomicBool::new(false),
} }
} }

View File

@ -7,6 +7,7 @@ pub struct SkullBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub note_block_sound: Mutex<Option<String>>, pub note_block_sound: Mutex<Option<String>>,
pub profile: Mutex<Option<NbtCompound>>, pub profile: Mutex<Option<NbtCompound>>,
pub custom_name: Mutex<Option<String>>,
} }
impl BlockEntity for SkullBlockEntity { impl BlockEntity for SkullBlockEntity {
@ -24,10 +25,15 @@ impl BlockEntity for SkullBlockEntity {
{ {
let note_block_sound = nbt.get_string("note_block_sound").map(ToString::to_string); let note_block_sound = nbt.get_string("note_block_sound").map(ToString::to_string);
let profile = nbt.get_compound("profile").cloned(); let profile = nbt.get_compound("profile").cloned();
let custom_name = nbt
.get_string("custom_name")
.or_else(|| nbt.get_string("CustomName"))
.map(ToString::to_string);
Self { Self {
position, position,
note_block_sound: Mutex::new(note_block_sound), note_block_sound: Mutex::new(note_block_sound),
profile: Mutex::new(profile), profile: Mutex::new(profile),
custom_name: Mutex::new(custom_name),
} }
} }
@ -42,6 +48,11 @@ impl BlockEntity for SkullBlockEntity {
{ {
nbt.put_compound("profile", prof.clone()); nbt.put_compound("profile", prof.clone());
} }
if let Ok(name) = self.custom_name.lock()
&& let Some(name) = name.as_ref()
{
nbt.put_string("custom_name", name.clone());
}
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -56,6 +67,11 @@ impl BlockEntity for SkullBlockEntity {
{ {
nbt.put_compound("profile", prof.clone()); nbt.put_compound("profile", prof.clone());
} }
if let Ok(name) = self.custom_name.try_lock()
&& let Some(ref name) = *name
{
nbt.put_string("custom_name", name.clone());
}
Some(nbt) Some(nbt)
} }
@ -72,6 +88,7 @@ impl SkullBlockEntity {
position, position,
note_block_sound: Mutex::new(None), note_block_sound: Mutex::new(None),
profile: Mutex::new(None), profile: Mutex::new(None),
custom_name: Mutex::new(None),
} }
} }
} }

View File

@ -18,6 +18,8 @@ pub struct StructureBlockBlockEntity {
pub mirror: Mutex<String>, pub mirror: Mutex<String>,
pub mode: Mutex<String>, pub mode: Mutex<String>,
pub ignore_entities: Mutex<bool>, pub ignore_entities: Mutex<bool>,
pub strict: Mutex<bool>,
pub powered: Mutex<bool>,
pub show_air: Mutex<bool>, pub show_air: Mutex<bool>,
pub show_bounding_box: Mutex<bool>, pub show_bounding_box: Mutex<bool>,
pub integrity: Mutex<f32>, pub integrity: Mutex<f32>,
@ -52,8 +54,18 @@ impl BlockEntity for StructureBlockBlockEntity {
mirror: Mutex::new(nbt.get_string("mirror").unwrap_or("NONE").to_string()), mirror: Mutex::new(nbt.get_string("mirror").unwrap_or("NONE").to_string()),
mode: Mutex::new(nbt.get_string("mode").unwrap_or("DATA").to_string()), mode: Mutex::new(nbt.get_string("mode").unwrap_or("DATA").to_string()),
ignore_entities: Mutex::new(nbt.get_bool("ignoreEntities").unwrap_or(true)), ignore_entities: Mutex::new(nbt.get_bool("ignoreEntities").unwrap_or(true)),
show_air: Mutex::new(nbt.get_bool("showAir").unwrap_or(false)), strict: Mutex::new(nbt.get_bool("strict").unwrap_or(false)),
show_bounding_box: Mutex::new(nbt.get_bool("showBoundingBox").unwrap_or(true)), powered: Mutex::new(nbt.get_bool("powered").unwrap_or(false)),
show_air: Mutex::new(
nbt.get_bool("showair")
.or_else(|| nbt.get_bool("showAir"))
.unwrap_or(false),
),
show_bounding_box: Mutex::new(
nbt.get_bool("showboundingbox")
.or_else(|| nbt.get_bool("showBoundingBox"))
.unwrap_or(true),
),
integrity: Mutex::new(nbt.get_float("integrity").unwrap_or(1.0)), integrity: Mutex::new(nbt.get_float("integrity").unwrap_or(1.0)),
seed: Mutex::new(nbt.get_long("seed").unwrap_or(0)), seed: Mutex::new(nbt.get_long("seed").unwrap_or(0)),
} }
@ -99,11 +111,17 @@ impl BlockEntity for StructureBlockBlockEntity {
if let Ok(ignore_entities) = self.ignore_entities.lock() { if let Ok(ignore_entities) = self.ignore_entities.lock() {
nbt.put_bool("ignoreEntities", *ignore_entities); nbt.put_bool("ignoreEntities", *ignore_entities);
} }
if let Ok(strict) = self.strict.lock() {
nbt.put_bool("strict", *strict);
}
if let Ok(powered) = self.powered.lock() {
nbt.put_bool("powered", *powered);
}
if let Ok(show_air) = self.show_air.lock() { if let Ok(show_air) = self.show_air.lock() {
nbt.put_bool("showAir", *show_air); nbt.put_bool("showair", *show_air);
} }
if let Ok(show_bounding_box) = self.show_bounding_box.lock() { if let Ok(show_bounding_box) = self.show_bounding_box.lock() {
nbt.put_bool("showBoundingBox", *show_bounding_box); nbt.put_bool("showboundingbox", *show_bounding_box);
} }
if let Ok(integrity) = self.integrity.lock() { if let Ok(integrity) = self.integrity.lock() {
nbt.put_float("integrity", *integrity); nbt.put_float("integrity", *integrity);
@ -128,8 +146,10 @@ impl BlockEntity for StructureBlockBlockEntity {
nbt.put_string("mirror", self.mirror.try_lock().ok()?.clone()); nbt.put_string("mirror", self.mirror.try_lock().ok()?.clone());
nbt.put_string("mode", self.mode.try_lock().ok()?.clone()); nbt.put_string("mode", self.mode.try_lock().ok()?.clone());
nbt.put_bool("ignoreEntities", *self.ignore_entities.try_lock().ok()?); nbt.put_bool("ignoreEntities", *self.ignore_entities.try_lock().ok()?);
nbt.put_bool("showAir", *self.show_air.try_lock().ok()?); nbt.put_bool("strict", *self.strict.try_lock().ok()?);
nbt.put_bool("showBoundingBox", *self.show_bounding_box.try_lock().ok()?); nbt.put_bool("powered", *self.powered.try_lock().ok()?);
nbt.put_bool("showair", *self.show_air.try_lock().ok()?);
nbt.put_bool("showboundingbox", *self.show_bounding_box.try_lock().ok()?);
nbt.put_float("integrity", *self.integrity.try_lock().ok()?); nbt.put_float("integrity", *self.integrity.try_lock().ok()?);
nbt.put_long("seed", *self.seed.try_lock().ok()?); nbt.put_long("seed", *self.seed.try_lock().ok()?);
Some(nbt) Some(nbt)
@ -159,6 +179,8 @@ impl StructureBlockBlockEntity {
mirror: Mutex::new("NONE".to_string()), mirror: Mutex::new("NONE".to_string()),
mode: Mutex::new("DATA".to_string()), mode: Mutex::new("DATA".to_string()),
ignore_entities: Mutex::new(true), ignore_entities: Mutex::new(true),
strict: Mutex::new(false),
powered: Mutex::new(false),
show_air: Mutex::new(false), show_air: Mutex::new(false),
show_bounding_box: Mutex::new(true), show_bounding_box: Mutex::new(true),
integrity: Mutex::new(1.0), integrity: Mutex::new(1.0),

View File

@ -1,10 +1,15 @@
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
use super::BlockEntity; use super::BlockEntity;
pub struct TestBlockBlockEntity { pub struct TestBlockBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub mode: Mutex<String>,
pub message: Mutex<String>,
pub powered: AtomicBool,
} }
impl BlockEntity for TestBlockBlockEntity { impl BlockEntity for TestBlockBlockEntity {
@ -16,14 +21,42 @@ impl BlockEntity for TestBlockBlockEntity {
self.position self.position
} }
fn from_nbt(_nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
where where
Self: Sized, Self: Sized,
{ {
Self { position } let mode = nbt.get_string("mode").unwrap_or("FAIL").to_string();
let message = nbt.get_string("message").unwrap_or("").to_string();
let powered = nbt.get_bool("powered").unwrap_or(false);
Self {
position,
mode: Mutex::new(mode),
message: Mutex::new(message),
powered: AtomicBool::new(powered),
}
} }
fn write_nbt(&self, _nbt: &mut NbtCompound) {} fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(mode) = self.mode.lock() {
nbt.put_string("mode", mode.clone());
}
if let Ok(message) = self.message.lock() {
nbt.put_string("message", message.clone());
}
nbt.put_bool("powered", self.powered.load(Ordering::Relaxed));
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new();
if let Ok(mode) = self.mode.try_lock() {
nbt.put_string("mode", mode.clone());
}
if let Ok(message) = self.message.try_lock() {
nbt.put_string("message", message.clone());
}
nbt.put_bool("powered", self.powered.load(Ordering::Relaxed));
Some(nbt)
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
@ -33,7 +66,12 @@ impl BlockEntity for TestBlockBlockEntity {
impl TestBlockBlockEntity { impl TestBlockBlockEntity {
pub const ID: &'static str = "minecraft:test_block"; pub const ID: &'static str = "minecraft:test_block";
#[must_use] #[must_use]
pub const fn new(position: BlockPos) -> Self { pub fn new(position: BlockPos) -> Self {
Self { position } Self {
position,
mode: Mutex::new("FAIL".to_string()),
message: Mutex::new(String::new()),
powered: AtomicBool::new(false),
}
} }
} }

View File

@ -1,10 +1,14 @@
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::sync::Mutex;
use super::BlockEntity; use super::BlockEntity;
pub struct TestInstanceBlockBlockEntity { pub struct TestInstanceBlockBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub data: Mutex<Option<NbtCompound>>,
pub errors: Mutex<Option<Vec<NbtTag>>>,
} }
impl BlockEntity for TestInstanceBlockBlockEntity { impl BlockEntity for TestInstanceBlockBlockEntity {
@ -16,14 +20,46 @@ impl BlockEntity for TestInstanceBlockBlockEntity {
self.position self.position
} }
fn from_nbt(_nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
where where
Self: Sized, Self: Sized,
{ {
Self { position } let data = nbt.get_compound("data").cloned();
let errors = nbt.get_list("errors").map(<[_]>::to_vec);
Self {
position,
data: Mutex::new(data),
errors: Mutex::new(errors),
}
} }
fn write_nbt(&self, _nbt: &mut NbtCompound) {} fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(data) = self.data.lock()
&& let Some(d) = data.as_ref()
{
nbt.put_compound("data", d.clone());
}
if let Ok(errors) = self.errors.lock()
&& let Some(errs) = errors.as_ref()
{
nbt.put_list("errors", errs.clone());
}
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new();
if let Ok(data) = self.data.try_lock()
&& let Some(ref d) = *data
{
nbt.put_compound("data", d.clone());
}
if let Ok(errors) = self.errors.try_lock()
&& let Some(ref errs) = *errors
{
nbt.put_list("errors", errs.clone());
}
Some(nbt)
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
@ -34,6 +70,10 @@ impl TestInstanceBlockBlockEntity {
pub const ID: &'static str = "minecraft:test_instance_block"; pub const ID: &'static str = "minecraft:test_instance_block";
#[must_use] #[must_use]
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { position } Self {
position,
data: Mutex::new(None),
errors: Mutex::new(None),
}
} }
} }

View File

@ -9,6 +9,7 @@ pub struct VaultBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub config: Mutex<Option<NbtCompound>>, pub config: Mutex<Option<NbtCompound>>,
pub server_data: Mutex<Option<NbtCompound>>, pub server_data: Mutex<Option<NbtCompound>>,
pub shared_data: Mutex<Option<NbtCompound>>,
pub rewarded_players: Mutex<FxHashSet<Uuid>>, pub rewarded_players: Mutex<FxHashSet<Uuid>>,
} }
@ -29,6 +30,7 @@ impl BlockEntity for VaultBlockEntity {
position, position,
config: Mutex::new(nbt.get_compound("config").cloned()), config: Mutex::new(nbt.get_compound("config").cloned()),
server_data: Mutex::new(nbt.get_compound("server_data").cloned()), server_data: Mutex::new(nbt.get_compound("server_data").cloned()),
shared_data: Mutex::new(nbt.get_compound("shared_data").cloned()),
rewarded_players: Mutex::new(FxHashSet::default()), rewarded_players: Mutex::new(FxHashSet::default()),
} }
} }
@ -44,19 +46,19 @@ impl BlockEntity for VaultBlockEntity {
{ {
nbt.put_compound("server_data", data.clone()); nbt.put_compound("server_data", data.clone());
} }
if let Ok(shared) = self.shared_data.lock()
&& let Some(shared) = shared.as_ref()
{
nbt.put_compound("shared_data", shared.clone());
}
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
let mut nbt = NbtCompound::new(); let mut nbt = NbtCompound::new();
if let Ok(cfg) = self.config.try_lock() if let Ok(shared) = self.shared_data.try_lock()
&& let Some(ref cfg) = *cfg && let Some(ref shared) = *shared
{ {
nbt.put_compound("config", cfg.clone()); nbt.put_compound("shared_data", shared.clone());
}
if let Ok(data) = self.server_data.try_lock()
&& let Some(ref data) = *data
{
nbt.put_compound("server_data", data.clone());
} }
Some(nbt) Some(nbt)
} }
@ -75,6 +77,7 @@ impl VaultBlockEntity {
position, position,
config: Mutex::new(None), config: Mutex::new(None),
server_data: Mutex::new(None), server_data: Mutex::new(None),
shared_data: Mutex::new(None),
rewarded_players: Mutex::new(FxHashSet::default()), rewarded_players: Mutex::new(FxHashSet::default()),
} }
} }

View File

@ -463,10 +463,17 @@ pub fn drop_loot(
} }
} }
if experience && let Some(experience) = &block.experience { let has_silk_touch = params.tool.as_ref().is_some_and(|tool| {
pumpkin_data::Enchantment::from_name("silk_touch")
.is_some_and(|e| tool.get_enchantment_level(e) > 0)
});
if experience
&& !has_silk_touch
&& let Some(experience) = &block.experience
{
let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(get_seed())); let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(get_seed()));
let amount = experience.experience.get(&mut random); let amount = experience.experience.get(&mut random);
// TODO: Silk touch gives no exp
if amount > 0 { if amount > 0 {
let mut event = crate::plugin::block::block_exp::BlockExpEvent { let mut event = crate::plugin::block::block_exp::BlockExpEvent {
block_pos: *pos, block_pos: *pos,

View File

@ -47,21 +47,25 @@ use crate::block::blocks::glazed_terracotta::GlazedTerracottaBlock;
use crate::block::blocks::grass_block::GrassBlock; use crate::block::blocks::grass_block::GrassBlock;
use crate::block::blocks::grindstone::GrindstoneBlock; use crate::block::blocks::grindstone::GrindstoneBlock;
use crate::block::blocks::hay::HayBlock; use crate::block::blocks::hay::HayBlock;
use crate::block::blocks::honey::HoneyBlock;
use crate::block::blocks::ice::{FrostedIceBlock, IceBlock}; use crate::block::blocks::ice::{FrostedIceBlock, IceBlock};
use crate::block::blocks::infested::InfestedBlock; use crate::block::blocks::infested::InfestedBlock;
use crate::block::blocks::iron_bars::IronBarsBlock; use crate::block::blocks::iron_bars::IronBarsBlock;
use crate::block::blocks::jigsaw::JigsawBlock; use crate::block::blocks::jigsaw::JigsawBlock;
// use crate::block::blocks::leaves::LeavesBlock; use crate::block::blocks::leaves::LeavesBlock;
use crate::block::blocks::light::LightBlock;
use crate::block::blocks::logs::LogBlock; use crate::block::blocks::logs::LogBlock;
use crate::block::blocks::loom::LoomBlock; use crate::block::blocks::loom::LoomBlock;
use crate::block::blocks::magma::MagmaBlock; use crate::block::blocks::magma::MagmaBlock;
use crate::block::blocks::mangrove_roots::MangroveRootsBlock; use crate::block::blocks::mangrove_roots::MangroveRootsBlock;
use crate::block::blocks::mud::MudBlock;
use crate::block::blocks::nether_portal::NetherPortalBlock; use crate::block::blocks::nether_portal::NetherPortalBlock;
use crate::block::blocks::note::NoteBlock; use crate::block::blocks::note::NoteBlock;
use crate::block::blocks::nylium::NyliumBlock; use crate::block::blocks::nylium::NyliumBlock;
use crate::block::blocks::piston::piston::PistonBlock; use crate::block::blocks::piston::piston::PistonBlock;
use crate::block::blocks::piston::piston_extension::PistonExtensionBlock; use crate::block::blocks::piston::piston_extension::PistonExtensionBlock;
use crate::block::blocks::piston::piston_head::PistonHeadBlock; use crate::block::blocks::piston::piston_head::PistonHeadBlock;
use crate::block::blocks::plant::azalea::AzaleaBlock;
use crate::block::blocks::plant::bamboo::BambooBlock; use crate::block::blocks::plant::bamboo::BambooBlock;
use crate::block::blocks::plant::bamboo_sapling::BambooSaplingBlock; use crate::block::blocks::plant::bamboo_sapling::BambooSaplingBlock;
use crate::block::blocks::plant::big_dripleaf::BigDripleafBlock; use crate::block::blocks::plant::big_dripleaf::BigDripleafBlock;
@ -69,12 +73,14 @@ use crate::block::blocks::plant::big_dripleaf_stem::BigDripleafStemBlock;
use crate::block::blocks::plant::bush::BushBlock; use crate::block::blocks::plant::bush::BushBlock;
use crate::block::blocks::plant::cactus::CactusBlock; use crate::block::blocks::plant::cactus::CactusBlock;
use crate::block::blocks::plant::cactus_flower::CactusFlowerBlock; use crate::block::blocks::plant::cactus_flower::CactusFlowerBlock;
use crate::block::blocks::plant::cave_vines::CaveVinesBlock;
use crate::block::blocks::plant::chorus_flower::ChorusFlowerBlock; use crate::block::blocks::plant::chorus_flower::ChorusFlowerBlock;
use crate::block::blocks::plant::chorus_plant::ChorusPlantBlock; use crate::block::blocks::plant::chorus_plant::ChorusPlantBlock;
use crate::block::blocks::plant::cocoa::CocoaBlock; use crate::block::blocks::plant::cocoa::CocoaBlock;
use crate::block::blocks::plant::crop::beetroot::BeetrootBlock; use crate::block::blocks::plant::crop::beetroot::BeetrootBlock;
use crate::block::blocks::plant::crop::carrot::CarrotBlock; use crate::block::blocks::plant::crop::carrot::CarrotBlock;
use crate::block::blocks::plant::crop::nether_wart::NetherWartBlock; use crate::block::blocks::plant::crop::nether_wart::NetherWartBlock;
use crate::block::blocks::plant::crop::pitcher_crop::PitcherCropBlock;
use crate::block::blocks::plant::crop::potatoes::PotatoBlock; use crate::block::blocks::plant::crop::potatoes::PotatoBlock;
use crate::block::blocks::plant::crop::sweet_berry_bush::SweetBerryBushBlock; use crate::block::blocks::plant::crop::sweet_berry_bush::SweetBerryBushBlock;
use crate::block::blocks::plant::crop::torch_flower::TorchFlowerBlock; use crate::block::blocks::plant::crop::torch_flower::TorchFlowerBlock;
@ -84,6 +90,7 @@ use crate::block::blocks::plant::eyeblossom::EyeblossomBlock;
use crate::block::blocks::plant::flower::FlowerBlock; use crate::block::blocks::plant::flower::FlowerBlock;
use crate::block::blocks::plant::flowerbed::FlowerbedBlock; use crate::block::blocks::plant::flowerbed::FlowerbedBlock;
use crate::block::blocks::plant::fungus::FungusBlock; use crate::block::blocks::plant::fungus::FungusBlock;
use crate::block::blocks::plant::hanging_roots::HangingRootsBlock;
use crate::block::blocks::plant::kelp::KelpBlock; use crate::block::blocks::plant::kelp::KelpBlock;
use crate::block::blocks::plant::leaf_litter::LeafLitterBlock; use crate::block::blocks::plant::leaf_litter::LeafLitterBlock;
use crate::block::blocks::plant::lily_pad::LilyPadBlock; use crate::block::blocks::plant::lily_pad::LilyPadBlock;
@ -132,9 +139,10 @@ use crate::block::blocks::redstone::sculk_sensor::SculkSensorBlock;
use crate::block::blocks::redstone::target_block::TargetBlock; use crate::block::blocks::redstone::target_block::TargetBlock;
use crate::block::blocks::redstone::tripwire::TripwireBlock; use crate::block::blocks::redstone::tripwire::TripwireBlock;
use crate::block::blocks::redstone::tripwire_hook::TripwireHookBlock; use crate::block::blocks::redstone::tripwire_hook::TripwireHookBlock;
use crate::block::blocks::scaffolding::ScaffoldingBlock;
use crate::block::blocks::sculk::sculk_catalyst::SculkCatalystBlock; use crate::block::blocks::sculk::sculk_catalyst::SculkCatalystBlock;
use crate::block::blocks::sculk::sculk_shrieker::SculkShriekerBlock; use crate::block::blocks::sculk::sculk_shrieker::SculkShriekerBlock;
use crate::block::blocks::sculk::sculk_vein::SculkVeinBlock; use crate::block::blocks::sculk::sculk_vein::MultifaceBlock;
use crate::block::blocks::shelf::ShelfBlock; use crate::block::blocks::shelf::ShelfBlock;
use crate::block::blocks::signs::SignBlock; use crate::block::blocks::signs::SignBlock;
use crate::block::blocks::slabs::SlabBlock; use crate::block::blocks::slabs::SlabBlock;
@ -142,10 +150,14 @@ use crate::block::blocks::slime::SlimeBlock;
use crate::block::blocks::smithing_table::SmithingTableBlock; use crate::block::blocks::smithing_table::SmithingTableBlock;
use crate::block::blocks::sniffer_egg::SnifferEggBlock; use crate::block::blocks::sniffer_egg::SnifferEggBlock;
use crate::block::blocks::snow::LayeredSnowBlock; use crate::block::blocks::snow::LayeredSnowBlock;
use crate::block::blocks::soul_sand::SoulSandBlock;
use crate::block::blocks::spawner::SpawnerBlock; use crate::block::blocks::spawner::SpawnerBlock;
use crate::block::blocks::sponge::{SpongeBlock, WetSpongeBlock}; use crate::block::blocks::sponge::{SpongeBlock, WetSpongeBlock};
use crate::block::blocks::stairs::StairBlock; use crate::block::blocks::stairs::StairBlock;
use crate::block::blocks::structure_block::StructureBlock; use crate::block::blocks::structure_block::StructureBlock;
use crate::block::blocks::structure_void::StructureVoidBlock;
use crate::block::blocks::test_block::{TestBlock, TestInstanceBlock};
use crate::block::blocks::tinted_glass::TintedGlassBlock;
use crate::block::blocks::tnt::TNTBlock; use crate::block::blocks::tnt::TNTBlock;
use crate::block::blocks::torches::TorchBlock; use crate::block::blocks::torches::TorchBlock;
use crate::block::blocks::trapdoor::TrapDoorBlock; use crate::block::blocks::trapdoor::TrapDoorBlock;
@ -264,14 +276,20 @@ pub fn default_registry() -> Arc<BlockRegistry> {
manager.register(InfestedBlock); manager.register(InfestedBlock);
manager.register(JukeboxBlock); manager.register(JukeboxBlock);
manager.register(LogBlock); manager.register(LogBlock);
// FIX despawn manager.register(LeavesBlock);
// manager.register(LeavesBlock);
manager.register(BambooBlock); manager.register(BambooBlock);
manager.register(BambooSaplingBlock); manager.register(BambooSaplingBlock);
manager.register(BannerBlock); manager.register(BannerBlock);
manager.register(SignBlock); manager.register(SignBlock);
manager.register(SlabBlock); manager.register(SlabBlock);
manager.register(SlimeBlock); manager.register(SlimeBlock);
manager.register(HoneyBlock);
manager.register(MudBlock);
manager.register(SoulSandBlock);
manager.register(ScaffoldingBlock);
manager.register(LightBlock);
manager.register(StructureVoidBlock);
manager.register(TintedGlassBlock);
manager.register(StairBlock); manager.register(StairBlock);
manager.register(StonecutterBlock); manager.register(StonecutterBlock);
manager.register(LoomBlock); manager.register(LoomBlock);
@ -279,6 +297,8 @@ pub fn default_registry() -> Arc<BlockRegistry> {
manager.register(SmithingTableBlock); manager.register(SmithingTableBlock);
manager.register(FletchingTableBlock); manager.register(FletchingTableBlock);
manager.register(StructureBlock); manager.register(StructureBlock);
manager.register(TestBlock);
manager.register(TestInstanceBlock);
manager.register(ShortPlantBlock); manager.register(ShortPlantBlock);
manager.register(DryVegetationBlock); manager.register(DryVegetationBlock);
manager.register(LilyPadBlock); manager.register(LilyPadBlock);
@ -298,6 +318,10 @@ pub fn default_registry() -> Arc<BlockRegistry> {
manager.register(PotatoBlock); manager.register(PotatoBlock);
manager.register(BeetrootBlock); manager.register(BeetrootBlock);
manager.register(TorchFlowerBlock); manager.register(TorchFlowerBlock);
manager.register(PitcherCropBlock);
manager.register(CaveVinesBlock);
manager.register(AzaleaBlock);
manager.register(HangingRootsBlock);
manager.register(CarrotBlock); manager.register(CarrotBlock);
manager.register(SweetBerryBushBlock); manager.register(SweetBerryBushBlock);
manager.register(SeaGrassBlock); manager.register(SeaGrassBlock);
@ -392,7 +416,7 @@ pub fn default_registry() -> Arc<BlockRegistry> {
manager.register(LeverBlock); manager.register(LeverBlock);
manager.register(LightningRodBlock); manager.register(LightningRodBlock);
manager.register(SculkSensorBlock); manager.register(SculkSensorBlock);
manager.register(SculkVeinBlock); manager.register(MultifaceBlock);
manager.register(SculkCatalystBlock); manager.register(SculkCatalystBlock);
manager.register(SculkShriekerBlock); manager.register(SculkShriekerBlock);
manager.register(ObserverBlock); manager.register(ObserverBlock);

View File

@ -1,15 +1,34 @@
use crate::command::argument_builder::{ArgumentBuilder, argument, command, literal}; use pumpkin_data::data_component_impl::EquipmentSlot;
use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::translation;
use pumpkin_inventory::screen_handler::InventoryPlayer;
use pumpkin_protocol::codec::item_stack_seralizer::ItemStackSerializer;
use pumpkin_protocol::java::client::play::CSetContainerSlot;
use pumpkin_util::PermissionLvl;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::math::vector3::Vector3;
use pumpkin_util::permission::{Permission, PermissionDefault, PermissionRegistry};
use pumpkin_util::text::TextComponent;
use pumpkin_util::text::hover::HoverEvent;
use pumpkin_world::inventory::Inventory;
use crate::command::argument_builder::{
ArgumentBuilder, LiteralArgumentBuilder, argument, command, literal,
};
use crate::command::argument_types::coordinates::block_pos::BlockPosArgumentType; use crate::command::argument_types::coordinates::block_pos::BlockPosArgumentType;
use crate::command::argument_types::coordinates::vec3::Vec3ArgumentType;
use crate::command::argument_types::core::integer::IntegerArgumentType;
use crate::command::argument_types::core::string::StringArgumentType; use crate::command::argument_types::core::string::StringArgumentType;
use crate::command::argument_types::entity::EntityArgumentType; use crate::command::argument_types::entity::EntityArgumentType;
use crate::command::argument_types::item::ItemStackArgumentType;
use crate::command::argument_types::slot::SlotArgumentType;
use crate::command::context::command_context::CommandContext; use crate::command::context::command_context::CommandContext;
use crate::command::errors::command_syntax_error::CommandSyntaxError;
use crate::command::errors::error_types::CommandErrorType; use crate::command::errors::error_types::CommandErrorType;
use crate::command::node::dispatcher::CommandDispatcher; use crate::command::node::dispatcher::CommandDispatcher;
use crate::command::node::{CommandExecutor, CommandExecutorResult}; use crate::command::node::{CommandExecutor, CommandExecutorResult};
use pumpkin_data::translation; use crate::entity::EntityBase;
use pumpkin_util::PermissionLvl; use crate::world::loot::LootContextParameters;
use pumpkin_util::permission::{Permission, PermissionDefault, PermissionRegistry};
use pumpkin_util::text::TextComponent;
const DESCRIPTION: &str = const DESCRIPTION: &str =
"Drops the given loot table into the specified inventory or into the world."; "Drops the given loot table into the specified inventory or into the world.";
@ -20,14 +39,29 @@ static ERROR_INVALID_LOOT_TABLE: CommandErrorType<1> = CommandErrorType::new(
"Loot table '%s' not found", "Loot table '%s' not found",
); );
static ERROR_ENTITY_NO_LOOT_TABLE: CommandErrorType<1> = CommandErrorType::new( static ERROR_NO_HELD_ITEMS: CommandErrorType<1> = CommandErrorType::new(
translation::bedrock::COMMANDS_LOOT_FAILURE_ENTITYNOLOOTTABLE, translation::java::COMMANDS_DROP_NO_HELD_ITEMS,
"Entity %s has no loot table", translation::java::COMMANDS_DROP_NO_HELD_ITEMS,
); );
static ERROR_NO_CONTAINER: CommandErrorType<1> = CommandErrorType::new( static ERROR_NO_ENTITY_LOOT_TABLE: CommandErrorType<1> = CommandErrorType::new(
translation::bedrock::COMMANDS_LOOT_FAILURE_NOCONTAINER, translation::java::COMMANDS_DROP_NO_LOOT_TABLE,
"Target position %s is not a container", translation::java::COMMANDS_DROP_NO_LOOT_TABLE,
);
static ERROR_NO_BLOCK_LOOT_TABLE: CommandErrorType<1> = CommandErrorType::new(
translation::java::COMMANDS_DROP_NO_LOOT_TABLE_BLOCK,
translation::java::COMMANDS_DROP_NO_LOOT_TABLE_BLOCK,
);
static ERROR_NOT_CONTAINER: CommandErrorType<3> = CommandErrorType::new(
translation::java::COMMANDS_ITEM_TARGET_NOT_A_CONTAINER,
translation::java::COMMANDS_ITEM_TARGET_NOT_A_CONTAINER,
);
static ERROR_NO_SUCH_SLOT: CommandErrorType<1> = CommandErrorType::new(
translation::java::COMMANDS_ITEM_TARGET_NO_SUCH_SLOT,
translation::java::COMMANDS_ITEM_TARGET_NO_SUCH_SLOT,
); );
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -35,16 +69,24 @@ enum Target {
Give, Give,
Spawn, Spawn,
Insert, Insert,
ReplaceEntity { has_count: bool },
ReplaceBlock { has_count: bool },
}
#[derive(Clone, Copy)]
enum ToolSource {
None,
Item,
MainHand,
OffHand,
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
enum Source { enum Source {
Loot, Loot,
Kill, Kill,
Mine { Mine { tool: ToolSource },
#[allow(dead_code)] Fish { tool: ToolSource },
has_tool: bool,
},
} }
struct LootExecutor { struct LootExecutor {
@ -52,152 +94,575 @@ struct LootExecutor {
source: Source, source: Source,
} }
fn insert_into_inventory( fn distribute_to_container(inventory: &dyn Inventory, mut stack: ItemStack) -> bool {
inventory: &dyn pumpkin_world::inventory::Inventory, let mut changed = false;
mut stack: pumpkin_data::item_stack::ItemStack,
) -> pumpkin_data::item_stack::ItemStack {
for i in 0..inventory.size() { for i in 0..inventory.size() {
if stack.is_empty() { if stack.is_empty() {
break; break;
} }
let mut slot_stack = inventory.get_stack(i); let mut slot_stack = inventory.get_stack(i);
if !slot_stack.is_empty() && slot_stack.get_item().id == stack.get_item().id { if slot_stack.is_empty() {
let max_stack_size = 64; inventory.set_stack(i, stack);
let space = max_stack_size - slot_stack.item_count; changed = true;
break;
}
if slot_stack.get_item().id == stack.get_item().id {
let max_stack_size = stack.get_max_stack_size();
let space = max_stack_size.saturating_sub(slot_stack.item_count);
if space > 0 { if space > 0 {
let to_add = stack.item_count.min(space); let to_add = stack.item_count.min(space);
slot_stack.item_count += to_add; slot_stack.item_count += to_add;
stack.item_count -= to_add; stack.item_count -= to_add;
inventory.set_stack(i, slot_stack); inventory.set_stack(i, slot_stack);
changed = true;
} }
} }
} }
changed
}
for i in 0..inventory.size() { fn get_hand_item(
if stack.is_empty() { context: &CommandContext,
break; is_mainhand: bool,
) -> Result<Option<ItemStack>, CommandSyntaxError> {
context.source.as_player().map_or_else(
|| {
let display_name = TextComponent::text("Server");
Err(ERROR_NO_HELD_ITEMS.create_without_context(display_name))
},
|player| {
let stack = if is_mainhand {
let slot = player.inventory().get_selected_slot() as usize;
player.inventory().get_stack(slot)
} else {
player.inventory().get_stack(40)
};
Ok(Some(stack))
},
)
}
#[allow(clippy::too_many_lines)]
fn replace_entity_slots(
entity: &dyn EntityBase,
start_slot: usize,
count: usize,
drops: &[ItemStack],
used_items: &mut Vec<ItemStack>,
) {
if let Some(player) = entity.get_player() {
if let Some(player_arc) = player.world().get_player_by_uuid(player.gameprofile.id) {
for i in 0..count {
let mojang_slot = start_slot + i;
let item_stack = if i < drops.len() {
drops[i].clone()
} else {
ItemStack::EMPTY.clone()
};
if (200..=226).contains(&mojang_slot) {
let ender_slot = mojang_slot - 200;
if ender_slot < player.ender_chest_inventory.size() {
player_arc
.ender_chest_inventory
.set_stack(ender_slot, item_stack.clone());
used_items.push(item_stack);
}
} else {
let inventory = player.inventory();
let mapped_slot = if mojang_slot == 98 {
Some(inventory.get_selected_slot() as usize)
} else if mojang_slot == 99 {
Some(40)
} else if mojang_slot == 100 {
Some(36)
} else if mojang_slot == 101 {
Some(37)
} else if mojang_slot == 102 {
Some(38)
} else if mojang_slot == 103 {
Some(39)
} else if mojang_slot <= 35 {
Some(mojang_slot)
} else {
None
};
if let Some(slot) = mapped_slot
&& slot < inventory.size()
{
player_arc.inventory().set_stack(slot, item_stack.clone());
let stack_serializer = ItemStackSerializer::from(item_stack.clone());
let packet = CSetContainerSlot::new(0, 0, slot as i16, &stack_serializer);
player_arc.enqueue_slot_packet(&packet, None, 0);
let eq_slot = if slot == 36 {
Some(EquipmentSlot::FEET)
} else if slot == 37 {
Some(EquipmentSlot::LEGS)
} else if slot == 38 {
Some(EquipmentSlot::CHEST)
} else if slot == 39 {
Some(EquipmentSlot::HEAD)
} else if slot == 40 {
Some(EquipmentSlot::OFF_HAND)
} else if slot == inventory.get_selected_slot() as usize {
Some(EquipmentSlot::MAIN_HAND)
} else {
None
};
if let Some(eq) = eq_slot {
player
.living_entity
.send_equipment_changes(&[(eq, item_stack.clone())]);
}
used_items.push(item_stack);
}
}
}
} }
let slot_stack = inventory.get_stack(i); } else if let Some(living) = entity.get_living_entity() {
if slot_stack.is_empty() { for i in 0..count {
inventory.set_stack(i, stack.clone()); let mojang_slot = start_slot + i;
stack.item_count = 0; let item_stack = if i < drops.len() {
break; drops[i].clone()
} else {
ItemStack::EMPTY.clone()
};
let mapped_eq = if mojang_slot == 98 {
Some(EquipmentSlot::MAIN_HAND)
} else if mojang_slot == 99 {
Some(EquipmentSlot::OFF_HAND)
} else if mojang_slot == 100 {
Some(EquipmentSlot::FEET)
} else if mojang_slot == 101 {
Some(EquipmentSlot::LEGS)
} else if mojang_slot == 102 {
Some(EquipmentSlot::CHEST)
} else if mojang_slot == 103 {
Some(EquipmentSlot::HEAD)
} else if mojang_slot == 105 {
Some(EquipmentSlot::BODY)
} else if mojang_slot == 106 {
Some(EquipmentSlot::SADDLE)
} else {
None
};
if let Some(eq) = mapped_eq {
living
.entity_equipment
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.put(&eq, item_stack.clone());
living.send_equipment_changes(&[(eq, item_stack.clone())]);
used_items.push(item_stack);
}
} }
} }
}
stack fn send_callback(context: &CommandContext, drops: &[ItemStack], table_id: Option<&str>) {
let msg = match (drops.len(), table_id) {
(1, Some(table)) => {
let drop = &drops[0];
let item = drop.item;
let item_name = item.registry_key;
let display_comp = TextComponent::text("[")
.add_child(item.translated_name())
.add_child(TextComponent::text("]"))
.hover_event(HoverEvent::ShowItem {
id: item_name.to_string().into(),
count: Some(drop.item_count as i32),
});
TextComponent::translate_cross(
translation::java::COMMANDS_DROP_SUCCESS_SINGLE_WITH_TABLE,
translation::bedrock::COMMANDS_LOOT_SUCCESS,
[
TextComponent::text(drop.item_count.to_string()),
display_comp,
TextComponent::text(table.to_string()),
],
)
}
(1, None) => {
let drop = &drops[0];
let item = drop.item;
let item_name = item.registry_key;
let display_comp = TextComponent::text("[")
.add_child(item.translated_name())
.add_child(TextComponent::text("]"))
.hover_event(HoverEvent::ShowItem {
id: item_name.to_string().into(),
count: Some(drop.item_count as i32),
});
TextComponent::translate_cross(
translation::java::COMMANDS_DROP_SUCCESS_SINGLE,
translation::bedrock::COMMANDS_LOOT_SUCCESS,
[
TextComponent::text(drop.item_count.to_string()),
display_comp,
],
)
}
(count, Some(table)) => TextComponent::translate_cross(
translation::java::COMMANDS_DROP_SUCCESS_MULTIPLE_WITH_TABLE,
translation::bedrock::COMMANDS_LOOT_SUCCESS,
[
TextComponent::text(count.to_string()),
TextComponent::text(table.to_string()),
],
),
(count, None) => TextComponent::translate_cross(
translation::java::COMMANDS_DROP_SUCCESS_MULTIPLE,
translation::bedrock::COMMANDS_LOOT_SUCCESS,
[TextComponent::text(count.to_string())],
),
};
context.source.send_feedback(msg, true);
} }
impl CommandExecutor for LootExecutor { impl CommandExecutor for LootExecutor {
#[allow(clippy::too_many_lines)] #[expect(clippy::too_many_lines)]
fn execute(&self, context: &CommandContext) -> CommandExecutorResult { fn execute(&self, context: &CommandContext) -> CommandExecutorResult {
let mut stacks = Vec::new(); let mut drops = Vec::new();
let mut table_id_for_callback: Option<String> = None;
match self.source { match self.source {
Source::Loot => { Source::Fish { tool } => {
let loot_table_str = StringArgumentType::get(context, "loot_table")?; let loot_table_str = StringArgumentType::get(context, "loot_table")?;
let formatted_key = if loot_table_str.contains(':') { let key = if loot_table_str.contains(':') {
loot_table_str.to_string() loot_table_str.to_string()
} else { } else {
format!("minecraft:{loot_table_str}") format!("minecraft:{loot_table_str}")
}; };
let loot_table = pumpkin_data::loot_table::get_loot_table(&formatted_key); let pos = BlockPosArgumentType::get_block_pos(context, "fish_pos")?;
if let Some(table) = loot_table { let tool_stack = match tool {
let seed: i64 = rand::random(); ToolSource::None => None,
stacks = crate::world::loot::generate_loot(table, seed); ToolSource::Item => Some(ItemStackArgumentType::get(context, "tool")?),
ToolSource::MainHand => get_hand_item(context, true)?,
ToolSource::OffHand => get_hand_item(context, false)?,
};
let loot_table =
pumpkin_data::loot_table::get_loot_table(&key).ok_or_else(|| {
ERROR_INVALID_LOOT_TABLE
.create_without_context(TextComponent::text(loot_table_str.to_string()))
})?;
let params = LootContextParameters {
position: Some(Vector3::new(
f64::from(pos.0.x) + 0.5,
f64::from(pos.0.y) + 0.5,
f64::from(pos.0.z) + 0.5,
)),
tool: tool_stack,
..Default::default()
};
let seed: i64 = rand::random();
drops = crate::world::loot::generate_loot_with_context(loot_table, seed, &params);
}
Source::Loot => {
let loot_table_str = StringArgumentType::get(context, "loot_table")?;
let key = if loot_table_str.contains(':') {
loot_table_str.to_string()
} else { } else {
return Err(ERROR_INVALID_LOOT_TABLE format!("minecraft:{loot_table_str}")
.create_without_context(TextComponent::text(loot_table_str.to_string()))); };
}
let loot_table =
pumpkin_data::loot_table::get_loot_table(&key).ok_or_else(|| {
ERROR_INVALID_LOOT_TABLE
.create_without_context(TextComponent::text(loot_table_str.to_string()))
})?;
let params = LootContextParameters {
position: context.source.as_player().map(|p| p.position()),
..Default::default()
};
let seed: i64 = rand::random();
drops = crate::world::loot::generate_loot_with_context(loot_table, seed, &params);
} }
Source::Kill => { Source::Kill => {
let target_entities = EntityArgumentType::get_entities(context, "target_entity")?; let target_entities = EntityArgumentType::get_entities(context, "target_entity")?;
let mut has_loot = false; let killer = context.source.as_player();
for entity in target_entities { let killer_tool = killer.as_ref().map(|p| {
p.inventory()
.get_stack(p.inventory().get_selected_slot() as usize)
});
let params = LootContextParameters {
killed_by_player: Some(killer.is_some()),
tool: killer_tool,
position: killer.as_ref().map(|p| p.position()),
..Default::default()
};
let mut last_key = None;
for entity in &target_entities {
let resource_name = entity.get_entity().entity_type.resource_name; let resource_name = entity.get_entity().entity_type.resource_name;
let key = format!("minecraft:entities/{resource_name}"); let key = format!("minecraft:entities/{resource_name}");
if let Some(loot_table) = pumpkin_data::loot_table::get_loot_table(&key) { if let Some(loot_table) = pumpkin_data::loot_table::get_loot_table(&key) {
has_loot = true;
let seed: i64 = rand::random(); let seed: i64 = rand::random();
stacks.extend(crate::world::loot::generate_loot(loot_table, seed)); drops.extend(crate::world::loot::generate_loot_with_context(
loot_table, seed, &params,
));
last_key = Some(key);
} }
} }
if !has_loot {
let entity_name = "selected entity".to_string(); if drops.is_empty() && last_key.is_none() {
return Err(ERROR_ENTITY_NO_LOOT_TABLE let display_name = target_entities.first().map_or_else(
.create_without_context(TextComponent::text(entity_name))); || TextComponent::text("selected entity"),
|target| target.as_ref().get_display_name(),
);
return Err(ERROR_NO_ENTITY_LOOT_TABLE.create_without_context(display_name));
} }
table_id_for_callback = last_key;
} }
Source::Mine { has_tool: _ } => { Source::Mine { tool } => {
let pos = BlockPosArgumentType::get_block_pos(context, "mine_pos") let pos = BlockPosArgumentType::get_block_pos(context, "mine_pos")?;
.or_else(|_| BlockPosArgumentType::get_block_pos(context, "pos"))?;
let world = context.world(); let world = context.world();
let block_state = world.get_block_state(&pos);
let block = world.get_block(&pos); let block = world.get_block(&pos);
let key = format!("minecraft:blocks/{}", block.name); let key = format!("minecraft:blocks/{}", block.name);
if let Some(loot_table) = pumpkin_data::loot_table::get_loot_table(&key) { let loot_table =
let seed: i64 = rand::random(); pumpkin_data::loot_table::get_loot_table(&key).ok_or_else(|| {
stacks.extend(crate::world::loot::generate_loot(loot_table, seed)); ERROR_NO_BLOCK_LOOT_TABLE
} .create_without_context(TextComponent::text(block.name.to_string()))
})?;
let tool_stack = match tool {
ToolSource::None => None,
ToolSource::Item => Some(ItemStackArgumentType::get(context, "tool")?),
ToolSource::MainHand => get_hand_item(context, true)?,
ToolSource::OffHand => get_hand_item(context, false)?,
};
let params = LootContextParameters {
block_state: Some(block_state),
tool: tool_stack,
position: Some(Vector3::new(
f64::from(pos.0.x) + 0.5,
f64::from(pos.0.y) + 0.5,
f64::from(pos.0.z) + 0.5,
)),
..Default::default()
};
let seed: i64 = rand::random();
drops = crate::world::loot::generate_loot_with_context(loot_table, seed, &params);
table_id_for_callback = Some(key);
} }
} }
let total_items: i32 = stacks.iter().map(|s| s.item_count as i32).sum();
match self.target { match self.target {
Target::Give => { Target::Give => {
let targets = EntityArgumentType::get_players(context, "targets")?; let targets = EntityArgumentType::get_players(context, "players")?;
for player in &targets { let mut used_items = Vec::new();
for stack in &stacks { for stack in &drops {
for player in &targets {
let mut remaining = stack.clone(); let mut remaining = stack.clone();
player.inventory.insert_stack_anywhere(&mut remaining); player.inventory().insert_stack_anywhere(&mut remaining);
if !remaining.is_empty() { if !remaining.is_empty() {
player.drop_item(remaining); player.drop_item(remaining);
} }
used_items.push(stack.clone());
} }
} }
send_callback(context, &used_items, table_id_for_callback.as_deref());
Ok(used_items.len() as i32)
} }
Target::Spawn => { Target::Spawn => {
let pos = BlockPosArgumentType::get_block_pos(context, "pos")?; let pos = Vec3ArgumentType::get_vector3(context, "target_pos")?;
let world = context.world(); let world = context.world();
for stack in stacks { let block_pos = BlockPos::new(
world.drop_stack(&pos, stack); pos.x.floor() as i32,
pos.y.floor() as i32,
pos.z.floor() as i32,
);
for stack in &drops {
world.drop_stack(&block_pos, stack.clone());
} }
send_callback(context, &drops, table_id_for_callback.as_deref());
Ok(drops.len() as i32)
} }
Target::Insert => { Target::Insert => {
let pos = BlockPosArgumentType::get_block_pos(context, "pos")?; let pos = BlockPosArgumentType::get_block_pos(context, "target_pos")?;
let world = context.world().clone(); let world = context.world().clone();
let Some(block_entity) = world.get_block_entity(&pos) else { let block_entity = world.get_block_entity(&pos).ok_or_else(|| {
return Err(ERROR_NO_CONTAINER ERROR_NOT_CONTAINER.create_without_context(
.create_without_context(TextComponent::text(pos.to_string()))); TextComponent::text(pos.0.x.to_string()),
}; TextComponent::text(pos.0.y.to_string()),
let Some(inventory) = block_entity.get_inventory() else { TextComponent::text(pos.0.z.to_string()),
return Err(ERROR_NO_CONTAINER )
.create_without_context(TextComponent::text(pos.to_string()))); })?;
}; let inventory = block_entity.get_inventory().ok_or_else(|| {
ERROR_NOT_CONTAINER.create_without_context(
TextComponent::text(pos.0.x.to_string()),
TextComponent::text(pos.0.y.to_string()),
TextComponent::text(pos.0.z.to_string()),
)
})?;
for stack in stacks { let mut used_items = Vec::new();
let remaining = insert_into_inventory(inventory.as_ref(), stack); for stack in &drops {
if !remaining.is_empty() { if distribute_to_container(inventory.as_ref(), stack.clone()) {
world.drop_stack(&pos, remaining); used_items.push(stack.clone());
} }
} }
send_callback(context, &used_items, table_id_for_callback.as_deref());
Ok(used_items.len() as i32)
}
Target::ReplaceBlock { has_count } => {
let pos = BlockPosArgumentType::get_block_pos(context, "target_pos")?;
let slot = SlotArgumentType::get(context, "slot")?;
let count = if has_count {
IntegerArgumentType::get(context, "count")? as usize
} else {
drops.len()
};
let world = context.world().clone();
let block_entity = world.get_block_entity(&pos).ok_or_else(|| {
ERROR_NOT_CONTAINER.create_without_context(
TextComponent::text(pos.0.x.to_string()),
TextComponent::text(pos.0.y.to_string()),
TextComponent::text(pos.0.z.to_string()),
)
})?;
let inventory = block_entity.get_inventory().ok_or_else(|| {
ERROR_NOT_CONTAINER.create_without_context(
TextComponent::text(pos.0.x.to_string()),
TextComponent::text(pos.0.y.to_string()),
TextComponent::text(pos.0.z.to_string()),
)
})?;
if slot >= inventory.size() {
return Err(ERROR_NO_SUCH_SLOT
.create_without_context(TextComponent::text(slot.to_string())));
}
let mut used_items = Vec::new();
for i in 0..count {
let s = slot + i;
if s < inventory.size() {
let to_add = if i < drops.len() {
drops[i].clone()
} else {
ItemStack::EMPTY.clone()
};
inventory.set_stack(s, to_add.clone());
used_items.push(to_add);
}
}
send_callback(context, &used_items, table_id_for_callback.as_deref());
Ok(used_items.len() as i32)
}
Target::ReplaceEntity { has_count } => {
let entities = EntityArgumentType::get_entities(context, "entities")?;
let slot = SlotArgumentType::get(context, "slot")?;
let count = if has_count {
IntegerArgumentType::get(context, "count")? as usize
} else {
drops.len()
};
let mut used_items = Vec::new();
for target in &entities {
replace_entity_slots(target.as_ref(), slot, count, &drops, &mut used_items);
}
if used_items.is_empty() && !entities.is_empty() {
return Err(ERROR_NO_SUCH_SLOT
.create_without_context(TextComponent::text(slot.to_string())));
}
send_callback(context, &used_items, table_id_for_callback.as_deref());
Ok(used_items.len() as i32)
} }
} }
let msg = TextComponent::translate_cross(
translation::bedrock::COMMANDS_LOOT_SUCCESS,
translation::bedrock::COMMANDS_LOOT_SUCCESS,
[TextComponent::text(total_items.to_string())],
);
context.source.send_feedback(msg, true);
Ok(total_items)
} }
} }
#[expect(clippy::too_many_lines)] fn add_sources(target: Target) -> Vec<LiteralArgumentBuilder> {
vec![
literal("fish").then(
argument("loot_table", StringArgumentType::SingleWord).then(
argument("fish_pos", BlockPosArgumentType)
.executes(LootExecutor {
target,
source: Source::Fish {
tool: ToolSource::None,
},
})
.then(
argument("tool", ItemStackArgumentType).executes(LootExecutor {
target,
source: Source::Fish {
tool: ToolSource::Item,
},
}),
)
.then(literal("mainhand").executes(LootExecutor {
target,
source: Source::Fish {
tool: ToolSource::MainHand,
},
}))
.then(literal("offhand").executes(LootExecutor {
target,
source: Source::Fish {
tool: ToolSource::OffHand,
},
})),
),
),
literal("loot").then(
argument("loot_table", StringArgumentType::SingleWord).executes(LootExecutor {
target,
source: Source::Loot,
}),
),
literal("kill").then(
argument("target_entity", EntityArgumentType::Entities).executes(LootExecutor {
target,
source: Source::Kill,
}),
),
literal("mine").then(
argument("mine_pos", BlockPosArgumentType)
.executes(LootExecutor {
target,
source: Source::Mine {
tool: ToolSource::None,
},
})
.then(
argument("tool", ItemStackArgumentType).executes(LootExecutor {
target,
source: Source::Mine {
tool: ToolSource::Item,
},
}),
)
.then(literal("mainhand").executes(LootExecutor {
target,
source: Source::Mine {
tool: ToolSource::MainHand,
},
}))
.then(literal("offhand").executes(LootExecutor {
target,
source: Source::Mine {
tool: ToolSource::OffHand,
},
})),
),
]
}
pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) {
registry.register_permission_or_panic(Permission::new( registry.register_permission_or_panic(Permission::new(
PERMISSION, PERMISSION,
@ -205,118 +670,56 @@ pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistr
PermissionDefault::Op(PermissionLvl::Two), PermissionDefault::Op(PermissionLvl::Two),
)); ));
let mut give_arg = argument("players", EntityArgumentType::Players);
for src in add_sources(Target::Give) {
give_arg = give_arg.then(src);
}
let mut spawn_arg = argument("target_pos", Vec3ArgumentType::Default);
for src in add_sources(Target::Spawn) {
spawn_arg = spawn_arg.then(src);
}
let mut insert_arg = argument("target_pos", BlockPosArgumentType);
for src in add_sources(Target::Insert) {
insert_arg = insert_arg.then(src);
}
let mut replace_block_slot = argument("slot", SlotArgumentType);
for src in add_sources(Target::ReplaceBlock { has_count: false }) {
replace_block_slot = replace_block_slot.then(src);
}
let mut replace_block_count = argument("count", IntegerArgumentType::with_min(0));
for src in add_sources(Target::ReplaceBlock { has_count: true }) {
replace_block_count = replace_block_count.then(src);
}
let replace_block_slot = replace_block_slot.then(replace_block_count);
let mut replace_entity_slot = argument("slot", SlotArgumentType);
for src in add_sources(Target::ReplaceEntity { has_count: false }) {
replace_entity_slot = replace_entity_slot.then(src);
}
let mut replace_entity_count = argument("count", IntegerArgumentType::with_min(0));
for src in add_sources(Target::ReplaceEntity { has_count: true }) {
replace_entity_count = replace_entity_count.then(src);
}
let replace_entity_slot = replace_entity_slot.then(replace_entity_count);
let builder = command("loot", DESCRIPTION) let builder = command("loot", DESCRIPTION)
.requires(PERMISSION) .requires(PERMISSION)
// give <targets> .then(literal("give").then(give_arg))
.then(literal("spawn").then(spawn_arg))
.then(literal("insert").then(insert_arg))
.then( .then(
literal("give").then( literal("replace")
argument("targets", EntityArgumentType::Players) .then(
.then(literal("loot").then( literal("block").then(
argument("loot_table", StringArgumentType::SingleWord).executes( argument("target_pos", BlockPosArgumentType).then(replace_block_slot),
LootExecutor {
target: Target::Give,
source: Source::Loot,
},
),
))
.then(literal("kill").then(
argument("target_entity", EntityArgumentType::Entities).executes(
LootExecutor {
target: Target::Give,
source: Source::Kill,
},
),
))
.then(
literal("mine").then(
argument("pos", BlockPosArgumentType)
.executes(LootExecutor {
target: Target::Give,
source: Source::Mine { has_tool: false },
})
.then(argument("tool", StringArgumentType::SingleWord).executes(
LootExecutor {
target: Target::Give,
source: Source::Mine { has_tool: true },
},
)),
),
), ),
), )
) .then(literal("entity").then(
// spawn <pos> argument("entities", EntityArgumentType::Entities).then(replace_entity_slot),
.then( )),
literal("spawn").then(
argument("pos", BlockPosArgumentType)
.then(literal("loot").then(
argument("loot_table", StringArgumentType::SingleWord).executes(
LootExecutor {
target: Target::Spawn,
source: Source::Loot,
},
),
))
.then(literal("kill").then(
argument("target_entity", EntityArgumentType::Entities).executes(
LootExecutor {
target: Target::Spawn,
source: Source::Kill,
},
),
))
.then(
literal("mine").then(
argument("mine_pos", BlockPosArgumentType)
.executes(LootExecutor {
target: Target::Spawn,
source: Source::Mine { has_tool: false },
})
.then(argument("tool", StringArgumentType::SingleWord).executes(
LootExecutor {
target: Target::Spawn,
source: Source::Mine { has_tool: true },
},
)),
),
),
),
)
// insert <pos>
.then(
literal("insert").then(
argument("pos", BlockPosArgumentType)
.then(literal("loot").then(
argument("loot_table", StringArgumentType::SingleWord).executes(
LootExecutor {
target: Target::Insert,
source: Source::Loot,
},
),
))
.then(literal("kill").then(
argument("target_entity", EntityArgumentType::Entities).executes(
LootExecutor {
target: Target::Insert,
source: Source::Kill,
},
),
))
.then(
literal("mine").then(
argument("mine_pos", BlockPosArgumentType)
.executes(LootExecutor {
target: Target::Insert,
source: Source::Mine { has_tool: false },
})
.then(argument("tool", StringArgumentType::SingleWord).executes(
LootExecutor {
target: Target::Insert,
source: Source::Mine { has_tool: true },
},
)),
),
),
),
); );
dispatcher.register(builder); dispatcher.register(builder);

View File

@ -22,6 +22,11 @@ impl MobEffect for RaidOmenMobEffect {
.lock() .lock()
.unwrap_or_else(std::sync::PoisonError::into_inner); .unwrap_or_else(std::sync::PoisonError::into_inner);
raids.create_or_extend_raid(raid_pos, &world); raids.create_or_extend_raid(raid_pos, &world);
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::RaidTrigger as i32,
1,
);
player.clear_raid_omen_position(); player.clear_raid_omen_position();
} }
} }

View File

@ -1596,7 +1596,16 @@ impl LivingEntity {
return; return;
} }
// Fetches the safe fall distance attribute if fall_distance >= 2.0
&& let Some(player) = caller.get_player()
{
player.increment_stat(
StatisticCategory::Custom,
CustomStatistic::FallOneCm as i32,
(fall_distance * 100.0).round() as i32,
);
}
let safe_fall_distance = self.get_attribute_value(&Attributes::SAFE_FALL_DISTANCE) as f32; let safe_fall_distance = self.get_attribute_value(&Attributes::SAFE_FALL_DISTANCE) as f32;
let unsafe_fall_distance = fall_distance + 1.0E-6 - safe_fall_distance; let unsafe_fall_distance = fall_distance + 1.0E-6 - safe_fall_distance;
@ -1667,8 +1676,7 @@ impl LivingEntity {
self.movement_input.store(Vector3::default()); self.movement_input.store(Vector3::default());
self.jumping.store(false, Relaxed); self.jumping.store(false, Relaxed);
// Statistics updates self.update_death_stats(&*dyn_self, cause.or(source));
self.update_death_stats(&*dyn_self, cause);
// Plays the death sound // Plays the death sound
world.send_entity_status(&self.entity, EntityStatus::Death, Some(ActorEventID::Death)); world.send_entity_status(&self.entity, EntityStatus::Death, Some(ActorEventID::Death));
@ -1838,16 +1846,17 @@ impl LivingEntity {
fn update_death_stats(&self, dyn_self: &dyn EntityBase, cause: Option<&dyn EntityBase>) { fn update_death_stats(&self, dyn_self: &dyn EntityBase, cause: Option<&dyn EntityBase>) {
if let Some(victim_player) = dyn_self.get_player() { if let Some(victim_player) = dyn_self.get_player() {
victim_player.increment_stat( victim_player.increment_custom_stat(CustomStatistic::Deaths, 1);
StatisticCategory::Custom,
CustomStatistic::Deaths as i32,
1,
);
victim_player.set_stat( victim_player.set_stat(
StatisticCategory::Custom, StatisticCategory::Custom,
CustomStatistic::TimeSinceDeath as i32, CustomStatistic::TimeSinceDeath as i32,
0, 0,
); );
victim_player.set_stat(
StatisticCategory::Custom,
CustomStatistic::TimeSinceRest as i32,
0,
);
if let Some(killer_entity) = cause.map(EntityBase::get_entity) { if let Some(killer_entity) = cause.map(EntityBase::get_entity) {
victim_player.increment_stat( victim_player.increment_stat(
StatisticCategory::KilledBy, StatisticCategory::KilledBy,
@ -1858,6 +1867,11 @@ impl LivingEntity {
} }
if let Some(killer_player) = cause.and_then(|c| c.get_player()) { if let Some(killer_player) = cause.and_then(|c| c.get_player()) {
killer_player.increment_stat(
StatisticCategory::Killed,
self.entity.entity_type.id as i32,
1,
);
if dyn_self.get_player().is_some() { if dyn_self.get_player().is_some() {
killer_player.increment_stat( killer_player.increment_stat(
StatisticCategory::Custom, StatisticCategory::Custom,
@ -2085,9 +2099,17 @@ impl LivingEntity {
.is_none_or(|equippable| equippable.damage_on_hurt); .is_none_or(|equippable| equippable.damage_on_hurt);
if takes_damage { if takes_damage {
let item_id = stack.item.id;
let slot_result = stack.damage_item(armor_damage); let slot_result = stack.damage_item(armor_damage);
if slot_result != pumpkin_data::item_stack::DamageResult::Untouched { if slot_result != pumpkin_data::item_stack::DamageResult::Untouched {
if slot_result == pumpkin_data::item_stack::DamageResult::Broken { if slot_result == pumpkin_data::item_stack::DamageResult::Broken {
if let Some(player) = caller.get_player() {
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Broken,
item_id as i32,
1,
);
}
let world = self.entity.world.load(); let world = self.entity.world.load();
world.send_entity_status( world.send_entity_status(
&self.entity, &self.entity,
@ -2591,14 +2613,11 @@ impl LivingEntity {
.lock() .lock()
.unwrap_or_else(std::sync::PoisonError::into_inner); .unwrap_or_else(std::sync::PoisonError::into_inner);
if let Some(stack) = equipment_guard.equipment.get_mut(&slot) { if let Some(stack) = equipment_guard.equipment.get_mut(&slot) {
let item_id = stack.item.id;
let durability_damage = (amount / 1.0).floor().max(1.0) as i32; let durability_damage = (amount / 1.0).floor().max(1.0) as i32;
if stack.damage_item(durability_damage) == DamageResult::Broken { if stack.damage_item(durability_damage) == DamageResult::Broken {
if let Some(player) = caller.get_player() { if let Some(player) = caller.get_player() {
player.increment_stat( player.increment_stat(StatisticCategory::Broken, item_id as i32, 1);
StatisticCategory::Broken,
stack.item.id as i32,
1,
);
} }
world.send_entity_status( world.send_entity_status(
&self.entity, &self.entity,
@ -2623,9 +2642,12 @@ impl LivingEntity {
let damage_after_armor = let damage_after_armor =
self.get_damage_after_armor_absorb(amount, &damage_type, cause.or(source)); self.get_damage_after_armor_absorb(amount, &damage_type, cause.or(source));
// Vanilla parity: 2. Magic absorb (Resistance effect first, then Enchantments) let effective_amount = self.get_damage_after_magic_absorb(
let effective_amount = damage_after_armor,
self.get_damage_after_magic_absorb(damage_after_armor, &damage_type, caller, cause); &damage_type,
caller,
cause.or(source),
);
// These damage types bypass the hurt cooldown and death protection // These damage types bypass the hurt cooldown and death protection
let bypasses_cooldown_protection = let bypasses_cooldown_protection =
@ -2719,7 +2741,7 @@ impl LivingEntity {
); );
} }
if let Some(attacker_player) = cause.and_then(|c| c.get_player()) { if let Some(attacker_player) = cause.or(source).and_then(|c| c.get_player()) {
attacker_player.increment_stat( attacker_player.increment_stat(
StatisticCategory::Custom, StatisticCategory::Custom,
CustomStatistic::DamageDealtAbsorbed as i32, CustomStatistic::DamageDealtAbsorbed as i32,
@ -2752,7 +2774,7 @@ impl LivingEntity {
self.set_health(new_health); self.set_health(new_health);
if let Some(attacker_player) = cause.and_then(|c| c.get_player()) { if let Some(attacker_player) = cause.or(source).and_then(|c| c.get_player()) {
attacker_player.increment_stat( attacker_player.increment_stat(
StatisticCategory::Custom, StatisticCategory::Custom,
CustomStatistic::DamageDealt as i32, CustomStatistic::DamageDealt as i32,

View File

@ -183,6 +183,10 @@ pub trait EntityBase: Send + Sync + std::any::Any {
None None
} }
fn get_owner_id(&self) -> Option<i32> {
None
}
fn get_eye_pos(&self) -> Vector3<f64> { fn get_eye_pos(&self) -> Vector3<f64> {
self.get_entity().get_eye_pos() self.get_entity().get_eye_pos()
} }

View File

@ -1142,6 +1142,13 @@ impl Player {
let inventory = self.inventory(); let inventory = self.inventory();
let item_stack = inventory.held_item(); let item_stack = inventory.held_item();
if !item_stack.is_empty() {
self.increment_stat(
statistics::StatisticCategory::Used,
item_stack.item.id as i32,
1,
);
}
let base_damage = self let base_damage = self
.living_entity .living_entity
@ -1473,6 +1480,7 @@ impl Player {
}; };
let mut stack = self.inventory.get_slot(slot_index); let mut stack = self.inventory.get_slot(slot_index);
let original_item = stack.item;
let result = stack.damage_item(amount); let result = stack.damage_item(amount);
let updated = (result != pumpkin_data::item_stack::DamageResult::Untouched) let updated = (result != pumpkin_data::item_stack::DamageResult::Untouched)
.then_some((result, stack.clone())); .then_some((result, stack.clone()));
@ -1484,26 +1492,24 @@ impl Player {
{ {
let mut event = crate::plugin::api::events::player::player_item_damage::PlayerItemDamageEvent::new( let mut event = crate::plugin::api::events::player::player_item_damage::PlayerItemDamageEvent::new(
player_arc, player_arc,
updated_stack.item.registry_key.to_string(), original_item.registry_key.to_string(),
amount, amount,
); );
server.plugin_manager.fire_blocking(&server, &mut event); server.plugin_manager.fire_blocking(&server, &mut event);
} }
// Send the break status before clearing the slot so the client can
// use the item texture for break particles.
if result == pumpkin_data::item_stack::DamageResult::Broken { if result == pumpkin_data::item_stack::DamageResult::Broken {
if let Some(server) = self.world().server.upgrade() if let Some(server) = self.world().server.upgrade()
&& let Some(player_arc) = self.world().get_player_by_uuid(self.gameprofile.id) && let Some(player_arc) = self.world().get_player_by_uuid(self.gameprofile.id)
{ {
let mut event = crate::plugin::api::events::player::player_item_break::PlayerItemBreakEvent::new( let mut event = crate::plugin::api::events::player::player_item_break::PlayerItemBreakEvent::new(
player_arc, player_arc,
updated_stack.item.registry_key.to_string(), original_item.registry_key.to_string(),
); );
server.plugin_manager.fire_blocking(&server, &mut event); server.plugin_manager.fire_blocking(&server, &mut event);
} }
self.increment_stat( self.increment_stat(
statistics::StatisticCategory::Broken, statistics::StatisticCategory::Broken,
updated_stack.item.id as i32, original_item.id as i32,
1, 1,
); );
self.world().send_entity_status( self.world().send_entity_status(
@ -1923,6 +1929,11 @@ impl Player {
self.get_entity().set_velocity(Vector3::default()); self.get_entity().set_velocity(Vector3::default());
self.sleeping_since.store(Some(0)); self.sleeping_since.store(Some(0));
self.set_stat(
statistics::StatisticCategory::Custom,
statistics::CustomStatistic::TimeSinceRest as i32,
0,
);
} }
pub fn get_off_ground_speed(&self) -> f64 { pub fn get_off_ground_speed(&self) -> f64 {
@ -2458,8 +2469,14 @@ impl Player {
if let Ok(mut stats) = self.stats.try_lock() { if let Ok(mut stats) = self.stats.try_lock() {
stats.increment_custom(statistics::CustomStatistic::PlayTime, 1); stats.increment_custom(statistics::CustomStatistic::PlayTime, 1);
stats.increment_custom(statistics::CustomStatistic::TotalWorldTime, 1); stats.increment_custom(statistics::CustomStatistic::TotalWorldTime, 1);
stats.increment_custom(statistics::CustomStatistic::TimeSinceDeath, 1); if !self.living_entity.dead.load(Ordering::Relaxed)
stats.increment_custom(statistics::CustomStatistic::TimeSinceRest, 1); && self.living_entity.health.load() > 0.0
{
stats.increment_custom(statistics::CustomStatistic::TimeSinceDeath, 1);
}
if !self.is_sleeping() {
stats.increment_custom(statistics::CustomStatistic::TimeSinceRest, 1);
}
if self.living_entity.entity.sneaking.load(Ordering::Relaxed) { if self.living_entity.entity.sneaking.load(Ordering::Relaxed) {
stats.increment_custom(statistics::CustomStatistic::SneakTime, 1); stats.increment_custom(statistics::CustomStatistic::SneakTime, 1);
} }
@ -2591,6 +2608,9 @@ impl Player {
if can_harvest { if can_harvest {
p.add_exhaustion(MINE_BLOCK_EXHAUSTION); p.add_exhaustion(MINE_BLOCK_EXHAUSTION);
} }
let item_id = p.inventory().held_item().item.id;
p.increment_stat(StatisticCategory::Used, item_id as i32, 1);
p.increment_stat(StatisticCategory::Mined, state.id.as_u16() as i32, 1);
} }
// Java clients decide completion on their own local timer, if the block is // Java clients decide completion on their own local timer, if the block is
@ -3037,6 +3057,8 @@ impl Player {
self.increment_stat(statistics::StatisticCategory::Custom, stat as i32, amount); self.increment_stat(statistics::StatisticCategory::Custom, stat as i32, amount);
} }
#[must_use]
#[allow(clippy::too_many_lines)]
pub fn get_movement_statistic(&self) -> statistics::CustomStatistic { pub fn get_movement_statistic(&self) -> statistics::CustomStatistic {
let entity = self.get_entity(); let entity = self.get_entity();
if entity.has_vehicle() { if entity.has_vehicle() {
@ -3046,7 +3068,9 @@ impl Player {
.unwrap_or_else(std::sync::PoisonError::into_inner); .unwrap_or_else(std::sync::PoisonError::into_inner);
if let Some(vehicle) = vehicle.as_ref() { if let Some(vehicle) = vehicle.as_ref() {
let entity_type = vehicle.get_entity().entity_type; let entity_type = vehicle.get_entity().entity_type;
if entity_type == &EntityType::OAK_BOAT if entity_type.has_tag(&pumpkin_data::tag::EntityType::MINECRAFT_BOAT)
|| entity_type.has_tag(&pumpkin_data::tag::EntityType::C_BOATS)
|| entity_type == &EntityType::OAK_BOAT
|| entity_type == &EntityType::SPRUCE_BOAT || entity_type == &EntityType::SPRUCE_BOAT
|| entity_type == &EntityType::BIRCH_BOAT || entity_type == &EntityType::BIRCH_BOAT
|| entity_type == &EntityType::JUNGLE_BOAT || entity_type == &EntityType::JUNGLE_BOAT
@ -3054,11 +3078,23 @@ impl Player {
|| entity_type == &EntityType::DARK_OAK_BOAT || entity_type == &EntityType::DARK_OAK_BOAT
|| entity_type == &EntityType::MANGROVE_BOAT || entity_type == &EntityType::MANGROVE_BOAT
|| entity_type == &EntityType::CHERRY_BOAT || entity_type == &EntityType::CHERRY_BOAT
|| entity_type == &EntityType::PALE_OAK_BOAT
|| entity_type == &EntityType::BAMBOO_RAFT || entity_type == &EntityType::BAMBOO_RAFT
|| entity_type == &EntityType::OAK_CHEST_BOAT
|| entity_type == &EntityType::SPRUCE_CHEST_BOAT
|| entity_type == &EntityType::BIRCH_CHEST_BOAT
|| entity_type == &EntityType::JUNGLE_CHEST_BOAT
|| entity_type == &EntityType::ACACIA_CHEST_BOAT
|| entity_type == &EntityType::DARK_OAK_CHEST_BOAT
|| entity_type == &EntityType::MANGROVE_CHEST_BOAT
|| entity_type == &EntityType::CHERRY_CHEST_BOAT
|| entity_type == &EntityType::PALE_OAK_CHEST_BOAT
|| entity_type == &EntityType::BAMBOO_CHEST_RAFT
{ {
return statistics::CustomStatistic::BoatOneCm; return statistics::CustomStatistic::BoatOneCm;
} }
if entity_type == &EntityType::MINECART if entity_type.has_tag(&pumpkin_data::tag::EntityType::C_MINECARTS)
|| entity_type == &EntityType::MINECART
|| entity_type == &EntityType::CHEST_MINECART || entity_type == &EntityType::CHEST_MINECART
|| entity_type == &EntityType::FURNACE_MINECART || entity_type == &EntityType::FURNACE_MINECART
|| entity_type == &EntityType::TNT_MINECART || entity_type == &EntityType::TNT_MINECART
@ -3073,6 +3109,9 @@ impl Player {
|| entity_type == &EntityType::MULE || entity_type == &EntityType::MULE
|| entity_type == &EntityType::SKELETON_HORSE || entity_type == &EntityType::SKELETON_HORSE
|| entity_type == &EntityType::ZOMBIE_HORSE || entity_type == &EntityType::ZOMBIE_HORSE
|| entity_type == &EntityType::CAMEL
|| entity_type == &EntityType::LLAMA
|| entity_type == &EntityType::TRADER_LLAMA
{ {
return statistics::CustomStatistic::HorseOneCm; return statistics::CustomStatistic::HorseOneCm;
} }
@ -3082,6 +3121,14 @@ impl Player {
if entity_type == &EntityType::STRIDER { if entity_type == &EntityType::STRIDER {
return statistics::CustomStatistic::StriderOneCm; return statistics::CustomStatistic::StriderOneCm;
} }
if entity_type == &EntityType::HAPPY_GHAST {
return statistics::CustomStatistic::HappyGhastOneCm;
}
if entity_type == &EntityType::NAUTILUS
|| entity_type == &EntityType::ZOMBIE_NAUTILUS
{
return statistics::CustomStatistic::NautilusOneCm;
}
} }
} }
@ -3105,7 +3152,10 @@ impl Player {
} }
if entity.touching_water.load(Ordering::Relaxed) { if entity.touching_water.load(Ordering::Relaxed) {
return statistics::CustomStatistic::WalkUnderWaterOneCm; if entity.is_submerged_in_water() {
return statistics::CustomStatistic::WalkUnderWaterOneCm;
}
return statistics::CustomStatistic::WalkOnWaterOneCm;
} }
if entity.sneaking.load(Ordering::Relaxed) { if entity.sneaking.load(Ordering::Relaxed) {
@ -3165,6 +3215,11 @@ impl Player {
} }
} }
pub fn can_use_game_master_blocks(&self) -> bool {
self.gamemode.load() == GameMode::Creative
&& self.permission_lvl.load() >= PermissionLvl::Two
}
/// Sends the world time to only this player. /// Sends the world time to only this player.
pub fn send_time(&self, world: &World) { pub fn send_time(&self, world: &World) {
let advance_time = { let advance_time = {
@ -4325,6 +4380,15 @@ impl Player {
for item in main_inv.iter_mut() { for item in main_inv.iter_mut() {
if !item.is_empty() { if !item.is_empty() {
let stack = std::mem::replace(item, ItemStack::EMPTY.clone()); let stack = std::mem::replace(item, ItemStack::EMPTY.clone());
self.increment_stat(
statistics::StatisticCategory::Dropped,
stack.item.id as i32,
stack.item_count as i32,
);
self.increment_custom_stat(
statistics::CustomStatistic::Drop,
stack.item_count as i32,
);
self.world().drop_stack(&block_pos, stack); self.world().drop_stack(&block_pos, stack);
} }
} }
@ -4577,10 +4641,9 @@ impl Player {
item_stack.item.id as i32, item_stack.item.id as i32,
item_stack.item_count as i32, item_stack.item_count as i32,
); );
self.increment_stat( self.increment_custom_stat(
statistics::StatisticCategory::Custom, statistics::CustomStatistic::Drop,
statistics::CustomStatistic::Drop as i32, item_stack.item_count as i32,
1,
); );
let item_pos = self.living_entity.entity.pos.load() let item_pos = self.living_entity.entity.pos.load()
+ Vector3::new(0.0, self.living_entity.entity.get_eye_height() - 0.3, 0.0); + Vector3::new(0.0, self.living_entity.entity.get_eye_height() - 0.3, 0.0);

View File

@ -413,6 +413,10 @@ impl ArrowEntity {
} }
impl EntityBase for ArrowEntity { impl EntityBase for ArrowEntity {
fn get_owner_id(&self) -> Option<i32> {
self.owner_id
}
fn write_custom_nbt(&self, nbt: &mut pumpkin_nbt::compound::NbtCompound) { fn write_custom_nbt(&self, nbt: &mut pumpkin_nbt::compound::NbtCompound) {
let item_stack = self let item_stack = self
.item_stack .item_stack
@ -1063,6 +1067,11 @@ impl EntityBase for ArrowEntity {
.unwrap_or_else(std::sync::PoisonError::into_inner); .unwrap_or_else(std::sync::PoisonError::into_inner);
let mut stack = Self::pickup_item_stack(&item_stack); let mut stack = Self::pickup_item_stack(&item_stack);
if player.is_creative() || player.inventory.insert_stack_anywhere(&mut stack) { if player.is_creative() || player.inventory.insert_stack_anywhere(&mut stack) {
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::PickedUp,
stack.item.id as i32,
1,
);
player.living_entity.pickup(&self.entity, 1); player.living_entity.pickup(&self.entity, 1);
// Remove arrow entity after pickup // Remove arrow entity after pickup

View File

@ -63,6 +63,10 @@ impl EggEntity {
} }
impl EntityBase for EggEntity { impl EntityBase for EggEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn init_data_tracker(&self) { fn init_data_tracker(&self) {
let entity = self.get_entity(); let entity = self.get_entity();
let stack = self let stack = self

View File

@ -46,6 +46,10 @@ impl EnderPearlEntity {
} }
impl EntityBase for EnderPearlEntity { impl EntityBase for EnderPearlEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
self.thrown.process_tick(caller); self.thrown.process_tick(caller);
} }

View File

@ -172,6 +172,10 @@ impl FireballEntity {
} }
impl EntityBase for FireballEntity { impl EntityBase for FireballEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn write_custom_nbt(&self, nbt: &mut NbtCompound) { fn write_custom_nbt(&self, nbt: &mut NbtCompound) {
nbt.put_double("acceleration_power", self.get_acceleration_power()); nbt.put_double("acceleration_power", self.get_acceleration_power());
nbt.put_float("ExplosionPower", self.get_explosion_power()); nbt.put_float("ExplosionPower", self.get_explosion_power());

View File

@ -84,6 +84,10 @@ impl FireworkRocketEntity {
} }
impl EntityBase for FireworkRocketEntity { impl EntityBase for FireworkRocketEntity {
fn get_owner_id(&self) -> Option<i32> {
self.entity.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
self.entity.process_tick(caller); self.entity.process_tick(caller);

View File

@ -218,6 +218,10 @@ impl FishingBobberEntity {
} }
impl EntityBase for FishingBobberEntity { impl EntityBase for FishingBobberEntity {
fn get_owner_id(&self) -> Option<i32> {
Some(self.owner_id)
}
fn get_entity(&self) -> &Entity { fn get_entity(&self) -> &Entity {
&self.entity &self.entity
} }

View File

@ -64,6 +64,10 @@ impl LingeringPotionEntity {
} }
impl EntityBase for LingeringPotionEntity { impl EntityBase for LingeringPotionEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn init_data_tracker(&self) { fn init_data_tracker(&self) {
let entity = self.get_entity(); let entity = self.get_entity();
let stack = self let stack = self

View File

@ -56,6 +56,10 @@ impl LlamaSpitEntity {
} }
impl EntityBase for LlamaSpitEntity { impl EntityBase for LlamaSpitEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
if self.get_entity().touching_water.load(Ordering::Relaxed) { if self.get_entity().touching_water.load(Ordering::Relaxed) {
self.get_entity().remove(); self.get_entity().remove();

View File

@ -272,6 +272,10 @@ impl ShulkerBulletEntity {
} }
impl EntityBase for ShulkerBulletEntity { impl EntityBase for ShulkerBulletEntity {
fn get_owner_id(&self) -> Option<i32> {
Some(self.owner_id)
}
fn get_entity(&self) -> &Entity { fn get_entity(&self) -> &Entity {
&self.entity &self.entity
} }

View File

@ -36,6 +36,10 @@ impl SmallFireballEntity {
} }
impl EntityBase for SmallFireballEntity { impl EntityBase for SmallFireballEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
self.thrown.process_tick(caller); self.thrown.process_tick(caller);
} }

View File

@ -41,6 +41,10 @@ impl SnowballEntity {
} }
impl EntityBase for SnowballEntity { impl EntityBase for SnowballEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
self.thrown.process_tick(caller); self.thrown.process_tick(caller);
} }

View File

@ -99,6 +99,10 @@ pub(crate) fn extinguish_fire_if_water_potion(
} }
impl EntityBase for SplashPotionEntity { impl EntityBase for SplashPotionEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn init_data_tracker(&self) { fn init_data_tracker(&self) {
let entity = self.get_entity(); let entity = self.get_entity();
let stack = self let stack = self

View File

@ -157,6 +157,10 @@ impl TridentEntity {
} }
impl EntityBase for TridentEntity { impl EntityBase for TridentEntity {
fn get_owner_id(&self) -> Option<i32> {
self.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
let entity = self.get_entity(); let entity = self.get_entity();
let world = entity.world.load(); let world = entity.world.load();
@ -401,6 +405,11 @@ impl EntityBase for TridentEntity {
.unwrap_or_else(std::sync::PoisonError::into_inner) .unwrap_or_else(std::sync::PoisonError::into_inner)
.clone(); .clone();
if player.is_creative() || player.inventory.insert_stack_anywhere(&mut stack) { if player.is_creative() || player.inventory.insert_stack_anywhere(&mut stack) {
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::PickedUp,
stack.item.id as i32,
1,
);
player.living_entity.pickup(&self.entity, 1); player.living_entity.pickup(&self.entity, 1);
self.get_entity().remove(); self.get_entity().remove();
} }

View File

@ -115,6 +115,10 @@ impl WindChargeEntity {
} }
impl EntityBase for WindChargeEntity { impl EntityBase for WindChargeEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown_item_entity.owner_id
}
fn tick(&self, caller: &dyn EntityBase, _server: &Server) { fn tick(&self, caller: &dyn EntityBase, _server: &Server) {
self.thrown_item_entity.process_tick(caller); self.thrown_item_entity.process_tick(caller);

View File

@ -80,6 +80,10 @@ impl WitherSkullEntity {
} }
impl EntityBase for WitherSkullEntity { impl EntityBase for WitherSkullEntity {
fn get_owner_id(&self) -> Option<i32> {
self.thrown.owner_id
}
fn write_custom_nbt(&self, nbt: &mut NbtCompound) { fn write_custom_nbt(&self, nbt: &mut NbtCompound) {
nbt.put_bool("dangerous", self.is_dangerous()); nbt.put_bool("dangerous", self.is_dangerous());
} }

View File

@ -17,19 +17,6 @@ use pumpkin_util::math::wrap_degrees;
pub struct ArmorStandItem; pub struct ArmorStandItem;
impl ArmorStandItem {
fn calculate_placement_position(location: &BlockPos, face: BlockDirection) -> BlockPos {
match face {
BlockDirection::Up => location.offset(Vector3::new(0, 1, 0)),
BlockDirection::Down => location.offset(Vector3::new(0, -1, 0)),
BlockDirection::North => location.offset(Vector3::new(0, 0, -1)),
BlockDirection::South => location.offset(Vector3::new(0, 0, 1)),
BlockDirection::West => location.offset(Vector3::new(-1, 0, 0)),
BlockDirection::East => location.offset(Vector3::new(1, 0, 0)),
}
}
}
impl ItemMetadata for ArmorStandItem { impl ItemMetadata for ArmorStandItem {
fn ids() -> Box<[u16]> { fn ids() -> Box<[u16]> {
[Item::ARMOR_STAND.id].into() [Item::ARMOR_STAND.id].into()
@ -47,10 +34,17 @@ impl ItemBehaviour for ArmorStandItem {
_block: &Block, _block: &Block,
_server: &Server, _server: &Server,
) { ) {
let world = player.world(); if face == BlockDirection::Down {
let position = Self::calculate_placement_position(&location, face).to_f64(); return;
}
let bottom_center = Vector3::new(position.x, position.y, position.z); let world = player.world();
let target_pos = location.offset(face.to_offset());
let bottom_center = Vector3::new(
f64::from(target_pos.0.x) + 0.5,
f64::from(target_pos.0.y),
f64::from(target_pos.0.z) + 0.5,
);
let armor_stand_dimensions = EntityType::ARMOR_STAND.dimension; let armor_stand_dimensions = EntityType::ARMOR_STAND.dimension;
let width = f64::from(armor_stand_dimensions[0]); let width = f64::from(armor_stand_dimensions[0]);
@ -74,7 +68,7 @@ impl ItemBehaviour for ArmorStandItem {
let (player_yaw, _) = player.rotation(); let (player_yaw, _) = player.rotation();
let rotation = ((wrap_degrees(player_yaw - 180.0) + 22.5) / 45.0).floor() * 45.0; let rotation = ((wrap_degrees(player_yaw - 180.0) + 22.5) / 45.0).floor() * 45.0;
let entity = Entity::new(world.clone(), position, &EntityType::ARMOR_STAND); let entity = Entity::new(world.clone(), bottom_center, &EntityType::ARMOR_STAND);
entity.set_rotation(rotation, 0.0); entity.set_rotation(rotation, 0.0);

View File

@ -174,13 +174,24 @@ impl ItemBehaviour for BoatItem {
let boat_entity = Arc::new(BoatEntity::new(entity)); let boat_entity = Arc::new(BoatEntity::new(entity));
world.spawn_entity(boat_entity); world.spawn_entity(boat_entity);
// Decrement item unless in creative mode let mut main_hand = player.inventory.held_item();
let mut stack = player.inventory.held_item(); let consumed = if !main_hand.is_empty() && main_hand.item.id == item.id {
stack.decrement_unless_creative(player.gamemode.load(), 1); main_hand.decrement_unless_creative(player.gamemode.load(), 1);
player.inventory.set_held_item(stack); player.inventory.set_held_item(main_hand);
true
} else {
false
};
// TODO: world.emitGameEvent(user, GameEvent.ENTITY_PLACE, hitResult.getPos()) if !consumed {
// TODO: user.incrementStat(Stats.USED.getOrCreateStat(this)) let mut off_hand = player.inventory.off_hand_item();
if !off_hand.is_empty() && off_hand.item.id == item.id {
off_hand.decrement_unless_creative(player.gamemode.load(), 1);
player
.inventory
.set_stack_in_hand(pumpkin_util::Hand::Left, off_hand);
}
}
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {

View File

@ -1,12 +1,14 @@
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::Ordering;
use crate::{ use crate::{
entity::player::Player, entity::{EntityBase, player::Player, r#type::from_type},
item::{ItemBehaviour, ItemMetadata}, item::{ItemBehaviour, ItemMetadata},
}; };
use pumpkin_data::{ use pumpkin_data::{
Block, BlockDirection, Block, BlockDirection,
dimension::Dimension, dimension::Dimension,
entity::EntityType,
fluid::Fluid, fluid::Fluid,
item::Item, item::Item,
item_stack::ItemStack, item_stack::ItemStack,
@ -17,6 +19,7 @@ use pumpkin_util::{
math::{position::BlockPos, vector3::Vector3}, math::{position::BlockPos, vector3::Vector3},
}; };
use pumpkin_world::{tick::TickPriority, world::BlockFlags}; use pumpkin_world::{tick::TickPriority, world::BlockFlags};
use uuid::Uuid;
use crate::world::World; use crate::world::World;
@ -57,8 +60,7 @@ fn get_start_and_end_pos(player: &Player) -> (Vector3<f64>, Vector3<f64>) {
let start_pos = player.eye_position(); let start_pos = player.eye_position();
let (yaw, pitch) = player.rotation(); let (yaw, pitch) = player.rotation();
let (yaw_rad, pitch_rad) = (f64::from(yaw.to_radians()), f64::from(pitch.to_radians())); let (yaw_rad, pitch_rad) = (f64::from(yaw.to_radians()), f64::from(pitch.to_radians()));
let block_interaction_range = 4.5; // This is not the same as the block_interaction_range in the let block_interaction_range = 4.5;
// player entity.
let direction = Vector3::new( let direction = Vector3::new(
-yaw_rad.sin() * pitch_rad.cos() * block_interaction_range, -yaw_rad.sin() * pitch_rad.cos() * block_interaction_range,
-pitch_rad.sin() * block_interaction_range, -pitch_rad.sin() * block_interaction_range,
@ -69,6 +71,46 @@ fn get_start_and_end_pos(player: &Player) -> (Vector3<f64>, Vector3<f64>) {
(start_pos, end_pos) (start_pos, end_pos)
} }
const fn get_mob_for_bucket(item: &Item) -> Option<(&'static EntityType, Sound)> {
if item.id == Item::AXOLOTL_BUCKET.id {
Some((&EntityType::AXOLOTL, Sound::ItemBucketEmptyAxolotl))
} else if item.id == Item::COD_BUCKET.id {
Some((&EntityType::COD, Sound::ItemBucketEmptyFish))
} else if item.id == Item::SALMON_BUCKET.id {
Some((&EntityType::SALMON, Sound::ItemBucketEmptyFish))
} else if item.id == Item::TROPICAL_FISH_BUCKET.id {
Some((&EntityType::TROPICAL_FISH, Sound::ItemBucketEmptyFish))
} else if item.id == Item::PUFFERFISH_BUCKET.id {
Some((&EntityType::PUFFERFISH, Sound::ItemBucketEmptyFish))
} else if item.id == Item::TADPOLE_BUCKET.id {
Some((&EntityType::TADPOLE, Sound::ItemBucketEmptyTadpole))
} else {
None
}
}
const fn get_empty_sound(item: &Item) -> Sound {
if let Some((_, sound)) = get_mob_for_bucket(item) {
sound
} else if item.id == Item::LAVA_BUCKET.id {
Sound::ItemBucketEmptyLava
} else if item.id == Item::POWDER_SNOW_BUCKET.id {
Sound::ItemBucketEmptyPowderSnow
} else {
Sound::ItemBucketEmpty
}
}
const fn get_fill_sound(item: &Item) -> Sound {
if item.id == Item::LAVA_BUCKET.id {
Sound::ItemBucketFillLava
} else if item.id == Item::POWDER_SNOW_BUCKET.id {
Sound::ItemBucketFillPowderSnow
} else {
Sound::ItemBucketFill
}
}
fn give_player_bucket_item(player: &Player, item: &'static Item) { fn give_player_bucket_item(player: &Player, item: &'static Item) {
if player.gamemode.load() == GameMode::Creative { if player.gamemode.load() == GameMode::Creative {
let has_item = { let has_item = {
@ -104,8 +146,6 @@ fn give_player_bucket_item(player: &Player, item: &'static Item) {
} }
} }
/// Tries to pick up powder snow, a waterlogged block, or a fluid source block at `block_pos`,
/// returning the matching filled bucket item on success.
pub(crate) fn try_pickup_fluid_at( pub(crate) fn try_pickup_fluid_at(
world: &Arc<World>, world: &Arc<World>,
block_pos: BlockPos, block_pos: BlockPos,
@ -288,9 +328,42 @@ impl ItemBehaviour for EmptyBucketItem {
} }
} }
world.play_sound(
get_fill_sound(item),
SoundCategory::Blocks,
&block_pos.to_f64(),
);
give_player_bucket_item(player, item); give_player_bucket_item(player, item);
} }
fn use_on_entity(&self, _item: &mut ItemStack, player: &Player, entity: Arc<dyn EntityBase>) {
let ent = entity.get_entity();
let entity_type = ent.entity_type;
if (entity_type == &EntityType::COW
|| entity_type == &EntityType::MOOSHROOM
|| entity_type == &EntityType::GOAT)
&& ent.age.load(Ordering::Relaxed) >= 0
{
let world = ent.world.load();
let sound = if entity_type == &EntityType::GOAT {
if let Some(goat) = entity
.cast_any()
.downcast_ref::<crate::entity::passive::goat::GoatEntity>()
&& goat.is_screaming()
{
Sound::EntityGoatScreamingMilk
} else {
Sound::EntityGoatMilk
}
} else {
Sound::EntityCowMilk
};
world.play_sound(sound, SoundCategory::Neutral, &ent.pos.load());
give_player_bucket_item(player, &Item::MILK_BUCKET);
}
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
@ -332,7 +405,32 @@ impl ItemBehaviour for FilledBucketItem {
server.plugin_manager.fire_blocking(&server, &mut event); server.plugin_manager.fire_blocking(&server, &mut event);
} }
//TODO: Spawn entity if applicable let place_pos = if world
.get_block_and_state(&pos)
.0
.is_waterlogged(world.get_block_state_id(&pos))
{
pos
} else {
pos.offset(direction.to_offset())
};
world.play_sound(
get_empty_sound(item),
SoundCategory::Blocks,
&place_pos.to_f64(),
);
if let Some((entity_type, _)) = get_mob_for_bucket(item) {
let spawn_coord = Vector3::new(
f64::from(place_pos.0.x) + 0.5,
f64::from(place_pos.0.y),
f64::from(place_pos.0.z) + 0.5,
);
let mob = from_type(entity_type, spawn_coord, &world, Uuid::new_v4());
world.spawn_entity(mob);
}
if player.gamemode.load() != GameMode::Creative { if player.gamemode.load() != GameMode::Creative {
let item_stack = ItemStack::new(1, &Item::BUCKET); let item_stack = ItemStack::new(1, &Item::BUCKET);
player player
@ -341,6 +439,35 @@ impl ItemBehaviour for FilledBucketItem {
} }
} }
fn use_on_entity(&self, item: &mut ItemStack, player: &Player, entity: Arc<dyn EntityBase>) {
if item.item.id == Item::WATER_BUCKET.id {
let entity_type = entity.get_entity().entity_type;
let result_item = if entity_type == &EntityType::AXOLOTL {
Some((&Item::AXOLOTL_BUCKET, Sound::ItemBucketFillAxolotl))
} else if entity_type == &EntityType::COD {
Some((&Item::COD_BUCKET, Sound::ItemBucketFillFish))
} else if entity_type == &EntityType::SALMON {
Some((&Item::SALMON_BUCKET, Sound::ItemBucketFillFish))
} else if entity_type == &EntityType::TROPICAL_FISH {
Some((&Item::TROPICAL_FISH_BUCKET, Sound::ItemBucketFillFish))
} else if entity_type == &EntityType::PUFFERFISH {
Some((&Item::PUFFERFISH_BUCKET, Sound::ItemBucketFillFish))
} else if entity_type == &EntityType::TADPOLE {
Some((&Item::TADPOLE_BUCKET, Sound::ItemBucketFillTadpole))
} else {
None
};
if let Some((mob_bucket, sound)) = result_item {
let ent = entity.get_entity();
let world = ent.world.load();
world.play_sound(sound, SoundCategory::Neutral, &ent.pos.load());
give_player_bucket_item(player, mob_bucket);
ent.remove();
}
}
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }

View File

@ -0,0 +1,193 @@
use std::any::Any;
use std::sync::{LazyLock, Mutex};
use rustc_hash::FxHashMap;
use crate::entity::EntityBase;
use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata};
use crate::server::Server;
use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::{Block, BlockDirection, BlockId, BlockStateId};
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::math::vector3::Vector3;
use pumpkin_util::text::TextComponent;
use pumpkin_world::world::BlockFlags;
static SELECTED_PROPERTIES: LazyLock<Mutex<FxHashMap<BlockId, &'static str>>> =
LazyLock::new(|| Mutex::new(FxHashMap::default()));
pub struct DebugStickItem;
impl ItemMetadata for DebugStickItem {
fn ids() -> Box<[u16]> {
Box::new([Item::DEBUG_STICK.id])
}
}
impl DebugStickItem {
#[expect(clippy::too_many_lines)]
fn handle_interaction(
player: &Player,
pos: &BlockPos,
block: &Block,
state_id: BlockStateId,
cycle: bool,
) -> bool {
let Some(props) = block.properties(state_id) else {
player.send_system_message_raw(
&TextComponent::translate(
"item.minecraft.debug_stick.empty",
[TextComponent::text(block.name)],
),
true,
);
return false;
};
let prop_list = props.to_props();
if prop_list.is_empty() {
player.send_system_message_raw(
&TextComponent::translate(
"item.minecraft.debug_stick.empty",
[TextComponent::text(block.name)],
),
true,
);
return false;
}
let prop_names: Vec<&'static str> = prop_list.iter().map(|(k, _)| *k).collect();
let mut map = SELECTED_PROPERTIES
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let mut selected_prop = map.get(&block.id).copied().unwrap_or(prop_names[0]);
if !prop_names.contains(&selected_prop) {
selected_prop = prop_names[0];
}
if cycle {
let mut possible_values: Vec<&'static str> = Vec::new();
for state in block.states {
if let Some(state_props) = block.properties(state.id) {
for (k, v) in state_props.to_props() {
if k == selected_prop && !possible_values.contains(&v) {
possible_values.push(v);
}
}
}
}
if possible_values.is_empty() {
return false;
}
let current_val = prop_list
.iter()
.find(|(k, _)| *k == selected_prop)
.map_or(possible_values[0], |(_, v)| *v);
let cur_idx = possible_values
.iter()
.position(|v| *v == current_val)
.unwrap_or(0);
let is_backward = player.get_entity().is_sneaking();
let new_idx = if is_backward {
(cur_idx + possible_values.len() - 1) % possible_values.len()
} else {
(cur_idx + 1) % possible_values.len()
};
let new_val = possible_values[new_idx];
let mut new_props = prop_list.clone();
for (k, v) in &mut new_props {
if *k == selected_prop {
*v = new_val;
}
}
let new_state_id = block.from_properties(&new_props).to_state_id(block);
let world = player.world();
world.set_block_state(pos, new_state_id, BlockFlags::NOTIFY_ALL);
player.send_system_message_raw(
&TextComponent::translate(
"item.minecraft.debug_stick.update",
[
TextComponent::text(selected_prop),
TextComponent::text(new_val),
],
),
true,
);
} else {
let cur_idx = prop_names
.iter()
.position(|name| *name == selected_prop)
.unwrap_or(0);
let is_backward = player.get_entity().is_sneaking();
let new_idx = if is_backward {
(cur_idx + prop_names.len() - 1) % prop_names.len()
} else {
(cur_idx + 1) % prop_names.len()
};
let new_selected_prop = prop_names[new_idx];
map.insert(block.id, new_selected_prop);
let current_val = prop_list
.iter()
.find(|(k, _)| *k == new_selected_prop)
.map_or("", |(_, v)| *v);
player.send_system_message_raw(
&TextComponent::translate(
"item.minecraft.debug_stick.select",
[
TextComponent::text(new_selected_prop),
TextComponent::text(current_val),
],
),
true,
);
}
true
}
}
impl ItemBehaviour for DebugStickItem {
fn can_mine(&self, player: &Player) -> bool {
if player.can_use_game_master_blocks() {
let (start, end) = self.get_start_and_end_pos(player);
let world = player.world();
if let Some((pos, _)) =
world.raycast(start, end, |pos, world| world.get_block(pos) != &Block::AIR)
{
let (block, state) = world.get_block_and_state(&pos);
Self::handle_interaction(player, &pos, block, state.id, false);
}
}
false
}
fn use_on_block(
&self,
_item: &mut ItemStack,
player: &Player,
location: BlockPos,
_face: BlockDirection,
_cursor_pos: Vector3<f32>,
block: &Block,
_server: &Server,
) {
if player.can_use_game_master_blocks() {
let world = player.world();
let state_id = world.get_block_state_id(&location);
Self::handle_interaction(player, &location, block, state_id, true);
}
}
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@ -13,6 +13,9 @@ use crate::{
item::{ItemBehaviour, ItemMetadata}, item::{ItemBehaviour, ItemMetadata},
}; };
use crate::entity::EntityBase;
use pumpkin_data::item_stack::ItemStack;
pub struct DyeItem; pub struct DyeItem;
impl ItemMetadata for DyeItem { impl ItemMetadata for DyeItem {
@ -22,6 +25,27 @@ impl ItemMetadata for DyeItem {
} }
impl ItemBehaviour for DyeItem { impl ItemBehaviour for DyeItem {
fn use_on_entity(&self, item: &mut ItemStack, player: &Player, entity: Arc<dyn EntityBase>) {
if let Some(sheep) = entity
.cast_any()
.downcast_ref::<crate::entity::passive::sheep::SheepEntity>()
&& let Some(color) =
crate::entity::passive::animal::get_dye_color_from_item(item.get_item())
&& !sheep.is_sheared()
&& color != sheep.get_color()
{
sheep.set_color(color);
let ent = entity.get_entity();
let world = ent.world.load();
world.play_sound(
pumpkin_data::sound::Sound::ItemDyeUse,
pumpkin_data::sound::SoundCategory::Players,
&ent.pos.load(),
);
item.decrement_unless_creative(player.gamemode.load(), 1);
}
}
fn can_mine(&self, player: &Player) -> bool { fn can_mine(&self, player: &Player) -> bool {
player.gamemode.load() != GameMode::Creative player.gamemode.load() != GameMode::Creative
} }

View File

@ -45,14 +45,19 @@ impl ItemBehaviour for EndCrystalItem {
|| !world || !world
.get_entities_at_box(&BoundingBox::new( .get_entities_at_box(&BoundingBox::new(
Vector3::new(location_vec.x, location_vec.y, location_vec.z), Vector3::new(location_vec.x, location_vec.y, location_vec.z),
Vector3::new(location_vec.x + 1.0, location_vec.y + 2.0, location_vec.z), Vector3::new(
location_vec.x + 1.0,
location_vec.y + 2.0,
location_vec.z + 1.0,
),
)) ))
.is_empty() .is_empty()
{ {
return; return;
} }
let entity = Entity::new(world.clone(), location.to_f64(), &EntityType::END_CRYSTAL); let spawn_pos = Vector3::new(location_vec.x + 0.5, location_vec.y, location_vec.z + 0.5);
let entity = Entity::new(world.clone(), spawn_pos, &EntityType::END_CRYSTAL);
let end_crystal = Arc::new(EndCrystalEntity::new(entity)); let end_crystal = Arc::new(EndCrystalEntity::new(entity));
world.spawn_entity(end_crystal.clone()); world.spawn_entity(end_crystal.clone());
end_crystal.set_show_bottom(false); end_crystal.set_show_bottom(false);

View File

@ -24,7 +24,7 @@ impl ItemMetadata for FireworkRocketItem {
impl ItemBehaviour for FireworkRocketItem { impl ItemBehaviour for FireworkRocketItem {
fn use_on_block( fn use_on_block(
&self, &self,
_item: &mut ItemStack, item: &mut ItemStack,
player: &Player, player: &Player,
location: BlockPos, location: BlockPos,
_face: BlockDirection, _face: BlockDirection,
@ -44,6 +44,7 @@ impl ItemBehaviour for FireworkRocketItem {
); );
let entity = FireworkRocketEntity::new(entity); let entity = FireworkRocketEntity::new(entity);
world.spawn_entity(Arc::new(entity)); world.spawn_entity(Arc::new(entity));
item.decrement_unless_creative(player.gamemode.load(), 1);
} }
fn normal_use(&self, _item: &Item, player: &Player) { fn normal_use(&self, _item: &Item, player: &Player) {
@ -56,6 +57,24 @@ impl ItemBehaviour for FireworkRocketItem {
); );
let entity = FireworkRocketEntity::new_shot(entity, player.get_entity()); let entity = FireworkRocketEntity::new_shot(entity, player.get_entity());
world.spawn_entity(Arc::new(entity)); world.spawn_entity(Arc::new(entity));
let mut held = player.inventory().held_item();
let mut is_main = true;
if held.is_empty() || held.item.id != Item::FIREWORK_ROCKET.id {
held = player.inventory().off_hand_item();
is_main = false;
if held.is_empty() || held.item.id != Item::FIREWORK_ROCKET.id {
return;
}
}
held.decrement_unless_creative(player.gamemode.load(), 1);
if is_main {
player.inventory().set_held_item(held);
} else {
player
.inventory()
.set_stack_in_hand(pumpkin_util::Hand::Left, held);
}
} }
} }

View File

@ -1,8 +1,10 @@
use std::any::Any; use std::any::Any;
use std::sync::Arc;
use crate::entity::player::Player; use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata}; use crate::item::{ItemBehaviour, ItemMetadata};
use crate::server::Server; use crate::server::Server;
use crate::world::World;
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack; use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::sound::{Sound, SoundCategory};
@ -20,6 +22,62 @@ impl ItemMetadata for GlassBottleItem {
} }
impl ItemBehaviour for GlassBottleItem { impl ItemBehaviour for GlassBottleItem {
fn normal_use(&self, _item: &Item, player: &Player) {
let world = player.world();
let (start_pos, end_pos) = self.get_start_and_end_pos(player);
let checker = |pos: &BlockPos, world_inner: &Arc<World>| {
let state_id = world_inner.get_block_state_id(pos);
let block = Block::from_state_id(state_id);
if state_id == Block::AIR.default_state.id {
return false;
}
block.id == Block::WATER.id || block.is_waterlogged(state_id)
};
if let Some((hit_pos, _)) = world.raycast(start_pos, end_pos, checker) {
world.play_sound(
Sound::ItemBottleFill,
SoundCategory::Players,
&hit_pos.to_f64(),
);
let water_bottle = ItemStack::new(1, &Item::POTION);
let mut held = player.inventory().held_item();
let mut is_main = true;
if held.is_empty() || held.item.id != Item::GLASS_BOTTLE.id {
held = player.inventory().off_hand_item();
is_main = false;
if held.is_empty() || held.item.id != Item::GLASS_BOTTLE.id {
return;
}
}
if held.item_count == 1 && player.gamemode.load() != pumpkin_util::GameMode::Creative {
if is_main {
player.inventory().set_held_item(water_bottle);
} else {
player
.inventory()
.set_stack_in_hand(pumpkin_util::Hand::Left, water_bottle);
}
} else {
held.decrement_unless_creative(player.gamemode.load(), 1);
if is_main {
player.inventory().set_held_item(held);
} else {
player
.inventory()
.set_stack_in_hand(pumpkin_util::Hand::Left, held);
}
let mut stack_to_give = water_bottle;
let was_added = player.inventory().insert_stack_anywhere(&mut stack_to_give);
if !was_added && !stack_to_give.is_empty() {
world.drop_stack(&player.position().to_block_pos(), stack_to_give);
}
}
}
}
fn use_on_block( fn use_on_block(
&self, &self,
item: &mut ItemStack, item: &mut ItemStack,
@ -77,6 +135,11 @@ impl ItemBehaviour for GlassBottleItem {
if let Some(new_state_id) = cauldron_action { if let Some(new_state_id) = cauldron_action {
world.set_block_state(&check_pos, new_state_id, BlockFlags::NOTIFY_ALL); world.set_block_state(&check_pos, new_state_id, BlockFlags::NOTIFY_ALL);
player.increment_stat(
pumpkin_data::statistic::StatisticCategory::Custom,
pumpkin_data::statistic::CustomStatistic::UseCauldron as i32,
1,
);
} }
world.play_sound( world.play_sound(
@ -86,10 +149,14 @@ impl ItemBehaviour for GlassBottleItem {
); );
let mut water_bottle = ItemStack::new(1, &Item::POTION); let mut water_bottle = ItemStack::new(1, &Item::POTION);
item.decrement_unless_creative(player.gamemode.load(), 1); if item.item_count == 1 && player.gamemode.load() != pumpkin_util::GameMode::Creative {
let was_added = player.inventory.insert_stack_anywhere(&mut water_bottle); *item = water_bottle;
if !was_added && !water_bottle.is_empty() { } else {
world.drop_stack(&player.position().to_block_pos(), water_bottle); item.decrement_unless_creative(player.gamemode.load(), 1);
let was_added = player.inventory().insert_stack_anywhere(&mut water_bottle);
if !was_added && !water_bottle.is_empty() {
world.drop_stack(&player.position().to_block_pos(), water_bottle);
}
} }
} }
} }

View File

@ -0,0 +1,84 @@
use std::any::Any;
use std::sync::Arc;
use std::sync::atomic::Ordering;
use crate::entity::Entity;
use crate::entity::decoration::item_frame::ItemFrameEntity;
use crate::entity::decoration::painting::PaintingEntity;
use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata};
use crate::server::Server;
use pumpkin_data::entity::EntityType;
use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_data::{Block, BlockDirection};
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::math::vector3::Vector3;
pub struct HangingEntityItem;
impl ItemMetadata for HangingEntityItem {
fn ids() -> Box<[u16]> {
[
Item::PAINTING.id,
Item::ITEM_FRAME.id,
Item::GLOW_ITEM_FRAME.id,
]
.into()
}
}
impl ItemBehaviour for HangingEntityItem {
fn use_on_block(
&self,
item: &mut ItemStack,
player: &Player,
location: BlockPos,
face: BlockDirection,
_cursor_pos: Vector3<f32>,
_block: &Block,
_server: &Server,
) {
let world = player.world();
let target_pos = location.offset(face.to_offset());
let pos = Vector3::new(
f64::from(target_pos.0.x) + 0.5,
f64::from(target_pos.0.y) + 0.5,
f64::from(target_pos.0.z) + 0.5,
);
if item.item.id == Item::PAINTING.id {
if face == BlockDirection::Up || face == BlockDirection::Down {
return;
}
let entity = Entity::new(world.clone(), pos, &EntityType::PAINTING);
entity
.data
.store(i32::from(face.to_index()), Ordering::Relaxed);
let painting = Arc::new(PaintingEntity::new(entity));
world.play_sound(Sound::EntityPaintingPlace, SoundCategory::Blocks, &pos);
world.spawn_entity(painting);
} else {
let entity_type = if item.item.id == Item::GLOW_ITEM_FRAME.id {
&EntityType::GLOW_ITEM_FRAME
} else {
&EntityType::ITEM_FRAME
};
let entity = Entity::new(world.clone(), pos, entity_type);
let frame = ItemFrameEntity::new(entity);
frame.set_facing(face);
let sound = frame.get_place_sound();
let frame_arc = Arc::new(frame);
world.play_sound(sound, SoundCategory::Blocks, &pos);
world.spawn_entity(frame_arc);
}
item.decrement_unless_creative(player.gamemode.load(), 1);
}
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@ -29,7 +29,7 @@ impl ItemMetadata for HoneyCombItem {
impl ItemBehaviour for HoneyCombItem { impl ItemBehaviour for HoneyCombItem {
fn use_on_block( fn use_on_block(
&self, &self,
_item: &mut ItemStack, item: &mut ItemStack,
player: &Player, player: &Player,
location: BlockPos, location: BlockPos,
_face: BlockDirection, _face: BlockDirection,
@ -38,7 +38,9 @@ impl ItemBehaviour for HoneyCombItem {
_server: &Server, _server: &Server,
) { ) {
let world = player.world(); let world = player.world();
try_wax_block(&world, location, block); if try_wax_block(&world, location, block) {
item.decrement_unless_creative(player.gamemode.load(), 1);
}
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {

View File

@ -0,0 +1,56 @@
use std::any::Any;
use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata};
use pumpkin_data::data_component_impl::RecipesImpl;
use pumpkin_data::item::Item;
pub struct KnowledgeBookItem;
pub struct DiscFragmentItem;
impl ItemMetadata for KnowledgeBookItem {
fn ids() -> Box<[u16]> {
Box::new([Item::KNOWLEDGE_BOOK.id])
}
}
impl ItemBehaviour for KnowledgeBookItem {
fn normal_use(&self, _item: &Item, player: &Player) {
let mut held = player.inventory().held_item();
let mut matched_main = true;
if held.is_empty() || held.item.id != Item::KNOWLEDGE_BOOK.id {
held = player.inventory().off_hand_item();
matched_main = false;
if held.is_empty() || held.item.id != Item::KNOWLEDGE_BOOK.id {
return;
}
}
let _recipes = held.get_data_component::<RecipesImpl>();
held.decrement_unless_creative(player.gamemode.load(), 1);
if matched_main {
player.inventory().set_held_item(held);
} else {
player
.inventory()
.set_stack_in_hand(pumpkin_util::Hand::Left, held);
}
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl ItemMetadata for DiscFragmentItem {
fn ids() -> Box<[u16]> {
Box::new([Item::DISC_FRAGMENT_5.id])
}
}
impl ItemBehaviour for DiscFragmentItem {
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@ -81,7 +81,7 @@ impl ItemBehaviour for MinecartItem {
let pos = location.to_f64(); let pos = location.to_f64();
let entity = Entity::new( let entity = Entity::new(
world.clone(), world.clone(),
Vector3::new(pos.x, pos.y + 0.0625 + height, pos.z), Vector3::new(pos.x + 0.5, pos.y + 0.0625 + height, pos.z + 0.5),
entity_type, entity_type,
); );
let minecart_entity = Arc::new(MinecartEntity::new(entity)); let minecart_entity = Arc::new(MinecartEntity::new(entity));

View File

@ -10,6 +10,7 @@ pub mod bundle;
pub mod clock; pub mod clock;
pub mod compass; pub mod compass;
pub mod crossbow; pub mod crossbow;
pub mod debug_stick;
pub mod dye; pub mod dye;
pub mod egg; pub mod egg;
pub mod end_crystal; pub mod end_crystal;
@ -21,20 +22,24 @@ pub mod fishing_rod;
pub mod glass_bottle; pub mod glass_bottle;
pub mod glowing_ink_sac; pub mod glowing_ink_sac;
pub mod goat_horn; pub mod goat_horn;
pub mod hanging_entity;
pub mod hoe; pub mod hoe;
pub mod honeycomb; pub mod honeycomb;
pub mod ignite; pub mod ignite;
pub mod ink_sac; pub mod ink_sac;
pub mod knowledge_book;
pub mod lead; pub mod lead;
pub mod mace; pub mod mace;
pub mod map; pub mod map;
pub mod minecart; pub mod minecart;
pub mod name_tag; pub mod name_tag;
pub mod on_a_stick; pub mod on_a_stick;
pub mod place_on_water;
pub mod potions; pub mod potions;
pub mod projectile_weapon; pub mod projectile_weapon;
pub mod saddle; pub mod saddle;
pub mod shears; pub mod shears;
pub mod shield;
pub mod shovel; pub mod shovel;
pub mod snowball; pub mod snowball;
pub mod spawn_egg; pub mod spawn_egg;
@ -52,18 +57,23 @@ use crate::item::items::brush::BrushItem;
use crate::item::items::bundle::BundleItem; use crate::item::items::bundle::BundleItem;
use crate::item::items::clock::ClockItem; use crate::item::items::clock::ClockItem;
use crate::item::items::compass::CompassItem; use crate::item::items::compass::CompassItem;
use crate::item::items::debug_stick::DebugStickItem;
use crate::item::items::end_crystal::EndCrystalItem; use crate::item::items::end_crystal::EndCrystalItem;
use crate::item::items::experience_bottle::ExperienceBottleItem; use crate::item::items::experience_bottle::ExperienceBottleItem;
use crate::item::items::glass_bottle::GlassBottleItem; use crate::item::items::glass_bottle::GlassBottleItem;
use crate::item::items::goat_horn::GoatHornItem; use crate::item::items::goat_horn::GoatHornItem;
use crate::item::items::hanging_entity::HangingEntityItem;
use crate::item::items::knowledge_book::{DiscFragmentItem, KnowledgeBookItem};
use crate::item::items::lead::LeadItem; use crate::item::items::lead::LeadItem;
use crate::item::items::map::MapItem; use crate::item::items::map::MapItem;
use crate::item::items::minecart::MinecartItem; use crate::item::items::minecart::MinecartItem;
use crate::item::items::name_tag::NameTagItem; use crate::item::items::name_tag::NameTagItem;
use crate::item::items::on_a_stick::{CarrotOnAStickItem, WarpedFungusOnAStickItem}; use crate::item::items::on_a_stick::{CarrotOnAStickItem, WarpedFungusOnAStickItem};
use crate::item::items::place_on_water::PlaceOnWaterBlockItem;
use crate::item::items::saddle::SaddleItem; use crate::item::items::saddle::SaddleItem;
use crate::item::items::shears::ShearsItem; use crate::item::items::shears::ShearsItem;
use crate::item::items::shield::ShieldItem;
use crate::item::items::spawn_egg::SpawnEggItem; use crate::item::items::spawn_egg::SpawnEggItem;
use crate::item::items::spyglass::SpyglassItem; use crate::item::items::spyglass::SpyglassItem;
use crate::item::items::wind_charge::WindChargeItem; use crate::item::items::wind_charge::WindChargeItem;
@ -151,6 +161,12 @@ pub fn default_registry() -> Arc<ItemRegistry> {
manager.register(LingeringPotionItem); manager.register(LingeringPotionItem);
manager.register(BundleItem); manager.register(BundleItem);
manager.register(LeadItem); manager.register(LeadItem);
manager.register(HangingEntityItem);
manager.register(PlaceOnWaterBlockItem);
manager.register(KnowledgeBookItem);
manager.register(DiscFragmentItem);
manager.register(ShieldItem);
manager.register(DebugStickItem);
Arc::new(manager) Arc::new(manager)
} }

View File

@ -3,7 +3,9 @@ use std::any::Any;
use crate::entity::EntityBase; use crate::entity::EntityBase;
use crate::entity::player::Player; use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata}; use crate::item::{ItemBehaviour, ItemMetadata};
use pumpkin_data::entity::EntityType;
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack;
pub struct CarrotOnAStickItem; pub struct CarrotOnAStickItem;
pub struct WarpedFungusOnAStickItem; pub struct WarpedFungusOnAStickItem;
@ -23,10 +25,17 @@ impl ItemBehaviour for CarrotOnAStickItem {
.ok() .ok()
.and_then(|guard| guard.clone()); .and_then(|guard| guard.clone());
if let Some(vehicle) = vehicle_opt if let Some(vehicle) = vehicle_opt
&& vehicle.get_entity().entity_type.id == EntityType::PIG.id
&& let Some(steerable) = vehicle.get_item_steerable() && let Some(steerable) = vehicle.get_item_steerable()
&& steerable.boost() && steerable.boost()
{ {
let before = player.inventory.held_item();
player.damage_held_item(7); player.damage_held_item(7);
if !before.is_empty() && player.inventory.held_item().is_empty() {
player
.inventory
.set_held_item(ItemStack::new(1, &Item::FISHING_ROD));
}
} }
} }
@ -50,10 +59,17 @@ impl ItemBehaviour for WarpedFungusOnAStickItem {
.ok() .ok()
.and_then(|guard| guard.clone()); .and_then(|guard| guard.clone());
if let Some(vehicle) = vehicle_opt if let Some(vehicle) = vehicle_opt
&& vehicle.get_entity().entity_type.id == EntityType::STRIDER.id
&& let Some(steerable) = vehicle.get_item_steerable() && let Some(steerable) = vehicle.get_item_steerable()
&& steerable.boost() && steerable.boost()
{ {
player.damage_held_item(7); let before = player.inventory.held_item();
player.damage_held_item(1);
if !before.is_empty() && player.inventory.held_item().is_empty() {
player
.inventory
.set_held_item(ItemStack::new(1, &Item::FISHING_ROD));
}
} }
} }

View File

@ -0,0 +1,81 @@
use std::any::Any;
use std::sync::Arc;
use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata};
use crate::world::{BlockFlags, World};
use pumpkin_data::Block;
use pumpkin_data::fluid::Fluid;
use pumpkin_data::item::Item;
use pumpkin_data::sound::Sound;
use pumpkin_util::math::position::BlockPos;
pub struct PlaceOnWaterBlockItem;
impl ItemMetadata for PlaceOnWaterBlockItem {
fn ids() -> Box<[u16]> {
[Item::LILY_PAD.id, Item::FROGSPAWN.id].into()
}
}
impl ItemBehaviour for PlaceOnWaterBlockItem {
fn normal_use(&self, item: &Item, player: &Player) {
let world = player.world();
let (start_pos, end_pos) = self.get_start_and_end_pos(player);
let checker = |pos: &BlockPos, world_inner: &Arc<World>| {
let state_id = world_inner.get_block_state_id(pos);
if state_id == Block::AIR.default_state.id {
return false;
}
Fluid::from_state_id(state_id).is_some()
};
let Some((hit_pos, _)) = world.raycast(start_pos, end_pos, checker) else {
return;
};
let above_pos = hit_pos.up();
let above_state = world.get_block_state(&above_pos);
if above_state.is_air() {
let (placed_block, sound) = if item.id == Item::LILY_PAD.id {
(&Block::LILY_PAD, Sound::BlockLilyPadPlace)
} else {
(&Block::FROGSPAWN, Sound::BlockFrogspawnPlace)
};
world.set_block_state(
&above_pos,
placed_block.default_state.id,
BlockFlags::NOTIFY_ALL,
);
world.play_sound(
sound,
pumpkin_data::sound::SoundCategory::Blocks,
&above_pos.to_f64(),
);
let mut main_hand = player.inventory.held_item();
let consumed = if !main_hand.is_empty() && main_hand.item.id == item.id {
main_hand.decrement_unless_creative(player.gamemode.load(), 1);
player.inventory.set_held_item(main_hand);
true
} else {
false
};
if !consumed {
let mut off_hand = player.inventory.off_hand_item();
if !off_hand.is_empty() && off_hand.item.id == item.id {
off_hand.decrement_unless_creative(player.gamemode.load(), 1);
player
.inventory
.set_stack_in_hand(pumpkin_util::Hand::Left, off_hand);
}
}
}
}
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@ -0,0 +1,18 @@
use std::any::Any;
use crate::item::{ItemBehaviour, ItemMetadata};
use pumpkin_data::item::Item;
pub struct ShieldItem;
impl ItemMetadata for ShieldItem {
fn ids() -> Box<[u16]> {
Box::new([Item::SHIELD.id])
}
}
impl ItemBehaviour for ShieldItem {
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@ -1,15 +1,20 @@
use std::sync::Arc;
use crate::block::entities::mob_spawner::MobSpawnerBlockEntity; use crate::block::entities::mob_spawner::MobSpawnerBlockEntity;
use crate::entity::EntityBase; use crate::entity::EntityBase;
use crate::entity::player::Player; use crate::entity::player::Player;
use crate::entity::r#type::from_type; use crate::entity::r#type::from_type;
use crate::item::{ItemBehaviour, ItemMetadata}; use crate::item::{ItemBehaviour, ItemMetadata};
use crate::server::Server; use crate::server::Server;
use crate::world::World;
use pumpkin_data::data_component_impl::{ use pumpkin_data::data_component_impl::{
AxolotlVariantImpl, CatVariantImpl, ChickenVariantImpl, CowVariantImpl, FoxVariantImpl, AxolotlVariantImpl, CatVariantImpl, ChickenVariantImpl, CowVariantImpl, FoxVariantImpl,
FrogVariantImpl, HorseVariantImpl, LlamaVariantImpl, MooshroomVariantImpl, PigVariantImpl, FrogVariantImpl, HorseVariantImpl, LlamaVariantImpl, MooshroomVariantImpl, PigVariantImpl,
RabbitVariantImpl, SheepColorImpl, ShulkerColorImpl, VillagerVariantImpl, WolfVariantImpl, RabbitVariantImpl, SheepColorImpl, ShulkerColorImpl, VillagerVariantImpl, WolfVariantImpl,
}; };
use pumpkin_data::entity::entity_from_egg; use pumpkin_data::entity::entity_from_egg;
use pumpkin_data::fluid::Fluid;
use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack; use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::{Block, BlockDirection}; use pumpkin_data::{Block, BlockDirection};
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -60,6 +65,61 @@ pub(crate) fn apply_entity_variant(item: &ItemStack, mob: &dyn EntityBase) {
} }
impl ItemBehaviour for SpawnEggItem { impl ItemBehaviour for SpawnEggItem {
fn normal_use(&self, item: &Item, player: &Player) {
if let Some(entity_type) = entity_from_egg(item.id) {
let world = player.world();
let (start_pos, end_pos) = self.get_start_and_end_pos(player);
let checker = |pos: &BlockPos, world_inner: &Arc<World>| {
let state_id = world_inner.get_block_state_id(pos);
if state_id == Block::AIR.default_state.id {
return false;
}
Fluid::from_state_id(state_id).is_some()
};
let Some((hit_pos, _)) = world.raycast(start_pos, end_pos, checker) else {
return;
};
let pos = Vector3::new(
f64::from(hit_pos.0.x) + 0.5,
f64::from(hit_pos.0.y),
f64::from(hit_pos.0.z) + 0.5,
);
let yaw = wrap_degrees(rand::random::<f32>() * 360.0) % 360.0;
let mob = from_type(entity_type, pos, &world, Uuid::new_v4());
mob.get_entity().set_rotation(yaw, 0.0);
let held = player.inventory.held_item();
let stack = if !held.is_empty() && held.item.id == item.id {
held
} else {
player.inventory.off_hand_item()
};
apply_entity_variant(&stack, mob.as_ref());
world.spawn_entity(mob);
let mut main_hand = player.inventory.held_item();
let consumed = if !main_hand.is_empty() && main_hand.item.id == item.id {
main_hand.decrement_unless_creative(player.gamemode.load(), 1);
player.inventory.set_held_item(main_hand);
true
} else {
false
};
if !consumed {
let mut off_hand = player.inventory.off_hand_item();
if !off_hand.is_empty() && off_hand.item.id == item.id {
off_hand.decrement_unless_creative(player.gamemode.load(), 1);
player
.inventory
.set_stack_in_hand(pumpkin_util::Hand::Left, off_hand);
}
}
}
}
fn use_on_block( fn use_on_block(
&self, &self,
item: &mut ItemStack, item: &mut ItemStack,
@ -83,23 +143,55 @@ impl ItemBehaviour for SpawnEggItem {
item.decrement_unless_creative(player.gamemode.load(), 1); item.decrement_unless_creative(player.gamemode.load(), 1);
return; return;
} }
let pos = BlockPos(location.0 + face.to_offset());
let target_state = world.get_block_state(&location);
let target_block = world.get_block(&location);
let spawn_block_pos = if target_state.is_air()
|| target_block.id == Block::WATER.id
|| target_block.id == Block::LAVA.id
{
location
} else {
BlockPos(location.0 + face.to_offset())
};
let pos = Vector3::new( let pos = Vector3::new(
f64::from(pos.0.x) + 0.5, f64::from(spawn_block_pos.0.x) + 0.5,
f64::from(pos.0.y), f64::from(spawn_block_pos.0.y),
f64::from(pos.0.z) + 0.5, f64::from(spawn_block_pos.0.z) + 0.5,
); );
// Create rotation like Vanilla
let yaw = wrap_degrees(rand::random::<f32>() * 360.0) % 360.0; let yaw = wrap_degrees(rand::random::<f32>() * 360.0) % 360.0;
let mob = from_type(entity_type, pos, &world, Uuid::new_v4()); let mob = from_type(entity_type, pos, &world, Uuid::new_v4());
// Set the rotation
mob.get_entity().set_rotation(yaw, 0.0); mob.get_entity().set_rotation(yaw, 0.0);
apply_entity_variant(item, mob.as_ref()); apply_entity_variant(item, mob.as_ref());
// Broadcast the new mob to all players world.spawn_entity(mob);
item.decrement_unless_creative(player.gamemode.load(), 1);
}
}
fn use_on_entity(&self, item: &mut ItemStack, player: &Player, entity: Arc<dyn EntityBase>) {
if let Some(entity_type) = entity_from_egg(item.item.id)
&& entity.get_entity().entity_type.id == entity_type.id
{
let world = player.world();
let pos = entity.get_entity().pos.load();
let mob = from_type(entity_type, pos, &world, Uuid::new_v4());
mob.get_entity()
.set_rotation(rand::random::<f32>() * 360.0, 0.0);
mob.get_entity()
.age
.store(-24000, std::sync::atomic::Ordering::Relaxed);
mob.get_entity().send_meta_data(
&[pumpkin_protocol::java::client::play::Metadata::new(
pumpkin_data::tracked_data::ageable_mob::DATA_BABY_ID,
true,
)],
None,
);
apply_entity_variant(item, mob.as_ref());
world.spawn_entity(mob); world.spawn_entity(mob);
item.decrement_unless_creative(player.gamemode.load(), 1); item.decrement_unless_creative(player.gamemode.load(), 1);
} }

View File

@ -36,12 +36,28 @@ impl ItemBehaviour for WindChargeItem {
let wind_charge = ThrownItemEntity::new(entity, player.get_entity(), WIND_CHARGE_GRAVITY); let wind_charge = ThrownItemEntity::new(entity, player.get_entity(), WIND_CHARGE_GRAVITY);
let (yaw, pitch) = player.rotation(); let (yaw, pitch) = player.rotation();
wind_charge.set_velocity_from(pitch, yaw, 0.0, POWER, 1.0); wind_charge.set_velocity_from(pitch, yaw, 0.0, POWER, 1.0);
// TODO: player.incrementStat(Stats.USED)
// TODO: Implement that the projectile will explode on impact
world.spawn_entity(Arc::new(WindChargeEntity::new_normal(wind_charge))); world.spawn_entity(Arc::new(WindChargeEntity::new_normal(wind_charge)));
let mut main_hand = player.inventory.held_item();
let consumed = if !main_hand.is_empty() && main_hand.item.id == Item::WIND_CHARGE.id {
main_hand.decrement_unless_creative(player.gamemode.load(), 1);
player.inventory.set_held_item(main_hand);
true
} else {
false
};
if !consumed {
let mut off_hand = player.inventory.off_hand_item();
if !off_hand.is_empty() && off_hand.item.id == Item::WIND_CHARGE.id {
off_hand.decrement_unless_creative(player.gamemode.load(), 1);
player
.inventory
.set_stack_in_hand(pumpkin_util::Hand::Left, off_hand);
}
}
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {

View File

@ -16,15 +16,13 @@ impl ItemMetadata for WritableBookItem {
} }
impl ItemBehaviour for WritableBookItem { impl ItemBehaviour for WritableBookItem {
fn normal_use(&self, item: &Item, player: &Player) { fn normal_use(&self, _item: &Item, player: &Player) {
if item.id == Item::WRITTEN_BOOK.id { player.try_send_client_packet(&COpenBook::new(VarInt(0)));
player.try_send_client_packet(&COpenBook::new(VarInt(0))); // 0 = main hand player.world().play_sound(
player.world().play_sound( Sound::ItemBookPageTurn,
Sound::ItemBookPageTurn, SoundCategory::Players,
SoundCategory::Players, &player.position(),
&player.position(), );
);
}
} }
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {

Some files were not shown because too many files have changed in this diff Show More