chore: less awaits more fun

This commit is contained in:
Alexander Medvedev 2026-05-14 12:28:43 +02:00
parent c8633b78d7
commit 92abb1e44e
350 changed files with 3888 additions and 4927 deletions

4
Cargo.lock generated
View File

@ -886,9 +886,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crossfire"
version = "3.1.10"
version = "3.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebed7d0a3a92ebc771f880516a5eecef5942a0fc67855dc4f30e719b04c77ac5"
checksum = "72bdfcf389b100bb85fcf39ad434f67b617813cf0608095c905b79f6b2194aea"
dependencies = [
"crossbeam-utils",
"futures-core",

View File

@ -120,7 +120,7 @@ console-subscriber = { version = "0.5.0", default-features = false }
crc-fast = "1.10.0"
criterion = { version = "0.8", default-features = false }
crossbeam-utils = "0.8.21"
crossfire = { version = "3.1.10", features = ["compat"] }
crossfire = { version = "3.1.12", features = ["compat"] }
crypto-bigint = "0.7.3"
dashmap = "6.1"
ecdsa = "0.16.9"

View File

@ -15,8 +15,6 @@ use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::HeightMap;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::math::vector3::Vector3;
use std::future::Future;
use std::pin::Pin;
use tracing::debug;
pub struct Cache {
@ -45,35 +43,21 @@ impl HeightLimitView for Cache {
}
impl BlockAccessor for Cache {
fn get_block<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = &'static Block> + Send + 'a>> {
Box::pin(async move { GenerationCache::get_block_state(self, &position.0).to_block() })
fn get_block(&self, position: &BlockPos) -> &'static Block {
GenerationCache::get_block_state(self, &position.0).to_block()
}
fn get_block_state<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = &'static BlockState> + Send + 'a>> {
Box::pin(async move { GenerationCache::get_block_state(self, &position.0).to_state() })
fn get_block_state(&self, position: &BlockPos) -> &'static BlockState {
GenerationCache::get_block_state(self, &position.0).to_state()
}
fn get_block_state_id<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = BlockStateId> + Send + 'a>> {
Box::pin(async move { GenerationCache::get_block_state(self, &position.0).0 })
fn get_block_state_id(&self, position: &BlockPos) -> BlockStateId {
GenerationCache::get_block_state(self, &position.0).0
}
fn get_block_and_state<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = (&'static Block, &'static BlockState)> + Send + 'a>> {
Box::pin(async move {
let id = GenerationCache::get_block_state(self, &position.0);
(id.to_block(), id.to_state())
})
fn get_block_and_state(&self, position: &BlockPos) -> (&'static Block, &'static BlockState) {
let state = GenerationCache::get_block_state(self, &position.0);
(state.to_block(), state.to_state())
}
}

View File

@ -1,4 +1,3 @@
use std::pin::Pin;
use std::sync::Arc;
use pumpkin_data::block_properties::is_air;
@ -1362,34 +1361,20 @@ impl ProtoChunk {
}
impl BlockAccessor for ProtoChunk {
fn get_block<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = &'static Block> + Send + 'a>> {
Box::pin(async move { self.get_block_state(&position.0).to_block() })
fn get_block(&self, position: &BlockPos) -> &'static Block {
self.get_block_state(&position.0).to_block()
}
fn get_block_state<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = &'static BlockState> + Send + 'a>> {
Box::pin(async move { self.get_block_state(&position.0).to_state() })
fn get_block_state(&self, position: &BlockPos) -> &'static BlockState {
self.get_block_state(&position.0).to_state()
}
fn get_block_state_id<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = BlockStateId> + Send + 'a>> {
Box::pin(async move { self.get_block_state(&position.0).0 })
fn get_block_state_id(&self, position: &BlockPos) -> BlockStateId {
self.get_block_state(&position.0).0
}
fn get_block_and_state<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = (&'static Block, &'static BlockState)> + Send + 'a>> {
Box::pin(async move {
let id = self.get_block_state(&position.0);
BlockState::from_id_with_block(id.0)
})
fn get_block_and_state(&self, position: &BlockPos) -> (&'static Block, &'static BlockState) {
let id = self.get_block_state(&position.0);
BlockState::from_id_with_block(id.0)
}
}

View File

@ -711,20 +711,6 @@ impl Level {
RawBlockState(id.unwrap_or(Block::VOID_AIR.default_state.id))
}
pub async fn get_rough_biome(self: &Arc<Self>, position: &BlockPos) -> &'static Biome {
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
let id = self
.get_or_fetch_chunk(chunk_coordinate, |chunk| {
chunk.section.get_rough_biome_absolute_y(
relative.x as usize,
relative.y,
relative.z as usize,
)
})
.await;
Biome::from_id(id.unwrap_or(0)).unwrap_or(&Biome::THE_VOID)
}
pub async fn set_block_state(
self: &Arc<Self>,
position: &BlockPos,
@ -798,6 +784,18 @@ impl Level {
self.loaded_chunks.get(coordinates).map(|x| f(x.value()))
}
pub fn get_rough_biome(&self, position: &BlockPos) -> &'static Biome {
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
let id = self.read_chunk_sync(&chunk_coordinate, |chunk| {
chunk.section.get_rough_biome_absolute_y(
relative.x as usize,
relative.y,
relative.z as usize,
)
});
Biome::from_id(id.flatten().unwrap_or(0)).unwrap_or(&Biome::THE_VOID)
}
pub fn read_entity_chunk_sync<R, F: Fn(&SyncEntityChunk) -> R>(
&self,
coordinates: &Vector2<i32>,
@ -808,6 +806,12 @@ impl Level {
.map(|x| f(x.value()))
}
pub fn get_entity_chunk_sync(&self, pos: &Vector2<i32>) -> Option<SyncEntityChunk> {
self.loaded_entity_chunks
.get(pos)
.map(|x| x.value().clone())
}
pub async fn get_or_fetch_entity_chunk<R, F: Fn(&SyncEntityChunk) -> R>(
self: &Arc<Self>,
pos: Vector2<i32>,

View File

@ -445,6 +445,50 @@ impl DynamicLightEngine {
}
}
pub fn get_block_light_level_sync(&self, level: &Level, position: &BlockPos) -> Option<u8> {
let (chunk_pos, relative) = position.chunk_and_chunk_relative_position();
level.read_chunk_sync(&chunk_pos, |chunk| {
let section_idx = (relative.y - chunk.section.min_y) as usize / 16;
let light_engine = chunk.light_engine.lock().ok()?;
light_engine
.block_light
.get(section_idx)?
.get(
relative.x as usize,
(relative.y - chunk.section.min_y) as usize % 16,
relative.z as usize,
)
.into()
})?
}
pub fn get_sky_light_level_sync(&self, level: &Level, position: &BlockPos) -> u8 {
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
level
.read_chunk_sync(&chunk_coordinate, |chunk| {
let section_index =
(relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
let light_engine = chunk
.light_engine
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
// Bounds check for section index (lock the light engine)
if section_index >= light_engine.sky_light.len() {
return 15;
}
light_engine.sky_light[section_index].get(
relative.x as usize,
(relative.y - chunk.section.min_y) as usize % BlockPalette::SIZE,
relative.z as usize,
)
})
.unwrap_or(0)
}
pub async fn get_block_light_level(
&self,
level: &Arc<Level>,

View File

@ -74,23 +74,11 @@ pub trait WorldPortalExt: Send + Sync {
}
pub trait BlockAccessor: Send + Sync {
fn get_block<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = &'static Block> + Send + 'a>>;
fn get_block(&self, position: &BlockPos) -> &'static Block;
fn get_block_state<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = &'static BlockState> + Send + 'a>>;
fn get_block_state(&self, position: &BlockPos) -> &'static BlockState;
fn get_block_state_id<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = BlockStateId> + Send + 'a>>;
fn get_block_state_id(&self, position: &BlockPos) -> BlockStateId;
fn get_block_and_state<'a>(
&'a self,
position: &'a BlockPos,
) -> Pin<Box<dyn Future<Output = (&'static Block, &'static BlockState)> + Send + 'a>>;
fn get_block_and_state(&self, position: &BlockPos) -> (&'static Block, &'static BlockState);
}

View File

@ -53,12 +53,10 @@ pub trait WallMountedBlock: Send + Sync {
world: &'a dyn BlockAccessor,
pos: &'a BlockPos,
direction: BlockDirection,
) -> BlockFuture<'a, bool> {
Box::pin(async move {
let block_pos = pos.offset(direction.to_offset());
let block_state = world.get_block_state(&block_pos).await;
block_state.is_side_solid(direction.opposite())
})
) -> bool {
let block_pos = pos.offset(direction.to_offset());
let block_state = world.get_block_state(&block_pos);
block_state.is_side_solid(direction.opposite())
}
fn get_state_for_neighbor_update<'a>(
@ -67,9 +65,7 @@ pub trait WallMountedBlock: Send + Sync {
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if self.get_direction(args.state_id, args.block).opposite() == args.direction
&& !self
.can_place_at(args.world, args.position, args.direction)
.await
&& !self.can_place_at(args.world, args.position, args.direction)
{
Block::AIR.default_state.id
} else {

View File

@ -21,13 +21,13 @@ impl BlockBehaviour for BannerBlock {
})
}
fn can_place_at<'a>(&'a self, args: crate::block::CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: crate::block::CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -40,7 +40,7 @@ impl BlockBehaviour for BannerBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -50,7 +50,7 @@ impl BlockBehaviour for BannerBlock {
}
}
async fn can_place_at(world: &dyn BlockAccessor, position: &BlockPos) -> bool {
let state = world.get_block_state(&position.down()).await;
fn can_place_at(world: &dyn BlockAccessor, position: &BlockPos) -> bool {
let state = world.get_block_state(&position.down());
state.is_solid()
}

View File

@ -60,7 +60,7 @@ impl BlockBehaviour for BarrelBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.get_inventory()
{
args.player

View File

@ -51,7 +51,7 @@ pub struct BeaconBlock;
impl BlockBehaviour for BeaconBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let block_entity = args.world.get_block_entity(args.position).await;
let block_entity = args.world.get_block_entity(args.position);
// Extract the inventory from the entity
let Some(inventory) = block_entity.and_then(BlockEntity::get_inventory) else {

View File

@ -70,23 +70,19 @@ const NO_SLEEP_IDS: &[u16] = &[
pub struct BedBlock;
impl BlockBehaviour for BedBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
if let Some(player) = args.player {
let facing = player.living_entity.entity.get_horizontal_facing();
return args
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
if let Some(player) = args.player {
let facing = player.living_entity.entity.get_horizontal_facing();
return args
.block_accessor
.get_block_state(args.position)
.replaceable()
&& args
.block_accessor
.get_block_state(args.position)
.await
.replaceable()
&& args
.block_accessor
.get_block_state(&args.position.offset(facing.to_offset()))
.await
.replaceable();
}
false
})
.get_block_state(&args.position.offset(facing.to_offset()))
.replaceable();
}
false
}
fn on_landed_upon<'a>(&'a self, args: OnLandedUponArgs<'a>) -> BlockFuture<'a, ()> {
@ -150,7 +146,7 @@ impl BlockBehaviour for BedBlock {
args.position.offset(bed_props.facing.to_offset())
};
let neighbor_block_id = args.world.get_block_state_id(&other_half_pos).await;
let neighbor_block_id = args.world.get_block_state_id(&other_half_pos);
if neighbor_block_id != args.block.id {
args.world.update_neighbors(&other_half_pos, None).await;
return;
@ -180,7 +176,7 @@ impl BlockBehaviour for BedBlock {
// If the block is being replaced with air (i.e., broken), the `broken` callback
// will handle breaking the other half with the correct drop flags. Only handle it here
// if the block is being replaced with something else (e.g., piston movement).
let new_state_id = args.world.get_block_state_id(args.position).await;
let new_state_id = args.world.get_block_state_id(args.position);
let new_block = Block::from_state_id(new_state_id);
if new_block == &Block::AIR {
return;
@ -194,7 +190,7 @@ impl BlockBehaviour for BedBlock {
args.position.offset(bed_props.facing.to_offset())
};
let (other_block, other_state) = args.world.get_block_and_state(&other_half_pos).await;
let (other_block, other_state) = args.world.get_block_and_state(&other_half_pos);
if other_block == args.block {
let other_props = BedProperties::from_state_id(other_state.id, other_block);
if other_props.part != bed_props.part {
@ -213,7 +209,7 @@ impl BlockBehaviour for BedBlock {
#[expect(clippy::too_many_lines)]
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let bed_props = BedProperties::from_state_id(state_id, args.block);
let (bed_head_pos, bed_foot_pos) = if bed_props.part == BedPart::Head {
@ -246,16 +242,8 @@ impl BlockBehaviour for BedBlock {
}
// Make sure the bed is not obstructed
if args
.world
.get_block_state(&bed_head_pos.up())
.await
.is_solid()
|| args
.world
.get_block_state(&bed_foot_pos.up())
.await
.is_solid()
if args.world.get_block_state(&bed_head_pos.up()).is_solid()
|| args.world.get_block_state(&bed_foot_pos.up()).is_solid()
{
args.player
.send_system_message_raw(
@ -370,7 +358,7 @@ impl BlockBehaviour for BedBlock {
}
}
args.player.sleep(bed_head_pos).await;
args.player.sleep(bed_head_pos);
Self::set_occupied(true, args.world, args.block, args.position, state_id).await;
BlockActionResult::SuccessServer

View File

@ -86,7 +86,7 @@ pub struct BlastFurnaceBlock;
impl BlockBehaviour for BlastFurnaceBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.clone().get_inventory()
&& let Some(property_delegate) = block_entity.clone().to_property_delegate()
&& let Some(experience_container) = block_entity.to_experience_container()
@ -130,7 +130,7 @@ impl BlockBehaviour for BlastFurnaceBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
// Extract and drop accumulated XP as orbs before removing the block entity
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(experience_container) = block_entity.to_experience_container()
{
let xp = experience_container.extract_experience();

View File

@ -52,7 +52,7 @@ pub struct BrewingStandBlock;
impl BlockBehaviour for BrewingStandBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.clone().get_inventory()
&& let Some(pd) = block_entity.clone().to_property_delegate()
{

View File

@ -84,15 +84,15 @@ impl CakeBlock {
impl BlockBehaviour for CakeBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
return Block::AIR.default_state.id;
}
Block::CAKE.default_state.id
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn use_with_item<'a>(
@ -100,7 +100,7 @@ impl BlockBehaviour for CakeBlock {
args: UseWithItemArgs<'a>,
) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let properties = CakeLikeProperties::from_state_id(state_id, args.block);
let item_lock = args.item_stack.lock().await;
let item = item_lock.item;
@ -159,7 +159,7 @@ impl BlockBehaviour for CakeBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
Self::consume_if_hungry(args.world, args.player, args.block, args.position, state_id)
.await
})
@ -167,7 +167,7 @@ impl BlockBehaviour for CakeBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -180,7 +180,7 @@ impl BlockBehaviour for CakeBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -190,7 +190,7 @@ impl BlockBehaviour for CakeBlock {
}
}
async fn can_place_at(world: &dyn BlockAccessor, position: &BlockPos) -> bool {
let state = world.get_block_state(&position.down()).await;
fn can_place_at(world: &dyn BlockAccessor, position: &BlockPos) -> bool {
let state = world.get_block_state(&position.down());
state.is_solid()
}

View File

@ -66,7 +66,7 @@ impl BlockBehaviour for CampfireBlock {
CampfireLikeProperties::from_state_id(args.block.default_state.id, args.block);
props.waterlogged = is_replacing_water;
props.signal_fire =
is_signal_fire_base_block(args.world.get_block(&args.position.down()).await);
is_signal_fire_base_block(args.world.get_block(&args.position.down()));
props.lit = !is_replacing_water;
props.facing = args.player.get_entity().get_horizontal_facing();
props.to_state_id(args.block)
@ -93,7 +93,7 @@ impl BlockBehaviour for CampfireBlock {
if args.direction == BlockDirection::Down {
props.signal_fire =
is_signal_fire_base_block(args.world.get_block(args.neighbor_position).await);
is_signal_fire_base_block(args.world.get_block(args.neighbor_position));
}
props.to_state_id(args.block)

View File

@ -92,7 +92,7 @@ impl CandleCakeBlock {
)
.await;
let (block, state) = world.get_block_and_state_id(location).await;
let (block, state) = world.get_block_and_state_id(location);
CakeBlock::consume_if_hungry(world, player, block, location, state).await
}
@ -122,7 +122,7 @@ impl BlockBehaviour for CandleCakeBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -135,7 +135,7 @@ impl BlockBehaviour for CandleCakeBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -145,7 +145,7 @@ impl BlockBehaviour for CandleCakeBlock {
}
}
async fn can_place_at(world: &dyn BlockAccessor, position: &BlockPos) -> bool {
let state = world.get_block_state(&position.down()).await;
fn can_place_at(world: &dyn BlockAccessor, position: &BlockPos) -> bool {
let state = world.get_block_state(&position.down());
state.is_solid()
}

View File

@ -50,7 +50,7 @@ impl BlockBehaviour for CandleBlock {
args: UseWithItemArgs<'a>,
) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
let mut properties = CandleLikeProperties::from_state_id(state.id, args.block);
let item_lock = args.item_stack.lock().await;
@ -102,7 +102,7 @@ impl BlockBehaviour for CandleBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let mut properties = CandleLikeProperties::from_state_id(state_id, args.block);
if properties.lit {
@ -121,22 +121,20 @@ impl BlockBehaviour for CandleBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn can_update_at<'a>(&'a self, args: CanUpdateAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let b = args.world.get_block(args.position).await;
args.player.get_entity().pose.load() != EntityPose::Crouching
&& CandleLikeProperties::from_state_id(args.state_id, args.block).candles != 4
&& args.block.id == b.id
})
fn can_update_at(&self, args: CanUpdateAtArgs<'_>) -> bool {
let b = BlockAccessor::get_block(args.world, args.position);
args.player.get_entity().pose.load() != EntityPose::Crouching
&& CandleLikeProperties::from_state_id(args.state_id, args.block).candles != 4
&& args.block.id == b.id
}
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -149,7 +147,7 @@ impl BlockBehaviour for CandleBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -159,7 +157,7 @@ impl BlockBehaviour for CandleBlock {
}
}
async fn can_place_at(block_accessor: &dyn BlockAccessor, position: &BlockPos) -> bool {
let (support_block, state) = block_accessor.get_block_and_state(&position.down()).await;
fn can_place_at(block_accessor: &dyn BlockAccessor, position: &BlockPos) -> bool {
let (support_block, state) = block_accessor.get_block_and_state(&position.down());
!support_block.is_waterlogged(state.id) && state.is_center_solid(BlockDirection::Up)
}

View File

@ -12,8 +12,8 @@ use pumpkin_world::world::{BlockAccessor, BlockFlags};
pub struct CarpetBlock;
impl BlockBehaviour for CarpetBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -21,7 +21,7 @@ impl BlockBehaviour for CarpetBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -32,7 +32,7 @@ impl BlockBehaviour for CarpetBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -45,8 +45,8 @@ impl BlockBehaviour for CarpetBlock {
pub struct MossCarpetBlock;
impl BlockBehaviour for MossCarpetBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -54,7 +54,7 @@ impl BlockBehaviour for MossCarpetBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -65,7 +65,7 @@ impl BlockBehaviour for MossCarpetBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -78,8 +78,8 @@ impl BlockBehaviour for MossCarpetBlock {
pub struct PaleMossCarpetBlock;
impl BlockBehaviour for PaleMossCarpetBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -87,7 +87,7 @@ impl BlockBehaviour for PaleMossCarpetBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -98,7 +98,7 @@ impl BlockBehaviour for PaleMossCarpetBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -107,6 +107,6 @@ impl BlockBehaviour for PaleMossCarpetBlock {
}
}
async fn can_place_at(block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
!is_air(block_accessor.get_block_state_id(&block_pos.down()).await)
fn can_place_at(block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
!is_air(block_accessor.get_block_state_id(&block_pos.down()))
}

View File

@ -40,8 +40,8 @@ impl BlockBehaviour for CarvedPumpkinBlock {
// Mojang uses some BlockPattern magic, way too complex tbh
Box::pin(async {
let down_pos = args.position.down();
let upper = args.world.get_block(&down_pos).await;
let lower = args.world.get_block(&down_pos.down()).await;
let upper = args.world.get_block(&down_pos);
let lower = args.world.get_block(&down_pos.down());
if upper == &Block::SNOW_BLOCK && lower == &Block::SNOW_BLOCK {
for i in 0..3 {
let pos = args.position.down_height(i);
@ -52,20 +52,18 @@ impl BlockBehaviour for CarvedPumpkinBlock {
BlockFlags::NOTIFY_LISTENERS,
)
.await;
args.world
.sync_world_event(
WorldEvent::ParticlesDestroyBlock,
pos,
Block::SNOW_BLOCK.default_state.id.into(),
)
.await;
args.world.sync_world_event(
WorldEvent::ParticlesDestroyBlock,
pos,
Block::SNOW_BLOCK.default_state.id.into(),
);
}
let entity = Entity::new(
args.world.clone(),
down_pos.down().to_centered_f64(),
&EntityType::SNOW_GOLEM,
);
let golem = SnowGolemEntity::new(entity).await;
let golem = SnowGolemEntity::new(entity);
args.world.spawn_entity(golem).await;
return;
}
@ -76,8 +74,8 @@ impl BlockBehaviour for CarvedPumpkinBlock {
let arm1 = down_pos.offset(dir.to_offset());
let arm2 = down_pos.offset(opposite.to_offset());
if args.world.get_block(&arm1).await == &Block::IRON_BLOCK
&& args.world.get_block(&arm2).await == &Block::IRON_BLOCK
if args.world.get_block(&arm1) == &Block::IRON_BLOCK
&& args.world.get_block(&arm2) == &Block::IRON_BLOCK
{
let pattern = [*args.position, down_pos, down_pos.down(), arm1, arm2];
@ -89,13 +87,11 @@ impl BlockBehaviour for CarvedPumpkinBlock {
BlockFlags::NOTIFY_LISTENERS,
)
.await;
args.world
.sync_world_event(
WorldEvent::ParticlesDestroyBlock,
p,
Block::IRON_BLOCK.default_state.id.into(),
)
.await;
args.world.sync_world_event(
WorldEvent::ParticlesDestroyBlock,
p,
Block::IRON_BLOCK.default_state.id.into(),
);
}
let entity = Entity::new(
@ -103,7 +99,7 @@ impl BlockBehaviour for CarvedPumpkinBlock {
down_pos.down().to_centered_f64(),
&EntityType::IRON_GOLEM,
);
let golem = IronGolemEntity::new(entity).await;
let golem = IronGolemEntity::new(entity);
args.world.spawn_entity(golem).await;
return;
}

View File

@ -2,7 +2,6 @@ use std::sync::Arc;
use crate::block::entities::BlockEntity;
use crate::block::entities::chest::ChestBlockEntity;
use futures::future::join;
use pumpkin_data::block_properties::{
BlockProperties, ChestLikeProperties, ChestType, HorizontalFacing,
};
@ -75,7 +74,7 @@ impl ScreenHandlerFactory for ChestScreenFactory {
// Shared chest behavior implementations
const LID_ANIMATION_EVENT_TYPE: u8 = 1;
async fn on_place_chest_impl(args: OnPlaceArgs<'_>) -> BlockStateId {
fn on_place_chest_impl(args: &OnPlaceArgs<'_>) -> BlockStateId {
let mut chest_props = ChestLikeProperties::default(args.block);
chest_props.waterlogged = args.replacing.water_source();
@ -85,8 +84,7 @@ async fn on_place_chest_impl(args: OnPlaceArgs<'_>) -> BlockStateId {
args.block,
args.position,
args.direction,
)
.await;
);
chest_props.facing = facing;
chest_props.r#type = r#type;
@ -114,9 +112,7 @@ async fn placed_chest_impl<E: BlockEntity + 'static>(
chest_props.facing,
connected_towards,
ChestType::Single,
)
.await
{
) {
neighbor_props.r#type = chest_props.r#type.opposite();
args.world
@ -130,11 +126,8 @@ async fn placed_chest_impl<E: BlockEntity + 'static>(
}
async fn normal_use_chest_impl(args: NormalUseArgs<'_>) -> BlockActionResult {
let (state, first_chest) = join(
args.world.get_block_state_id(args.position),
args.world.get_block_entity(args.position),
)
.await;
let state = args.world.get_block_state_id(args.position);
let first_chest = args.world.get_block_entity(args.position);
let Some(first_inventory) = first_chest.and_then(BlockEntity::get_inventory) else {
return BlockActionResult::Fail;
@ -147,13 +140,13 @@ async fn normal_use_chest_impl(args: NormalUseArgs<'_>) -> BlockActionResult {
ChestType::Right => Some(chest_props.facing.rotate_counter_clockwise()),
};
if is_chest_blocked(args.world, args.position).await {
if is_chest_blocked(args.world, args.position) {
return BlockActionResult::Success;
}
if let Some(direction) = connected_towards {
let neighbor_pos = args.position.offset(direction.to_offset());
if is_chest_blocked(args.world, &neighbor_pos).await {
if is_chest_blocked(args.world, &neighbor_pos) {
return BlockActionResult::Success;
}
}
@ -162,7 +155,6 @@ async fn normal_use_chest_impl(args: NormalUseArgs<'_>) -> BlockActionResult {
&& let Some(second_inventory) = args
.world
.get_block_entity(&args.position.offset(direction.to_offset()))
.await
.and_then(BlockEntity::get_inventory)
{
// Vanilla: chestType == ChestType.RIGHT ? DoubleBlockProperties.Type.FIRST : DoubleBlockProperties.Type.SECOND;
@ -197,9 +189,7 @@ async fn broken_chest_impl(args: BrokenArgs<'_>) {
chest_props.facing,
connected_towards,
chest_props.r#type.opposite(),
)
.await
{
) {
neighbor_props.r#type = ChestType::Single;
args.world
@ -217,7 +207,7 @@ pub struct ChestBlock;
impl BlockBehaviour for ChestBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(on_place_chest_impl(args))
Box::pin(async move { on_place_chest_impl(&args) })
}
fn on_synced_block_event<'a>(
@ -246,7 +236,7 @@ pub struct CopperChestBlock;
impl BlockBehaviour for CopperChestBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(on_place_chest_impl(args))
Box::pin(async move { on_place_chest_impl(&args) })
}
fn on_synced_block_event<'a>(
@ -270,7 +260,7 @@ impl BlockBehaviour for CopperChestBlock {
fn random_tick<'a>(&'a self, args: RandomTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let current_state_id = args.world.get_block_state_id(args.position).await;
let current_state_id = args.world.get_block_state_id(args.position);
let chest_props = ChestLikeProperties::from_state_id(current_state_id, args.block);
// Only oxidize LEFT or SINGLE chests (not RIGHT) to prevent double oxidation
@ -279,7 +269,7 @@ impl BlockBehaviour for CopperChestBlock {
}
// Only oxidize if no players are viewing the chest
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(chest_entity) = block_entity.as_any().downcast_ref::<ChestBlockEntity>()
&& chest_entity.get_viewer_count() > 0
{
@ -355,7 +345,7 @@ async fn try_oxidize_copper_chest(
// Scan neighbors in 4-block Manhattan distance to calculate oxidation chance
let (same_level_count, higher_level_count) =
count_neighbor_oxidation_levels(world, position, current_level).await;
count_neighbor_oxidation_levels(world, position, current_level);
// If we found any neighbors at a LOWER level, oxidation is blocked
// (This is handled in count_neighbor_oxidation_levels by returning early)
@ -380,7 +370,7 @@ async fn try_oxidize_copper_chest(
/// Count copper blocks at same and higher oxidation levels within 4-block Manhattan distance.
/// Returns (same, higher) counts, or (0, 0) if a lower-level neighbor was found (blocking oxidation).
async fn count_neighbor_oxidation_levels(
fn count_neighbor_oxidation_levels(
world: &Arc<World>,
center: &BlockPos,
current_level: u8,
@ -405,7 +395,7 @@ async fn count_neighbor_oxidation_levels(
center.0.z + dz,
));
let neighbor_block = world.get_block(&neighbor_pos).await;
let neighbor_block = world.get_block(&neighbor_pos);
if let Some(neighbor_level) = get_oxidation_level(neighbor_block) {
match neighbor_level.cmp(&current_level) {
@ -434,7 +424,7 @@ pub struct TrappedChestBlock;
impl BlockBehaviour for TrappedChestBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(on_place_chest_impl(args))
Box::pin(async move { on_place_chest_impl(&args) })
}
fn on_synced_block_event<'a>(
@ -473,7 +463,7 @@ impl BlockBehaviour for TrappedChestBlock {
// Get viewer count from this chest
let viewer_count = if let Some(block_entity) =
args.world.get_block_entity(args.position).await
args.world.get_block_entity(args.position)
&& let Some(trapped_chest) = block_entity
.as_any()
.downcast_ref::<TrappedChestBlockEntity>()
@ -503,7 +493,7 @@ impl BlockBehaviour for TrappedChestBlock {
}
}
async fn compute_chest_props(
fn compute_chest_props(
world: &World,
player: &Player,
block: &Block,
@ -518,9 +508,8 @@ async fn compute_chest_props(
return (ChestType::Single, chest_facing);
};
let (clicked_block, clicked_block_state) = world
.get_block_and_state_id(&block_pos.offset(face.to_offset()))
.await;
let (clicked_block, clicked_block_state) =
world.get_block_and_state_id(&block_pos.offset(face.to_offset()));
if clicked_block == block {
let clicked_props =
@ -548,7 +537,6 @@ async fn compute_chest_props(
chest_facing.rotate_clockwise(),
ChestType::Single,
)
.await
.is_some()
{
(ChestType::Left, chest_facing)
@ -560,7 +548,6 @@ async fn compute_chest_props(
chest_facing.rotate_counter_clockwise(),
ChestType::Single,
)
.await
.is_some()
{
(ChestType::Right, chest_facing)
@ -569,7 +556,7 @@ async fn compute_chest_props(
}
}
async fn get_chest_properties_if_can_connect(
fn get_chest_properties_if_can_connect(
world: &World,
block: &Block,
block_pos: &BlockPos,
@ -577,9 +564,8 @@ async fn get_chest_properties_if_can_connect(
direction: HorizontalFacing,
wanted_type: ChestType,
) -> Option<ChestLikeProperties> {
let (neighbor_block, neighbor_block_state) = world
.get_block_and_state_id(&block_pos.offset(direction.to_offset()))
.await;
let (neighbor_block, neighbor_block_state) =
world.get_block_and_state_id(&block_pos.offset(direction.to_offset()));
if neighbor_block != block {
return None;
@ -593,13 +579,13 @@ async fn get_chest_properties_if_can_connect(
None
}
async fn is_chest_blocked(world: &World, block_pos: &BlockPos) -> bool {
fn is_chest_blocked(world: &World, block_pos: &BlockPos) -> bool {
// TODO: Block opening when a cat is sitting on top.
has_block_on_top(world, block_pos).await
has_block_on_top(world, block_pos)
}
async fn has_block_on_top(world: &World, block_pos: &BlockPos) -> bool {
fn has_block_on_top(world: &World, block_pos: &BlockPos) -> bool {
let above_pos = block_pos.up();
let above_state = world.get_block_state(&above_pos).await;
let above_state = world.get_block_state(&above_pos);
above_state.is_solid_block()
}

View File

@ -41,12 +41,12 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
let properties = ChiseledBookshelfLikeProperties::from_state_id(state.id, args.block);
if let Some(slot) = Self::get_slot_for_hit(args.hit, properties.facing) {
if Self::is_slot_used(properties, slot) {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(block_entity) = block_entity
.as_any()
.downcast_ref::<ChiseledBookshelfBlockEntity>()
@ -75,7 +75,7 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
args: UseWithItemArgs<'a>,
) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
let properties = ChiseledBookshelfLikeProperties::from_state_id(state.id, args.block);
if !args
@ -90,7 +90,7 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
if let Some(slot) = Self::get_slot_for_hit(args.hit, properties.facing) {
if Self::is_slot_used(properties, slot) {
return BlockActionResult::PassToDefaultBlockAction;
} else if let Some(block_entity) = args.world.get_block_entity(args.position).await
} else if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(block_entity) = block_entity
.as_any()
.downcast_ref::<ChiseledBookshelfBlockEntity>()
@ -125,7 +125,7 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
args: GetComparatorOutputArgs<'a>,
) -> BlockFuture<'a, Option<u8>> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(block_entity) = block_entity
.as_any()
.downcast_ref::<ChiseledBookshelfBlockEntity>()
@ -164,9 +164,7 @@ impl ChiseledBookshelfBlock {
.await;
entity.update_state(properties, world.clone(), slot).await;
world
.play_sound(sound, SoundCategory::Blocks, &position.to_centered_f64())
.await;
world.play_sound(sound, SoundCategory::Blocks, &position.to_centered_f64());
}
async fn try_remove_book(
@ -195,9 +193,7 @@ impl ChiseledBookshelfBlock {
}
entity.update_state(properties, world.clone(), slot).await;
world
.play_sound(sound, SoundCategory::Blocks, &position.to_centered_f64())
.await;
world.play_sound(sound, SoundCategory::Blocks, &position.to_centered_f64());
}
fn get_slot_for_hit(hit: &BlockHitResult<'_>, facing: HorizontalFacing) -> Option<i8> {

View File

@ -23,13 +23,13 @@ use tracing::warn;
pub struct CommandBlock;
impl CommandBlock {
async fn get_relative_facing(
fn get_relative_facing(
world: &World,
pos: &BlockPos,
dir: Facing,
) -> Option<(BlockPos, CommandBlockLikeProperties)> {
let target_pos = pos.offset(dir.to_block_direction().to_offset());
let block = world.get_block(&target_pos).await;
let block = world.get_block(&target_pos);
let allowed_blocks = [
Block::COMMAND_BLOCK.name,
@ -40,24 +40,24 @@ impl CommandBlock {
return None;
}
let state_id = world.get_block_state_id(&target_pos).await;
let state_id = world.get_block_state_id(&target_pos);
let props = CommandBlockLikeProperties::from_state_id(state_id, block);
Some((target_pos, props))
}
async fn conditions_met(world: &Arc<World>, pos: &BlockPos, facing: Facing) -> bool {
let (block, state_id) = world.get_block_and_state_id(pos).await;
fn conditions_met(world: &Arc<World>, pos: &BlockPos, facing: Facing) -> bool {
let (block, state_id) = world.get_block_and_state_id(pos);
let props = CommandBlockLikeProperties::from_state_id(state_id, block);
if !props.conditional {
return true;
}
let Some(before) = Self::get_relative_facing(world, pos, facing.opposite()).await else {
let Some(before) = Self::get_relative_facing(world, pos, facing.opposite()) else {
return false;
};
let Some(before_entity) = world.get_block_entity(&before.0).await else {
let Some(before_entity) = world.get_block_entity(&before.0) else {
warn!("Command block has no matching entity");
return false;
};
@ -83,7 +83,7 @@ impl CommandBlock {
return;
}
let state_id = world.get_block_state_id(pos).await;
let state_id = world.get_block_state_id(pos);
let props = CommandBlockLikeProperties::from_state_id(state_id, block);
if !props.conditional {
@ -93,11 +93,10 @@ impl CommandBlock {
return;
}
let Some(behind) = Self::get_relative_facing(world, pos, props.facing.opposite()).await
else {
let Some(behind) = Self::get_relative_facing(world, pos, props.facing.opposite()) else {
return;
};
let Some(behind_entity) = world.get_block_entity(&behind.0).await else {
let Some(behind_entity) = world.get_block_entity(&behind.0) else {
warn!(
"Command Block exists at {} with no matching block entity!",
behind.0
@ -159,12 +158,12 @@ impl CommandBlock {
if !command_blocks_work {
return;
}
let block = world.get_block(&pos).await;
let block = world.get_block(&pos);
if block.id != Block::CHAIN_COMMAND_BLOCK.id {
break;
}
let Some(block_entity) = world.get_block_entity(&pos).await else {
let Some(block_entity) = world.get_block_entity(&pos) else {
warn!("Missing command block entity");
break;
};
@ -172,14 +171,14 @@ impl CommandBlock {
let command_entity: &CommandBlockEntity = block_entity.as_any().downcast_ref().unwrap();
let powered = command_entity.powered.load(Ordering::Relaxed);
let auto = command_entity.auto.load(Ordering::Relaxed);
let state_id = world.get_block_state_id(&pos).await;
let state_id = world.get_block_state_id(&pos);
let props = CommandBlockLikeProperties::from_state_id(state_id, block);
if powered || auto {
let conditions_met = Self::conditions_met(&world, &pos, direction).await;
let conditions_met = Self::conditions_met(&world, &pos, direction);
if conditions_met {
let command = command_entity.command.lock().await;
let entity = world.get_block_entity(&pos).await.unwrap();
let entity = world.get_block_entity(&pos).unwrap();
Self::execute(server, world.clone(), entity, &command).await;
} else if props.conditional {
command_entity.success_count.store(0, Ordering::Release);
@ -224,7 +223,7 @@ impl BlockBehaviour for CommandBlock {
if args.player.permission_lvl.load() < PermissionLvl::Two {
return BlockActionResult::Pass;
}
let Some(block_entity) = args.world.get_block_entity(args.position).await else {
let Some(block_entity) = args.world.get_block_entity(args.position) else {
return BlockActionResult::Pass;
};
args.world.update_block_entity(&block_entity).await;
@ -239,7 +238,7 @@ impl BlockBehaviour for CommandBlock {
if !command_blocks_work {
return;
}
if let Some(block_entity) = args.world.get_block_entity(args.position).await {
if let Some(block_entity) = args.world.get_block_entity(args.position) {
if block_entity.resource_location() != CommandBlockEntity::ID {
return;
}
@ -267,7 +266,7 @@ impl BlockBehaviour for CommandBlock {
if !command_blocks_work {
return;
}
let Some(block_entity) = args.world.get_block_entity(args.position).await else {
let Some(block_entity) = args.world.get_block_entity(args.position) else {
return;
};
if block_entity.resource_location() != CommandBlockEntity::ID {
@ -279,7 +278,7 @@ impl BlockBehaviour for CommandBlock {
return;
};
let props = CommandBlockLikeProperties::from_state_id(
args.world.get_block_state_id(args.position).await,
args.world.get_block_state_id(args.position),
args.block,
);
@ -300,7 +299,7 @@ impl BlockBehaviour for CommandBlock {
)
.await;
let block = args.world.get_block(args.position).await;
let block = args.world.get_block(args.position);
let is_auto = command_entity.auto.load(Ordering::Relaxed);
let can_run = command_entity.powered.load(Ordering::Relaxed) || is_auto;
if block == &Block::REPEATING_COMMAND_BLOCK && can_run {
@ -311,16 +310,14 @@ impl BlockBehaviour for CommandBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
if let Some(player) = args.player
&& player.gamemode.load() == GameMode::Creative
{
return true;
}
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
if let Some(player) = args.player
&& player.gamemode.load() == GameMode::Creative
{
return true;
}
false
})
false
}
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
@ -344,7 +341,7 @@ impl BlockBehaviour for CommandBlock {
args: crate::block::GetComparatorOutputArgs<'a>,
) -> BlockFuture<'a, Option<u8>> {
Box::pin(async {
let entity = args.world.get_block_entity(args.position).await;
let entity = args.world.get_block_entity(args.position);
entity.map_or_else(
|| {

View File

@ -29,7 +29,7 @@ pub struct ComposterBlock;
impl BlockBehaviour for ComposterBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let props = ComposterLikeProperties::from_state_id(state_id, args.block);
if props.level == 8 {
self.clear_composter(args.world, args.position, state_id, args.block)
@ -45,7 +45,7 @@ impl BlockBehaviour for ComposterBlock {
args: UseWithItemArgs<'a>,
) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let props = ComposterLikeProperties::from_state_id(state_id, args.block);
let level = props.level;
@ -80,8 +80,7 @@ impl BlockBehaviour for ComposterBlock {
)
.await;
args.world
.sync_world_event(WorldEvent::ComposterFill, *args.position, 1)
.await;
.sync_world_event(WorldEvent::ComposterFill, *args.position, 1);
}
// Consume the item
@ -91,7 +90,7 @@ impl BlockBehaviour for ComposterBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let props = ComposterLikeProperties::from_state_id(state_id, args.block);
let level = props.level;
if level == 7 {
@ -161,8 +160,7 @@ impl ComposterBlock {
let item_entity = ItemEntity::new(
Entity::new(world.clone(), item_position, &EntityType::ITEM),
ItemStack::new(1, &Item::BONE_MEAL),
)
.await;
);
world.spawn_entity(Arc::new(item_entity)).await;
}

View File

@ -32,7 +32,7 @@ impl BlockBehaviour for DirtPathBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
return Block::DIRT.default_state.id;
}
@ -45,9 +45,7 @@ impl BlockBehaviour for DirtPathBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if args.direction == BlockDirection::Up
&& !can_place_at(args.world, args.position).await
{
if args.direction == BlockDirection::Up && !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -56,12 +54,12 @@ impl BlockBehaviour for DirtPathBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
}
async fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let state = world.get_block_state(&block_pos.up()).await;
fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let state = world.get_block_state(&block_pos.up());
!state.is_solid() // TODO: add fence gate block
}

View File

@ -37,7 +37,7 @@ use pumpkin_util::GameMode;
type DoorProperties = pumpkin_data::block_properties::OakDoorLikeProperties;
async fn toggle_door(player: &Player, world: &Arc<World>, block_pos: &BlockPos) {
let (block, block_state) = world.get_block_and_state_id(block_pos).await;
let (block, block_state) = world.get_block_and_state_id(block_pos);
let mut door_props = DoorProperties::from_state_id(block_state, block);
door_props.open = !door_props.open;
@ -47,18 +47,16 @@ async fn toggle_door(player: &Player, world: &Arc<World>, block_pos: &BlockPos)
};
let other_pos = block_pos.offset(other_half.to_offset());
let (other_block, other_state_id) = world.get_block_and_state_id(&other_pos).await;
let (other_block, other_state_id) = world.get_block_and_state_id(&other_pos);
let mut other_door_props = DoorProperties::from_state_id(other_state_id, other_block);
other_door_props.open = door_props.open;
world
.play_block_sound_expect(
player,
get_sound(block, door_props.open),
SoundCategory::Blocks,
*block_pos,
)
.await;
world.play_block_sound_expect(
player,
get_sound(block, door_props.open),
SoundCategory::Blocks,
*block_pos,
);
world
.set_block_state(
@ -114,24 +112,22 @@ async fn get_hinge(
let top_pos = pos.up();
let left_dir = facing.rotate_counter_clockwise();
let left_pos = pos.offset(left_dir.to_block_direction().to_offset());
let (left_block, left_state) = world.get_block_and_state(&left_pos).await;
let (left_block, left_state) = world.get_block_and_state(&left_pos);
let top_facing = top_pos.offset(facing.to_block_direction().to_offset());
let top_state = world.get_block_state(&top_facing).await;
let top_state = world.get_block_state(&top_facing);
let right_dir = facing.rotate_clockwise();
let right_pos = pos.offset(right_dir.to_block_direction().to_offset());
let (right_block, right_state) = world.get_block_and_state(&right_pos).await;
let (right_block, right_state) = world.get_block_and_state(&right_pos);
let top_right = top_pos.offset(facing.to_block_direction().to_offset());
let top_right_state = world.get_block_state(&top_right).await;
let top_right_state = world.get_block_state(&top_right);
let has_left_door = world
.get_block(&left_pos)
.await
.has_tag(&tag::Block::MINECRAFT_DOORS)
&& DoorProperties::from_state_id(left_state.id, left_block).half == DoubleBlockHalf::Lower;
let has_right_door = world
.get_block(&right_pos)
.await
.has_tag(&tag::Block::MINECRAFT_DOORS)
&& DoorProperties::from_state_id(right_state.id, right_block).half
== DoubleBlockHalf::Lower;
@ -184,8 +180,8 @@ impl BlockBehaviour for DoorBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
@ -223,7 +219,7 @@ impl BlockBehaviour for DoorBlock {
DoubleBlockHalf::Lower => args.position.up(),
};
let neighbor_block_id = args.world.get_block_state_id(&other_half_pos).await;
let neighbor_block_id = args.world.get_block_state_id(&other_half_pos);
if neighbor_block_id != args.block.id {
args.world.update_neighbors(&other_half_pos, None).await;
return; // Neighbor is already gone or is a different block
@ -244,7 +240,7 @@ impl BlockBehaviour for DoorBlock {
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let block_state = args.world.get_block_state(args.position).await;
let block_state = args.world.get_block_state(args.position);
let mut door_props = DoorProperties::from_state_id(block_state.id, args.block);
let other_half = match door_props.half {
@ -252,7 +248,7 @@ impl BlockBehaviour for DoorBlock {
DoubleBlockHalf::Lower => BlockDirection::Up,
};
let other_pos = args.position.offset(other_half.to_offset());
let (other_block, other_state_id) = args.world.get_block_and_state_id(&other_pos).await;
let (other_block, other_state_id) = args.world.get_block_and_state_id(&other_pos);
if other_block.id != args.block.id {
return;
@ -271,13 +267,11 @@ impl BlockBehaviour for DoorBlock {
door_props.open = door_props.powered;
other_door_props.open = other_door_props.powered;
args.world
.play_block_sound(
get_sound(args.block, powered),
SoundCategory::Blocks,
*args.position,
)
.await;
args.world.play_block_sound(
get_sound(args.block, powered),
SoundCategory::Blocks,
*args.position,
);
}
args.world
@ -309,7 +303,7 @@ impl BlockBehaviour for DoorBlock {
{
if lv == DoubleBlockHalf::Lower
&& args.direction == BlockDirection::Down
&& !can_place_at(args.world, args.position).await
&& !can_place_at(args.world, args.position)
{
return 0;
}
@ -333,7 +327,7 @@ impl BlockBehaviour for DoorBlock {
return;
}
let new_state_id = args.world.get_block_state_id(args.position).await;
let new_state_id = args.world.get_block_state_id(args.position);
let new_block = Block::from_state_id(new_state_id);
if new_block == &Block::AIR {
return;
@ -356,10 +350,9 @@ impl BlockBehaviour for DoorBlock {
}
}
async fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
world.get_block_state(&block_pos.up()).await.replaceable()
fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
world.get_block_state(&block_pos.up()).replaceable()
&& world
.get_block_state(&block_pos.down())
.await
.is_side_solid(BlockDirection::Up)
}

View File

@ -19,11 +19,11 @@ impl DragonEggBlock {
let z = pos.0.z + rng().random_range(-16..16);
let test_pos = BlockPos::new(x, y, z);
let state = world.get_block_state(&test_pos).await;
let below_state = world.get_block_state(&test_pos.down()).await;
let state = world.get_block_state(&test_pos);
let below_state = world.get_block_state(&test_pos.down());
if state.is_air() && !below_state.is_air() {
let current_state = world.get_block_state(pos).await;
let current_state = world.get_block_state(pos);
world
.set_block_state(
&test_pos,

View File

@ -28,16 +28,13 @@ impl BlockMetadata for DripstoneBlock {
}
impl BlockBehaviour for DripstoneBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
can_place_at_pos(
args.block_accessor,
args.position,
args.direction,
args.player,
)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at_pos(
args.block_accessor,
args.position,
args.direction,
args.player,
)
}
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
@ -48,9 +45,7 @@ impl BlockBehaviour for DripstoneBlock {
args.position,
Some(args.direction),
Some(args.player),
)
.await
else {
) else {
//this shouldn't happen
return Block::AIR.id;
};
@ -65,8 +60,7 @@ impl BlockBehaviour for DripstoneBlock {
args.world,
args.position,
args.state_id,
)
.await;
);
match vertical_dir {
VerticalDirection::Up => {
update_stalagmite(args.world, len, args.position).await;
@ -90,8 +84,7 @@ impl BlockBehaviour for DripstoneBlock {
args.world,
&new_tip_pos,
args.state.id,
)
.await;
);
match vertical_dir {
VerticalDirection::Up => {
update_stalagmite(args.world, len, &new_tip_pos).await;
@ -107,7 +100,7 @@ impl BlockBehaviour for DripstoneBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at_pos(args.world, args.position, None, None).await {
if !can_place_at_pos(args.world, args.position, None, None) {
return Block::AIR.default_state.id;
}
let mut dripstone_props =
@ -117,14 +110,14 @@ impl BlockBehaviour for DripstoneBlock {
}
match dripstone_props.vertical_direction {
VerticalDirection::Up => {
let block_above = args.world.get_block(&args.position.up()).await;
let block_above = args.world.get_block(&args.position.up());
if block_above != &Block::POINTED_DRIPSTONE {
dripstone_props.thickness = DripstoneThickness::Tip;
return dripstone_props.to_state_id(args.block);
}
}
VerticalDirection::Down => {
let block_below = args.world.get_block(&args.position.down()).await;
let block_below = args.world.get_block(&args.position.down());
if block_below != &Block::POINTED_DRIPSTONE {
dripstone_props.thickness = DripstoneThickness::Tip;
return dripstone_props.to_state_id(args.block);
@ -136,7 +129,7 @@ impl BlockBehaviour for DripstoneBlock {
}
}
async fn update_stalagmite(world: &Arc<World>, stalagmite_len: u8, tip_pos: &BlockPos) {
let block_above = world.get_block(&tip_pos.up()).await;
let block_above = world.get_block(&tip_pos.up());
if block_above == &Block::POINTED_DRIPSTONE {
modify_dripstone_thickness_to(world, tip_pos, DripstoneThickness::TipMerge).await;
modify_dripstone_thickness_to(world, &tip_pos.up(), DripstoneThickness::TipMerge).await;
@ -203,7 +196,7 @@ async fn update_stalagmite(world: &Arc<World>, stalagmite_len: u8, tip_pos: &Blo
}
async fn update_stalactite(world: &Arc<World>, stalagmite_len: u8, tip_pos: &BlockPos) {
let block_below = world.get_block(&tip_pos.down()).await;
let block_below = world.get_block(&tip_pos.down());
if block_below == &Block::POINTED_DRIPSTONE {
modify_dripstone_thickness_to(world, tip_pos, DripstoneThickness::TipMerge).await;
modify_dripstone_thickness_to(world, &tip_pos.down(), DripstoneThickness::TipMerge).await;
@ -256,7 +249,7 @@ async fn update_stalactite(world: &Arc<World>, stalagmite_len: u8, tip_pos: &Blo
_ => {}
}
}
async fn get_stalagmite_or_stalactice_len_and_dir_from_tip_pos(
fn get_stalagmite_or_stalactice_len_and_dir_from_tip_pos(
world: &Arc<World>,
position: &BlockPos,
block_state_id: BlockStateId,
@ -268,7 +261,7 @@ async fn get_stalagmite_or_stalactice_len_and_dir_from_tip_pos(
let mut next_dripstone_pos = offset_pos_by_vertical_dir(position, props.vertical_direction);
//We dont care if it's longer than 5 blocks because of how thickness system works.
while dripstone_len < 5 {
if world.get_block(&next_dripstone_pos).await != &Block::POINTED_DRIPSTONE {
if world.get_block(&next_dripstone_pos) != &Block::POINTED_DRIPSTONE {
break;
}
next_dripstone_pos =
@ -277,7 +270,7 @@ async fn get_stalagmite_or_stalactice_len_and_dir_from_tip_pos(
}
(dripstone_len, props.vertical_direction)
}
async fn can_place_at_pos(
fn can_place_at_pos(
block_accessor: &dyn BlockAccessor,
position: &BlockPos,
placing_direction: Option<BlockDirection>,
@ -289,22 +282,21 @@ async fn can_place_at_pos(
position,
placing_direction,
player_option,
)
.await
else {
) else {
return false;
};
let support_pos = match support_block_vertical_direction {
VerticalDirection::Up => position.up(),
VerticalDirection::Down => position.down(),
};
let support_block = block_accessor.get_block(&support_pos).await;
let support_block = block_accessor.get_block(&support_pos);
if can_support_dripstone(support_block) {
return true;
}
false
}
async fn get_support_block_vertical_direction(
fn get_support_block_vertical_direction(
block_accessor: &dyn BlockAccessor,
position: &BlockPos,
placing_direction_wrapper: Option<BlockDirection>,
@ -312,7 +304,7 @@ async fn get_support_block_vertical_direction(
) -> Option<VerticalDirection> {
let Some(placing_direction) = placing_direction_wrapper else {
//then this is basically called by a neighbor update check
let (block, state) = block_accessor.get_block_and_state(position).await;
let (block, state) = block_accessor.get_block_and_state(position);
if block != &Block::POINTED_DRIPSTONE {
return None;
}
@ -322,8 +314,8 @@ async fn get_support_block_vertical_direction(
match block_direction_to_vertical_direction(placing_direction) {
Some(ver_dir) => match ver_dir {
VerticalDirection::Up => {
let block_above = block_accessor.get_block(&position.up()).await;
let block_below = block_accessor.get_block(&position.down()).await;
let block_above = block_accessor.get_block(&position.up());
let block_below = block_accessor.get_block(&position.down());
if can_support_dripstone(block_above) {
return Some(VerticalDirection::Up);
} else if can_support_dripstone(block_below) {
@ -332,8 +324,8 @@ async fn get_support_block_vertical_direction(
None
}
VerticalDirection::Down => {
let block_above = block_accessor.get_block(&position.up()).await;
let block_below = block_accessor.get_block(&position.down()).await;
let block_above = block_accessor.get_block(&position.up());
let block_below = block_accessor.get_block(&position.down());
if can_support_dripstone(block_below) {
return Some(VerticalDirection::Down);
} else if can_support_dripstone(block_above) {
@ -342,32 +334,29 @@ async fn get_support_block_vertical_direction(
None
}
},
None => match player_option {
Some(player) => {
let (_, pitch) = player.rotation();
let (can_place_above, can_place_below) = {
let block_above = block_accessor.get_block(&position.up()).await;
let block_below = block_accessor.get_block(&position.down()).await;
(
can_support_dripstone(block_above),
can_support_dripstone(block_below),
)
};
match (can_place_above, can_place_below) {
(true, true) => {
if pitch > 0.0 {
Some(VerticalDirection::Down)
} else {
Some(VerticalDirection::Up)
}
None => player_option.map_or(Some(VerticalDirection::Up), |player| {
let (_, pitch) = player.rotation();
let (can_place_above, can_place_below) = {
let block_above = block_accessor.get_block(&position.up());
let block_below = block_accessor.get_block(&position.down());
(
can_support_dripstone(block_above),
can_support_dripstone(block_below),
)
};
match (can_place_above, can_place_below) {
(true, true) => {
if pitch > 0.0 {
Some(VerticalDirection::Down)
} else {
Some(VerticalDirection::Up)
}
(false, false) => None,
(true, false) => Some(VerticalDirection::Up),
(false, true) => Some(VerticalDirection::Down),
}
(false, false) => None,
(true, false) => Some(VerticalDirection::Up),
(false, true) => Some(VerticalDirection::Down),
}
None => Some(VerticalDirection::Up),
},
}),
}
}
fn can_support_dripstone(support_block: &Block) -> bool {
@ -384,7 +373,7 @@ async fn modify_dripstone_thickness_to(
pos: &BlockPos,
new_thickness: DripstoneThickness,
) {
let (block, support_block_state_id) = world.get_block_and_state_id(pos).await;
let (block, support_block_state_id) = world.get_block_and_state_id(pos);
if block != &Block::POINTED_DRIPSTONE {
//this shouldn't happen

View File

@ -2,7 +2,7 @@ use std::sync::Arc;
use crate::block::registry::BlockActionResult;
use crate::block::{BlockBehaviour, BlockFuture, NormalUseArgs};
use pumpkin_data::translation;
use pumpkin_data::{Block, translation};
use pumpkin_inventory::enchanting::enchanting_screen_handler::EnchantingTableScreenHandler;
use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{
@ -25,37 +25,28 @@ impl BlockBehaviour for EnchantingTableBlock {
for off_z in -1..=1 {
for off_x in -1..=1 {
if (off_z != 0 || off_x != 0)
&& args.world.get_block_state(&args.position.add(off_x, 0, off_z)).await.id == 0 // Air
&& args.world.get_block_state(&args.position.add(off_x, 1, off_z)).await.id == 0
&& args.world.get_block_state(&args.position.add(off_x, 0, off_z)).id == 0 // Air
&& args.world.get_block_state(&args.position.add(off_x, 1, off_z)).id == 0
// Air
{
for off_y in 0..=1 {
if self
.is_bookshelf(
args.world,
&args.position.add(off_x * 2, off_y, off_z * 2),
)
.await
{
if Self::is_bookshelf(
args.world,
&args.position.add(off_x * 2, off_y, off_z * 2),
) {
bookshelf_count += 1;
}
if off_x != 0 && off_z != 0 {
if self
.is_bookshelf(
args.world,
&args.position.add(off_x * 2, off_y, off_z),
)
.await
{
if Self::is_bookshelf(
args.world,
&args.position.add(off_x * 2, off_y, off_z),
) {
bookshelf_count += 1;
}
if self
.is_bookshelf(
args.world,
&args.position.add(off_x, off_y, off_z * 2),
)
.await
{
if Self::is_bookshelf(
args.world,
&args.position.add(off_x, off_y, off_z * 2),
) {
bookshelf_count += 1;
}
}
@ -80,10 +71,10 @@ impl BlockBehaviour for EnchantingTableBlock {
}
impl EnchantingTableBlock {
async fn is_bookshelf(&self, world: &Arc<crate::world::World>, pos: &BlockPos) -> bool {
let state = world.get_block_state(pos).await;
fn is_bookshelf(world: &Arc<crate::world::World>, pos: &BlockPos) -> bool {
let state = world.get_block_state(pos);
let block = pumpkin_data::Block::from_state_id(state.id);
block.name == "bookshelf"
block == &Block::BOOKSHELF
}
}

View File

@ -16,8 +16,7 @@ impl BlockBehaviour for EndRodBlock {
let blockstate = args
.world
.get_block_state_id(&args.position.offset(args.direction.to_offset()))
.await;
.get_block_state_id(&args.position.offset(args.direction.to_offset()));
if Block::from_state_id(blockstate).eq(args.block)
&& EndRodLikeProperties::from_state_id(blockstate, args.block).facing

View File

@ -74,11 +74,11 @@ impl BlockBehaviour for EnderChestBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if is_chest_blocked(args.world, args.position).await {
if is_chest_blocked(args.world, args.position) {
return BlockActionResult::Success;
}
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(block_entity) = block_entity
.as_any()
.downcast_ref::<EnderChestBlockEntity>()
@ -108,13 +108,13 @@ impl BlockBehaviour for EnderChestBlock {
}
}
async fn is_chest_blocked(world: &World, block_pos: &BlockPos) -> bool {
fn is_chest_blocked(world: &World, block_pos: &BlockPos) -> bool {
// TODO: Block opening when a cat is sitting on top.
has_block_on_top(world, block_pos).await
has_block_on_top(world, block_pos)
}
async fn has_block_on_top(world: &World, block_pos: &BlockPos) -> bool {
fn has_block_on_top(world: &World, block_pos: &BlockPos) -> bool {
let above_pos = block_pos.up();
let above_state = world.get_block_state(&above_pos).await;
let above_state = world.get_block_state(&above_pos);
above_state.is_solid_block()
}
impl EnderChestBlock {

View File

@ -52,11 +52,11 @@ impl BlockBehaviour for FallingBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let (block, state) = args.world.get_block_and_state(&args.position.down()).await;
let (block, state) = args.world.get_block_and_state(&args.position.down());
if !Self::can_fall_through(state, block) || args.position.0.y < args.world.min_y {
return;
}
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
FallingEntity::replace_spawn(args.world, *args.position, state.id).await;
})
}

View File

@ -43,7 +43,7 @@ impl BlockBehaviour for FarmlandBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
return Block::DIRT.default_state.id;
}
args.block.default_state.id
@ -55,9 +55,7 @@ impl BlockBehaviour for FarmlandBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if args.direction == BlockDirection::Up
&& !can_place_at(args.world, args.position).await
{
if args.direction == BlockDirection::Up && !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -66,14 +64,14 @@ impl BlockBehaviour for FarmlandBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
fn random_tick<'a>(&'a self, args: RandomTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
// TODO: add rain check. Remember to check which one is most optimized.
if is_water_nearby(args.world, args.position).await {
if is_water_nearby(args.world, args.position) {
let mut props = FarmlandProperties::default(args.block);
props.moisture = 7;
args.world
@ -84,13 +82,12 @@ impl BlockBehaviour for FarmlandBlock {
)
.await;
} else {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let mut props = FarmlandProperties::from_state_id(state_id, args.block);
if props.moisture == 0 {
if !args
.world
.get_block(&args.position.up())
.await
.has_tag(&tag::Block::MINECRAFT_MAINTAINS_FARMLAND)
{
//TODO push entities up
@ -117,12 +114,12 @@ impl BlockBehaviour for FarmlandBlock {
}
}
async fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let state = world.get_block_state(&block_pos.up()).await;
fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let state = world.get_block_state(&block_pos.up());
!state.is_solid() // TODO: add fence gate block
}
async fn is_water_nearby(world: &Arc<World>, block_pos: &BlockPos) -> bool {
fn is_water_nearby(world: &Arc<World>, block_pos: &BlockPos) -> bool {
for dx in -4..=4 {
for dy in 0..=1 {
for dz in -4..=4 {
@ -132,7 +129,7 @@ async fn is_water_nearby(world: &Arc<World>, block_pos: &BlockPos) -> bool {
z: dz,
});
//TODO this should use tag water. It does not seem to work rn.
if world.get_block(&check_pos).await == &Block::WATER {
if world.get_block(&check_pos) == &Block::WATER {
return true;
}
}

View File

@ -42,7 +42,7 @@ pub async fn toggle_fence_gate(
block_pos: &BlockPos,
player: &Player,
) -> BlockStateId {
let (block, state) = world.get_block_and_state_id(block_pos).await;
let (block, state) = world.get_block_and_state_id(block_pos);
let mut fence_gate_props = FenceGateProperties::from_state_id(state, block);
if fence_gate_props.open {
@ -60,14 +60,12 @@ pub async fn toggle_fence_gate(
fence_gate_props.open = true;
}
world
.play_block_sound_expect(
player,
get_sound(block, fence_gate_props.open),
SoundCategory::Blocks,
*block_pos,
)
.await;
world.play_block_sound_expect(
player,
get_sound(block, fence_gate_props.open),
SoundCategory::Blocks,
*block_pos,
);
world
.set_block_state(
@ -101,7 +99,7 @@ impl BlockBehaviour for FenceGateBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let fence_props = is_in_wall(&args).await;
let fence_props = is_in_wall(&args);
fence_props.to_state_id(args.block)
})
}
@ -116,7 +114,7 @@ impl BlockBehaviour for FenceGateBlock {
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let block_state = args.world.get_block_state(args.position).await;
let block_state = args.world.get_block_state(args.position);
let mut fence_gate_props =
FenceGateProperties::from_state_id(block_state.id, args.block);
let powered = block_receives_redstone_power(args.world, args.position).await;
@ -130,13 +128,11 @@ impl BlockBehaviour for FenceGateBlock {
if powered != fence_gate_props.open {
fence_gate_props.open = powered;
args.world
.play_block_sound(
get_sound(args.block, powered),
SoundCategory::Blocks,
*args.position,
)
.await;
args.world.play_block_sound(
get_sound(args.block, powered),
SoundCategory::Blocks,
*args.position,
);
}
args.world
@ -150,7 +146,7 @@ impl BlockBehaviour for FenceGateBlock {
}
}
async fn is_in_wall(args: &GetStateForNeighborUpdateArgs<'_>) -> FenceGateProperties {
fn is_in_wall(args: &GetStateForNeighborUpdateArgs<'_>) -> FenceGateProperties {
let mut fence_props = FenceGateProperties::from_state_id(args.state_id, args.block);
let side_offset_left = args
@ -165,8 +161,8 @@ async fn is_in_wall(args: &GetStateForNeighborUpdateArgs<'_>) -> FenceGateProper
args.neighbor_position == &side_offset_left || args.neighbor_position == &side_offset_right;
if neighbor_on_side {
let neighbor_right = args.world.get_block(&side_offset_right).await;
let neighbor_left = args.world.get_block(&side_offset_left).await;
let neighbor_right = args.world.get_block(&side_offset_right);
let neighbor_left = args.world.get_block(&side_offset_left);
fence_props.in_wall = neighbor_left.has_tag(&tag::Block::MINECRAFT_WALLS)
|| neighbor_right.has_tag(&tag::Block::MINECRAFT_WALLS);

View File

@ -28,7 +28,7 @@ impl BlockBehaviour for FenceBlock {
let mut fence_props = FenceProperties::default(args.block);
fence_props.waterlogged = args.replacing.water_source();
compute_fence_state(fence_props, args.world, args.block, args.position).await
compute_fence_state(fence_props, args.world, args.block, args.position)
})
}
@ -38,12 +38,12 @@ impl BlockBehaviour for FenceBlock {
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let fence_props = FenceProperties::from_state_id(args.state_id, args.block);
compute_fence_state(fence_props, args.world, args.block, args.position).await
compute_fence_state(fence_props, args.world, args.block, args.position)
})
}
}
pub async fn compute_fence_state(
pub fn compute_fence_state(
mut fence_props: FenceProperties,
world: &World,
block: &Block,
@ -51,7 +51,7 @@ pub async fn compute_fence_state(
) -> u16 {
for direction in BlockDirection::horizontal() {
let other_block_pos = block_pos.offset(direction.to_offset());
let (other_block, other_block_state) = world.get_block_and_state(&other_block_pos).await;
let (other_block, other_block_state) = world.get_block_and_state(&other_block_pos);
let connected = connects_to(block, other_block, other_block_state, direction);
match direction {

View File

@ -54,14 +54,10 @@ impl FireBlock {
.is_some_and(|f| f.burn_chance > 0)
}
async fn are_blocks_around_flammable(
&self,
block_accessor: &dyn BlockAccessor,
pos: &BlockPos,
) -> bool {
fn are_blocks_around_flammable(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
for direction in BlockDirection::all() {
let neighbor_pos = pos.offset(direction.to_offset());
let block_state = block_accessor.get_block_state(&neighbor_pos).await;
let block_state = block_accessor.get_block_state(&neighbor_pos);
if Self::is_flammable(block_state) {
return true;
}
@ -69,21 +65,21 @@ impl FireBlock {
false
}
pub async fn get_state_for_position(
pub fn get_state_for_position(
&self,
world: &World,
block: &Block,
pos: &BlockPos,
) -> BlockStateId {
let down_pos = pos.down();
let down_state = world.get_block_state(&down_pos).await;
let down_state = world.get_block_state(&down_pos);
if Self::is_flammable(down_state) || down_state.is_side_solid(BlockDirection::Up) {
return block.default_state.id;
}
let mut fire_props = FireProperties::from_state_id(block.default_state.id, block);
for direction in BlockDirection::all() {
let neighbor_pos = pos.offset(direction.to_offset());
let neighbor_state = world.get_block_state(&neighbor_pos).await;
let neighbor_state = world.get_block_state(&neighbor_pos);
if Self::is_flammable(neighbor_state) {
match direction {
BlockDirection::North => fire_props.north = true,
@ -99,16 +95,16 @@ impl FireBlock {
}
// Used for spreading fire
pub async fn get_burn_chance(&self, world: &Arc<World>, pos: &BlockPos) -> i32 {
let block_state = world.get_block_state(pos).await;
pub fn get_burn_chance(&self, world: &Arc<World>, pos: &BlockPos) -> i32 {
let block_state = world.get_block_state(pos);
if !block_state.is_air() {
return 0;
}
let mut total_burn_chance = 0;
for dir in BlockDirection::all() {
let neighbor_block = world.get_block(&pos.offset(dir.to_offset())).await;
if world.get_fluid(&pos.offset(dir.to_offset())).await.name != Fluid::EMPTY.name {
let neighbor_block = world.get_block(&pos.offset(dir.to_offset()));
if world.get_fluid(&pos.offset(dir.to_offset())).name != Fluid::EMPTY.name {
continue; // Skip if there is a fluid
}
if let Some(flammable) = &neighbor_block.flammable {
@ -130,7 +126,7 @@ impl FireBlock {
block.flammable.as_ref().map_or(0, |f| f.burn_chance.into())
}
async fn is_increased_burnout_biome(world: &World, pos: &BlockPos) -> bool {
fn is_increased_burnout_biome(world: &World, pos: &BlockPos) -> bool {
// Fire burnout increases in the Nether
if world.dimension == Dimension::THE_NETHER {
return true;
@ -138,7 +134,7 @@ impl FireBlock {
// Fire burnout increases in specific biomes
// TODO: Use proper tag or bool for this when available
let biome_id = world.level.get_rough_biome(pos).await.id;
let biome_id = world.level.get_rough_biome(pos).id;
matches!(
biome_id,
id if id == Biome::BAMBOO_JUNGLE.id
@ -153,7 +149,7 @@ impl FireBlock {
}
async fn try_spreading_fire(&self, world: &Arc<World>, pos: &BlockPos, chance: i32, age: u8) {
let block = world.get_block(pos).await;
let block = world.get_block(pos);
let odds = Self::get_burn_odds(block);
if rand::rng().random_range(0..chance) < odds {
let old_block = block;
@ -161,9 +157,7 @@ impl FireBlock {
&& !Self::is_near_rain(world.as_ref(), pos)
{
let new_age = (age + (rand::rng().random_range(0..5) / 4)).min(15) as u8;
let state_id = self
.get_state_for_position(world.as_ref(), &Block::FIRE, pos)
.await;
let state_id = self.get_state_for_position(world.as_ref(), &Block::FIRE, pos);
let mut fire_props = FireProperties::from_state_id(state_id, &Block::FIRE);
fire_props.age = new_age;
let new_state_id = fire_props.to_state_id(&Block::FIRE);
@ -199,7 +193,7 @@ impl BlockBehaviour for FireBlock {
// First lets check if we are in OverWorld or Nether, its not possible to place an Nether portal in other dimensions in Vanilla
if (dimension == &Dimension::OVERWORLD || dimension == &Dimension::THE_NETHER)
&& let Some(portal) =
NetherPortal::get_new_portal(args.world, args.position, HorizontalAxis::X).await
NetherPortal::get_new_portal(args.world, args.position, HorizontalAxis::X)
{
portal.create(args.world).await;
return;
@ -225,24 +219,20 @@ impl BlockBehaviour for FireBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if self
.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(args.world),
block_accessor: args.world,
block: &Block::FIRE,
state: Block::FIRE.default_state,
position: args.position,
direction: None,
player: None,
use_item_on: None,
})
.await
{
if self.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(args.world),
block_accessor: args.world,
block: &Block::FIRE,
state: Block::FIRE.default_state,
position: args.position,
direction: None,
player: None,
use_item_on: None,
}) {
let old_fire_props = FireProperties::from_state_id(args.state_id, &Block::FIRE);
let fire_state_id = self
.get_state_for_position(args.world, &Block::FIRE, args.position)
.await;
let fire_state_id =
self.get_state_for_position(args.world, &Block::FIRE, args.position);
let mut fire_props = FireProperties::from_state_id(fire_state_id, &Block::FIRE);
fire_props.age = old_fire_props.age;
return fire_props.to_state_id(&Block::FIRE);
@ -251,18 +241,12 @@ impl BlockBehaviour for FireBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let state = args
.block_accessor
.get_block_state(&args.position.down())
.await;
if state.is_side_solid(BlockDirection::Up) {
return true;
}
self.are_blocks_around_flammable(args.block_accessor, args.position)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
let state = args.block_accessor.get_block_state(&args.position.down());
if state.is_side_solid(BlockDirection::Up) {
return true;
}
Self::are_blocks_around_flammable(args.block_accessor, args.position)
}
#[expect(clippy::too_many_lines)]
@ -281,20 +265,17 @@ impl BlockBehaviour for FireBlock {
.await;
// Check if fire can survive
if !Self
.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(world),
block_accessor: world.as_ref(),
block,
state: block.default_state,
position: pos,
direction: None,
player: None,
use_item_on: None,
})
.await
{
if !self.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(world),
block_accessor: world.as_ref(),
block,
state: block.default_state,
position: pos,
direction: None,
player: None,
use_item_on: None,
}) {
world
.set_block_state(
pos,
@ -305,8 +286,8 @@ impl BlockBehaviour for FireBlock {
return;
}
let block_state = world.get_block_state(pos).await;
let block_below = world.get_block(&pos.down()).await;
let block_state = world.get_block_state(pos);
let block_below = world.get_block(&pos.down());
// Check for infiniburn blocks (depending on dimension)
let infiniburn = match world.dimension.id {
@ -353,8 +334,8 @@ impl BlockBehaviour for FireBlock {
if !infiniburn {
// Check if fire should extinguish due to lack of fuel
if !self.are_blocks_around_flammable(world.as_ref(), pos).await {
let block_below_state = world.get_block_state(&pos.down()).await;
if !Self::are_blocks_around_flammable(world.as_ref(), pos) {
let block_below_state = world.get_block_state(&pos.down());
if !block_below_state.is_side_solid(BlockDirection::Up) || new_age > 3 {
world
.set_block_state(
@ -370,7 +351,7 @@ impl BlockBehaviour for FireBlock {
// At max age, fire has a chance to extinguish if not on flammable block
if new_age == 15
&& rand::rng().random_range(0..4) == 0
&& !Self::is_flammable(world.get_block_state(&pos.down()).await)
&& !Self::is_flammable(world.get_block_state(&pos.down()))
{
world
.set_block_state(
@ -384,7 +365,7 @@ impl BlockBehaviour for FireBlock {
}
// Burn adjacent blocks
let extra = if Self::is_increased_burnout_biome(world, pos).await {
let extra = if Self::is_increased_burnout_biome(world, pos) {
-50 // Increases chance of block being destroyed
} else {
0
@ -448,7 +429,7 @@ impl BlockBehaviour for FireBlock {
for yy in -1..=4 {
if xx != 0 || yy != 0 || zz != 0 {
let offset_pos = pos.offset(Vector3::new(xx, yy, zz));
let ignite_odds = self.get_burn_chance(world, &offset_pos).await;
let ignite_odds = self.get_burn_chance(world, &offset_pos);
if ignite_odds > 0 {
// Skip if spreding is disabled or if there are no players nearby
@ -473,7 +454,7 @@ impl BlockBehaviour for FireBlock {
(ignite_odds + 40 + difficulty * 7) / (new_age as i32 + 30);
// Reduce spread odds in certain biomes
if Self::is_increased_burnout_biome(world, &offset_pos).await {
if Self::is_increased_burnout_biome(world, &offset_pos) {
odds /= 2; // Fire spreads 50% slower
}
@ -484,9 +465,11 @@ impl BlockBehaviour for FireBlock {
let spread_age = (new_age + rand::rng().random_range(0..5) / 4)
.min(15)
as u8;
let fire_state_id = self
.get_state_for_position(world.as_ref(), block, &offset_pos)
.await;
let fire_state_id = self.get_state_for_position(
world.as_ref(),
block,
&offset_pos,
);
let mut new_fire_props =
FireProperties::from_state_id(fire_state_id, &Block::FIRE);
new_fire_props.age = spread_age;
@ -509,7 +492,7 @@ impl BlockBehaviour for FireBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
FireBlockBase::broken(args.world, *args.position).await;
FireBlockBase::broken(args.world, *args.position);
})
}
}

View File

@ -26,8 +26,8 @@ pub mod soul_fire;
pub struct FireBlockBase;
impl FireBlockBase {
pub async fn get_fire_type(world: &World, pos: &BlockPos) -> Block {
let block = world.get_block(&pos.down()).await;
pub fn get_fire_type(world: &World, pos: &BlockPos) -> Block {
let block = world.get_block(&pos.down());
if SoulFireBlock::is_soul_base(block) {
return Block::SOUL_FIRE;
}
@ -43,49 +43,44 @@ impl FireBlockBase {
&& block != &Block::LAVA
}
pub async fn is_soul_fire(world: &Arc<World>, block_pos: &BlockPos) -> bool {
let block = world.get_block(&block_pos.down()).await;
pub fn is_soul_fire(world: &Arc<World>, block_pos: &BlockPos) -> bool {
let block = world.get_block(&block_pos.down());
block.has_tag(&tag::Block::MINECRAFT_SOUL_FIRE_BASE_BLOCKS)
}
pub async fn can_place_at(world: &Arc<World>, block_pos: &BlockPos) -> bool {
let block_state = world.get_block_state(block_pos).await;
pub fn can_place_at(world: &Arc<World>, block_pos: &BlockPos) -> bool {
let block_state = world.get_block_state(block_pos);
if !block_state.is_air() {
return false;
}
if Self::is_soul_fire(world, block_pos).await {
SoulFireBlock
.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(world),
block_accessor: world.as_ref(),
block: &Block::SOUL_FIRE,
state: Block::SOUL_FIRE.default_state,
position: block_pos,
direction: None,
player: None,
use_item_on: None,
})
.await
if Self::is_soul_fire(world, block_pos) {
SoulFireBlock.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(world),
block_accessor: world.as_ref(),
block: &Block::SOUL_FIRE,
state: Block::SOUL_FIRE.default_state,
position: block_pos,
direction: None,
player: None,
use_item_on: None,
})
} else {
FireBlock
.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(world),
block_accessor: world.as_ref(),
block: &Block::FIRE,
state: Block::FIRE.default_state,
position: block_pos,
direction: None,
player: None,
use_item_on: None,
})
.await
|| Self::should_light_portal_at(world, block_pos, BlockDirection::Up).await
FireBlock.can_place_at(CanPlaceAtArgs {
server: None,
world: Some(world),
block_accessor: world.as_ref(),
block: &Block::FIRE,
state: Block::FIRE.default_state,
position: block_pos,
direction: None,
player: None,
use_item_on: None,
}) || Self::should_light_portal_at(world, block_pos, BlockDirection::Up)
}
}
pub async fn should_light_portal_at(
pub fn should_light_portal_at(
world: &Arc<World>,
block_pos: &BlockPos,
direction: BlockDirection,
@ -97,7 +92,7 @@ impl FireBlockBase {
let mut found = false;
for dir in BlockDirection::all() {
if world.get_block(&block_pos.offset(dir.to_offset())).await == &Block::OBSIDIAN {
if world.get_block(&block_pos.offset(dir.to_offset())) == &Block::OBSIDIAN {
found = true;
break;
}
@ -114,9 +109,7 @@ impl FireBlockBase {
Xoroshiro::from_seed(rand::rng().random()),
))
};
return NetherPortal::get_new_portal(world, block_pos, dir.to_horizontal_axis().unwrap())
.await
.is_some();
NetherPortal::get_new_portal(world, block_pos, dir.to_horizontal_axis().unwrap()).is_some()
}
/// Shared fire collision behavior used by `fire` and `soul_fire`.
@ -162,9 +155,7 @@ impl FireBlockBase {
})
}
async fn broken(world: &World, block_pos: BlockPos) {
world
.sync_world_event(WorldEvent::SoundExtinguishFire, block_pos, 0)
.await;
fn broken(world: &World, block_pos: BlockPos) {
world.sync_world_event(WorldEvent::SoundExtinguishFire, block_pos, 0);
}
}

View File

@ -30,7 +30,7 @@ impl BlockBehaviour for SoulFireBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !Self::is_soul_base(args.world.get_block(&args.position.down()).await) {
if !Self::is_soul_base(args.world.get_block(&args.position.down())) {
return Block::AIR.default_state.id;
}
@ -38,15 +38,13 @@ impl BlockBehaviour for SoulFireBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
Self::is_soul_base(args.block_accessor.get_block(&args.position.down()).await)
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
Self::is_soul_base(args.block_accessor.get_block(&args.position.down()))
}
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
FireBlockBase::broken(args.world, *args.position).await;
FireBlockBase::broken(args.world, *args.position);
})
}
}

View File

@ -85,7 +85,7 @@ pub struct FurnaceBlock;
impl BlockBehaviour for FurnaceBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.clone().get_inventory()
&& let Some(property_delegate) = block_entity.clone().to_property_delegate()
&& let Some(experience_container) = block_entity.to_experience_container()
@ -126,7 +126,7 @@ impl BlockBehaviour for FurnaceBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
// Extract and drop accumulated XP as orbs before removing the block entity
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(experience_container) = block_entity.to_experience_container()
{
let xp = experience_container.extract_experience();

View File

@ -26,7 +26,7 @@ impl BlockBehaviour for GlassPaneBlock {
let mut pane_props = GlassPaneProperties::default(args.block);
pane_props.waterlogged = args.replacing.water_source();
compute_pane_state(pane_props, args.world, args.block, args.position).await
compute_pane_state(pane_props, args.world, args.block, args.position)
})
}
@ -36,12 +36,12 @@ impl BlockBehaviour for GlassPaneBlock {
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let pane_props = GlassPaneProperties::from_state_id(args.state_id, args.block);
compute_pane_state(pane_props, args.world, args.block, args.position).await
compute_pane_state(pane_props, args.world, args.block, args.position)
})
}
}
pub async fn compute_pane_state(
pub fn compute_pane_state(
mut pane_props: GlassPaneProperties,
world: &World,
block: &Block,
@ -49,7 +49,7 @@ pub async fn compute_pane_state(
) -> u16 {
for direction in BlockDirection::horizontal() {
let other_block_pos = block_pos.offset(direction.to_offset());
let (other_block, other_block_state) = world.get_block_and_state(&other_block_pos).await;
let (other_block, other_block_state) = world.get_block_and_state(&other_block_pos);
let connected = other_block == block
|| other_block_state.is_side_solid(direction.opposite())

View File

@ -27,16 +27,13 @@ impl BlockBehaviour for GrindstoneBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
// Use the provided direction, or fallback to the current state's direction if missing
let direction = args
.direction
.unwrap_or_else(|| self.get_direction(args.state.id, args.block));
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
// Use the provided direction, or fallback to the current state's direction if missing
let direction = args
.direction
.unwrap_or_else(|| self.get_direction(args.state.id, args.block));
WallMountedBlock::can_place_at(self, args.block_accessor, args.position, direction)
.await
})
WallMountedBlock::can_place_at(self, args.block_accessor, args.position, direction)
}
fn get_state_for_neighbor_update<'a>(
@ -53,8 +50,8 @@ impl WallMountedBlock for GrindstoneBlock {
_world: &'a dyn BlockAccessor,
_pos: &'a BlockPos,
_direction: BlockDirection,
) -> BlockFuture<'a, bool> {
Box::pin(async move { true })
) -> bool {
true
}
fn get_direction(&self, state_id: BlockStateId, block: &Block) -> BlockDirection {

View File

@ -59,7 +59,7 @@ type HopperLikeProperties = pumpkin_data::block_properties::HopperLikeProperties
impl BlockBehaviour for HopperBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(inventory) = block_entity.get_inventory()
{
args.player
@ -104,7 +104,7 @@ impl BlockBehaviour for HopperBlock {
check_powered_state(
args.world,
args.position,
args.world.get_block_state_id(args.position).await,
args.world.get_block_state_id(args.position),
args.block,
)
.await;

View File

@ -23,7 +23,7 @@ impl BlockBehaviour for IronBarsBlock {
let mut bars_props = IronBarsProperties::default(args.block);
bars_props.waterlogged = args.replacing.water_source();
compute_bars_state(bars_props, args.world, args.block, args.position).await
compute_bars_state(bars_props, args.world, args.block, args.position)
})
}
@ -33,12 +33,12 @@ impl BlockBehaviour for IronBarsBlock {
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let bars_props = IronBarsProperties::from_state_id(args.state_id, args.block);
compute_bars_state(bars_props, args.world, args.block, args.position).await
compute_bars_state(bars_props, args.world, args.block, args.position)
})
}
}
pub async fn compute_bars_state(
pub fn compute_bars_state(
mut bars_props: IronBarsProperties,
world: &World,
block: &Block,
@ -46,7 +46,7 @@ pub async fn compute_bars_state(
) -> u16 {
for direction in BlockDirection::horizontal() {
let other_block_pos = block_pos.offset(direction.to_offset());
let (other_block, other_block_state) = world.get_block_and_state(&other_block_pos).await;
let (other_block, other_block_state) = world.get_block_and_state(&other_block_pos);
let connected = other_block == block
|| other_block_state.is_side_solid(direction.opposite())

View File

@ -52,7 +52,7 @@ impl JukeboxBlock {
/// Drops the record from the jukebox - matches vanilla's `JukeboxBlockEntity.dropRecord()`
/// Spawns item at (pos + 0.5, pos + 1.01, pos + 0.5) with horizontal random offset
async fn drop_record(position: &BlockPos, world: &Arc<World>) {
if let Some(block_entity) = world.get_block_entity(position).await
if let Some(block_entity) = world.get_block_entity(position)
&& let Some(jukebox_entity) = block_entity.as_any().downcast_ref::<JukeboxBlockEntity>()
{
let record = jukebox_entity.clear_record().await;
@ -67,7 +67,7 @@ impl JukeboxBlock {
let entity = Entity::new(world.clone(), spawn_pos, &EntityType::ITEM);
// Vanilla: setToDefaultPickupDelay() = 10 ticks
let item_entity = Arc::new(ItemEntity::new(entity, record).await);
let item_entity = Arc::new(ItemEntity::new(entity, record));
world.spawn_entity(item_entity).await;
}
}
@ -76,16 +76,12 @@ impl JukeboxBlock {
/// Stops the music and updates block state
async fn stop_playing(block: &Block, position: &BlockPos, world: &Arc<World>) {
Self::set_record_state(false, block, position, world).await;
world
.sync_world_event(WorldEvent::SoundStopJukeboxSong, *position, 0)
.await;
world.sync_world_event(WorldEvent::SoundStopJukeboxSong, *position, 0);
}
/// Starts playing music
async fn start_playing(position: &BlockPos, world: &Arc<World>, song_id: u32) {
world
.sync_world_event(WorldEvent::SoundPlayJukeboxSong, *position, song_id as i32)
.await;
fn start_playing(position: &BlockPos, world: &Arc<World>, song_id: u32) {
world.sync_world_event(WorldEvent::SoundPlayJukeboxSong, *position, song_id as i32);
}
}
@ -102,7 +98,7 @@ impl BlockBehaviour for JukeboxBlock {
/// Vanilla: `JukeboxBlock.onUse()` - drops record if present
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state(args.position).await.id;
let state_id = args.world.get_block_state(args.position).id;
// Vanilla: if (state.get(HAS_RECORD) && world.getBlockEntity(pos) instanceof JukeboxBlockEntity lv)
if Self::has_record_state(args.block, state_id) {
@ -125,7 +121,7 @@ impl BlockBehaviour for JukeboxBlock {
) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let world = args.world;
let state_id = world.get_block_state(args.position).await.id;
let state_id = world.get_block_state(args.position).id;
// Vanilla: if (state.get(HAS_RECORD)) return PASS_TO_DEFAULT_BLOCK_ACTION
if Self::has_record_state(args.block, state_id) {
@ -157,7 +153,7 @@ impl BlockBehaviour for JukeboxBlock {
let record = item_stack.split_unless_creative(args.player.gamemode.load(), 1);
// Vanilla: lv4.setStack(lv3)
if let Some(block_entity) = world.get_block_entity(args.position).await
if let Some(block_entity) = world.get_block_entity(args.position)
&& let Some(jukebox_entity) =
block_entity.as_any().downcast_ref::<JukeboxBlockEntity>()
{
@ -170,7 +166,7 @@ impl BlockBehaviour for JukeboxBlock {
Self::set_record_state(true, args.block, args.position, world).await;
// Start playing the music (client-side audio)
Self::start_playing(args.position, world, jukebox_song.get_id()).await;
Self::start_playing(args.position, world, jukebox_song.get_id());
// TODO: world.emitGameEvent(GameEvent.BLOCK_CHANGE, pos, ...)
// TODO: player.incrementStat(Stats.PLAY_RECORD)
@ -186,8 +182,7 @@ impl BlockBehaviour for JukeboxBlock {
Self::drop_record(args.position, args.world).await;
// Stop the music
args.world
.sync_world_event(WorldEvent::SoundStopJukeboxSong, *args.position, 0)
.await;
.sync_world_event(WorldEvent::SoundStopJukeboxSong, *args.position, 0);
})
}
@ -214,7 +209,7 @@ impl BlockBehaviour for JukeboxBlock {
) -> BlockFuture<'a, u8> {
Box::pin(async move {
// Vanilla: return world.getBlockEntity(pos) instanceof JukeboxBlockEntity lv && lv.getManager().isPlaying() ? 15 : 0
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(jukebox_entity) =
block_entity.as_any().downcast_ref::<JukeboxBlockEntity>()
&& jukebox_entity.is_playing()
@ -233,7 +228,7 @@ impl BlockBehaviour for JukeboxBlock {
) -> BlockFuture<'a, Option<u8>> {
Box::pin(async move {
// Vanilla: return world.getBlockEntity(pos) instanceof JukeboxBlockEntity lv ? lv.getComparatorOutput() : 0
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(jukebox_entity) =
block_entity.as_any().downcast_ref::<JukeboxBlockEntity>()
{

View File

@ -20,7 +20,7 @@ impl BlockBehaviour for LadderBlock {
Box::pin(async move {
let clicked_pos = args.use_item_on.position;
let (clicked_block, clicked_block_state_id) =
args.world.get_block_and_state_id(&clicked_pos).await;
args.world.get_block_and_state_id(&clicked_pos);
if clicked_block == &Block::LADDER {
//you can't click on a ladder and place a ladder
let props =
@ -38,7 +38,7 @@ impl BlockBehaviour for LadderBlock {
if dir == Facing::Up || dir == Facing::Down {
continue;
}
if !can_place_ladder_at(args.world, args.position, dir.to_block_direction()).await {
if !can_place_ladder_at(args.world, args.position, dir.to_block_direction()) {
continue;
}
props.facing = dir
@ -51,19 +51,17 @@ impl BlockBehaviour for LadderBlock {
Block::AIR.default_state.id
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
for dir in BlockDirection::horizontal() {
let Some(world) = args.world else {
//this won't happen
return false;
};
if can_place_ladder_at(world, args.position, dir).await {
return true;
}
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
for dir in BlockDirection::horizontal() {
let Some(world) = args.world else {
//this won't happen
return false;
};
if can_place_ladder_at(world, args.position, dir) {
return true;
}
false
})
}
false
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -77,7 +75,6 @@ impl BlockBehaviour for LadderBlock {
args.position,
props.facing.to_block_direction().opposite(),
)
.await
{
return 0;
}
@ -87,7 +84,7 @@ impl BlockBehaviour for LadderBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
if Block::from_state_id(state_id) != &Block::LADDER {
return;
}
@ -96,9 +93,7 @@ impl BlockBehaviour for LadderBlock {
args.world,
args.position,
props.facing.to_block_direction().opposite(),
)
.await
{
) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -116,9 +111,8 @@ pub const fn horizontal_facing_from_offset(offset: Vector3<i32>) -> Option<Block
_ => None,
}
}
async fn can_place_ladder_at(world: &World, block_pos: &BlockPos, facing: BlockDirection) -> bool {
fn can_place_ladder_at(world: &World, block_pos: &BlockPos, facing: BlockDirection) -> bool {
world
.get_block_state(&block_pos.offset(facing.to_offset()))
.await
.is_side_solid(facing.opposite())
}

View File

@ -38,7 +38,7 @@ impl BlockBehaviour for LanternBlock {
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()).await;
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;
}
@ -47,8 +47,8 @@ impl BlockBehaviour for LanternBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.world.unwrap(), args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.world.unwrap(), args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -56,7 +56,7 @@ impl BlockBehaviour for LanternBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -67,7 +67,7 @@ impl BlockBehaviour for LanternBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -76,25 +76,24 @@ impl BlockBehaviour for LanternBlock {
}
}
async fn can_place_at(world: &World, position: &BlockPos) -> bool {
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())
.await
.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()).await,
world.get_block(&position.down()).await,
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()).await;
let block_up_state = world.get_block_state(&position.up()).await;
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)

View File

@ -60,7 +60,7 @@ impl BlockBehaviour for LecternBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(lectern_entity) =
block_entity.as_any().downcast_ref::<LecternBlockEntity>()
{
@ -70,7 +70,7 @@ impl BlockBehaviour for LecternBlock {
// Need to find a proper way to give items to player. For now skip.
let mut props = LecternLikeProperties::from_state_id(
args.world.get_block_state(args.position).await.id,
args.world.get_block_state(args.position).id,
args.block,
);
Self::update_lectern_state(
@ -97,7 +97,7 @@ impl BlockBehaviour for LecternBlock {
// Check if it's a book
if item_stack.item.registry_key.contains("book")
&& let Some(block_entity) = args.world.get_block_entity(args.position).await
&& let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(lectern_entity) =
block_entity.as_any().downcast_ref::<LecternBlockEntity>()
&& lectern_entity.book.lock().await.is_empty()
@ -106,7 +106,7 @@ impl BlockBehaviour for LecternBlock {
lectern_entity.set_stack(0, book).await;
let mut props = LecternLikeProperties::from_state_id(
args.world.get_block_state(args.position).await.id,
args.world.get_block_state(args.position).id,
args.block,
);
Self::update_lectern_state(true, args.block, args.position, args.world, &mut props)
@ -119,7 +119,7 @@ impl BlockBehaviour for LecternBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if let Some(block_entity) = args.world.get_block_entity(args.position).await
if let Some(block_entity) = args.world.get_block_entity(args.position)
&& let Some(lectern_entity) =
block_entity.as_any().downcast_ref::<LecternBlockEntity>()
{
@ -135,7 +135,7 @@ impl BlockBehaviour for LecternBlock {
),
&EntityType::ITEM,
);
let item_entity = ItemEntity::new(entity, book).await;
let item_entity = ItemEntity::new(entity, book);
args.world.spawn_entity(Arc::new(item_entity)).await;
}
}

View File

@ -60,7 +60,6 @@ impl BlockBehaviour for NetherPortalBlock {
if is_horizontal_and_different
|| args.neighbor_state_id == args.state_id
|| NetherPortal::get_on_axis(args.world, args.position, state_axis)
.await
.is_some_and(|e| e.was_already_valid())
{
return args.state_id;

View File

@ -26,7 +26,7 @@ pub struct NoteBlock;
impl NoteBlock {
pub async fn play_note(props: &NoteBlockLikeProperties, world: &World, pos: &BlockPos) {
if !is_base_block(props.instrument) || world.get_block_state(&pos.up()).await.is_air() {
if !is_base_block(props.instrument) || world.get_block_state(&pos.up()).is_air() {
world.add_synced_block_event(*pos, 0, 0).await;
}
}
@ -34,20 +34,20 @@ impl NoteBlock {
((f32::from(note) - 12.0) / 12.0).exp2()
}
async fn get_state_with_instrument(
fn get_state_with_instrument(
world: &World,
pos: &BlockPos,
state: BlockStateId,
block: &Block,
) -> BlockStateId {
let upper_instrument = world.get_block_state(&pos.up()).await.instrument;
let upper_instrument = world.get_block_state(&pos.up()).instrument;
let mut note_props = NoteBlockLikeProperties::from_state_id(state, block);
if !is_base_block(upper_instrument) {
note_props.instrument = upper_instrument;
return note_props.to_state_id(block);
}
let below_instrument = world.get_block_state(&pos.down()).await.instrument;
let below_instrument = world.get_block_state(&pos.down()).instrument;
let below_instrument = if is_base_block(below_instrument) {
below_instrument
} else {
@ -61,7 +61,7 @@ impl NoteBlock {
impl BlockBehaviour for NoteBlock {
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let block_state = args.world.get_block_state(args.position).await;
let block_state = args.world.get_block_state(args.position);
let mut note_props = NoteBlockLikeProperties::from_state_id(block_state.id, args.block);
let powered = block_receives_redstone_power(args.world, args.position).await;
// check if powered state changed
@ -83,7 +83,7 @@ impl BlockBehaviour for NoteBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let block_state = args.world.get_block_state(args.position).await;
let block_state = args.world.get_block_state(args.position);
let mut note_props = NoteBlockLikeProperties::from_state_id(block_state.id, args.block);
note_props.note = (note_props.note + 1) % 25;
args.world
@ -114,7 +114,7 @@ impl BlockBehaviour for NoteBlock {
args: OnSyncedBlockEventArgs<'a>,
) -> BlockFuture<'a, bool> {
Box::pin(async move {
let block_state = args.world.get_block_state(args.position).await;
let block_state = args.world.get_block_state(args.position);
let note_props = NoteBlockLikeProperties::from_state_id(block_state.id, args.block);
let instrument = note_props.instrument;
let pitch = if is_base_block(instrument) {
@ -124,15 +124,13 @@ impl BlockBehaviour for NoteBlock {
1.0 // default pitch
};
// check hasCustomSound
args.world
.play_sound_raw(
convert_instrument_to_sound(instrument) as u16,
SoundCategory::Records,
&args.position.to_f64(),
3.0,
pitch,
)
.await;
args.world.play_sound_raw(
convert_instrument_to_sound(instrument) as u16,
SoundCategory::Records,
&args.position.to_f64(),
3.0,
pitch,
);
true
})
}
@ -145,7 +143,6 @@ impl BlockBehaviour for NoteBlock {
Block::NOTE_BLOCK.default_state.id,
args.block,
)
.await
})
}
@ -160,8 +157,7 @@ impl BlockBehaviour for NoteBlock {
args.position,
args.state_id,
args.block,
)
.await;
);
}
args.state_id
})

View File

@ -49,7 +49,7 @@ impl<'a> PistonHandler<'a> {
pub async fn calculate_push(&mut self) -> bool {
self.moved_blocks.clear();
self.broken_blocks.clear();
let (block, block_state) = self.world.get_block_and_state(&self.pos_to).await;
let (block, block_state) = self.world.get_block_and_state(&self.pos_to);
if !PistonBlock::is_movable(
block,
@ -69,7 +69,7 @@ impl<'a> PistonHandler<'a> {
}
for i in 0..self.moved_blocks.len() {
let block_pos = self.moved_blocks[i];
let block = self.world.get_block(&block_pos).await;
let block = self.world.get_block(&block_pos);
if Self::is_block_sticky(block)
&& !self.try_move_adjacent_block(block, &block_pos).await
{
@ -94,7 +94,7 @@ impl<'a> PistonHandler<'a> {
}
async fn try_move(&mut self, pos: BlockPos, dir: BlockDirection) -> bool {
let (block, block_state) = self.world.get_block_and_state(&pos).await;
let (block, block_state) = self.world.get_block_and_state(&pos);
if block_state.is_air() {
return true;
}
@ -114,7 +114,7 @@ impl<'a> PistonHandler<'a> {
while Self::is_block_sticky(block) {
let block_pos = pos.offset_dir(self.motion_direction.opposite().to_offset(), i as i32);
let block2 = block;
let (block, block_state) = self.world.get_block_and_state(&block_pos).await;
let (block, block_state) = self.world.get_block_and_state(&block_pos);
if block_state.is_air()
|| !Self::is_adjacent_block_stuck(block2, block)
|| !PistonBlock::is_movable(
@ -146,7 +146,7 @@ impl<'a> PistonHandler<'a> {
self.set_moved_blocks(j, l);
for m in 0..=(l + j) {
let block_pos3 = self.moved_blocks[m];
let block = self.world.get_block(&block_pos3).await;
let block = self.world.get_block(&block_pos3);
if Self::is_block_sticky(block)
&& !Box::pin(self.try_move_adjacent_block(block, &block_pos3)).await
{
@ -155,7 +155,7 @@ impl<'a> PistonHandler<'a> {
}
return true;
}
let (block, block_state) = self.world.get_block_and_state(&block_pos2).await;
let (block, block_state) = self.world.get_block_and_state(&block_pos2);
if block_state.is_air() {
return true;
}
@ -201,7 +201,7 @@ impl<'a> PistonHandler<'a> {
continue;
}
let block_pos = pos.offset(direction.to_offset());
let block_state2 = self.world.get_block(&block_pos).await;
let block_state2 = self.world.get_block(&block_pos);
if Self::is_adjacent_block_stuck(block_state2, block)
&& !self.try_move(block_pos, direction).await
{

View File

@ -91,8 +91,7 @@ impl BlockBehaviour for PistonBlock {
let pos = args
.position
.offset(props.facing.to_block_direction().to_offset());
let (block_to_check, block_to_check_state_id) =
args.world.get_block_and_state_id(&pos).await;
let (block_to_check, block_to_check_state_id) = args.world.get_block_and_state_id(&pos);
if &Block::PISTON_HEAD == block_to_check {
let head_props =
PistonHeadProperties::from_state_id(block_to_check_state_id, block_to_check);
@ -144,7 +143,7 @@ impl BlockBehaviour for PistonBlock {
args.data,
);
let state = world.get_block_state(pos).await;
let state = world.get_block_state(pos);
let mut props = PistonProps::from_state_id(state.id, block);
let dir = props.facing.to_block_direction();
@ -180,22 +179,20 @@ impl BlockBehaviour for PistonBlock {
.await;
// Play piston extend sound
let pitch = rand::rng().random_range(0.6f32..0.85);
world
.play_sound_fine(
Sound::BlockPistonExtend,
SoundCategory::Blocks,
&pos.to_centered_f64(),
0.5,
pitch,
)
.await;
world.play_sound_fine(
Sound::BlockPistonExtend,
SoundCategory::Blocks,
&pos.to_centered_f64(),
0.5,
pitch,
);
return true;
}
// Reduce Piston
let extended_pos = pos.offset(dir.to_offset());
if let Some(block_entity) = world.get_block_entity(&extended_pos).await
if let Some(block_entity) = world.get_block_entity(&extended_pos)
&& let Some(piston) = block_entity.as_any().downcast_ref::<PistonBlockEntity>()
{
piston.finish(world.clone()).await;
@ -237,9 +234,9 @@ impl BlockBehaviour for PistonBlock {
world.update_neighbors(pos, None).await;
if sticky {
let pull_pos = pos.offset_dir(dir.to_offset(), 2);
let (block, state) = world.get_block_and_state(&pull_pos).await;
let (block, state) = world.get_block_and_state(&pull_pos);
let piston_piece = if block == &Block::MOVING_PISTON
&& let Some(entity) = world.get_block_entity(&pull_pos).await
&& let Some(entity) = world.get_block_entity(&pull_pos)
&& let Some(piston) = entity.as_any().downcast_ref::<PistonBlockEntity>()
&& piston.facing == dir
&& piston.extending
@ -281,15 +278,13 @@ impl BlockBehaviour for PistonBlock {
}
// Play piston contract sound
let pitch = rand::rng().random_range(0.6f32..0.75);
world
.play_sound_fine(
Sound::BlockPistonContract,
SoundCategory::Blocks,
&pos.to_centered_f64(),
0.5,
pitch,
)
.await;
world.play_sound_fine(
Sound::BlockPistonContract,
SoundCategory::Blocks,
&pos.to_centered_f64(),
0.5,
pitch,
);
true
})
}
@ -298,7 +293,7 @@ impl BlockBehaviour for PistonBlock {
async fn should_extend(world: &World, block_pos: &BlockPos, piston_dir: BlockDirection) -> bool {
for dir in BlockDirection::all() {
let neighbor_pos = block_pos.offset(dir.to_offset());
let (block, state) = world.get_block_and_state(&neighbor_pos).await;
let (block, state) = world.get_block_and_state(&neighbor_pos);
// Pistons can't be powered from the same direction as they are facing
if dir == piston_dir
|| !is_emitting_redstone_power(block, state, world, &neighbor_pos, dir).await
@ -308,13 +303,13 @@ async fn should_extend(world: &World, block_pos: &BlockPos, piston_dir: BlockDir
return true;
}
let neighbor_pos = block_pos.offset(BlockDirection::Down.to_offset());
let (block, state) = world.get_block_and_state(&neighbor_pos).await;
let (block, state) = world.get_block_and_state(&neighbor_pos);
if is_emitting_redstone_power(block, state, world, block_pos, BlockDirection::Down).await {
return true;
}
for dir in BlockDirection::all() {
let neighbor_pos = block_pos.up().offset(dir.to_offset());
let (block, state) = world.get_block_and_state(&neighbor_pos).await;
let (block, state) = world.get_block_and_state(&neighbor_pos);
if dir == BlockDirection::Down
|| !is_emitting_redstone_power(block, state, world, &neighbor_pos, dir).await
{
@ -326,7 +321,7 @@ async fn should_extend(world: &World, block_pos: &BlockPos, piston_dir: BlockDir
}
pub async fn try_move(world: &Arc<World>, block: &Block, block_pos: &BlockPos) {
let state = world.get_block_state(block_pos).await;
let state = world.get_block_state(block_pos);
let props = PistonProps::from_state_id(state.id, block);
let dir = props.facing.to_block_direction();
let should_extent = should_extend(world, block_pos, dir).await;
@ -342,13 +337,13 @@ pub async fn try_move(world: &Arc<World>, block: &Block, block_pos: &BlockPos) {
}
} else if !should_extent && props.extended {
let new_pos = block_pos.offset_dir(dir.to_offset(), 2);
let (new_block, new_state) = world.get_block_and_state_id(&new_pos).await;
let (new_block, new_state) = world.get_block_and_state_id(&new_pos);
let mut r#type = 1;
if new_block == &Block::MOVING_PISTON {
let new_props = MovingPistonLikeProperties::from_state_id(new_state, new_block);
if new_props.facing == props.facing
&& let Some(entity) = world.get_block_entity(&new_pos).await
&& let Some(entity) = world.get_block_entity(&new_pos)
{
let piston = entity.as_any().downcast_ref::<PistonBlockEntity>().unwrap();
if piston.extending && piston.current_progress.load() < 0.5
@ -374,7 +369,7 @@ async fn move_piston(
sticky: bool,
) -> bool {
let extended_pos = block_pos.offset(dir.to_offset());
if !extend && world.get_block(&extended_pos).await == &Block::PISTON_HEAD {
if !extend && world.get_block(&extended_pos) == &Block::PISTON_HEAD {
world
.set_block_state(
&extended_pos,
@ -394,7 +389,7 @@ async fn move_piston(
let mut moved_block_states: Vec<&BlockState> = Vec::new();
for &block_pos in &moved_blocks {
let block_state = world.get_block_state(&block_pos).await;
let block_state = world.get_block_state(&block_pos);
moved_block_states.push(block_state);
moved_blocks_map.insert(block_pos, block_state);
}
@ -405,7 +400,7 @@ async fn move_piston(
let move_direction = if extend { dir } else { dir.opposite() };
for &broken_block_pos in broken_blocks.iter().rev() {
let block_state = world.get_block_state(&broken_block_pos).await;
let block_state = world.get_block_state(&broken_block_pos);
world
.break_block(
&broken_block_pos,
@ -417,7 +412,7 @@ async fn move_piston(
}
for (index, &moved_block_pos) in moved_blocks.iter().rev().enumerate() {
let block_state = world.get_block_state(&moved_block_pos).await;
let block_state = world.get_block_state(&moved_block_pos);
let target_pos = moved_block_pos.offset(move_direction.to_offset());
moved_blocks_map.remove(&target_pos);

View File

@ -20,7 +20,7 @@ impl BlockBehaviour for PistonExtensionBlock {
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).await;
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, new_block);
if props.extended {

View File

@ -21,7 +21,7 @@ impl BlockBehaviour for PistonHeadBlock {
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).await;
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, new_block);
if props.extended {
@ -35,7 +35,7 @@ impl BlockBehaviour for PistonHeadBlock {
}
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let head_state_id = args.world.get_block_state_id(args.position).await;
let head_state_id = args.world.get_block_state_id(args.position);
let head_props =
PistonHeadProperties::from_state_id(head_state_id, &Block::PISTON_HEAD);
if head_props.facing != Facing::Up {
@ -48,12 +48,12 @@ impl BlockBehaviour for PistonHeadBlock {
.to_block_direction()
.to_offset(),
);
let piston_block = args.world.get_block(&piston_pos).await;
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).await;
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).await;

View File

@ -27,10 +27,8 @@ pub struct BambooBlock;
impl BlockBehaviour for BambooBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let (block_below, state_id_below) = args
.world
.get_block_and_state_id(&args.position.down())
.await;
let (block_below, state_id_below) =
args.world.get_block_and_state_id(&args.position.down());
if block_below.has_tag(&MINECRAFT_SUPPORTS_BAMBOO) {
let mut props = BambooLikeProperties::from_state_id(
@ -47,7 +45,7 @@ impl BlockBehaviour for BambooBlock {
}
} else {
let (block_above, state_id_above) =
args.world.get_block_and_state_id(&args.position.up()).await;
args.world.get_block_and_state_id(&args.position.up());
if block_above == &Block::BAMBOO {
let props_above =
BambooLikeProperties::from_state_id(state_id_above, block_above);
@ -76,21 +74,17 @@ impl BlockBehaviour for BambooBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !<Self as PlantBlockBase>::can_place_at(self, args.world.as_ref(), args.position)
.await
{
if !<Self as PlantBlockBase>::can_place_at(self, args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
} else if args.world.get_block(&args.position.down()).await == &Block::BAMBOO_SAPLING {
} else if args.world.get_block(&args.position.down()) == &Block::BAMBOO_SAPLING {
args.world
.set_block_state(
&args.position.down(),
@ -107,12 +101,12 @@ impl BlockBehaviour for BambooBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !<Self as PlantBlockBase>::can_place_at(self, args.world, args.position).await {
if !<Self as PlantBlockBase>::can_place_at(self, args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
}
let neighbor_block = args.world.get_block(args.neighbor_position).await;
let neighbor_block = args.world.get_block(args.neighbor_position);
if args.direction == BlockDirection::Up && neighbor_block == &Block::BAMBOO {
let neighbor_props =
BambooLikeProperties::from_state_id(args.neighbor_state_id, neighbor_block);
@ -143,8 +137,8 @@ async fn update_leaves_and_grow(world: Arc<World>, position: &BlockPos) {
let below_pos = position.down();
let two_below_pos = position.down_height(2);
let (block, state_id) = world.get_block_and_state_id(position).await;
let state_above = world.get_block_state(&above_pos).await;
let (block, state_id) = world.get_block_and_state_id(position);
let state_above = world.get_block_state(&above_pos);
if !state_above.is_air() {
return;
@ -155,12 +149,12 @@ async fn update_leaves_and_grow(world: Arc<World>, position: &BlockPos) {
return;
}
let bamboo_count = count_bamboo_below(world.clone(), position).await;
let bamboo_count = count_bamboo_below(&world, position);
if bamboo_count >= 16 {
return;
}
let (block_below, state_id_below) = world.get_block_and_state_id(&below_pos).await;
let (block_two_below, state_id_two_below) = world.get_block_and_state_id(&two_below_pos).await;
let (block_below, state_id_below) = world.get_block_and_state_id(&below_pos);
let (block_two_below, state_id_two_below) = world.get_block_and_state_id(&two_below_pos);
let mut props_below = BambooLikeProperties::from_state_id(state_id_below, block_below);
@ -209,13 +203,13 @@ async fn update_leaves_and_grow(world: Arc<World>, position: &BlockPos) {
.await;
}
async fn count_bamboo_below(world: Arc<World>, pos: &BlockPos) -> usize {
fn count_bamboo_below(world: &World, pos: &BlockPos) -> usize {
let mut bamboo_count = 0;
let mut found_bamboo_below = true;
let mut current_position = pos.down();
while found_bamboo_below && bamboo_count < 16 {
found_bamboo_below = false;
if world.get_block(&current_position).await == &Block::BAMBOO {
if world.get_block(&current_position) == &Block::BAMBOO {
current_position = current_position.down();
bamboo_count += 1;
found_bamboo_below = true;
@ -224,13 +218,13 @@ async fn count_bamboo_below(world: Arc<World>, pos: &BlockPos) -> usize {
bamboo_count
}
async fn count_bamboo_above(world: Arc<World>, pos: &BlockPos) -> usize {
fn count_bamboo_above(world: &World, pos: &BlockPos) -> usize {
let mut bamboo_count = 0;
let mut found_bamboo_below = true;
let mut current_position = pos.up();
while found_bamboo_below && bamboo_count < 16 {
found_bamboo_below = false;
if world.get_block(&current_position).await == &Block::BAMBOO {
if world.get_block(&current_position) == &Block::BAMBOO {
current_position = current_position.up();
bamboo_count += 1;
found_bamboo_below = true;
@ -240,16 +234,15 @@ async fn count_bamboo_above(world: Arc<World>, pos: &BlockPos) -> usize {
}
async fn bone_meal(world: Arc<World>, position: &BlockPos) {
let mut bamboo_above = count_bamboo_above(Arc::clone(&world), position).await;
let bamboo_below = count_bamboo_below(Arc::clone(&world), position).await;
let bamboo_below = count_bamboo_below(&world, position);
let growth_amount = rand::rng().random_range(1..=3);
for _ in 0..growth_amount {
for (bamboo_above, _) in (count_bamboo_above(&world, position)..).zip(0..growth_amount) {
let current_total_height = bamboo_above + bamboo_below + 1;
let next_pos = position.up_height(bamboo_above as i32);
let next_state = world.get_block_state(&next_pos).await;
let next_state = world.get_block_state(&next_pos);
if !next_state.is_air() || current_total_height >= 16 {
return;
@ -261,22 +254,20 @@ async fn bone_meal(world: Arc<World>, position: &BlockPos) {
}
update_leaves_and_grow(Arc::clone(&world), position).await;
bamboo_above += 1;
}
}
impl PlantBlockBase for BambooBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let block = block_accessor.get_block(pos).await;
let block = block_accessor.get_block(pos);
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_BAMBOO)
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down()).await
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down())
}
}

View File

@ -22,11 +22,8 @@ use crate::block::{
pub struct BambooSaplingBlock;
impl BlockBehaviour for BambooSaplingBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, &args.position.down())
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, &args.position.down())
}
fn use_with_item<'a>(
@ -57,7 +54,7 @@ impl BlockBehaviour for BambooSaplingBlock {
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if args.block == &Block::BAMBOO_SAPLING
&& args.world.get_block(&args.position.up()).await == &Block::BAMBOO
&& args.world.get_block(&args.position.up()) == &Block::BAMBOO
{
args.world
.set_block_state(
@ -75,11 +72,11 @@ impl BlockBehaviour for BambooSaplingBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !<Self as PlantBlockBase>::can_place_at(self, args.world, args.position).await {
if !<Self as PlantBlockBase>::can_place_at(self, args.world, args.position) {
return Block::AIR.default_state.id;
}
if args.direction == BlockDirection::Up
&& args.world.get_block(args.neighbor_position).await == &Block::BAMBOO
&& args.world.get_block(args.neighbor_position) == &Block::BAMBOO
{
return Block::BAMBOO.default_state.id;
}
@ -89,7 +86,7 @@ impl BlockBehaviour for BambooSaplingBlock {
fn random_tick<'a>(&'a self, args: crate::block::RandomTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let state_above = args.world.get_block_state(&args.position.up()).await;
let state_above = args.world.get_block_state(&args.position.up());
if !state_above.is_air() || rand::rng().random_range(0..3) > 0 {
return;
}
@ -108,12 +105,12 @@ impl BlockBehaviour for BambooSaplingBlock {
}
impl PlantBlockBase for BambooSaplingBlock {
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down()).await
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down())
}
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
block.has_tag(&pumpkin_data::tag::Block::MINECRAFT_SUPPORTS_BAMBOO)
}
}

View File

@ -50,7 +50,7 @@ impl BlockBehaviour for BigDripleafBlock {
}
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
if block_receives_redstone_power(args.world, args.position).await {
reset_tilt(state.id, args.world, args.position).await;
} else {
@ -82,17 +82,13 @@ impl BlockBehaviour for BigDripleafBlock {
})
}
//TODO: onProjectileHit
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let (support_block, support_block_state_id) = args
.world
.get_block_and_state_id(&args.position.down())
.await;
let (support_block, support_block_state_id) =
args.world.get_block_and_state_id(&args.position.down());
let facing = if support_block == &Block::BIG_DRIPLEAF {
get_dripleaf_facing_dir(support_block_state_id)
} else {
@ -128,7 +124,7 @@ impl BlockBehaviour for BigDripleafBlock {
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if block_receives_redstone_power(args.world, args.position).await {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
reset_tilt(state_id, args.world, args.position).await;
}
})
@ -138,8 +134,7 @@ impl BlockBehaviour for BigDripleafBlock {
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.down();
let (support_block, support_state_id) =
args.world.get_block_and_state_id(&support_pos).await;
let (support_block, support_state_id) = args.world.get_block_and_state_id(&support_pos);
if support_block == &Block::BIG_DRIPLEAF {
let old_dripleaf_props = BigDripleafLikeProperties::from_state_id(
support_state_id,
@ -175,7 +170,7 @@ async fn set_tilt_and_schedule_tick(
) {
set_tilt(state_id, world, pos, tilt).await;
if let Some(tilt_sound) = sound_wrapper {
play_tilt_sound(world, pos, tilt_sound).await;
play_tilt_sound(world, pos, tilt_sound);
}
let tick_delay = match tilt {
Tilt::None => -1,
@ -193,19 +188,17 @@ async fn set_tilt_and_schedule_tick(
.await;
}
}
async fn play_tilt_sound(world: &Arc<World>, pos: &BlockPos, tilt_sound: Sound) {
fn play_tilt_sound(world: &Arc<World>, pos: &BlockPos, tilt_sound: Sound) {
let pitch = rand::rng().random_range(0.8f32..1.2f32);
let v = pos.as_vector3();
let position = Vector3::new(v.x as f64, v.y as f64, v.z as f64);
world
.play_sound_fine(tilt_sound, SoundCategory::Blocks, &position, 1f32, pitch)
.await;
world.play_sound_fine(tilt_sound, SoundCategory::Blocks, &position, 1f32, pitch);
}
async fn reset_tilt(state_id: BlockStateId, world: &Arc<World>, pos: &BlockPos) {
set_tilt(state_id, world, pos, Tilt::None).await;
let props = BigDripleafLikeProperties::from_state_id(state_id, &Block::BIG_DRIPLEAF);
if props.tilt != Tilt::None {
play_tilt_sound(world, pos, Sound::BlockBigDripleafTiltUp).await;
play_tilt_sound(world, pos, Sound::BlockBigDripleafTiltUp);
}
}
async fn set_tilt(state_id: BlockStateId, world: &Arc<World>, pos: &BlockPos, new_tilt: Tilt) {
@ -234,8 +227,8 @@ fn is_dripleaf_waterlogged(state_id: BlockStateId) -> bool {
dripleaf_props.waterlogged
}
impl PlantBlockBase for BigDripleafBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_block = block_accessor.get_block(pos);
can_plant_dripleaf_on_top(support_block)
}
async fn get_state_for_neighbor_update(
@ -244,7 +237,7 @@ impl PlantBlockBase for BigDripleafBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
if is_dripleaf_waterlogged(block_state) {
return Block::WATER.default_state.id;
}

View File

@ -21,10 +21,8 @@ pub struct BigDripleafStemBlock;
pub type BigDripleafStemLikeProperties = LadderLikeProperties;
impl BlockBehaviour for BigDripleafStemBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -46,8 +44,8 @@ impl BlockBehaviour for BigDripleafStemBlock {
}
}
impl PlantBlockBase for BigDripleafStemBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_block = block_accessor.get_block(pos);
can_plant_dripleaf_on_top(support_block)
}
@ -57,8 +55,8 @@ impl PlantBlockBase for BigDripleafStemBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
let block = block_accessor.get_block(block_pos).await;
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
let block = block_accessor.get_block(block_pos);
let dripleaf_stem_props =
BigDripleafStemLikeProperties::from_state_id(block_state, block);
@ -72,7 +70,7 @@ impl PlantBlockBase for BigDripleafStemBlock {
}
pub async fn handle_big_dripleaf_breaking(world: &Arc<World>, position: &BlockPos) {
let support_pos = position.down();
let (support_block, support_state_id) = world.get_block_and_state_id(&support_pos).await;
let (support_block, support_state_id) = world.get_block_and_state_id(&support_pos);
if support_block == &Block::BIG_DRIPLEAF_STEM {
let dripleaf_stem_props =
BigDripleafStemLikeProperties::from_state_id(support_state_id, support_block);

View File

@ -15,10 +15,8 @@ impl BlockMetadata for BushBlock {
}
impl BlockBehaviour for BushBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(

View File

@ -20,7 +20,7 @@ pub struct CactusBlock;
impl BlockBehaviour for CactusBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -31,19 +31,19 @@ impl BlockBehaviour for CactusBlock {
fn random_tick<'a>(&'a self, args: RandomTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let block_up = args.position.up();
if args.world.get_block_state(&block_up).await.is_air() {
let state = args.world.get_block_state(args.position).await;
if args.world.get_block_state(&block_up).is_air() {
let state = args.world.get_block_state(args.position);
let mut props = CactusLikeProperties::from_state_id(state.id, args.block);
let age = props.age;
let mut i = 1;
while args.world.get_block(&args.position.down_height(i)).await == &Block::CACTUS {
while args.world.get_block(&args.position.down_height(i)) == &Block::CACTUS {
i += 1;
if 1 == 3 && age == 15 {
return;
}
}
if age == 8 && can_place_at(args.world.as_ref(), &block_up).await {
if age == 8 && can_place_at(args.world.as_ref(), &block_up) {
let d = if i >= 3 { 0.25 } else { 0.1 };
if rand::rng().random_range(0.0..1.0) <= d {
args.world
@ -102,7 +102,7 @@ impl BlockBehaviour for CactusBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -112,21 +112,19 @@ impl BlockBehaviour for CactusBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
}
async fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
fn can_place_at(world: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
for direction in BlockDirection::horizontal() {
let (block, state) = world
.get_block_and_state(&block_pos.offset(direction.to_offset()))
.await;
let (block, state) = world.get_block_and_state(&block_pos.offset(direction.to_offset()));
if state.is_solid() || block == &Block::LAVA {
return false;
}
}
let block = world.get_block(&block_pos.down()).await;
let block = world.get_block(&block_pos.down());
(block == &Block::CACTUS || block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CACTUS))
&& !world.get_block_state(&block_pos.up()).await.is_liquid()
&& !world.get_block_state(&block_pos.up()).is_liquid()
}

View File

@ -11,10 +11,8 @@ use pumpkin_world::world::BlockAccessor;
pub struct CactusFlowerBlock;
impl BlockBehaviour for CactusFlowerBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -33,14 +31,13 @@ impl BlockBehaviour for CactusFlowerBlock {
}
impl PlantBlockBase for CactusFlowerBlock {
async fn can_place_at(
fn can_place_at(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let support_pos = pos.down();
let (support_block, support_block_state) =
block_accessor.get_block_and_state(&support_pos).await;
let (support_block, support_block_state) = block_accessor.get_block_and_state(&support_pos);
if supports_cactus_flower(support_block, support_block_state) {
return true;
}
@ -52,7 +49,7 @@ impl PlantBlockBase for CactusFlowerBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::AIR.default_state.id;
}
block_state

View File

@ -18,8 +18,8 @@ use crate::block::{
pub struct ChorusFlowerBlock;
impl BlockBehaviour for ChorusFlowerBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_survive(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_survive(args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -27,8 +27,7 @@ impl BlockBehaviour for ChorusFlowerBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if args.direction != BlockDirection::Up && !can_survive(args.world, args.position).await
{
if args.direction != BlockDirection::Up && !can_survive(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -39,7 +38,7 @@ impl BlockBehaviour for ChorusFlowerBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_survive(args.world.as_ref(), args.position).await {
if !can_survive(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -48,8 +47,8 @@ impl BlockBehaviour for ChorusFlowerBlock {
}
}
async fn can_survive(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(&pos.down()).await;
fn can_survive(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(&pos.down());
if block_below == &Block::CHORUS_PLANT
|| block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CHORUS_FLOWER)
@ -65,7 +64,7 @@ async fn can_survive(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool
// Exactly one horizontal neighbor must be a chorus plant stem.
let mut plant_count = 0u32;
for dir in BlockDirection::horizontal() {
let neighbor = block_accessor.get_block(&pos.offset(dir.to_offset())).await;
let neighbor = block_accessor.get_block(&pos.offset(dir.to_offset()));
if neighbor == &Block::CHORUS_PLANT {
plant_count += 1;
if plant_count > 1 {

View File

@ -23,12 +23,12 @@ impl BlockBehaviour for ChorusPlantBlock {
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
// Compute all 6 face connections immediately so the placed block visually connects to its neighbors.
get_state_with_connections(args.world, args.block, args.position).await
get_state_with_connections(args.world, args.block, args.position)
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_survive(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_survive(args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -36,7 +36,7 @@ impl BlockBehaviour for ChorusPlantBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_survive(args.world, args.position).await {
if !can_survive(args.world, args.position) {
// Schedule delayed destruction so the whole plant cascades down.
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
@ -45,7 +45,7 @@ impl BlockBehaviour for ChorusPlantBlock {
}
// Update the single face connection for the direction that changed.
let neighbor_block = args.world.get_block(args.neighbor_position).await;
let neighbor_block = args.world.get_block(args.neighbor_position);
let connect = neighbor_block == &Block::CHORUS_PLANT
|| neighbor_block == &Block::CHORUS_FLOWER
|| (args.direction == BlockDirection::Down
@ -69,7 +69,7 @@ impl BlockBehaviour for ChorusPlantBlock {
Box::pin(async move {
// Destroy if unsupported; breaking propagates neighbor-update callbacks
// to connected chorus blocks, which schedule their own ticks.
if !can_survive(args.world.as_ref(), args.position).await {
if !can_survive(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -78,7 +78,7 @@ impl BlockBehaviour for ChorusPlantBlock {
}
}
async fn get_state_with_connections(
fn get_state_with_connections(
block_accessor: &dyn BlockAccessor,
block: &Block,
pos: &BlockPos,
@ -89,20 +89,12 @@ async fn get_state_with_connections(
let connects = |b: &Block| b.id == plant_id || b.id == flower_id;
let block_down = block_accessor.get_block(&pos.down()).await;
let block_up = block_accessor.get_block(&pos.up()).await;
let block_north = block_accessor
.get_block(&pos.offset(BlockDirection::North.to_offset()))
.await;
let block_east = block_accessor
.get_block(&pos.offset(BlockDirection::East.to_offset()))
.await;
let block_south = block_accessor
.get_block(&pos.offset(BlockDirection::South.to_offset()))
.await;
let block_west = block_accessor
.get_block(&pos.offset(BlockDirection::West.to_offset()))
.await;
let block_down = block_accessor.get_block(&pos.down());
let block_up = block_accessor.get_block(&pos.up());
let block_north = block_accessor.get_block(&pos.offset(BlockDirection::North.to_offset()));
let block_east = block_accessor.get_block(&pos.offset(BlockDirection::East.to_offset()));
let block_south = block_accessor.get_block(&pos.offset(BlockDirection::South.to_offset()));
let block_west = block_accessor.get_block(&pos.offset(BlockDirection::West.to_offset()));
let props = BrownMushroomBlockLikeProperties {
down: connects(block_down) || block_down.has_tag(supports),
@ -115,12 +107,12 @@ async fn get_state_with_connections(
props.to_state_id(block)
}
async fn can_survive(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
fn can_survive(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let below_pos = pos.down();
let above_pos = pos.up();
let (block_below, state_below) = block_accessor.get_block_and_state(&below_pos).await;
let state_above = block_accessor.get_block_state(&above_pos).await;
let (block_below, state_below) = block_accessor.get_block_and_state(&below_pos);
let state_above = block_accessor.get_block_state(&above_pos);
// A horizontal branch is invalid when both the block immediately above and
// below this one are non-air (enclosed inside something).
@ -128,12 +120,12 @@ async fn can_survive(block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool
for dir in BlockDirection::horizontal() {
let neighbor_pos = pos.offset(dir.to_offset());
let neighbor_block = block_accessor.get_block(&neighbor_pos).await;
let neighbor_block = block_accessor.get_block(&neighbor_pos);
if neighbor_block == &Block::CHORUS_PLANT {
if block_above_or_below {
return false;
}
let neighbor_below = block_accessor.get_block(&neighbor_pos.down()).await;
let neighbor_below = block_accessor.get_block(&neighbor_pos.down());
if neighbor_below == &Block::CHORUS_PLANT
|| neighbor_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CHORUS_PLANT)
{

View File

@ -16,15 +16,8 @@ type BeetrootProperties = NetherWartLikeProperties;
pub struct BeetrootBlock;
impl BlockBehaviour for BeetrootBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as CropBlockBase>::can_plant_on_top(
self,
args.block_accessor,
&args.position.down(),
)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as CropBlockBase>::can_plant_on_top(self, args.block_accessor, &args.position.down())
}
fn get_state_for_neighbor_update<'a>(

View File

@ -11,15 +11,8 @@ use crate::block::{
pub struct CarrotBlock;
impl BlockBehaviour for CarrotBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as CropBlockBase>::can_plant_on_top(
self,
args.block_accessor,
&args.position.down(),
)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as CropBlockBase>::can_plant_on_top(self, args.block_accessor, &args.position.down())
}
fn get_state_for_neighbor_update<'a>(

View File

@ -45,10 +45,8 @@ impl AttachedStemBlock {
}
impl BlockBehaviour for AttachedStemBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -76,8 +74,8 @@ impl BlockBehaviour for AttachedStemBlock {
}
impl PlantBlockBase for AttachedStemBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
if block == &Block::ATTACHED_PUMPKIN_STEM {
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_PUMPKIN_STEM)
} else {

View File

@ -58,10 +58,8 @@ impl StemBlock {
}
impl BlockBehaviour for StemBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -84,7 +82,7 @@ impl BlockBehaviour for StemBlock {
// TODO add light level check
let f: f32 = get_available_moisture(args.world, args.position, args.block).await;
if rand::rng().random_range(0..=(25.0 / f).floor() as i32) == 0 {
let (block, state) = args.world.get_block_and_state_id(args.position).await;
let (block, state) = args.world.get_block_and_state_id(args.position);
let props = StemProperties::from_state_id(state, block);
let age = i32::from(props.age);
if age < 7 {
@ -100,8 +98,8 @@ impl BlockBehaviour for StemBlock {
Xoroshiro::from_seed(rand::rng().random()),
));
let plant_block_pos = args.position.offset(dir.to_offset());
let plant_block_state = args.world.get_block_state(&plant_block_pos).await;
let under_block: &Block = args.world.get_block(&plant_block_pos.down()).await;
let plant_block_state = args.world.get_block_state(&plant_block_pos);
let under_block: &Block = args.world.get_block(&plant_block_pos.down());
if plant_block_state.is_air()
&& (under_block == &Block::FARMLAND
|| under_block.has_tag(&tag::Block::MINECRAFT_DIRT))
@ -130,8 +128,8 @@ impl BlockBehaviour for StemBlock {
}
impl PlantBlockBase for StemBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
if block == &Block::PUMPKIN_STEM {
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_PUMPKIN_STEM)
} else {

View File

@ -30,8 +30,8 @@ pub mod torch_flower;
pub mod wheat;
trait CropBlockBase: PlantBlockBase {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
block == &Block::FARMLAND
}
@ -51,7 +51,7 @@ trait CropBlockBase: PlantBlockBase {
}
async fn random_tick(&self, world: &Arc<World>, pos: &BlockPos) {
let (block, state) = world.get_block_and_state_id(pos).await;
let (block, state) = world.get_block_and_state_id(pos);
let age = self.get_age(state, block);
if age < self.max_age() {
let f = get_available_moisture(world, pos, block).await;
@ -90,9 +90,8 @@ pub async fn get_available_moisture(world: &Arc<World>, pos: &BlockPos, block: &
for dz in -1..=1 {
let mut local_moisture = 0.0;
let (block, block_state) = world
.get_block_and_state_id(&down_pos.offset(Vector3 { x: dx, y: 0, z: dz }))
.await;
let (block, block_state) =
world.get_block_and_state_id(&down_pos.offset(Vector3 { x: dx, y: 0, z: dz }));
if block == &Block::FARMLAND {
local_moisture = 1.0;
let props = FarmlandProperties::from_state_id(block_state, block);
@ -113,13 +112,13 @@ pub async fn get_available_moisture(world: &Arc<World>, pos: &BlockPos, block: &
let south = pos.offset(South.to_offset());
let west = pos.offset(West.to_offset());
let east = pos.offset(East.to_offset());
let horizontal = world.get_block(&west).await == block || world.get_block(&east).await == block;
let vertical = world.get_block(&north).await == block || world.get_block(&south).await == block;
let horizontal = world.get_block(&west) == block || world.get_block(&east) == block;
let vertical = world.get_block(&north) == block || world.get_block(&south) == block;
if (horizontal && vertical)
|| world.get_block(&west.offset(North.to_offset())).await == block
|| world.get_block(&east.offset(North.to_offset())).await == block
|| world.get_block(&east.offset(South.to_offset())).await == block
|| world.get_block(&west.offset(South.to_offset())).await == block
|| world.get_block(&west.offset(North.to_offset())) == block
|| world.get_block(&east.offset(North.to_offset())) == block
|| world.get_block(&east.offset(South.to_offset())) == block
|| world.get_block(&west.offset(South.to_offset())) == block
{
moisture /= 2.0;
}

View File

@ -25,10 +25,8 @@ use crate::{
pub struct NetherWartBlock;
impl BlockBehaviour for NetherWartBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -54,19 +52,19 @@ impl BlockBehaviour for NetherWartBlock {
}
impl PlantBlockBase for NetherWartBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_NETHER_WART)
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down()).await
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down())
}
}
impl CropBlockBase for NetherWartBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, pos).await
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, pos)
}
fn max_age(&self) -> i32 {
@ -85,7 +83,7 @@ impl CropBlockBase for NetherWartBlock {
}
async fn random_tick(&self, world: &Arc<World>, pos: &BlockPos) {
let (block, state) = world.get_block_and_state_id(pos).await;
let (block, state) = world.get_block_and_state_id(pos);
let age = self.get_age(state, block);
if age < self.max_age() && rand::rng().random_range(0..=10) == 0 {
world

View File

@ -11,15 +11,8 @@ use crate::block::{
pub struct PotatoBlock;
impl BlockBehaviour for PotatoBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as CropBlockBase>::can_plant_on_top(
self,
args.block_accessor,
&args.position.down(),
)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as CropBlockBase>::can_plant_on_top(self, args.block_accessor, &args.position.down())
}
fn get_state_for_neighbor_update<'a>(

View File

@ -32,7 +32,7 @@ pub struct SweetBerryBushBlock;
impl BlockBehaviour for SweetBerryBushBlock {
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let mut props = NetherWartLikeProperties::from_state_id(state_id, args.block);
match props.age {
2 | 3 => {
@ -66,7 +66,7 @@ impl BlockBehaviour for SweetBerryBushBlock {
args: UseWithItemArgs<'a>,
) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let props = NetherWartLikeProperties::from_state_id(state_id, &Block::SWEET_BERRY_BUSH);
if props.age != 3 && args.item_stack.lock().await.get_item() == &Item::BONE_MEAL {
BlockActionResult::Pass
@ -76,10 +76,8 @@ impl BlockBehaviour for SweetBerryBushBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -119,7 +117,7 @@ impl BlockBehaviour for SweetBerryBushBlock {
entity.last_pos.load() - entity.pos.load()
};
let state_id = args.world.get_block_state_id(args.position).await;
let state_id = args.world.get_block_state_id(args.position);
let props = NetherWartLikeProperties::from_state_id(state_id, args.block);
if props.age == 0 {
return;
@ -153,20 +151,20 @@ impl PlantBlockBase for SweetBerryBushBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::AIR.default_state.id;
}
block_state
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down()).await
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down())
}
}
impl CropBlockBase for SweetBerryBushBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, pos).await
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, pos)
}
fn max_age(&self) -> i32 {
@ -185,10 +183,10 @@ impl CropBlockBase for SweetBerryBushBlock {
}
async fn random_tick(&self, world: &Arc<World>, pos: &BlockPos) {
let (block, state) = world.get_block_and_state_id(pos).await;
let (block, state) = world.get_block_and_state_id(pos);
let age = self.get_age(state, block);
if age < self.max_age() {
let state_above = world.get_block_state(&pos.up()).await;
let state_above = world.get_block_state(&pos.up());
if state_above.is_full_cube() || state_above.is_solid() {
return;

View File

@ -16,15 +16,8 @@ type TorchFlowerProperties = TorchflowerCropLikeProperties;
pub struct TorchFlowerBlock;
impl BlockBehaviour for TorchFlowerBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as CropBlockBase>::can_plant_on_top(
self,
args.block_accessor,
&args.position.down(),
)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as CropBlockBase>::can_plant_on_top(self, args.block_accessor, &args.position.down())
}
fn get_state_for_neighbor_update<'a>(

View File

@ -11,15 +11,8 @@ use crate::block::{
pub struct WheatBlock;
impl BlockBehaviour for WheatBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as CropBlockBase>::can_plant_on_top(
self,
args.block_accessor,
&args.position.down(),
)
.await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as CropBlockBase>::can_plant_on_top(self, args.block_accessor, &args.position.down())
}
fn get_state_for_neighbor_update<'a>(

View File

@ -22,10 +22,8 @@ impl BlockMetadata for DryVegetationBlock {
}
impl BlockBehaviour for DryVegetationBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -45,12 +43,8 @@ impl BlockBehaviour for DryVegetationBlock {
}
impl PlantBlockBase for DryVegetationBlock {
async fn can_plant_on_top(
&self,
block_accessor: &dyn BlockAccessor,
block_pos: &BlockPos,
) -> bool {
let block_below = block_accessor.get_block(block_pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(block_pos);
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_DRY_VEGETATION)
}
}

View File

@ -19,10 +19,8 @@ impl BlockMetadata for FlowerBlock {
}
impl BlockBehaviour for FlowerBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(

View File

@ -22,19 +22,17 @@ impl BlockMetadata for FlowerbedBlock {
}
impl BlockBehaviour for FlowerbedBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let block_below = args.block_accessor.get_block(&args.position.down()).await;
block_below.has_tag(&tag::Block::MINECRAFT_DIRT) || block_below == &Block::FARMLAND
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
let block_below = args.block_accessor.get_block(&args.position.down());
block_below.has_tag(&tag::Block::MINECRAFT_DIRT) || block_below == &Block::FARMLAND
}
fn can_update_at<'a>(&'a self, args: CanUpdateAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { Segmented::can_update_at(self, args).await })
fn can_update_at(&self, args: CanUpdateAtArgs<'_>) -> bool {
Segmented::can_update_at(self, args)
}
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move { Segmented::on_place(self, args).await })
Segmented::on_place(self, args)
}
fn get_state_for_neighbor_update<'a>(

View File

@ -14,10 +14,8 @@ impl BlockMetadata for FungusBlock {
}
impl BlockBehaviour for FungusBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -35,19 +33,19 @@ impl BlockBehaviour for FungusBlock {
}
}
impl PlantBlockBase for FungusBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let block = block_accessor.get_block(pos).await;
let block = block_accessor.get_block(pos);
if block == &Block::WARPED_FUNGUS {
return block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_WARPED_FUNGUS);
}
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_CRIMSON_FUNGUS)
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down()).await
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
<Self as PlantBlockBase>::can_plant_on_top(self, block_accessor, &block_pos.down())
}
}

View File

@ -18,10 +18,8 @@ impl BlockMetadata for KelpBlock {
}
impl BlockBehaviour for KelpBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -40,7 +38,7 @@ impl BlockBehaviour for KelpBlock {
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.down();
let support_block = args.world.get_block(&support_pos).await;
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::KELP {
args.world
.set_block_state(
@ -55,7 +53,7 @@ impl BlockBehaviour for KelpBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.down();
let support_block = args.world.get_block(&support_pos).await;
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::KELP_PLANT {
args.world
.set_block_state(
@ -77,7 +75,7 @@ impl BlockBehaviour for KelpBlock {
}
impl PlantBlockBase for KelpBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
@ -85,9 +83,8 @@ impl PlantBlockBase for KelpBlock {
// Determine support block
let support_pos = pos;
let (replacing_block, replacing_block_state) =
block_accessor.get_block_and_state(&pos.up()).await;
let (support_block, support_block_state) =
block_accessor.get_block_and_state(support_pos).await;
block_accessor.get_block_and_state(&pos.up());
let (support_block, support_block_state) = block_accessor.get_block_and_state(support_pos);
if replacing_block == &Block::WATER {
let water_props =
WaterLikeProperties::from_state_id(replacing_block_state.id, replacing_block);
@ -122,7 +119,7 @@ impl PlantBlockBase for KelpBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::WATER.default_state.id;
}
block_state

View File

@ -19,18 +19,13 @@ impl BlockMetadata for LeafLitterBlock {
}
impl BlockBehaviour for LeafLitterBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let block_below = args
.block_accessor
.get_block_state(&args.position.down())
.await;
block_below.is_side_solid(BlockDirection::Up)
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
let block_below = args.block_accessor.get_block_state(&args.position.down());
block_below.is_side_solid(BlockDirection::Up)
}
fn can_update_at<'a>(&'a self, args: CanUpdateAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { Segmented::can_update_at(self, args).await })
fn can_update_at(&self, args: CanUpdateAtArgs<'_>) -> bool {
Segmented::can_update_at(self, args)
}
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
@ -43,7 +38,7 @@ impl BlockBehaviour for LeafLitterBlock {
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if args.direction == BlockDirection::Down {
let block_below_state = args.world.get_block_state(&args.position.down()).await;
let block_below_state = args.world.get_block_state(&args.position.down());
if !block_below_state.is_side_solid(BlockDirection::Up) {
return Block::AIR.default_state.id;
}

View File

@ -31,10 +31,8 @@ impl BlockBehaviour for LilyPadBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -54,10 +52,10 @@ impl BlockBehaviour for LilyPadBlock {
}
impl PlantBlockBase for LilyPadBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
// TODO: get and use fluids not blocks
let block = block_accessor.get_block(pos).await;
let above_fluid = block_accessor.get_block(&pos.up()).await;
let block = block_accessor.get_block(pos);
let above_fluid = block_accessor.get_block(&pos.up());
(block.has_tag(&tag::Fluid::MINECRAFT_SUPPORTS_LILY_PAD)
|| block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_LILY_PAD))
&& above_fluid.is_air()

View File

@ -37,8 +37,8 @@ pub mod weeping_vines;
pub mod wither_rose;
trait PlantBlockBase {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_VEGETATION)
}
@ -48,14 +48,13 @@ trait PlantBlockBase {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !self.can_place_at(block_accessor, block_pos).await {
if !self.can_place_at(block_accessor, block_pos) {
return Block::AIR.default_state.id;
}
block_state
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
self.can_plant_on_top(block_accessor, &block_pos.down())
.await
}
}

View File

@ -17,10 +17,8 @@ impl BlockMetadata for MushroomPlantBlock {
}
impl BlockBehaviour for MushroomPlantBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -40,8 +38,8 @@ impl BlockBehaviour for MushroomPlantBlock {
}
impl PlantBlockBase for MushroomPlantBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block = block_accessor.get_block(pos);
block.has_tag(&tag::Block::MINECRAFT_OVERRIDES_MUSHROOM_LIGHT_REQUIREMENT)
// TODO: Check light level and isOpaqueFullCube
}

View File

@ -7,10 +7,8 @@ use pumpkin_world::BlockStateId;
pub struct NetherSproutsBlock;
impl BlockBehaviour for NetherSproutsBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -28,12 +26,12 @@ impl BlockBehaviour for NetherSproutsBlock {
}
}
impl PlantBlockBase for NetherSproutsBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let block = block_accessor.get_block(pos).await;
let block = block_accessor.get_block(pos);
block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_NETHER_SPROUTS)
}
}

View File

@ -18,10 +18,8 @@ impl BlockMetadata for RootsBlock {
}
impl BlockBehaviour for RootsBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -41,8 +39,8 @@ impl BlockBehaviour for RootsBlock {
}
impl PlantBlockBase for RootsBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(pos);
if block_below == &Block::WARPED_ROOTS {
block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_WARPED_ROOTS)
} else {
@ -50,8 +48,7 @@ impl PlantBlockBase for RootsBlock {
}
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
self.can_plant_on_top(block_accessor, &block_pos.down())
.await
}
}

View File

@ -18,7 +18,7 @@ pub struct SaplingBlock;
impl SaplingBlock {
async fn generate(&self, world: &Arc<World>, pos: &BlockPos) {
let (block, state) = world.get_block_and_state_id(pos).await;
let (block, state) = world.get_block_and_state_id(pos);
let mut props = SaplingProperties::from_state_id(state, block);
if props.stage == 0 {
props.stage = 1;
@ -32,10 +32,8 @@ impl SaplingBlock {
}
impl BlockBehaviour for SaplingBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(

View File

@ -32,10 +32,9 @@ impl BlockBehaviour for SeaPickleBlock {
|| !args
.world
.get_block(&args.position.down())
.await
.has_tag(&tag::Block::MINECRAFT_CORAL_BLOCKS)
|| !SeaPickleProperties::from_state_id(
args.world.get_block_state_id(args.position).await,
args.world.get_block_state_id(args.position),
args.block,
)
.waterlogged
@ -62,11 +61,10 @@ impl BlockBehaviour for SeaPickleBlock {
);
if &lv == args.position
|| rand::rng().random_range(0..6) != 0
|| !args.world.get_block(&lv).await.eq(&Block::WATER)
|| !args.world.get_block(&lv).eq(&Block::WATER)
|| !args
.world
.get_block(&lv.down())
.await
.has_tag(&tag::Block::MINECRAFT_CORAL_BLOCKS)
{
continue;
@ -124,21 +122,14 @@ impl BlockBehaviour for SeaPickleBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let support_block = args
.block_accessor
.get_block_state(&args.position.down())
.await;
support_block.is_center_solid(BlockDirection::Up)
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
let support_block = args.block_accessor.get_block_state(&args.position.down());
support_block.is_center_solid(BlockDirection::Up)
}
fn can_update_at<'a>(&'a self, args: CanUpdateAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
args.player.get_entity().pose.load() != EntityPose::Crouching
&& SeaPickleProperties::from_state_id(args.state_id, args.block).pickles < 4
})
fn can_update_at(&self, args: CanUpdateAtArgs<'_>) -> bool {
args.player.get_entity().pose.load() != EntityPose::Crouching
&& SeaPickleProperties::from_state_id(args.state_id, args.block).pickles < 4
}
fn get_state_for_neighbor_update<'a>(

View File

@ -13,10 +13,8 @@ use crate::block::{
#[pumpkin_block("minecraft:seagrass")]
pub struct SeaGrassBlock;
impl BlockBehaviour for SeaGrassBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -36,13 +34,13 @@ impl BlockBehaviour for SeaGrassBlock {
}
impl PlantBlockBase for SeaGrassBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let (support_block, support_block_state) = block_accessor.get_block_and_state(pos).await;
let replacing_block = block_accessor.get_block(&pos.up()).await;
let (support_block, support_block_state) = block_accessor.get_block_and_state(pos);
let replacing_block = block_accessor.get_block(&pos.up());
if replacing_block != &Block::WATER && replacing_block != &Block::SEAGRASS {
return false;
}
@ -57,7 +55,7 @@ impl PlantBlockBase for SeaGrassBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::WATER.default_state.id;
}
block_state

View File

@ -73,11 +73,9 @@ pub trait Segmented: BlockBehaviour {
}
}
fn can_update_at<'a>(&'a self, ctx: CanUpdateAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let current_props = Self::Properties::from_state_id(ctx.state_id, ctx.block);
self.can_add_segment(&current_props)
})
fn can_update_at(&self, ctx: CanUpdateAtArgs<'_>) -> bool {
let current_props = Self::Properties::from_state_id(ctx.state_id, ctx.block);
self.can_add_segment(&current_props)
}
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {

View File

@ -15,10 +15,8 @@ impl BlockMetadata for ShortPlantBlock {
}
impl BlockBehaviour for ShortPlantBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(

View File

@ -17,10 +17,8 @@ use pumpkin_world::world::{BlockAccessor, BlockFlags};
pub struct SmallDripleafBlock;
impl BlockBehaviour for SmallDripleafBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
@ -65,7 +63,7 @@ impl BlockBehaviour for SmallDripleafBlock {
let mut upper_small_dripleaf_props =
SmallDripleafLikeProperties::default(&Block::SMALL_DRIPLEAF);
let upper_block = args.world.get_block(&args.position.up()).await;
let upper_block = args.world.get_block(&args.position.up());
upper_small_dripleaf_props.facing = lower_small_dripleaf_props.facing;
upper_small_dripleaf_props.waterlogged = upper_block == &Block::WATER;
upper_small_dripleaf_props.half = DoubleBlockHalf::Upper;
@ -86,13 +84,13 @@ fn is_small_dripleaf_waterlogged(state_id: BlockStateId) -> bool {
dripleaf_props.waterlogged
}
impl PlantBlockBase for SmallDripleafBlock {
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_block = block_accessor.get_block(pos).await;
fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
let support_block = block_accessor.get_block(pos);
if support_block == &Block::SMALL_DRIPLEAF {
return true;
}
let upper_block = block_accessor.get_block(&pos.up_height(2)).await;
let upper_block = block_accessor.get_block(&pos.up_height(2));
if upper_block != &Block::AIR
&& upper_block != &Block::WATER
&& upper_block != &Block::SMALL_DRIPLEAF
@ -100,7 +98,7 @@ impl PlantBlockBase for SmallDripleafBlock {
return false;
}
let (replacing_block, replacing_block_state) =
block_accessor.get_block_and_state(&pos.up()).await;
block_accessor.get_block_and_state(&pos.up());
if replacing_block == &Block::SMALL_DRIPLEAF && replacing_block_state.is_waterlogged() {
//in case of neighbor update check
supports_small_dripleaf(support_block, true)
@ -115,14 +113,14 @@ impl PlantBlockBase for SmallDripleafBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
if is_small_dripleaf_waterlogged(block_state) {
return Block::WATER.default_state.id;
}
return Block::AIR.default_state.id;
}
let upper_block = block_accessor.get_block(&block_pos.up()).await;
let below_blow = block_accessor.get_block(&block_pos.down()).await;
let upper_block = block_accessor.get_block(&block_pos.up());
let below_blow = block_accessor.get_block(&block_pos.down());
if upper_block != &Block::SMALL_DRIPLEAF && below_blow != &Block::SMALL_DRIPLEAF {
if is_small_dripleaf_waterlogged(block_state) {
return Block::WATER.default_state.id;

View File

@ -11,10 +11,8 @@ use pumpkin_world::world::BlockAccessor;
pub struct SporeBlossomBlock;
impl BlockBehaviour for SporeBlossomBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -32,15 +30,15 @@ impl BlockBehaviour for SporeBlossomBlock {
}
}
impl PlantBlockBase for SporeBlossomBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
_block_accessor: &dyn pumpkin_world::world::BlockAccessor,
_pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
false
}
async fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let ceiling_block = block_accessor.get_block(&block_pos.up()).await;
fn can_place_at(&self, block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let ceiling_block = block_accessor.get_block(&block_pos.up());
supports_spore_blossom(ceiling_block)
}
}

View File

@ -22,7 +22,7 @@ pub struct SugarCaneBlock;
impl BlockBehaviour for SugarCaneBlock {
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if !can_place_at(args.world.as_ref(), args.position).await {
if !can_place_at(args.world.as_ref(), args.position) {
args.world
.break_block(args.position, None, BlockFlags::empty())
.await;
@ -32,16 +32,11 @@ impl BlockBehaviour for SugarCaneBlock {
fn random_tick<'a>(&'a self, args: RandomTickArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
if args
.world
.get_block_state(&args.position.up())
.await
.is_air()
&& !(args.world.get_block(&args.position.down()).await == &Block::SUGAR_CANE
&& args.world.get_block(&args.position.down().down()).await
== &Block::SUGAR_CANE)
if args.world.get_block_state(&args.position.up()).is_air()
&& !(args.world.get_block(&args.position.down()) == &Block::SUGAR_CANE
&& args.world.get_block(&args.position.down().down()) == &Block::SUGAR_CANE)
{
let state_id = args.world.get_block_state(args.position).await.id;
let state_id = args.world.get_block_state(args.position).id;
let age = CactusLikeProperties::from_state_id(state_id, args.block).age;
if age == 15 {
args.world
@ -74,7 +69,7 @@ impl BlockBehaviour for SugarCaneBlock {
args: GetStateForNeighborUpdateArgs<'a>,
) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
if !can_place_at(args.world, args.position).await {
if !can_place_at(args.world, args.position) {
args.world
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
.await;
@ -83,13 +78,13 @@ impl BlockBehaviour for SugarCaneBlock {
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move { can_place_at(args.block_accessor, args.position).await })
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
can_place_at(args.block_accessor, args.position)
}
}
async fn can_place_at(block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(&block_pos.down()).await;
fn can_place_at(block_accessor: &dyn BlockAccessor, block_pos: &BlockPos) -> bool {
let block_below = block_accessor.get_block(&block_pos.down());
if block_below == &Block::SUGAR_CANE {
return true;
@ -97,9 +92,7 @@ async fn can_place_at(block_accessor: &dyn BlockAccessor, block_pos: &BlockPos)
if block_below.has_tag(&tag::Block::MINECRAFT_SUPPORTS_SUGAR_CANE) {
for direction in HorizontalFacing::all() {
let block = block_accessor
.get_block(&block_pos.down().offset(direction.to_offset()))
.await;
let block = block_accessor.get_block(&block_pos.down().offset(direction.to_offset()));
// TODO: use fluid
if block.has_tag(&tag::Fluid::MINECRAFT_SUPPORTS_SUGAR_CANE_ADJACENTLY)
&& block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_SUGAR_CANE_ADJACENTLY)

View File

@ -32,32 +32,23 @@ impl BlockMetadata for TallPlantBlock {
}
impl BlockBehaviour for TallPlantBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
let up_pos = args.position.up();
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
let up_pos = args.position.up();
let upper_state = args.block_accessor.get_block_state(&up_pos).await;
let Some(world) = args.world else {
return <Self as PlantBlockBase>::can_place_at(
self,
args.block_accessor,
args.position,
)
.await
&& upper_state.is_air();
};
if up_pos.0.y > world.get_top_y() {
return false;
}
let upper_state = args.block_accessor.get_block_state(&up_pos);
let Some(world) = args.world else {
return <Self as PlantBlockBase>::can_place_at(
self,
args.block_accessor,
args.position,
)
.await
&& upper_state.is_air();
})
) && upper_state.is_air();
};
if up_pos.0.y > world.get_top_y() {
return false;
}
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
&& upper_state.is_air()
}
fn get_state_for_neighbor_update<'a>(
@ -71,14 +62,11 @@ impl BlockBehaviour for TallPlantBlock {
DoubleBlockHalf::Upper => (args.position.down_height(2), args.position.down()),
DoubleBlockHalf::Lower => (args.position.down(), args.position.up()),
};
if !<Self as PlantBlockBase>::can_place_at(self, args.world, &support_block_pos.up())
.await
{
if !<Self as PlantBlockBase>::can_place_at(self, args.world, &support_block_pos.up()) {
return Block::AIR.default_state.id;
}
let (other_block, other_state_id) =
args.world.get_block_and_state_id(&other_block_pos).await;
let (other_block, other_state_id) = args.world.get_block_and_state_id(&other_block_pos);
if Self::ids().contains(&other_block.id) {
let other_props =
TallSeagrassLikeProperties::from_state_id(other_state_id, other_block);
@ -117,8 +105,7 @@ impl BlockBehaviour for TallPlantBlock {
DoubleBlockHalf::Upper => args.position.down(),
DoubleBlockHalf::Lower => args.position.up(),
};
let (other_block, other_state_id) =
args.world.get_block_and_state_id(&other_block_pos).await;
let (other_block, other_state_id) = args.world.get_block_and_state_id(&other_block_pos);
if Self::ids().contains(&other_block.id) {
let other_props =
TallSeagrassLikeProperties::from_state_id(other_state_id, other_block);

View File

@ -10,10 +10,8 @@ use crate::block::{
#[pumpkin_block("minecraft:tall_seagrass")]
pub struct TallSeaGrassBlock;
impl BlockBehaviour for TallSeaGrassBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
@ -33,20 +31,20 @@ impl BlockBehaviour for TallSeaGrassBlock {
}
impl PlantBlockBase for TallSeaGrassBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let (support_block, support_block_state) = block_accessor.get_block_and_state(pos).await;
let replacing_block = block_accessor.get_block(&pos.up()).await;
let (support_block, support_block_state) = block_accessor.get_block_and_state(pos);
let replacing_block = block_accessor.get_block(&pos.up());
if replacing_block != &Block::WATER && replacing_block != &Block::TALL_SEAGRASS {
return false;
}
if replacing_block == &Block::TALL_SEAGRASS {
//only for blockupdate
let block_above = block_accessor.get_block(&pos.up_height(2)).await;
let block_above = block_accessor.get_block(&pos.up_height(2));
let is_support_seagrass_block = support_block == &Block::TALL_SEAGRASS;
let is_above_seagrass_block = block_above == &Block::TALL_SEAGRASS;
match (is_support_seagrass_block, is_above_seagrass_block) {
@ -68,7 +66,7 @@ impl PlantBlockBase for TallSeaGrassBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::WATER.default_state.id;
}
block_state

View File

@ -16,10 +16,8 @@ impl BlockMetadata for TwistingVinesBlock {
}
impl BlockBehaviour for TwistingVinesBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -38,7 +36,7 @@ impl BlockBehaviour for TwistingVinesBlock {
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.down();
let support_block = args.world.get_block(&support_pos).await;
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::TWISTING_VINES {
args.world
.set_block_state(
@ -53,7 +51,7 @@ impl BlockBehaviour for TwistingVinesBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.down();
let support_block = args.world.get_block(&support_pos).await;
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::TWISTING_VINES_PLANT {
args.world
.set_block_state(
@ -68,15 +66,14 @@ impl BlockBehaviour for TwistingVinesBlock {
}
impl PlantBlockBase for TwistingVinesBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
// Determine support block
let support_pos = pos;
let (support_block, support_block_state) =
block_accessor.get_block_and_state(support_pos).await;
let (support_block, support_block_state) = block_accessor.get_block_and_state(support_pos);
if support_block == &Block::TWISTING_VINES || support_block == &Block::TWISTING_VINES_PLANT
{
@ -95,7 +92,7 @@ impl PlantBlockBase for TwistingVinesBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::AIR.default_state.id;
}
block_state

View File

@ -16,10 +16,8 @@ impl BlockMetadata for WeepingVinesBlock {
}
impl BlockBehaviour for WeepingVinesBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -38,7 +36,7 @@ impl BlockBehaviour for WeepingVinesBlock {
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.up();
let support_block = args.world.get_block(&support_pos).await;
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::WEEPING_VINES {
args.world
.set_block_state(
@ -53,7 +51,7 @@ impl BlockBehaviour for WeepingVinesBlock {
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
let support_pos = args.position.up();
let support_block = args.world.get_block(&support_pos).await;
let support_block = args.world.get_block(&support_pos);
if support_block == &Block::WEEPING_VINES_PLANT {
args.world
.set_block_state(
@ -68,15 +66,14 @@ impl BlockBehaviour for WeepingVinesBlock {
}
impl PlantBlockBase for WeepingVinesBlock {
async fn can_place_at(
fn can_place_at(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
// Determine support block
let support_pos = pos.up();
let (support_block, support_block_state) =
block_accessor.get_block_and_state(&support_pos).await;
let (support_block, support_block_state) = block_accessor.get_block_and_state(&support_pos);
if support_block == &Block::WEEPING_VINES || support_block == &Block::WEEPING_VINES_PLANT {
return true;
@ -94,7 +91,7 @@ impl PlantBlockBase for WeepingVinesBlock {
block_pos: &BlockPos,
block_state: BlockStateId,
) -> BlockStateId {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos).await {
if !<Self as PlantBlockBase>::can_place_at(self, block_accessor, block_pos) {
return Block::AIR.default_state.id;
}
block_state

View File

@ -42,10 +42,8 @@ impl BlockBehaviour for WitherRoseBlock {
}
})
}
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
})
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position)
}
fn get_state_for_neighbor_update<'a>(
&'a self,
@ -64,12 +62,12 @@ impl BlockBehaviour for WitherRoseBlock {
}
impl PlantBlockBase for WitherRoseBlock {
async fn can_plant_on_top(
fn can_plant_on_top(
&self,
block_accessor: &dyn pumpkin_world::world::BlockAccessor,
pos: &pumpkin_util::math::position::BlockPos,
) -> bool {
let support_block = block_accessor.get_block(pos).await;
let support_block = block_accessor.get_block(pos);
support_block.has_tag(&tag::Block::MINECRAFT_SUPPORTS_WITHER_ROSE)
}
}

View File

@ -96,7 +96,7 @@ impl BlockBehaviour for PowderSnowBlock {
Sound::EntityGenericBigFall
};
living.entity.play_sound(sound).await;
living.entity.play_sound(sound);
}
})
}

View File

@ -42,8 +42,10 @@ impl crate::block::BlockBehaviour for PumpkinBlock {
args.position.to_f64(),
&EntityType::ITEM,
);
let item_entity =
Arc::new(ItemEntity::new(entity, ItemStack::new(4, &Item::PUMPKIN_SEEDS)).await);
let item_entity = Arc::new(ItemEntity::new(
entity,
ItemStack::new(4, &Item::PUMPKIN_SEEDS),
));
args.world.spawn_entity(item_entity).await;
// TODO: Deduct 1 durability from held shears (skip in Creative mode).
BlockActionResult::Consume

View File

@ -32,30 +32,24 @@ pub trait RedstoneGateBlockProperties {
}
pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlockProperties> {
// 💡 Converted async fn to fn returning BlockFuture
fn can_place_at<'a>(
&'a self,
world: &'a dyn BlockAccessor,
pos: BlockPos,
) -> BlockFuture<'a, bool>
// 💡 Converted async fn to fn
fn can_place_at(&self, world: &dyn BlockAccessor, pos: BlockPos) -> bool
where
Self: Send + Sync,
{
Box::pin(async move {
let under_pos = pos.down();
let under_state = world.get_block_state(&under_pos).await;
self.can_place_above(world, under_pos, under_state).await
})
let under_pos = pos.down();
let under_state = world.get_block_state(&under_pos);
self.can_place_above(world, under_pos, under_state)
}
// 💡 Converted async fn to fn returning BlockFuture
fn can_place_above<'a>(
&'a self,
_world: &'a dyn BlockAccessor,
// 💡 Converted async fn to fn
fn can_place_above(
&self,
_world: &dyn BlockAccessor,
_pos: BlockPos,
state: &'a BlockState,
) -> BlockFuture<'a, bool> {
Box::pin(async { state.is_side_solid(BlockDirection::Up) })
state: &BlockState,
) -> bool {
state.is_side_solid(BlockDirection::Up)
}
fn get_weak_redstone_power<'a>(&'a self, args: GetRedstonePowerArgs<'a>) -> BlockFuture<'a, u8>
@ -90,8 +84,8 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
Self: Send + Sync,
{
Box::pin(async move {
let state = args.world.get_block_state(args.position).await;
if RedstoneGateBlock::can_place_at(self, args.world.as_ref(), *args.position).await {
let state = args.world.get_block_state(args.position);
if RedstoneGateBlock::can_place_at(self, args.world.as_ref(), *args.position) {
self.update_powered(args.world, *args.position, state, args.block)
.await;
return;
@ -259,9 +253,8 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
Box::pin(async move {
let props = T::from_state_id(state.id, block);
let facing = props.get_facing().opposite();
let (target_block, target_state) = world
.get_block_and_state(&pos.offset(facing.to_offset()))
.await;
let (target_block, target_state) =
world.get_block_and_state(&pos.offset(facing.to_offset()));
if target_block == &Block::COMPARATOR {
let props = ComparatorLikeProperties::from_state_id(target_state.id, target_block);
props.facing != facing
@ -286,7 +279,7 @@ pub async fn get_power<T: BlockProperties + RedstoneGateBlockProperties + Send>(
let props = T::from_state_id(state_id, block);
let facing = props.get_facing();
let source_pos = pos.offset(facing.to_offset());
let (source_block, source_state) = world.get_block_and_state(&source_pos).await;
let (source_block, source_state) = world.get_block_and_state(&source_pos);
let source_level = get_redstone_power(
source_block,
source_state,
@ -314,7 +307,7 @@ async fn get_power_on_side(
only_gate: bool,
) -> u8 {
let side_pos = pos.offset(side.to_block_direction().to_offset());
let (side_block, side_state) = world.get_block_and_state(&side_pos).await;
let (side_block, side_state) = world.get_block_and_state(&side_pos);
if !only_gate || is_diode(side_block) {
world
.block_registry

View File

@ -21,31 +21,25 @@ use pumpkin_util::math::position::BlockPos;
use pumpkin_world::BlockStateId;
use pumpkin_world::world::BlockFlags;
async fn ring_bell(
position: BlockPos,
world: &Arc<World>,
hit_direction: Option<HorizontalFacing>,
) {
let (block, state_id) = world.get_block_and_state_id(&position).await;
fn ring_bell(position: BlockPos, world: &Arc<World>, hit_direction: Option<HorizontalFacing>) {
let (block, state_id) = world.get_block_and_state_id(&position);
let props = BellLikeProperties::from_state_id(state_id, block);
let direction = hit_direction.map_or(props.facing, |direction3| direction3);
if let Some(block_entity) = world.get_block_entity(&position).await
if let Some(block_entity) = world.get_block_entity(&position)
&& let Some(be) = block_entity.as_any().downcast_ref::<BellBlockEntity>()
{
be.activate(direction);
}
world
.play_sound_fine(
Sound::BlockBellUse,
SoundCategory::Blocks,
&position.to_centered_f64(),
1.0,
2.0,
)
.await;
world.play_sound_fine(
Sound::BlockBellUse,
SoundCategory::Blocks,
&position.to_centered_f64(),
1.0,
2.0,
);
//TODO Emit game event: BLOCK_CHANGE -> Send block update Packet
}
@ -73,10 +67,9 @@ fn is_point_on_bell(
}
}
async fn is_single_wall(position: BlockPos, facing: HorizontalFacing, world: &World) -> bool {
fn is_single_wall(position: BlockPos, facing: HorizontalFacing, world: &World) -> bool {
!world
.get_block(&position.offset(facing.to_offset()))
.await
.is_solid()
}
@ -97,28 +90,26 @@ impl WallMountedBlock for BellBlock {
}
impl BlockBehaviour for BellBlock {
fn can_place_at<'a>(&'a self, args: CanPlaceAtArgs<'a>) -> BlockFuture<'a, bool> {
Box::pin(async move {
if let Some(direction) = args.direction
&& let Some(world) = args.world
{
if direction == BlockDirection::Up {
let block: &Block = world.get_block(args.position).await;
fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
if let Some(direction) = args.direction
&& let Some(world) = args.world
{
if direction == BlockDirection::Up {
let block: &Block = world.get_block(args.position);
if block.has_tag(&tag::Block::MINECRAFT_UNSTABLE_BOTTOM_CENTER) {
false
} else {
let block_pos = args.position.offset(direction.to_offset());
let block_state = world.get_block_state(&block_pos).await;
block_state.is_center_solid(direction)
}
if block.has_tag(&tag::Block::MINECRAFT_UNSTABLE_BOTTOM_CENTER) {
false
} else {
WallMountedBlock::can_place_at(self, world, args.position, direction).await
let block_pos = args.position.offset(direction.to_offset());
let block_state = world.get_block_state(&block_pos);
block_state.is_center_solid(direction)
}
} else {
false
WallMountedBlock::can_place_at(self, world, args.position, direction)
}
})
} else {
false
}
}
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
@ -136,7 +127,7 @@ impl BlockBehaviour for BellBlock {
}
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
let props = BellLikeProperties::from_state_id(state.id, args.block);
@ -147,8 +138,7 @@ impl BlockBehaviour for BellBlock {
*args.position,
args.world,
args.hit.face.to_horizontal_facing(),
)
.await;
);
BlockActionResult::Success
})
@ -170,7 +160,7 @@ impl BlockBehaviour for BellBlock {
props.attachment = match block_face {
AttachFace::Wall => {
if is_single_wall(*args.position, props.facing.opposite(), args.world).await {
if is_single_wall(*args.position, props.facing.opposite(), args.world) {
BellAttachment::SingleWall
} else {
BellAttachment::DoubleWall
@ -189,7 +179,7 @@ impl BlockBehaviour for BellBlock {
let world: &World = args.world;
let is_receiving_power = block_receives_redstone_power(world, args.position).await;
let state = args.world.get_block_state(args.position).await;
let state = args.world.get_block_state(args.position);
let mut props = BellLikeProperties::from_state_id(state.id, args.block);
@ -205,7 +195,7 @@ impl BlockBehaviour for BellBlock {
.await;
if is_receiving_power {
ring_bell(*args.position, args.world, None).await;
ring_bell(*args.position, args.world, None);
}
}
})

Some files were not shown because too many files have changed in this diff Show More