package me.km.inventory; import java.util.Arrays; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; public class ModInventory extends Inventory { private static int modIds = 0; private final int modId; private final int allSlots; private final int rows; private final byte[] data; private final byte[] smallData; public ModInventory(byte[] data, int slots, int allSlots) { super(slots); this.modId = modIds++; this.allSlots = allSlots; this.rows = allSlots / 9 + (allSlots % 9 == 0 ? 0 : 1); this.data = data; this.smallData = deleteZeros(data); } private static int countZeros(String slots) { int i = 0; for(char c : slots.toCharArray()) { if(c == '0') { i++; } } return i; } private static byte[] deleteZeros(byte[] bytes) { int size = 0; for(byte b : bytes) { size += (b & 3) != 0 ? 1 : 0; size += (b & 12) != 0 ? 1 : 0; size += (b & 48) != 0 ? 1 : 0; size += (b & 192) != 0 ? 1 : 0; } size = (size >> 2) + ((size & 3) != 0 ? 1 : 0); byte[] b = new byte[size]; byte current; int index = 0; int pos = 0; for(int i = 0; i < bytes.length; i++) { for(int j = 0; j < 8; j += 2) { current = (byte) ((bytes[i] >> j) & 3); if(current != 0) { b[index] |= current << pos; pos += 2; if(pos == 8) { pos = 0; index++; } } } } return b; } public ModInventory(String slots) { super(Math.min(54, slots.length() - countZeros(slots))); this.modId = modIds++; allSlots = Math.min(54, slots.length()); this.rows = allSlots / 9 + (allSlots % 9 == 0 ? 0 : 1); this.data = new byte[14]; int id; for(int i = 0; i < allSlots; i++) { id = Character.getNumericValue(slots.charAt(i)); if(id > 3 || id < 0) { id = 0; } switch(i % 4) { case 0: data[i / 4] += id; break; case 1: data[i / 4] += id << 2; break; case 2: data[i / 4] += id << 4; break; case 3: data[i / 4] += id << 6; break; } } this.smallData = deleteZeros(data); } public ModInventory(int slots) { super(Math.max(9, Math.min(54, ((slots / 9) + ((slots % 9) == 0 ? 0 : 1)) * 9))); this.modId = modIds++; this.allSlots = super.getSizeInventory(); this.rows = allSlots / 9; this.data = new byte[14]; // default is 3 to every 2 bits Arrays.fill(this.data, (byte) 0xFF); this.smallData = data; } public byte[] getData() { return data; } public int getRows() { return rows; } public int getSlotStatus(int slot) { if(slot < 0 || slot >= this.getSizeInventory()) { return 1; } int index = Math.max(0, Math.min(smallData.length, slot / 4)); switch(slot % 4) { case 0: return smallData[index] & 3; case 1: return (smallData[index] >> 2) & 3; case 2: return (smallData[index] >> 4) & 3; case 3: return (smallData[index] >> 6) & 3; } return 0; } public int getSlotStatus(int x, int y) { int slot = y * 9 + x; int index = Math.max(0, Math.min(13, slot / 4)); switch(slot % 4) { case 0: return data[index] & 3; case 1: return (data[index] >> 2) & 3; case 2: return (data[index] >> 4) & 3; case 3: return (data[index] >> 6) & 3; } return 0; } public boolean isSlotValid(int x, int y) { return getSlotStatus(x, y) != 0; } public boolean shouldRenderOverlay(int x, int y) { int status = getSlotStatus(x, y); return status == 0 || status == 2; } public boolean shouldRenderDarker(int x, int y) { return getSlotStatus(x, y) == 3; } public int getModId() { return modId; } @Override public ItemStack addItem(ItemStack stack) { stack = stack.copy(); this.moveToEqualItemStack(stack); if(stack.isEmpty()) { return ItemStack.EMPTY; } else { this.moveToEmptySlot(stack); return stack.isEmpty() ? ItemStack.EMPTY : stack; } } private void moveToEqualItemStack(ItemStack stack) { for(int i = 0; i < getSizeInventory(); i++) { // ignore special fields if(getSlotStatus(i) != 1) { continue; } ItemStack slotStack = getStackInSlot(i); if(ItemStack.areItemsEqual(slotStack, stack)) { this.mergeItemStacks(stack, slotStack); if(stack.isEmpty()) { return; } } } } private void mergeItemStacks(ItemStack stack, ItemStack slotStack) { int maxSize = Math.min(getInventoryStackLimit(), slotStack.getMaxStackSize()); int maxMoveable = Math.min(stack.getCount(), maxSize - slotStack.getCount()); if(maxMoveable > 0) { slotStack.grow(maxMoveable); stack.shrink(maxMoveable); markDirty(); } } private void moveToEmptySlot(ItemStack stack) { for(int i = 0; i < getSizeInventory(); i++) { // ignore special fields if(getSlotStatus(i) != 1) { continue; } ItemStack slotStack = getStackInSlot(i); if(slotStack.isEmpty()) { setInventorySlotContents(i, stack.copy()); stack.setCount(0); return; } } } public int getAllSlots() { return allSlots; } }