diff --git a/pumpkin-world/src/item/item_registry.rs b/pumpkin-world/src/item/item_registry.rs index 20e48248..d71a9932 100644 --- a/pumpkin-world/src/item/item_registry.rs +++ b/pumpkin-world/src/item/item_registry.rs @@ -56,6 +56,8 @@ pub struct ItemComponents { pub attribute_modifiers: Option, #[serde(rename = "minecraft:food")] pub food: Option, + #[serde(rename = "minecraft:consumable")] + pub consumable: Option, #[serde(rename = "minecraft:equippable")] pub equippable: Option, } @@ -88,6 +90,29 @@ pub struct Food { pub can_always_eat: Option, } +#[derive(Deserialize, Clone, Debug)] +#[serde(default)] +pub struct Consumable { + pub consume_seconds: f32, + pub has_consume_particles: bool, + pub animation: Option, + pub sound: Option, + // TODO: Effects implementation?? + pub on_consume_effects: Option>, +} + +impl Default for Consumable { + fn default() -> Self { + Self { + consume_seconds: 1.6, + has_consume_particles: true, + animation: None, + sound: None, + on_consume_effects: None, + } + } +} + #[derive(Deserialize, Clone, Debug, Default)] #[serde(default)] pub struct Equippable { diff --git a/pumpkin/src/net/packet/play.rs b/pumpkin/src/net/packet/play.rs index b8f8de40..01f328e5 100644 --- a/pumpkin/src/net/packet/play.rs +++ b/pumpkin/src/net/packet/play.rs @@ -917,19 +917,20 @@ impl Player { let item = item_registry::get_item_by_id(item_stack.item_id) .ok_or(InventoryError::InvalidPacket)?; - if let Some(food) = item.components.food { - log::debug!("Player tried eat food: {:?}", food); - + if let Some(consumable) = &item.components.consumable { let player = self.clone(); *self.eating.lock().await = Some(tokio::spawn(async move { - sleep(Duration::from_millis(1610)).await; + sleep(Duration::from_secs_f32(consumable.consume_seconds)).await; player .client .send_packet(&CEntityStatus::new(player.entity_id(), 9)) .await; + // TODO: how i can play sound?? + //self.world().play_sound(sound!(consumable.sound), category, position) + if player.gamemode.load() != GameMode::Creative { let mut inventory = player.inventory().lock().await; let item_count = &mut inventory.held_item_mut().as_mut().unwrap().item_count; @@ -940,15 +941,17 @@ impl Player { } } - player - .set_health( - player.living_entity.health.load(), - player.food.load(Ordering::Relaxed) + food.nutrition, - player.food_saturation.load() + food.saturation, - ) - .await; + if let Some(food) = item.components.food { + player + .set_health( + player.living_entity.health.load(), + player.food.load(Ordering::Relaxed) + food.nutrition, + player.food_saturation.load() + food.saturation, + ) + .await; - log::debug!("Player eated food: {:?}", food); + log::debug!("Player eated food: {:?}", food); + } })); return Ok(()); }