diff --git a/src/main/java/fr/themode/demo/PlayerInit.java b/src/main/java/fr/themode/demo/PlayerInit.java index 51af82ac2..252386302 100644 --- a/src/main/java/fr/themode/demo/PlayerInit.java +++ b/src/main/java/fr/themode/demo/PlayerInit.java @@ -108,7 +108,7 @@ public class PlayerInit { player.getInventory().addItemStack(item); Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "Test inventory"); - inventory.setInventoryCondition((slot, inventory1, inventoryConditionResult) -> { + inventory.setInventoryCondition((p, slot, inventoryConditionResult) -> { inventoryConditionResult.setCancel(false); }); inventory.setItemStack(0, item.clone()); diff --git a/src/main/java/fr/themode/minestom/entity/EntityManager.java b/src/main/java/fr/themode/minestom/entity/EntityManager.java index da0b01d61..48de5ed39 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityManager.java +++ b/src/main/java/fr/themode/minestom/entity/EntityManager.java @@ -70,20 +70,6 @@ public class EntityManager { } - private void waitingPlayersTick() { - Player waitingPlayer; - while ((waitingPlayer = waitingPlayers.poll()) != null) { - final Player playerCache = waitingPlayer; - playersPool.execute(() -> { - PlayerLoginEvent loginEvent = new PlayerLoginEvent(); - playerCache.callEvent(PlayerLoginEvent.class, loginEvent); - Instance spawningInstance = loginEvent.getSpawningInstance() == null ? instanceManager.createInstanceContainer() : loginEvent.getSpawningInstance(); - - playerCache.setInstance(spawningInstance); - }); - } - } - /** * Update each entity type separately independently of their location * @@ -170,6 +156,20 @@ public class EntityManager { } } + // Add connected clients after the handshake (used to free the networking threads) + private void waitingPlayersTick() { + Player waitingPlayer; + while ((waitingPlayer = waitingPlayers.poll()) != null) { + final Player playerCache = waitingPlayer; + playersPool.execute(() -> { + PlayerLoginEvent loginEvent = new PlayerLoginEvent(); + playerCache.callEvent(PlayerLoginEvent.class, loginEvent); + Instance spawningInstance = loginEvent.getSpawningInstance() == null ? instanceManager.createInstanceContainer() : loginEvent.getSpawningInstance(); + + playerCache.setInstance(spawningInstance); + }); + } + } public UpdateType getUpdateType() { return updateType; diff --git a/src/main/java/fr/themode/minestom/inventory/Inventory.java b/src/main/java/fr/themode/minestom/inventory/Inventory.java index f85120fbd..d21edc240 100644 --- a/src/main/java/fr/themode/minestom/inventory/Inventory.java +++ b/src/main/java/fr/themode/minestom/inventory/Inventory.java @@ -162,7 +162,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); - InventoryClickResult clickResult = clickProcessor.leftClick(getInventoryCondition(), slot, clicked, cursor); + InventoryClickResult clickResult = clickProcessor.leftClick(getInventoryCondition(), player, slot, clicked, cursor); if (clickResult.doRefresh()) player.getPlayerConnection().sendPacket(getWindowItemsPacket()); @@ -183,7 +183,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View boolean isInWindow = isClickInWindow(slot); ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); - InventoryClickResult clickResult = clickProcessor.rightClick(getInventoryCondition(), slot, clicked, cursor); + InventoryClickResult clickResult = clickProcessor.rightClick(getInventoryCondition(), player, slot, clicked, cursor); if (clickResult.doRefresh()) player.getPlayerConnection().sendPacket(getWindowItemsPacket()); @@ -208,7 +208,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryCondition inventoryCondition = getInventoryCondition(); if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem); - inventoryCondition.accept(slot, null, result); + inventoryCondition.accept(player, slot, result); cursorItem = result.getCursorItem(); clicked = result.getClickedItem(); @@ -312,7 +312,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); ItemStack heldItem = playerInventory.getItemStack(key); - InventoryClickResult clickResult = clickProcessor.changeHeld(getInventoryCondition(), slot, clicked, heldItem); + InventoryClickResult clickResult = clickProcessor.changeHeld(getInventoryCondition(), player, slot, clicked, heldItem); if (clickResult.doRefresh()) player.getPlayerConnection().sendPacket(getWindowItemsPacket()); @@ -356,7 +356,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryCondition inventoryCondition = getInventoryCondition(); if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem); - inventoryCondition.accept(slot, null, result); + inventoryCondition.accept(player, slot, result); cursorItem = result.getCursorItem(); clicked = result.getClickedItem(); diff --git a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java index 8ec10b34b..c0545e928 100644 --- a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java +++ b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java @@ -262,7 +262,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack cursor = getCursorItem(); ItemStack clicked = getItemStack(convertSlot(slot, OFFSET)); - InventoryClickResult clickResult = clickProcessor.leftClick(getInventoryCondition(), slot, clicked, cursor); + InventoryClickResult clickResult = clickProcessor.leftClick(getInventoryCondition(), player, slot, clicked, cursor); if (clickResult.doRefresh()) sendSlotRefresh((short) slot, clicked); @@ -276,7 +276,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack cursor = getCursorItem(); ItemStack clicked = getItemStack(slot, OFFSET); - InventoryClickResult clickResult = clickProcessor.rightClick(getInventoryCondition(), slot, clicked, cursor); + InventoryClickResult clickResult = clickProcessor.rightClick(getInventoryCondition(), player, slot, clicked, cursor); if (clickResult.doRefresh()) sendSlotRefresh((short) slot, clicked); @@ -309,7 +309,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler InventoryCondition inventoryCondition = getInventoryCondition(); if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem); - inventoryCondition.accept(slot, null, result); + inventoryCondition.accept(player, slot, result); cursorItem = result.getCursorItem(); clicked = result.getClickedItem(); @@ -377,7 +377,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack heldItem = getItemStack(key); ItemStack clicked = getItemStack(slot, OFFSET); - InventoryClickResult clickResult = clickProcessor.changeHeld(getInventoryCondition(), slot, clicked, heldItem); + InventoryClickResult clickResult = clickProcessor.changeHeld(getInventoryCondition(), player, slot, clicked, heldItem); if (clickResult.doRefresh()) sendSlotRefresh((short) slot, clicked); @@ -397,7 +397,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler InventoryCondition inventoryCondition = getInventoryCondition(); if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem); - inventoryCondition.accept(slot, null, result); + inventoryCondition.accept(player, slot, result); cursorItem = result.getCursorItem(); clicked = result.getClickedItem(); @@ -427,18 +427,36 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler if (!leftDraggingMap.containsKey(player)) return; Set slots = leftDraggingMap.get(player); - int size = slots.size(); + int slotCount = slots.size(); int cursorAmount = stackingRule.getAmount(cursorItem); - if (size > cursorAmount) + if (slotCount > cursorAmount) return; - int slotSize = (int) ((float) cursorAmount / (float) size); + // 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(); - draggedItem = stackingRule.apply(draggedItem, slotSize); - setItemStack(s, OFFSET, draggedItem); + 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, cursorAmount - (slotSize * size)); + cursorItem = stackingRule.apply(cursorItem, finalCursorAmount); setCursorItem(cursorItem); leftDraggingMap.remove(player); @@ -453,14 +471,13 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler return; for (Integer s : slots) { ItemStack draggedItem = cursorItem.clone(); - ItemStack slotItem = getItemStack(s); - if (draggedItem.isSimilar(slotItem)) { + 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); } - System.out.println("TEST: " + s + ":" + OFFSET); } else if (slotItem.isAir()) { draggedItem = stackingRule.apply(draggedItem, 1); setItemStack(s, OFFSET, draggedItem); @@ -499,7 +516,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler InventoryCondition inventoryCondition = getInventoryCondition(); if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem); - inventoryCondition.accept(slot, null, result); + inventoryCondition.accept(player, slot, result); cursorItem = result.getCursorItem(); clicked = result.getClickedItem(); 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 e699197e1..79a4c951a 100644 --- a/src/main/java/fr/themode/minestom/inventory/click/InventoryClickProcessor.java +++ b/src/main/java/fr/themode/minestom/inventory/click/InventoryClickProcessor.java @@ -1,14 +1,23 @@ package fr.themode.minestom.inventory.click; +import fr.themode.minestom.entity.Player; import fr.themode.minestom.inventory.rule.InventoryCondition; import fr.themode.minestom.inventory.rule.InventoryConditionResult; import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.item.StackingRule; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + public class InventoryClickProcessor { - public InventoryClickResult leftClick(InventoryCondition inventoryCondition, int slot, ItemStack clicked, ItemStack cursor) { - InventoryClickResult clickResult = startCondition(inventoryCondition, slot, clicked, cursor); + // Dragging maps + private Map> leftDraggingMap = new HashMap<>(); + private Map> rightDraggingMap = new HashMap<>(); + + public InventoryClickResult leftClick(InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { + InventoryClickResult clickResult = startCondition(inventoryCondition, player, slot, clicked, cursor); if (clickResult.isCancel()) { return clickResult; @@ -50,8 +59,8 @@ public class InventoryClickProcessor { return clickResult; } - public InventoryClickResult rightClick(InventoryCondition inventoryCondition, int slot, ItemStack clicked, ItemStack cursor) { - InventoryClickResult clickResult = startCondition(inventoryCondition, slot, clicked, cursor); + public InventoryClickResult rightClick(InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { + InventoryClickResult clickResult = startCondition(inventoryCondition, player, slot, clicked, cursor); if (clickResult.isCancel()) { return clickResult; @@ -107,8 +116,8 @@ public class InventoryClickProcessor { return clickResult; } - public InventoryClickResult changeHeld(InventoryCondition inventoryCondition, int slot, ItemStack clicked, ItemStack cursor) { - InventoryClickResult clickResult = startCondition(inventoryCondition, slot, clicked, cursor); + public InventoryClickResult changeHeld(InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { + InventoryClickResult clickResult = startCondition(inventoryCondition, player, slot, clicked, cursor); if (clickResult.isCancel()) { return clickResult; @@ -147,11 +156,11 @@ public class InventoryClickProcessor { return clickResult; } - private InventoryClickResult startCondition(InventoryCondition inventoryCondition, int slot, ItemStack clicked, ItemStack cursor) { + private InventoryClickResult startCondition(InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) { InventoryClickResult clickResult = new InventoryClickResult(clicked, cursor); if (inventoryCondition != null) { InventoryConditionResult result = new InventoryConditionResult(clicked, cursor); - inventoryCondition.accept(slot, null, result); + inventoryCondition.accept(player, slot, result); cursor = result.getCursorItem(); clicked = result.getClickedItem(); diff --git a/src/main/java/fr/themode/minestom/inventory/rule/InventoryCondition.java b/src/main/java/fr/themode/minestom/inventory/rule/InventoryCondition.java index aa7caad00..e0fdf4d82 100644 --- a/src/main/java/fr/themode/minestom/inventory/rule/InventoryCondition.java +++ b/src/main/java/fr/themode/minestom/inventory/rule/InventoryCondition.java @@ -1,9 +1,9 @@ package fr.themode.minestom.inventory.rule; -import fr.themode.minestom.inventory.Inventory; +import fr.themode.minestom.entity.Player; public interface InventoryCondition { - void accept(int slot, Inventory inventory, InventoryConditionResult inventoryConditionResult); + void accept(Player player, int slot, InventoryConditionResult inventoryConditionResult); } diff --git a/src/main/java/fr/themode/minestom/item/ItemStack.java b/src/main/java/fr/themode/minestom/item/ItemStack.java index b3ddd9978..2fccaaa2c 100644 --- a/src/main/java/fr/themode/minestom/item/ItemStack.java +++ b/src/main/java/fr/themode/minestom/item/ItemStack.java @@ -8,7 +8,7 @@ import java.util.ArrayList; public class ItemStack implements DataContainer { - public static final ItemStack AIR_ITEM = new ItemStack(0, (byte) 1); + public static final ItemStack AIR_ITEM = new ItemStack(0, (byte) 0); private static StackingRule defaultStackingRule; private int materialId;