InputSlotCrafter.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Roughly Enough Items by Danielshe.
  3. * Licensed under the MIT License.
  4. */
  5. package me.shedaniel.rei.server;
  6. import com.google.common.collect.Lists;
  7. import it.unimi.dsi.fastutil.ints.IntArrayList;
  8. import it.unimi.dsi.fastutil.ints.IntList;
  9. import it.unimi.dsi.fastutil.ints.IntListIterator;
  10. import net.minecraft.container.Container;
  11. import net.minecraft.container.Slot;
  12. import net.minecraft.entity.player.PlayerInventory;
  13. import net.minecraft.inventory.Inventory;
  14. import net.minecraft.item.ItemStack;
  15. import net.minecraft.recipe.Ingredient;
  16. import net.minecraft.server.network.ServerPlayerEntity;
  17. import net.minecraft.util.DefaultedList;
  18. import net.minecraft.util.Identifier;
  19. import java.util.Comparator;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. public class InputSlotCrafter<C extends Inventory> implements RecipeGridAligner<Integer> {
  24. protected Container craftingContainer;
  25. protected ContainerInfo containerInfo;
  26. protected PlayerInventory inventory;
  27. private InputSlotCrafter(Container craftingContainer, ContainerInfo containerInfo) {
  28. this.craftingContainer = craftingContainer;
  29. this.containerInfo = containerInfo;
  30. }
  31. public static <C extends Inventory> void start(Identifier category, Container craftingContainer_1, ServerPlayerEntity player, Map<Integer, List<ItemStack>> map, boolean hasShift) {
  32. ContainerInfo containerInfo = ContainerInfoHandler.getContainerInfo(category, craftingContainer_1.getClass());
  33. new InputSlotCrafter<C>(craftingContainer_1, containerInfo).fillInputSlots(player, map, hasShift);
  34. }
  35. private void fillInputSlots(ServerPlayerEntity player, Map<Integer, List<ItemStack>> map, boolean hasShift) {
  36. this.inventory = player.inventory;
  37. if (this.canReturnInputs() || player.isCreative()) {
  38. // Return the already placed items on the grid
  39. this.returnInputs();
  40. RecipeFinder recipeFinder = new RecipeFinder();
  41. recipeFinder.clear();
  42. for (ItemStack stack : player.inventory.main) {
  43. recipeFinder.addNormalItem(stack);
  44. }
  45. this.containerInfo.populateRecipeFinder(craftingContainer, recipeFinder);
  46. DefaultedList<Ingredient> ingredients = DefaultedList.of();
  47. map.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).forEach(entry -> {
  48. ingredients.add(Ingredient.ofStacks(entry.getValue().toArray(new ItemStack[0])));
  49. });
  50. if (recipeFinder.findRecipe(ingredients, (IntList) null)) {
  51. this.fillInputSlots(recipeFinder, ingredients, hasShift);
  52. } else {
  53. this.returnInputs();
  54. craftingContainer.sendContentUpdates();
  55. throw new NullPointerException();
  56. }
  57. craftingContainer.sendContentUpdates();
  58. }
  59. }
  60. @Override
  61. public void acceptAlignedInput(Iterator<Integer> iterator_1, int int_1, int int_2, int int_3, int int_4) {
  62. Slot slot_1 = this.craftingContainer.getSlot(int_1);
  63. ItemStack itemStack_1 = net.minecraft.recipe.RecipeFinder.getStackFromId((Integer) iterator_1.next());
  64. if (!itemStack_1.isEmpty()) {
  65. for (int int_5 = 0; int_5 < int_2; ++int_5) {
  66. this.fillInputSlot(slot_1, itemStack_1);
  67. }
  68. }
  69. }
  70. protected void fillInputSlot(Slot slot_1, ItemStack itemStack_1) {
  71. int int_1 = this.inventory.method_7371(itemStack_1);
  72. if (int_1 != -1) {
  73. ItemStack itemStack_2 = this.inventory.getInvStack(int_1).copy();
  74. if (!itemStack_2.isEmpty()) {
  75. if (itemStack_2.getCount() > 1) {
  76. this.inventory.takeInvStack(int_1, 1);
  77. } else {
  78. this.inventory.removeInvStack(int_1);
  79. }
  80. itemStack_2.setCount(1);
  81. if (slot_1.getStack().isEmpty()) {
  82. slot_1.setStack(itemStack_2);
  83. } else {
  84. slot_1.getStack().increment(1);
  85. }
  86. }
  87. }
  88. }
  89. @SuppressWarnings("deprecation")
  90. protected void fillInputSlots(RecipeFinder recipeFinder, DefaultedList<Ingredient> ingredients, boolean hasShift) {
  91. // boolean boolean_2 = this.craftingContainer.matches(recipe_1);
  92. boolean boolean_2 = false;
  93. int int_1 = recipeFinder.countRecipeCrafts(ingredients, (IntList) null);
  94. int int_2;
  95. if (boolean_2) {
  96. for (int_2 = 0; int_2 < this.containerInfo.getCraftingHeight(craftingContainer) * this.containerInfo.getCraftingWidth(craftingContainer) + 1; ++int_2) {
  97. if (int_2 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) {
  98. ItemStack itemStack_1 = this.craftingContainer.getSlot(int_2).getStack();
  99. if (!itemStack_1.isEmpty() && Math.min(int_1, itemStack_1.getMaxCount()) < itemStack_1.getCount() + 1) {
  100. return;
  101. }
  102. }
  103. }
  104. }
  105. int_2 = this.getAmountToFill(hasShift, int_1, boolean_2);
  106. IntList intList_1 = new IntArrayList();
  107. if (recipeFinder.findRecipe(ingredients, intList_1, int_2)) {
  108. int int_4 = int_2;
  109. IntListIterator var8 = intList_1.iterator();
  110. while (var8.hasNext()) {
  111. int int_5 = (Integer) var8.next();
  112. int int_6 = RecipeFinder.getStackFromId(int_5).getMaxCount();
  113. if (int_6 < int_4) {
  114. int_4 = int_6;
  115. }
  116. }
  117. if (recipeFinder.findRecipe(ingredients, intList_1, int_4)) {
  118. this.returnInputs();
  119. this.alignRecipeToGrid(this.containerInfo.getCraftingWidth(craftingContainer), this.containerInfo.getCraftingHeight(craftingContainer), this.containerInfo.getCraftingResultSlotIndex(craftingContainer), ingredients, intList_1.iterator(), int_4);
  120. }
  121. }
  122. }
  123. protected int getAmountToFill(boolean hasShift, int int_1, boolean boolean_2) {
  124. int int_2 = 1;
  125. if (hasShift) {
  126. int_2 = int_1;
  127. } else if (boolean_2) {
  128. int_2 = 64;
  129. for (int int_3 = 0; int_3 < this.containerInfo.getCraftingWidth(craftingContainer) * this.containerInfo.getCraftingHeight(craftingContainer) + 1; ++int_3) {
  130. if (int_3 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) {
  131. ItemStack itemStack_1 = this.craftingContainer.getSlot(int_3).getStack();
  132. if (!itemStack_1.isEmpty() && int_2 > itemStack_1.getCount()) {
  133. int_2 = itemStack_1.getCount();
  134. }
  135. }
  136. }
  137. if (int_2 < 64) {
  138. ++int_2;
  139. }
  140. }
  141. return int_2;
  142. }
  143. protected void returnInputs() {
  144. for (int int_1 = 0; int_1 < this.containerInfo.getCraftingWidth(craftingContainer) * this.containerInfo.getCraftingHeight(craftingContainer) + 1; ++int_1) {
  145. if (int_1 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) {
  146. this.returnSlot(int_1);
  147. }
  148. }
  149. this.containerInfo.clearCraftingSlots(craftingContainer);
  150. }
  151. protected void returnSlot(int int_1) {
  152. ItemStack itemStack_1 = this.craftingContainer.getSlot(int_1).getStack();
  153. if (!itemStack_1.isEmpty()) {
  154. for (; itemStack_1.getCount() > 0; this.craftingContainer.getSlot(int_1).takeStack(1)) {
  155. int int_2 = this.inventory.getOccupiedSlotWithRoomForStack(itemStack_1);
  156. if (int_2 == -1) {
  157. int_2 = this.inventory.getEmptySlot();
  158. }
  159. ItemStack itemStack_2 = itemStack_1.copy();
  160. itemStack_2.setCount(1);
  161. if (!this.inventory.insertStack(int_2, itemStack_2)) {
  162. throw new IllegalStateException("rei.rei.no.slot.in.inv");
  163. }
  164. }
  165. }
  166. }
  167. private boolean canReturnInputs() {
  168. List<ItemStack> list_1 = Lists.newArrayList();
  169. int int_1 = this.getFreeInventorySlots();
  170. for (int int_2 = 0; int_2 < this.containerInfo.getCraftingWidth(craftingContainer) * this.containerInfo.getCraftingHeight(craftingContainer) + 1; ++int_2) {
  171. if (int_2 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) {
  172. ItemStack itemStack_1 = this.craftingContainer.getSlot(int_2).getStack().copy();
  173. if (!itemStack_1.isEmpty()) {
  174. int int_3 = this.inventory.getOccupiedSlotWithRoomForStack(itemStack_1);
  175. if (int_3 == -1 && list_1.size() <= int_1) {
  176. Iterator var6 = list_1.iterator();
  177. while (var6.hasNext()) {
  178. ItemStack itemStack_2 = (ItemStack) var6.next();
  179. if (itemStack_2.isItemEqualIgnoreDamage(itemStack_1) && itemStack_2.getCount() != itemStack_2.getMaxCount() && itemStack_2.getCount() + itemStack_1.getCount() <= itemStack_2.getMaxCount()) {
  180. itemStack_2.increment(itemStack_1.getCount());
  181. itemStack_1.setCount(0);
  182. break;
  183. }
  184. }
  185. if (!itemStack_1.isEmpty()) {
  186. if (list_1.size() >= int_1) {
  187. return false;
  188. }
  189. list_1.add(itemStack_1);
  190. }
  191. } else if (int_3 == -1) {
  192. return false;
  193. }
  194. }
  195. }
  196. }
  197. return true;
  198. }
  199. private int getFreeInventorySlots() {
  200. int int_1 = 0;
  201. Iterator var2 = this.inventory.main.iterator();
  202. while (var2.hasNext()) {
  203. ItemStack itemStack_1 = (ItemStack) var2.next();
  204. if (itemStack_1.isEmpty()) {
  205. ++int_1;
  206. }
  207. }
  208. return int_1;
  209. }
  210. }