ItemUpdateEvent

Created and implemented ItemUpdateEvent
Added javadoc to VirtualInventory
This commit is contained in:
NichtStudioCode 2021-01-25 18:08:49 +01:00
parent a4bdf57360
commit ea35d94dda
4 changed files with 500 additions and 128 deletions

@ -8,6 +8,8 @@ import java.util.UUID;
public interface SlotElement { public interface SlotElement {
ItemStackHolder getItemStackHolder();
interface ItemStackHolder { interface ItemStackHolder {
ItemStack getItemStack(UUID viewerUUID); ItemStack getItemStack(UUID viewerUUID);
@ -33,6 +35,11 @@ public interface SlotElement {
public ItemStack getItemStack(UUID viewerUUID) { public ItemStack getItemStack(UUID viewerUUID) {
return item.getItemBuilder().buildFor(viewerUUID); return item.getItemBuilder().buildFor(viewerUUID);
} }
@Override
public ItemStackHolder getItemStackHolder() {
return this;
}
} }
@ -65,6 +72,11 @@ public interface SlotElement {
public ItemStack getItemStack(UUID viewerUUID) { public ItemStack getItemStack(UUID viewerUUID) {
return getItemStack(); return getItemStack();
} }
@Override
public ItemStackHolder getItemStackHolder() {
return this;
}
} }
@ -90,19 +102,15 @@ public interface SlotElement {
return slot; return slot;
} }
public SlotElement getBottomSlotElement() { public ItemStackHolder getItemStackHolder() {
LinkedSlotElement element = this; LinkedSlotElement element = this;
while (true) { while (true) {
SlotElement below = element.getGui().getSlotElement(element.getSlotIndex()); SlotElement below = element.getGui().getSlotElement(element.getSlotIndex());
if (below instanceof LinkedSlotElement) element = (LinkedSlotElement) below; if (below instanceof LinkedSlotElement) element = (LinkedSlotElement) below;
else return below; else return (ItemStackHolder) below;
} }
} }
public ItemStackHolder getItemStackHolder() {
return (ItemStackHolder) getBottomSlotElement();
}
} }
} }

@ -15,9 +15,7 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
abstract class IndexedGUI implements GUI { abstract class IndexedGUI implements GUI {
@ -48,10 +46,13 @@ abstract class IndexedGUI implements GUI {
VirtualInventory virtualInventory = element.getVirtualInventory(); VirtualInventory virtualInventory = element.getVirtualInventory();
int index = element.getIndex(); int index = element.getIndex();
Player player = (Player) event.getWhoClicked();
ItemStack cursor = event.getCursor(); ItemStack cursor = event.getCursor();
ItemStack clicked = event.getCurrentItem(); ItemStack clicked = event.getCurrentItem();
if (virtualInventory.isSynced(index, clicked)) { if (virtualInventory.isSynced(index, clicked)) {
boolean cancelled = false;
switch (event.getAction()) { switch (event.getAction()) {
case CLONE_STACK: case CLONE_STACK:
@ -62,28 +63,28 @@ abstract class IndexedGUI implements GUI {
case DROP_ONE_SLOT: case DROP_ONE_SLOT:
case PICKUP_ONE: case PICKUP_ONE:
virtualInventory.removeOne(index); cancelled = virtualInventory.removeOne(player, index);
break; break;
case DROP_ALL_SLOT: case DROP_ALL_SLOT:
case PICKUP_ALL: case PICKUP_ALL:
virtualInventory.removeItem(index); cancelled = virtualInventory.removeItem(player, index);
break; break;
case PICKUP_HALF: case PICKUP_HALF:
virtualInventory.removeHalf(index); cancelled = virtualInventory.removeHalf(player, index);
break; break;
case PLACE_ALL: case PLACE_ALL:
virtualInventory.place(index, cursor); cancelled = virtualInventory.place(player, index, cursor);
break; break;
case PLACE_ONE: case PLACE_ONE:
virtualInventory.placeOne(index, cursor); cancelled = virtualInventory.placeOne(player, index, cursor);
break; break;
case PLACE_SOME: case PLACE_SOME:
virtualInventory.setMaxAmount(index); cancelled = virtualInventory.setToMaxAmount(player, index);
break; break;
case MOVE_TO_OTHER_INVENTORY: case MOVE_TO_OTHER_INVENTORY:
@ -93,7 +94,8 @@ abstract class IndexedGUI implements GUI {
event.getWhoClicked().getInventory().addItem(virtualInventory.getItemStack(index)); event.getWhoClicked().getInventory().addItem(virtualInventory.getItemStack(index));
if (!leftover.isEmpty()) leftOverAmount = leftover.get(0).getAmount(); 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; break;
default: default:
@ -101,6 +103,8 @@ abstract class IndexedGUI implements GUI {
event.setCancelled(true); event.setCancelled(true);
break; break;
} }
if (cancelled) event.setCancelled(true);
} else event.setCancelled(true); } else event.setCancelled(true);
} }
@ -108,6 +112,7 @@ abstract class IndexedGUI implements GUI {
public void handleItemShift(InventoryClickEvent event) { public void handleItemShift(InventoryClickEvent event) {
event.setCancelled(true); event.setCancelled(true);
Player player = (Player) event.getWhoClicked();
ItemStack clicked = event.getCurrentItem(); ItemStack clicked = event.getCurrentItem();
List<VirtualInventory> virtualInventories = getAllVirtualInventories(); List<VirtualInventory> virtualInventories = getAllVirtualInventories();
@ -116,7 +121,7 @@ abstract class IndexedGUI implements GUI {
for (VirtualInventory virtualInventory : virtualInventories) { for (VirtualInventory virtualInventory : virtualInventories) {
ItemStack toAdd = clicked.clone(); ItemStack toAdd = clicked.clone();
toAdd.setAmount(amountLeft); toAdd.setAmount(amountLeft);
amountLeft = virtualInventory.addItem(toAdd); amountLeft = virtualInventory.addItem(player, toAdd);
if (amountLeft == 0) break; if (amountLeft == 0) break;
} }
@ -128,10 +133,11 @@ abstract class IndexedGUI implements GUI {
private List<VirtualInventory> getAllVirtualInventories() { private List<VirtualInventory> getAllVirtualInventories() {
List<VirtualInventory> virtualInventories = new ArrayList<>(); List<VirtualInventory> virtualInventories = new ArrayList<>();
ArrayUtils Arrays.stream(slotElements)
.findAllOccurrences(slotElements, element -> element instanceof VISlotElement) .filter(Objects::nonNull)
.values().stream() .map(SlotElement::getItemStackHolder)
.map(element -> ((VISlotElement) element).getVirtualInventory()) .filter(holder -> holder instanceof VISlotElement)
.map(holder -> ((VISlotElement) holder).getVirtualInventory())
.forEach(vi -> { .forEach(vi -> {
if (!virtualInventories.contains(vi)) virtualInventories.add(vi); if (!virtualInventories.contains(vi)) virtualInventories.add(vi);
}); });
@ -174,12 +180,8 @@ abstract class IndexedGUI implements GUI {
SlotElement slotElement = slotElements[index]; SlotElement slotElement = slotElements[index];
if (slotElement != null) { if (slotElement != null) {
if (slotElement instanceof ItemSlotElement) { ItemStackHolder holder = slotElement.getItemStackHolder();
return ((ItemSlotElement) slotElement).getItem(); if (holder instanceof ItemSlotElement) return ((ItemSlotElement) holder).getItem();
} else if (slotElement instanceof LinkedSlotElement) {
SlotElement bottom = ((LinkedSlotElement) slotElement).getBottomSlotElement();
if (bottom instanceof ItemSlotElement) return ((ItemSlotElement) bottom).getItem();
}
} }
return null; return null;
@ -188,11 +190,7 @@ abstract class IndexedGUI implements GUI {
@Override @Override
public ItemStackHolder getItemStackHolder(int index) { public ItemStackHolder getItemStackHolder(int index) {
SlotElement slotElement = slotElements[index]; SlotElement slotElement = slotElements[index];
if (slotElement instanceof ItemStackHolder) { return slotElement == null ? null : slotElement.getItemStackHolder();
return (ItemStackHolder) slotElement;
} else if (slotElement instanceof LinkedSlotElement) {
return ((LinkedSlotElement) slotElement).getItemStackHolder();
} else return null;
} }
@Override @Override

@ -2,9 +2,12 @@ package de.studiocode.invgui.virtualinventory;
import de.studiocode.invgui.InvGui; import de.studiocode.invgui.InvGui;
import de.studiocode.invgui.util.ArrayUtils; 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 de.studiocode.invgui.window.Window;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -19,45 +22,318 @@ public class VirtualInventory implements ConfigurationSerializable {
private int size; private int size;
private ItemStack[] items; 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 <code>size</code>.
*/
public VirtualInventory(@Nullable UUID uuid, int size, @NotNull ItemStack[] items) { 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.uuid = uuid;
this.size = size; this.size = size;
this.items = items; 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) { public VirtualInventory(@Nullable UUID uuid, int size) {
this(uuid, size, new ItemStack[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<String, Object> args) { public static VirtualInventory deserialize(@NotNull Map<String, Object> args) {
//noinspection unchecked //noinspection unchecked
return new VirtualInventory(UUID.fromString((String) args.get("uuid")), return new VirtualInventory(UUID.fromString((String) args.get("uuid")),
(int) args.get("size"), ((ArrayList<ItemStack>) args.get("items")).toArray(new ItemStack[0])); (int) args.get("size"), ((ArrayList<ItemStack>) args.get("items")).toArray(new ItemStack[0]));
} }
/**
* Gets the size of this {@link VirtualInventory}.
*
* @return The size of this {@link VirtualInventory}
*/
public int getSize() { public int getSize() {
return size; 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) { public void resize(int size) {
this.size = size; this.size = size;
this.items = Arrays.copyOf(items, 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) { public boolean isSynced(int index, ItemStack assumedStack) {
ItemStack actualStack = items[index]; ItemStack actualStack = items[index];
return (actualStack == null && assumedStack == null) return (actualStack == null && assumedStack == null)
|| (actualStack != null && actualStack.equals(assumedStack)); || (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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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(); final int originalAmount = itemStack.getAmount();
int amountLeft = originalAmount; int amountLeft = originalAmount;
// find all slots where the item partially fits and add it there // find all slots where the item partially fits and add it there
ItemStack partialStack; Pair<Integer, ItemStack> partialSlot;
while ((partialStack = findPartialSlot(itemStack)) != null && amountLeft != 0) while ((partialSlot = findPartialSlot(itemStack)) != null && amountLeft != 0)
amountLeft = addTo(partialStack, amountLeft); amountLeft = addTo(player, partialSlot, amountLeft);
if (amountLeft != 0) { if (amountLeft != 0) {
// there are still items left, put the rest on an empty slot // there are still items left, put the rest on an empty slot
@ -65,8 +341,8 @@ public class VirtualInventory implements ConfigurationSerializable {
if (emptyIndex != -1) { if (emptyIndex != -1) {
ItemStack leftover = itemStack.clone(); ItemStack leftover = itemStack.clone();
leftover.setAmount(amountLeft); leftover.setAmount(amountLeft);
items[emptyIndex] = leftover; if (!place(player, emptyIndex, leftover))
amountLeft = 0; amountLeft = 0;
} }
} }
@ -77,111 +353,49 @@ public class VirtualInventory implements ConfigurationSerializable {
return amountLeft; return amountLeft;
} }
private ItemStack findPartialSlot(ItemStack itemStack) { private Pair<Integer, ItemStack> findPartialSlot(ItemStack itemStack) {
for (ItemStack currentStack : items) { for (int i = 0; i < items.length; i++) {
ItemStack currentStack = items[i];
if (currentStack != null && currentStack.getAmount() < currentStack.getMaxStackSize() if (currentStack != null && currentStack.getAmount() < currentStack.getMaxStackSize()
&& currentStack.isSimilar(itemStack)) return currentStack; && currentStack.isSimilar(itemStack)) return new Pair<>(i, currentStack);
} }
return null; return null;
} }
private int addTo(ItemStack itemStack, int amount) { private int addTo(Player player, Pair<Integer, ItemStack> partialSlot, int amount) {
int index = partialSlot.getFirst();
ItemStack itemStack = partialSlot.getSecond();
int maxAddable = Math.min(itemStack.getMaxStackSize() - itemStack.getAmount(), amount); 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) { int currentAmount = itemStack.getAmount();
setItem(index, itemStack); int newAmount = currentAmount + maxAddable;
} 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();
if (there == null) { ItemUpdateEvent event = createAndCallEvent(player, itemStack, index, currentAmount, newAmount);
ItemStack single = itemStack.clone();
single.setAmount(1); if (!event.isCancelled()) {
setItem(index, single); itemStack.setAmount(itemStack.getAmount() + maxAddable);
} else { return amount - maxAddable;
there.setAmount(currentAmount + 1); } else return amount;
notifyWindows();
}
}
public boolean hasItem(int index) {
return items[index] != null;
} }
/**
* 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) { public void addWindow(Window window) {
windows.add(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) { public void removeWindow(Window window) {
windows.remove(window); windows.remove(window);
} }
@ -191,10 +405,27 @@ public class VirtualInventory implements ConfigurationSerializable {
windows.forEach(window -> window.handleVirtualInventoryUpdate(this))); 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() { public UUID getUuid() {
return uuid; return uuid;
} }
/**
* Serializes this {@link VirtualInventory} to a {@link Map}
*
* @return A {@link Map} that contains the serialized data of this {@link VirtualInventory}
*/
@NotNull @NotNull
@Override @Override
public Map<String, Object> serialize() { public Map<String, Object> serialize() {

@ -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 <code>null</code>
* 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 <code>null</code>
* 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;
}
}