Pumpkin/pumpkin/src/block/blocks/redstone/pressure_plate/plate.rs
Alexander Medvedev 5bfa6528da chore: changed block registration
only require block ids, should make bin size smaller and let the compiler better optimize, should also be faster performance wise
2026-01-23 23:32:17 +01:00

124 lines
3.8 KiB
Rust

use pumpkin_data::{
Block, BlockDirection, BlockState,
block_properties::BlockProperties,
tag::{self},
};
use pumpkin_util::math::{boundingbox::BoundingBox, position::BlockPos};
use pumpkin_world::{BlockStateId, world::BlockFlags};
use crate::{
block::{
BlockBehaviour, BlockFuture, BlockMetadata, CanPlaceAtArgs, EmitsRedstonePowerArgs,
GetRedstonePowerArgs, OnEntityCollisionArgs, OnNeighborUpdateArgs, OnScheduledTickArgs,
OnStateReplacedArgs,
},
world::World,
};
use super::PressurePlate;
/// This is for Normal Pressure plates, so not Gold or Iron
pub struct PressurePlateBlock;
type PressurePlateProps = pumpkin_data::block_properties::StonePressurePlateLikeProperties;
impl BlockMetadata for PressurePlateBlock {
fn ids() -> Box<[u16]> {
let mut combined = Vec::new();
combined.extend_from_slice(tag::Block::MINECRAFT_WOODEN_PRESSURE_PLATES.1);
combined.extend_from_slice(tag::Block::MINECRAFT_STONE_PRESSURE_PLATES.1);
combined.into_boxed_slice()
}
}
impl BlockBehaviour for PressurePlateBlock {
fn on_entity_collision<'a>(&'a self, args: OnEntityCollisionArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
self.on_entity_collision_pp(args).await;
})
}
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
self.on_scheduled_tick_pp(args).await;
})
}
fn on_state_replaced<'a>(&'a self, args: OnStateReplacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
self.on_state_replaced_pp(args).await;
})
}
fn get_weak_redstone_power<'a>(
&'a self,
args: GetRedstonePowerArgs<'a>,
) -> BlockFuture<'a, u8> {
Box::pin(async move { self.get_redstone_output(args.block, args.state.id) })
}
fn get_strong_redstone_power<'a>(
&'a self,
args: GetRedstonePowerArgs<'a>,
) -> BlockFuture<'a, u8> {
Box::pin(async move {
if args.direction == BlockDirection::Up {
return self.get_redstone_output(args.block, args.state.id);
}
0
})
}
fn emits_redstone_power<'a>(
&'a self,
_args: EmitsRedstonePowerArgs<'a>,
) -> BlockFuture<'a, bool> {
Box::pin(async move { true })
}
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !Self::can_pressure_plate_place_at(args.world, args.position).await {
args.world
.break_block(args.position, None, BlockFlags::NOTIFY_ALL)
.await;
}
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
Self::can_pressure_plate_place_at(args.world.unwrap(), args.position).await
})
}
}
impl PressurePlate for PressurePlateBlock {
fn get_redstone_output(&self, block: &Block, state: BlockStateId) -> u8 {
let props = PressurePlateProps::from_state_id(state, block);
if props.powered { 15 } else { 0 }
}
async fn calculate_redstone_output(&self, world: &World, _block: &Block, pos: &BlockPos) -> u8 {
// TODO: this is bad use real box
let aabb = BoundingBox::from_block(pos);
if !world.get_entities_at_box(&aabb).await.is_empty()
|| !world.get_players_at_box(&aabb).await.is_empty()
{
return 15;
}
0
}
fn set_redstone_output(
&self,
block: &Block,
state: &BlockState,
output: u8,
) -> pumpkin_world::BlockStateId {
let mut props = PressurePlateProps::from_state_id(state.id, block);
props.powered = output > 0;
props.to_state_id(block)
}
}