diff --git a/pom.xml b/pom.xml index aeda679..d557bf0 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ org.apache.maven.plugins maven-compiler-plugin + 3.8.1 8 8 diff --git a/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java b/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java index 47ccd95..333af8a 100644 --- a/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java +++ b/src/main/java/de/studiocode/invui/gui/impl/IndexedGUI.java @@ -19,7 +19,6 @@ import de.studiocode.invui.window.Window; import de.studiocode.invui.window.WindowManager; import de.studiocode.invui.window.impl.merged.MergedWindow; import de.studiocode.invui.window.impl.merged.split.SplitWindow; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; @@ -131,8 +130,7 @@ abstract class IndexedGUI implements GUI { Window window = WindowManager.getInstance().findOpenWindow(player).orElse(null); ItemStack invStack = virtualInventory.getItemStack(index); - ItemUpdateEvent updateEvent = new ItemUpdateEvent(virtualInventory, index, updateReason, invStack, null); - Bukkit.getPluginManager().callEvent(updateEvent); + ItemUpdateEvent updateEvent = virtualInventory.createAndCallEvent(index, updateReason, invStack, null); if (!updateEvent.isCancelled()) { int leftOverAmount; diff --git a/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java b/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java index 8f57647..49875c2 100644 --- a/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java +++ b/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventory.java @@ -373,6 +373,53 @@ public class VirtualInventory implements ConfigurationSerializable { return amountLeft; } + /** + * Returns the amount of items that wouldn't fit in the inventory when added. + *
+ * Note: This method does not add any {@link ItemStack}s to the {@link VirtualInventory}. + * + * @param itemStack The {@link ItemStack} to use + * @return How many items wouldn't fit in the inventory when added + */ + public int simulateAdd(ItemStack itemStack) { + int amountLeft = itemStack.getAmount(); + + // find all slots where the item partially fits + for (int partialSlot : findPartialSlots(itemStack)) { + ItemStack partialItem = items[partialSlot]; + amountLeft = Math.max(0, amountLeft - (partialItem.getMaxStackSize() - partialItem.getAmount())); + if (amountLeft == 0) break; + } + + // remaining items would be added to an empty slot + if (amountLeft != 0 && ArrayUtils.findFirstEmptyIndex(items) != -1) amountLeft = 0; + + return amountLeft; + } + + /** + * Simulates adding multiple {@link ItemStack}s to this {@link VirtualInventory} + * and returns the amount of {@link ItemStack}s that did not fit.
+ * This method should only be used for simulating the addition of multiple {@link ItemStack}s. + * For a single {@link ItemStack} use {@link #simulateAdd(ItemStack)}
+ * Note: This method does not add any {@link ItemStack}s to the {@link VirtualInventory}. + * + * @param itemStacks The {@link ItemStack} to be used in the simulation + * @return An array of integers representing the leftover amount for each {@link ItemStack} provided. + * The size of this array is always equal to the amount of {@link ItemStack}s provided as method parameters. + */ + public int[] simulateMultiAdd(List itemStacks) { + if (itemStacks.size() < 2) throw new IllegalArgumentException("Illegal amount of ItemStacks in List"); + + VirtualInventory copiedInv = new VirtualInventory(null, size, getItems()); + int[] result = new int[itemStacks.size()]; + for (int index = 0; index != itemStacks.size(); index++) { + result[index] = copiedInv.addItem(null, itemStacks.get(index)); + } + + return result; + } + public int collectToCursor(@Nullable UpdateReason updateReason, ItemStack itemStack) { int amount = itemStack.getAmount(); int maxStackSize = itemStack.getMaxStackSize(); @@ -482,10 +529,18 @@ public class VirtualInventory implements ConfigurationSerializable { windows.forEach(window -> window.handleVirtualInventoryUpdate(this))); } - private ItemUpdateEvent createAndCallEvent(int index, UpdateReason updateReason, ItemStack previousItemStack, ItemStack newItemStack) { + /** + * Creates an {@link ItemUpdateEvent} and calls the {@link #itemUpdateHandler} to handle it. + * + * @param index The slot index of the affected {@link ItemStack} + * @param updateReason The {@link UpdateReason} + * @param previousItemStack The {@link ItemStack} that was previously on that slot + * @param newItemStack The {@link ItemStack} that will be on that slot + * @return The {@link ItemUpdateEvent} after it has been handled by the {@link #itemUpdateHandler} + */ + public ItemUpdateEvent createAndCallEvent(int index, UpdateReason updateReason, ItemStack previousItemStack, ItemStack newItemStack) { ItemUpdateEvent event = new ItemUpdateEvent(this, index, updateReason, previousItemStack, newItemStack); if (itemUpdateHandler != null) itemUpdateHandler.accept(event); - Bukkit.getPluginManager().callEvent(event); return event; } diff --git a/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventoryManager.java b/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventoryManager.java index 1b6ab27..3ced4b1 100644 --- a/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventoryManager.java +++ b/src/main/java/de/studiocode/invui/virtualinventory/VirtualInventoryManager.java @@ -18,7 +18,7 @@ import java.util.UUID; */ public class VirtualInventoryManager { - private static final File SAVE_DIR = new File("plugins/InvUI/VirtualInventory/"); + private static final File SAVE_DIR = new File("plugins/InvUI/VirtualInventory/" + InvUI.getInstance().getPlugin().getName() + "/"); private static VirtualInventoryManager instance; diff --git a/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java b/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java index 298aad6..2d09dc8 100644 --- a/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java +++ b/src/main/java/de/studiocode/invui/virtualinventory/event/ItemUpdateEvent.java @@ -2,9 +2,6 @@ package de.studiocode.invui.virtualinventory.event; import de.studiocode.invui.virtualinventory.VirtualInventory; import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,9 +9,7 @@ import org.jetbrains.annotations.Nullable; /** * An event that is called whenever a slot inside a {@link VirtualInventory} gets updated. */ -public class ItemUpdateEvent extends Event implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); +public class ItemUpdateEvent { private final VirtualInventory virtualInventory; private final ItemStack previousItemStack; @@ -45,15 +40,6 @@ public class ItemUpdateEvent extends Event implements Cancellable { this.newItemStack = newItemStack; } - /** - * Gets the {@link HandlerList} of this {@link Event} - * - * @return The {@link HandlerList} of this {@link Event} - */ - public static HandlerList getHandlerList() { - return handlers; - } - /** * Gets the {@link VirtualInventory} where this action takes place. * @@ -99,25 +85,22 @@ public class ItemUpdateEvent extends Event implements Cancellable { return slot; } - @Override + /** + * Gets the cancellation state of this event. + * + * @return The cancellation state of this event. + */ public boolean isCancelled() { return cancelled; } - @Override + /** + * Sets the cancellation state of this event. + * + * @param cancel If this event should be cancelled. + */ public void setCancelled(boolean cancel) { this.cancelled = cancel; } - /** - * Gets the {@link HandlerList} of this {@link Event} - * - * @return The {@link HandlerList} of this {@link Event} - */ - @NotNull - @Override - public HandlerList getHandlers() { - return handlers; - } - }