ModInventory.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package me.km.inventory;
  2. import java.util.Arrays;
  3. import net.minecraft.inventory.Inventory;
  4. import net.minecraft.item.ItemStack;
  5. public class ModInventory extends Inventory {
  6. private static int modIds = 0;
  7. private final int modId;
  8. private final int allSlots;
  9. private final int rows;
  10. private final byte[] data;
  11. private final byte[] smallData;
  12. public ModInventory(byte[] data, int slots, int allSlots) {
  13. super(slots);
  14. this.modId = modIds++;
  15. this.allSlots = allSlots;
  16. this.rows = allSlots / 9 + (allSlots % 9 == 0 ? 0 : 1);
  17. this.data = data;
  18. this.smallData = deleteZeros(data);
  19. }
  20. private static int countZeros(String slots) {
  21. int i = 0;
  22. for(char c : slots.toCharArray()) {
  23. if(c == '0') {
  24. i++;
  25. }
  26. }
  27. return i;
  28. }
  29. private static byte[] deleteZeros(byte[] bytes) {
  30. int size = 0;
  31. for(byte b : bytes) {
  32. size += (b & 3) != 0 ? 1 : 0;
  33. size += (b & 12) != 0 ? 1 : 0;
  34. size += (b & 48) != 0 ? 1 : 0;
  35. size += (b & 192) != 0 ? 1 : 0;
  36. }
  37. size = (size >> 2) + ((size & 3) != 0 ? 1 : 0);
  38. byte[] b = new byte[size];
  39. byte current;
  40. int index = 0;
  41. int pos = 0;
  42. for(int i = 0; i < bytes.length; i++) {
  43. for(int j = 0; j < 8; j += 2) {
  44. current = (byte) ((bytes[i] >> j) & 3);
  45. if(current != 0) {
  46. b[index] |= current << pos;
  47. pos += 2;
  48. if(pos == 8) {
  49. pos = 0;
  50. index++;
  51. }
  52. }
  53. }
  54. }
  55. return b;
  56. }
  57. public ModInventory(String slots) {
  58. super(Math.min(54, slots.length() - countZeros(slots)));
  59. this.modId = modIds++;
  60. allSlots = Math.min(54, slots.length());
  61. this.rows = allSlots / 9 + (allSlots % 9 == 0 ? 0 : 1);
  62. this.data = new byte[14];
  63. int id;
  64. for(int i = 0; i < allSlots; i++) {
  65. id = Character.getNumericValue(slots.charAt(i));
  66. if(id > 3 || id < 0) {
  67. id = 0;
  68. }
  69. switch(i % 4) {
  70. case 0:
  71. data[i / 4] += id;
  72. break;
  73. case 1:
  74. data[i / 4] += id << 2;
  75. break;
  76. case 2:
  77. data[i / 4] += id << 4;
  78. break;
  79. case 3:
  80. data[i / 4] += id << 6;
  81. break;
  82. }
  83. }
  84. this.smallData = deleteZeros(data);
  85. }
  86. public ModInventory(int slots) {
  87. super(Math.max(9, Math.min(54, ((slots / 9) + ((slots % 9) == 0 ? 0 : 1)) * 9)));
  88. this.modId = modIds++;
  89. this.allSlots = super.getContainerSize();
  90. this.rows = allSlots / 9;
  91. this.data = new byte[14];
  92. // default is 3 to every 2 bits
  93. Arrays.fill(this.data, (byte) 0xFF);
  94. this.smallData = data;
  95. }
  96. public byte[] getData() {
  97. return data;
  98. }
  99. public int getRows() {
  100. return rows;
  101. }
  102. public int getSlotStatus(int slot) {
  103. if(slot < 0 || slot >= this.getContainerSize()) {
  104. return 1;
  105. }
  106. int index = Math.max(0, Math.min(smallData.length, slot / 4));
  107. switch(slot % 4) {
  108. case 0:
  109. return smallData[index] & 3;
  110. case 1:
  111. return (smallData[index] >> 2) & 3;
  112. case 2:
  113. return (smallData[index] >> 4) & 3;
  114. case 3:
  115. return (smallData[index] >> 6) & 3;
  116. }
  117. return 0;
  118. }
  119. public int getSlotStatus(int x, int y) {
  120. int slot = y * 9 + x;
  121. int index = Math.max(0, Math.min(13, slot / 4));
  122. switch(slot % 4) {
  123. case 0:
  124. return data[index] & 3;
  125. case 1:
  126. return (data[index] >> 2) & 3;
  127. case 2:
  128. return (data[index] >> 4) & 3;
  129. case 3:
  130. return (data[index] >> 6) & 3;
  131. }
  132. return 0;
  133. }
  134. public boolean isSlotValid(int x, int y) {
  135. return getSlotStatus(x, y) != 0;
  136. }
  137. public boolean shouldRenderOverlay(int x, int y) {
  138. int status = getSlotStatus(x, y);
  139. return status == 0 || status == 2;
  140. }
  141. public boolean shouldRenderDarker(int x, int y) {
  142. return getSlotStatus(x, y) == 3;
  143. }
  144. public int getModId() {
  145. return modId;
  146. }
  147. @Override
  148. public ItemStack addItem(ItemStack stack) {
  149. stack = stack.copy();
  150. this.moveToEqualItemStack(stack);
  151. if(stack.isEmpty()) {
  152. return ItemStack.EMPTY;
  153. } else {
  154. this.moveToEmptySlot(stack);
  155. return stack.isEmpty() ? ItemStack.EMPTY : stack;
  156. }
  157. }
  158. private void moveToEqualItemStack(ItemStack stack) {
  159. for(int i = 0; i < getContainerSize(); i++) {
  160. // ignore special fields
  161. if(getSlotStatus(i) != 1) {
  162. continue;
  163. }
  164. ItemStack slotStack = getItem(i);
  165. if(ItemStack.matches(slotStack, stack)) {
  166. this.mergeItemStacks(stack, slotStack);
  167. if(stack.isEmpty()) {
  168. return;
  169. }
  170. }
  171. }
  172. }
  173. private void mergeItemStacks(ItemStack stack, ItemStack slotStack) {
  174. int maxSize = Math.min(getMaxStackSize(), slotStack.getMaxStackSize());
  175. int maxMoveable = Math.min(stack.getCount(), maxSize - slotStack.getCount());
  176. if(maxMoveable > 0) {
  177. slotStack.grow(maxMoveable);
  178. stack.shrink(maxMoveable);
  179. setChanged();
  180. }
  181. }
  182. private void moveToEmptySlot(ItemStack stack) {
  183. for(int i = 0; i < getContainerSize(); i++) {
  184. // ignore special fields
  185. if(getSlotStatus(i) != 1) {
  186. continue;
  187. }
  188. ItemStack slotStack = getItem(i);
  189. if(slotStack.isEmpty()) {
  190. setItem(i, stack.copy());
  191. stack.setCount(0);
  192. return;
  193. }
  194. }
  195. }
  196. public int getAllSlots() {
  197. return allSlots;
  198. }
  199. }