diff --git a/src/main/java/fr/themode/minestom/inventory/Inventory.java b/src/main/java/fr/themode/minestom/inventory/Inventory.java index 31182c888..0ee527237 100644 --- a/src/main/java/fr/themode/minestom/inventory/Inventory.java +++ b/src/main/java/fr/themode/minestom/inventory/Inventory.java @@ -337,7 +337,36 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View @Override public void dragging(Player player, int slot, int button) { + PlayerInventory playerInventory = player.getInventory(); + boolean isInWindow = isClickInWindow(slot); + ItemStack clicked = null; + ItemStack cursor = getCursorItem(player); + if (slot != -999) + clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); + InventoryClickResult clickResult = clickProcessor.dragging(getInventoryCondition(), player, + slot, button, + clicked, cursor, + + s -> isClickInWindow(s) ? getItemStack(s) : playerInventory.getItemStack(s, offset), + + (s, item) -> { + System.out.println("click window:" + isClickInWindow(s)); + if (isClickInWindow(s)) { + setItemStack(s, item); + } else { + playerInventory.setItemStack(s, offset, item); + } + }); + + if (clickResult == null) + return; + + if (isInWindow) { + setCursorPlayerItem(player, clickResult.getCursor()); + } else { + setCursorPlayerItem(player, clickResult.getCursor()); + } } @Override diff --git a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java index 23cb827f9..9eff099ea 100644 --- a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java +++ b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java @@ -12,7 +12,7 @@ import fr.themode.minestom.net.packet.server.play.SetSlotPacket; import fr.themode.minestom.net.packet.server.play.WindowItemsPacket; import fr.themode.minestom.net.player.PlayerConnection; -import java.util.*; +import java.util.Arrays; import static fr.themode.minestom.utils.inventory.PlayerInventoryUtils.*; @@ -249,9 +249,6 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler return windowItemsPacket; } - private Map> leftDraggingMap = new HashMap<>(); - private Map> rightDraggingMap = new HashMap<>(); - @Override public void leftClick(Player player, int slot) { ItemStack cursor = getCursorItem(); @@ -383,123 +380,20 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler @Override public void dragging(Player player, int slot, int button) { - ItemStack cursorItem = getCursorItem(); + ItemStack cursor = getCursorItem(); ItemStack clicked = null; if (slot != -999) clicked = getItemStack(slot, OFFSET); - // Start condition - InventoryCondition inventoryCondition = getInventoryCondition(); - if (inventoryCondition != null) { - InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem); - inventoryCondition.accept(player, slot, result); + InventoryClickResult clickResult = clickProcessor.dragging(getInventoryCondition(), player, + slot, button, + clicked, cursor, s -> getItemStack(s, OFFSET), + (s, item) -> setItemStack(s, OFFSET, item)); - cursorItem = result.getCursorItem(); - clicked = result.getClickedItem(); - - if (result.isCancel()) { - setItemStack(slot, OFFSET, clicked); - setCursorItem(cursorItem); - // Refresh client slot - sendSlotRefresh((short) slot, clicked); - return; - } - } - // End condition - - StackingRule stackingRule = cursorItem.getStackingRule(); - - if (slot == -999) { - // Start or end left/right drag - if (button == 0) { - // Start left - this.leftDraggingMap.put(player, new HashSet<>()); - } else if (button == 4) { - // Start right - this.rightDraggingMap.put(player, new HashSet<>()); - } else if (button == 2) { - // End left - if (!leftDraggingMap.containsKey(player)) - return; - Set slots = leftDraggingMap.get(player); - int slotCount = slots.size(); - int cursorAmount = stackingRule.getAmount(cursorItem); - if (slotCount > cursorAmount) - return; - // Should be size of each defined slot (if not full) - int slotSize = (int) ((float) cursorAmount / (float) slotCount); - int finalCursorAmount = cursorAmount; - - for (Integer s : slots) { - ItemStack draggedItem = cursorItem.clone(); - ItemStack slotItem = getItemStack(s, OFFSET); - int maxSize = stackingRule.getMaxSize(); - if (stackingRule.canBeStacked(draggedItem, slotItem)) { - int amount = slotItem.getAmount() + slotSize; - if (stackingRule.canApply(slotItem, amount)) { - slotItem = stackingRule.apply(slotItem, amount); - finalCursorAmount -= slotSize; - } else { - int removedAmount = amount - maxSize; - slotItem = stackingRule.apply(slotItem, maxSize); - finalCursorAmount -= removedAmount; - } - } else if (slotItem.isAir()) { - slotItem = stackingRule.apply(draggedItem, slotSize); - finalCursorAmount -= slotSize; - } - - setItemStack(s, OFFSET, slotItem); - } - cursorItem = stackingRule.apply(cursorItem, finalCursorAmount); - setCursorItem(cursorItem); - - leftDraggingMap.remove(player); - } else if (button == 6) { - // End right - if (!rightDraggingMap.containsKey(player)) - return; - Set slots = rightDraggingMap.get(player); - int size = slots.size(); - int cursorAmount = stackingRule.getAmount(cursorItem); - if (size > cursorAmount) - return; - for (Integer s : slots) { - ItemStack draggedItem = cursorItem.clone(); - ItemStack slotItem = getItemStack(s, OFFSET); - if (stackingRule.canBeStacked(draggedItem, slotItem)) { - int amount = slotItem.getAmount() + 1; - if (stackingRule.canApply(slotItem, amount)) { - slotItem = stackingRule.apply(slotItem, amount); - setItemStack(s, OFFSET, slotItem); - } - } else if (slotItem.isAir()) { - draggedItem = stackingRule.apply(draggedItem, 1); - setItemStack(s, OFFSET, draggedItem); - } - } - cursorItem = stackingRule.apply(cursorItem, cursorAmount - size); - setCursorItem(cursorItem); - - rightDraggingMap.remove(player); - - } - } else { - // Add slot - if (button == 1) { - // Add left slot - if (!leftDraggingMap.containsKey(player)) - return; - leftDraggingMap.get(player).add(slot); - - } else if (button == 5) { - // Add right slot - if (!rightDraggingMap.containsKey(player)) - return; - rightDraggingMap.get(player).add(slot); - } - } + if (clickResult == null) + return; + setCursorItem(clickResult.getCursor()); } @Override diff --git a/src/main/java/fr/themode/minestom/inventory/click/InventoryClickProcessor.java b/src/main/java/fr/themode/minestom/inventory/click/InventoryClickProcessor.java index 8d4f3c808..3f487fcdf 100644 --- a/src/main/java/fr/themode/minestom/inventory/click/InventoryClickProcessor.java +++ b/src/main/java/fr/themode/minestom/inventory/click/InventoryClickProcessor.java @@ -7,8 +7,11 @@ import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.item.StackingRule; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Function; public class InventoryClickProcessor { @@ -153,8 +156,109 @@ public class InventoryClickProcessor { return clickResult; } - private InventoryClickResult startCondition(InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { + public InventoryClickResult dragging(InventoryCondition inventoryCondition, Player player, + int slot, int button, + ItemStack clicked, ItemStack cursor, + Function itemGetter, + BiConsumer itemSetter) { InventoryClickResult clickResult = new InventoryClickResult(clicked, cursor); + + StackingRule stackingRule = cursor.getStackingRule(); + + if (slot == -999) { + // Start or end left/right drag + if (button == 0) { + // Start left + this.leftDraggingMap.put(player, new HashSet<>()); + } else if (button == 4) { + // Start right + this.rightDraggingMap.put(player, new HashSet<>()); + } else if (button == 2) { + // End left + if (!leftDraggingMap.containsKey(player)) + return null; + Set slots = leftDraggingMap.get(player); + int slotCount = slots.size(); + int cursorAmount = stackingRule.getAmount(cursor); + if (slotCount > cursorAmount) + return null; + // Should be size of each defined slot (if not full) + int slotSize = (int) ((float) cursorAmount / (float) slotCount); + int finalCursorAmount = cursorAmount; + + for (Integer s : slots) { + ItemStack draggedItem = cursor.clone(); + ItemStack slotItem = itemGetter.apply(s); + int maxSize = stackingRule.getMaxSize(); + if (stackingRule.canBeStacked(draggedItem, slotItem)) { + int amount = slotItem.getAmount() + slotSize; + if (stackingRule.canApply(slotItem, amount)) { + slotItem = stackingRule.apply(slotItem, amount); + finalCursorAmount -= slotSize; + } else { + int removedAmount = amount - maxSize; + slotItem = stackingRule.apply(slotItem, maxSize); + finalCursorAmount -= removedAmount; + } + } else if (slotItem.isAir()) { + slotItem = stackingRule.apply(draggedItem, slotSize); + finalCursorAmount -= slotSize; + } + itemSetter.accept(s, slotItem); + } + cursor = stackingRule.apply(cursor, finalCursorAmount); + clickResult.setCursor(cursor); + + leftDraggingMap.remove(player); + } else if (button == 6) { + // End right + if (!rightDraggingMap.containsKey(player)) + return null; + Set slots = rightDraggingMap.get(player); + int size = slots.size(); + int cursorAmount = stackingRule.getAmount(cursor); + if (size > cursorAmount) + return null; + for (Integer s : slots) { + ItemStack draggedItem = cursor.clone(); + ItemStack slotItem = itemGetter.apply(s); + if (stackingRule.canBeStacked(draggedItem, slotItem)) { + int amount = slotItem.getAmount() + 1; + if (stackingRule.canApply(slotItem, amount)) { + slotItem = stackingRule.apply(slotItem, amount); + itemSetter.accept(s, slotItem); + } + } else if (slotItem.isAir()) { + draggedItem = stackingRule.apply(draggedItem, 1); + itemSetter.accept(s, draggedItem); + } + } + cursor = stackingRule.apply(cursor, cursorAmount - size); + clickResult.setCursor(cursor); + + rightDraggingMap.remove(player); + + } + } else { + // Add slot + if (button == 1) { + // Add left slot + if (!leftDraggingMap.containsKey(player)) + return null; + leftDraggingMap.get(player).add(slot); + + } else if (button == 5) { + // Add right slot + if (!rightDraggingMap.containsKey(player)) + return null; + rightDraggingMap.get(player).add(slot); + } + } + + return clickResult; + } + + private InventoryClickResult startCondition(InventoryClickResult clickResult, InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursor); inventoryCondition.accept(player, slot, result); @@ -171,4 +275,9 @@ public class InventoryClickProcessor { return clickResult; } + private InventoryClickResult startCondition(InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { + InventoryClickResult clickResult = new InventoryClickResult(clicked, cursor); + return startCondition(clickResult, inventoryCondition, player, slot, clicked, cursor); + } + }