Pumpkin/pumpkin/src/block/blocks/lanterns.rs
2026-05-14 12:28:43 +02:00

101 lines
3.4 KiB
Rust

use crate::block::{
BlockBehaviour, BlockFuture, BlockMetadata, CanPlaceAtArgs, GetStateForNeighborUpdateArgs,
OnPlaceArgs, OnScheduledTickArgs,
};
use crate::world::World;
use pumpkin_data::block_properties::BlockProperties;
use pumpkin_data::tag::Taggable;
use pumpkin_data::{Block, BlockDirection, tag};
use pumpkin_util::math::position::BlockPos;
use pumpkin_world::BlockStateId;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::BlockFlags;
pub struct LanternBlock;
impl BlockMetadata for LanternBlock {
fn ids() -> Box<[u16]> {
[
Block::LANTERN.id,
Block::SOUL_LANTERN.id,
Block::COPPER_LANTERN.id,
Block::EXPOSED_COPPER_LANTERN.id,
Block::WEATHERED_COPPER_LANTERN.id,
Block::OXIDIZED_COPPER_LANTERN.id,
Block::WAXED_COPPER_LANTERN.id,
Block::WAXED_EXPOSED_COPPER_LANTERN.id,
Block::WAXED_WEATHERED_COPPER_LANTERN.id,
Block::WAXED_OXIDIZED_COPPER_LANTERN.id,
]
.into()
}
}
impl BlockBehaviour for LanternBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let mut props =
pumpkin_data::block_properties::LanternLikeProperties::default(args.block);
props.r#waterlogged = args.replacing.water_source();
let block_up_state = args.world.get_block_state(&args.position.up());
if block_up_state.is_center_solid(BlockDirection::Down) {
props.r#hanging = true;
}
props.to_state_id(args.block)
})
}
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.world.unwrap(), args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
}
args.state_id
})
}
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world, args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
}
})
}
}
fn can_place_at(world: &World, position: &BlockPos) -> bool {
//idk why this don't update with .is_center_solid so this is a 'temporary patch'
if world
.get_block(&position.down())
.has_tag(&tag::Block::C_FENCE_GATES)
{
let fence_gate_props =
pumpkin_data::block_properties::OakFenceGateLikeProperties::from_state_id(
world.get_block_state_id(&position.down()),
world.get_block(&position.down()),
);
if fence_gate_props.open {
return false;
}
}
let (block_down, block_down_state) = world.get_block_and_state(&position.down());
let block_up_state = world.get_block_state(&position.up());
block_down_state.is_center_solid(BlockDirection::Up)
|| block_up_state.is_center_solid(BlockDirection::Down)
|| block_down.has_tag(&tag::Block::MINECRAFT_UNSTABLE_BOTTOM_CENTER)
}