132 lines
4.3 KiB
Rust
132 lines
4.3 KiB
Rust
use std::sync::Arc;
|
|
use std::sync::Mutex;
|
|
|
|
use pumpkin_data::translation;
|
|
use pumpkin_data::{
|
|
Block, BlockDirection, BlockStateId, HorizontalFacingExt,
|
|
block_properties::{AttachFace, GrindstoneLikeProperties},
|
|
};
|
|
use pumpkin_inventory::grindstone_screen_handler::GrindstoneScreenHandler;
|
|
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
|
use pumpkin_inventory::screen_handler::{
|
|
InventoryPlayer, ScreenHandlerFactory, SharedScreenHandler,
|
|
};
|
|
use pumpkin_macros::pumpkin_block;
|
|
use pumpkin_util::math::position::BlockPos;
|
|
use pumpkin_util::text::TextComponent;
|
|
use pumpkin_world::inventory::SimpleInventory;
|
|
use pumpkin_world::world::BlockAccessor;
|
|
|
|
use crate::block::registry::BlockActionResult;
|
|
use crate::block::{
|
|
BlockBehaviour, CanPlaceAtArgs, GetScreenHandlerFactoryArgs, GetStateForNeighborUpdateArgs,
|
|
NormalUseArgs, OnPlaceArgs, PathComputationType,
|
|
};
|
|
use pumpkin_data::BlockState;
|
|
|
|
use super::abstract_wall_mounting::WallMountedBlock;
|
|
|
|
#[pumpkin_block("minecraft:grindstone")]
|
|
pub struct GrindstoneBlock;
|
|
|
|
impl BlockBehaviour for GrindstoneBlock {
|
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
|
server: args.server,
|
|
world: args.world,
|
|
block: args.block,
|
|
position: args.position,
|
|
player: args.player,
|
|
}) {
|
|
args.player.increment_stat(
|
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
|
pumpkin_data::statistic::CustomStatistic::InteractWithGrindstone as i32,
|
|
1,
|
|
);
|
|
args.player
|
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
|
}
|
|
|
|
BlockActionResult::Success
|
|
}
|
|
|
|
fn get_screen_handler_factory(
|
|
&self,
|
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
|
Some(Box::new(GrindstoneScreenFactory))
|
|
}
|
|
|
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
|
let mut props = GrindstoneLikeProperties::from_state_id(args.block.default_state.id);
|
|
(props.face, props.facing) =
|
|
WallMountedBlock::get_placement_face(self, args.player, args.direction);
|
|
|
|
props.to_state_id(args.block)
|
|
}
|
|
|
|
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
|
|
// Use the provided direction, or fallback to the current state's direction if missing
|
|
let direction = args
|
|
.direction
|
|
.unwrap_or_else(|| self.get_direction(args.state.id, args.block));
|
|
|
|
WallMountedBlock::can_place_at(self, args.block_accessor, args.position, direction)
|
|
}
|
|
|
|
fn get_state_for_neighbor_update(
|
|
&self,
|
|
args: GetStateForNeighborUpdateArgs<'_>,
|
|
) -> BlockStateId {
|
|
WallMountedBlock::get_state_for_neighbor_update(self, args)
|
|
}
|
|
|
|
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
|
|
false
|
|
}
|
|
}
|
|
|
|
impl WallMountedBlock for GrindstoneBlock {
|
|
fn can_place_at(
|
|
&self,
|
|
_world: &dyn BlockAccessor,
|
|
_pos: &BlockPos,
|
|
_direction: BlockDirection,
|
|
) -> bool {
|
|
true
|
|
}
|
|
|
|
fn get_direction(&self, state_id: BlockStateId, _block: &Block) -> BlockDirection {
|
|
let props = GrindstoneLikeProperties::from_state_id(state_id);
|
|
match props.face {
|
|
AttachFace::Floor => BlockDirection::Up,
|
|
AttachFace::Ceiling => BlockDirection::Down,
|
|
AttachFace::Wall => props.facing.to_block_direction(),
|
|
}
|
|
}
|
|
}
|
|
|
|
struct GrindstoneScreenFactory;
|
|
|
|
impl ScreenHandlerFactory for GrindstoneScreenFactory {
|
|
fn create_screen_handler(
|
|
&self,
|
|
sync_id: u8,
|
|
player_inventory: &Arc<PlayerInventory>,
|
|
_player: &dyn InventoryPlayer,
|
|
) -> Option<SharedScreenHandler> {
|
|
let inventory = Arc::new(SimpleInventory::new(3));
|
|
let handler = GrindstoneScreenHandler::new(sync_id, player_inventory, inventory);
|
|
let concrete_arc = Arc::new(Mutex::new(handler));
|
|
|
|
Some(concrete_arc as SharedScreenHandler)
|
|
}
|
|
|
|
fn get_display_name(&self) -> TextComponent {
|
|
pumpkin_macros::translate_cross!(
|
|
translation::java::CONTAINER_GRINDSTONE_TITLE,
|
|
translation::bedrock::TILE_GRINDSTONE_NAME
|
|
)
|
|
}
|
|
}
|