Skip to content

Commit

Permalink
Handle items being picked up (#61)
Browse files Browse the repository at this point in the history
When an item is now being picked up by a human entity who has an open gui which spans across the bottom inventory, items will now be moved to the internal cache if possible instead of picking put into the bottom inventory. Items that can't be put into the cache are left on the ground.
  • Loading branch information
stefvanschie committed Jun 30, 2020
1 parent 8d3478e commit 7f284b8
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -71,6 +74,45 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) {
}
}

/**
* Handles users picking up items while their bottom inventory is in use.
*
* @param event the event fired when an entity picks up an item
* @since 0.6.1
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onEntityPickupItem(@NotNull EntityPickupItemEvent event) {
if (!(event.getEntity() instanceof HumanEntity)) {
return;
}

InventoryHolder holder = ((HumanEntity) event.getEntity()).getOpenInventory().getTopInventory().getHolder();

if (!(holder instanceof Gui)) {
return;
}

Gui gui = (Gui) holder;

if (gui.getState() != Gui.State.BOTTOM) {
return;
}

int leftOver = gui.getHumanEntityCache().add((HumanEntity) event.getEntity(), event.getItem().getItemStack());

if (leftOver == 0) {
event.getItem().remove();
} else {
ItemStack itemStack = event.getItem().getItemStack();

itemStack.setAmount(leftOver);

event.getItem().setItemStack(itemStack);
}

event.setCancelled(true);
}

/**
* Handles small drag events which are likely clicks instead. These small drags will be interpreted as clicks and
* will fire a click event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,58 @@ public void restoreAndForgetAll() {
clearCache();
}

/**
* Adds the given item stack to the human entity's cached inventory. The returned amount is the amount of items of
* the provided item stack that could not be put into the cached inventory. This number will always be equal or
* less than the amount of items in the provided item stack, but no less than zero. The item stack provided will not
* be updated with this leftover amount. If the human entity provided is not in the human entity cache, this method
* will return an {@link IllegalStateException}. The items will be added to the inventory in the same way as the
* items are stored. The items may be added to an already existing item stack, but the item stack's amount will
* never go over the maximum stack size.
*
* @param humanEntity the human entity to add the item to
* @param item the item to add to the cached inventory
* @return the amount of leftover items that couldn't be fit in the cached inventory
* @throws IllegalStateException if the human entity's inventory is not cached
* @since 0.6.1
*/
protected int add(@NotNull HumanEntity humanEntity, @NotNull ItemStack item) {
ItemStack[] items = inventories.get(humanEntity);

if (items == null) {
throw new IllegalStateException("The human entity '" + humanEntity.getUniqueId().toString() +
"' does not have a cached inventory");
}

int amountPutIn = 0;

for (int i = 0; i < items.length; i++) {
ItemStack itemStack = items[i];

if (itemStack == null) {
items[i] = item.clone();
items[i].setAmount(item.getAmount() - amountPutIn);
amountPutIn = item.getAmount();
break;
}

if (!itemStack.isSimilar(item)) {
continue;
}

int additionalAmount = Math.min(itemStack.getMaxStackSize() - itemStack.getAmount(), item.getAmount());

itemStack.setAmount(itemStack.getAmount() + additionalAmount);
amountPutIn += additionalAmount;

if (amountPutIn == item.getAmount()) {
break;
}
}

return item.getAmount() - amountPutIn;
}

/**
* Stores this player's inventory in the cache. If the player was already stored, their cache will be overwritten.
*
Expand Down

0 comments on commit 7f284b8

Please sign in to comment.