diff --git a/pumpkin-protocol/src/server/play/mod.rs b/pumpkin-protocol/src/server/play/mod.rs index e4135dc2c..5b594591d 100644 --- a/pumpkin-protocol/src/server/play/mod.rs +++ b/pumpkin-protocol/src/server/play/mod.rs @@ -23,6 +23,7 @@ mod player_position; mod player_position_rotation; mod player_rotation; mod player_session; +mod set_command_block; mod set_creative_slot; mod set_held_item; mod swing_arm; @@ -55,6 +56,7 @@ pub use player_position::*; pub use player_position_rotation::*; pub use player_rotation::*; pub use player_session::*; +pub use set_command_block::*; pub use set_creative_slot::*; pub use set_held_item::*; pub use swing_arm::*; diff --git a/pumpkin-protocol/src/server/play/set_command_block.rs b/pumpkin-protocol/src/server/play/set_command_block.rs new file mode 100644 index 000000000..ea953ca05 --- /dev/null +++ b/pumpkin-protocol/src/server/play/set_command_block.rs @@ -0,0 +1,35 @@ +use pumpkin_data::packet::serverbound::PLAY_SET_COMMAND_BLOCK; +use pumpkin_macros::packet; +use pumpkin_util::math::position::BlockPos; +use serde::Deserialize; + +use crate::codec::var_int::VarInt; + +#[derive(Deserialize)] +#[packet(PLAY_SET_COMMAND_BLOCK)] +pub struct SSetCommandBlock { + pub pos: BlockPos, + pub command: String, + pub mode: VarInt, + pub flags: i8, +} + +pub enum CommandBlockMode { + Chain, + Repeating, + /// Redstone only + Impulse, +} + +impl TryFrom for CommandBlockMode { + type Error = (); + + fn try_from(value: VarInt) -> Result { + match value.0 { + 0 => Ok(Self::Chain), + 1 => Ok(Self::Repeating), + 2 => Ok(Self::Impulse), + _ => Err(()), + } + } +} diff --git a/pumpkin-world/src/block/entities/barrel.rs b/pumpkin-world/src/block/entities/barrel.rs index 39102be7f..f143b3b44 100644 --- a/pumpkin-world/src/block/entities/barrel.rs +++ b/pumpkin-world/src/block/entities/barrel.rs @@ -70,7 +70,6 @@ impl BlockEntity for BarrelBlockEntity { impl BarrelBlockEntity { pub const ID: &'static str = "minecraft:barrel"; pub fn new(position: BlockPos) -> Self { - println!("Creating barrel"); Self { position, items: from_fn(|_| Arc::new(Mutex::new(ItemStack::EMPTY))), diff --git a/pumpkin-world/src/block/entities/command_block.rs b/pumpkin-world/src/block/entities/command_block.rs new file mode 100644 index 000000000..26a2015a5 --- /dev/null +++ b/pumpkin-world/src/block/entities/command_block.rs @@ -0,0 +1,54 @@ +use std::sync::atomic::AtomicBool; + +use async_trait::async_trait; +use pumpkin_util::math::position::BlockPos; + +use super::BlockEntity; + +pub struct CommandBlockEntity { + pub position: BlockPos, + pub powered: AtomicBool, + _condition_met: AtomicBool, + _auto: AtomicBool, + pub dirty: AtomicBool, +} + +impl CommandBlockEntity { + pub const ID: &'static str = "minecraft:command_block"; + pub fn new(position: BlockPos) -> Self { + Self { + position, + powered: AtomicBool::new(false), + _condition_met: AtomicBool::new(false), + _auto: AtomicBool::new(false), + dirty: AtomicBool::new(false), + } + } +} + +#[async_trait] +impl BlockEntity for CommandBlockEntity { + fn identifier(&self) -> &'static str { + Self::ID + } + fn get_position(&self) -> BlockPos { + self.position + } + + fn from_nbt(_nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self + where + Self: Sized, + { + Self::new(position) + } + + async fn write_nbt(&self, _nbt: &mut pumpkin_nbt::compound::NbtCompound) {} + + fn is_dirty(&self) -> bool { + self.dirty.load(std::sync::atomic::Ordering::Relaxed) + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} diff --git a/pumpkin-world/src/block/entities/mod.rs b/pumpkin-world/src/block/entities/mod.rs index b7685ccbb..40595dcbf 100644 --- a/pumpkin-world/src/block/entities/mod.rs +++ b/pumpkin-world/src/block/entities/mod.rs @@ -16,6 +16,7 @@ use crate::{inventory::Inventory, world::SimpleWorld}; pub mod barrel; pub mod bed; pub mod chest; +pub mod command_block; pub mod comparator; pub mod piston; pub mod sign; diff --git a/pumpkin-world/src/block/entities/piston.rs b/pumpkin-world/src/block/entities/piston.rs index 7554b3b2c..cd309071e 100644 --- a/pumpkin-world/src/block/entities/piston.rs +++ b/pumpkin-world/src/block/entities/piston.rs @@ -33,7 +33,7 @@ impl PistonBlockEntity { if self.last_progress.load() < 1.0 { let pos = self.position; world.remove_block_entity(&pos).await; - if world.get_block(&pos).await.unwrap() == Block::MOVING_PISTON { + if world.get_block(&pos).await == Block::MOVING_PISTON { let state = if self.source { Block::AIR.default_state_id } else { @@ -72,7 +72,7 @@ impl BlockEntity for PistonBlockEntity { if current_progress >= 1.0 { let pos = self.position; world.remove_block_entity(&pos).await; - if world.get_block(&pos).await.unwrap() == Block::MOVING_PISTON { + if world.get_block(&pos).await == Block::MOVING_PISTON { if self.pushed_block_state.is_air() { world .clone() diff --git a/pumpkin-world/src/world.rs b/pumpkin-world/src/world.rs index 61de2b9f0..d7f062dca 100644 --- a/pumpkin-world/src/world.rs +++ b/pumpkin-world/src/world.rs @@ -44,7 +44,7 @@ pub trait SimpleWorld: Send + Sync { flags: BlockFlags, ) -> BlockStateId; - async fn get_block(&self, position: &BlockPos) -> Result; + async fn get_block(&self, position: &BlockPos) -> pumpkin_data::Block; async fn update_neighbor( self: Arc, diff --git a/pumpkin/src/block/blocks/bed.rs b/pumpkin/src/block/blocks/bed.rs index ec1a99a80..6e0f71003 100644 --- a/pumpkin/src/block/blocks/bed.rs +++ b/pumpkin/src/block/blocks/bed.rs @@ -47,14 +47,11 @@ impl PumpkinBlock for BedBlock { ) -> bool { let facing = player.living_entity.entity.get_horizontal_facing(); - world - .get_block_state(block_pos) - .await - .is_ok_and(|state| state.replaceable()) + world.get_block_state(block_pos).await.replaceable() && world .get_block_state(&block_pos.offset(facing.to_offset())) .await - .is_ok_and(|state| state.replaceable()) + .replaceable() } async fn on_place( diff --git a/pumpkin/src/block/blocks/cactus.rs b/pumpkin/src/block/blocks/cactus.rs index 0350bc316..1c5f2e502 100644 --- a/pumpkin/src/block/blocks/cactus.rs +++ b/pumpkin/src/block/blocks/cactus.rs @@ -33,12 +33,8 @@ impl PumpkinBlock for CactusBlock { } async fn random_tick(&self, block: &Block, world: &Arc, pos: &BlockPos) { - if world.get_block_state(&pos.up()).await.unwrap().is_air() { - let state_id = world - .get_block_state(pos) - .await - .expect("`location` should be a cactus") - .id; + if world.get_block_state(&pos.up()).await.is_air() { + let state_id = world.get_block_state(pos).await.id; let age = CactusLikeProperties::from_state_id(state_id, block).age; if age == Integer0To15::L15 { world @@ -112,18 +108,13 @@ async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { for direction in BlockDirection::horizontal() { let (block, state) = world .get_block_and_block_state(&block_pos.offset(direction.to_offset())) - .await - .unwrap(); + .await; if state.is_solid() || block == Block::LAVA { return false; } } - let block = world.get_block(&block_pos.down()).await.unwrap(); + let block = world.get_block(&block_pos.down()).await; // TODO: use tags (block == Block::CACTUS || block.is_tagged_with("minecraft:sand").unwrap()) - && !world - .get_block_state(&block_pos.up()) - .await - .unwrap() - .is_liquid() + && !world.get_block_state(&block_pos.up()).await.is_liquid() } diff --git a/pumpkin/src/block/blocks/chest.rs b/pumpkin/src/block/blocks/chest.rs index ad3b8428c..d3c86c827 100644 --- a/pumpkin/src/block/blocks/chest.rs +++ b/pumpkin/src/block/blocks/chest.rs @@ -168,12 +168,9 @@ async fn compute_chest_props( return (ChestType::Single, chest_facing); }; - let Ok((clicked_block, clicked_block_state)) = world + let (clicked_block, clicked_block_state) = world .get_block_and_block_state(&block_pos.offset(face.to_offset())) - .await - else { - return (ChestType::Single, chest_facing); - }; + .await; if clicked_block == *block { let clicked_props = @@ -230,12 +227,9 @@ async fn get_chest_properties_if_can_connect( direction: HorizontalFacing, wanted_type: ChestType, ) -> Option { - let Ok((neighbor_block, neighbor_block_state)) = world + let (neighbor_block, neighbor_block_state) = world .get_block_and_block_state(&block_pos.offset(direction.to_offset())) - .await - else { - return None; - }; + .await; if neighbor_block != *block { return None; diff --git a/pumpkin/src/block/blocks/command.rs b/pumpkin/src/block/blocks/command.rs new file mode 100644 index 000000000..b11ac492c --- /dev/null +++ b/pumpkin/src/block/blocks/command.rs @@ -0,0 +1,91 @@ +use std::sync::{Arc, atomic::Ordering}; + +use async_trait::async_trait; +use pumpkin_data::Block; +use pumpkin_util::math::position::BlockPos; +use pumpkin_world::{ + block::entities::{BlockEntity, command_block::CommandBlockEntity}, + chunk::TickPriority, +}; + +use crate::{ + block::pumpkin_block::{BlockMetadata, PumpkinBlock}, + world::World, +}; + +use super::redstone::block_receives_redstone_power; + +pub struct CommandBlock; + +impl CommandBlock { + pub async fn update( + world: &World, + block: &Block, + command_block: CommandBlockEntity, + pos: &BlockPos, + powered: bool, + ) { + if command_block.powered.load(Ordering::Relaxed) == powered { + return; + } + command_block.powered.store(powered, Ordering::Relaxed); + if powered { + world + .schedule_block_tick(block, *pos, 1, TickPriority::Normal) + .await; + } + } +} + +impl BlockMetadata for CommandBlock { + fn namespace(&self) -> &'static str { + "minecraft" + } + + fn ids(&self) -> &'static [&'static str] { + &[ + Block::COMMAND_BLOCK.name, + Block::CHAIN_COMMAND_BLOCK.name, + Block::REPEATING_COMMAND_BLOCK.name, + ] + } +} + +#[async_trait] +impl PumpkinBlock for CommandBlock { + async fn on_neighbor_update( + &self, + world: &Arc, + block: &Block, + pos: &BlockPos, + _source_block: &Block, + _notify: bool, + ) { + if let Some((nbt, block_entity)) = world.get_block_entity(pos).await { + let command_entity = CommandBlockEntity::from_nbt(&nbt, *pos); + + if block_entity.identifier() != command_entity.identifier() { + return; + } + Self::update( + world, + block, + command_entity, + pos, + block_receives_redstone_power(world, pos).await, + ) + .await; + } + } + + async fn on_scheduled_tick(&self, world: &Arc, _block: &Block, pos: &BlockPos) { + if let Some((nbt, block_entity)) = world.get_block_entity(pos).await { + let command_entity = CommandBlockEntity::from_nbt(&nbt, *pos); + + if block_entity.identifier() != command_entity.identifier() { + return; + } + // TODO + } + } +} diff --git a/pumpkin/src/block/blocks/dirt_path.rs b/pumpkin/src/block/blocks/dirt_path.rs index d7d2ae1cb..4ed7544ce 100644 --- a/pumpkin/src/block/blocks/dirt_path.rs +++ b/pumpkin/src/block/blocks/dirt_path.rs @@ -78,6 +78,6 @@ impl PumpkinBlock for DirtPathBlock { } async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { - let state = world.get_block_state(&block_pos.up()).await.unwrap(); + let state = world.get_block_state(&block_pos.up()).await; !state.is_solid() // TODO: add fence gate block } diff --git a/pumpkin/src/block/blocks/doors.rs b/pumpkin/src/block/blocks/doors.rs index 284c4357d..1b7c41789 100644 --- a/pumpkin/src/block/blocks/doors.rs +++ b/pumpkin/src/block/blocks/doors.rs @@ -31,7 +31,7 @@ use crate::world::World; type DoorProperties = pumpkin_data::block_properties::OakDoorLikeProperties; async fn toggle_door(world: &Arc, block_pos: &BlockPos) { - let (block, block_state) = world.get_block_and_block_state(block_pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(block_pos).await; let mut door_props = DoorProperties::from_state_id(block_state.id, &block); door_props.open = !door_props.open; @@ -41,7 +41,7 @@ async fn toggle_door(world: &Arc, block_pos: &BlockPos) { }; let other_pos = block_pos.offset(other_half.to_offset()); - let (other_block, other_state_id) = world.get_block_and_block_state(&other_pos).await.unwrap(); + let (other_block, other_state_id) = world.get_block_and_block_state(&other_pos).await; let mut other_door_props = DoorProperties::from_state_id(other_state_id.id, &other_block); other_door_props.open = door_props.open; @@ -100,19 +100,18 @@ 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_state = world.get_block_state(&left_pos).await.unwrap(); + let left_state = world.get_block_state(&left_pos).await; let top_facing = top_pos.offset(facing.to_block_direction().to_offset()); - let top_state = world.get_block_state(&top_facing).await.unwrap(); + let top_state = world.get_block_state(&top_facing).await; let right_dir = facing.rotate_clockwise(); let right_pos = pos.offset(right_dir.to_block_direction().to_offset()); - let right_state = world.get_block_state(&right_pos).await.unwrap(); + let right_state = world.get_block_state(&right_pos).await; let top_right = top_pos.offset(facing.to_block_direction().to_offset()); - let top_right_state = world.get_block_state(&top_right).await.unwrap(); + let top_right_state = world.get_block_state(&top_right).await; let has_left_door = world .get_block(&left_pos) .await - .unwrap() .is_tagged_with("minecraft:doors") .unwrap() && DoorProperties::from_state_id(left_state.id, block).half == DoubleBlockHalf::Lower; @@ -120,7 +119,6 @@ async fn get_hinge( let has_right_door = world .get_block(&right_pos) .await - .unwrap() .is_tagged_with("minecraft:doors") .unwrap() && DoorProperties::from_state_id(right_state.id, block).half == DoubleBlockHalf::Lower; @@ -263,7 +261,7 @@ impl PumpkinBlock for DoorBlock { _source_block: &Block, _notify: bool, ) { - let block_state = world.get_block_state(pos).await.unwrap(); + let block_state = world.get_block_state(pos).await; let mut door_props = DoorProperties::from_state_id(block_state.id, block); let other_half = match door_props.half { @@ -271,8 +269,7 @@ impl PumpkinBlock for DoorBlock { DoubleBlockHalf::Lower => BlockDirection::Up, }; let other_pos = pos.offset(other_half.to_offset()); - let (other_block, other_state_id) = - world.get_block_and_block_state(&other_pos).await.unwrap(); + let (other_block, other_state_id) = world.get_block_and_block_state(&other_pos).await; let powered = block_receives_redstone_power(world, pos).await || block_receives_redstone_power(world, &other_pos).await; @@ -343,12 +340,8 @@ impl PumpkinBlock for DoorBlock { } async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { - world - .get_block_state(&block_pos.up()) - .await - .is_ok_and(|state| state.replaceable()) - && world - .get_block_state(&block_pos.down()) - .await - .is_ok_and(|state| state.is_solid() && state.is_full_cube()) + let down = world.get_block_state(&block_pos.down()).await; + world.get_block_state(&block_pos.up()).await.replaceable() + && down.is_solid() + && down.is_full_cube() } diff --git a/pumpkin/src/block/blocks/farmland.rs b/pumpkin/src/block/blocks/farmland.rs index dfccafb71..a7e29e6b5 100644 --- a/pumpkin/src/block/blocks/farmland.rs +++ b/pumpkin/src/block/blocks/farmland.rs @@ -77,6 +77,6 @@ impl PumpkinBlock for FarmLandBlock { } async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { - let state = world.get_block_state(&block_pos.up()).await.unwrap(); + let state = world.get_block_state(&block_pos.up()).await; !state.is_solid() // TODO: add fence gate block } diff --git a/pumpkin/src/block/blocks/fence_gates.rs b/pumpkin/src/block/blocks/fence_gates.rs index 535a69b00..7de3baf16 100644 --- a/pumpkin/src/block/blocks/fence_gates.rs +++ b/pumpkin/src/block/blocks/fence_gates.rs @@ -22,7 +22,7 @@ use pumpkin_data::item::Item; type FenceGateProperties = pumpkin_data::block_properties::OakFenceGateLikeProperties; pub async fn toggle_fence_gate(world: &Arc, block_pos: &BlockPos) -> BlockStateId { - let (block, state) = world.get_block_and_block_state(block_pos).await.unwrap(); + let (block, state) = world.get_block_and_block_state(block_pos).await; let mut fence_gate_props = FenceGateProperties::from_state_id(state.id, &block); fence_gate_props.open = !fence_gate_props.open; diff --git a/pumpkin/src/block/blocks/fences.rs b/pumpkin/src/block/blocks/fences.rs index 7fd75c536..da4dc56a1 100644 --- a/pumpkin/src/block/blocks/fences.rs +++ b/pumpkin/src/block/blocks/fences.rs @@ -72,11 +72,8 @@ pub async fn compute_fence_state( ) -> u16 { for direction in BlockDirection::horizontal() { let other_block_pos = block_pos.offset(direction.to_offset()); - let Ok((other_block, other_block_state)) = - world.get_block_and_block_state(&other_block_pos).await - else { - continue; - }; + let (other_block, other_block_state) = + world.get_block_and_block_state(&other_block_pos).await; let connected = connects_to(block, &other_block, &other_block_state, direction); match direction { diff --git a/pumpkin/src/block/blocks/fire/fire.rs b/pumpkin/src/block/blocks/fire/fire.rs index 82526bac8..a7207d4f8 100644 --- a/pumpkin/src/block/blocks/fire/fire.rs +++ b/pumpkin/src/block/blocks/fire/fire.rs @@ -104,7 +104,7 @@ impl PumpkinBlock for FireBlock { _neighbor_pos: &BlockPos, _neighbor_state: BlockStateId, ) -> BlockStateId { - if !FireBlockBase::can_place_on(&world.get_block(&block_pos.down()).await.unwrap()) { + if !FireBlockBase::can_place_on(&world.get_block(&block_pos.down()).await) { return Block::AIR.default_state_id; } diff --git a/pumpkin/src/block/blocks/fire/mod.rs b/pumpkin/src/block/blocks/fire/mod.rs index 9584197f7..7aac040d7 100644 --- a/pumpkin/src/block/blocks/fire/mod.rs +++ b/pumpkin/src/block/blocks/fire/mod.rs @@ -15,7 +15,7 @@ pub struct FireBlockBase; impl FireBlockBase { pub async fn get_fire_type(world: &World, pos: &BlockPos) -> Block { - let (block, _block_state) = world.get_block_and_block_state(&pos.down()).await.unwrap(); + let (block, _block_state) = world.get_block_and_block_state(&pos.down()).await; if SoulFireBlock::is_soul_base(&block) { return Block::SOUL_FIRE; } @@ -32,9 +32,8 @@ impl FireBlockBase { } pub async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { - let block_state = world.get_block_state(block_pos).await.unwrap(); - block_state.is_air() - && Self::can_place_on(&world.get_block(&block_pos.down()).await.unwrap()) + let block_state = world.get_block_state(block_pos).await; + block_state.is_air() && Self::can_place_on(&world.get_block(&block_pos.down()).await) } async fn broken(world: Arc, block_pos: BlockPos) { diff --git a/pumpkin/src/block/blocks/fire/soul_fire.rs b/pumpkin/src/block/blocks/fire/soul_fire.rs index 888c81e2f..d1d20a42b 100644 --- a/pumpkin/src/block/blocks/fire/soul_fire.rs +++ b/pumpkin/src/block/blocks/fire/soul_fire.rs @@ -39,7 +39,7 @@ impl PumpkinBlock for SoulFireBlock { _neighbor_pos: &BlockPos, _neighbor_state: BlockStateId, ) -> BlockStateId { - if !Self::is_soul_base(&world.get_block(&block_pos.down()).await.unwrap()) { + if !Self::is_soul_base(&world.get_block(&block_pos.down()).await) { return Block::AIR.default_state_id; } @@ -57,7 +57,7 @@ impl PumpkinBlock for SoulFireBlock { _use_item_on: &SUseItemOn, ) -> bool { FireBlockBase::can_place_at(world, block_pos).await - && Self::is_soul_base(&world.get_block(&block_pos.down()).await.unwrap()) + && Self::is_soul_base(&world.get_block(&block_pos.down()).await) } async fn broken( diff --git a/pumpkin/src/block/blocks/glass_panes.rs b/pumpkin/src/block/blocks/glass_panes.rs index 3b07b413c..0a9fdd21e 100644 --- a/pumpkin/src/block/blocks/glass_panes.rs +++ b/pumpkin/src/block/blocks/glass_panes.rs @@ -70,11 +70,8 @@ pub async fn compute_pane_state( ) -> u16 { for direction in BlockDirection::horizontal() { let other_block_pos = block_pos.offset(direction.to_offset()); - let Ok((other_block, other_block_state)) = - world.get_block_and_block_state(&other_block_pos).await - else { - continue; - }; + let (other_block, other_block_state) = + world.get_block_and_block_state(&other_block_pos).await; let connected = other_block == *block || (other_block_state.is_solid() && other_block_state.is_full_cube()) diff --git a/pumpkin/src/block/blocks/iron_bars.rs b/pumpkin/src/block/blocks/iron_bars.rs index bfa06d5eb..11d45de64 100644 --- a/pumpkin/src/block/blocks/iron_bars.rs +++ b/pumpkin/src/block/blocks/iron_bars.rs @@ -61,11 +61,8 @@ pub async fn compute_bars_state( ) -> u16 { for direction in BlockDirection::horizontal() { let other_block_pos = block_pos.offset(direction.to_offset()); - let Ok((other_block, other_block_state)) = - world.get_block_and_block_state(&other_block_pos).await - else { - continue; - }; + let (other_block, other_block_state) = + world.get_block_and_block_state(&other_block_pos).await; let connected = other_block == *block || (other_block_state.is_solid() && other_block_state.is_full_cube()) diff --git a/pumpkin/src/block/blocks/jukebox.rs b/pumpkin/src/block/blocks/jukebox.rs index 5f78ea8f2..192c46eef 100644 --- a/pumpkin/src/block/blocks/jukebox.rs +++ b/pumpkin/src/block/blocks/jukebox.rs @@ -22,11 +22,7 @@ pub struct JukeboxBlock; impl JukeboxBlock { async fn has_record(&self, block: &Block, location: BlockPos, world: &World) -> bool { - let state_id = world - .get_block_state(&location) - .await - .expect("`location` should be a jukebox") - .id; + let state_id = world.get_block_state(&location).await.id; JukeboxLikeProperties::from_state_id(state_id, block).has_record } diff --git a/pumpkin/src/block/blocks/mod.rs b/pumpkin/src/block/blocks/mod.rs index 02feb667d..be92be1dd 100644 --- a/pumpkin/src/block/blocks/mod.rs +++ b/pumpkin/src/block/blocks/mod.rs @@ -2,6 +2,7 @@ pub mod barrel; pub mod bed; pub mod cactus; pub mod chest; +pub mod command; pub mod crafting_table; pub mod dirt_path; pub mod doors; diff --git a/pumpkin/src/block/blocks/note.rs b/pumpkin/src/block/blocks/note.rs index d43bdedc6..a8de0a84b 100644 --- a/pumpkin/src/block/blocks/note.rs +++ b/pumpkin/src/block/blocks/note.rs @@ -29,9 +29,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.unwrap().is_air() - { + if !is_base_block(props.instrument) || world.get_block_state(&pos.up()).await.is_air() { world.add_synced_block_event(*pos, 0, 0).await; } } @@ -49,7 +47,6 @@ impl NoteBlock { &world .get_block_state(&pos.up()) .await - .unwrap() .instrument .to_lowercase(), ); @@ -62,7 +59,6 @@ impl NoteBlock { &world .get_block_state(&pos.down()) .await - .unwrap() .instrument .to_lowercase(), ); @@ -86,7 +82,7 @@ impl PumpkinBlock for NoteBlock { _source_block: &Block, _notify: bool, ) { - let block_state = world.get_block_state(pos).await.unwrap(); + let block_state = world.get_block_state(pos).await; let mut note_props = NoteBlockLikeProperties::from_state_id(block_state.id, block); let powered = block_receives_redstone_power(world, pos).await; // check if powered state changed @@ -109,7 +105,7 @@ impl PumpkinBlock for NoteBlock { _server: &Server, world: &Arc, ) { - let block_state = world.get_block_state(&pos).await.unwrap(); + let block_state = world.get_block_state(&pos).await; let mut note_props = NoteBlockLikeProperties::from_state_id(block_state.id, block); let next_index = note_props.note.to_index() + 1; // Increment and check if max @@ -145,7 +141,7 @@ impl PumpkinBlock for NoteBlock { _type: u8, _data: u8, ) -> bool { - let block_state = world.get_block_state(pos).await.unwrap(); + let block_state = world.get_block_state(pos).await; let note_props = NoteBlockLikeProperties::from_state_id(block_state.id, block); let instrument = note_props.instrument; let pitch = if is_base_block(instrument) { diff --git a/pumpkin/src/block/blocks/piston/mod.rs b/pumpkin/src/block/blocks/piston/mod.rs index 2b509aa3d..5a7e02fd9 100644 --- a/pumpkin/src/block/blocks/piston/mod.rs +++ b/pumpkin/src/block/blocks/piston/mod.rs @@ -49,11 +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_block_state(&self.pos_to) - .await - .unwrap(); + let (block, block_state) = self.world.get_block_and_block_state(&self.pos_to).await; dbg!(PistonBlock::is_movable( &block, &block_state, @@ -78,7 +74,7 @@ impl<'a> PistonHandler<'a> { return false; } for block_pos in self.moved_blocks.clone() { - let block = self.world.get_block(&block_pos).await.unwrap(); + let block = self.world.get_block(&block_pos).await; if Self::is_block_sticky(&block) && !self.try_move_adjacent_block(&block, block_pos).await { @@ -103,8 +99,7 @@ impl<'a> PistonHandler<'a> { } async fn try_move(&mut self, pos: BlockPos, dir: BlockDirection) -> bool { - let (mut block, mut block_state) = - self.world.get_block_and_block_state(&pos).await.unwrap(); + let (mut block, mut block_state) = self.world.get_block_and_block_state(&pos).await; if block_state.is_air() { return true; } @@ -124,11 +119,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; - (block, block_state) = self - .world - .get_block_and_block_state(&block_pos) - .await - .unwrap(); + (block, block_state) = self.world.get_block_and_block_state(&block_pos).await; if block_state.is_air() || !Self::is_adjacent_block_stuck(&block2, &block) || !PistonBlock::is_movable( @@ -160,7 +151,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.unwrap(); + let block = self.world.get_block(&block_pos3).await; if Self::is_block_sticky(&block) && !Box::pin(self.try_move_adjacent_block(&block, block_pos3)).await { @@ -169,11 +160,7 @@ impl<'a> PistonHandler<'a> { } return true; } - (block, block_state) = self - .world - .get_block_and_block_state(&block_pos2) - .await - .unwrap(); + (block, block_state) = self.world.get_block_and_block_state(&block_pos2).await; if block_state.is_air() { return true; } @@ -219,7 +206,7 @@ impl<'a> PistonHandler<'a> { continue; } let block_pos = pos.offset(direction.to_offset()); - let block_state2 = self.world.get_block(&block_pos).await.unwrap(); + let block_state2 = self.world.get_block(&block_pos).await; if Self::is_adjacent_block_stuck(&block_state2, block) && !self.try_move(block_pos, direction).await { diff --git a/pumpkin/src/block/blocks/piston/piston.rs b/pumpkin/src/block/blocks/piston/piston.rs index 9f81a945b..f2c997748 100644 --- a/pumpkin/src/block/blocks/piston/piston.rs +++ b/pumpkin/src/block/blocks/piston/piston.rs @@ -142,7 +142,7 @@ impl PumpkinBlock for PistonBlock { r#type: u8, data: u8, ) -> bool { - let state = world.get_block_state(pos).await.unwrap(); + let state = world.get_block_state(pos).await; let mut props = PistonProps::from_state_id(state.id, block); let dir = props.facing.to_block_direction(); @@ -225,7 +225,7 @@ impl PumpkinBlock for PistonBlock { world.update_neighbors(pos, None).await; if sticky { let pos = pos.offset_dir(dir.to_offset(), 2); - let (block, state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (block, state) = world.get_block_and_block_state(&pos).await; let mut bl2 = false; if block == Block::MOVING_PISTON { if let Some(entity) = world.get_block_entity(&pos).await { @@ -273,10 +273,7 @@ impl PumpkinBlock 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_block_state(&neighbor_pos) - .await - .unwrap(); + let (block, state) = world.get_block_and_block_state(&neighbor_pos).await; // 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 @@ -286,19 +283,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_block_state(&neighbor_pos) - .await - .unwrap(); + let (block, state) = world.get_block_and_block_state(&neighbor_pos).await; 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_block_state(&neighbor_pos) - .await - .unwrap(); + let (block, state) = world.get_block_and_block_state(&neighbor_pos).await; if dir == BlockDirection::Down || !is_emitting_redstone_power(&block, &state, world, &neighbor_pos, dir).await { @@ -310,7 +301,7 @@ async fn should_extend(world: &World, block_pos: &BlockPos, piston_dir: BlockDir } async fn try_move(world: &Arc, block: &Block, block_pos: &BlockPos) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; 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; @@ -326,7 +317,7 @@ async fn try_move(world: &Arc, 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_block_state(&new_pos).await.unwrap(); + let (new_block, new_state) = world.get_block_and_block_state(&new_pos).await; let mut r#type = 1; if new_block == Block::MOVING_PISTON { @@ -358,7 +349,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.unwrap() == Block::PISTON_HEAD { + if !extend && world.get_block(&extended_pos).await == Block::PISTON_HEAD { world .set_block_state( &extended_pos, @@ -379,7 +370,7 @@ async fn move_piston( let mut moved_block_states: Vec = Vec::new(); for &block_pos in &moved_blocks { - let block_state = world.get_block_state(&block_pos).await.unwrap(); + let block_state = world.get_block_state(&block_pos).await; moved_block_states.push(block_state.clone()); moved_blocks_map.insert(block_pos, block_state); } @@ -390,7 +381,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.unwrap(); + let block_state = world.get_block_state(&broken_block_pos).await; world .break_block( &broken_block_pos, @@ -402,7 +393,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.unwrap(); + let block_state = world.get_block_state(&moved_block_pos).await; let target_pos = moved_block_pos.offset(move_direction.to_offset()); moved_blocks_map.remove(&target_pos); diff --git a/pumpkin/src/block/blocks/piston/piston_extension.rs b/pumpkin/src/block/blocks/piston/piston_extension.rs index dda63a6d7..65a8292a5 100644 --- a/pumpkin/src/block/blocks/piston/piston_extension.rs +++ b/pumpkin/src/block/blocks/piston/piston_extension.rs @@ -34,7 +34,7 @@ impl PumpkinBlock for PistonExtensionBlock { ) { let props = MovingPistonProps::from_state_id(state.id, &Block::MOVING_PISTON); let pos = location.offset(props.facing.opposite().to_block_direction().to_offset()); - let (new_block, new_state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (new_block, new_state) = world.get_block_and_block_state(&pos).await; if PistonBlock::ids(&PistonBlock).contains(&new_block.name) { let props = PistonProps::from_state_id(new_state.id, &new_block); if props.extended { diff --git a/pumpkin/src/block/blocks/piston/piston_head.rs b/pumpkin/src/block/blocks/piston/piston_head.rs index 1b31077ff..fabc9084b 100644 --- a/pumpkin/src/block/blocks/piston/piston_head.rs +++ b/pumpkin/src/block/blocks/piston/piston_head.rs @@ -34,7 +34,7 @@ impl PumpkinBlock for PistonHeadBlock { ) { let props = PistonHeadProperties::from_state_id(state.id, &Block::PISTON_HEAD); let pos = location.offset(props.facing.opposite().to_block_direction().to_offset()); - let (new_block, new_state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (new_block, new_state) = world.get_block_and_block_state(&pos).await; if PistonBlock::ids(&PistonBlock).contains(&new_block.name) { let props = PistonProps::from_state_id(new_state.id, &new_block); if props.extended { diff --git a/pumpkin/src/block/blocks/redstone/buttons.rs b/pumpkin/src/block/blocks/redstone/buttons.rs index 22ea20873..4b6a21c7b 100644 --- a/pumpkin/src/block/blocks/redstone/buttons.rs +++ b/pumpkin/src/block/blocks/redstone/buttons.rs @@ -26,7 +26,7 @@ use crate::server::Server; use crate::world::World; async fn click_button(world: &Arc, block_pos: &BlockPos) { - let (block, state) = world.get_block_and_block_state(block_pos).await.unwrap(); + let (block, state) = world.get_block_and_block_state(block_pos).await; let mut button_props = ButtonLikeProperties::from_state_id(state.id, &block); if !button_props.powered { @@ -113,7 +113,7 @@ impl PumpkinBlock for ButtonBlock { } async fn on_scheduled_tick(&self, world: &Arc, block: &Block, block_pos: &BlockPos) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; let mut props = ButtonLikeProperties::from_state_id(state.id, block); props.powered = false; world diff --git a/pumpkin/src/block/blocks/redstone/lever.rs b/pumpkin/src/block/blocks/redstone/lever.rs index 4f0554f23..ae7318618 100644 --- a/pumpkin/src/block/blocks/redstone/lever.rs +++ b/pumpkin/src/block/blocks/redstone/lever.rs @@ -20,7 +20,7 @@ use crate::{ }; async fn toggle_lever(world: &Arc, block_pos: &BlockPos) { - let (block, state) = world.get_block_and_block_state(block_pos).await.unwrap(); + let (block, state) = world.get_block_and_block_state(block_pos).await; let mut lever_props = LeverLikeProperties::from_state_id(state.id, &block); lever_props.powered = !lever_props.powered; diff --git a/pumpkin/src/block/blocks/redstone/mod.rs b/pumpkin/src/block/blocks/redstone/mod.rs index 2d54db881..2ab429114 100644 --- a/pumpkin/src/block/blocks/redstone/mod.rs +++ b/pumpkin/src/block/blocks/redstone/mod.rs @@ -26,7 +26,7 @@ pub mod turbo; pub async fn update_wire_neighbors(world: &Arc, pos: &BlockPos) { for direction in BlockDirection::all() { let neighbor_pos = pos.offset(direction.to_offset()); - let block = world.get_block(&neighbor_pos).await.unwrap(); + let block = world.get_block(&neighbor_pos).await; world .block_registry .on_neighbor_update(world, &block, &neighbor_pos, &block, true) @@ -34,7 +34,7 @@ pub async fn update_wire_neighbors(world: &Arc, pos: &BlockPos) { for n_direction in BlockDirection::all() { let n_neighbor_pos = neighbor_pos.offset(n_direction.to_offset()); - let block = world.get_block(&n_neighbor_pos).await.unwrap(); + let block = world.get_block(&n_neighbor_pos).await; world .block_registry .on_neighbor_update(world, &block, &n_neighbor_pos, &block, true) @@ -90,8 +90,7 @@ async fn get_max_strong_power(world: &World, pos: &BlockPos, dust_power: bool) - for side in BlockDirection::all() { let (block, state) = world .get_block_and_block_state(&pos.offset(side.to_offset())) - .await - .unwrap(); + .await; max_power = max_power.max( get_strong_power( &block, @@ -112,8 +111,7 @@ async fn get_max_weak_power(world: &World, pos: &BlockPos, dust_power: bool) -> for side in BlockDirection::all() { let (block, state) = world .get_block_and_block_state(&pos.offset(side.to_offset())) - .await - .unwrap(); + .await; max_power = max_power.max( get_weak_power( &block, @@ -166,10 +164,7 @@ async fn get_strong_power( pub async fn block_receives_redstone_power(world: &World, pos: &BlockPos) -> bool { for face in BlockDirection::all() { let neighbor_pos = pos.offset(face.to_offset()); - let (block, state) = world - .get_block_and_block_state(&neighbor_pos) - .await - .unwrap(); + let (block, state) = world.get_block_and_block_state(&neighbor_pos).await; if is_emitting_redstone_power(&block, &state, world, pos, face).await { return true; } @@ -183,7 +178,7 @@ pub fn is_diode(block: &Block) -> bool { pub async fn diode_get_input_strength(world: &World, pos: &BlockPos, facing: BlockDirection) -> u8 { let input_pos = pos.offset(facing.to_offset()); - let (input_block, input_state) = world.get_block_and_block_state(&input_pos).await.unwrap(); + let (input_block, input_state) = world.get_block_and_block_state(&input_pos).await; let power: u8 = get_redstone_power(&input_block, &input_state, world, &input_pos, facing).await; if power == 0 && input_state.is_solid() { return get_max_weak_power(world, &input_pos, true).await; diff --git a/pumpkin/src/block/blocks/redstone/observer.rs b/pumpkin/src/block/blocks/redstone/observer.rs index 663723710..71b7fd6f6 100644 --- a/pumpkin/src/block/blocks/redstone/observer.rs +++ b/pumpkin/src/block/blocks/redstone/observer.rs @@ -50,7 +50,7 @@ impl PumpkinBlock for ObserverBlock { } async fn on_scheduled_tick(&self, world: &Arc, block: &Block, block_pos: &BlockPos) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; let mut props = ObserverLikeProperties::from_state_id(state.id, block); if props.powered { diff --git a/pumpkin/src/block/blocks/redstone/pressure_plate/mod.rs b/pumpkin/src/block/blocks/redstone/pressure_plate/mod.rs index 6e8154775..a696d16a9 100644 --- a/pumpkin/src/block/blocks/redstone/pressure_plate/mod.rs +++ b/pumpkin/src/block/blocks/redstone/pressure_plate/mod.rs @@ -25,7 +25,7 @@ pub trait PressurePlate { } async fn on_scheduled_tick_pp(&self, world: &Arc, block: &Block, pos: &BlockPos) { - let state = world.get_block_state(pos).await.unwrap(); + let state = world.get_block_state(pos).await; let output = self.get_redstone_output(block, state.id); if output > 0 { self.update_plate_state(world, *pos, block, state, output) diff --git a/pumpkin/src/block/blocks/redstone/rails/common.rs b/pumpkin/src/block/blocks/redstone/rails/common.rs index 2538a5e3b..d7ab3e1ca 100644 --- a/pumpkin/src/block/blocks/redstone/rails/common.rs +++ b/pumpkin/src/block/blocks/redstone/rails/common.rs @@ -16,7 +16,7 @@ pub(super) async fn rail_placement_is_valid(world: &World, block: &Block, pos: & return false; } - let state_id = world.get_block_state_id(pos).await.unwrap(); + let state_id = world.get_block_state_id(pos).await; let rail_props = RailProperties::new(state_id, block); let rail_leaning_direction = match rail_props.shape() { RailShape::AscendingNorth => Some(HorizontalFacing::North), @@ -36,7 +36,7 @@ pub(super) async fn rail_placement_is_valid(world: &World, block: &Block, pos: & } pub(super) async fn can_place_rail_at(world: &World, pos: &BlockPos) -> bool { - let state = world.get_block_state(&pos.down()).await.unwrap(); + let state = world.get_block_state(&pos.down()).await; state.is_solid() } diff --git a/pumpkin/src/block/blocks/redstone/rails/mod.rs b/pumpkin/src/block/blocks/redstone/rails/mod.rs index 4c9eacc10..7534e776f 100644 --- a/pumpkin/src/block/blocks/redstone/rails/mod.rs +++ b/pumpkin/src/block/blocks/redstone/rails/mod.rs @@ -27,7 +27,7 @@ struct Rail { impl Rail { async fn find_with_elevation(world: &World, position: BlockPos) -> Option { - let (block, block_state) = world.get_block_and_block_state(&position).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(&position).await; if block.is_tagged_with("#minecraft:rails").unwrap() { let properties = RailProperties::new(block_state.id, &block); return Some(Self { @@ -39,7 +39,7 @@ impl Rail { } let pos = position.up(); - let (block, block_state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(&pos).await; if block.is_tagged_with("#minecraft:rails").unwrap() { let properties = RailProperties::new(block_state.id, &block); return Some(Self { @@ -51,7 +51,7 @@ impl Rail { } let pos = position.down(); - let (block, block_state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(&pos).await; if block.is_tagged_with("#minecraft:rails").unwrap() { let properties = RailProperties::new(block_state.id, &block); return Some(Self { diff --git a/pumpkin/src/block/blocks/redstone/redstone_lamp.rs b/pumpkin/src/block/blocks/redstone/redstone_lamp.rs index dc49049f5..5243c8759 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_lamp.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_lamp.rs @@ -43,7 +43,7 @@ impl PumpkinBlock for RedstoneLamp { _source_block: &Block, _notify: bool, ) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; let mut props = RedstoneLampProperties::from_state_id(state.id, block); let is_lit = props.lit; let is_receiving_power = block_receives_redstone_power(world, block_pos).await; @@ -67,7 +67,7 @@ impl PumpkinBlock for RedstoneLamp { } async fn on_scheduled_tick(&self, world: &Arc, block: &Block, block_pos: &BlockPos) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; let mut props = RedstoneLampProperties::from_state_id(state.id, block); let is_lit = props.lit; let is_receiving_power = block_receives_redstone_power(world, block_pos).await; diff --git a/pumpkin/src/block/blocks/redstone/redstone_torch.rs b/pumpkin/src/block/blocks/redstone/redstone_torch.rs index c391cf30d..869c4878c 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_torch.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_torch.rs @@ -67,7 +67,7 @@ impl PumpkinBlock for RedstoneTorchBlock { _source_block: &Block, _notify: bool, ) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; if world.is_block_tick_scheduled(block_pos, block).await { return; @@ -153,7 +153,7 @@ impl PumpkinBlock for RedstoneTorchBlock { } async fn on_scheduled_tick(&self, world: &Arc, block: &Block, block_pos: &BlockPos) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; if block == &Block::REDSTONE_WALL_TORCH { let mut props = RWallTorchProps::from_state_id(state.id, block); let should_be_lit_now = should_be_lit( @@ -208,7 +208,7 @@ impl PumpkinBlock for RedstoneTorchBlock { pub async fn should_be_lit(world: &World, pos: &BlockPos, face: BlockDirection) -> bool { let other_pos = pos.offset(face.to_offset()); - let (block, state) = world.get_block_and_block_state(&other_pos).await.unwrap(); + let (block, state) = world.get_block_and_block_state(&other_pos).await; get_redstone_power(&block, &state, world, &other_pos, face).await == 0 } diff --git a/pumpkin/src/block/blocks/redstone/redstone_wire.rs b/pumpkin/src/block/blocks/redstone/redstone_wire.rs index 19e631718..09b99d2e7 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_wire.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_wire.rs @@ -132,11 +132,11 @@ impl PumpkinBlock for RedstoneWireBlock { for direction in BlockDirection::horizontal() { let other_block_pos = block_pos.offset(direction.to_offset()); - let other_block = world.get_block(&other_block_pos).await.unwrap(); + let other_block = world.get_block(&other_block_pos).await; if wire_props.is_side_connected(direction) && other_block != Block::REDSTONE_WIRE { let up_block_pos = other_block_pos.up(); - let up_block = world.get_block(&up_block_pos).await.unwrap(); + let up_block = world.get_block(&up_block_pos).await; if up_block == Block::REDSTONE_WIRE { world .replace_with_state_for_neighbor_update( @@ -148,7 +148,7 @@ impl PumpkinBlock for RedstoneWireBlock { } let down_block_pos = other_block_pos.down(); - let down_block = world.get_block(&down_block_pos).await.unwrap(); + let down_block = world.get_block(&down_block_pos).await; if down_block == Block::REDSTONE_WIRE { world .replace_with_state_for_neighbor_update( @@ -170,7 +170,7 @@ impl PumpkinBlock for RedstoneWireBlock { _server: &Server, world: &Arc, ) { - let state = world.get_block_state(&location).await.unwrap(); + let state = world.get_block_state(&location).await; let wire = RedstoneWireProperties::from_state_id(state.id, block); on_use(wire, world, &location).await; } @@ -184,7 +184,7 @@ impl PumpkinBlock for RedstoneWireBlock { _server: &Server, world: &Arc, ) -> BlockActionResult { - let state = world.get_block_state(&location).await.unwrap(); + let state = world.get_block_state(&location).await; let wire = RedstoneWireProperties::from_state_id(state.id, block); if on_use(wire, world, &location).await { BlockActionResult::Consume @@ -202,7 +202,7 @@ impl PumpkinBlock for RedstoneWireBlock { _notify: bool, ) { if can_place_at(world, pos).await { - let state = world.get_block_state(pos).await.unwrap(); + let state = world.get_block_state(pos).await; let mut wire = RedstoneWireProperties::from_state_id(state.id, block); let new_power = calculate_power(world, pos).await; if wire.power.to_index() as u8 != new_power { @@ -279,7 +279,7 @@ impl PumpkinBlock for RedstoneWireBlock { } async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { - let floor = world.get_block_state(&block_pos.down()).await.unwrap(); + let floor = world.get_block_state(&block_pos.down()).await; // TODO: Only check face instead of block floor.is_full_cube() } @@ -351,24 +351,20 @@ fn can_connect_diagonal_to(block: &Block) -> bool { pub async fn get_side(world: &World, pos: &BlockPos, side: BlockDirection) -> WireConnection { let neighbor_pos: BlockPos = pos.offset(side.to_offset()); - let (neighbor, state) = world - .get_block_and_block_state(&neighbor_pos) - .await - .unwrap(); + let (neighbor, state) = world.get_block_and_block_state(&neighbor_pos).await; if can_connect_to(world, &neighbor, side, &state).await { return WireConnection::Side; } let up_pos = pos.offset(BlockDirection::Up.to_offset()); - let up_state = world.get_block_state(&up_pos).await.unwrap(); + let up_state = world.get_block_state(&up_pos).await; if !up_state.is_solid() && can_connect_diagonal_to( &world .get_block(&neighbor_pos.offset(BlockDirection::Up.to_offset())) - .await - .unwrap(), + .await, ) { WireConnection::Up @@ -376,8 +372,7 @@ pub async fn get_side(world: &World, pos: &BlockPos, side: BlockDirection) -> Wi && can_connect_diagonal_to( &world .get_block(&neighbor_pos.offset(BlockDirection::Down.to_offset())) - .await - .unwrap(), + .await, ) { WireConnection::Side @@ -581,7 +576,7 @@ impl CardinalWireConnectionExt for WestWireConnection { } async fn max_wire_power(wire_power: u8, world: &World, pos: BlockPos) -> u8 { - let (block, block_state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(&pos).await; if block == Block::REDSTONE_WIRE { let wire = RedstoneWireProperties::from_state_id(block_state.id, &block); wire_power.max(wire.power.to_index() as u8) @@ -595,15 +590,12 @@ async fn calculate_power(world: &World, pos: &BlockPos) -> u8 { let mut wire_power: u8 = 0; let up_pos = pos.offset(BlockDirection::Up.to_offset()); - let (_up_block, up_state) = world.get_block_and_block_state(&up_pos).await.unwrap(); + let (_up_block, up_state) = world.get_block_and_block_state(&up_pos).await; for side in BlockDirection::all() { let neighbor_pos = pos.offset(side.to_offset()); wire_power = max_wire_power(wire_power, world, neighbor_pos).await; - let (neighbor, neighbor_state) = world - .get_block_and_block_state(&neighbor_pos) - .await - .unwrap(); + let (neighbor, neighbor_state) = world.get_block_and_block_state(&neighbor_pos).await; block_power = block_power.max( get_redstone_power_no_dust(&neighbor, &neighbor_state, world, neighbor_pos, side).await, ); diff --git a/pumpkin/src/block/blocks/redstone/repeater.rs b/pumpkin/src/block/blocks/redstone/repeater.rs index 87fbc530f..762b90ddd 100644 --- a/pumpkin/src/block/blocks/redstone/repeater.rs +++ b/pumpkin/src/block/blocks/redstone/repeater.rs @@ -66,7 +66,7 @@ impl PumpkinBlock for RepeaterBlock { _source_block: &Block, _notify: bool, ) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; let mut rep = RepeaterProperties::from_state_id(state.id, block); let should_be_locked = should_be_locked(&rep.facing, world, block_pos).await; if !rep.locked && should_be_locked { @@ -90,7 +90,7 @@ impl PumpkinBlock for RepeaterBlock { } async fn on_scheduled_tick(&self, world: &Arc, block: &Block, block_pos: &BlockPos) { - let state = world.get_block_state(block_pos).await.unwrap(); + let state = world.get_block_state(block_pos).await; let mut rep = RepeaterProperties::from_state_id(state.id, block); if rep.locked { return; @@ -120,7 +120,7 @@ impl PumpkinBlock for RepeaterBlock { _server: &Server, world: &Arc, ) { - let state = world.get_block_state(&location).await.unwrap(); + let state = world.get_block_state(&location).await; let props = RepeaterProperties::from_state_id(state.id, block); on_use(props, world, location, block).await; } @@ -134,7 +134,7 @@ impl PumpkinBlock for RepeaterBlock { _server: &Server, world: &Arc, ) -> BlockActionResult { - let state = world.get_block_state(&location).await.unwrap(); + let state = world.get_block_state(&location).await; let props = RepeaterProperties::from_state_id(state.id, block); on_use(props, world, location, block).await; BlockActionResult::Consume @@ -204,7 +204,7 @@ async fn should_be_locked(facing: &HorizontalFacing, world: &World, pos: &BlockP async fn get_power_on_side(world: &World, pos: &BlockPos, side: HorizontalFacing) -> u8 { let side_pos = pos.offset(side.to_block_direction().to_offset()); - let (side_block, side_state) = world.get_block_and_block_state(&side_pos).await.unwrap(); + let (side_block, side_state) = world.get_block_and_block_state(&side_pos).await; if is_diode(&side_block) { get_weak_power( &side_block, @@ -222,12 +222,12 @@ async fn get_power_on_side(world: &World, pos: &BlockPos, side: HorizontalFacing async fn on_state_change(rep: RepeaterProperties, world: &Arc, pos: &BlockPos) { let front_pos = pos.offset(rep.facing.opposite().to_block_direction().to_offset()); - let front_block = world.get_block(&front_pos).await.unwrap(); + let front_block = world.get_block(&front_pos).await; world.update_neighbor(&front_pos, &front_block).await; for direction in BlockDirection::all() { let neighbor_pos = front_pos.offset(direction.to_offset()); - let block = world.get_block(&neighbor_pos).await.unwrap(); + let block = world.get_block(&neighbor_pos).await; world.update_neighbor(&neighbor_pos, &block).await; } } @@ -240,8 +240,7 @@ async fn schedule_tick( ) { let front_block = world .get_block(&pos.offset(rep.facing.opposite().to_block_direction().to_offset())) - .await - .unwrap(); + .await; let priority = if is_diode(&front_block) { TickPriority::ExtremelyHigh } else if !should_be_powered { diff --git a/pumpkin/src/block/blocks/redstone/turbo.rs b/pumpkin/src/block/blocks/redstone/turbo.rs index a3c4e36b4..791990e1e 100644 --- a/pumpkin/src/block/blocks/redstone/turbo.rs +++ b/pumpkin/src/block/blocks/redstone/turbo.rs @@ -4,7 +4,10 @@ use pumpkin_data::{ Block, BlockState, - block_properties::{BlockProperties, EnumVariants, Integer0To15, RedstoneWireLikeProperties}, + block_properties::{ + BlockProperties, EnumVariants, Integer0To15, RedstoneWireLikeProperties, + get_state_by_state_id, + }, }; use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use pumpkin_world::{block::BlockDirection, world::BlockFlags}; @@ -42,7 +45,7 @@ impl UpdateNode { async fn new(world: &World, pos: BlockPos) -> Self { Self { pos, - state: world.get_block_state(&pos).await.unwrap(), + state: world.get_block_state(&pos).await, visited: false, neighbors: None, xbias: 0, @@ -329,9 +332,7 @@ impl RedstoneWireTurbo { let node = &mut self.nodes[upd1.index]; let mut wire = unwrap_wire(&node.state); wire.power = new_wire.power; - node.state = world - .get_state_by_id(wire.to_state_id(&Block::REDSTONE_WIRE)) - .unwrap(); + node.state = get_state_by_state_id(wire.to_state_id(&Block::REDSTONE_WIRE)).unwrap(); self.propagate_changes(world, upd1, layer).await; } diff --git a/pumpkin/src/block/blocks/stairs.rs b/pumpkin/src/block/blocks/stairs.rs index 8e76f3f27..bd752fd1a 100644 --- a/pumpkin/src/block/blocks/stairs.rs +++ b/pumpkin/src/block/blocks/stairs.rs @@ -77,7 +77,7 @@ impl PumpkinBlock for StairBlock { _source_block: &Block, _notify: bool, ) { - let state_id = world.get_block_state_id(block_pos).await.unwrap(); + let state_id = world.get_block_state_id(block_pos).await; let mut stair_props = StairsProperties::from_state_id(state_id, block); let new_shape = @@ -158,7 +158,7 @@ async fn get_stair_properties_if_exists( world: &World, block_pos: &BlockPos, ) -> Option { - let (block, block_state) = world.get_block_and_block_state(block_pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(block_pos).await; block .is_tagged_with("#minecraft:stairs") .unwrap() diff --git a/pumpkin/src/block/blocks/sugar_cane.rs b/pumpkin/src/block/blocks/sugar_cane.rs index e01806244..f8fb85dd6 100644 --- a/pumpkin/src/block/blocks/sugar_cane.rs +++ b/pumpkin/src/block/blocks/sugar_cane.rs @@ -32,12 +32,8 @@ impl PumpkinBlock for SugarCaneBlock { } async fn random_tick(&self, block: &Block, world: &Arc, pos: &BlockPos) { - if world.get_block_state(&pos.up()).await.unwrap().is_air() { - let state_id = world - .get_block_state(pos) - .await - .expect("`location` should be a sugar cane") - .id; + if world.get_block_state(&pos.up()).await.is_air() { + let state_id = world.get_block_state(pos).await.id; let age = CactusLikeProperties::from_state_id(state_id, block).age; if age == Integer0To15::L15 { world @@ -93,7 +89,7 @@ impl PumpkinBlock for SugarCaneBlock { } async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { - let block_below = world.get_block(&block_pos.down()).await.unwrap(); + let block_below = world.get_block(&block_pos.down()).await; if block_below == Block::SUGAR_CANE { return true; @@ -105,8 +101,7 @@ async fn can_place_at(world: &World, block_pos: &BlockPos) -> bool { for direction in HorizontalFacing::all() { let block = world .get_block(&block_pos.down().offset(direction.to_offset())) - .await - .unwrap(); + .await; if block == Block::WATER || block == Block::FROSTED_ICE { return true; diff --git a/pumpkin/src/block/blocks/trapdoor.rs b/pumpkin/src/block/blocks/trapdoor.rs index e26207fe1..ad6a2b17c 100644 --- a/pumpkin/src/block/blocks/trapdoor.rs +++ b/pumpkin/src/block/blocks/trapdoor.rs @@ -21,7 +21,7 @@ use std::sync::Arc; type TrapDoorProperties = pumpkin_data::block_properties::OakTrapdoorLikeProperties; async fn toggle_trapdoor(world: &Arc, block_pos: &BlockPos) { - let (block, block_state) = world.get_block_and_block_state(block_pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(block_pos).await; let mut trapdoor_props = TrapDoorProperties::from_state_id(block_state.id, &block); trapdoor_props.open = !trapdoor_props.open; @@ -147,7 +147,7 @@ impl PumpkinBlock for TrapDoorBlock { _source_block: &Block, _notify: bool, ) { - let block_state = world.get_block_state(pos).await.unwrap(); + let block_state = world.get_block_state(pos).await; let mut trapdoor_props = TrapDoorProperties::from_state_id(block_state.id, block); let powered = block_receives_redstone_power(world, pos).await; if powered != trapdoor_props.powered { diff --git a/pumpkin/src/block/blocks/walls.rs b/pumpkin/src/block/blocks/walls.rs index 0ff044755..5b018888f 100644 --- a/pumpkin/src/block/blocks/walls.rs +++ b/pumpkin/src/block/blocks/walls.rs @@ -75,18 +75,12 @@ pub async fn compute_wall_state( block: &Block, block_pos: &BlockPos, ) -> u16 { - let (block_above, block_above_state) = world - .get_block_and_block_state(&block_pos.up()) - .await - .unwrap(); + let (block_above, block_above_state) = world.get_block_and_block_state(&block_pos.up()).await; for direction in HorizontalFacing::all() { let other_block_pos = block_pos.offset(direction.to_offset()); - let Ok((other_block, other_block_state)) = - world.get_block_and_block_state(&other_block_pos).await - else { - continue; - }; + let (other_block, other_block_state) = + world.get_block_and_block_state(&other_block_pos).await; let connected = other_block == *block || (other_block_state.is_solid() && other_block_state.is_full_cube()) diff --git a/pumpkin/src/block/fluid/flowing.rs b/pumpkin/src/block/fluid/flowing.rs index 44c967d10..b596f8baa 100644 --- a/pumpkin/src/block/fluid/flowing.rs +++ b/pumpkin/src/block/fluid/flowing.rs @@ -87,9 +87,7 @@ pub trait FlowingFluid { } async fn spread_fluid(&self, world: &Arc, fluid: &Fluid, block_pos: &BlockPos) { - let Ok(block_state_id) = world.get_block_state_id(block_pos).await else { - return; - }; + let block_state_id = world.get_block_state_id(block_pos).await; if let Some(new_fluid_state) = self.get_new_liquid(world, fluid, block_pos).await { if new_fluid_state.to_state_id(fluid) != block_state_id { world @@ -147,9 +145,7 @@ pub trait FlowingFluid { fluid: &Fluid, block_pos: &BlockPos, ) -> Option { - let Ok(current_state_id) = world.get_block_state_id(block_pos).await else { - return None; - }; + let current_state_id = world.get_block_state_id(block_pos).await; let current_props = FlowingFluidProperties::from_state_id(current_state_id, fluid); let current_level = i32::from(current_props.level.to_index()) + 1; @@ -161,9 +157,7 @@ pub trait FlowingFluid { for direction in BlockDirection::horizontal() { let neighbor_pos = block_pos.offset(direction.to_offset()); - let Ok(neighbor_state_id) = world.get_block_state_id(&neighbor_pos).await else { - continue; - }; + let neighbor_state_id = world.get_block_state_id(&neighbor_pos).await; if !self.is_same_fluid(fluid, neighbor_state_id) { continue; @@ -181,9 +175,7 @@ pub trait FlowingFluid { if source_count >= 2 && self.can_convert_to_source(world).await { let below_pos = block_pos.down(); - let Ok(below_state_id) = world.get_block_state_id(&below_pos).await else { - return Some(current_props); - }; + let below_state_id = world.get_block_state_id(&below_pos).await; if self .is_solid_or_source(world, &below_pos, below_state_id, fluid) .await @@ -193,9 +185,7 @@ pub trait FlowingFluid { } let above_pos = block_pos.up(); - let Ok(above_state_id) = world.get_block_state_id(&above_pos).await else { - return Some(current_props); - }; + let above_state_id = world.get_block_state_id(&above_pos).await; if self.is_same_fluid(fluid, above_state_id) { return Some(self.get_flowing(fluid, Level::L8, true).await); @@ -223,9 +213,7 @@ pub trait FlowingFluid { state_id: BlockStateId, fluid: &Fluid, ) -> bool { - let Ok(block) = world.get_block(block_pos).await else { - return false; - }; + let block = world.get_block(block_pos).await; if block.id != 0 && !self.can_be_replaced(world, block_pos, block.id).await { return true; @@ -240,9 +228,7 @@ pub trait FlowingFluid { } async fn spread_to_sides(&self, world: &Arc, fluid: &Fluid, block_pos: &BlockPos) { - let Ok(block_state_id) = world.get_block_state_id(block_pos).await else { - return; - }; + let block_state_id = world.get_block_state_id(block_pos).await; let props = FlowingFluidProperties::from_state_id(block_state_id, fluid); let level = i32::from(props.level.to_index()) + 1; @@ -286,9 +272,7 @@ pub trait FlowingFluid { let mut ctx = None; for direction in BlockDirection::horizontal() { let side_pos = block_pos.offset(direction.to_offset()); - let Ok(side_state_id) = world.get_block_state_id(&side_pos).await else { - continue; - }; + let side_state_id = world.get_block_state_id(&side_pos).await; let side_props = FlowingFluidProperties::from_state_id(side_state_id, fluid); @@ -349,9 +333,7 @@ pub trait FlowingFluid { continue; } - let Ok(next_state_id) = world.get_block_state_id(&next_pos).await else { - continue; - }; + let next_state_id = world.get_block_state_id(&next_pos).await; if self.is_same_fluid(fluid, next_state_id) { let next_props = FlowingFluidProperties::from_state_id(next_state_id, fluid); @@ -395,9 +377,7 @@ pub trait FlowingFluid { } async fn can_pass_through(&self, world: &Arc, fluid: &Fluid, pos: &BlockPos) -> bool { - let Ok(state_id) = world.get_block_state_id(pos).await else { - return false; - }; + let state_id = world.get_block_state_id(pos).await; if self.is_same_fluid(fluid, state_id) { return true; @@ -407,9 +387,7 @@ pub trait FlowingFluid { } async fn can_replace_block(&self, world: &Arc, pos: &BlockPos, _fluid: &Fluid) -> bool { - let Ok(block) = world.get_block(pos).await else { - return false; - }; + let block = world.get_block(pos).await; if self.can_be_replaced(world, pos, block.id).await { return true; @@ -419,9 +397,7 @@ pub trait FlowingFluid { } async fn can_be_replaced(&self, world: &Arc, pos: &BlockPos, block_id: BlockId) -> bool { - let Ok(block_state_id) = world.get_block_state_id(pos).await else { - return false; - }; + let block_state_id = world.get_block_state_id(pos).await; if let Some(fluid) = Fluid::from_state_id(block_state_id) { if fluid.is_source(block_state_id) && fluid.is_falling(block_state_id) { @@ -440,9 +416,7 @@ pub trait FlowingFluid { _pos: &BlockPos, below_pos: &BlockPos, ) -> bool { - let Ok(below_state_id) = world.get_block_state_id(below_pos).await else { - return false; - }; + let below_state_id = world.get_block_state_id(below_pos).await; if self.is_same_fluid(fluid, below_state_id) { return true; diff --git a/pumpkin/src/block/mod.rs b/pumpkin/src/block/mod.rs index ec29e2eae..2a64bdeac 100644 --- a/pumpkin/src/block/mod.rs +++ b/pumpkin/src/block/mod.rs @@ -1,6 +1,7 @@ use blocks::barrel::BarrelBlock; use blocks::bed::BedBlock; use blocks::cactus::CactusBlock; +use blocks::command::CommandBlock; use blocks::dirt_path::DirtPathBlock; use blocks::doors::DoorBlock; use blocks::farmland::FarmLandBlock; @@ -100,6 +101,7 @@ pub fn default_registry() -> Arc { manager.register(NetherPortalBlock); manager.register(NoteBlock); manager.register(PumpkinBlock); + manager.register(CommandBlock); manager.register(PressurePlateBlock); manager.register(WeightedPressurePlateBlock); diff --git a/pumpkin/src/block/registry.rs b/pumpkin/src/block/registry.rs index 2b6a322cb..ecc139bd2 100644 --- a/pumpkin/src/block/registry.rs +++ b/pumpkin/src/block/registry.rs @@ -299,10 +299,10 @@ impl BlockRegistry { block: &Block, flags: BlockFlags, ) { - let state = world.get_block_state(location).await.unwrap(); + let state = world.get_block_state(location).await; for direction in BlockDirection::all() { let neighbor_pos = location.offset(direction.to_offset()); - let neighbor_state = world.get_block_state(&neighbor_pos).await.unwrap(); + let neighbor_state = world.get_block_state(&neighbor_pos).await; let pumpkin_block = self.get_pumpkin_block(block); if let Some(pumpkin_block) = pumpkin_block { let new_state = pumpkin_block diff --git a/pumpkin/src/command/commands/fill.rs b/pumpkin/src/command/commands/fill.rs index 68ba7e89b..c4d716679 100644 --- a/pumpkin/src/command/commands/fill.rs +++ b/pumpkin/src/command/commands/fill.rs @@ -112,18 +112,16 @@ impl CommandExecutor for Executor { for y in start_y..=end_y { for z in start_z..=end_z { let block_position = BlockPos(Vector3 { x, y, z }); - match world.get_block_state(&block_position).await { - Ok(old_state) if old_state.is_air() => { - world - .set_block_state( - &block_position, - block_state_id, - BlockFlags::FORCE_STATE, - ) - .await; - placed_blocks += 1; - } - _ => {} + let old_state = world.get_block_state(&block_position).await; + if old_state.is_air() { + world + .set_block_state( + &block_position, + block_state_id, + BlockFlags::FORCE_STATE, + ) + .await; + placed_blocks += 1; } } } diff --git a/pumpkin/src/command/commands/setblock.rs b/pumpkin/src/command/commands/setblock.rs index e3f45e21a..eb3e89d5b 100644 --- a/pumpkin/src/command/commands/setblock.rs +++ b/pumpkin/src/command/commands/setblock.rs @@ -73,8 +73,9 @@ impl CommandExecutor for Executor { .await; true } - Mode::Keep => match world.get_block_state(&pos).await { - Ok(old_state) if old_state.is_air() => { + Mode::Keep => { + let old_state = world.get_block_state(&pos).await; + if old_state.is_air() { world .set_block_state( &pos, @@ -83,10 +84,10 @@ impl CommandExecutor for Executor { ) .await; true + } else { + false } - Ok(_) => false, - Err(e) => return Err(CommandError::OtherPumpkin(e.into())), - }, + } }; sender diff --git a/pumpkin/src/entity/living.rs b/pumpkin/src/entity/living.rs index a7cc8ad1f..43a622dbc 100644 --- a/pumpkin/src/entity/living.rs +++ b/pumpkin/src/entity/living.rs @@ -200,10 +200,7 @@ impl LivingEntity { pub async fn is_in_water(&self) -> bool { let world = self.entity.world.read().await; let block_pos = self.entity.block_pos.load(); - world - .get_block(&block_pos) - .await - .is_ok_and(|block| block == Block::WATER) + world.get_block(&block_pos).await == Block::WATER } pub async fn update_fall_distance( diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index 7f121c7f0..0d8371c2e 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -590,12 +590,11 @@ impl Entity { for y in blockpos.0.y..=blockpos1.0.y { for z in blockpos.0.z..=blockpos1.0.z { let pos = BlockPos::new(x, y, z); - if let Ok((block, state)) = world.get_block_and_block_state(&pos).await { - world - .block_registry - .on_entity_collision(block, &world, entity, pos, state, server) - .await; - } + let (block, state) = world.get_block_and_block_state(&pos).await; + world + .block_registry + .on_entity_collision(block, &world, entity, pos, state, server) + .await; if let Ok(fluid) = world.get_fluid(&pos).await { world .block_registry diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 143899f24..5bd154ebd 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -57,10 +57,6 @@ use pumpkin_inventory::{ use pumpkin_macros::send_cancellable; use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::tag::NbtTag; -use pumpkin_protocol::client::play::{ - CCloseContainer, CEntityPositionSync, COpenScreen, CSetContainerContent, CSetContainerProperty, - CSetContainerSlot, CSetCursorItem, CSetPlayerInventory, PlayerInfoFlags, PreviousMessage, -}; use pumpkin_protocol::{ IdOr, RawPacket, ServerPacket, client::play::{ @@ -91,6 +87,14 @@ use pumpkin_protocol::{ client::play::Metadata, server::play::{SClickSlot, SKeepAlive}, }; +use pumpkin_protocol::{ + client::play::{ + CCloseContainer, CEntityPositionSync, COpenScreen, CSetContainerContent, + CSetContainerProperty, CSetContainerSlot, CSetCursorItem, CSetPlayerInventory, + PlayerInfoFlags, PreviousMessage, + }, + server::play::SSetCommandBlock, +}; use pumpkin_util::{ GameMode, math::{ @@ -641,8 +645,8 @@ impl Player { if self.mining.load(Relaxed) { let pos = self.mining_pos.lock().await; let world = self.world().await; - let block = world.get_block(&pos).await.unwrap(); - let state = world.get_block_state(&pos).await.unwrap(); + let block = world.get_block(&pos).await; + let state = world.get_block_state(&pos).await; // Is the block broken? if state.is_air() { world @@ -1937,6 +1941,10 @@ impl Player { .handle_player_action(SPlayerAction::read(payload)?, server) .await; } + SSetCommandBlock::PACKET_ID => { + self.handle_set_command_block(SSetCommandBlock::read(payload)?) + .await; + } SPlayerCommand::PACKET_ID => { self.handle_player_command(SPlayerCommand::read(payload)?) .await; diff --git a/pumpkin/src/item/items/axe.rs b/pumpkin/src/item/items/axe.rs index c17536ce8..45f064ae1 100644 --- a/pumpkin/src/item/items/axe.rs +++ b/pumpkin/src/item/items/axe.rs @@ -50,7 +50,7 @@ impl PumpkinItem for AxeItem { let new_block = Block::from_id(replacement_block.unwrap()); let new_block = &new_block.unwrap(); let new_state_id = if block.is_tagged_with("#minecraft:logs") == Some(true) { - let log_information = world.get_block_state_id(&location).await.unwrap(); + let log_information = world.get_block_state_id(&location).await; let log_props = PaleOakWoodLikeProperties::from_state_id(log_information, block); // create new properties for the new log. let mut new_log_properties = PaleOakWoodLikeProperties::default(new_block); @@ -65,7 +65,7 @@ impl PumpkinItem for AxeItem { // Let's check if It's a door else if block.is_tagged_with("#minecraft:doors") == Some(true) { // get block state of the old log. - let door_information = world.get_block_state_id(&location).await.unwrap(); + let door_information = world.get_block_state_id(&location).await; // get the log properties let door_props = OakDoorLikeProperties::from_state_id(door_information, block); // create new properties for the new log. diff --git a/pumpkin/src/item/items/bucket.rs b/pumpkin/src/item/items/bucket.rs index 8091da414..629ea0f2c 100644 --- a/pumpkin/src/item/items/bucket.rs +++ b/pumpkin/src/item/items/bucket.rs @@ -60,15 +60,12 @@ fn get_start_and_end_pos(player: &Player) -> (Vector3, Vector3) { #[async_trait] impl PumpkinItem for EmptyBucketItem { - #[allow(clippy::too_many_lines)] async fn normal_use(&self, _item: &Item, player: &Player) { let world = player.world().await.clone(); let (start_pos, end_pos) = get_start_and_end_pos(player); let checker = async |pos: &BlockPos, world_inner: &Arc| { - let Ok(state_id) = world_inner.get_block_state_id(pos).await else { - return false; - }; + let state_id = world_inner.get_block_state_id(pos).await; state_id == Block::WATER.default_state_id || state_id == Block::LAVA.default_state_id }; @@ -76,10 +73,6 @@ impl PumpkinItem for EmptyBucketItem { let (block_pos, _) = world.raytrace(start_pos, end_pos, checker).await; if let Some(pos) = block_pos { - let Ok(_state_id) = world.get_block_state_id(&pos).await else { - return; - }; - world .set_block_state(&pos, Block::AIR.id, BlockFlags::NOTIFY_NEIGHBORS) .await; @@ -99,9 +92,7 @@ impl PumpkinItem for FilledBucketItem { let world = player.world().await.clone(); let (start_pos, end_pos) = get_start_and_end_pos(player); let checker = async |pos: &BlockPos, world_inner: &Arc| { - let Ok(state_id) = world_inner.get_block_state_id(pos).await else { - return false; - }; + let state_id = world_inner.get_block_state_id(pos).await; if Fluid::from_state_id(state_id).is_some() { return false; } diff --git a/pumpkin/src/item/items/hoe.rs b/pumpkin/src/item/items/hoe.rs index dab600c3d..a9f62c75d 100644 --- a/pumpkin/src/item/items/hoe.rs +++ b/pumpkin/src/item/items/hoe.rs @@ -61,11 +61,7 @@ impl PumpkinItem for HoeItem { if (block == &Block::GRASS_BLOCK || block == &Block::DIRT_PATH || block == &Block::DIRT) - && world - .get_block_state(&location.up()) - .await - .unwrap() - .is_air() + && world.get_block_state(&location.up()).await.is_air() { future_block = &Block::FARMLAND; } diff --git a/pumpkin/src/item/items/honeycomb.rs b/pumpkin/src/item/items/honeycomb.rs index 4486cf8ac..1114e6cb0 100644 --- a/pumpkin/src/item/items/honeycomb.rs +++ b/pumpkin/src/item/items/honeycomb.rs @@ -45,7 +45,7 @@ impl PumpkinItem for HoneyCombItem { && block.is_tagged_with("#minecraft:doors").unwrap() { // get block state of the old log. - let door_information = world.get_block_state_id(&location).await.unwrap(); + let door_information = world.get_block_state_id(&location).await; // get the log properties let door_props = OakDoorLikeProperties::from_state_id(door_information, block); // create new properties for the new log. diff --git a/pumpkin/src/item/items/shovel.rs b/pumpkin/src/item/items/shovel.rs index 9df0e2dc4..6ca66e573 100644 --- a/pumpkin/src/item/items/shovel.rs +++ b/pumpkin/src/item/items/shovel.rs @@ -46,12 +46,7 @@ impl PumpkinItem for ShovelItem { || block == &Block::MYCELIUM { let world = player.world().await; - if face != BlockDirection::Down - && world - .get_block_state(&location.up()) - .await - .unwrap() - .is_air() + if face != BlockDirection::Down && world.get_block_state(&location.up()).await.is_air() { world .set_block_state( diff --git a/pumpkin/src/net/packet/play.rs b/pumpkin/src/net/packet/play.rs index ce369683c..54e1c6f0b 100644 --- a/pumpkin/src/net/packet/play.rs +++ b/pumpkin/src/net/packet/play.rs @@ -3,6 +3,8 @@ use pumpkin_data::item::Item; use pumpkin_inventory::InventoryError; use pumpkin_inventory::equipment_slot::EquipmentSlot; use pumpkin_inventory::screen_handler::ScreenHandler; +use pumpkin_world::block::entities::BlockEntity; +use pumpkin_world::block::entities::command_block::CommandBlockEntity; use pumpkin_world::world::BlockFlags; use rsa::pkcs1v15::{Signature as RsaPkcs1v15Signature, VerifyingKey}; use rsa::signature::Verifier; @@ -47,7 +49,8 @@ use pumpkin_protocol::client::play::{ }; use pumpkin_protocol::codec::var_int::VarInt; use pumpkin_protocol::server::play::{ - FLAG_ON_GROUND, SChunkBatch, SCookieResponse as SPCookieResponse, SPlayerSession, SUpdateSign, + CommandBlockMode, FLAG_ON_GROUND, SChunkBatch, SCookieResponse as SPCookieResponse, + SPlayerSession, SSetCommandBlock, SUpdateSign, }; use pumpkin_protocol::{ client::play::{ @@ -86,7 +89,6 @@ pub enum BlockPlacingError { InvalidBlockFace, BlockOutOfWorld, InvalidGamemode, - NoBaseBlock, } impl std::fmt::Display for BlockPlacingError { @@ -99,13 +101,13 @@ impl PumpkinError for BlockPlacingError { fn is_kick(&self) -> bool { match self { Self::BlockOutOfReach | Self::BlockOutOfWorld | Self::InvalidGamemode => false, - Self::InvalidBlockFace | Self::NoBaseBlock => true, + Self::InvalidBlockFace => true, } } fn severity(&self) -> log::Level { match self { - Self::BlockOutOfWorld | Self::InvalidGamemode | Self::NoBaseBlock => log::Level::Trace, + Self::BlockOutOfWorld | Self::InvalidGamemode => log::Level::Trace, Self::BlockOutOfReach | Self::InvalidBlockFace => log::Level::Warn, } } @@ -114,7 +116,6 @@ impl PumpkinError for BlockPlacingError { match self { Self::BlockOutOfReach | Self::BlockOutOfWorld | Self::InvalidGamemode => None, Self::InvalidBlockFace => Some("Invalid block face".into()), - Self::NoBaseBlock => Some("No base block".into()), } } } @@ -565,9 +566,7 @@ impl Player { } let world = self.world().await; - let Ok(block) = world.get_block(&pick_item.pos).await else { - return; - }; + let block = world.get_block(&pick_item.pos).await; if block.item_id == 0 { // Invalid block id (blocks such as tall seagrass) @@ -606,6 +605,33 @@ impl Player { // // TODO: Implement and merge any redundant code with pick_item_from_block // } + pub async fn handle_set_command_block(&self, command: SSetCommandBlock) { + // TODO: check things + let pos = command.pos; + if let Some((nbt, block_entity)) = self.world().await.get_block_entity(&pos).await { + let command_entity = CommandBlockEntity::from_nbt(&nbt, pos); + + if block_entity.identifier() != command_entity.identifier() { + log::warn!( + "Client tried to change Command block but not Command block entity found" + ); + return; + } + + let Ok(command_block_mode) = CommandBlockMode::try_from(command.mode) else { + self.kick(TextComponent::text("Invalid Command block mode")) + .await; + return; + }; + + let _block_state = match command_block_mode { + CommandBlockMode::Chain => Block::CHAIN_COMMAND_BLOCK, + CommandBlockMode::Repeating => Block::REPEATING_COMMAND_BLOCK, + CommandBlockMode::Impulse => Block::COMMAND_BLOCK, + }; + } + } + pub async fn handle_player_command(&self, command: SPlayerCommand) { if command.entity_id != self.entity_id().into() { return; @@ -1099,8 +1125,7 @@ impl Player { let location = player_action.location; let entity = &self.living_entity.entity; let world = &entity.world.read().await; - let block = world.get_block(&location).await.unwrap(); - let state = world.get_block_state(&location).await.unwrap(); + let (block, state) = world.get_block_and_block_state(&location).await; let inventory = self.inventory(); let held = inventory.held_item(); @@ -1119,8 +1144,6 @@ impl Player { // TODO: Config if self.gamemode.load() == GameMode::Creative { // Block break & play sound - - let broken_state = world.get_block_state(&location).await.unwrap(); world .break_block( &location, @@ -1130,14 +1153,7 @@ impl Player { .await; server .block_registry - .broken( - Arc::clone(world), - &block, - self, - location, - server, - broken_state, - ) + .broken(Arc::clone(world), &block, self, location, server, state) .await; self.update_sequence(player_action.sequence.0); return; @@ -1150,7 +1166,7 @@ impl Player { let speed = block::calc_block_breaking(self, &state, block.name).await; // Instant break if speed >= 1.0 { - let broken_state = world.get_block_state(&location).await.unwrap(); + let broken_state = world.get_block_state(&location).await; world .break_block( &location, @@ -1219,27 +1235,26 @@ impl Player { .store(false, std::sync::atomic::Ordering::Relaxed); world.set_block_breaking(entity, location, -1).await; - if let Ok((block, state)) = world.get_block_and_block_state(&location).await { - let drop = self.gamemode.load() != GameMode::Creative - && self.can_harvest(&state, block.name).await; + let (block, state) = world.get_block_and_block_state(&location).await; + let drop = self.gamemode.load() != GameMode::Creative + && self.can_harvest(&state, block.name).await; - world - .break_block( - &location, - Some(self.clone()), - if drop { - BlockFlags::NOTIFY_NEIGHBORS - } else { - BlockFlags::SKIP_DROPS | BlockFlags::NOTIFY_NEIGHBORS - }, - ) - .await; + world + .break_block( + &location, + Some(self.clone()), + if drop { + BlockFlags::NOTIFY_NEIGHBORS + } else { + BlockFlags::SKIP_DROPS | BlockFlags::NOTIFY_NEIGHBORS + }, + ) + .await; - server - .block_registry - .broken(Arc::clone(world), &block, self, location, server, state) - .await; - } + server + .block_registry + .broken(Arc::clone(world), &block, self, location, server, state) + .await; self.update_sequence(player_action.sequence.0); } @@ -1329,9 +1344,7 @@ impl Player { let entity = &self.living_entity.entity; let world = &entity.world.read().await; - let Ok(block) = world.get_block(&location).await else { - return Err(BlockPlacingError::NoBaseBlock.into()); - }; + let block = world.get_block(&location).await; let sneaking = self .living_entity @@ -1593,7 +1606,7 @@ impl Player { let clicked_block_pos = BlockPos(location.0); let (clicked_block, clicked_block_state) = - world.get_block_and_block_state(&clicked_block_pos).await?; + world.get_block_and_block_state(&clicked_block_pos).await; let replace_clicked_block = if clicked_block == block { world @@ -1626,7 +1639,7 @@ impl Player { } else { let block_pos = BlockPos(location.0 + face.to_offset()); let (previous_block, previous_block_state) = - world.get_block_and_block_state(&block_pos).await?; + world.get_block_and_block_state(&block_pos).await; let replace_previous_block = if previous_block == block { world diff --git a/pumpkin/src/world/explosion.rs b/pumpkin/src/world/explosion.rs index ac4cb9f73..b94693528 100644 --- a/pumpkin/src/world/explosion.rs +++ b/pumpkin/src/world/explosion.rs @@ -41,8 +41,7 @@ impl Explosion { let mut h = self.power * (0.7 + rand::random::() * 0.6); while h > 0.0 { let block_pos = BlockPos::floored(pos_x, pos_y, pos_z); - let (block, state) = - world.get_block_and_block_state(&block_pos).await.unwrap(); + let (block, state) = world.get_block_and_block_state(&block_pos).await; // if !world.is_in_build_limit(&block_pos) { // // Pass by reference @@ -72,13 +71,13 @@ impl Explosion { let blocks = self.get_blocks_to_destroy(world).await; // TODO: Entity damage, fire for pos in blocks { - let block_state = world.get_block_state(&pos).await.unwrap(); + let block_state = world.get_block_state(&pos).await; if block_state.is_air() { continue; } - let block = world.get_block(&pos).await.unwrap(); + let block = world.get_block(&pos).await; let pumpkin_block = server.block_registry.get_pumpkin_block(&block); world.set_block_state(&pos, 0, BlockFlags::NOTIFY_ALL).await; diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index dbe56d978..f34641ade 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -213,7 +213,7 @@ impl World { // it prevents deadlocks and also removes the need to wait for a lock when adding a new synced block drop(queue); for event in events { - let block = self.get_block(&event.pos).await.unwrap(); // TODO + let block = self.get_block(&event.pos).await; // TODO if !self .block_registry .on_synced_block_event(&block, self, &event.pos, event.r#type, event.data) @@ -463,7 +463,7 @@ impl World { let fluids_to_tick = self.level.get_and_tick_fluid_ticks().await; for scheduled_tick in blocks_to_tick { - let block = self.get_block(&scheduled_tick.block_pos).await.unwrap(); + let block = self.get_block(&scheduled_tick.block_pos).await; if scheduled_tick.target_block_id != block.id { continue; } @@ -506,14 +506,12 @@ impl World { { let pos = BlockPos(Vector3::new(position.x, y, position.z)); let block = self.get_block_state(&pos).await; - if let Ok(block) = block { - if block.is_air() { - continue; - } + if block.is_air() { + continue; } return y; } - 319 + i32::from(generation_settings.shape.height) } #[expect(clippy::too_many_lines)] @@ -1378,7 +1376,7 @@ impl World { .await; } - let block_state = self.get_block_state(position).await.unwrap(); + let block_state = self.get_block_state(position).await; let new_block = Block::from_state_id(block_state_id).unwrap(); let new_fluid = self.get_fluid(position).await.unwrap_or(Fluid::EMPTY); @@ -1516,8 +1514,7 @@ impl World { cause: Option>, flags: BlockFlags, ) { - let (broken_block, broken_block_state) = - self.get_block_and_block_state(position).await.unwrap(); + let (broken_block, broken_block_state) = self.get_block_and_block_state(position).await; let event = BlockBreakEvent::new(cause.clone(), broken_block.clone(), *position, 0, false); let event = PLUGIN_MANAGER @@ -1583,10 +1580,7 @@ impl World { } } - pub async fn get_block_state_id( - &self, - position: &BlockPos, - ) -> Result { + pub async fn get_block_state_id(&self, position: &BlockPos) -> BlockStateId { let chunk = self.get_chunk(position).await; let (_, relative) = position.chunk_and_chunk_relative_position(); @@ -1596,49 +1590,43 @@ impl World { relative.y, relative.z as usize, ) else { - return Err(GetBlockError::BlockOutOfWorldBounds); + return Block::AIR.default_state_id; }; - Ok(id) + id } - /// Gets a `Block` from the block registry. Returns `None` if the block was not found. - pub async fn get_block( - &self, - position: &BlockPos, - ) -> Result { - let id = self.get_block_state_id(position).await?; - get_block_by_state_id(id).ok_or(GetBlockError::InvalidBlockId) + /// Gets a `Block` from the block registry. Returns `Block::AIR` if the block was not found. + pub async fn get_block(&self, position: &BlockPos) -> pumpkin_data::Block { + let id = self.get_block_state_id(position).await; + get_block_by_state_id(id).unwrap_or(Block::AIR) } pub async fn get_fluid( &self, position: &BlockPos, ) -> Result { - let id = self.get_block_state_id(position).await?; + let id = self.get_block_state_id(position).await; Fluid::from_state_id(id).ok_or(GetBlockError::InvalidBlockId) } - /// Gets the `BlockState` from the block registry. Returns `None` if the block state was not found. - pub async fn get_block_state( - &self, - position: &BlockPos, - ) -> Result { - let id = self.get_block_state_id(position).await?; - get_state_by_state_id(id).ok_or(GetBlockError::InvalidBlockId) - } - - pub fn get_state_by_id(&self, id: u16) -> Result { - get_state_by_state_id(id).ok_or(GetBlockError::InvalidBlockId) + /// Gets the `BlockState` from the block registry. Returns Air if the block state was not found. + pub async fn get_block_state(&self, position: &BlockPos) -> pumpkin_data::BlockState { + let id = self.get_block_state_id(position).await; + get_state_by_state_id(id) + .unwrap_or(get_state_by_state_id(Block::AIR.default_state_id).unwrap()) } /// Gets the Block + Block state from the Block Registry, Returns None if the Block state has not been found pub async fn get_block_and_block_state( &self, position: &BlockPos, - ) -> Result<(pumpkin_data::Block, pumpkin_data::BlockState), GetBlockError> { - let id = self.get_block_state_id(position).await?; - get_block_and_state_by_state_id(id).ok_or(GetBlockError::InvalidBlockId) + ) -> (pumpkin_data::Block, pumpkin_data::BlockState) { + let id = self.get_block_state_id(position).await; + get_block_and_state_by_state_id(id).unwrap_or(( + Block::AIR, + get_state_by_state_id(Block::AIR.default_state_id).unwrap(), + )) } /// Updates neighboring blocks of a block @@ -1647,7 +1635,7 @@ impl World { block_pos: &BlockPos, except: Option, ) { - let source_block = self.get_block(block_pos).await.unwrap(); + let source_block = self.get_block(block_pos).await; for direction in BlockDirection::update_order() { if except.is_some_and(|d| d == direction) { continue; @@ -1657,20 +1645,12 @@ impl World { let neighbor_block = self.get_block(&neighbor_pos).await; let neighbor_fluid = self.get_fluid(&neighbor_pos).await; - if let Ok(neighbor_block) = neighbor_block { - if let Some(neighbor_pumpkin_block) = - self.block_registry.get_pumpkin_block(&neighbor_block) - { - neighbor_pumpkin_block - .on_neighbor_update( - self, - &neighbor_block, - &neighbor_pos, - &source_block, - false, - ) - .await; - } + if let Some(neighbor_pumpkin_block) = + self.block_registry.get_pumpkin_block(&neighbor_block) + { + neighbor_pumpkin_block + .on_neighbor_update(self, &neighbor_block, &neighbor_pos, &source_block, false) + .await; } if let Ok(neighbor_fluid) = neighbor_fluid { @@ -1690,7 +1670,7 @@ impl World { neighbor_block_pos: &BlockPos, source_block: &Block, ) { - let neighbor_block = self.get_block(neighbor_block_pos).await.unwrap(); + let neighbor_block = self.get_block(neighbor_block_pos).await; if let Some(neighbor_pumpkin_block) = self.block_registry.get_pumpkin_block(&neighbor_block) { @@ -1712,13 +1692,7 @@ impl World { direction: BlockDirection, flags: BlockFlags, ) { - let (block, block_state) = match self.get_block_and_block_state(block_pos).await { - Ok(block) => block, - Err(_error) => { - // Neighbor is outside the world. Don't try to update it - return; - } - }; + let (block, block_state) = self.get_block_and_block_state(block_pos).await; if flags.contains(BlockFlags::SKIP_REDSTONE_WIRE_STATE_REPLACEMENT) && block.id == Block::REDSTONE_WIRE.id @@ -1727,7 +1701,7 @@ impl World { } let neighbor_pos = block_pos.offset(direction.to_offset()); - let neighbor_state_id = self.get_block_state_id(&neighbor_pos).await.unwrap(); + let neighbor_state_id = self.get_block_state_id(&neighbor_pos).await; let new_state_id = self .block_registry @@ -1902,7 +1876,7 @@ impl pumpkin_world::world::SimpleWorld for World { Self::set_block_state(&self, position, block_state_id, flags).await } - async fn get_block(&self, position: &BlockPos) -> Result { + async fn get_block(&self, position: &BlockPos) -> pumpkin_data::Block { Self::get_block(self, position).await } diff --git a/pumpkin/src/world/portal/nether.rs b/pumpkin/src/world/portal/nether.rs index fdd3e4ab6..facfe3cc6 100644 --- a/pumpkin/src/world/portal/nether.rs +++ b/pumpkin/src/world/portal/nether.rs @@ -121,7 +121,7 @@ impl NetherPortal { let limit_y = pos.0.y - Self::MAX_HEIGHT as i32; let mut pos = *pos; while pos.0.y > limit_y { - let (block, state) = world.get_block_and_block_state(&pos.down()).await.unwrap(); + let (block, state) = world.get_block_and_block_state(&pos.down()).await; if !Self::valid_state_inside_portal(&block, &state) { break; } @@ -143,17 +143,14 @@ impl NetherPortal { let mut lower_corner; for i in 0..=Self::MAX_WIDTH { lower_corner = original_lower_corner.offset_dir(negative_dir.to_offset(), i as i32); - let (block, block_state) = world - .get_block_and_block_state(&lower_corner) - .await - .unwrap(); + let (block, block_state) = world.get_block_and_block_state(&lower_corner).await; if !Self::valid_state_inside_portal(&block, &block_state) { if Self::FRAME_BLOCK != block { break; } return i; } - let block = world.get_block(&lower_corner.down()).await.unwrap(); + let block = world.get_block(&lower_corner.down()).await; if Self::FRAME_BLOCK != block { break; } @@ -196,14 +193,14 @@ impl NetherPortal { let mut pos = lower_corner .offset_dir(BlockDirection::Up.to_offset(), i) .offset_dir(negative_dir.to_offset(), -1); - if world.get_block(&pos).await.unwrap() != Self::FRAME_BLOCK { + if world.get_block(&pos).await != Self::FRAME_BLOCK { return i as u32; } pos = lower_corner .offset_dir(BlockDirection::Up.to_offset(), i) .offset_dir(negative_dir.to_offset(), width as i32); - if world.get_block(&pos).await.unwrap() != Self::FRAME_BLOCK { + if world.get_block(&pos).await != Self::FRAME_BLOCK { return i as u32; } @@ -211,7 +208,7 @@ impl NetherPortal { pos = lower_corner .offset_dir(BlockDirection::Up.to_offset(), i) .offset_dir(negative_dir.to_offset(), j as i32); - let (block, block_state) = world.get_block_and_block_state(&pos).await.unwrap(); + let (block, block_state) = world.get_block_and_block_state(&pos).await; if !Self::valid_state_inside_portal(&block, &block_state) { return i as u32; } @@ -235,7 +232,7 @@ impl NetherPortal { pos = lower_corner .offset_dir(BlockDirection::Up.to_offset(), height as i32) .offset_dir(dir.to_offset(), i as i32); - if Self::FRAME_BLOCK != world.get_block(&pos).await.unwrap() { + if Self::FRAME_BLOCK != world.get_block(&pos).await { return false; } }