ItemUpdateEvent UpdateReason

This commit is contained in:
NichtStudioCode 2021-04-21 20:55:18 +02:00
parent ff56f8e017
commit edde43b1ae
7 changed files with 120 additions and 80 deletions

@ -7,6 +7,7 @@ import de.studiocode.invui.gui.structure.Structure;
import de.studiocode.invui.item.Item;
import de.studiocode.invui.item.ItemBuilder;
import de.studiocode.invui.virtualinventory.VirtualInventory;
import de.studiocode.invui.virtualinventory.event.UpdateReason;
import de.studiocode.invui.window.Window;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@ -167,6 +168,7 @@ public interface GUI extends GUIParent {
/**
* Sets the {@link ItemBuilder} that will be used if nothing else
* is placed on a slot.
*
* @param itemBuilder The {@link ItemBuilder}
*/
void setBackground(@Nullable ItemBuilder itemBuilder);
@ -174,7 +176,7 @@ public interface GUI extends GUIParent {
/**
* Gets the {@link ItemBuilder} that will used if nothing else
* is placed on a slot.
*
*
* @return The {@link ItemBuilder}
*/
ItemBuilder getBackground();
@ -222,13 +224,13 @@ public interface GUI extends GUIParent {
/**
* A method called when an {@link ItemStack} has been dragged over the {@link GUI}.
*
* @param player The player that is responsible for this action
* @param slot The slot index
* @param oldStack The {@link ItemStack} that was previously on that slot
* @param newStack The new {@link ItemStack} that would be there if the action isn't cancelled
* @param updateReason The reason for this item update.
* @param slot The slot index
* @param oldStack The {@link ItemStack} that was previously on that slot
* @param newStack The new {@link ItemStack} that would be there if the action isn't cancelled
* @return If the action has been cancelled
*/
boolean handleItemDrag(Player player, int slot, ItemStack oldStack, ItemStack newStack);
boolean handleItemDrag(UpdateReason updateReason, int slot, ItemStack oldStack, ItemStack newStack);
/**
* Adds a {@link GUIParent} to the set of {@link GUIParent}s.

@ -13,6 +13,8 @@ import de.studiocode.invui.item.ItemBuilder;
import de.studiocode.invui.util.ArrayUtils;
import de.studiocode.invui.virtualinventory.VirtualInventory;
import de.studiocode.invui.virtualinventory.event.ItemUpdateEvent;
import de.studiocode.invui.virtualinventory.event.PlayerUpdateReason;
import de.studiocode.invui.virtualinventory.event.UpdateReason;
import de.studiocode.invui.window.Window;
import de.studiocode.invui.window.WindowManager;
import de.studiocode.invui.window.impl.merged.MergedWindow;
@ -73,6 +75,8 @@ abstract class IndexedGUI implements GUI {
Player player = (Player) event.getWhoClicked();
ItemStack cursor = event.getCursor();
ItemStack clicked = event.getCurrentItem();
UpdateReason updateReason = new PlayerUpdateReason(player, event);
if (virtualInventory.isSynced(index, clicked)) {
boolean cancelled = false;
@ -87,38 +91,38 @@ abstract class IndexedGUI implements GUI {
case DROP_ONE_SLOT:
case PICKUP_ONE:
cancelled = virtualInventory.removeOne(player, index);
cancelled = virtualInventory.removeOne(updateReason, index);
break;
case DROP_ALL_SLOT:
case PICKUP_ALL:
cancelled = virtualInventory.removeItem(player, index);
cancelled = virtualInventory.removeItem(updateReason, index);
break;
case PICKUP_HALF:
cancelled = virtualInventory.removeHalf(player, index);
cancelled = virtualInventory.removeHalf(updateReason, index);
break;
case PLACE_ALL:
cancelled = virtualInventory.place(player, index, cursor);
cancelled = virtualInventory.place(updateReason, index, cursor);
break;
case PLACE_ONE:
cancelled = virtualInventory.placeOne(player, index, cursor);
cancelled = virtualInventory.placeOne(updateReason, index, cursor);
break;
case PLACE_SOME:
cancelled = virtualInventory.setToMaxAmount(player, index);
cancelled = virtualInventory.setToMaxAmount(updateReason, index);
break;
case SWAP_WITH_CURSOR:
cancelled = virtualInventory.setItemStack(player, index, event.getCursor());
cancelled = virtualInventory.setItemStack(updateReason, index, event.getCursor());
break;
case COLLECT_TO_CURSOR:
cancelled = true;
ItemStack newCursor = cursor.clone();
newCursor.setAmount(virtualInventory.collectToCursor(player, newCursor));
newCursor.setAmount(virtualInventory.collectToCursor(updateReason, newCursor));
player.setItemOnCursor(newCursor);
break;
@ -127,7 +131,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, player, invStack, null);
ItemUpdateEvent updateEvent = new ItemUpdateEvent(virtualInventory, index, updateReason, invStack, null);
Bukkit.getPluginManager().callEvent(updateEvent);
if (!updateEvent.isCancelled()) {
@ -142,7 +146,7 @@ abstract class IndexedGUI implements GUI {
otherGui = this;
}
leftOverAmount = ((IndexedGUI) otherGui).putIntoVirtualInventories(player, invStack, virtualInventory);
leftOverAmount = ((IndexedGUI) otherGui).putIntoVirtualInventories(updateReason, invStack, virtualInventory);
} else {
leftOverAmount = 0;
HashMap<Integer, ItemStack> leftover = event.getWhoClicked().getInventory().addItem(virtualInventory.getItemStack(index));
@ -165,7 +169,7 @@ abstract class IndexedGUI implements GUI {
}
@Override
public boolean handleItemDrag(Player player, int slot, ItemStack oldStack, ItemStack newStack) {
public boolean handleItemDrag(UpdateReason updateReason, int slot, ItemStack oldStack, ItemStack newStack) {
SlotElement element = getSlotElement(slot);
if (element != null) element = element.getHoldingElement();
if (element instanceof VISlotElement) {
@ -173,7 +177,7 @@ abstract class IndexedGUI implements GUI {
VirtualInventory virtualInventory = viSlotElement.getVirtualInventory();
int viIndex = viSlotElement.getIndex();
if (virtualInventory.isSynced(viIndex, oldStack)) {
return virtualInventory.setItemStack(player, viIndex, newStack);
return virtualInventory.setItemStack(updateReason, viIndex, newStack);
}
}
@ -189,14 +193,16 @@ abstract class IndexedGUI implements GUI {
Player player = (Player) event.getWhoClicked();
ItemStack clicked = event.getCurrentItem();
int amountLeft = putIntoVirtualInventories(player, clicked);
UpdateReason updateReason = new PlayerUpdateReason(player, event);
int amountLeft = putIntoVirtualInventories(updateReason, clicked);
if (amountLeft != clicked.getAmount()) {
if (amountLeft != 0) event.getCurrentItem().setAmount(amountLeft);
else event.getClickedInventory().setItem(event.getSlot(), null);
}
}
private int putIntoVirtualInventories(Player player, ItemStack itemStack, VirtualInventory... ignored) {
private int putIntoVirtualInventories(UpdateReason updateReason, ItemStack itemStack, VirtualInventory... ignored) {
if (itemStack.getAmount() <= 0) throw new IllegalArgumentException("Illegal ItemStack amount");
List<VirtualInventory> virtualInventories = getAllVirtualInventories(ignored);
@ -205,7 +211,7 @@ abstract class IndexedGUI implements GUI {
for (VirtualInventory virtualInventory : virtualInventories) {
ItemStack toAdd = itemStack.clone();
toAdd.setAmount(amountLeft);
amountLeft = virtualInventory.addItem(player, toAdd);
amountLeft = virtualInventory.addItem(updateReason, toAdd);
if (amountLeft == 0) break;
}

@ -3,10 +3,10 @@ package de.studiocode.invui.virtualinventory;
import de.studiocode.invui.InvUI;
import de.studiocode.invui.util.ArrayUtils;
import de.studiocode.invui.virtualinventory.event.ItemUpdateEvent;
import de.studiocode.invui.virtualinventory.event.UpdateReason;
import de.studiocode.invui.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;
@ -76,7 +76,7 @@ public class VirtualInventory implements ConfigurationSerializable {
/**
* Gets a deep copy of the {@link ItemStack}s in this {@link VirtualInventory}
*
*
* @return A copy of the {@link ItemStack}s in this {@link VirtualInventory}
*/
public ItemStack[] getItems() {
@ -111,14 +111,14 @@ public class VirtualInventory implements ConfigurationSerializable {
/**
* Sets 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 itemStack The {@link ItemStack} that should be put on that slot
* @param updateReason The reason for item update, can be null.
* @param index The slot index
* @param itemStack The {@link ItemStack} that should be put on that slot
* @return If the action has been cancelled
*/
public boolean setItemStack(Player player, int index, ItemStack itemStack) {
public boolean setItemStack(@Nullable UpdateReason updateReason, int index, ItemStack itemStack) {
ItemStack newStack = itemStack.clone();
ItemUpdateEvent event = createAndCallEvent(index, player, items[index], newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, items[index], newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -153,12 +153,12 @@ public class VirtualInventory implements ConfigurationSerializable {
* 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
* @param updateReason The reason for item update, can be null.
* @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) {
public boolean place(@Nullable UpdateReason updateReason, int index, ItemStack itemStack) {
ItemStack currentStack = items[index];
ItemStack newStack;
@ -169,7 +169,7 @@ public class VirtualInventory implements ConfigurationSerializable {
newStack.setAmount(newStack.getAmount() + itemStack.getAmount());
}
ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, currentStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -184,12 +184,12 @@ public class VirtualInventory implements ConfigurationSerializable {
* 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
* @param updateReason The reason for item update, can be null.
* @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) {
public boolean placeOne(@Nullable UpdateReason updateReason, int index, ItemStack itemStack) {
ItemStack currentStack = items[index];
ItemStack newStack;
@ -201,7 +201,7 @@ public class VirtualInventory implements ConfigurationSerializable {
newStack.setAmount(newStack.getAmount() + 1);
}
ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, currentStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -231,17 +231,17 @@ public class VirtualInventory implements ConfigurationSerializable {
* 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
* @param updateReason The reason for item update, can be null.
* @param index The slot index
* @return If the action has been cancelled
*/
public boolean setToMaxAmount(Player player, int index) {
public boolean setToMaxAmount(@Nullable UpdateReason updateReason, int index) {
ItemStack currentStack = items[index];
if (currentStack != null) {
ItemStack newStack = currentStack.clone();
newStack.setAmount(newStack.getMaxStackSize());
ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, currentStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -257,15 +257,15 @@ public class VirtualInventory implements ConfigurationSerializable {
* 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
* @param updateReason The reason for item update, can be null.
* @param index The slot index
* @return If the action has been cancelled
*/
public boolean removeItem(Player player, int index) {
public boolean removeItem(@Nullable UpdateReason updateReason, int index) {
ItemStack currentStack = items[index];
if (currentStack != null) {
ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, null);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, currentStack, null);
if (!event.isCancelled()) {
items[index] = null;
notifyWindows();
@ -280,11 +280,11 @@ public class VirtualInventory implements ConfigurationSerializable {
/**
* 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
* @param updateReason The reason for item update, can be null.
* @param index The slot index
* @return If the action has been cancelled
*/
public boolean removeOne(Player player, int index) {
public boolean removeOne(@Nullable UpdateReason updateReason, int index) {
ItemStack currentStack = items[index];
if (currentStack != null) {
int newAmount = currentStack.getAmount() - 1;
@ -293,14 +293,14 @@ public class VirtualInventory implements ConfigurationSerializable {
ItemStack newStack = currentStack.clone();
newStack.setAmount(newAmount);
ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, currentStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
return false;
}
} else return removeItem(player, index);
} else return removeItem(updateReason, index);
}
return true;
@ -309,11 +309,11 @@ public class VirtualInventory implements ConfigurationSerializable {
/**
* 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
* @param updateReason The reason for item update, can be null.
* @param index The slot index
* @return If the action has been cancelled
*/
public boolean removeHalf(Player player, int index) {
public boolean removeHalf(@Nullable UpdateReason updateReason, int index) {
ItemStack currentStack = items[index];
if (currentStack != null) {
int newAmount = currentStack.getAmount() / 2;
@ -322,7 +322,7 @@ public class VirtualInventory implements ConfigurationSerializable {
ItemStack newStack = currentStack.clone();
newStack.setAmount(newAmount);
ItemUpdateEvent event = createAndCallEvent(index, player, currentStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, currentStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -330,7 +330,7 @@ public class VirtualInventory implements ConfigurationSerializable {
return false;
}
} else return removeItem(player, index);
} else return removeItem(updateReason, index);
}
return true;
@ -339,17 +339,17 @@ public class VirtualInventory implements ConfigurationSerializable {
/**
* 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
* @param updateReason The reason for item update, can be null.
* @param itemStack The {@link ItemStack} to add
* @return The amount of items that couldn't be added
*/
public int addItem(Player player, ItemStack itemStack) {
public int addItem(@Nullable UpdateReason updateReason, ItemStack itemStack) {
final int originalAmount = itemStack.getAmount();
int amountLeft = originalAmount;
// find all slots where the item partially fits and add it there
for (int partialSlot : findPartialSlots(itemStack)) {
amountLeft = addTo(player, partialSlot, amountLeft);
amountLeft = addTo(updateReason, partialSlot, amountLeft);
if (amountLeft == 0) break;
}
@ -359,7 +359,7 @@ public class VirtualInventory implements ConfigurationSerializable {
if (emptyIndex != -1) {
ItemStack leftover = itemStack.clone();
leftover.setAmount(amountLeft);
if (!place(player, emptyIndex, leftover))
if (!place(updateReason, emptyIndex, leftover))
amountLeft = 0;
}
}
@ -371,13 +371,13 @@ public class VirtualInventory implements ConfigurationSerializable {
return amountLeft;
}
public int collectToCursor(Player player, ItemStack itemStack) {
public int collectToCursor(@Nullable UpdateReason updateReason, ItemStack itemStack) {
int amount = itemStack.getAmount();
int maxStackSize = itemStack.getMaxStackSize();
if (amount < itemStack.getMaxStackSize()) {
// find partial slots and take items from there
for (int partialSlot : findPartialSlots(itemStack)) {
amount += takeFrom(player, partialSlot, maxStackSize - amount);
amount += takeFrom(updateReason, partialSlot, maxStackSize - amount);
if (amount == maxStackSize) break;
}
@ -385,7 +385,7 @@ public class VirtualInventory implements ConfigurationSerializable {
if (amount < itemStack.getMaxStackSize()) {
int fullSlot = findFullSlot(itemStack);
if (fullSlot != -1) {
amount += takeFrom(player, fullSlot, maxStackSize - amount);
amount += takeFrom(updateReason, fullSlot, maxStackSize - amount);
}
}
}
@ -415,7 +415,7 @@ public class VirtualInventory implements ConfigurationSerializable {
return -1;
}
private int addTo(Player player, int index, int amount) {
private int addTo(@Nullable UpdateReason updateReason, int index, int amount) {
ItemStack itemStack = items[index];
int maxAddable = Math.min(itemStack.getMaxStackSize() - itemStack.getAmount(), amount);
@ -426,7 +426,7 @@ public class VirtualInventory implements ConfigurationSerializable {
ItemStack newStack = itemStack.clone();
newStack.setAmount(newAmount);
ItemUpdateEvent event = createAndCallEvent(index, player, itemStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, itemStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -434,7 +434,7 @@ public class VirtualInventory implements ConfigurationSerializable {
} else return amount;
}
private int takeFrom(Player player, int index, int maxTake) {
private int takeFrom(@Nullable UpdateReason updateReason, int index, int maxTake) {
ItemStack itemStack = items[index];
int amount = itemStack.getAmount();
int take = Math.min(amount, maxTake);
@ -445,7 +445,7 @@ public class VirtualInventory implements ConfigurationSerializable {
newStack.setAmount(amount - take);
} else newStack = null;
ItemUpdateEvent event = createAndCallEvent(index, player, itemStack, newStack);
ItemUpdateEvent event = createAndCallEvent(index, updateReason, itemStack, newStack);
if (!event.isCancelled()) {
items[index] = newStack;
notifyWindows();
@ -480,8 +480,8 @@ public class VirtualInventory implements ConfigurationSerializable {
windows.forEach(window -> window.handleVirtualInventoryUpdate(this)));
}
private ItemUpdateEvent createAndCallEvent(int index, Player player, ItemStack previousItemStack, ItemStack newItemStack) {
ItemUpdateEvent event = new ItemUpdateEvent(this, index, player, previousItemStack, newItemStack);
private 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;

@ -19,7 +19,7 @@ public class ItemUpdateEvent extends Event implements Cancellable {
private final VirtualInventory virtualInventory;
private final ItemStack previousItemStack;
private final ItemStack newItemStack;
private final Player player;
private final UpdateReason updateReason;
private final int slot;
private boolean cancelled;
@ -28,17 +28,19 @@ public class ItemUpdateEvent extends Event implements Cancellable {
* 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>
* @param updateReason The {@link UpdateReason} for the calling of this event.
* This will probably be a {@link PlayerUpdateReason} in most cases but can be a custom one
* if you called the methods in the {@link VirtualInventory} yourself.
* if it wasn't a {@link Player}
* @param slot The slot that is affected
* @param previousItemStack The {@link ItemStack} that was there previously
* @param newItemStack The {@link ItemStack} that will be there if the event isn't cancelled
*/
public ItemUpdateEvent(@NotNull VirtualInventory virtualInventory, int slot, @Nullable Player player,
public ItemUpdateEvent(@NotNull VirtualInventory virtualInventory, int slot, @Nullable UpdateReason updateReason,
@Nullable ItemStack previousItemStack, @Nullable ItemStack newItemStack) {
this.virtualInventory = virtualInventory;
this.slot = slot;
this.player = player;
this.updateReason = updateReason;
this.previousItemStack = previousItemStack;
this.newItemStack = newItemStack;
}
@ -62,13 +64,12 @@ public class ItemUpdateEvent extends Event implements Cancellable {
}
/**
* Gets the {@link Player} who changed the {@link ItemStack} or <code>null</code>
* if it wasn't a {@link Player}.
* Gets the {@link UpdateReason} for the calling of this event.
*
* @return The {@link Player}
* @return The reason why this event was called. Probably a {@link PlayerUpdateReason} in most cases.
*/
public Player getPlayer() {
return player;
public UpdateReason getUpdateReason() {
return updateReason;
}
/**

@ -0,0 +1,24 @@
package de.studiocode.invui.virtualinventory.event;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryEvent;
public class PlayerUpdateReason implements UpdateReason {
private final Player player;
private final InventoryEvent event;
public PlayerUpdateReason(Player player, InventoryEvent event) {
this.player = player;
this.event = event;
}
public Player getPlayer() {
return player;
}
public InventoryEvent getEvent() {
return event;
}
}

@ -0,0 +1,4 @@
package de.studiocode.invui.virtualinventory.event;
public interface UpdateReason {
}

@ -11,6 +11,8 @@ import de.studiocode.invui.item.ItemBuilder;
import de.studiocode.invui.util.ArrayUtils;
import de.studiocode.invui.util.Pair;
import de.studiocode.invui.virtualinventory.VirtualInventory;
import de.studiocode.invui.virtualinventory.event.PlayerUpdateReason;
import de.studiocode.invui.virtualinventory.event.UpdateReason;
import de.studiocode.invui.window.Window;
import de.studiocode.invui.window.WindowManager;
import org.bukkit.Bukkit;
@ -89,6 +91,7 @@ public abstract class BaseWindow implements Window {
@Override
public void handleDrag(InventoryDragEvent event) {
Player player = ((Player) event.getWhoClicked()).getPlayer();
UpdateReason updateReason = new PlayerUpdateReason(player, event);
Map<Integer, ItemStack> newItems = event.getNewItems();
int itemsLeft = event.getCursor() == null ? 0 : event.getCursor().getAmount();
@ -98,7 +101,7 @@ public abstract class BaseWindow implements Window {
// get the GUI at that index and ask for permission to drag an Item there
Pair<GUI, Integer> pair = getGuiAt(rawSlot);
if (pair != null && pair.getFirst().handleItemDrag(player, pair.getSecond(), currentStack, newItems.get(rawSlot))) {
if (pair != null && pair.getFirst().handleItemDrag(updateReason, pair.getSecond(), currentStack, newItems.get(rawSlot))) {
// the drag was cancelled
int currentAmount = currentStack == null ? 0 : currentStack.getAmount();
int newAmount = newItems.get(rawSlot).getAmount();