diff --git a/CHANGELOG-old.md b/CHANGELOG-old.md index 1f3999ba1e..57bc1eb9b5 100644 --- a/CHANGELOG-old.md +++ b/CHANGELOG-old.md @@ -7,6 +7,11 @@ - Fixed Wireless Transmitter only working upright (Darkere) - Fixed Portable Grid not opening when pointing at a block (Darkere) - Fixed being able to circumvent locked slots by scrolling (Darkere) +- Processing patterns now use the order of items/fluids specified in the pattern (Darkere, necauqua) +- Fixed multiple bugs related to transferring recipes into the crafting grid (Darkere) +- Fixed autocrafting task getting stuck if two tasks fulfilled each others requirements (Darkere) +- Fixed fluid autocrafting breaking when using 2 stacks of the same fluid in a pattern (Darkere) +- Amount specifying screen is now limited to valid values (Darkere) ### 1.9.16 diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a3e352f6..eb8bda729a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,18 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- Fixed multiple bugs related to transferring recipes into the Crafting Grid. +- Processing patterns now use the order of items/fluids specified in the pattern + by [@necauqua](https://github.com/necauqua) and [@Darkere](https://github.com/Darkere). +- Fixed autocrafting task getting stuck if two tasks fulfilled each others requirements. +- Fixed fluid autocrafting breaking when using 2 stacks of the same fluid in a pattern. +- Amount specifying screen is now limited to valid values. +- Fixed crash on servers when starting with latest Forge. + +## [v1.10.0-beta.4] - 2021-12-28 + +### Fixed + - Fixed client crash when hovering over a fluid in the Fluid Grid by [@jackodsteel](https://github.com/jackodsteel). - Fixed random client crashes when starting the game. diff --git a/build.gradle b/build.gradle index a0ef3e0baf..15a7cea0c2 100755 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ apply plugin: 'maven-publish' group = 'com.refinedmods' archivesBaseName = 'refinedstorage' -version = '1.10.0-beta.4' +version = '1.10.0' if (System.getenv('GITHUB_SHA') != null) { version += '+' + System.getenv('GITHUB_SHA').substring(0, 7) @@ -102,7 +102,7 @@ processResources { } dependencies { - minecraft 'net.minecraftforge:forge:1.18.1-39.0.0' + minecraft 'net.minecraftforge:forge:1.18.1-39.0.59' compileOnly fg.deobf("mezz.jei:jei-1.18.1:9.1.0.41:api") runtimeOnly fg.deobf("mezz.jei:jei-1.18.1:9.1.0.41") diff --git a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java index e0eef87031..c1cc8e56ce 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -1,7 +1,6 @@ package com.refinedmods.refinedstorage.api.autocrafting; import com.refinedmods.refinedstorage.api.util.Action; -import com.refinedmods.refinedstorage.api.util.StackListEntry; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; @@ -152,7 +151,7 @@ default boolean hasConnectedFluidInventory() { * @param action action to perform * @return whether insertion was successful */ - default boolean insertItemsIntoInventory(Collection> toInsert, Action action) { + default boolean insertItemsIntoInventory(Collection toInsert, Action action) { IItemHandler dest = getConnectedInventory(); @@ -164,11 +163,10 @@ default boolean insertItemsIntoInventory(Collection> t return false; } - Deque> stacks = new ArrayDeque<>(toInsert); + Deque stacks = new ArrayDeque<>(toInsert); - StackListEntry currentEntry = stacks.poll(); - ItemStack current = currentEntry != null ? currentEntry.getStack() : null; + ItemStack current = stacks.poll(); List availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList()); @@ -189,9 +187,8 @@ default boolean insertItemsIntoInventory(Collection> t } if (remainder.isEmpty()) { // If we inserted successfully, get a next stack. - currentEntry = stacks.poll(); + current = stacks.poll(); - current = currentEntry != null ? currentEntry.getStack() : null; } else if (current.getCount() == remainder.getCount()) { // If we didn't insert anything over ALL these slots, stop here. break; } else { // If we didn't insert all, continue with other slots and use our remainder. @@ -215,7 +212,7 @@ default boolean insertItemsIntoInventory(Collection> t * @param action action to perform * @return whether insertion was successful */ - default boolean insertFluidsIntoInventory(Collection> toInsert, Action action) { + default boolean insertFluidsIntoInventory(Collection toInsert, Action action) { IFluidHandler dest = getConnectedFluidInventory(); if (toInsert.isEmpty()) { @@ -226,12 +223,12 @@ default boolean insertFluidsIntoInventory(Collection> return false; } - for (StackListEntry entry : toInsert) { - int filled = dest.fill(entry.getStack(), action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE); + for (FluidStack stack : toInsert) { + int filled = dest.fill(stack, action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE); - if (filled != entry.getStack().getAmount()) { + if (filled != stack.getAmount()) { if (action == Action.PERFORM) { - LogManager.getLogger().warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", entry.getStack().getTranslationKey()); + LogManager.getLogger().warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", stack.getTranslationKey()); } return false; diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java index c25b424f94..4a6ef9aa9f 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java @@ -6,7 +6,6 @@ import com.refinedmods.refinedstorage.api.util.IComparer; import com.refinedmods.refinedstorage.api.util.IStackList; import com.refinedmods.refinedstorage.api.util.StackListEntry; -import com.refinedmods.refinedstorage.apiimpl.API; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; @@ -19,15 +18,15 @@ public final class IoUtil { private IoUtil() { } - public static IStackList extractFromInternalItemStorage(IStackList list, IStorageDisk storage, Action action) { - IStackList extracted = API.instance().createItemStackList(); + public static List extractFromInternalItemStorage(List list, IStorageDisk storage, Action action) { + List extracted = new ArrayList<>(); - for (StackListEntry entry : list.getStacks()) { - ItemStack result = storage.extract(entry.getStack(), entry.getStack().getCount(), DEFAULT_EXTRACT_FLAGS, action); + for (ItemStack stack : list) { + ItemStack result = storage.extract(stack, stack.getCount(), DEFAULT_EXTRACT_FLAGS, action); - if (result.isEmpty() || result.getCount() != entry.getStack().getCount()) { + if (result.isEmpty() || result.getCount() != stack.getCount()) { if (action == Action.PERFORM) { - throw new IllegalStateException("The internal crafting inventory reported that " + entry.getStack() + " was available but we got " + result); + throw new IllegalStateException("The internal crafting inventory reported that " + stack + " was available but we got " + result); } return null; @@ -39,15 +38,15 @@ public static IStackList extractFromInternalItemStorage(IStackList extractFromInternalFluidStorage(IStackList list, IStorageDisk storage, Action action) { - IStackList extracted = API.instance().createFluidStackList(); + public static List extractFromInternalFluidStorage(List list, IStorageDisk storage, Action action) { + List extracted = new ArrayList<>(); - for (StackListEntry entry : list.getStacks()) { - FluidStack result = storage.extract(entry.getStack(), entry.getStack().getAmount(), DEFAULT_EXTRACT_FLAGS, action); + for (FluidStack stack : list) { + FluidStack result = storage.extract(stack, stack.getAmount(), DEFAULT_EXTRACT_FLAGS, action); - if (result.isEmpty() || result.getAmount() != entry.getStack().getAmount()) { + if (result.isEmpty() || result.getAmount() != stack.getAmount()) { if (action == Action.PERFORM) { - throw new IllegalStateException("The internal crafting inventory reported that " + entry.getStack() + " was available but we got " + result); + throw new IllegalStateException("The internal crafting inventory reported that " + stack + " was available but we got " + result); } return null; diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/calculator/CraftingCalculator.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/calculator/CraftingCalculator.java index d7cfc77c44..0e4c52a2e9 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/calculator/CraftingCalculator.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/calculator/CraftingCalculator.java @@ -257,7 +257,7 @@ private void calculateForFluids(int qty, FluidStack fromSelf = fluidResults.get(possibleInput, IComparer.COMPARE_NBT); FluidStack fromNetwork = fluidStorageSource.get(possibleInput, IComparer.COMPARE_NBT); - int remaining = possibleInput.getAmount() * qty; + int remaining = ingredient.getCount() * qty; if (remaining < 0) { // int overflow throw new CraftingCalculatorException(CalculationResultType.TOO_COMPLEX); diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/NodeRequirements.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/NodeRequirements.java index fe2e3559f8..67f9b9acf0 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/NodeRequirements.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/NodeRequirements.java @@ -11,12 +11,10 @@ import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.items.ItemHandlerHelper; import javax.annotation.Nullable; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class NodeRequirements { private static final String NBT_ITEMS_TO_USE = "ItemsToUse"; @@ -32,9 +30,9 @@ public class NodeRequirements { private final Map fluidsNeededPerCraft = new LinkedHashMap<>(); @Nullable - private IStackList cachedSimulatedItemRequirementSet = null; + private List cachedSimulatedItemRequirementSet = null; @Nullable - private IStackList cachedSimulatedFluidRequirementSet = null; + private List cachedSimulatedFluidRequirementSet = null; public void addItemRequirement(int ingredientNumber, ItemStack stack, int size, int perCraft) { if (!itemsNeededPerCraft.containsKey(ingredientNumber)) { @@ -56,13 +54,13 @@ public void addFluidRequirement(int ingredientNumber, FluidStack stack, int size cachedSimulatedFluidRequirementSet = null; } - public IStackList getSingleItemRequirementSet(boolean simulate) { - IStackList cached = cachedSimulatedItemRequirementSet; + public List getSingleItemRequirementSet(boolean simulate) { + List cached = cachedSimulatedItemRequirementSet; if (simulate && cached != null) { return cached; } - IStackList toReturn = API.instance().createItemStackList(); + List toReturn = new ArrayList<>(); for (int i = 0; i < itemRequirements.size(); i++) { int needed = itemsNeededPerCraft.get(i); @@ -78,7 +76,7 @@ public IStackList getSingleItemRequirementSet(boolean simulate) { itemRequirements.get(i).remove(toUse, needed); } - toReturn.add(toUse, needed); + toReturn.add(ItemHandlerHelper.copyStackWithSize(toUse, needed)); needed = 0; } else { @@ -101,13 +99,13 @@ public IStackList getSingleItemRequirementSet(boolean simulate) { return toReturn; } - public IStackList getSingleFluidRequirementSet(boolean simulate) { - IStackList cached = cachedSimulatedFluidRequirementSet; + public List getSingleFluidRequirementSet(boolean simulate) { + List cached = cachedSimulatedFluidRequirementSet; if (simulate && cached != null) { return cached; } - IStackList toReturn = API.instance().createFluidStackList(); + List toReturn = new ArrayList<>(); for (int i = 0; i < fluidRequirements.size(); i++) { int needed = fluidsNeededPerCraft.get(i); @@ -123,7 +121,9 @@ public IStackList getSingleFluidRequirementSet(boolean simulate) { fluidRequirements.get(i).remove(toUse, needed); } - toReturn.add(toUse, needed); + FluidStack stack = toUse.copy(); + stack.setAmount(needed); + toReturn.add(stack); needed = 0; } else { diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java index b24bc6e440..f6bdfc0410 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java @@ -11,11 +11,15 @@ import com.refinedmods.refinedstorage.apiimpl.API; import com.refinedmods.refinedstorage.apiimpl.autocrafting.task.v6.IoUtil; import com.refinedmods.refinedstorage.apiimpl.autocrafting.task.v6.SerializationUtil; +import com.refinedmods.refinedstorage.apiimpl.util.FluidStackList; +import com.refinedmods.refinedstorage.apiimpl.util.ItemStackList; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; +import java.util.List; + public class ProcessingNode extends Node { private static final String NBT_ITEMS_RECEIVED = "ItemsReceived"; private static final String NBT_FLUIDS_RECEIVED = "FluidsReceived"; @@ -69,7 +73,7 @@ private void initSetsToReceive() { @Override public void update(INetwork network, int ticks, NodeList nodes, IStorageDisk internalStorage, IStorageDisk internalFluidStorage, NodeListener listener) { if (getQuantity() <= 0) { - if (state == ProcessingState.PROCESSED) { + if (totalQuantity == quantityFinished) { listener.onAllDone(this); } return; @@ -117,8 +121,8 @@ public void update(INetwork network, int ticks, NodeList nodes, IStorageDisk extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(true), internalStorage, Action.SIMULATE); - IStackList extractedFluids = null; + List extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(true), internalStorage, Action.SIMULATE); + List extractedFluids = null; if (extractedItems != null) { extractedFluids = IoUtil.extractFromInternalFluidStorage(requirements.getSingleFluidRequirementSet(true), internalFluidStorage, Action.SIMULATE); if (extractedFluids != null) { @@ -128,9 +132,9 @@ public void update(INetwork network, int ticks, NodeList nodes, IStorageDisk { private final ArrayListMultimap> stacks = ArrayListMultimap.create(); private final Map index = new HashMap<>(); + public FluidStackList() { + } + + public FluidStackList(Iterable stacks) { + for (FluidStack stack : stacks) { + add(stack); + } + } + @Override public StackListResult add(@Nonnull FluidStack stack, int size) { if (stack.isEmpty() || size <= 0) { diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/util/ItemStackList.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/util/ItemStackList.java index 0843a20c61..e4b0f0cfd7 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/util/ItemStackList.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/util/ItemStackList.java @@ -20,6 +20,15 @@ public class ItemStackList implements IStackList { private final ArrayListMultimap> stacks = ArrayListMultimap.create(); private final Map index = new HashMap<>(); + public ItemStackList() { + } + + public ItemStackList(Iterable stacks) { + for (ItemStack stack : stacks) { + add(stack); + } + } + @Override public StackListResult add(@Nonnull ItemStack stack, int size) { if (stack.isEmpty() || size <= 0) { diff --git a/src/main/java/com/refinedmods/refinedstorage/integration/jei/GridRecipeTransferHandler.java b/src/main/java/com/refinedmods/refinedstorage/integration/jei/GridRecipeTransferHandler.java index 35d7744a82..93c0fabdea 100644 --- a/src/main/java/com/refinedmods/refinedstorage/integration/jei/GridRecipeTransferHandler.java +++ b/src/main/java/com/refinedmods/refinedstorage/integration/jei/GridRecipeTransferHandler.java @@ -151,14 +151,15 @@ private void moveItems(GridContainerMenu gridContainer, Object recipe, IRecipeLa if (gridContainer.getGrid().getGridType() == GridType.PATTERN && !(recipe instanceof CraftingRecipe)) { moveForProcessing(recipeLayout, tracker); } else { - move(gridContainer, recipeLayout); + move(gridContainer, recipeLayout, recipe); } } - private void move(GridContainerMenu gridContainer, IRecipeLayout recipeLayout) { + private void move(GridContainerMenu gridContainer, IRecipeLayout recipeLayout, Object recipe) { RS.NETWORK_HANDLER.sendToServer(new GridTransferMessage( recipeLayout.getItemStacks().getGuiIngredients(), - gridContainer.slots.stream().filter(s -> s.container instanceof CraftingContainer).collect(Collectors.toList()) + gridContainer.slots.stream().filter(s -> s.container instanceof CraftingContainer).collect(Collectors.toList()), + recipe instanceof CraftingRecipe )); } diff --git a/src/main/java/com/refinedmods/refinedstorage/item/PatternItem.java b/src/main/java/com/refinedmods/refinedstorage/item/PatternItem.java index d21ab9c070..89745c8f2a 100644 --- a/src/main/java/com/refinedmods/refinedstorage/item/PatternItem.java +++ b/src/main/java/com/refinedmods/refinedstorage/item/PatternItem.java @@ -39,7 +39,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -public class PatternItem extends Item implements ICraftingPatternProvider, IItemRenderProperties { +public class PatternItem extends Item implements ICraftingPatternProvider { private static final Map CACHE = new HashMap<>(); private static final String NBT_VERSION = "Version"; diff --git a/src/main/java/com/refinedmods/refinedstorage/network/grid/GridTransferMessage.java b/src/main/java/com/refinedmods/refinedstorage/network/grid/GridTransferMessage.java index 19c17e5fa1..a0935671b3 100644 --- a/src/main/java/com/refinedmods/refinedstorage/network/grid/GridTransferMessage.java +++ b/src/main/java/com/refinedmods/refinedstorage/network/grid/GridTransferMessage.java @@ -20,13 +20,15 @@ public class GridTransferMessage { private final ItemStack[][] recipe = new ItemStack[9][]; private Map> inputs; private List slots; + boolean isCraftingRecipe; public GridTransferMessage() { } - public GridTransferMessage(Map> inputs, List slots) { + public GridTransferMessage(Map> inputs, List slots, boolean isCraftingRecipe) { this.inputs = inputs; this.slots = slots; + this.isCraftingRecipe = isCraftingRecipe; } public static GridTransferMessage decode(FriendlyByteBuf buf) { @@ -51,7 +53,7 @@ public static void encode(GridTransferMessage message, FriendlyByteBuf buf) { buf.writeInt(message.slots.size()); for (Slot slot : message.slots) { - IGuiIngredient ingredient = message.inputs.get(slot.getSlotIndex() + 1); + IGuiIngredient ingredient = message.inputs.get(slot.getSlotIndex() + (message.isCraftingRecipe ? 1 : 0)); List ingredients = new ArrayList<>(); diff --git a/src/main/java/com/refinedmods/refinedstorage/screen/AmountSpecifyingScreen.java b/src/main/java/com/refinedmods/refinedstorage/screen/AmountSpecifyingScreen.java index f2050d9e6b..926f519ba7 100644 --- a/src/main/java/com/refinedmods/refinedstorage/screen/AmountSpecifyingScreen.java +++ b/src/main/java/com/refinedmods/refinedstorage/screen/AmountSpecifyingScreen.java @@ -64,6 +64,18 @@ public void onPostInit(int x, int y) { amountField.setTextColor(RenderSettings.INSTANCE.getSecondaryColor()); amountField.setCanLoseFocus(false); amountField.changeFocus(true); + amountField.setResponder(text -> { + int amount = 0; + try { + amount = Integer.parseInt(amountField.getValue()); + } catch (NumberFormatException e) { + // NO OP + } + + if (amount > getMaxAmount()) { + amountField.setValue(String.valueOf(getMaxAmount())); + } + }); addRenderableWidget(amountField); diff --git a/src/main/java/com/refinedmods/refinedstorage/screen/BaseScreen.java b/src/main/java/com/refinedmods/refinedstorage/screen/BaseScreen.java index dce27f567b..9a27f1840d 100644 --- a/src/main/java/com/refinedmods/refinedstorage/screen/BaseScreen.java +++ b/src/main/java/com/refinedmods/refinedstorage/screen/BaseScreen.java @@ -205,7 +205,7 @@ protected void slotClicked(Slot slot, int slotId, int mouseButton, ClickType typ minecraft.player, slot.index, slot.getItem(), - slot.getMaxStackSize(), + Math.min(slot.getMaxStackSize(), slot.getItem().getMaxStackSize()), ((FilterSlot) slot).isAlternativesAllowed() ? (parent -> new AlternativesScreen( parent, minecraft.player, diff --git a/src/main/java/com/refinedmods/refinedstorage/screen/grid/GridScreen.java b/src/main/java/com/refinedmods/refinedstorage/screen/grid/GridScreen.java index b0073294d7..a539da1f1f 100644 --- a/src/main/java/com/refinedmods/refinedstorage/screen/grid/GridScreen.java +++ b/src/main/java/com/refinedmods/refinedstorage/screen/grid/GridScreen.java @@ -320,7 +320,7 @@ private boolean isOverClear(double mouseX, double mouseY) { return RenderUtils.inBounds(82, y, 7, 7, mouseX, mouseY); case PATTERN: if (((GridNetworkNode) grid).isProcessingPattern()) { - return RenderUtils.inBounds(154, y, 7, 7, mouseX, mouseY); + return RenderUtils.inBounds(149, y, 7, 7, mouseX, mouseY); } return RenderUtils.inBounds(82, y, 7, 7, mouseX, mouseY);