diff --git a/src/main/java/fr/themode/minestom/instance/Instance.java b/src/main/java/fr/themode/minestom/instance/Instance.java index 561b2c2e3..77a9ac510 100644 --- a/src/main/java/fr/themode/minestom/instance/Instance.java +++ b/src/main/java/fr/themode/minestom/instance/Instance.java @@ -116,7 +116,7 @@ public class Instance { protected void sendChunkUpdate(Chunk chunk) { ChunkDataPacket chunkDataPacket = new ChunkDataPacket(); - chunkDataPacket.fullChunk = true; // TODO partial chunk data + chunkDataPacket.fullChunk = false; // TODO partial chunk data chunkDataPacket.chunk = chunk; getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(chunkDataPacket)); } diff --git a/src/main/java/fr/themode/minestom/inventory/Inventory.java b/src/main/java/fr/themode/minestom/inventory/Inventory.java index c3b02c16f..d57a5c56c 100644 --- a/src/main/java/fr/themode/minestom/inventory/Inventory.java +++ b/src/main/java/fr/themode/minestom/inventory/Inventory.java @@ -71,6 +71,11 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { return itemStacks[slot]; } + @Override + public ItemStack[] getItemStacks() { + return Arrays.copyOf(itemStacks, itemStacks.length); + } + public void updateItems() { WindowItemsPacket windowItemsPacket = getWindowItemsPacket(); getViewers().forEach(p -> p.getPlayerConnection().sendPacket(windowItemsPacket)); @@ -138,13 +143,13 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { if (cursorItem.isSimilar(clicked)) { resultCursor = cursorItem.clone(); resultClicked = clicked.clone(); - int amount = cursorItem.getAmount() + clicked.getAmount(); - if (amount > 64) { - resultCursor.setAmount((byte) (amount - 64)); + int totalAmount = cursorItem.getAmount() + clicked.getAmount(); + if (totalAmount > 64) { + resultCursor.setAmount((byte) (totalAmount - 64)); resultClicked.setAmount((byte) 64); } else { resultCursor = ItemStack.AIR_ITEM; - resultClicked.setAmount((byte) amount); + resultClicked.setAmount((byte) totalAmount); } } else { resultCursor = clicked.clone(); @@ -154,11 +159,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { if (isInWindow) { setItemStack(slot, resultClicked); setCursorPlayerItem(player, resultCursor); - //updateItems(); } else { playerInventory.setItemStack(slot, offset, resultClicked); setCursorPlayerItem(player, resultCursor); - //playerInventory.update(); } } @@ -176,7 +179,6 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { ItemStack resultClicked; if (cursorItem.isSimilar(clicked)) { - resultCursor = cursorItem.clone(); resultClicked = clicked.clone(); int amount = clicked.getAmount() + 1; if (amount > 64) { @@ -222,7 +224,81 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { @Override public void shiftClick(Player player, int slot) { + PlayerInventory playerInventory = player.getInventory(); + boolean isInWindow = isClickInWindow(slot); + ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); + if (clicked.isAir()) + return; + + ItemStack resultClicked = clicked.clone(); + boolean filled = false; + + if (!isInWindow) { + for (int i = 0; i < itemStacks.length; i++) { + ItemStack item = itemStacks[i]; + if (item.isSimilar(clicked)) { + int amount = item.getAmount(); + if (amount == 64) + continue; + int totalAmount = resultClicked.getAmount() + amount; + if (totalAmount > 64) { + item.setAmount((byte) 64); + setItemStack(i, item); + resultClicked.setAmount((byte) (totalAmount - 64)); + filled = false; + continue; + } else { + resultClicked.setAmount((byte) totalAmount); + setItemStack(i, resultClicked); + playerInventory.setItemStack(slot, offset, ItemStack.AIR_ITEM); + filled = true; + break; + } + } else if (item.isAir()) { + // Switch + setItemStack(i, resultClicked); + playerInventory.setItemStack(slot, offset, ItemStack.AIR_ITEM); + filled = true; + break; + } + } + if (!filled) { + playerInventory.setItemStack(slot, offset, resultClicked); + } + } else { + for (int i = 44; i >= 0; i--) { // Hotbar + ItemStack item = playerInventory.getItemStack(i, offset); + if (item.isSimilar(clicked)) { + int amount = item.getAmount(); + if (amount == 64) + continue; + int totalAmount = resultClicked.getAmount() + amount; + if (totalAmount > 64) { + item.setAmount((byte) 64); + playerInventory.setItemStack(i, offset, item); + resultClicked.setAmount((byte) (totalAmount - 64)); + filled = false; + continue; + } else { + resultClicked.setAmount((byte) totalAmount); + playerInventory.setItemStack(i, offset, resultClicked); + setItemStack(slot, ItemStack.AIR_ITEM); + filled = true; + break; + } + } else if (item.isAir()) { + // Switch + playerInventory.setItemStack(i, offset, resultClicked); + setItemStack(slot, ItemStack.AIR_ITEM); + filled = true; + break; + } + } + if (!filled) { // Still not filled, inventory is full + setItemStack(slot, resultClicked); + } + } } @Override @@ -249,7 +325,6 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { resultClicked = ItemStack.AIR_ITEM; resultHeld = clicked.clone(); } else { - System.out.println("CASE3"); // Otherwise replace held item and held resultClicked = heldItem.clone(); resultHeld = clicked.clone(); @@ -278,4 +353,82 @@ public class Inventory implements InventoryModifier, InventoryClickHandler { public void dropItemStack(Player player, int slot) { } + + @Override + public void doubleClick(Player player, int slot) { + PlayerInventory playerInventory = player.getInventory(); + ItemStack cursorItem = getCursorItem(player).clone(); + if (cursorItem.isAir()) + return; + + int amount = cursorItem.getAmount(); + + if (amount == 64) + return; + + // Start by looping through the opened inventory + for (int i = 0; i < itemStacks.length; i++) { + if (i == slot) + continue; + if (amount == 64) + break; + ItemStack item = itemStacks[i]; + if (cursorItem.isSimilar(item)) { + int totalAmount = amount + item.getAmount(); + if (totalAmount > 64) { + cursorItem.setAmount((byte) 64); + item.setAmount((byte) (totalAmount - 64)); + setItemStack(i, item); + } else { + cursorItem.setAmount((byte) totalAmount); + setItemStack(i, ItemStack.AIR_ITEM); + } + amount = cursorItem.getAmount(); + } + } + + // Looping through player inventory + for (int i = 9; i < PlayerInventory.INVENTORY_SIZE - 9; i++) { // Inventory + if (playerInventory.convertToPacketSlot(i) == slot) + continue; + if (amount == 64) + break; + ItemStack item = playerInventory.getItemStack(i); + if (cursorItem.isSimilar(item)) { + int totalAmount = amount + item.getAmount(); + if (totalAmount > 64) { + cursorItem.setAmount((byte) 64); + item.setAmount((byte) (totalAmount - 64)); + playerInventory.setItemStack(i, offset, item); + } else { + cursorItem.setAmount((byte) totalAmount); + playerInventory.setItemStack(i, offset, ItemStack.AIR_ITEM); + } + amount = cursorItem.getAmount(); + } + } + + for (int i = 0; i < 9; i++) { // Hotbar + if (playerInventory.convertToPacketSlot(i) == slot) + continue; + if (amount == 64) + break; + ItemStack item = playerInventory.getItemStack(i); + if (cursorItem.isSimilar(item)) { + int totalAmount = amount + item.getAmount(); + if (totalAmount > 64) { + cursorItem.setAmount((byte) 64); + item.setAmount((byte) (totalAmount - 64)); + playerInventory.setItemStack(i, offset, item); + } else { + cursorItem.setAmount((byte) totalAmount); + playerInventory.setItemStack(i, offset, ItemStack.AIR_ITEM); + } + amount = cursorItem.getAmount(); + } + } + + setCursorPlayerItem(player, cursorItem); + playerInventory.update(); + } } diff --git a/src/main/java/fr/themode/minestom/inventory/InventoryClickHandler.java b/src/main/java/fr/themode/minestom/inventory/InventoryClickHandler.java index 6d3683773..015117fbf 100644 --- a/src/main/java/fr/themode/minestom/inventory/InventoryClickHandler.java +++ b/src/main/java/fr/themode/minestom/inventory/InventoryClickHandler.java @@ -18,4 +18,6 @@ public interface InventoryClickHandler { void dropItemStack(Player player, int slot); + void doubleClick(Player player, int slot); + } diff --git a/src/main/java/fr/themode/minestom/inventory/InventoryModifier.java b/src/main/java/fr/themode/minestom/inventory/InventoryModifier.java index 305fc78bb..bb6fb395e 100644 --- a/src/main/java/fr/themode/minestom/inventory/InventoryModifier.java +++ b/src/main/java/fr/themode/minestom/inventory/InventoryModifier.java @@ -9,4 +9,6 @@ public interface InventoryModifier { boolean addItemStack(ItemStack itemStack); ItemStack getItemStack(int slot); + + ItemStack[] getItemStacks(); } diff --git a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java index 9ca1f2463..8432e7ae6 100644 --- a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java +++ b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java @@ -10,7 +10,7 @@ import java.util.Arrays; public class PlayerInventory implements InventoryModifier { - private static final int TOTAL_INVENTORY_SIZE = 46; + public static final int INVENTORY_SIZE = 46; private static final int CRAFT_SLOT_1 = 36; private static final int CRAFT_SLOT_2 = 37; @@ -24,7 +24,7 @@ public class PlayerInventory implements InventoryModifier { private static final int OFFHAND_SLOT = 45; private Player player; - private ItemStack[] items = new ItemStack[TOTAL_INVENTORY_SIZE]; + private ItemStack[] items = new ItemStack[INVENTORY_SIZE]; public PlayerInventory(Player player) { this.player = player; @@ -37,6 +37,11 @@ public class PlayerInventory implements InventoryModifier { return this.items[slot]; } + @Override + public ItemStack[] getItemStacks() { + return Arrays.copyOf(items, items.length); + } + @Override public void setItemStack(int slot, ItemStack itemStack) { safeItemInsert(slot, itemStack); @@ -131,7 +136,7 @@ public class PlayerInventory implements InventoryModifier { return slot; } - private int convertToPacketSlot(int slot) { + protected int convertToPacketSlot(int slot) { if (slot > -1 && slot < 9) { // Held bar 0-9 slot = slot + 36; } else if (slot > 8 && slot < 36) { // Inventory 9-35 @@ -148,14 +153,14 @@ public class PlayerInventory implements InventoryModifier { private void sendSlotRefresh(short slot, ItemStack itemStack) { SetSlotPacket setSlotPacket = new SetSlotPacket(); - setSlotPacket.windowId = (byte) (slot > 35 && slot < TOTAL_INVENTORY_SIZE ? 0 : -2); + setSlotPacket.windowId = (byte) (slot > 35 && slot < INVENTORY_SIZE ? 0 : -2); setSlotPacket.slot = slot; setSlotPacket.itemStack = itemStack; player.getPlayerConnection().sendPacket(setSlotPacket); } private WindowItemsPacket createWindowItemsPacket() { - ItemStack[] convertedSlots = new ItemStack[TOTAL_INVENTORY_SIZE]; + ItemStack[] convertedSlots = new ItemStack[INVENTORY_SIZE]; Arrays.fill(convertedSlots, ItemStack.AIR_ITEM); // TODO armor and craft for (int i = 0; i < items.length; i++) { @@ -165,7 +170,7 @@ public class PlayerInventory implements InventoryModifier { WindowItemsPacket windowItemsPacket = new WindowItemsPacket(); windowItemsPacket.windowId = 0; - windowItemsPacket.count = TOTAL_INVENTORY_SIZE; + windowItemsPacket.count = INVENTORY_SIZE; windowItemsPacket.items = convertedSlots; return windowItemsPacket; } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java index 57592cc1c..d93484ef5 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java @@ -143,8 +143,9 @@ public class LoginStartPacket implements ClientPreplayPacket { //System.out.println("HAHAHAHHAHHAH " + player.getUuid()); PlayerInventory inventory = player.getInventory(); - inventory.addItemStack(new ItemStack(1, (byte) 60)); - inventory.addItemStack(new ItemStack(1, (byte) 50)); + for (int i = 0; i < 20; i++) { + inventory.addItemStack(new ItemStack(1, (byte) 64)); + } Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre"); inv.setItemStack(0, new ItemStack(1, (byte) 1)); diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientClickWindowPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientClickWindowPacket.java index 0fea667d5..ef67da6a9 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientClickWindowPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientClickWindowPacket.java @@ -42,14 +42,7 @@ public class ClientClickWindowPacket implements ClientPlayPacket { } break; case 1: - switch (button) { - case 0: - // Shift + left click - break; - case 1: - // Shift + right click - break; - } + inventory.shiftClick(player, slot); // Shift + left/right have identical behavior break; case 2: inventory.changeHeld(player, slot, button); @@ -64,7 +57,7 @@ public class ClientClickWindowPacket implements ClientPlayPacket { // Dragging break; case 6: - // Double click (merge similar items) + inventory.doubleClick(player, slot); break; } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientCloseWindow.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientCloseWindow.java index 47ced2f04..a95ad38bb 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientCloseWindow.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientCloseWindow.java @@ -12,7 +12,6 @@ public class ClientCloseWindow implements ClientPlayPacket { @Override public void process(Player player) { - System.out.println("CLOSED: " + windowId); Inventory openInventory = player.getOpenInventory(); // if windowId == 0 then it is player's inventory, meaning that they hadn't been any open inventory packet if (openInventory != null)