Pumpkin/pumpkin/src/item/items/egg.rs
Alexander Medvedev d8a124cf92 feat: ender pearl
2026-04-16 21:46:18 +02:00

74 lines
2.5 KiB
Rust

use std::pin::Pin;
use std::sync::Arc;
use crate::entity::Entity;
use crate::entity::player::Player;
use crate::entity::projectile::egg::EggEntity;
use crate::item::{ItemBehaviour, ItemMetadata};
use pumpkin_data::entity::EntityType;
use pumpkin_data::item::Item;
use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::sound::Sound;
pub struct EggItem;
impl ItemMetadata for EggItem {
fn ids() -> Box<[u16]> {
[Item::EGG.id, Item::BLUE_EGG.id, Item::BROWN_EGG.id].into()
}
}
const POWER: f32 = 1.5;
impl ItemBehaviour for EggItem {
fn normal_use<'a>(
&'a self,
_block: &'a Item,
player: &'a Player,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let position = player.position();
let world = player.world();
world
.play_sound(
Sound::EntityEggThrow,
pumpkin_data::sound::SoundCategory::Players,
&position,
)
.await;
// Capture the held item stack and pass it to the thrown egg entity
let item_stack: ItemStack = player.inventory.held_item().lock().await.clone();
let entity = Entity::new(world.clone(), position, &EntityType::EGG);
let egg = EggEntity::new_shot(entity, &player.living_entity.entity).await;
// Propagate the item stack so clients show correct variant
egg.set_item_stack(item_stack.clone()).await;
let yaw = player.living_entity.entity.yaw.load();
let pitch = player.living_entity.entity.pitch.load();
egg.thrown
.set_velocity_from(&player.living_entity.entity, pitch, yaw, 0.0, POWER, 1.0);
world.spawn_entity(Arc::new(egg)).await;
// Consume item
let held_item = player.inventory.held_item();
let mut main_hand = held_item.lock().await;
if !main_hand.is_empty() && Self::ids().contains(&main_hand.item.id) {
main_hand.decrement_unless_creative(player.gamemode.load(), 1);
} else {
let off_hand_item = player.inventory.off_hand_item().await;
let mut off_hand = off_hand_item.lock().await;
if !off_hand.is_empty() && Self::ids().contains(&off_hand.item.id) {
off_hand.decrement_unless_creative(player.gamemode.load(), 1);
}
}
})
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}