mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-01 12:41:50 +01:00
SPIGOT-1107: Shift clicking and delegation for custom inventories
PR #398
This commit is contained in:
parent
357b573a19
commit
79e55b6dcf
2 changed files with 45 additions and 239 deletions
|
@ -271,7 +271,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||||
|
|
||||||
private void openCustomInventory(Inventory inventory, EntityPlayer player, String windowType) {
|
private void openCustomInventory(Inventory inventory, EntityPlayer player, String windowType) {
|
||||||
if (player.playerConnection == null) return;
|
if (player.playerConnection == null) return;
|
||||||
Container container = new CraftContainer(inventory, this, player.nextContainerCounter());
|
Container container = new CraftContainer(inventory, this.getHandle(), player.nextContainerCounter());
|
||||||
|
|
||||||
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||||
if(container == null) return;
|
if(container == null) return;
|
||||||
|
@ -345,7 +345,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||||
if (inventory instanceof CraftInventoryView) {
|
if (inventory instanceof CraftInventoryView) {
|
||||||
container = ((CraftInventoryView) inventory).getHandle();
|
container = ((CraftInventoryView) inventory).getHandle();
|
||||||
} else {
|
} else {
|
||||||
container = new CraftContainer(inventory, player.nextContainerCounter());
|
container = new CraftContainer(inventory, this.getHandle(), player.nextContainerCounter());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger an INVENTORY_OPEN event
|
// Trigger an INVENTORY_OPEN event
|
||||||
|
|
|
@ -8,32 +8,43 @@ import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryView;
|
import org.bukkit.inventory.InventoryView;
|
||||||
|
|
||||||
import net.minecraft.server.Container;
|
import net.minecraft.server.Container;
|
||||||
|
import net.minecraft.server.ContainerAnvil;
|
||||||
|
import net.minecraft.server.ContainerBeacon;
|
||||||
|
import net.minecraft.server.ContainerBrewingStand;
|
||||||
|
import net.minecraft.server.ContainerChest;
|
||||||
|
import net.minecraft.server.ContainerDispenser;
|
||||||
|
import net.minecraft.server.ContainerEnchantTable;
|
||||||
|
import net.minecraft.server.ContainerFurnace;
|
||||||
|
import net.minecraft.server.ContainerHopper;
|
||||||
|
import net.minecraft.server.ContainerShulkerBox;
|
||||||
|
import net.minecraft.server.ContainerWorkbench;
|
||||||
import net.minecraft.server.EntityHuman;
|
import net.minecraft.server.EntityHuman;
|
||||||
import net.minecraft.server.IInventory;
|
import net.minecraft.server.IInventory;
|
||||||
|
import net.minecraft.server.ItemStack;
|
||||||
import net.minecraft.server.PacketPlayOutOpenWindow;
|
import net.minecraft.server.PacketPlayOutOpenWindow;
|
||||||
import net.minecraft.server.Slot;
|
import net.minecraft.server.PlayerInventory;
|
||||||
import net.minecraft.server.SlotShulkerBox;
|
|
||||||
|
|
||||||
public class CraftContainer extends Container {
|
public class CraftContainer extends Container {
|
||||||
|
|
||||||
private final InventoryView view;
|
private final InventoryView view;
|
||||||
private InventoryType cachedType;
|
private InventoryType cachedType;
|
||||||
private String cachedTitle;
|
private String cachedTitle;
|
||||||
|
private Container delegate;
|
||||||
private final int cachedSize;
|
private final int cachedSize;
|
||||||
|
|
||||||
public CraftContainer(InventoryView view, int id) {
|
public CraftContainer(InventoryView view, EntityHuman player, int id) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.windowId = id;
|
this.windowId = id;
|
||||||
// TODO: Do we need to check that it really is a CraftInventory?
|
// TODO: Do we need to check that it really is a CraftInventory?
|
||||||
IInventory top = ((CraftInventory) view.getTopInventory()).getInventory();
|
IInventory top = ((CraftInventory) view.getTopInventory()).getInventory();
|
||||||
IInventory bottom = ((CraftInventory) view.getBottomInventory()).getInventory();
|
PlayerInventory bottom = (PlayerInventory) ((CraftInventory) view.getBottomInventory()).getInventory();
|
||||||
cachedType = view.getType();
|
cachedType = view.getType();
|
||||||
cachedTitle = view.getTitle();
|
cachedTitle = view.getTitle();
|
||||||
cachedSize = getSize();
|
cachedSize = getSize();
|
||||||
setupSlots(top, bottom);
|
setupSlots(top, bottom, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CraftContainer(final Inventory inventory, final HumanEntity player, int id) {
|
public CraftContainer(final Inventory inventory, final EntityHuman player, int id) {
|
||||||
this(new InventoryView() {
|
this(new InventoryView() {
|
||||||
@Override
|
@Override
|
||||||
public Inventory getTopInventory() {
|
public Inventory getTopInventory() {
|
||||||
|
@ -42,19 +53,19 @@ public class CraftContainer extends Container {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Inventory getBottomInventory() {
|
public Inventory getBottomInventory() {
|
||||||
return player.getInventory();
|
return getPlayer().getInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HumanEntity getPlayer() {
|
public HumanEntity getPlayer() {
|
||||||
return player;
|
return player.getBukkitEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InventoryType getType() {
|
public InventoryType getType() {
|
||||||
return inventory.getType();
|
return inventory.getType();
|
||||||
}
|
}
|
||||||
}, id);
|
}, player, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,11 +92,11 @@ public class CraftContainer extends Container {
|
||||||
CraftPlayer player = (CraftPlayer) view.getPlayer();
|
CraftPlayer player = (CraftPlayer) view.getPlayer();
|
||||||
String type = getNotchInventoryType(cachedType);
|
String type = getNotchInventoryType(cachedType);
|
||||||
IInventory top = ((CraftInventory) view.getTopInventory()).getInventory();
|
IInventory top = ((CraftInventory) view.getTopInventory()).getInventory();
|
||||||
IInventory bottom = ((CraftInventory) view.getBottomInventory()).getInventory();
|
PlayerInventory bottom = (PlayerInventory) ((CraftInventory) view.getBottomInventory()).getInventory();
|
||||||
this.b.clear();
|
this.b.clear();
|
||||||
this.c.clear();
|
this.c.clear();
|
||||||
if (typeChanged) {
|
if (typeChanged) {
|
||||||
setupSlots(top, bottom);
|
setupSlots(top, bottom, player.getHandle());
|
||||||
}
|
}
|
||||||
int size = getSize();
|
int size = getSize();
|
||||||
player.getHandle().playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.windowId, type, new ChatComponentText(cachedTitle), size));
|
player.getHandle().playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.windowId, type, new ChatComponentText(cachedTitle), size));
|
||||||
|
@ -121,263 +132,58 @@ public class CraftContainer extends Container {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupSlots(IInventory top, IInventory bottom) {
|
private void setupSlots(IInventory top, PlayerInventory bottom, EntityHuman entityhuman) {
|
||||||
switch (cachedType) {
|
switch (cachedType) {
|
||||||
case CREATIVE:
|
case CREATIVE:
|
||||||
break; // TODO: This should be an error?
|
break; // TODO: This should be an error?
|
||||||
case PLAYER:
|
case PLAYER:
|
||||||
case CHEST:
|
case CHEST:
|
||||||
setupChest(top, bottom);
|
delegate = new ContainerChest(bottom, top, entityhuman);
|
||||||
break;
|
break;
|
||||||
case DISPENSER:
|
case DISPENSER:
|
||||||
case DROPPER:
|
case DROPPER:
|
||||||
setupDispenser(top, bottom);
|
delegate = new ContainerDispenser(bottom, top);
|
||||||
break;
|
break;
|
||||||
case FURNACE:
|
case FURNACE:
|
||||||
setupFurnace(top, bottom);
|
delegate = new ContainerFurnace(bottom, top);
|
||||||
break;
|
break;
|
||||||
case CRAFTING: // TODO: This should be an error?
|
case CRAFTING: // TODO: This should be an error?
|
||||||
case WORKBENCH:
|
case WORKBENCH:
|
||||||
setupWorkbench(top, bottom);
|
delegate = new ContainerWorkbench(bottom, entityhuman.world, entityhuman.getChunkCoordinates());
|
||||||
break;
|
break;
|
||||||
case ENCHANTING:
|
case ENCHANTING:
|
||||||
setupEnchanting(top, bottom);
|
delegate = new ContainerEnchantTable(bottom, entityhuman.world, entityhuman.getChunkCoordinates());
|
||||||
break;
|
break;
|
||||||
case BREWING:
|
case BREWING:
|
||||||
setupBrewing(top, bottom);
|
delegate = new ContainerBrewingStand(bottom, top);
|
||||||
break;
|
break;
|
||||||
case HOPPER:
|
case HOPPER:
|
||||||
setupHopper(top, bottom);
|
delegate = new ContainerHopper(bottom, top, entityhuman);
|
||||||
break;
|
break;
|
||||||
case ANVIL:
|
case ANVIL:
|
||||||
setupAnvil(top, bottom);
|
delegate = new ContainerAnvil(bottom, entityhuman.world, entityhuman.getChunkCoordinates(), entityhuman);
|
||||||
break;
|
break;
|
||||||
case BEACON:
|
case BEACON:
|
||||||
setupBeacon(top, bottom);
|
delegate = new ContainerBeacon(bottom, top);
|
||||||
break;
|
break;
|
||||||
case SHULKER_BOX:
|
case SHULKER_BOX:
|
||||||
setupShulkerBox(top, bottom);
|
delegate = new ContainerShulkerBox(bottom, top, entityhuman);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (delegate != null) {
|
||||||
|
this.b = delegate.b; // PAIL: items
|
||||||
|
this.c = delegate.c; // PAIL: slots
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupChest(IInventory top, IInventory bottom) {
|
@Override
|
||||||
int rows = top.getSize() / 9;
|
public ItemStack b(EntityHuman entityhuman, int i) { // PAIL: shiftClick
|
||||||
int row;
|
return (delegate != null) ? delegate.b(entityhuman, i) : super.b(entityhuman, i);
|
||||||
int col;
|
|
||||||
// This code copied from ContainerChest
|
|
||||||
int i = (rows - 4) * 18;
|
|
||||||
for (row = 0; row < rows; ++row) {
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(top, col + row * 9, 8 + col * 18, 18 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 103 + row * 18 + i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col, 8 + col * 18, 161 + i));
|
|
||||||
}
|
|
||||||
// End copy from ContainerChest
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWorkbench(IInventory top, IInventory bottom) {
|
@Override
|
||||||
// This code copied from ContainerWorkbench
|
public boolean a(EntityHuman entity) { // PAIL: canUse
|
||||||
this.a(new Slot(top, 0, 124, 35));
|
|
||||||
|
|
||||||
int row;
|
|
||||||
int col;
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (col = 0; col < 3; ++col) {
|
|
||||||
this.a(new Slot(top, 1 + col + row * 3, 30 + col * 18, 17 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 84 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col, 8 + col * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerWorkbench
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupFurnace(IInventory top, IInventory bottom) {
|
|
||||||
// This code copied from ContainerFurnace
|
|
||||||
this.a(new Slot(top, 0, 56, 17));
|
|
||||||
this.a(new Slot(top, 1, 56, 53));
|
|
||||||
this.a(new Slot(top, 2, 116, 35));
|
|
||||||
|
|
||||||
int row;
|
|
||||||
int col;
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 84 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col, 8 + col * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerFurnace
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupDispenser(IInventory top, IInventory bottom) {
|
|
||||||
// This code copied from ContainerDispenser
|
|
||||||
int row;
|
|
||||||
int col;
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (col = 0; col < 3; ++col) {
|
|
||||||
this.a(new Slot(top, col + row * 3, 61 + col * 18, 17 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 84 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (col = 0; col < 9; ++col) {
|
|
||||||
this.a(new Slot(bottom, col, 8 + col * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerDispenser
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupEnchanting(IInventory top, IInventory bottom) {
|
|
||||||
// This code copied from ContainerEnchantTable
|
|
||||||
this.a((new Slot(top, 0, 15, 47)));
|
|
||||||
this.a((new Slot(top, 0, 35, 47)));
|
|
||||||
|
|
||||||
int row;
|
|
||||||
|
|
||||||
for (row = 0; row < 3; ++row) {
|
|
||||||
for (int i1 = 0; i1 < 9; ++i1) {
|
|
||||||
this.a(new Slot(bottom, i1 + row * 9 + 9, 8 + i1 * 18, 84 + row * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (row = 0; row < 9; ++row) {
|
|
||||||
this.a(new Slot(bottom, row, 8 + row * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerEnchantTable
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupBrewing(IInventory top, IInventory bottom) {
|
|
||||||
// This code copied from ContainerBrewingStand
|
|
||||||
this.a(new Slot(top, 0, 56, 46));
|
|
||||||
this.a(new Slot(top, 1, 79, 53));
|
|
||||||
this.a(new Slot(top, 2, 102, 46));
|
|
||||||
this.a(new Slot(top, 3, 79, 17));
|
|
||||||
this.a(new Slot(top, 4, 17, 17));
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
for (int j = 0; j < 9; ++j) {
|
|
||||||
this.a(new Slot(bottom, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 9; ++i) {
|
|
||||||
this.a(new Slot(bottom, i, 8 + i * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerBrewingStand
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupHopper(IInventory top, IInventory bottom) {
|
|
||||||
// This code copied from ContainerHopper
|
|
||||||
byte b0 = 51;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < top.getSize(); ++i) {
|
|
||||||
this.a(new Slot(top, i, 44 + i * 18, 20));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
for (int j = 0; j < 9; ++j) {
|
|
||||||
this.a(new Slot(bottom, j + i * 9 + 9, 8 + j * 18, i * 18 + b0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 9; ++i) {
|
|
||||||
this.a(new Slot(bottom, i, 8 + i * 18, 58 + b0));
|
|
||||||
}
|
|
||||||
// End copy from ContainerHopper
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupAnvil(IInventory top, IInventory bottom) {
|
|
||||||
// This code copied from ContainerAnvil
|
|
||||||
this.a(new Slot(top, 0, 27, 47));
|
|
||||||
this.a(new Slot(top, 1, 76, 47));
|
|
||||||
this.a(new Slot(top, 2, 134, 47));
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
for (int j = 0; j < 9; ++j) {
|
|
||||||
this.a(new Slot(bottom, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 9; ++i) {
|
|
||||||
this.a(new Slot(bottom, i, 8 + i * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerAnvil
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupBeacon(IInventory top, IInventory bottom) {
|
|
||||||
// This code is copied from ContainerBeacon
|
|
||||||
this.a(new Slot(top, 0, 136, 110));
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
for (int j = 0; j < 9; ++j) {
|
|
||||||
this.a(new Slot(bottom, j + i * 9 + 9, 36 + j * 18, 137 + i * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 9; ++i) {
|
|
||||||
this.a(new Slot(bottom, i, 36 + i * 18, 195));
|
|
||||||
}
|
|
||||||
// End copy from ContainerBeacon
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupShulkerBox(IInventory top, IInventory bottom) {
|
|
||||||
// This code is copied from ContainerShulkerBox
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
for (j = 0; j < 9; ++j) {
|
|
||||||
this.a((Slot) (new SlotShulkerBox(top, j + i * 9, 8 + j * 18, 18 + i * 18)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
for (j = 0; j < 9; ++j) {
|
|
||||||
this.a(new Slot(bottom, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 9; ++i) {
|
|
||||||
this.a(new Slot(bottom, i, 8 + i * 18, 142));
|
|
||||||
}
|
|
||||||
// End copy from ContainerShulkerBox
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a(EntityHuman entity) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue