Split block placement and interaction from the packet handler
@@ -9,7 +9,7 @@ use feather_core::items::ItemStack;
use feather_core::network::packets::PlayerBlockPlacement;
use feather_core::util::Gamemode;
use feather_server_types::{BlockUpdateCause, Game, HeldItem, InventoryUpdateEvent, PacketBuffers};
-use fecs::World;
+use fecs::{Entity, World};
use smallvec::smallvec;
use std::sync::Arc;
@@ -24,8 +24,42 @@ pub fn handle_player_block_placement(
packet_buffers
.received::<PlayerBlockPlacement>()
.for_each_valid(world, |world, (player, packet)| {
- // TODO: handle slabs, blocks with directions, etc.
+ let target_block = match game.block_at(packet.location) {
+ Some(block) => block,
+ None => {
+ game.disconnect(
+ player,
+ world,
+ "Attempted to interact with block in unloaded chunk",
+ );
+ return;
+ }
+ };
+
+ // Decide whether the player should place a block or interact with the block they are targeting
+ // TODO: Maybe player shifting may need to be taken into account (shift click on interactable block)
+ match target_block.kind() {
+ // Case which handles blocks that can be interacted with
+ BlockKind::Furnace | BlockKind::CraftingTable => {
+ handle_block_interaction(game, world, player, target_block.kind(), packet);
+ }
+ // Case which handles block placement (ie: target block is not interactable)
+ _ => {
+ handle_block_placement(game, world, player, target_block.kind(), packet);
+ }
+ };
+ });
+}
+
+pub fn handle_block_placement(
+ game: &mut Game,
+ world: &mut World,
+ player: Entity,
+ target_block_kind: BlockKind,
+ packet: PlayerBlockPlacement,
+) {
let gamemode = *world.get::<Gamemode>(player);
+
let inventory = world.get::<Inventory>(player);
let item = match inventory.item_in_main_hand(player, world) {
@@ -40,16 +74,8 @@ pub fn handle_player_block_placement(
None => return, // Item is not a block
};
- let placed_on = match game.block_at(packet.location) {
- Some(block) => block,
- None => {
- game.disconnect(player, world, "attempted to place block in unloaded chunk");
- return;
- }
- };
-
// TODO: waterlogged blocks, more
- let pos = match placed_on.kind() {
+ let pos = match target_block_kind {
BlockKind::Grass | BlockKind::TallGrass | BlockKind::Water | BlockKind::Lava => {
packet.location
}
@@ -85,5 +111,15 @@ pub fn handle_player_block_placement(
drop(inventory);
game.handle(world, event);
}
- });
+}
+
+/// Handles interaction with blocks that have an inventory
+pub fn handle_block_interaction(
+ game: &mut Game,
+ world: &mut World,
+ player: Entity,
+ target_block_kind: BlockKind,
+ packet: PlayerBlockPlacement,
+) {
+ let gamemode = *world.get::<Gamemode>(player);
}
