Pumpkin/pumpkin/src/item/items/shovel.rs
Alexander Medvedev 3629f43dcc fix: disable cave carver for now
fixes some issues
2026-05-23 16:36:08 +02:00

102 lines
3.4 KiB
Rust

use std::pin::Pin;
use crate::entity::player::Player;
use crate::item::{ItemBehaviour, ItemMetadata};
use crate::server::Server;
use pumpkin_data::BlockDirection;
use pumpkin_data::block_properties::{BlockProperties, CampfireLikeProperties};
use pumpkin_data::item_stack::ItemStack;
use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_data::world::WorldEvent;
use pumpkin_data::{Block, tag};
use pumpkin_util::GameMode;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::math::vector3::Vector3;
use pumpkin_world::world::BlockFlags;
use rand::{RngExt, rng};
pub struct ShovelItem;
impl ItemMetadata for ShovelItem {
fn ids() -> Box<[u16]> {
tag::Item::MINECRAFT_SHOVELS.1.into()
}
}
impl ItemBehaviour for ShovelItem {
fn use_on_block<'a>(
&'a self,
item: &'a mut ItemStack,
player: &'a Player,
location: BlockPos,
face: BlockDirection,
_cursor_pos: Vector3<f32>,
block: &'a Block,
_server: &'a Server,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let world = player.world();
// Yes, Minecraft does hardcode these
let mut changed = if (block == &Block::GRASS_BLOCK
|| block == &Block::DIRT
|| block == &Block::COARSE_DIRT
|| block == &Block::ROOTED_DIRT
|| block == &Block::PODZOL
|| block == &Block::MYCELIUM)
&& face != BlockDirection::Down
&& world.get_block_state(&location.up()).is_air()
{
world
.set_block_state(
&location,
Block::DIRT_PATH.default_state.id,
BlockFlags::NOTIFY_ALL,
)
.await;
true
} else {
false
};
if block == &Block::CAMPFIRE || block == &Block::SOUL_CAMPFIRE {
let mut campfire_props = CampfireLikeProperties::from_state_id(
world.get_block_state(&location).id,
block,
);
if campfire_props.lit {
world.sync_world_event(WorldEvent::SoundExtinguishFire, location, 0);
campfire_props.lit = false;
world
.set_block_state(
&location,
campfire_props.to_state_id(block),
BlockFlags::NOTIFY_ALL,
)
.await;
let seed = rng().random::<f64>();
player
.play_sound(
Sound::BlockFireExtinguish as u16,
SoundCategory::Ambient,
&location.to_f64(),
0.5,
2.0,
seed,
)
.await;
changed = true;
}
}
if changed && player.gamemode.load() != GameMode::Creative {
// TODO: Handle DamageResult::Broken to broadcast item break and update player slot.
let _ = item.damage_item(1);
}
})
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}