diff --git a/src/main/java/net/minestom/server/inventory/click/ClickType.java b/src/main/java/net/minestom/server/inventory/click/ClickType.java index 2eb9b91d8..c6fe8eda8 100644 --- a/src/main/java/net/minestom/server/inventory/click/ClickType.java +++ b/src/main/java/net/minestom/server/inventory/click/ClickType.java @@ -9,8 +9,14 @@ public enum ClickType { START_SHIFT_CLICK, SHIFT_CLICK, - START_DRAGGING, - DRAGGING, + START_LEFT_DRAGGING, + START_RIGHT_DRAGGING, + + LEFT_DRAGGING, + RIGHT_DRAGGING, + + END_LEFT_DRAGGING, + END_RIGHT_DRAGGING, START_DOUBLE_CLICK, DOUBLE_CLICK, diff --git a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java index df23a86bf..6f2a834f8 100644 --- a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java +++ b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java @@ -232,7 +232,7 @@ public class InventoryClickProcessor { @NotNull ItemStack clicked, @NotNull ItemStack cursor, @NotNull Int2ObjectFunction itemGetter, @NotNull BiConsumer itemSetter) { - InventoryClickResult clickResult = startCondition(inventory, player, slot, ClickType.START_DRAGGING, clicked, cursor); + InventoryClickResult clickResult = null; final StackingRule stackingRule = cursor.getStackingRule(); @@ -240,10 +240,16 @@ public class InventoryClickProcessor { // Start or end left/right drag if (button == 0) { // Start left - this.leftDraggingMap.put(player, new IntOpenHashSet()); + clickResult = startCondition(inventory, player, slot, ClickType.START_LEFT_DRAGGING, clicked, cursor); + + if (!clickResult.isCancel()) + this.leftDraggingMap.put(player, new IntOpenHashSet()); } else if (button == 4) { // Start right - this.rightDraggingMap.put(player, new IntOpenHashSet()); + clickResult = startCondition(inventory, player, slot, ClickType.START_RIGHT_DRAGGING, clicked, cursor); + + if (!clickResult.isCancel()) + this.rightDraggingMap.put(player, new IntOpenHashSet()); } else if (button == 2) { // End left if (!leftDraggingMap.containsKey(player)) @@ -253,39 +259,58 @@ public class InventoryClickProcessor { final int cursorAmount = stackingRule.getAmount(cursor); if (slotCount > cursorAmount) return null; - // Should be size of each defined slot (if not full) - final int slotSize = (int) ((float) cursorAmount / (float) slotCount); - int finalCursorAmount = cursorAmount; + + boolean cancel = false; for (int s : slots) { ItemStack slotItem = itemGetter.apply(s); - clickResult = startCondition(inventory, player, s, ClickType.DRAGGING, slotItem, cursor); - if (clickResult.isCancel()) + clickResult = startCondition(inventory, player, s, ClickType.LEFT_DRAGGING, slotItem, cursor); + + if (clickResult.isCancel()) { + cancel = true; + break; - StackingRule slotItemRule = slotItem.getStackingRule(); - - final int maxSize = stackingRule.getMaxSize(cursor); - if (stackingRule.canBeStacked(cursor, slotItem)) { - final int amount = slotItemRule.getAmount(slotItem); - if (stackingRule.canApply(slotItem, amount + slotSize)) { - slotItem = stackingRule.apply(slotItem, a -> a + slotSize); - finalCursorAmount -= slotSize; - } else { - final int removedAmount = maxSize - amount; - slotItem = stackingRule.apply(slotItem, maxSize); - finalCursorAmount -= removedAmount; - } - } else if (slotItem.isAir()) { - slotItem = stackingRule.apply(cursor, slotSize); - finalCursorAmount -= slotSize; } - itemSetter.accept(s, slotItem); - - callClickEvent(player, inventory, s, ClickType.DRAGGING, slotItem, cursor); } - cursor = stackingRule.apply(cursor, finalCursorAmount); - clickResult.setCursor(cursor); + + cancel |= startCondition(inventory, player, slot, ClickType.END_LEFT_DRAGGING, clicked, cursor).isCancel(); + + // Should be size of each defined slot (if not full) + final int slotSize = (int) ((float) cursorAmount / (float) slotCount); + int finalCursorAmount = cursorAmount; + + if (!cancel) { + for (int s : slots) { + ItemStack slotItem = itemGetter.apply(s); + StackingRule slotItemRule = slotItem.getStackingRule(); + + final int maxSize = stackingRule.getMaxSize(cursor); + if (stackingRule.canBeStacked(cursor, slotItem)) { + final int amount = slotItemRule.getAmount(slotItem); + if (stackingRule.canApply(slotItem, amount + slotSize)) { + slotItem = stackingRule.apply(slotItem, a -> a + slotSize); + finalCursorAmount -= slotSize; + } else { + final int removedAmount = maxSize - amount; + slotItem = stackingRule.apply(slotItem, maxSize); + finalCursorAmount -= removedAmount; + } + } else if (slotItem.isAir()) { + slotItem = stackingRule.apply(cursor, slotSize); + finalCursorAmount -= slotSize; + } + itemSetter.accept(s, slotItem); + + callClickEvent(player, inventory, s, ClickType.LEFT_DRAGGING, slotItem, cursor); + } + + // If no slots were dragged over, no need to apply any kind of stacking rules + if (clickResult != null) { + cursor = stackingRule.apply(cursor, finalCursorAmount); + clickResult.setCursor(cursor); + } + } leftDraggingMap.remove(player); } else if (button == 6) { @@ -297,32 +322,51 @@ public class InventoryClickProcessor { int cursorAmount = stackingRule.getAmount(cursor); if (size > cursorAmount) return null; + + boolean cancel = false; + for (int s : slots) { - ItemStack draggedItem = cursor; ItemStack slotItem = itemGetter.apply(s); - clickResult = startCondition(inventory, player, s, ClickType.DRAGGING, slotItem, cursor); - if (clickResult.isCancel()) - break; + clickResult = startCondition(inventory, player, s, ClickType.RIGHT_DRAGGING, slotItem, cursor); - StackingRule slotItemRule = slotItem.getStackingRule(); - if (stackingRule.canBeStacked(draggedItem, slotItem)) { - final int amount = slotItemRule.getAmount(slotItem) + 1; - if (stackingRule.canApply(slotItem, amount)) { - slotItem = stackingRule.apply(slotItem, amount); - itemSetter.accept(s, slotItem); + if (clickResult.isCancel()) { + cancel = true; + + break; + } + } + + cancel |= startCondition(inventory, player, slot, ClickType.END_RIGHT_DRAGGING, clicked, cursor).isCancel(); + + if (!cancel) { + for (int s : slots) { + ItemStack draggedItem = cursor; + ItemStack slotItem = itemGetter.apply(s); + + StackingRule slotItemRule = slotItem.getStackingRule(); + if (stackingRule.canBeStacked(draggedItem, slotItem)) { + final int amount = slotItemRule.getAmount(slotItem) + 1; + if (stackingRule.canApply(slotItem, amount)) { + slotItem = stackingRule.apply(slotItem, amount); + itemSetter.accept(s, slotItem); + cursorAmount -= 1; + } + } else if (slotItem.isAir()) { + draggedItem = stackingRule.apply(draggedItem, 1); + itemSetter.accept(s, draggedItem); cursorAmount -= 1; } - } else if (slotItem.isAir()) { - draggedItem = stackingRule.apply(draggedItem, 1); - itemSetter.accept(s, draggedItem); - cursorAmount -= 1; + + callClickEvent(player, inventory, s, ClickType.RIGHT_DRAGGING, draggedItem, cursor); } - callClickEvent(player, inventory, s, ClickType.DRAGGING, draggedItem, cursor); + // If no slots were dragged over, no need to apply any kind of stacking rules + if (clickResult != null) { + cursor = stackingRule.apply(cursor, cursorAmount); + clickResult.setCursor(cursor); + } } - cursor = stackingRule.apply(cursor, cursorAmount); - clickResult.setCursor(cursor); rightDraggingMap.remove(player);