123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- 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;
- }
- }
|