package org.bukkit.craftbukkit.inventory; import net.minecraft.server.ChatComponentText; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryView; import net.minecraft.server.Container; import net.minecraft.server.EntityHuman; import net.minecraft.server.IInventory; import net.minecraft.server.PacketPlayOutOpenWindow; import net.minecraft.server.Slot; import net.minecraft.server.SlotShulkerBox; public class CraftContainer extends Container { private final InventoryView view; private InventoryType cachedType; private String cachedTitle; private final int cachedSize; public CraftContainer(InventoryView view, int id) { this.view = view; this.windowId = id; // TODO: Do we need to check that it really is a CraftInventory? IInventory top = ((CraftInventory) view.getTopInventory()).getInventory(); IInventory bottom = ((CraftInventory) view.getBottomInventory()).getInventory(); cachedType = view.getType(); cachedTitle = view.getTitle(); cachedSize = getSize(); setupSlots(top, bottom); } public CraftContainer(final Inventory inventory, final HumanEntity player, int id) { this(new InventoryView() { @Override public Inventory getTopInventory() { return inventory; } @Override public Inventory getBottomInventory() { return player.getInventory(); } @Override public HumanEntity getPlayer() { return player; } @Override public InventoryType getType() { return inventory.getType(); } }, id); } @Override public InventoryView getBukkitView() { return view; } private int getSize() { return view.getTopInventory().getSize(); } @Override public boolean c(EntityHuman entityhuman) { if (cachedType == view.getType() && cachedSize == getSize() && cachedTitle.equals(view.getTitle())) { return true; } // If the window type has changed for some reason, update the player // This method will be called every tick or something, so it's // as good a place as any to put something like this. boolean typeChanged = (cachedType != view.getType()); cachedType = view.getType(); cachedTitle = view.getTitle(); if (view.getPlayer() instanceof CraftPlayer) { CraftPlayer player = (CraftPlayer) view.getPlayer(); String type = getNotchInventoryType(cachedType); IInventory top = ((CraftInventory) view.getTopInventory()).getInventory(); IInventory bottom = ((CraftInventory) view.getBottomInventory()).getInventory(); this.b.clear(); this.c.clear(); if (typeChanged) { setupSlots(top, bottom); } int size = getSize(); player.getHandle().playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.windowId, type, new ChatComponentText(cachedTitle), size)); player.updateInventory(); } return true; } public static String getNotchInventoryType(InventoryType type) { switch (type) { case WORKBENCH: return "minecraft:crafting_table"; case FURNACE: return "minecraft:furnace"; case DISPENSER: return "minecraft:dispenser"; case ENCHANTING: return "minecraft:enchanting_table"; case BREWING: return "minecraft:brewing_stand"; case BEACON: return "minecraft:beacon"; case ANVIL: return "minecraft:anvil"; case HOPPER: return "minecraft:hopper"; case DROPPER: return "minecraft:dropper"; case SHULKER_BOX: return "minecraft:shulker_box"; default: return "minecraft:chest"; } } private void setupSlots(IInventory top, IInventory bottom) { switch (cachedType) { case CREATIVE: break; // TODO: This should be an error? case PLAYER: case CHEST: setupChest(top, bottom); break; case DISPENSER: case DROPPER: setupDispenser(top, bottom); break; case FURNACE: setupFurnace(top, bottom); break; case CRAFTING: // TODO: This should be an error? case WORKBENCH: setupWorkbench(top, bottom); break; case ENCHANTING: setupEnchanting(top, bottom); break; case BREWING: setupBrewing(top, bottom); break; case HOPPER: setupHopper(top, bottom); break; case ANVIL: setupAnvil(top, bottom); break; case BEACON: setupBeacon(top, bottom); break; case SHULKER_BOX: setupShulkerBox(top, bottom); break; } } private void setupChest(IInventory top, IInventory bottom) { int rows = top.getSize() / 9; int row; 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) { // This code copied from ContainerWorkbench 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; } }