diff options
Diffstat (limited to 'src/main/java/gregtech')
5 files changed, 289 insertions, 63 deletions
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java index f8274a7f26..d964d9a7f1 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java @@ -105,6 +105,8 @@ import gregtech.common.tileentities.machines.IDualInputHatch; import gregtech.common.tileentities.machines.IDualInputInventory; import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch; import gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_LargeTurbine; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; @@ -1349,7 +1351,7 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity } /** - * Drains fluid from the given hatch, including {@link IDualInputHatch}. + * Drains fluid from the given hatch, including {@link IDualInputHatch}. Should never be used during recipe check! * * @param doDrain If false, fluid will not actually be consumed * @return Whether the hatch contains enough fluid to drain @@ -1471,6 +1473,37 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity return rList; } + public Map<GT_Utility.ItemId, ItemStack> getStoredInputsFromME() { + Map<GT_Utility.ItemId, ItemStack> inputsFromME = new Object2ReferenceOpenHashMap<>(); + for (GT_MetaTileEntity_Hatch_InputBus tHatch : filterValidMTEs(mInputBusses)) { + if (tHatch instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { + for (int i = meBus.getSizeInventory() - 1; i >= 0; i--) { + ItemStack itemStack = meBus.getStackInSlot(i); + if (itemStack != null) { + // Prevent the same item from different ME buses from being recognized + inputsFromME.put(GT_Utility.ItemId.createNoCopy(itemStack), itemStack); + } + } + } + } + return inputsFromME; + } + + public Map<Fluid, FluidStack> getStoredFluidsFromME() { + Map<Fluid, FluidStack> fluidsFromME = new Reference2ReferenceOpenHashMap<>(); + for (GT_MetaTileEntity_Hatch_Input tHatch : filterValidMTEs(mInputHatches)) { + if (tHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { + for (FluidStack fluid : meHatch.getStoredFluids()) { + if (fluid != null) { + // Prevent the same fluid from different ME hatches from being recognized + fluidsFromME.put(fluid.getFluid(), fluid); + } + } + } + } + return fluidsFromME; + } + @Override public RecipeMap<?> getRecipeMap() { return null; diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index ddb0708716..04f65a8342 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -26,6 +26,9 @@ import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.logic.FluidInventoryLogic; import gregtech.api.logic.ItemInventoryLogic; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Input; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_MultiInput; import gregtech.api.objects.GT_ItemStack; import gregtech.api.recipe.RecipeCategory; import gregtech.api.recipe.RecipeMap; @@ -35,11 +38,15 @@ import gregtech.api.recipe.metadata.EmptyRecipeMetadataStorage; import gregtech.api.recipe.metadata.IRecipeMetadataStorage; import gregtech.api.util.extensions.ArrayExt; import gregtech.api.util.item.ItemHolder; +import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_InputBus_ME; +import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Input_ME; import ic2.core.Ic2Items; import it.unimi.dsi.fastutil.objects.Object2LongArrayMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import it.unimi.dsi.fastutil.objects.Reference2LongArrayMap; import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; public class GT_Recipe implements Comparable<GT_Recipe> { @@ -482,7 +489,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> { /** * Returns the number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that inputs - * are found but not enough. Refer to SingleRecipeCheck#checkRecipeInputs. + * are found but not enough. */ public double maxParallelCalculatedByInputs(int maxParallel, FluidStack[] aFluidInputs, ItemStack... aInputs) { if (mInputs.length > 0 && aInputs == null) return 0; @@ -998,6 +1005,200 @@ public class GT_Recipe implements Comparable<GT_Recipe> { if (aPersistentHash == 0) this.mPersistentHash = 1; else this.mPersistentHash = aPersistentHash; } + + /** + * @param inputBusses List of input busses to check. + * @return An array containing the amount of item to consume from the first slot of every input bus. + * {@code null} if at least one item fails to match the recipe ingredient. + */ + public static int[] getItemConsumptionAmountArray(ArrayList<GT_MetaTileEntity_Hatch_InputBus> inputBusses, + GT_Recipe_AssemblyLine recipe) { + int itemCount = recipe.mInputs.length; + if (itemCount == 0) return null; + int[] tStacks = new int[itemCount]; + for (int i = 0; i < itemCount; i++) { + GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) return null; + ItemStack slotStack; + if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { + slotStack = meBus.getShadowItemStack(0); + } else { + slotStack = inputBus.getStackInSlot(0); + } + if (slotStack == null) return null; + + int amount = getMatchedIngredientAmount(slotStack, recipe.mInputs[i], recipe.mOreDictAlt[i]); + if (amount < 0) return null; + + tStacks[i] = amount; + } + return tStacks; + } + + public static int getMatchedIngredientAmount(ItemStack aSlotStack, ItemStack aIngredient, ItemStack[] alts) { + if (alts == null || alts.length == 0) { + if (GT_Utility.areStacksEqual(aSlotStack, aIngredient, true)) { + return aIngredient.stackSize; + } + return -1; + } + for (ItemStack tAltStack : alts) { + if (GT_Utility.areStacksEqual(aSlotStack, tAltStack, true)) { + return tAltStack.stackSize; + } + } + return -1; + } + + /** + * @param inputBusses Input bus list to check. Usually the input bus list of multi. + * @param itemConsumptions Should be generated by {@link GT_Recipe_AssemblyLine#getItemConsumptionAmountArray}. + * @Return The number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that + * inputs are found but not enough. + */ + public static double maxParallelCalculatedByInputItems(ArrayList<GT_MetaTileEntity_Hatch_InputBus> inputBusses, + int maxParallel, int[] itemConsumptions, Map<GT_Utility.ItemId, ItemStack> inputsFromME) { + // Recipe item matching is done in the generation of itemConsumptions. + + Map<GT_Utility.ItemId, Long> itemConsumptionsFromME = new Object2LongOpenHashMap<>(); + double currentParallel = maxParallel; + + // Calculate the amount of each item to consume from ME + for (int i = 0; i < itemConsumptions.length; i++) { + GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) return 0; + if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { + ItemStack item = meBus.getShadowItemStack(0); + if (item == null) return 0; + GT_Utility.ItemId id = GT_Utility.ItemId.createNoCopy(item); + itemConsumptionsFromME.merge(id, (long) itemConsumptions[i], Long::sum); + } + } + // Calculate parallel from ME input busses + for (Entry<GT_Utility.ItemId, Long> entry : itemConsumptionsFromME.entrySet()) { + if (!inputsFromME.containsKey(entry.getKey())) return 0; + long consume = entry.getValue(); + // For non-consumed inputs + if (consume == 0) continue; + currentParallel = Math + .min(currentParallel, (double) inputsFromME.get(entry.getKey()).stackSize / consume); + if (currentParallel <= 0) return 0; + } + + // Calculate parallel from regular input busses + for (int i = 0; i < itemConsumptions.length; i++) { + GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) return 0; + if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME) continue; + + ItemStack item = inputBus.getStackInSlot(0); + if (item == null) return 0; + // For non-consumed inputs + if (itemConsumptions[i] == 0) continue; + currentParallel = Math.min(currentParallel, (double) item.stackSize / itemConsumptions[i]); + if (currentParallel <= 0) return 0; + } + return currentParallel; + } + + /** + * @param inputHatches Input hatch list to check. Usually the input hatch list of multi. + * @param fluidConsumptions Fluid inputs of the recipe. + * @return The number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that + * fluids are found but not enough. + */ + public static double maxParallelCalculatedByInputFluids(ArrayList<GT_MetaTileEntity_Hatch_Input> inputHatches, + int maxParallel, FluidStack[] fluidConsumptions, Map<Fluid, FluidStack> fluidsFromME) { + Map<Fluid, Long> fluidConsumptionsFromME = new Reference2LongOpenHashMap<>(); + double currentParallel = maxParallel; + + // Calculate the amount of each fluid to consume from ME + for (int i = 0; i < fluidConsumptions.length; i++) { + GT_MetaTileEntity_Hatch_Input inputHatch = inputHatches.get(i); + if (!inputHatch.isValid()) return 0; + if (inputHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { + FluidStack fluid = meHatch.getShadowFluidStack(0); + if (fluid == null) return 0; + if (!GT_Utility.areFluidsEqual(fluid, fluidConsumptions[i])) return 0; + fluidConsumptionsFromME.merge(fluid.getFluid(), (long) fluidConsumptions[i].amount, Long::sum); + } + } + // Calculate parallel from ME input hatches + for (Entry<Fluid, Long> entry : fluidConsumptionsFromME.entrySet()) { + Fluid fluid = entry.getKey(); + if (!fluidsFromME.containsKey(fluid)) return 0; + long consume = entry.getValue(); + currentParallel = Math.min(currentParallel, (double) fluidsFromME.get(fluid).amount / consume); + if (currentParallel <= 0) return 0; + } + + // Calculate parallel from regular input hatches + for (int i = 0; i < fluidConsumptions.length; i++) { + GT_MetaTileEntity_Hatch_Input inputHatch = inputHatches.get(i); + if (!inputHatch.isValid()) return 0; + if (inputHatch instanceof GT_MetaTileEntity_Hatch_Input_ME) continue; + + FluidStack fluid; + if (inputHatch instanceof GT_MetaTileEntity_Hatch_MultiInput multiInput) { + fluid = multiInput.getFluid(0); + } else { + fluid = inputHatch.getFillableStack(); + } + if (fluid == null) return 0; + if (!GT_Utility.areFluidsEqual(fluid, fluidConsumptions[i])) return 0; + currentParallel = Math.min(currentParallel, (double) fluid.amount / fluidConsumptions[i].amount); + if (currentParallel <= 0) return 0; + } + return currentParallel; + } + + /** + * WARNING: Ensure that item inputs are enough to be consumed with + * {@link GT_Recipe_AssemblyLine#maxParallelCalculatedByInputItems} before calling this method! + * + * @param inputBusses Input bus list to check. Usually the input bus list of multi. + * @param itemConsumptions Should be generated by {@link GT_Recipe_AssemblyLine#getItemConsumptionAmountArray}. + */ + public static void consumeInputItems(ArrayList<GT_MetaTileEntity_Hatch_InputBus> inputBusses, + int amountMultiplier, int[] itemConsumptions, Map<GT_Utility.ItemId, ItemStack> inputsFromME) { + for (int i = 0; i < itemConsumptions.length; i++) { + GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) continue; + ItemStack item; + if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { + item = inputsFromME.get(GT_Utility.ItemId.createNoCopy(meBus.getShadowItemStack(0))); + } else { + item = inputBus.getStackInSlot(0); + } + item.stackSize -= itemConsumptions[i] * amountMultiplier; + } + } + + /** + * WARNING: Ensure that fluid inputs are enough to be consumed with + * {@link GT_Recipe_AssemblyLine#maxParallelCalculatedByInputFluids} before calling this method! + * + * @param inputHatches Input hatch list to check. Usually the input hatch list of multi. + * @param fluidConsumptions Fluid inputs of the recipe. + */ + public static void consumeInputFluids(ArrayList<GT_MetaTileEntity_Hatch_Input> inputHatches, + int amountMultiplier, FluidStack[] fluidConsumptions, Map<Fluid, FluidStack> fluidsFromME) { + for (int i = 0; i < fluidConsumptions.length; i++) { + GT_MetaTileEntity_Hatch_Input inputHatch = inputHatches.get(i); + if (!inputHatch.isValid()) continue; + FluidStack fluid; + if (inputHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { + fluid = fluidsFromME.get( + meHatch.getShadowFluidStack(0) + .getFluid()); + } else if (inputHatch instanceof GT_MetaTileEntity_Hatch_MultiInput multiInput) { + fluid = multiInput.getFluid(0); + } else { + fluid = inputHatch.getFillableStack(); + } + fluid.amount -= fluidConsumptions[i].amount * amountMultiplier; + } + } } public static class GT_Recipe_WithAlt extends GT_Recipe { diff --git a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java index a99ec29822..6b5ce10387 100644 --- a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java +++ b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java @@ -537,6 +537,16 @@ public class GT_MetaTileEntity_Hatch_InputBus_ME extends GT_MetaTileEntity_Hatch return null; } + /** + * Used to avoid slot update. + */ + public ItemStack getShadowItemStack(int index) { + if (index < 0 || index >= shadowInventory.length) { + return null; + } + return shadowInventory[index]; + } + @Override public boolean isValidSlot(int aIndex) { return aIndex == getManualSlot(); diff --git a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java index b8a2c78763..6e1ba2b3ce 100644 --- a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java +++ b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java @@ -414,6 +414,9 @@ public class GT_MetaTileEntity_Hatch_Input_ME extends GT_MetaTileEntity_Hatch_In return null; } + /** + * Used to avoid slot update. + */ public FluidStack getShadowFluidStack(int index) { if (index < 0 || index >= storedFluids.length) { return null; diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java index 307843896c..7c7c27c880 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java @@ -20,10 +20,12 @@ import static gregtech.api.util.GT_Utility.filterValidMTEs; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.NotNull; @@ -46,7 +48,6 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_ExtendedPowerMultiBlockBase; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_DataAccess; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus; import gregtech.api.multitileentity.multiblock.casing.Glasses; import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.RecipeMaps; @@ -197,21 +198,25 @@ public class GT_MetaTileEntity_AssemblyLine extends if (GT_Values.D1) { GT_FML_LOGGER.info("Start ALine recipe check"); } + CheckRecipeResult result = CheckRecipeResultRegistry.NO_DATA_STICKS; + ArrayList<ItemStack> tDataStickList = getDataItems(2); if (tDataStickList.isEmpty()) { - return CheckRecipeResultRegistry.NO_DATA_STICKS; + return result; } if (GT_Values.D1) { GT_FML_LOGGER.info("Stick accepted, " + tDataStickList.size() + " Data Sticks found"); } - int[] tStack = new int[0]; + int[] tStacks = new int[0]; FluidStack[] tFluids = new FluidStack[0]; long averageVoltage = getAverageInputVoltage(); long maxAmp = mEnergyHatches.size() <= 1 ? 1 : getMaxInputAmps(); - CheckRecipeResult result = CheckRecipeResultRegistry.NO_DATA_STICKS; + int maxParallel = 1; + Map<GT_Utility.ItemId, ItemStack> inputsFromME = getStoredInputsFromME(); + Map<Fluid, FluidStack> fluidsFromME = getStoredFluidsFromME(); - nextDataStick: for (ItemStack tDataStick : tDataStickList) { + for (ItemStack tDataStick : tDataStickList) { GT_AssemblyLineUtils.LookupResult tLookupResult = GT_AssemblyLineUtils .findAssemblyLineRecipeFromDataStick(tDataStick, false); @@ -239,7 +244,7 @@ public class GT_MetaTileEntity_AssemblyLine extends // So here we check against the recipe found on the data stick. // If we run into missing buses/hatches or bad inputs, we go to the next data stick. - // This check only happens if we have a valid up to date data stick. + // This check only happens if we have a valid up-to-date data stick. // first validate we have enough input busses and input hatches for this recipe if (mInputBusses.size() < tRecipe.mInputs.length || mInputHatches.size() < tRecipe.mFluidInputs.length) { @@ -256,45 +261,39 @@ public class GT_MetaTileEntity_AssemblyLine extends } // Check Inputs allign - int aItemCount = tRecipe.mInputs.length; - tStack = new int[aItemCount]; - for (int i = 0; i < aItemCount; i++) { - GT_MetaTileEntity_Hatch_InputBus tInputBus = mInputBusses.get(i); - if (!tInputBus.isValid()) { - result = CheckRecipeResultRegistry.NO_RECIPE; - continue nextDataStick; - } - ItemStack tSlotStack = tInputBus.getStackInSlot(0); - int tRequiredStackSize = isStackValidIngredient(tSlotStack, tRecipe.mInputs[i], tRecipe.mOreDictAlt[i]); - if (tRequiredStackSize < 0) { - result = CheckRecipeResultRegistry.NO_RECIPE; - continue nextDataStick; - } + int[] itemConsumptions = GT_Recipe_AssemblyLine.getItemConsumptionAmountArray(mInputBusses, tRecipe); + if (itemConsumptions == null || itemConsumptions.length == 0) { + result = CheckRecipeResultRegistry.NO_RECIPE; + continue; + } + maxParallel = (int) GT_Recipe_AssemblyLine + .maxParallelCalculatedByInputItems(mInputBusses, maxParallel, itemConsumptions, inputsFromME); + if (maxParallel <= 0) { + result = CheckRecipeResultRegistry.NO_RECIPE; + continue; + } + tStacks = itemConsumptions; - tStack[i] = tRequiredStackSize; - if (GT_Values.D1) { - GT_FML_LOGGER.info("Item: " + i + " accepted"); - } + if (GT_Values.D1) { + GT_FML_LOGGER.info("All Items accepted"); } // Check Fluid Inputs allign - int aFluidCount = tRecipe.mFluidInputs.length; - if (aFluidCount > 0) { - for (int i = 0; i < aFluidCount; i++) { - if (!drain(mInputHatches.get(i), tRecipe.mFluidInputs[i], false)) { - result = CheckRecipeResultRegistry.NO_RECIPE; - continue nextDataStick; - } - if (GT_Values.D1) { - GT_FML_LOGGER.info("Fluid:" + i + " accepted"); - } - + if (tRecipe.mFluidInputs.length > 0) { + maxParallel = (int) GT_Recipe_AssemblyLine + .maxParallelCalculatedByInputFluids(mInputHatches, maxParallel, tRecipe.mFluidInputs, fluidsFromME); + if (maxParallel <= 0) { + result = CheckRecipeResultRegistry.NO_RECIPE; + continue; } - // Finish Fluid Inputs allign check. tFluids = tRecipe.mFluidInputs; } if (GT_Values.D1) { + GT_FML_LOGGER.info("All fluids accepted"); + } + + if (GT_Values.D1) { GT_FML_LOGGER.info("Check overclock"); } @@ -339,23 +338,18 @@ public class GT_MetaTileEntity_AssemblyLine extends if (!result.wasSuccessful()) { return result; } + // Must be something wrong here... - if (tStack.length == 0) { - return CheckRecipeResultRegistry.NO_RECIPE; + if (tStacks.length == 0 || maxParallel <= 0) { + return CheckRecipeResultRegistry.INTERNAL_ERROR; } if (GT_Values.D1) { GT_FML_LOGGER.info("All checked start consuming inputs"); } - for (int i = 0; i < tStack.length; i++) { - ItemStack stackInSlot = mInputBusses.get(i) - .getStackInSlot(0); - stackInSlot.stackSize -= tStack[i]; - } - for (int i = 0; i < tFluids.length; i++) { - drain(mInputHatches.get(i), tFluids[i], true); - } + GT_Recipe_AssemblyLine.consumeInputItems(mInputBusses, maxParallel, tStacks, inputsFromME); + GT_Recipe_AssemblyLine.consumeInputFluids(mInputHatches, maxParallel, tFluids, fluidsFromME); if (this.lEUt > 0) { this.lEUt = -this.lEUt; @@ -369,21 +363,6 @@ public class GT_MetaTileEntity_AssemblyLine extends return result; } - private static int isStackValidIngredient(ItemStack aSlotStack, ItemStack aIngredient, ItemStack[] alts) { - if (alts == null || alts.length == 0) return isStackValidIngredient(aSlotStack, aIngredient); - for (ItemStack tAltStack : alts) { - int i = isStackValidIngredient(aSlotStack, tAltStack); - if (i >= 0) return i; - } - return -1; - } - - private static int isStackValidIngredient(ItemStack aSlotStack, ItemStack aIngredient) { - if (GT_Utility.areStacksEqual(aSlotStack, aIngredient, true) && aIngredient.stackSize <= aSlotStack.stackSize) - return aIngredient.stackSize; - return -1; - } - @Override public boolean onRunningTick(ItemStack aStack) { for (GT_MetaTileEntity_Hatch_DataAccess hatch_dataAccess : mDataAccessHatches) { |