Pumpkin/crates/pumpkin/src/block/blocks/brushable_block.rs
Alexander Medvedev 1b87483949 fix: android tls
2026-09-01 20:54:37 +02:00

104 lines
3.4 KiB
Rust

use std::sync::Arc;
use pumpkin_data::block_properties::SuspiciousSandLikeProperties;
use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_data::{Block, BlockId, BlockStateId};
use pumpkin_world::world::BlockFlags;
use crate::block::entities::brushable_block::BrushableBlockBlockEntity;
use crate::block::{BlockBehaviour, BlockMetadata, BrokenArgs, OnPlaceArgs, PlacedArgs};
pub struct BrushableBlock;
impl BlockMetadata for BrushableBlock {
fn ids() -> Box<[BlockId]> {
[BlockId::SUSPICIOUS_SAND, BlockId::SUSPICIOUS_GRAVEL].into()
}
}
impl BrushableBlock {
pub fn brush(
world: &Arc<crate::world::World>,
pos: &pumpkin_util::math::position::BlockPos,
block: &Block,
) {
let state = world.get_block_state(pos);
let mut props = SuspiciousSandLikeProperties::from_state_id(state.id);
let is_gravel = block.id == BlockId::SUSPICIOUS_GRAVEL;
if let Some(be) = world.get_block_entity(pos)
&& let Some(brush_be) = be.as_any().downcast_ref::<BrushableBlockBlockEntity>()
{
let mut hits = brush_be
.hits
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
*hits += 1;
if *hits >= 4 {
let item = brush_be
.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take();
if let Some(item_stack) = item {
world.drop_stack(pos, item_stack);
}
let target_block = if is_gravel {
&Block::GRAVEL
} else {
&Block::SAND
};
world.set_block_state(pos, target_block.default_state.id, BlockFlags::NOTIFY_ALL);
let sound = if is_gravel {
Sound::ItemBrushBrushingGravelComplete
} else {
Sound::ItemBrushBrushingSandComplete
};
world.play_sound(sound, SoundCategory::Blocks, &pos.to_f64());
} else {
props.dusted = (*hits as u8).min(3);
world.set_block_state(pos, props.to_state_id(block), BlockFlags::NOTIFY_ALL);
let sound = if is_gravel {
Sound::ItemBrushBrushingGravel
} else {
Sound::ItemBrushBrushingSand
};
world.play_sound(sound, SoundCategory::Blocks, &pos.to_f64());
}
}
}
}
impl BlockBehaviour for BrushableBlock {
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
let props = SuspiciousSandLikeProperties::default(args.block);
props.to_state_id(args.block)
}
fn placed(&self, args: PlacedArgs<'_>) {
let entity = BrushableBlockBlockEntity::new(*args.position);
args.world.add_block_entity(Arc::new(entity));
}
fn broken(&self, args: BrokenArgs<'_>) {
if let Some(be) = args.world.get_block_entity(args.position)
&& let Some(brush_be) = be.as_any().downcast_ref::<BrushableBlockBlockEntity>()
&& let Some(contained) = brush_be
.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take()
{
args.world.drop_stack(args.position, contained);
}
}
}