61 lines
2.4 KiB
Rust
61 lines
2.4 KiB
Rust
use pumpkin_data::block_properties::Facing;
|
|
use pumpkin_data::{Block, BlockState, FacingExt};
|
|
use pumpkin_macros::pumpkin_block;
|
|
use pumpkin_world::world::BlockFlags;
|
|
|
|
use crate::block::blocks::piston::piston::try_move;
|
|
use crate::block::{BlockBehaviour, BrokenArgs, OnNeighborUpdateArgs, PathComputationType};
|
|
|
|
use super::piston::PistonProps;
|
|
|
|
pub(crate) type PistonHeadProperties = pumpkin_data::block_properties::PistonHeadLikeProperties;
|
|
|
|
#[pumpkin_block("minecraft:piston_head")]
|
|
pub struct PistonHeadBlock;
|
|
|
|
impl BlockBehaviour for PistonHeadBlock {
|
|
fn broken(&self, args: BrokenArgs<'_>) {
|
|
let props = PistonHeadProperties::from_state_id(args.state.id);
|
|
let pos = args
|
|
.position
|
|
.offset(props.facing.opposite().to_block_direction().to_offset());
|
|
let (new_block, new_state) = args.world.get_block_and_state_id(&pos);
|
|
if &Block::PISTON == new_block || &Block::STICKY_PISTON == new_block {
|
|
let props = PistonProps::from_state_id(new_state);
|
|
if props.extended {
|
|
// TODO: use player
|
|
args.world.break_block(&pos, None, BlockFlags::SKIP_DROPS);
|
|
}
|
|
}
|
|
}
|
|
fn on_neighbor_update(&self, args: OnNeighborUpdateArgs<'_>) {
|
|
let head_state_id = args.world.get_block_state_id(args.position);
|
|
let head_props = PistonHeadProperties::from_state_id(head_state_id);
|
|
if head_props.facing != Facing::Up {
|
|
return;
|
|
}
|
|
let piston_pos = args.position.offset(
|
|
head_props
|
|
.facing
|
|
.opposite()
|
|
.to_block_direction()
|
|
.to_offset(),
|
|
);
|
|
let piston_block = args.world.get_block(&piston_pos);
|
|
if &Block::PISTON == piston_block || &Block::STICKY_PISTON == piston_block {
|
|
let up_pos = args
|
|
.position
|
|
.offset(head_props.facing.to_block_direction().to_offset());
|
|
let upper_block = args.world.get_block(&up_pos);
|
|
if upper_block != &Block::REDSTONE_BLOCK {
|
|
//Then somebody probably broke the redstone block, try to check if piston should still be extended.
|
|
try_move(args.world, piston_block, &piston_pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
|
|
false
|
|
}
|
|
}
|