Skip to content

Commit

Permalink
Pick Item working for hotbar slots
Browse files Browse the repository at this point in the history
  • Loading branch information
Bafran committed Dec 27, 2024
1 parent 0793981 commit b26b964
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 48 deletions.
18 changes: 8 additions & 10 deletions pumpkin-inventory/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,15 @@ impl PlayerInventory {
self.items[self.selected + 36 - 9] = item;
}

pub fn get_hotbar_slot(&mut self) -> Option<usize> {
// // first searches the player's hotbar for an empty slot, starting from the current slot and looping around to the slot before it.
// for i in 0..9 {
// let slot = (self.selected + i) % 9;
// if self.items[slot + 36].is_none() {
// return Some(slot + 36);
// }
// }
pub fn get_pick_item_hotbar_slot(&mut self, item_id: u16) -> usize {
for slot in 35..=44 {
match &self.items[slot - 9] {
Some(item) if item.item_id == item_id => return slot,
_ => continue,
}
}

// If there still are no slots that meet that criteria, then the server uses the currently selected slot
Some(self.selected)
self.selected + 36
}


Expand Down
8 changes: 4 additions & 4 deletions pumpkin-protocol/src/server/play/s_pick_item.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use pumpkin_core::math::position::WorldPosition;
use pumpkin_macros::server_packet;
use serde::Deserialize;

use crate::VarInt;

#[derive(Deserialize)]
#[server_packet("play:pick_item_from_block")]
pub struct SPickItem {
pub slot: VarInt,
pub struct SPickItemFromBlock {
pub pos: WorldPosition,
pub include_data: bool,
}
91 changes: 60 additions & 31 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ use pumpkin_protocol::{
Action, ActionType, SChatCommand, SChatMessage, SClientCommand, SClientInformationPlay,
SConfirmTeleport, SInteract, SPlayPingRequest, SPlayerAbilities, SPlayerAction,
SPlayerCommand, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation,
SSetCreativeSlot, SSetHeldItem, SSwingArm, SUseItemOn, Status, SPickItem,
SSetCreativeSlot, SSetHeldItem, SSwingArm, SUseItemOn, Status, SPickItemFromBlock,
},
};
use pumpkin_world::block::{block_registry::get_block_by_item, BlockFace};
use pumpkin_world::item::item_registry::get_item_by_id;
use pumpkin_world::item::ItemStack;
use thiserror::Error;

fn modulus(a: f32, b: f32) -> f32 {
Expand Down Expand Up @@ -312,38 +313,66 @@ impl Player {
.store(ground.on_ground, std::sync::atomic::Ordering::Relaxed);
}

pub async fn handle_pick_item(&self, pick_item: SPickItem) {
let source_slot = pick_item.slot.0 as usize;
let mut inventory = self.inventory().lock().await;

let dest_slot = inventory.get_hotbar_slot().unwrap() + 36;
let dest_item = inventory.get_slot(source_slot).unwrap().as_ref();
pub async fn handle_pick_item_from_block(&self, pick_item: SPickItemFromBlock) {
let pos = pick_item.pos;
// If player is in creative mode && include_data, then pick block with additional data
let include_data = pick_item.include_data;

if self.can_interact_with_block_at(&pos, 1.0) {
let world = self.world();
let block = world.get_block(pos).await;
if let Ok(block) = block {
let item_id = block.item_id;
let mut inventory = self.inventory().lock().await;

log::warn!("Item id: {}", item_id);

let dest_slot = inventory.get_pick_item_hotbar_slot(item_id);
log::warn!("Dest slot: {}", dest_slot);
// let picked_item = ItemStack::new(1, item_id);
// let slot = Slot::from(&picked_item);
// // Returns previous value
// inventory.state_id += 1;
// // Set Container Slot with window ID set to -2, updating the chosen hotbar slot.
// let packet = CSetContainerSlot::new(
// (-2) as i8,
// (inventory.state_id) as i32,
// dest_slot,
// &slot
// );
// self.client.send_packet(&packet).await;

// Set held item
let packet = CSetHeldItem::new((dest_slot - 36) as i8);
self.client.send_packet(&packet).await;
}
} else {
log::warn!("Player cannot interact with block at {}", pos);
}

log::warn!("Picking item from slot {} to slot {}", source_slot, dest_slot);

// Set Container Slot with window ID set to -2, updating the chosen hotbar slot.
let slot = Slot::from(dest_item);
let packet = CSetContainerSlot::new(
(-2) as i8,
(inventory.state_id) as i32,
dest_slot,
&slot
);
self.client.send_packet(&packet).await;

// Set Container Slot with window ID set to -2, updating the slot where the picked item used to be.
let slot = Slot::from(None);
let packet = CSetContainerSlot::new(
(-2) as i8,
(inventory.state_id) as i32,
source_slot,
&slot
);
self.client.send_packet(&packet).await;

// Set Held Item, switching to the newly chosen slot.
let packet = CSetHeldItem::new(dest_slot as i8);
self.client.send_packet(&packet).await;
// Set Container Slot with window ID set to -2, updating the chosen hotbar slot.
// let packet = CSetContainerSlot::new(
// (-2) as i8,
// (inventory.state_id) as i32,
// dest_slot,
// &slot
// );
// self.client.send_packet(&packet).await;

// // Set Container Slot with window ID set to -2, updating the slot where the picked item used to be.
// let slot = Slot::from(None);
// let packet = CSetContainerSlot::new(
// (-2) as i8,
// (inventory.state_id) as i32,
// source_slot,
// &slot
// );
// self.client.send_packet(&packet).await;

// // Set Held Item, switching to the newly chosen slot.
// let packet = CSetHeldItem::new(dest_slot as i8);
// self.client.send_packet(&packet).await;
}

pub async fn handle_player_command(&self, command: SPlayerCommand) {
Expand Down
6 changes: 3 additions & 3 deletions pumpkin/src/entity/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use pumpkin_protocol::{
SChatCommand, SChatMessage, SClientCommand, SClientInformationPlay, SClientTickEnd,
SCommandSuggestion, SConfirmTeleport, SInteract, SPlayerAbilities, SPlayerAction,
SPlayerCommand, SPlayerInput, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation,
SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUseItem, SUseItemOn, SPickItem,
SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUseItem, SUseItemOn, SPickItemFromBlock,
},
RawPacket, ServerPacket, SoundCategory, VarInt,
};
Expand Down Expand Up @@ -712,8 +712,8 @@ impl Player {
SSetPlayerGround::PACKET_ID => {
self.handle_player_ground(&SSetPlayerGround::read(bytebuf)?);
}
SPickItem::PACKET_ID => {
self.handle_pick_item(SPickItem::read(bytebuf)?).await;
SPickItemFromBlock::PACKET_ID => {
self.handle_pick_item_from_block(SPickItemFromBlock::read(bytebuf)?).await;
}
SPlayerAbilities::PACKET_ID => {
self.handle_player_abilities(SPlayerAbilities::read(bytebuf)?)
Expand Down

0 comments on commit b26b964

Please sign in to comment.