Skip to content

Commit

Permalink
Added item swapping
Browse files Browse the repository at this point in the history
  • Loading branch information
Bafran committed Dec 28, 2024
1 parent 1dcf6d6 commit d095e07
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
10 changes: 10 additions & 0 deletions pumpkin-inventory/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@ impl PlayerInventory {
self.selected
}

pub fn get_empty_slot(&self) -> Option<usize> {
for slot in 9..=44 {
if self.items[slot - 9].is_none() {
return Some(slot);
}
}

None
}

pub fn slots(&self) -> Vec<Option<&ItemStack>> {
let mut slots = vec![self.crafting_output.as_ref()];
slots.extend(self.crafting.iter().map(|c| c.as_ref()));
Expand Down
47 changes: 36 additions & 11 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ impl Player {
};

let mut inventory = self.inventory().lock().await;

let source_slot = inventory.get_slot_with_item(block.item_id);
let mut dest_slot = inventory.get_pick_item_hotbar_slot();

Expand All @@ -333,48 +334,59 @@ impl Player {

match source_slot {
Some(slot_index) if !(slot_index > 36 && slot_index <= 44) => {
// Handle existing item case
let item_stack = match inventory.get_slot(slot_index) {
Ok(Some(stack)) => *stack,
// Case where item is in inventory

// Save items
let source_slot_data = match inventory.get_slot(slot_index) {
Ok(Some(stack)) => Slot::from(&*stack),
_ => return,
};
let dest_slot_data = match inventory.get_slot(dest_slot + 36) {
Ok(Some(stack)) => Slot::from(&*stack),
_ => Slot::from(None),
};

// Update destination slot
let slot_data = Slot::from(&item_stack);
inventory.state_id += 1;
let dest_packet = CSetContainerSlot::new(
0,
inventory.state_id as i32,
dest_slot + 36,
&slot_data,
&source_slot_data,
);
self.client.send_packet(&dest_packet).await;

if inventory
.set_slot(dest_slot + 36, Some(item_stack), false)
.set_slot(dest_slot + 36, source_slot_data.to_item(), false)
.is_err()
{
log::error!("Pick item set slot error!");
return;
}

// Clear source slot
let slot_data = Slot::from(None);
// Update source slot
inventory.state_id += 1;
let source_packet =
CSetContainerSlot::new(0, inventory.state_id as i32, slot_index, &slot_data);
CSetContainerSlot::new(0, inventory.state_id as i32, slot_index, &dest_slot_data);
self.client.send_packet(&source_packet).await;

if inventory.set_slot(slot_index, None, false).is_err() {
if inventory.set_slot(slot_index, dest_slot_data.to_item(), false).is_err() {
log::error!("Failed to clear source slot!");
return;
}
}
Some(slot_index) => {
// Case where item is in hotbar
dest_slot = slot_index - 36;
}
None if self.gamemode.load() == GameMode::Creative => {
// Handle creative mode case
// Save dest slot data
let dest_slot_data = match inventory.get_slot(dest_slot + 36) {
Ok(Some(stack)) => Slot::from(&*stack),
_ => Slot::from(None),
};

// Case where item is not present, if in creative mode create the item
let item_stack = ItemStack::new(1, block.item_id);
let slot_data = Slot::from(&item_stack);
inventory.state_id += 1;
Expand All @@ -393,6 +405,19 @@ impl Player {
log::error!("Pick item set slot error!");
return;
}

// Check if there is any empty slot in the player inventory
if let Some(slot_index) = inventory.get_empty_slot() {
inventory.state_id += 1;
let source_packet = CSetContainerSlot::new(0, inventory.state_id as i32, slot_index, &dest_slot_data);
self.client.send_packet(&source_packet).await;

if inventory.set_slot(slot_index, dest_slot_data.to_item(), false).is_err() {
log::error!("Failed to clear source slot!");
return;
}
}

}
_ => return,
}
Expand Down

0 comments on commit d095e07

Please sign in to comment.