feat(block): implement archaeology brushable blocks
This commit is contained in:
parent
75200d79ae
commit
22daa1e5d0
104
crates/pumpkin/src/block/blocks/brushable_block.rs
Normal file
104
crates/pumpkin/src/block/blocks/brushable_block.rs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use pumpkin_data::block_properties::{BlockProperties, 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, BlockFuture, 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 async 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, block);
|
||||||
|
|
||||||
|
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().await;
|
||||||
|
*hits += 1;
|
||||||
|
|
||||||
|
if *hits >= 4 {
|
||||||
|
let item = brush_be.item.lock().await.take();
|
||||||
|
if let Some(item_stack) = item {
|
||||||
|
world.drop_stack(pos, item_stack).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_block = if is_gravel {
|
||||||
|
&Block::GRAVEL
|
||||||
|
} else {
|
||||||
|
&Block::SAND
|
||||||
|
};
|
||||||
|
|
||||||
|
world
|
||||||
|
.set_block_state(pos, target_block.default_state.id, BlockFlags::NOTIFY_ALL)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
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)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
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<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let props = SuspiciousSandLikeProperties::default(args.block);
|
||||||
|
props.to_state_id(args.block)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let entity = BrushableBlockBlockEntity::new(*args.position);
|
||||||
|
args.world.add_block_entity(Arc::new(entity));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
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().await.take()
|
||||||
|
{
|
||||||
|
args.world.drop_stack(args.position, contained).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -110,6 +110,7 @@ pub mod coral;
|
|||||||
pub mod abstract_wall_mounting;
|
pub mod abstract_wall_mounting;
|
||||||
|
|
||||||
pub mod beacon;
|
pub mod beacon;
|
||||||
|
pub mod brushable_block;
|
||||||
pub mod creaking_heart;
|
pub mod creaking_heart;
|
||||||
pub mod decorated_pot;
|
pub mod decorated_pot;
|
||||||
pub mod sniffer_egg;
|
pub mod sniffer_egg;
|
||||||
|
|||||||
@ -129,6 +129,7 @@ use crate::block::blocks::signs::SignBlock;
|
|||||||
use crate::block::blocks::slabs::SlabBlock;
|
use crate::block::blocks::slabs::SlabBlock;
|
||||||
use crate::block::blocks::slime::SlimeBlock;
|
use crate::block::blocks::slime::SlimeBlock;
|
||||||
use crate::block::blocks::snow::LayeredSnowBlock;
|
use crate::block::blocks::snow::LayeredSnowBlock;
|
||||||
|
use crate::block::blocks::brushable_block::BrushableBlock;
|
||||||
use crate::block::blocks::sniffer_egg::SnifferEggBlock;
|
use crate::block::blocks::sniffer_egg::SnifferEggBlock;
|
||||||
use crate::block::blocks::spawner::SpawnerBlock;
|
use crate::block::blocks::spawner::SpawnerBlock;
|
||||||
use crate::block::blocks::sponge::{SpongeBlock, WetSpongeBlock};
|
use crate::block::blocks::sponge::{SpongeBlock, WetSpongeBlock};
|
||||||
@ -258,6 +259,7 @@ pub fn default_registry() -> Arc<BlockRegistry> {
|
|||||||
manager.register(DecoratedPotBlock);
|
manager.register(DecoratedPotBlock);
|
||||||
manager.register(CreakingHeartBlock);
|
manager.register(CreakingHeartBlock);
|
||||||
manager.register(SnifferEggBlock);
|
manager.register(SnifferEggBlock);
|
||||||
|
manager.register(BrushableBlock);
|
||||||
manager.register(BushBlock);
|
manager.register(BushBlock);
|
||||||
manager.register(FlowerBlock);
|
manager.register(FlowerBlock);
|
||||||
manager.register(PotatoBlock);
|
manager.register(PotatoBlock);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user