mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 11:07:53 +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);
|
refreshOpenInventory(null);
|
||||||
}
|
}
|
||||||
playerConnection.sendPacket(closeWindowPacket);
|
playerConnection.sendPacket(closeWindowPacket);
|
||||||
|
inventory.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshGameMode(GameMode gameMode) {
|
public void refreshGameMode(GameMode gameMode) {
|
||||||
|
@ -2,6 +2,7 @@ package fr.themode.minestom.inventory;
|
|||||||
|
|
||||||
import fr.themode.minestom.entity.Player;
|
import fr.themode.minestom.entity.Player;
|
||||||
import fr.themode.minestom.item.ItemStack;
|
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.packet.server.play.WindowItemsPacket;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -11,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class Inventory implements InventoryClickHandler {
|
public class Inventory implements InventoryModifier, InventoryClickHandler {
|
||||||
|
|
||||||
private static AtomicInteger lastInventoryId = new AtomicInteger();
|
private static AtomicInteger lastInventoryId = new AtomicInteger();
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setItemStack(int slot, ItemStack itemStack) {
|
public void setItemStack(int slot, ItemStack itemStack) {
|
||||||
if (slot < 0 || slot > inventoryType.getAdditionalSlot())
|
if (slot < 0 || slot > inventoryType.getAdditionalSlot())
|
||||||
throw new IllegalArgumentException(inventoryType.toString() + " does not have slot " + slot);
|
throw new IllegalArgumentException(inventoryType.toString() + " does not have slot " + slot);
|
||||||
@ -59,6 +61,12 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
safeItemInsert(slot, itemStack);
|
safeItemInsert(slot, itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addItemStack(ItemStack itemStack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ItemStack getItemStack(int slot) {
|
public ItemStack getItemStack(int slot) {
|
||||||
return itemStacks[slot];
|
return itemStacks[slot];
|
||||||
}
|
}
|
||||||
@ -88,7 +96,13 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
|
|
||||||
private void safeItemInsert(int slot, ItemStack itemStack) {
|
private void safeItemInsert(int slot, ItemStack itemStack) {
|
||||||
synchronized (this) {
|
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();
|
resultCursor = cursorItem.clone();
|
||||||
resultClicked = clicked.clone();
|
resultClicked = clicked.clone();
|
||||||
int amount = cursorItem.getAmount() + clicked.getAmount();
|
int amount = cursorItem.getAmount() + clicked.getAmount();
|
||||||
if (amount > 100) {
|
if (amount > 64) {
|
||||||
resultCursor.setAmount((byte) (amount - 100));
|
resultCursor.setAmount((byte) (amount - 64));
|
||||||
resultClicked.setAmount((byte) 100);
|
resultClicked.setAmount((byte) 64);
|
||||||
} else {
|
} else {
|
||||||
resultCursor = ItemStack.AIR_ITEM;
|
resultCursor = ItemStack.AIR_ITEM;
|
||||||
resultClicked.setAmount((byte) amount);
|
resultClicked.setAmount((byte) amount);
|
||||||
@ -140,11 +154,11 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
if (isInWindow) {
|
if (isInWindow) {
|
||||||
setItemStack(slot, resultClicked);
|
setItemStack(slot, resultClicked);
|
||||||
setCursorPlayerItem(player, resultCursor);
|
setCursorPlayerItem(player, resultCursor);
|
||||||
updateItems();
|
//updateItems();
|
||||||
} else {
|
} else {
|
||||||
playerInventory.setItemStack(slot, offset, resultClicked);
|
playerInventory.setItemStack(slot, offset, resultClicked);
|
||||||
setCursorPlayerItem(player, resultCursor);
|
setCursorPlayerItem(player, resultCursor);
|
||||||
playerInventory.update();
|
//playerInventory.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +179,7 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
resultCursor = cursorItem.clone();
|
resultCursor = cursorItem.clone();
|
||||||
resultClicked = clicked.clone();
|
resultClicked = clicked.clone();
|
||||||
int amount = clicked.getAmount() + 1;
|
int amount = clicked.getAmount() + 1;
|
||||||
if (amount > 100) {
|
if (amount > 64) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
resultCursor = cursorItem.clone();
|
resultCursor = cursorItem.clone();
|
||||||
@ -200,11 +214,9 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
if (isInWindow) {
|
if (isInWindow) {
|
||||||
setItemStack(slot, resultClicked);
|
setItemStack(slot, resultClicked);
|
||||||
setCursorPlayerItem(player, resultCursor);
|
setCursorPlayerItem(player, resultCursor);
|
||||||
updateItems();
|
|
||||||
} else {
|
} else {
|
||||||
playerInventory.setItemStack(slot, offset, resultClicked);
|
playerInventory.setItemStack(slot, offset, resultClicked);
|
||||||
setCursorPlayerItem(player, resultCursor);
|
setCursorPlayerItem(player, resultCursor);
|
||||||
playerInventory.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +227,41 @@ public class Inventory implements InventoryClickHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void changeHeld(Player player, int slot, int key) {
|
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
|
@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.entity.Player;
|
||||||
import fr.themode.minestom.item.ItemStack;
|
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.packet.server.play.WindowItemsPacket;
|
||||||
import fr.themode.minestom.net.player.PlayerConnection;
|
import fr.themode.minestom.net.player.PlayerConnection;
|
||||||
|
|
||||||
import java.util.Arrays;
|
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 Player player;
|
||||||
private ItemStack[] items = new ItemStack[45];
|
private ItemStack[] items = new ItemStack[TOTAL_INVENTORY_SIZE];
|
||||||
|
|
||||||
public PlayerInventory(Player player) {
|
public PlayerInventory(Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -18,28 +32,67 @@ public class PlayerInventory {
|
|||||||
Arrays.fill(items, ItemStack.AIR_ITEM);
|
Arrays.fill(items, ItemStack.AIR_ITEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ItemStack getItemStack(int slot) {
|
public ItemStack getItemStack(int slot) {
|
||||||
return this.items[slot];
|
return this.items[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setItemStack(int slot, ItemStack itemStack) {
|
public void setItemStack(int slot, ItemStack itemStack) {
|
||||||
safeItemInsert(slot, 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) {
|
public void setHelmet(ItemStack itemStack) {
|
||||||
safeItemInsert(5, itemStack);
|
safeItemInsert(HELMET_SLOT, itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChestplate(ItemStack itemStack) {
|
public void setChestplate(ItemStack itemStack) {
|
||||||
safeItemInsert(6, itemStack);
|
safeItemInsert(CHESTPLATE_SLOT, itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLeggings(ItemStack itemStack) {
|
public void setLeggings(ItemStack itemStack) {
|
||||||
safeItemInsert(7, itemStack);
|
safeItemInsert(LEGGINGS_SLOT, itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBoots(ItemStack 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() {
|
public void update() {
|
||||||
@ -49,13 +102,15 @@ public class PlayerInventory {
|
|||||||
|
|
||||||
private void safeItemInsert(int slot, ItemStack itemStack) {
|
private void safeItemInsert(int slot, ItemStack itemStack) {
|
||||||
synchronized (this) {
|
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) {
|
protected void setItemStack(int slot, int offset, ItemStack itemStack) {
|
||||||
slot = convertSlot(slot, offset);
|
slot = convertSlot(slot, offset);
|
||||||
// System.out.println("NEWSLOT: "+slot +" : "+itemStack.getItemId());
|
|
||||||
safeItemInsert(slot, itemStack);
|
safeItemInsert(slot, itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +119,7 @@ public class PlayerInventory {
|
|||||||
return this.items[slot];
|
return this.items[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected int convertSlot(int slot, int offset) {
|
protected int convertSlot(int slot, int offset) {
|
||||||
final int rowSize = 9;
|
final int rowSize = 9;
|
||||||
slot -= offset;
|
slot -= offset;
|
||||||
@ -72,27 +128,44 @@ public class PlayerInventory {
|
|||||||
} else {
|
} else {
|
||||||
slot = slot + rowSize;
|
slot = slot + rowSize;
|
||||||
}
|
}
|
||||||
System.out.println("DEBUG: " + slot);
|
|
||||||
return 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() {
|
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
|
Arrays.fill(convertedSlots, ItemStack.AIR_ITEM); // TODO armor and craft
|
||||||
|
|
||||||
// Hotbar
|
for (int i = 0; i < items.length; i++) {
|
||||||
for (int i = 0; i < 9; i++) {
|
int slot = convertToPacketSlot(i);
|
||||||
convertedSlots[36 + i] = items[i];
|
convertedSlots[slot] = items[i];
|
||||||
}
|
|
||||||
|
|
||||||
// Inventory
|
|
||||||
for (int i = 10; i < 9 + 9 * 3; i++) {
|
|
||||||
convertedSlots[i] = items[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
||||||
windowItemsPacket.windowId = 0;
|
windowItemsPacket.windowId = 0;
|
||||||
windowItemsPacket.count = 45;
|
windowItemsPacket.count = TOTAL_INVENTORY_SIZE;
|
||||||
windowItemsPacket.items = convertedSlots;
|
windowItemsPacket.items = convertedSlots;
|
||||||
return windowItemsPacket;
|
return windowItemsPacket;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package fr.themode.minestom.item;
|
package fr.themode.minestom.item;
|
||||||
|
|
||||||
public class ItemStack implements Cloneable {
|
public class ItemStack {
|
||||||
|
|
||||||
public static final ItemStack AIR_ITEM = new ItemStack(0, (byte) 1);
|
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());
|
//System.out.println("HAHAHAHHAHHAH " + player.getUuid());
|
||||||
|
|
||||||
PlayerInventory inventory = player.getInventory();
|
PlayerInventory inventory = player.getInventory();
|
||||||
inventory.setItemStack(1, new ItemStack(1, (byte) 32));
|
inventory.addItemStack(new ItemStack(1, (byte) 60));
|
||||||
inventory.setItemStack(2, new ItemStack(1, (byte) 32));
|
inventory.addItemStack(new ItemStack(1, (byte) 50));
|
||||||
inventory.update();
|
|
||||||
|
|
||||||
Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre");
|
Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre");
|
||||||
inv.setItemStack(0, new ItemStack(1, (byte) 1));
|
inv.setItemStack(0, new ItemStack(1, (byte) 1));
|
||||||
|
@ -52,7 +52,7 @@ public class ClientClickWindowPacket implements ClientPlayPacket {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// Number key 1-9
|
inventory.changeHeld(player, slot, button);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// Middle click (only creative players in non-player inventories)
|
// Middle click (only creative players in non-player inventories)
|
||||||
|
Loading…
Reference in New Issue
Block a user