From 7f73342e276e2d960be2e851c5c9562192437ffc Mon Sep 17 00:00:00 2001 From: shedaniel Date: Wed, 12 Aug 2020 00:38:05 +0800 Subject: Improve ContainerInfo to allow non-vanilla slots or custom behaviour --- .../autocrafting/DefaultRecipeBookHandler.java | 6 +- .../me/shedaniel/rei/server/ContainerContext.java | 39 ++++ .../me/shedaniel/rei/server/ContainerInfo.java | 82 +++++++- .../java/me/shedaniel/rei/server/DumpHandler.java | 58 ++++++ .../me/shedaniel/rei/server/GridCleanHandler.java | 50 +++++ .../shedaniel/rei/server/GridStacksProvider.java | 31 +++ .../me/shedaniel/rei/server/InputSlotCrafter.java | 207 ++++++++------------- .../rei/server/InventoryStackAccessor.java | 52 ++++++ .../java/me/shedaniel/rei/server/RecipeFinder.java | 26 ++- .../rei/server/RecipeFinderPopulator.java | 35 ++++ .../me/shedaniel/rei/server/RecipeGridAligner.java | 48 +---- .../me/shedaniel/rei/server/SlotStackAccessor.java | 50 +++++ .../me/shedaniel/rei/server/StackAccessor.java | 34 ++++ 13 files changed, 528 insertions(+), 190 deletions(-) create mode 100644 src/main/java/me/shedaniel/rei/server/ContainerContext.java create mode 100644 src/main/java/me/shedaniel/rei/server/DumpHandler.java create mode 100644 src/main/java/me/shedaniel/rei/server/GridCleanHandler.java create mode 100644 src/main/java/me/shedaniel/rei/server/GridStacksProvider.java create mode 100644 src/main/java/me/shedaniel/rei/server/InventoryStackAccessor.java create mode 100644 src/main/java/me/shedaniel/rei/server/RecipeFinderPopulator.java create mode 100644 src/main/java/me/shedaniel/rei/server/SlotStackAccessor.java create mode 100644 src/main/java/me/shedaniel/rei/server/StackAccessor.java (limited to 'src/main/java') diff --git a/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultRecipeBookHandler.java b/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultRecipeBookHandler.java index 7683b23af..4ad16a4c5 100644 --- a/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultRecipeBookHandler.java +++ b/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultRecipeBookHandler.java @@ -54,16 +54,14 @@ public class DefaultRecipeBookHandler implements AutoTransferHandler { if (display instanceof DefaultCraftingDisplay) { DefaultCraftingDisplay craftingDisplay = (DefaultCraftingDisplay) display; if (craftingDisplay.getOptionalRecipe().isPresent()) { - int h = -1, w = -1; + int h, w; if (container instanceof CraftingTableContainer) { h = 3; w = 3; } else if (container instanceof PlayerContainer) { h = 2; w = 2; - } - if (h == -1 || w == -1) - return Result.createNotApplicable(); + } else return Result.createNotApplicable(); Recipe recipe = (craftingDisplay).getOptionalRecipe().get(); if (craftingDisplay.getHeight() > h || craftingDisplay.getWidth() > w) return Result.createFailed(I18n.translate("error.rei.transfer.too_small", h, w)); diff --git a/src/main/java/me/shedaniel/rei/server/ContainerContext.java b/src/main/java/me/shedaniel/rei/server/ContainerContext.java new file mode 100644 index 000000000..18158e673 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/ContainerContext.java @@ -0,0 +1,39 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.container.Container; +import net.minecraft.entity.player.PlayerEntity; + +public interface ContainerContext { + T getContainer(); + + PlayerEntity getPlayerEntity(); + + ContainerInfo getContainerInfo(); + + default StackAccessor getStack(int slotIndex) { + return getContainerInfo().getStack(this, slotIndex); + } +} diff --git a/src/main/java/me/shedaniel/rei/server/ContainerInfo.java b/src/main/java/me/shedaniel/rei/server/ContainerInfo.java index 11c90064e..2a6649f3b 100644 --- a/src/main/java/me/shedaniel/rei/server/ContainerInfo.java +++ b/src/main/java/me/shedaniel/rei/server/ContainerInfo.java @@ -24,17 +24,95 @@ package me.shedaniel.rei.server; import net.minecraft.container.Container; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.slot.Slot; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.collection.DefaultedList; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public interface ContainerInfo { Class getContainerClass(); + default StackAccessor getStack(ContainerContext context, int slotIndex) { + return new SlotStackAccessor(context.getContainer().getSlot(slotIndex)); + } + + default GridCleanHandler getGridCleanHandler() { + return context -> { + T container = context.getContainer(); + for (StackAccessor gridStack : getGridStacks(context)) { + GridCleanHandler.returnSlotToPlayerInventory(context, gridStack); + } + + clearCraftingSlots(container); + }; + } + + default DumpHandler getDumpHandler() { + return (context, stackToInsert) -> { + List inventoryStacks = context.getContainerInfo().getInventoryStacks(context); + + StackAccessor nextSlot = DumpHandler.getOccupiedSlotWithRoomForStack(stackToInsert, inventoryStacks); + if (nextSlot == null) { + nextSlot = DumpHandler.getEmptySlot(inventoryStacks); + } + if (nextSlot == null) { + return false; + } + + ItemStack stack = stackToInsert.copy(); + stack.setCount(nextSlot.getItemStack().getCount() + stack.getCount()); + nextSlot.setItemStack(stack); + return true; + }; + } + + default RecipeFinderPopulator getRecipeFinderPopulator() { + return context -> recipeFinder -> { + for (StackAccessor inventoryStack : getInventoryStacks(context)) { + recipeFinder.addNormalItem(inventoryStack.getItemStack()); + } + populateRecipeFinder(context.getContainer(), recipeFinder); + }; + } + + default List getGridStacks(ContainerContext context) { + return IntStream.range(0, getCraftingWidth(context.getContainer()) * getCraftingHeight(context.getContainer()) + 1) + .filter(value -> value != getCraftingResultSlotIndex(context.getContainer())) + .mapToObj(context::getStack) + .collect(Collectors.toList()); + } + + default List getInventoryStacks(ContainerContext context) { + PlayerInventory inventory = context.getPlayerEntity().inventory; + return IntStream.range(0, inventory.main.size()) + .mapToObj(index -> (StackAccessor) new InventoryStackAccessor(inventory, index)) + .collect(Collectors.toList()); + } + + default void markDirty(ContainerContext context) { + context.getPlayerEntity().inventory.markDirty(); + context.getContainer().sendContentUpdates(); + + DefaultedList defaultedList = DefaultedList.of(); + for (Slot slot : context.getPlayerEntity().container.slots) { + defaultedList.add(slot.getStack()); + } + + ((ServerPlayerEntity) context.getPlayerEntity()).onContainerRegistered(context.getPlayerEntity().container, defaultedList); + } + int getCraftingResultSlotIndex(T container); int getCraftingWidth(T container); int getCraftingHeight(T container); - void clearCraftingSlots(T container); + default void clearCraftingSlots(T container) {} - void populateRecipeFinder(T container, RecipeFinder var1); + default void populateRecipeFinder(T container, RecipeFinder var1) {} } diff --git a/src/main/java/me/shedaniel/rei/server/DumpHandler.java b/src/main/java/me/shedaniel/rei/server/DumpHandler.java new file mode 100644 index 000000000..c5e04e12b --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/DumpHandler.java @@ -0,0 +1,58 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.container.Container; +import net.minecraft.item.ItemStack; + +import java.util.List; + +@FunctionalInterface +public interface DumpHandler { + boolean dump(ContainerContext context, ItemStack stackToInsert); + + static StackAccessor getOccupiedSlotWithRoomForStack(ItemStack stack, List inventoryStacks) { + for (StackAccessor inventoryStack : inventoryStacks) { + if (canStackAddMore(inventoryStack.getItemStack(), stack)) { + return inventoryStack; + } + } + + return null; + } + + static StackAccessor getEmptySlot(List inventoryStacks) { + for (StackAccessor inventoryStack : inventoryStacks) { + if (inventoryStack.getItemStack().isEmpty()) { + return inventoryStack; + } + } + + return null; + } + + static boolean canStackAddMore(ItemStack existingStack, ItemStack stack) { + return !existingStack.isEmpty() && ItemStack.areItemsEqual(existingStack, stack) && existingStack.isStackable() && existingStack.getCount() + stack.getCount() <= existingStack.getMaxCount(); + } +} diff --git a/src/main/java/me/shedaniel/rei/server/GridCleanHandler.java b/src/main/java/me/shedaniel/rei/server/GridCleanHandler.java new file mode 100644 index 000000000..557675533 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/GridCleanHandler.java @@ -0,0 +1,50 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.container.Container; +import net.minecraft.item.ItemStack; + +@FunctionalInterface +public interface GridCleanHandler { + void clean(ContainerContext context); + + static void error(String translationKey) { + throw new IllegalStateException(translationKey); + } + + static void returnSlotToPlayerInventory(ContainerContext context, StackAccessor stackAccessor) { + DumpHandler dumpHandler = context.getContainerInfo().getDumpHandler(); + ItemStack stackToReturn = stackAccessor.getItemStack(); + if (!stackToReturn.isEmpty()) { + for (; stackToReturn.getCount() > 0; stackAccessor.takeStack(1)) { + ItemStack stackToInsert = stackToReturn.copy(); + stackToInsert.setCount(1); + if (!dumpHandler.dump(context, stackToInsert)) { + error("rei.rei.no.slot.in.inv"); + } + } + } + } +} diff --git a/src/main/java/me/shedaniel/rei/server/GridStacksProvider.java b/src/main/java/me/shedaniel/rei/server/GridStacksProvider.java new file mode 100644 index 000000000..5d127aa34 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/GridStacksProvider.java @@ -0,0 +1,31 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.container.Container; + +@FunctionalInterface +public interface GridStacksProvider { + Iterable getStacks(ContainerContext context); +} diff --git a/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java b/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java index 7ee9078a6..8d8eeb4cb 100644 --- a/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java +++ b/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java @@ -23,27 +23,27 @@ package me.shedaniel.rei.server; -import com.google.common.collect.Lists; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.container.Container; -import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; -import net.minecraft.screen.slot.Slot; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; import java.util.*; -public class InputSlotCrafter implements RecipeGridAligner { +public class InputSlotCrafter implements RecipeGridAligner, ContainerContext { protected Container container; protected ContainerInfo containerInfo; - protected PlayerInventory inventory; + private List gridStacks; + private List inventoryStacks; + private ServerPlayerEntity player; private InputSlotCrafter(Container container, ContainerInfo containerInfo) { this.container = container; @@ -56,197 +56,148 @@ public class InputSlotCrafter implements RecipeGridAligner< } private void fillInputSlots(ServerPlayerEntity player, Map> map, boolean hasShift) { - this.inventory = player.inventory; - if (this.canReturnInputs() || player.isCreative()) { + this.player = player; + this.inventoryStacks = this.containerInfo.getInventoryStacks(this); + this.gridStacks = this.containerInfo.getGridStacks(this); + if (player.isCreative()) { + player.skipPacketSlotUpdates = true; // Return the already placed items on the grid this.returnInputs(); RecipeFinder recipeFinder = new RecipeFinder(); - recipeFinder.clear(); - for (ItemStack stack : player.inventory.main) { - recipeFinder.addNormalItem(stack); - } - this.containerInfo.populateRecipeFinder(container, recipeFinder); + this.containerInfo.getRecipeFinderPopulator().populate(this).accept(recipeFinder); DefaultedList ingredients = DefaultedList.of(); map.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).forEach(entry -> { ingredients.add(Ingredient.ofItems(entry.getValue().stream().map(ItemStack::getItem).toArray(Item[]::new))); }); + if (recipeFinder.findRecipe(ingredients, null)) { this.fillInputSlots(recipeFinder, ingredients, hasShift); } else { this.returnInputs(); - player.inventory.markDirty(); + player.skipPacketSlotUpdates = false; + this.containerInfo.markDirty(this); throw new NotEnoughMaterialsException(); } - player.inventory.markDirty(); + player.skipPacketSlotUpdates = false; + this.containerInfo.markDirty(this); } } @Override - public void acceptAlignedInput(Iterator iterator_1, int int_1, int int_2, int int_3, int int_4) { - Slot slot_1 = this.container.getSlot(int_1); - ItemStack itemStack_1 = RecipeFinder.getStackFromId(iterator_1.next()); - if (!itemStack_1.isEmpty()) { - for (int int_5 = 0; int_5 < int_2; ++int_5) { - this.fillInputSlot(slot_1, itemStack_1); + public void acceptAlignedInput(Iterator iterator_1, StackAccessor gridSlot, int craftsAmount) { + ItemStack toBeTakenStack = RecipeFinder.getStackFromId(iterator_1.next()); + if (!toBeTakenStack.isEmpty()) { + for (int i = 0; i < craftsAmount; ++i) { + this.fillInputSlot(gridSlot, toBeTakenStack); } } } - protected void fillInputSlot(Slot slot_1, ItemStack itemStack_1) { - int int_1 = this.inventory.method_7371(itemStack_1); - if (int_1 != -1) { - ItemStack itemStack_2 = this.inventory.getInvStack(int_1).copy(); - if (!itemStack_2.isEmpty()) { - if (itemStack_2.getCount() > 1) { - this.inventory.takeInvStack(int_1, 1); + protected void fillInputSlot(StackAccessor slot, ItemStack toBeTakenStack) { + int takenSlotIndex = this.method_7371(toBeTakenStack); + if (takenSlotIndex != -1) { + ItemStack takenStack = this.inventoryStacks.get(takenSlotIndex).getItemStack().copy(); + if (!takenStack.isEmpty()) { + if (takenStack.getCount() > 1) { + this.inventoryStacks.get(takenSlotIndex).takeStack(1); } else { - this.inventory.removeInvStack(int_1); + this.inventoryStacks.get(takenSlotIndex).setItemStack(ItemStack.EMPTY); } - itemStack_2.setCount(1); - if (slot_1.getStack().isEmpty()) { - slot_1.setStack(itemStack_2); + takenStack.setCount(1); + if (slot.getItemStack().isEmpty()) { + slot.setItemStack(takenStack); } else { - slot_1.getStack().increment(1); + slot.getItemStack().increment(1); } - } } } protected void fillInputSlots(RecipeFinder recipeFinder, DefaultedList ingredients, boolean hasShift) { - // boolean boolean_2 = this.craftingContainer.matches(recipe_1); - boolean boolean_2 = false; - int int_1 = recipeFinder.countRecipeCrafts(ingredients, null); - int int_2; - if (boolean_2) { - for (int_2 = 0; int_2 < this.containerInfo.getCraftingHeight(container) * this.containerInfo.getCraftingWidth(container) + 1; ++int_2) { - if (int_2 != this.containerInfo.getCraftingResultSlotIndex(container)) { - ItemStack itemStack_1 = this.container.getSlot(int_2).getStack(); - if (!itemStack_1.isEmpty() && Math.min(int_1, itemStack_1.getMaxCount()) < itemStack_1.getCount() + 1) { - return; - } - } - } - } - - int_2 = this.getAmountToFill(hasShift, int_1, boolean_2); + int recipeCrafts = recipeFinder.countRecipeCrafts(ingredients, null); + int amountToFill = this.getAmountToFill(hasShift, recipeCrafts, false); IntList intList_1 = new IntArrayList(); - if (recipeFinder.findRecipe(ingredients, intList_1, int_2)) { - int int_4 = int_2; + if (recipeFinder.findRecipe(ingredients, intList_1, amountToFill)) { + int finalCraftsAmount = amountToFill; - for (int int_5 : intList_1) { - int int_6 = RecipeFinder.getStackFromId(int_5).getMaxCount(); - if (int_6 < int_4) { - int_4 = int_6; - } + for (int itemId : intList_1) { + finalCraftsAmount = Math.min(finalCraftsAmount, RecipeFinder.getStackFromId(itemId).getMaxCount()); } - if (recipeFinder.findRecipe(ingredients, intList_1, int_4)) { + if (recipeFinder.findRecipe(ingredients, intList_1, finalCraftsAmount)) { this.returnInputs(); - this.alignRecipeToGrid(this.containerInfo.getCraftingWidth(container), this.containerInfo.getCraftingHeight(container), this.containerInfo.getCraftingResultSlotIndex(container), ingredients, intList_1.iterator(), int_4); + this.alignRecipeToGrid(gridStacks, intList_1.iterator(), finalCraftsAmount); } } } - protected int getAmountToFill(boolean hasShift, int int_1, boolean boolean_2) { - int int_2 = 1; + protected int getAmountToFill(boolean hasShift, int recipeCrafts, boolean boolean_2) { + int amountToFill = 1; if (hasShift) { - int_2 = int_1; + amountToFill = recipeCrafts; } else if (boolean_2) { - int_2 = 64; - for (int int_3 = 0; int_3 < this.containerInfo.getCraftingWidth(container) * this.containerInfo.getCraftingHeight(container) + 1; ++int_3) { - if (int_3 != this.containerInfo.getCraftingResultSlotIndex(container)) { - ItemStack itemStack_1 = this.container.getSlot(int_3).getStack(); - if (!itemStack_1.isEmpty() && int_2 > itemStack_1.getCount()) { - int_2 = itemStack_1.getCount(); - } + amountToFill = 64; + for (StackAccessor stackAccessor : gridStacks) { + ItemStack itemStack = stackAccessor.getItemStack(); + if (!itemStack.isEmpty() && amountToFill > itemStack.getCount()) { + amountToFill = itemStack.getCount(); } } - if (int_2 < 64) { - ++int_2; + if (amountToFill < 64) { + ++amountToFill; } } - return int_2; + return amountToFill; } protected void returnInputs() { - for (int int_1 = 0; int_1 < this.containerInfo.getCraftingWidth(container) * this.containerInfo.getCraftingHeight(container) + 1; ++int_1) { - if (int_1 != this.containerInfo.getCraftingResultSlotIndex(container)) { - this.returnSlot(int_1); - } - } - - this.containerInfo.clearCraftingSlots(container); + this.containerInfo.getGridCleanHandler().clean(this); } - protected void returnSlot(int int_1) { - ItemStack itemStack_1 = this.container.getSlot(int_1).getStack(); - if (!itemStack_1.isEmpty()) { - for (; itemStack_1.getCount() > 0; this.container.getSlot(int_1).takeStack(1)) { - int int_2 = this.inventory.getOccupiedSlotWithRoomForStack(itemStack_1); - if (int_2 == -1) { - int_2 = this.inventory.getEmptySlot(); - } - - ItemStack itemStack_2 = itemStack_1.copy(); - itemStack_2.setCount(1); - if (!this.inventory.insertStack(int_2, itemStack_2)) { - throw new IllegalStateException("rei.rei.no.slot.in.inv"); - } + public int method_7371(ItemStack itemStack) { + for (int i = 0; i < inventoryStacks.size(); i++) { + ItemStack itemStack1 = this.inventoryStacks.get(i).getItemStack(); + if (!itemStack1.isEmpty() && areItemsEqual(itemStack, itemStack1) && !itemStack1.isDamaged() && !itemStack1.hasEnchantments() && !itemStack1.hasCustomName()) { + return i; } } + + return -1; } - private boolean canReturnInputs() { - List list_1 = Lists.newArrayList(); - int int_1 = this.getFreeInventorySlots(); - - for (int int_2 = 0; int_2 < this.containerInfo.getCraftingWidth(container) * this.containerInfo.getCraftingHeight(container) + 1; ++int_2) { - if (int_2 != this.containerInfo.getCraftingResultSlotIndex(container)) { - ItemStack itemStack_1 = this.container.getSlot(int_2).getStack().copy(); - if (!itemStack_1.isEmpty()) { - int int_3 = this.inventory.getOccupiedSlotWithRoomForStack(itemStack_1); - if (int_3 == -1 && list_1.size() <= int_1) { - - for (ItemStack itemStack_2 : list_1) { - if (itemStack_2.isItemEqualIgnoreDamage(itemStack_1) && itemStack_2.getCount() != itemStack_2.getMaxCount() && itemStack_2.getCount() + itemStack_1.getCount() <= itemStack_2.getMaxCount()) { - itemStack_2.increment(itemStack_1.getCount()); - itemStack_1.setCount(0); - break; - } - } - - if (!itemStack_1.isEmpty()) { - if (list_1.size() >= int_1) { - return false; - } - - list_1.add(itemStack_1); - } - } else if (int_3 == -1) { - return false; - } - } - } - } - - return true; + private static boolean areItemsEqual(ItemStack stack1, ItemStack stack2) { + return stack1.getItem() == stack2.getItem() && ItemStack.areTagsEqual(stack1, stack2); } private int getFreeInventorySlots() { int int_1 = 0; - for (ItemStack itemStack_1 : this.inventory.main) { - if (itemStack_1.isEmpty()) { + for (StackAccessor inventoryStack : inventoryStacks) { + if (inventoryStack.getItemStack().isEmpty()) { ++int_1; } } return int_1; } + @Override + public Container getContainer() { + return container; + } + + @Override + public PlayerEntity getPlayerEntity() { + return player; + } + + @Override + public ContainerInfo getContainerInfo() { + return containerInfo; + } + public static class NotEnoughMaterialsException extends RuntimeException {} } diff --git a/src/main/java/me/shedaniel/rei/server/InventoryStackAccessor.java b/src/main/java/me/shedaniel/rei/server/InventoryStackAccessor.java new file mode 100644 index 000000000..71deced61 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/InventoryStackAccessor.java @@ -0,0 +1,52 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; + +public class InventoryStackAccessor implements StackAccessor { + protected Inventory inventory; + protected int index; + + public InventoryStackAccessor(Inventory inventory, int index) { + this.inventory = inventory; + this.index = index; + } + + @Override + public ItemStack getItemStack() { + return inventory.getInvStack(index); + } + + @Override + public void setItemStack(ItemStack stack) { + this.inventory.setInvStack(index, stack); + } + + @Override + public ItemStack takeStack(int amount) { + return this.inventory.takeInvStack(index, amount); + } +} diff --git a/src/main/java/me/shedaniel/rei/server/RecipeFinder.java b/src/main/java/me/shedaniel/rei/server/RecipeFinder.java index d9e0d429d..f0d90f770 100644 --- a/src/main/java/me/shedaniel/rei/server/RecipeFinder.java +++ b/src/main/java/me/shedaniel/rei/server/RecipeFinder.java @@ -172,10 +172,10 @@ public class RecipeFinder { this.bitSet.clear(0, this.ingredientCount + this.usableIngredientSize + this.ingredientCount); int int_5 = 0; - List list_1 = ingredientsInput.stream().collect(Collectors.toList()); - - for (int int_6 = 0; int_6 < list_1.size(); ++int_6) { - if (boolean_2 && list_1.get(int_6).isEmpty()) { + List list_1 = new ArrayList<>(ingredientsInput); + + for (Ingredient ingredient : list_1) { + if (boolean_2 && ingredient.isEmpty()) { intList_1.add(0); } else { for (int int_7 = 0; int_7 < this.usableIngredientSize; ++int_7) { @@ -187,7 +187,7 @@ public class RecipeFinder { } } } - + ++int_5; } } @@ -198,10 +198,8 @@ public class RecipeFinder { private int[] getUsableIngredientItemIds() { IntCollection intCollection_1 = new IntAVLTreeSet(); - Iterator var2 = this.ingredients.iterator(); - - while (var2.hasNext()) { - Ingredient ingredient_1 = (Ingredient) var2.next(); + + for (Ingredient ingredient_1 : this.ingredients) { intCollection_1.addAll(ingredient_1.getIds()); } @@ -325,17 +323,15 @@ public class RecipeFinder { @SuppressWarnings("deprecation") private int method_7415() { int int_1 = Integer.MAX_VALUE; - Iterator var2 = this.ingredients.iterator(); - - while (var2.hasNext()) { - Ingredient ingredient_1 = (Ingredient) var2.next(); + + for (Ingredient ingredient_1 : this.ingredients) { int int_2 = 0; - + int int_3; for (IntListIterator var5 = ingredient_1.getIds().iterator(); var5.hasNext(); int_2 = Math.max(int_2, RecipeFinder.this.idToAmountMap.get(int_3))) { int_3 = var5.next(); } - + if (int_1 > 0) { int_1 = Math.min(int_1, int_2); } diff --git a/src/main/java/me/shedaniel/rei/server/RecipeFinderPopulator.java b/src/main/java/me/shedaniel/rei/server/RecipeFinderPopulator.java new file mode 100644 index 000000000..be785ebbd --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/RecipeFinderPopulator.java @@ -0,0 +1,35 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.container.Container; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +@FunctionalInterface +public interface RecipeFinderPopulator { + @NotNull + Consumer populate(ContainerContext context); +} diff --git a/src/main/java/me/shedaniel/rei/server/RecipeGridAligner.java b/src/main/java/me/shedaniel/rei/server/RecipeGridAligner.java index e672d2015..80744de65 100644 --- a/src/main/java/me/shedaniel/rei/server/RecipeGridAligner.java +++ b/src/main/java/me/shedaniel/rei/server/RecipeGridAligner.java @@ -23,56 +23,22 @@ package me.shedaniel.rei.server; -import net.minecraft.recipe.Ingredient; -import net.minecraft.util.collection.DefaultedList; -import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.ApiStatus; import java.util.Iterator; +import java.util.List; @ApiStatus.Internal public interface RecipeGridAligner { - default void alignRecipeToGrid(int int_1, int int_2, int int_3, DefaultedList recipe_1, Iterator iterator_1, int int_4) { - int int_7 = 0; - - for (int int_8 = 0; int_8 < int_2; ++int_8) { - if (int_7 == int_3) { - ++int_7; + default void alignRecipeToGrid(List gridStacks, Iterator iterator_1, int craftsAmount) { + for (StackAccessor gridStack : gridStacks) { + if (!iterator_1.hasNext()) { + return; } - boolean boolean_1 = (float) int_2 < (float) int_2 / 2.0F; - int int_9 = MathHelper.floor((float) int_2 / 2.0F - (float) int_2 / 2.0F); - if (boolean_1 && int_9 > int_8) { - int_7 += int_1; - ++int_8; - } - - for (int int_10 = 0; int_10 < int_1; ++int_10) { - if (!iterator_1.hasNext()) { - return; - } - - boolean_1 = (float) int_1 < (float) int_1 / 2.0F; - int_9 = MathHelper.floor((float) int_1 / 2.0F - (float) int_1 / 2.0F); - int int_11 = int_1; - boolean boolean_2 = int_10 < int_1; - if (boolean_1) { - int_11 = int_9 + int_1; - boolean_2 = int_9 <= int_10 && int_10 < int_9 + int_1; - } - - if (boolean_2) { - this.acceptAlignedInput(iterator_1, int_7, int_4, int_8, int_10); - } else if (int_11 == int_10) { - int_7 += int_1 - int_10; - break; - } - - ++int_7; - } + this.acceptAlignedInput(iterator_1, gridStack, craftsAmount); } - } - void acceptAlignedInput(Iterator var1, int var2, int var3, int var4, int var5); + void acceptAlignedInput(Iterator var1, StackAccessor gridSlot, int craftsAmount); } \ No newline at end of file diff --git a/src/main/java/me/shedaniel/rei/server/SlotStackAccessor.java b/src/main/java/me/shedaniel/rei/server/SlotStackAccessor.java new file mode 100644 index 000000000..46b4d7b8b --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/SlotStackAccessor.java @@ -0,0 +1,50 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.item.ItemStack; +import net.minecraft.screen.slot.Slot; + +public class SlotStackAccessor implements StackAccessor { + protected Slot slot; + + public SlotStackAccessor(Slot slot) { + this.slot = slot; + } + + @Override + public ItemStack getItemStack() { + return slot.getStack(); + } + + @Override + public void setItemStack(ItemStack stack) { + this.slot.setStack(stack); + } + + @Override + public ItemStack takeStack(int amount) { + return slot.takeStack(amount); + } +} diff --git a/src/main/java/me/shedaniel/rei/server/StackAccessor.java b/src/main/java/me/shedaniel/rei/server/StackAccessor.java new file mode 100644 index 000000000..65b722a9e --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/StackAccessor.java @@ -0,0 +1,34 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.server; + +import net.minecraft.item.ItemStack; + +public interface StackAccessor { + ItemStack getItemStack(); + + void setItemStack(ItemStack stack); + + ItemStack takeStack(int amount); +} -- cgit