diff --git a/src/main/java/de/studiocode/invgui/gui/SlotElement.java b/src/main/java/de/studiocode/invgui/gui/SlotElement.java index eaed102..4a66e8f 100644 --- a/src/main/java/de/studiocode/invgui/gui/SlotElement.java +++ b/src/main/java/de/studiocode/invgui/gui/SlotElement.java @@ -8,6 +8,8 @@ import java.util.UUID; public interface SlotElement { + ItemStackHolder getItemStackHolder(); + interface ItemStackHolder { ItemStack getItemStack(UUID viewerUUID); @@ -33,6 +35,11 @@ public interface SlotElement { public ItemStack getItemStack(UUID viewerUUID) { return item.getItemBuilder().buildFor(viewerUUID); } + + @Override + public ItemStackHolder getItemStackHolder() { + return this; + } } @@ -65,6 +72,11 @@ public interface SlotElement { public ItemStack getItemStack(UUID viewerUUID) { return getItemStack(); } + + @Override + public ItemStackHolder getItemStackHolder() { + return this; + } } @@ -90,19 +102,15 @@ public interface SlotElement { return slot; } - public SlotElement getBottomSlotElement() { + public ItemStackHolder getItemStackHolder() { LinkedSlotElement element = this; while (true) { SlotElement below = element.getGui().getSlotElement(element.getSlotIndex()); if (below instanceof LinkedSlotElement) element = (LinkedSlotElement) below; - else return below; + else return (ItemStackHolder) below; } } - public ItemStackHolder getItemStackHolder() { - return (ItemStackHolder) getBottomSlotElement(); - } - } } diff --git a/src/main/java/de/studiocode/invgui/gui/impl/IndexedGUI.java b/src/main/java/de/studiocode/invgui/gui/impl/IndexedGUI.java index 2bef502..5806498 100644 --- a/src/main/java/de/studiocode/invgui/gui/impl/IndexedGUI.java +++ b/src/main/java/de/studiocode/invgui/gui/impl/IndexedGUI.java @@ -15,9 +15,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; abstract class IndexedGUI implements GUI { @@ -48,10 +46,13 @@ abstract class IndexedGUI implements GUI { VirtualInventory virtualInventory = element.getVirtualInventory(); int index = element.getIndex(); + Player player = (Player) event.getWhoClicked(); ItemStack cursor = event.getCursor(); ItemStack clicked = event.getCurrentItem(); if (virtualInventory.isSynced(index, clicked)) { + boolean cancelled = false; + switch (event.getAction()) { case CLONE_STACK: @@ -62,28 +63,28 @@ abstract class IndexedGUI implements GUI { case DROP_ONE_SLOT: case PICKUP_ONE: - virtualInventory.removeOne(index); + cancelled = virtualInventory.removeOne(player, index); break; case DROP_ALL_SLOT: case PICKUP_ALL: - virtualInventory.removeItem(index); + cancelled = virtualInventory.removeItem(player, index); break; case PICKUP_HALF: - virtualInventory.removeHalf(index); + cancelled = virtualInventory.removeHalf(player, index); break; case PLACE_ALL: - virtualInventory.place(index, cursor); + cancelled = virtualInventory.place(player, index, cursor); break; case PLACE_ONE: - virtualInventory.placeOne(index, cursor); + cancelled = virtualInventory.placeOne(player, index, cursor); break; case PLACE_SOME: - virtualInventory.setMaxAmount(index); + cancelled = virtualInventory.setToMaxAmount(player, index); break; case MOVE_TO_OTHER_INVENTORY: @@ -93,7 +94,8 @@ abstract class IndexedGUI implements GUI { event.getWhoClicked().getInventory().addItem(virtualInventory.getItemStack(index)); if (!leftover.isEmpty()) leftOverAmount = leftover.get(0).getAmount(); - virtualInventory.setAmount(index, leftOverAmount); + // TODO: find a way to cancel at this point + virtualInventory.setAmount(player, index, leftOverAmount, true); break; default: @@ -101,6 +103,8 @@ abstract class IndexedGUI implements GUI { event.setCancelled(true); break; } + + if (cancelled) event.setCancelled(true); } else event.setCancelled(true); } @@ -108,6 +112,7 @@ abstract class IndexedGUI implements GUI { public void handleItemShift(InventoryClickEvent event) { event.setCancelled(true); + Player player = (Player) event.getWhoClicked(); ItemStack clicked = event.getCurrentItem(); List virtualInventories = getAllVirtualInventories(); @@ -116,7 +121,7 @@ abstract class IndexedGUI implements GUI { for (VirtualInventory virtualInventory : virtualInventories) { ItemStack toAdd = clicked.clone(); toAdd.setAmount(amountLeft); - amountLeft = virtualInventory.addItem(toAdd); + amountLeft = virtualInventory.addItem(player, toAdd); if (amountLeft == 0) break; } @@ -128,10 +133,11 @@ abstract class IndexedGUI implements GUI { private List getAllVirtualInventories() { List virtualInventories = new ArrayList<>(); - ArrayUtils - .findAllOccurrences(slotElements, element -> element instanceof VISlotElement) - .values().stream() - .map(element -> ((VISlotElement) element).getVirtualInventory()) + Arrays.stream(slotElements) + .filter(Objects::nonNull) + .map(SlotElement::getItemStackHolder) + .filter(holder -> holder instanceof VISlotElement) + .map(holder -> ((VISlotElement) holder).getVirtualInventory()) .forEach(vi -> { if (!virtualInventories.contains(vi)) virtualInventories.add(vi); }); @@ -174,12 +180,8 @@ abstract class IndexedGUI implements GUI { SlotElement slotElement = slotElements[index]; if (slotElement != null) { - if (slotElement instanceof ItemSlotElement) { - return ((ItemSlotElement) slotElement).getItem(); - } else if (slotElement instanceof LinkedSlotElement) { - SlotElement bottom = ((LinkedSlotElement) slotElement).getBottomSlotElement(); - if (bottom instanceof ItemSlotElement) return ((ItemSlotElement) bottom).getItem(); - } + ItemStackHolder holder = slotElement.getItemStackHolder(); + if (holder instanceof ItemSlotElement) return ((ItemSlotElement) holder).getItem(); } return null; @@ -188,11 +190,7 @@ abstract class IndexedGUI implements GUI { @Override public ItemStackHolder getItemStackHolder(int index) { SlotElement slotElement = slotElements[index]; - if (slotElement instanceof ItemStackHolder) { - return (ItemStackHolder) slotElement; - } else if (slotElement instanceof LinkedSlotElement) { - return ((LinkedSlotElement) slotElement).getItemStackHolder(); - } else return null; + return slotElement == null ? null : slotElement.getItemStackHolder(); } @Override diff --git a/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java b/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java index cc98301..f8f8fd1 100644 --- a/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java +++ b/src/main/java/de/studiocode/invgui/virtualinventory/VirtualInventory.java @@ -2,9 +2,12 @@ package de.studiocode.invgui.virtualinventory; import de.studiocode.invgui.InvGui; import de.studiocode.invgui.util.ArrayUtils; +import de.studiocode.invgui.util.Pair; +import de.studiocode.invgui.virtualinventory.event.ItemUpdateEvent; import de.studiocode.invgui.window.Window; import org.bukkit.Bukkit; import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,45 +22,318 @@ public class VirtualInventory implements ConfigurationSerializable { private int size; private ItemStack[] items; + /** + * Creates a new {@link VirtualInventory}. + * + * @param uuid The {@link UUID} this {@link VirtualInventory} should have. + * Can be null, only used for serialization. + * @param size The size of the {@link VirtualInventory} ( size > 0 ) + * @param items An array of {@link ItemStack} which reflects the contents of this + * {@link VirtualInventory}, therefore the length of that array has + * to be the same as size. + */ public VirtualInventory(@Nullable UUID uuid, int size, @NotNull ItemStack[] items) { + if (size < 1) throw new IllegalArgumentException("size cannot be smaller than 1"); + if (items.length != size) throw new IllegalArgumentException("items length has to be the same as size"); + this.uuid = uuid; this.size = size; this.items = items; } + /** + * Creates a new {@link VirtualInventory}. + * + * @param uuid The {@link UUID} this {@link VirtualInventory} should have. + * Can be null, only used for serialization. + * @param size The size of the {@link VirtualInventory} + */ public VirtualInventory(@Nullable UUID uuid, int size) { this(uuid, size, new ItemStack[size]); } + /** + * Deserializes to {@link VirtualInventory} + * + * @param args The args which contain the data to deserialize + * @return The deserialized {@link VirtualInventory} + */ public static VirtualInventory deserialize(@NotNull Map args) { //noinspection unchecked return new VirtualInventory(UUID.fromString((String) args.get("uuid")), (int) args.get("size"), ((ArrayList) args.get("items")).toArray(new ItemStack[0])); } + /** + * Gets the size of this {@link VirtualInventory}. + * + * @return The size of this {@link VirtualInventory} + */ public int getSize() { return size; } + /** + * Changes the size of this {@link VirtualInventory}, removing + * existing {@link ItemStack}s reduced. + * + * @param size The new size of this {@link VirtualInventory} + */ public void resize(int size) { this.size = size; this.items = Arrays.copyOf(items, size); } + /** + * Checks if the {@link ItemStack} on that slot index is the same + * as the assumed {@link ItemStack} provided as parameter. + * + * @param index The slot index + * @param assumedStack The assumed {@link ItemStack} + * @return If the {@link ItemStack} on that slot is the same as the assumed {@link ItemStack} + */ public boolean isSynced(int index, ItemStack assumedStack) { ItemStack actualStack = items[index]; return (actualStack == null && assumedStack == null) || (actualStack != null && actualStack.equals(assumedStack)); } - public int addItem(ItemStack itemStack) { + /** + * Sets an {@link ItemStack} on a specific slot. + * + * @param index The slot index + * @param itemStack The {@link ItemStack} that should be put on that slot + */ + public void setItem(int index, ItemStack itemStack) { + items[index] = itemStack.clone(); + notifyWindows(); + } + + /** + * Gets the {@link ItemStack} on a specific slot. + * + * @param index The slot index + * @return The {@link ItemStack} on that slot + */ + public ItemStack getItemStack(int index) { + return items[index]; + } + + /** + * Checks if there is an {@link ItemStack} on a specific slot. + * + * @param index The slot index + * @return If there is an {@link ItemStack} on that slot + */ + public boolean hasItem(int index) { + return items[index] != null; + } + + /** + * Sets an {@link ItemStack} on a specific slot or adds the amount + * if there already is an {@link ItemStack} on that slot. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @param itemStack The {@link ItemStack} to place + * @return If the action has been cancelled + */ + public boolean place(Player player, int index, ItemStack itemStack) { + ItemStack there = items[index]; + int currentAmount = there == null ? 0 : there.getAmount(); + + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, + currentAmount + itemStack.getAmount()); + + if (!event.isCancelled()) { + if (there == null) { + setItem(index, itemStack); + } else { + there.setAmount(currentAmount + itemStack.getAmount()); + notifyWindows(); + } + + return false; + } + + return true; + } + + /** + * Puts on of an {@link ItemStack} on a specific slots or adds one + * if there is already an {@link ItemStack} on that slot. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @param itemStack The {@link ItemStack} to place one of + * @return If the action has been cancelled + */ + public boolean placeOne(Player player, int index, ItemStack itemStack) { + ItemStack there = items[index]; + int currentAmount = there == null ? 0 : there.getAmount(); + + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, + currentAmount, currentAmount + 1); + + if (!event.isCancelled()) { + if (there == null) { + ItemStack single = itemStack.clone(); + single.setAmount(1); + setItem(index, single); + } else { + there.setAmount(currentAmount + 1); + notifyWindows(); + } + + return false; + } + + return true; + } + + /** + * Changes the amount of an {@link ItemStack} on a specific slot. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @param amount The new amount + * @return If the action has been cancelled + */ + public boolean setAmount(Player player, int index, int amount, boolean ignoreCancelled) { + ItemStack itemStack = items[index]; + if (itemStack != null) { + int currentAmount = itemStack.getAmount(); + + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, amount); + + if (!event.isCancelled() || ignoreCancelled) { + if (amount == 0) items[index] = null; + else itemStack.setAmount(amount); + + notifyWindows(); + + return false; + } + } + + return true; + } + + /** + * Changes the amount of an {@link ItemStack} on a specific slot + * to the {@link ItemStack}'s {@link ItemStack#getMaxStackSize()}. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @return If the action has been cancelled + */ + public boolean setToMaxAmount(Player player, int index) { + ItemStack itemStack = items[index]; + if (itemStack != null) { + int currentAmount = itemStack.getAmount(); + int newAmount = itemStack.getMaxStackSize(); + + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, + currentAmount, newAmount); + + if (!event.isCancelled()) { + itemStack.setAmount(newAmount); + notifyWindows(); + } else return true; + } + return false; + } + + /** + * Removes an {@link ItemStack} on a specific slot from + * the {@link VirtualInventory}. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @return If the action has been cancelled + */ + public boolean removeItem(Player player, int index) { + ItemStack itemStack = items[index]; + if (itemStack != null) { + + ItemUpdateEvent event =createAndCallEvent(player, itemStack, index, + itemStack.getAmount(), 0); + + if (!event.isCancelled()) { + items[index] = null; + notifyWindows(); + } else return true; + } + + return false; + } + + /** + * Removes one from an {@link ItemStack} on a specific slot. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @return If the action has been cancelled + */ + public boolean removeOne(Player player, int index) { + ItemStack itemStack = items[index]; + if (itemStack != null) { + int currentAmount = itemStack.getAmount(); + int newAmount = currentAmount - 1; + + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount); + + if (!event.isCancelled()) { + if (newAmount > 0) itemStack.setAmount(newAmount); + else items[index] = null; + + notifyWindows(); + } else return true; + } + + return false; + } + + /** + * Removes half of the {@link ItemStack} on a specific slot. + * + * @param player The player that did this or null if it wasn't a player. + * @param index The slot index + * @return If the action has been cancelled + */ + public boolean removeHalf(Player player, int index) { + ItemStack itemStack = items[index]; + if (itemStack != null) { + int currentAmount = itemStack.getAmount(); + int newAmount = itemStack.getAmount() / 2; + + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount); + + if (!event.isCancelled()) { + if (newAmount > 0) itemStack.setAmount(newAmount); + else items[index] = null; + notifyWindows(); + } else return true; + } + + return false; + } + + /** + * Adds an {@link ItemStack} to the {@link VirtualInventory}. + * + * @param player The player that did this or null if it wasn't a player. + * @param itemStack The {@link ItemStack} to add + * @return The amount of items that couldn't be added + */ + public int addItem(Player player, ItemStack itemStack) { final int originalAmount = itemStack.getAmount(); int amountLeft = originalAmount; // find all slots where the item partially fits and add it there - ItemStack partialStack; - while ((partialStack = findPartialSlot(itemStack)) != null && amountLeft != 0) - amountLeft = addTo(partialStack, amountLeft); + Pair partialSlot; + while ((partialSlot = findPartialSlot(itemStack)) != null && amountLeft != 0) + amountLeft = addTo(player, partialSlot, amountLeft); if (amountLeft != 0) { // there are still items left, put the rest on an empty slot @@ -65,8 +341,8 @@ public class VirtualInventory implements ConfigurationSerializable { if (emptyIndex != -1) { ItemStack leftover = itemStack.clone(); leftover.setAmount(amountLeft); - items[emptyIndex] = leftover; - amountLeft = 0; + if (!place(player, emptyIndex, leftover)) + amountLeft = 0; } } @@ -77,111 +353,49 @@ public class VirtualInventory implements ConfigurationSerializable { return amountLeft; } - private ItemStack findPartialSlot(ItemStack itemStack) { - for (ItemStack currentStack : items) { + private Pair findPartialSlot(ItemStack itemStack) { + for (int i = 0; i < items.length; i++) { + ItemStack currentStack = items[i]; if (currentStack != null && currentStack.getAmount() < currentStack.getMaxStackSize() - && currentStack.isSimilar(itemStack)) return currentStack; + && currentStack.isSimilar(itemStack)) return new Pair<>(i, currentStack); } return null; } - private int addTo(ItemStack itemStack, int amount) { + private int addTo(Player player, Pair partialSlot, int amount) { + int index = partialSlot.getFirst(); + ItemStack itemStack = partialSlot.getSecond(); + int maxAddable = Math.min(itemStack.getMaxStackSize() - itemStack.getAmount(), amount); - itemStack.setAmount(itemStack.getAmount() + maxAddable); - return amount - maxAddable; - } - - public void setItem(int index, ItemStack itemStack) { - items[index] = itemStack.clone(); - notifyWindows(); - } - - public void setAmount(int index, int amount) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - if (amount == 0) items[index] = null; - else itemStack.setAmount(amount); - - notifyWindows(); - } - } - - public void setMaxAmount(int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - itemStack.setAmount(itemStack.getMaxStackSize()); - notifyWindows(); - } - } - - public ItemStack getItemStack(int index) { - return items[index]; - } - - public void removeItem(int index) { - if (items[index] != null) { - items[index] = null; - notifyWindows(); - } - } - - public void removeOne(int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - int amount = itemStack.getAmount() - 1; - if (amount > 0) itemStack.setAmount(amount); - else items[index] = null; - - notifyWindows(); - } - } - - public void removeHalf(int index) { - ItemStack itemStack = items[index]; - if (itemStack != null) { - int amount = itemStack.getAmount() / 2; - if (amount > 0) itemStack.setAmount(amount); - else items[index] = null; - - notifyWindows(); - } - } - - public void place(int index, ItemStack itemStack) { - ItemStack there = items[index]; - int currentAmount = there == null ? 0 : there.getAmount(); - if (there == null) { - setItem(index, itemStack); - } else { - there.setAmount(currentAmount + itemStack.getAmount()); - notifyWindows(); - } - } - - public void placeOne(int index, ItemStack itemStack) { - ItemStack there = items[index]; - int currentAmount = there == null ? 0 : there.getAmount(); + int currentAmount = itemStack.getAmount(); + int newAmount = currentAmount + maxAddable; - if (there == null) { - ItemStack single = itemStack.clone(); - single.setAmount(1); - setItem(index, single); - } else { - there.setAmount(currentAmount + 1); - notifyWindows(); - } - } - - public boolean hasItem(int index) { - return items[index] != null; + ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount); + + if (!event.isCancelled()) { + itemStack.setAmount(itemStack.getAmount() + maxAddable); + return amount - maxAddable; + } else return amount; } + /** + * Adds a {@link Window} to the window set, telling the {@link VirtualInventory} that it is + * currently being displayed in that {@link Window}. + * + * @param window The {@link Window} the {@link VirtualInventory} is currently displayed in. + */ public void addWindow(Window window) { windows.add(window); } + /** + * Removes an {@link Window} from the window set, telling the {@link VirtualInventory} that it + * is no longer being displayed in that {@link Window}. + * + * @param window The {@link Window} the {@link VirtualInventory} is no longer displayed in. + */ public void removeWindow(Window window) { windows.remove(window); } @@ -191,10 +405,27 @@ public class VirtualInventory implements ConfigurationSerializable { windows.forEach(window -> window.handleVirtualInventoryUpdate(this))); } + private ItemUpdateEvent createAndCallEvent(Player player, ItemStack itemStack, int index, int previousAmount, int newAmount) { + ItemUpdateEvent event = new ItemUpdateEvent(this, player, itemStack, index, previousAmount, newAmount); + Bukkit.getPluginManager().callEvent(event); + + return event; + } + + /** + * Gets the {@link UUID} of this {@link VirtualInventory}. + * + * @return The {@link UUID} of this {@link VirtualInventory} + */ public UUID getUuid() { return uuid; } + /** + * Serializes this {@link VirtualInventory} to a {@link Map} + * + * @return A {@link Map} that contains the serialized data of this {@link VirtualInventory} + */ @NotNull @Override public Map serialize() { diff --git a/src/main/java/de/studiocode/invgui/virtualinventory/event/ItemUpdateEvent.java b/src/main/java/de/studiocode/invgui/virtualinventory/event/ItemUpdateEvent.java new file mode 100644 index 0000000..16cd83a --- /dev/null +++ b/src/main/java/de/studiocode/invgui/virtualinventory/event/ItemUpdateEvent.java @@ -0,0 +1,135 @@ +package de.studiocode.invgui.virtualinventory.event; + +import de.studiocode.invgui.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; + +/** + * 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(); + + private final VirtualInventory virtualInventory; + private final ItemStack itemStack; + private final Player player; + private final int slot; + private final int previousAmount; + private final int newAmount; + + private boolean cancelled; + + /** + * Creates a new {@link ItemUpdateEvent}. + * + * @param virtualInventory The {@link VirtualInventory} where this action takes place. + * @param player The {@link Player} who changed the {@link ItemStack} or null + * if it wasn't a {@link Player} + * @param itemStack The {@link ItemStack} that is affected + * @param slot The slot that is affected + * @param previousAmount The previous amount of the {@link ItemStack} + * @param newAmount The amount that the {@link ItemStack} will have if the event is not being cancelled + */ + public ItemUpdateEvent(@NotNull VirtualInventory virtualInventory, @Nullable Player player, @NotNull ItemStack itemStack, int slot, int previousAmount, + int newAmount) { + this.virtualInventory = virtualInventory; + this.player = player; + this.itemStack = itemStack; + this.slot = slot; + this.previousAmount = previousAmount; + this.newAmount = newAmount; + } + + /** + * 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. + * + * @return The {@link VirtualInventory} + */ + public VirtualInventory getVirtualInventory() { + return virtualInventory; + } + + /** + * Gets the {@link Player} who changed the {@link ItemStack} or null + * if it wasn't a {@link Player}. + * + * @return The {@link Player} + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the {@link ItemStack} involved in this action. + * + * @return The {@link ItemStack} + */ + public ItemStack getItemStack() { + return itemStack; + } + + /** + * Gets the slot that is affected. + * + * @return The slot + */ + public int getSlot() { + return slot; + } + + /** + * Gets the previous amount of the {@link ItemStack} + * + * @return The previous amount + */ + public int getPreviousAmount() { + return previousAmount; + } + + /** + * Gets the new amount of the {@link ItemStack} if the event + * isn't being cancelled. + * + * @return The new amount + */ + public int getNewAmount() { + return newAmount; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + 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; + } + +}