feat: more item work
This commit is contained in:
parent
4e614c9eeb
commit
3a3ba2c873
@ -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
@ -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>()
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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<'_>) {
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
crates/pumpkin/src/block/blocks/honey.rs
Normal file
29
crates/pumpkin/src/block/blocks/honey.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
crates/pumpkin/src/block/blocks/light.rs
Normal file
65
crates/pumpkin/src/block/blocks/light.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
16
crates/pumpkin/src/block/blocks/mud.rs
Normal file
16
crates/pumpkin/src/block/blocks/mud.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
69
crates/pumpkin/src/block/blocks/plant/azalea.rs
Normal file
69
crates/pumpkin/src/block/blocks/plant/azalea.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
126
crates/pumpkin/src/block/blocks/plant/cave_vines.rs
Normal file
126
crates/pumpkin/src/block/blocks/plant/cave_vines.rs
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 {
|
||||||
|
|||||||
145
crates/pumpkin/src/block/blocks/plant/crop/pitcher_crop.rs
Normal file
145
crates/pumpkin/src/block/blocks/plant/crop/pitcher_crop.rs
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
crates/pumpkin/src/block/blocks/plant/hanging_roots.rs
Normal file
54
crates/pumpkin/src/block/blocks/plant/hanging_roots.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
82
crates/pumpkin/src/block/blocks/scaffolding.rs
Normal file
82
crates/pumpkin/src/block/blocks/scaffolding.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
))
|
))
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
16
crates/pumpkin/src/block/blocks/soul_sand.rs
Normal file
16
crates/pumpkin/src/block/blocks/soul_sand.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
|
|||||||
8
crates/pumpkin/src/block/blocks/structure_void.rs
Normal file
8
crates/pumpkin/src/block/blocks/structure_void.rs
Normal 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 {}
|
||||||
57
crates/pumpkin/src/block/blocks/test_block.rs
Normal file
57
crates/pumpkin/src/block/blocks/test_block.rs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
8
crates/pumpkin/src/block/blocks/tinted_glass.rs
Normal file
8
crates/pumpkin/src/block/blocks/tinted_glass.rs
Normal 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 {}
|
||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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, ¶ms);
|
||||||
|
}
|
||||||
|
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, ¶ms);
|
||||||
}
|
}
|
||||||
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, ¶ms,
|
||||||
|
));
|
||||||
|
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, ¶ms);
|
||||||
|
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);
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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());
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
193
crates/pumpkin/src/item/items/debug_stick.rs
Normal file
193
crates/pumpkin/src/item/items/debug_stick.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
84
crates/pumpkin/src/item/items/hanging_entity.rs
Normal file
84
crates/pumpkin/src/item/items/hanging_entity.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 {
|
||||||
|
|||||||
56
crates/pumpkin/src/item/items/knowledge_book.rs
Normal file
56
crates/pumpkin/src/item/items/knowledge_book.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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));
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
81
crates/pumpkin/src/item/items/place_on_water.rs
Normal file
81
crates/pumpkin/src/item/items/place_on_water.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
18
crates/pumpkin/src/item/items/shield.rs
Normal file
18
crates/pumpkin/src/item/items/shield.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
Loading…
Reference in New Issue
Block a user