diff --git a/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxHopperHandler.java b/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxHopperHandler.java index b5daca9..6c2811c 100644 --- a/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxHopperHandler.java +++ b/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxHopperHandler.java @@ -1,15 +1,11 @@ package me.barny1094875.shulkerstackingog.Listeners; -import me.barny1094875.shulkerstackingog.ShulkerStacking_OG; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.block.ShulkerBox; +import me.barny1094875.shulkerstackingog.ShulkerBoxHelpers.ShulkerBoxUtils; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; public class ShulkerBoxHopperHandler implements Listener { @@ -19,72 +15,44 @@ public class ShulkerBoxHopperHandler implements Listener { ItemStack eventItem = event.getItem(); Inventory eventDestination = event.getDestination(); Inventory eventSource = event.getSource(); - // if the item is a shulker box - if (eventItem.getType().toString().contains("SHULKER_BOX")) { + if (!ShulkerBoxUtils.isEmptyShulkerBox(eventItem)) { - // check that the shulker box is empty - BlockStateMeta shulkerMeta = (BlockStateMeta) eventItem.getItemMeta(); - ShulkerBox shulker = (ShulkerBox) shulkerMeta.getBlockState(); - if (!shulker.getInventory().isEmpty()) { + return; - return; + } + + event.setCancelled(true); + + int toMove = eventItem.getAmount(); + for (int i = 0; i < eventSource.getSize() && toMove > 0; i++) { + + ItemStack sourceItem = eventSource.getItem(i); + if (!ShulkerBoxUtils.isEmptyShulkerBox(sourceItem)) { + + continue; } - // cancel the event so that I can guarantee where the item will be - event.setCancelled(true); - // item is always in eventSource now + if (!sourceItem.getType().equals(eventItem.getType())) { - Material shulkerType = eventItem.getType(); - // loop through the destination to see if there is a shulker box stack to add to - for (int i = 0; i < eventDestination.getSize(); i++) { - - ItemStack destinationItem = eventDestination.getItem(i); - if (destinationItem == null) { - - continue; - - } - - // if the item is the right kind of shulker box - if (destinationItem.getType().equals(shulkerType)) { - - // check that the shulker boxes are emtpy - BlockStateMeta destinationShulkerMeta = (BlockStateMeta) destinationItem.getItemMeta(); - ShulkerBox destinationShulker = (ShulkerBox) destinationShulkerMeta.getBlockState(); - if (!destinationShulker.getInventory().isEmpty()) { - - continue; - - } - - // check that the item stack is not full - if (destinationItem.getAmount() > 63) { - - continue; - - } - - destinationItem.setAmount(destinationItem.getAmount() + 1); - Bukkit.getScheduler().runTaskLater(ShulkerStacking_OG.getPlugin(), () -> { - - eventItem.setAmount(eventItem.getAmount() - 1); - - }, 1); - return; - - } + continue; } - // if no shulker box was found, try to put it in the first empty slot - if (eventDestination.addItem(eventItem).isEmpty()) { + int moveAmount = Math.min(sourceItem.getAmount(), toMove); + int remaining = ShulkerBoxUtils.mergeIntoExistingStacks(eventDestination, eventItem, moveAmount); + remaining = ShulkerBoxUtils.fillEmptySlots(eventDestination, eventItem, remaining); - Bukkit.getScheduler().runTaskLater(ShulkerStacking_OG.getPlugin(), () -> { + int moved = moveAmount - remaining; + if (moved > 0) { - eventItem.setAmount(eventItem.getAmount() - 1); + sourceItem.setAmount(sourceItem.getAmount() - moved); + toMove -= moved; + if (sourceItem.getAmount() <= 0) { - }, 1); + eventSource.setItem(i, null); + + } } diff --git a/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxMergeHandler.java b/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxMergeHandler.java new file mode 100644 index 0000000..5fdc667 --- /dev/null +++ b/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxMergeHandler.java @@ -0,0 +1,55 @@ +package me.barny1094875.shulkerstackingog.Listeners; + +import me.barny1094875.shulkerstackingog.ShulkerBoxHelpers.ShulkerBoxUtils; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ItemMergeEvent; +import org.bukkit.inventory.ItemStack; + +public class ShulkerBoxMergeHandler implements Listener { + + @EventHandler + public void onItemMerge(ItemMergeEvent event) { + + ItemStack target = event.getTarget().getItemStack(); + ItemStack source = event.getEntity().getItemStack(); + + if (!ShulkerBoxUtils.isEmptyShulkerBox(target) || !ShulkerBoxUtils.isEmptyShulkerBox(source)) { + + return; + + } + + if (!target.getType().equals(source.getType())) { + + return; + + } + + event.setCancelled(true); + + int space = 64 - target.getAmount(); + if (space <= 0) { + + return; + + } + + int moved = Math.min(space, source.getAmount()); + target.setAmount(target.getAmount() + moved); + int remaining = source.getAmount() - moved; + + if (remaining <= 0) { + + event.getEntity().remove(); + + } else { + + source.setAmount(remaining); + event.getEntity().setItemStack(source); + + } + + } + +} diff --git a/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxPickupHandler.java b/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxPickupHandler.java index e8f7243..6752b9e 100644 --- a/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxPickupHandler.java +++ b/src/main/java/me/barny1094875/shulkerstackingog/Listeners/ShulkerBoxPickupHandler.java @@ -1,6 +1,6 @@ package me.barny1094875.shulkerstackingog.Listeners; -import org.bukkit.block.ShulkerBox; +import me.barny1094875.shulkerstackingog.ShulkerBoxHelpers.ShulkerBoxUtils; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -8,7 +8,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; public class ShulkerBoxPickupHandler implements Listener { @@ -16,88 +15,40 @@ public class ShulkerBoxPickupHandler implements Listener { public void shulkerBoxStacking(EntityPickupItemEvent event) { ItemStack item = event.getItem().getItemStack(); + if (!event.getEntity().getType().equals(EntityType.PLAYER)) { return; } - Player player = (Player) event.getEntity(); - Inventory playerInventory = player.getInventory(); - if (item.getType().toString().contains("SHULKER_BOX")) { + if (!ShulkerBoxUtils.isEmptyShulkerBox(item)) { - BlockStateMeta shulker1Meta = (BlockStateMeta) item.getItemMeta(); - ShulkerBox shulker1 = (ShulkerBox) shulker1Meta.getBlockState(); - // check the inventory of the ground item shulker - if (shulker1.getInventory().isEmpty()) { - - // check for shulker box stacks to add to - for (int i = 0; i < playerInventory.getSize(); i++) { - - ItemStack inventoryItem = playerInventory.getItem(i); - if (inventoryItem == null) { - - continue; - - } - - if (inventoryItem.getType().equals(item.getType())) { - - BlockStateMeta shulker2Meta = (BlockStateMeta) inventoryItem.getItemMeta(); - ShulkerBox shulker2 = (ShulkerBox) shulker2Meta.getBlockState(); - // check the inventory of the inventory shulker - if (shulker2.getInventory().isEmpty()) { - - if (inventoryItem.getAmount() + item.getAmount() <= 64) { - - inventoryItem.setAmount(inventoryItem.getAmount() + item.getAmount()); - event.getItem().setHealth(-1); - event.setCancelled(true); - return; - - } - - if (inventoryItem.getAmount() <= 64) { - - item.setAmount((item.getAmount() + inventoryItem.getAmount()) - 64); - if (item.getAmount() <= 0) { - - event.getItem().setHealth(-1); - return; - - } - - event.getItem().setItemStack(item); - inventoryItem.setAmount(64); - event.setCancelled(true); - - } - - } - - } - - } - - // look for air gaps to add the shulkers to - for (int i = 0; i < playerInventory.getSize(); i++) { - - ItemStack inventoryItem = playerInventory.getItem(i); - if (inventoryItem == null) { - - playerInventory.setItem(i, item); - event.getItem().setHealth(-1); - event.setCancelled(true); - return; - - } - - } - - } + return; } + event.setCancelled(true); + + Player player = (Player) event.getEntity(); + Inventory playerInventory = player.getInventory(); + + int remaining = item.getAmount(); + remaining = ShulkerBoxUtils.mergeIntoExistingStacks(playerInventory, item, remaining); + remaining = ShulkerBoxUtils.fillEmptySlots(playerInventory, item, remaining); + + if (remaining <= 0) { + + event.getItem().remove(); + player.updateInventory(); + return; + + } + + ItemStack remainingItem = new ItemStack(item.getType(), remaining); + event.getItem().setItemStack(remainingItem); + player.updateInventory(); + } } diff --git a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalLeftClick.java b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalLeftClick.java index aa3f42d..49688d5 100644 --- a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalLeftClick.java +++ b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalLeftClick.java @@ -1,5 +1,6 @@ package me.barny1094875.shulkerstackingog.ShulkerBoxHelpers; +import org.bukkit.Material; import org.bukkit.block.ShulkerBox; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; @@ -27,7 +28,7 @@ public class NormalLeftClick { // add the shulker itemStacks together event.getCurrentItem() .setAmount(event.getCursor().getAmount() + event.getCurrentItem().getAmount()); - event.getWhoClicked().getItemOnCursor().setAmount(0); + event.getWhoClicked().setItemOnCursor(new ItemStack(Material.AIR)); } else { diff --git a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalRightClick.java b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalRightClick.java index e0cebe0..618910c 100644 --- a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalRightClick.java +++ b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/NormalRightClick.java @@ -1,5 +1,6 @@ package me.barny1094875.shulkerstackingog.ShulkerBoxHelpers; +import org.bukkit.Material; import org.bukkit.block.ShulkerBox; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; @@ -25,7 +26,16 @@ public class NormalRightClick { if (currentItem.getAmount() < 64) { event.getCurrentItem().setAmount(currentItem.getAmount() + 1); - event.getCursor().setAmount(cursorItem.getAmount() - 1); + int newCursorAmount = cursorItem.getAmount() - 1; + if (newCursorAmount <= 0) { + + event.getWhoClicked().setItemOnCursor(new ItemStack(Material.AIR)); + + } else { + + event.getCursor().setAmount(newCursorAmount); + + } event.setCancelled(true); } diff --git a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/ShulkerBoxUtils.java b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/ShulkerBoxUtils.java new file mode 100644 index 0000000..a28f5da --- /dev/null +++ b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerBoxHelpers/ShulkerBoxUtils.java @@ -0,0 +1,101 @@ +package me.barny1094875.shulkerstackingog.ShulkerBoxHelpers; + +import org.bukkit.Material; +import org.bukkit.block.ShulkerBox; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; + +public final class ShulkerBoxUtils { + + private ShulkerBoxUtils() { + + } + + public static boolean isEmptyShulkerBox(ItemStack itemStack) { + + if (itemStack == null || itemStack.getType() == Material.AIR) { + + return false; + + } + + if (!itemStack.getType().toString().contains("SHULKER_BOX")) { + + return false; + + } + + if (!(itemStack.getItemMeta() instanceof BlockStateMeta)) { + + return false; + + } + + BlockStateMeta meta = (BlockStateMeta) itemStack.getItemMeta(); + if (!(meta.getBlockState() instanceof ShulkerBox shulkerBox)) { + + return false; + + } + + return shulkerBox.getInventory().isEmpty(); + + } + + public static int mergeIntoExistingStacks(Inventory inventory, ItemStack prototype, int amountToAdd) { + + for (int i = 0; i < inventory.getSize() && amountToAdd > 0; i++) { + + ItemStack slot = inventory.getItem(i); + if (!isEmptyShulkerBox(slot)) { + + continue; + + } + + if (!slot.getType().equals(prototype.getType())) { + + continue; + + } + + int space = 64 - slot.getAmount(); + if (space <= 0) { + + continue; + + } + + int moved = Math.min(space, amountToAdd); + slot.setAmount(slot.getAmount() + moved); + amountToAdd -= moved; + + } + + return amountToAdd; + + } + + public static int fillEmptySlots(Inventory inventory, ItemStack prototype, int amountToAdd) { + + for (int i = 0; i < inventory.getSize() && amountToAdd > 0; i++) { + + ItemStack slot = inventory.getItem(i); + if (slot != null && slot.getType() != Material.AIR) { + + continue; + + } + + int moved = Math.min(64, amountToAdd); + inventory.setItem(i, new ItemStack(prototype.getType(), moved)); + amountToAdd -= moved; + + } + + return amountToAdd; + + } + +} diff --git a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerStacking_OG.java b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerStacking_OG.java index 039837d..72461f6 100644 --- a/src/main/java/me/barny1094875/shulkerstackingog/ShulkerStacking_OG.java +++ b/src/main/java/me/barny1094875/shulkerstackingog/ShulkerStacking_OG.java @@ -22,6 +22,7 @@ public final class ShulkerStacking_OG extends JavaPlugin { getServer().getPluginManager().registerEvents(new ShulkerDragHandler(), this); getServer().getPluginManager().registerEvents(new ShulkerDragDupePrevention(), this); getServer().getPluginManager().registerEvents(new ShulkerBoxHopperHandler(), this); + getServer().getPluginManager().registerEvents(new ShulkerBoxMergeHandler(), this); }