mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 02:57:37 +01:00
Inventory click listener
This commit is contained in:
parent
e2e7d67013
commit
60f5768011
@ -136,6 +136,7 @@ public class Player extends LivingEntity {
|
||||
refreshOpenInventory(null);
|
||||
}
|
||||
playerConnection.sendPacket(closeWindowPacket);
|
||||
inventory.update();
|
||||
}
|
||||
|
||||
public void refreshGameMode(GameMode gameMode) {
|
||||
|
@ -2,6 +2,7 @@ package fr.themode.minestom.inventory;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.server.play.SetSlotPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.WindowItemsPacket;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -11,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Inventory implements InventoryClickHandler {
|
||||
public class Inventory implements InventoryModifier, InventoryClickHandler {
|
||||
|
||||
private static AtomicInteger lastInventoryId = new AtomicInteger();
|
||||
|
||||
@ -52,6 +53,7 @@ public class Inventory implements InventoryClickHandler {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemStack(int slot, ItemStack itemStack) {
|
||||
if (slot < 0 || slot > inventoryType.getAdditionalSlot())
|
||||
throw new IllegalArgumentException(inventoryType.toString() + " does not have slot " + slot);
|
||||
@ -59,6 +61,12 @@ public class Inventory implements InventoryClickHandler {
|
||||
safeItemInsert(slot, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addItemStack(ItemStack itemStack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(int slot) {
|
||||
return itemStacks[slot];
|
||||
}
|
||||
@ -88,7 +96,13 @@ public class Inventory implements InventoryClickHandler {
|
||||
|
||||
private void safeItemInsert(int slot, ItemStack itemStack) {
|
||||
synchronized (this) {
|
||||
this.itemStacks[slot] = itemStack == null ? ItemStack.AIR_ITEM : itemStack;
|
||||
itemStack = itemStack == null ? ItemStack.AIR_ITEM : itemStack;
|
||||
this.itemStacks[slot] = itemStack;
|
||||
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
||||
setSlotPacket.windowId = 1;
|
||||
setSlotPacket.slot = (short) slot;
|
||||
setSlotPacket.itemStack = itemStack;
|
||||
getViewers().forEach(player -> player.getPlayerConnection().sendPacket(setSlotPacket));
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,9 +139,9 @@ public class Inventory implements InventoryClickHandler {
|
||||
resultCursor = cursorItem.clone();
|
||||
resultClicked = clicked.clone();
|
||||
int amount = cursorItem.getAmount() + clicked.getAmount();
|
||||
if (amount > 100) {
|
||||
resultCursor.setAmount((byte) (amount - 100));
|
||||
resultClicked.setAmount((byte) 100);
|
||||
if (amount > 64) {
|
||||
resultCursor.setAmount((byte) (amount - 64));
|
||||
resultClicked.setAmount((byte) 64);
|
||||
} else {
|
||||
resultCursor = ItemStack.AIR_ITEM;
|
||||
resultClicked.setAmount((byte) amount);
|
||||
@ -140,11 +154,11 @@ public class Inventory implements InventoryClickHandler {
|
||||
if (isInWindow) {
|
||||
setItemStack(slot, resultClicked);
|
||||
setCursorPlayerItem(player, resultCursor);
|
||||
updateItems();
|
||||
//updateItems();
|
||||
} else {
|
||||
playerInventory.setItemStack(slot, offset, resultClicked);
|
||||
setCursorPlayerItem(player, resultCursor);
|
||||
playerInventory.update();
|
||||
//playerInventory.update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +179,7 @@ public class Inventory implements InventoryClickHandler {
|
||||
resultCursor = cursorItem.clone();
|
||||
resultClicked = clicked.clone();
|
||||
int amount = clicked.getAmount() + 1;
|
||||
if (amount > 100) {
|
||||
if (amount > 64) {
|
||||
return;
|
||||
} else {
|
||||
resultCursor = cursorItem.clone();
|
||||
@ -200,11 +214,9 @@ public class Inventory implements InventoryClickHandler {
|
||||
if (isInWindow) {
|
||||
setItemStack(slot, resultClicked);
|
||||
setCursorPlayerItem(player, resultCursor);
|
||||
updateItems();
|
||||
} else {
|
||||
playerInventory.setItemStack(slot, offset, resultClicked);
|
||||
setCursorPlayerItem(player, resultCursor);
|
||||
playerInventory.update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +227,41 @@ public class Inventory implements InventoryClickHandler {
|
||||
|
||||
@Override
|
||||
public void changeHeld(Player player, int slot, int key) {
|
||||
PlayerInventory playerInventory = player.getInventory();
|
||||
|
||||
if (!getCursorItem(player).isAir())
|
||||
return;
|
||||
|
||||
boolean isInWindow = isClickInWindow(slot);
|
||||
ItemStack heldItem = playerInventory.getItemStack(key);
|
||||
ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset);
|
||||
|
||||
ItemStack resultClicked;
|
||||
ItemStack resultHeld;
|
||||
|
||||
if (clicked.isAir()) {
|
||||
// Set held item [key] to slot
|
||||
resultClicked = ItemStack.AIR_ITEM;
|
||||
resultHeld = clicked.clone();
|
||||
} else {
|
||||
if (heldItem.isAir()) {
|
||||
// if held item [key] is air then set clicked to held
|
||||
resultClicked = ItemStack.AIR_ITEM;
|
||||
resultHeld = clicked.clone();
|
||||
} else {
|
||||
System.out.println("CASE3");
|
||||
// Otherwise replace held item and held
|
||||
resultClicked = heldItem.clone();
|
||||
resultHeld = clicked.clone();
|
||||
}
|
||||
}
|
||||
|
||||
if (isInWindow) {
|
||||
setItemStack(slot, resultClicked);
|
||||
} else {
|
||||
playerInventory.setItemStack(slot, offset, resultClicked);
|
||||
}
|
||||
playerInventory.setItemStack(key, resultHeld);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,12 @@
|
||||
package fr.themode.minestom.inventory;
|
||||
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
|
||||
public interface InventoryModifier {
|
||||
|
||||
void setItemStack(int slot, ItemStack itemStack);
|
||||
|
||||
boolean addItemStack(ItemStack itemStack);
|
||||
|
||||
ItemStack getItemStack(int slot);
|
||||
}
|
@ -2,15 +2,29 @@ package fr.themode.minestom.inventory;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
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.Arrays;
|
||||
|
||||
public class PlayerInventory {
|
||||
public class PlayerInventory implements InventoryModifier {
|
||||
|
||||
private static final int TOTAL_INVENTORY_SIZE = 46;
|
||||
|
||||
private static final int CRAFT_SLOT_1 = 36;
|
||||
private static final int CRAFT_SLOT_2 = 37;
|
||||
private static final int CRAFT_SLOT_3 = 38;
|
||||
private static final int CRAFT_SLOT_4 = 39;
|
||||
private static final int CRAFT_RESULT = 40;
|
||||
private static final int HELMET_SLOT = 41;
|
||||
private static final int CHESTPLATE_SLOT = 42;
|
||||
private static final int LEGGINGS_SLOT = 43;
|
||||
private static final int BOOTS_SLOT = 44;
|
||||
private static final int OFFHAND_SLOT = 45;
|
||||
|
||||
private Player player;
|
||||
private ItemStack[] items = new ItemStack[45];
|
||||
private ItemStack[] items = new ItemStack[TOTAL_INVENTORY_SIZE];
|
||||
|
||||
public PlayerInventory(Player player) {
|
||||
this.player = player;
|
||||
@ -18,28 +32,67 @@ public class PlayerInventory {
|
||||
Arrays.fill(items, ItemStack.AIR_ITEM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(int slot) {
|
||||
return this.items[slot];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemStack(int slot, ItemStack itemStack) {
|
||||
safeItemInsert(slot, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addItemStack(ItemStack itemStack) {
|
||||
synchronized (this) {
|
||||
for (int i = 0; i < items.length - 10; i++) {
|
||||
ItemStack item = items[i];
|
||||
if (item.isAir()) {
|
||||
setItemStack(i, itemStack);
|
||||
return true;
|
||||
} else if (itemStack.isSimilar(item)) {
|
||||
// TODO check max stack size
|
||||
int itemAmount = item.getAmount();
|
||||
if (itemAmount == 64)
|
||||
continue;
|
||||
int totalAmount = itemStack.getAmount() + itemAmount;
|
||||
if (totalAmount > 64) {
|
||||
item.setAmount((byte) 64);
|
||||
sendSlotRefresh((short) convertToPacketSlot(i), item);
|
||||
itemStack.setAmount((byte) (totalAmount - 64));
|
||||
} else {
|
||||
item.setAmount((byte) totalAmount);
|
||||
sendSlotRefresh((short) convertToPacketSlot(i), item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setHelmet(ItemStack itemStack) {
|
||||
safeItemInsert(5, itemStack);
|
||||
safeItemInsert(HELMET_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setChestplate(ItemStack itemStack) {
|
||||
safeItemInsert(6, itemStack);
|
||||
safeItemInsert(CHESTPLATE_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setLeggings(ItemStack itemStack) {
|
||||
safeItemInsert(7, itemStack);
|
||||
safeItemInsert(LEGGINGS_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setBoots(ItemStack itemStack) {
|
||||
safeItemInsert(8, itemStack);
|
||||
safeItemInsert(BOOTS_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setItemInMainHand(ItemStack itemStack) {
|
||||
safeItemInsert(player.getHeldSlot(), itemStack);
|
||||
}
|
||||
|
||||
public void setItemInOffHand(ItemStack itemStack) {
|
||||
safeItemInsert(OFFHAND_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
@ -49,13 +102,15 @@ public class PlayerInventory {
|
||||
|
||||
private void safeItemInsert(int slot, ItemStack itemStack) {
|
||||
synchronized (this) {
|
||||
this.items[slot] = itemStack == null ? ItemStack.AIR_ITEM : itemStack;
|
||||
itemStack = itemStack == null ? ItemStack.AIR_ITEM : itemStack;
|
||||
this.items[slot] = itemStack;
|
||||
System.out.println("INSERT: " + slot);
|
||||
sendSlotRefresh((short) slot, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setItemStack(int slot, int offset, ItemStack itemStack) {
|
||||
slot = convertSlot(slot, offset);
|
||||
// System.out.println("NEWSLOT: "+slot +" : "+itemStack.getItemId());
|
||||
safeItemInsert(slot, itemStack);
|
||||
}
|
||||
|
||||
@ -64,6 +119,7 @@ public class PlayerInventory {
|
||||
return this.items[slot];
|
||||
}
|
||||
|
||||
|
||||
protected int convertSlot(int slot, int offset) {
|
||||
final int rowSize = 9;
|
||||
slot -= offset;
|
||||
@ -72,27 +128,44 @@ public class PlayerInventory {
|
||||
} else {
|
||||
slot = slot + rowSize;
|
||||
}
|
||||
System.out.println("DEBUG: " + slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
private 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
|
||||
slot = slot;
|
||||
} else if (slot >= CRAFT_SLOT_1 && slot <= CRAFT_RESULT) { // Crafting 36-40
|
||||
slot = slot - 36;
|
||||
} else if (slot >= HELMET_SLOT && slot <= BOOTS_SLOT) { // Armor 41-44
|
||||
slot = slot - 36;
|
||||
} else if (slot == OFFHAND_SLOT) { // Off hand
|
||||
slot = 45;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
private void sendSlotRefresh(short slot, ItemStack itemStack) {
|
||||
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
||||
setSlotPacket.windowId = (byte) (slot > 35 && slot < TOTAL_INVENTORY_SIZE ? 0 : -2);
|
||||
setSlotPacket.slot = slot;
|
||||
setSlotPacket.itemStack = itemStack;
|
||||
player.getPlayerConnection().sendPacket(setSlotPacket);
|
||||
}
|
||||
|
||||
private WindowItemsPacket createWindowItemsPacket() {
|
||||
ItemStack[] convertedSlots = new ItemStack[45];
|
||||
ItemStack[] convertedSlots = new ItemStack[TOTAL_INVENTORY_SIZE];
|
||||
Arrays.fill(convertedSlots, ItemStack.AIR_ITEM); // TODO armor and craft
|
||||
|
||||
// Hotbar
|
||||
for (int i = 0; i < 9; i++) {
|
||||
convertedSlots[36 + i] = items[i];
|
||||
}
|
||||
|
||||
// Inventory
|
||||
for (int i = 10; i < 9 + 9 * 3; i++) {
|
||||
convertedSlots[i] = items[i];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
int slot = convertToPacketSlot(i);
|
||||
convertedSlots[slot] = items[i];
|
||||
}
|
||||
|
||||
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
||||
windowItemsPacket.windowId = 0;
|
||||
windowItemsPacket.count = 45;
|
||||
windowItemsPacket.count = TOTAL_INVENTORY_SIZE;
|
||||
windowItemsPacket.items = convertedSlots;
|
||||
return windowItemsPacket;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package fr.themode.minestom.item;
|
||||
|
||||
public class ItemStack implements Cloneable {
|
||||
public class ItemStack {
|
||||
|
||||
public static final ItemStack AIR_ITEM = new ItemStack(0, (byte) 1);
|
||||
|
||||
|
@ -143,9 +143,8 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
//System.out.println("HAHAHAHHAHHAH " + player.getUuid());
|
||||
|
||||
PlayerInventory inventory = player.getInventory();
|
||||
inventory.setItemStack(1, new ItemStack(1, (byte) 32));
|
||||
inventory.setItemStack(2, new ItemStack(1, (byte) 32));
|
||||
inventory.update();
|
||||
inventory.addItemStack(new ItemStack(1, (byte) 60));
|
||||
inventory.addItemStack(new ItemStack(1, (byte) 50));
|
||||
|
||||
Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre");
|
||||
inv.setItemStack(0, new ItemStack(1, (byte) 1));
|
||||
|
@ -52,7 +52,7 @@ public class ClientClickWindowPacket implements ClientPlayPacket {
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// Number key 1-9
|
||||
inventory.changeHeld(player, slot, button);
|
||||
break;
|
||||
case 3:
|
||||
// Middle click (only creative players in non-player inventories)
|
||||
|
Loading…
Reference in New Issue
Block a user