aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/util
diff options
context:
space:
mode:
authorMaxim <maxim235@gmx.de>2023-07-10 10:13:04 +0200
committerGitHub <noreply@github.com>2023-07-10 10:13:04 +0200
commitfe0387946550f89a403b09f4e8cf6e43ee8f2e8f (patch)
tree6b56a553c2a5bbf2427a93e92724452ba5bc60f7 /src/main/java/gregtech/api/util
parent9fe44bf0eaa55825c1c3cdf90f69aeeb668f45b1 (diff)
downloadGT5-Unofficial-fe0387946550f89a403b09f4e8cf6e43ee8f2e8f.tar.gz
GT5-Unofficial-fe0387946550f89a403b09f4e8cf6e43ee8f2e8f.tar.bz2
GT5-Unofficial-fe0387946550f89a403b09f4e8cf6e43ee8f2e8f.zip
Generic processing logic (#2096)
* Added enumeration for check recipe result * Rework processing logic to work with MTEs too * Switched first few multiblocks to new checkRecipe method * Applied generic logic to EBF * Added support for long power base and applied generic processing logic to more machines * Address some feedback * Added more setter to further configure the processing logic * Change internal checkRecipe to work with checkRecipeResult, to allow the injection of custom failure messages * Suppress warning, change access * Merge recipeMap and mapSupplier * Move calls to setMetaTEController and setRecipeMap to base classes * Make processingLogic final * Make results non-null * Rename `ProcessingLogic#checkRecipe` -> `#validateRecipe` Otherwise it's confusing with `GT_MetaTileEntity_MultiBlockBase#checkRecipe` * oops * Added recipe locking to generic processing logic * Rename: getWorldObject -> getIHasWorldObjectAndCoords * Annotate missing overrides * Renamed recipeLockableController -> recipeLockableMachine * Migrated Cleanroom * Migrated pyrolyse oven * Migrated driller * Migrated charcoal pit * Migrated DT * Rename: controller -> machine * Make recipemaps override base `findRecipe` and mark others final * Remove unused maps * Add FindRecipeResult * Remove IHasWorldObjectAndCoords parameter from findRecipe This removes argument for printer recipemap to pass for GT_ModHandler.getAllRecipeOutput, but I don't think there's any mod that adds world-specific coloring recipe. * Added method to set processing logic power so machines can override it on demand * Restructure CheckRecipeResult, show voltage required and move package * Reword: insufficient voltage -> power * Change text color: dark gray -> gray * Added findRecipeResult for insufficient heat * Migrated PCB factory * Fix result not being reset on shut down * Show coil tier for heat * clean * Reverted migration of driller base * Migrated TPM * Moved getting of parallel supplier, to accomodate TPM * Migrated power gen multiblocks * Migrated Assembling Line * Migrated fusion * Migrated multi smelter * Migrated boiler * Migrated DTPF * Migrated ore factory * Migrated heat exchanger * Make checkRecipe() final, javadoc, minor cleanup * Fix overclock behavior with multiple hatches, javadoc, minor cleanup * Minor fix for javadoc * Fixed creation of OC calculator not factoring in batch mode correctly * Make GT_ParallelHelper#setRecipe nonnull * Rework SimpleCheckRecipeResult to not require registration * Migrate charcoal pit and cleanroom * Fix result not being reset when turning off machine * Add API for BW to make recipemap sensitive to special slot on recipe search * Migrated PA * Migrated driller base * Make ProcessingLogic#duration int * Minor cleanup * missing recipe locking for long multi * Fix NPE * Show crash message and turn off machine * minor javadoc fix * Fixed power setting for extended power base * Integrate SingleRecipeCheck into ProcessingLogic, fix duration overflow, fix duration for batch mode, migrate PA for GT_MetaTileEntity_ExtendedPowerMultiBlockBase * Fixed ME stocking busses * Minor PA fixes * Cleanup item collecting logic & apply to normal multi as well * Oversight * Derp * Multiple voltage instead of amperage with recipe map amperage, since usually amperage is intended for parallel, not for recipe checking * Fix missing EU modifiers on PCB factory OC calculator * Removed left over OC method * Fixed duration calculation of PCB not applying roughness multiplier * Fixed OC parameters * Make createOverclockCalculator nonnull & more nonnull annotations * Fixed input processing voltage * Round down voltage for other machines too * Revert Nano Forge, return correct long voltage * Use region / endregion --------- Co-authored-by: miozune <miozune@gmail.com>
Diffstat (limited to 'src/main/java/gregtech/api/util')
-rw-r--r--src/main/java/gregtech/api/util/GT_OverclockCalculator.java13
-rw-r--r--src/main/java/gregtech/api/util/GT_ParallelHelper.java137
-rw-r--r--src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java9
-rw-r--r--src/main/java/gregtech/api/util/GT_Recipe.java893
-rw-r--r--src/main/java/gregtech/api/util/GT_Single_Recipe_Check.java421
-rw-r--r--src/main/java/gregtech/api/util/GT_Single_Recipe_Check_Processing_Array.java244
-rw-r--r--src/main/java/gregtech/api/util/GT_Utility.java17
-rw-r--r--src/main/java/gregtech/api/util/VoidProtectionHelper.java2
8 files changed, 499 insertions, 1237 deletions
diff --git a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
index ba90240f14..6636b27bc7 100644
--- a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
+++ b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java
@@ -1,5 +1,7 @@
package gregtech.api.util;
+import javax.annotation.Nonnull;
+
public class GT_OverclockCalculator {
/**
@@ -15,7 +17,7 @@ public class GT_OverclockCalculator {
* GT++ machines
* mHeatDiscountAmount - The value used for discount final eut per 900 heat
*/
- private float mEUtDiscount = 1, mSpeedBoost = 1, mHeatDiscountAmount = 0.95f;
+ private double mEUtDiscount = 1, mSpeedBoost = 1, mHeatDiscountAmount = 0.95f;
/**
* mEUtIncreasePerOC - How much the bits should be moved to the left when it is overclocking (Going up, 2 meaning
* it is multiplied with 4x)
@@ -42,6 +44,15 @@ public class GT_OverclockCalculator {
private static final int HEAT_PERFECT_OVERCLOCK_THRESHOLD = 1800;
/**
+ * Creates calculator that doesn't do OC at all.
+ */
+ public static GT_OverclockCalculator ofNoOverclock(@Nonnull GT_Recipe recipe) {
+ return new GT_OverclockCalculator().setRecipeEUt(recipe.mEUt)
+ .setDuration(recipe.mDuration)
+ .setEUt(recipe.mEUt);
+ }
+
+ /**
* An Overclock helper for calculating overclocks in many different situations
*/
public GT_OverclockCalculator() {}
diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
index 9ceec7af44..4c9f53745b 100644
--- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java
+++ b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
@@ -1,11 +1,17 @@
package gregtech.api.util;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
+import gregtech.api.interfaces.tileentity.IRecipeLockable;
import gregtech.api.interfaces.tileentity.IVoidable;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
import gregtech.api.objects.XSTR;
+import gregtech.api.recipe.check.SingleRecipeCheck;
@SuppressWarnings({ "unused", "UnusedReturnValue" })
public class GT_ParallelHelper {
@@ -15,6 +21,14 @@ public class GT_ParallelHelper {
*/
private IVoidable machine;
/**
+ * Machine used for single recipe locking calculation
+ */
+ private IRecipeLockable singleRecipeMachine;
+ /**
+ * Is locked to a single recipe?
+ */
+ private boolean isRecipeLocked;
+ /**
* Recipe used when trying to calculate parallels
*/
private GT_Recipe mRecipe;
@@ -79,7 +93,7 @@ public class GT_ParallelHelper {
/**
* What is the duration multiplier with batch mode enabled
*/
- private float mDurationMultiplier;
+ private double mDurationMultiplier;
/**
* Modifier which is applied on the recipe eut. Useful for GT++ machines
*/
@@ -128,8 +142,14 @@ public class GT_ParallelHelper {
/**
* Sets the recipe, which will be used for the parallel calculation
*/
- public GT_ParallelHelper setRecipe(GT_Recipe aRecipe) {
- mRecipe = aRecipe;
+ public GT_ParallelHelper setRecipe(@Nonnull GT_Recipe aRecipe) {
+ mRecipe = Objects.requireNonNull(aRecipe);
+ return this;
+ }
+
+ public GT_ParallelHelper setRecipeLocked(IRecipeLockable singleRecipeMachine, boolean isRecipeLocked) {
+ this.singleRecipeMachine = singleRecipeMachine;
+ this.isRecipeLocked = isRecipeLocked;
return this;
}
@@ -186,7 +206,7 @@ public class GT_ParallelHelper {
* modifier of 1 does nothing
*/
public GT_ParallelHelper enableBatchMode(int aBatchModifier) {
- mBatchMode = true;
+ mBatchMode = aBatchModifier > 1;
mBatchModifier = aBatchModifier;
return this;
}
@@ -207,6 +227,9 @@ public class GT_ParallelHelper {
if (mBuilt) {
throw new IllegalStateException("Tried to build twice");
}
+ if (mRecipe == null) {
+ throw new IllegalStateException("Recipe is not set");
+ }
mBuilt = true;
determineParallel();
return this;
@@ -225,7 +248,7 @@ public class GT_ParallelHelper {
/**
* @return The duration multiplier if batch mode was enabled for the multiblock
*/
- public float getDurationMultiplier() {
+ public double getDurationMultiplierDouble() {
if (!mBuilt) {
throw new IllegalStateException("Tried to get duration multiplier before building");
}
@@ -236,6 +259,14 @@ public class GT_ParallelHelper {
}
/**
+ * @deprecated Use {@link #getDurationMultiplierDouble()}
+ */
+ @Deprecated
+ public float getDurationMultiplier() {
+ return (float) getDurationMultiplierDouble();
+ }
+
+ /**
* @return The ItemOutputs from the recipe
*/
public ItemStack[] getItemOutputs() {
@@ -264,35 +295,50 @@ public class GT_ParallelHelper {
if (mRecipe.mEUt > mAvailableEUt) {
return;
}
- ItemStack[] tItemInputs = null;
- FluidStack[] tFluidInputs = null;
- long tCurrentUsage = 0;
- // see if people want to consume their inputs with the Parallel Helper or not
+ if (mItemInputs == null) {
+ mItemInputs = new ItemStack[0];
+ }
+ if (mFluidInputs == null) {
+ mFluidInputs = new FluidStack[0];
+ }
+
+ ItemStack[] tItemInputs;
+ FluidStack[] tFluidInputs;
+ // see if people want to consume their inputs or not
if (mConsume) {
tItemInputs = mItemInputs;
tFluidInputs = mFluidInputs;
} else {
- if (mItemInputs == null) {
- tItemInputs = new ItemStack[] {};
- } else {
- tItemInputs = new ItemStack[mItemInputs.length];
- for (int i = 0; i < mItemInputs.length; i++) {
- tItemInputs[i] = mItemInputs[i].copy();
- }
+ // copy to prevent consuming original inputs
+ tItemInputs = new ItemStack[mItemInputs.length];
+ for (int i = 0; i < mItemInputs.length; i++) {
+ tItemInputs[i] = mItemInputs[i].copy();
}
-
- if (mFluidInputs == null) {
- mFluidInputs = new FluidStack[] {};
- } else {
- tFluidInputs = new FluidStack[mFluidInputs.length];
- for (int i = 0; i < mFluidInputs.length; i++) {
- tFluidInputs[i] = mFluidInputs[i].copy();
- }
+ tFluidInputs = new FluidStack[mFluidInputs.length];
+ for (int i = 0; i < mFluidInputs.length; i++) {
+ tFluidInputs[i] = mFluidInputs[i].copy();
}
}
+
if (mBatchMode) {
mMaxParallel *= mBatchModifier;
}
+
+ SingleRecipeCheck recipeCheck = null;
+ SingleRecipeCheck.Builder tSingleRecipeCheckBuilder = null;
+ if (isRecipeLocked && singleRecipeMachine != null) {
+ recipeCheck = singleRecipeMachine.getSingleRecipeCheck();
+ if (recipeCheck == null) {
+ // Machine is configured to lock to a single recipe, but haven't built the recipe checker yet.
+ // Build the checker on next successful recipe.
+ GT_Recipe.GT_Recipe_Map recipeMap = singleRecipeMachine.getRecipeMap();
+ if (recipeMap != null) {
+ tSingleRecipeCheckBuilder = SingleRecipeCheck.builder(recipeMap)
+ .setBefore(tItemInputs, tFluidInputs);
+ }
+ }
+ }
+
// Let's look at how many parallels we can get with void protection
if (protectExcessItem || protectExcessFluid) {
if (machine == null) {
@@ -307,31 +353,50 @@ public class GT_ParallelHelper {
mMaxParallel = Math.min(voidProtectionHelper.getMaxParallel(), mMaxParallel);
}
- float tRecipeEUt = mRecipe.mEUt * mEUtModifier;
+ final int tRecipeEUt = (int) Math.ceil(mRecipe.mEUt * mEUtModifier);
+ final int batchCorrectedMaxParallel = mMaxParallel / mBatchModifier;
// Consume inputs to determine normal parallel
- for (; mCurrentParallel < mMaxParallel / mBatchModifier
- && tCurrentUsage < (mAvailableEUt - tRecipeEUt); mCurrentParallel++) {
- if (mRecipe.isRecipeInputEqual(true, false, tFluidInputs, tItemInputs)) {
+ if (recipeCheck != null) {
+ int actualMaxParallel = (int) Math.min(batchCorrectedMaxParallel, mAvailableEUt / tRecipeEUt);
+ mCurrentParallel = recipeCheck.checkRecipeInputs(true, actualMaxParallel, tItemInputs, tFluidInputs);
+ } else {
+ long tCurrentUsage = 0;
+ boolean builtRecipeCheck = false;
+ for (; mCurrentParallel < batchCorrectedMaxParallel
+ && tCurrentUsage < (mAvailableEUt - tRecipeEUt); mCurrentParallel++) {
+ if (!mRecipe.isRecipeInputEqual(true, false, tFluidInputs, tItemInputs)) {
+ break;
+ }
tCurrentUsage += tRecipeEUt;
- } else {
- break;
+ if (tSingleRecipeCheckBuilder != null && !builtRecipeCheck) {
+ // If recipe checker is not built yet, build and set it
+ SingleRecipeCheck builtCheck = tSingleRecipeCheckBuilder.setAfter(tItemInputs, tFluidInputs)
+ .setRecipe(mRecipe)
+ .build();
+ singleRecipeMachine.setSingleRecipeCheck(builtCheck);
+ builtRecipeCheck = true;
+ }
}
}
// If Batch Mode is enabled determine how many extra parallels we can get
- if (mBatchMode) {
+ if (mBatchMode && mCurrentParallel > 0) {
int tExtraParallels = 0;
- while (tExtraParallels < mCurrentParallel * (mBatchModifier - 1)
- && mRecipe.isRecipeInputEqual(false, false, tFluidInputs, tItemInputs)) {
- mRecipe.isRecipeInputEqual(true, false, tFluidInputs, tItemInputs);
- tExtraParallels++;
+ final int maxExtraParallels = mCurrentParallel * (mBatchModifier - 1);
+ if (recipeCheck != null) {
+ tExtraParallels = recipeCheck.checkRecipeInputs(true, maxExtraParallels, tItemInputs, tFluidInputs);
+ } else {
+ while (tExtraParallels < maxExtraParallels
+ && mRecipe.isRecipeInputEqual(true, false, tFluidInputs, tItemInputs)) {
+ tExtraParallels++;
+ }
}
mDurationMultiplier = 1.0f + (float) tExtraParallels / mCurrentParallel;
mCurrentParallel += tExtraParallels;
}
// If we want to calculate outputs we do it here
- if (mCalculateOutputs) {
+ if (mCalculateOutputs && mCurrentParallel > 0) {
if (mRecipe.mOutputs != null) {
mItemOutputs = new ItemStack[mRecipe.mOutputs.length];
for (int i = 0; i < mRecipe.mOutputs.length; i++) {
diff --git a/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java b/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java
index 66bc16cae3..0ef28bd705 100644
--- a/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java
+++ b/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java
@@ -2,6 +2,8 @@ package gregtech.api.util;
import java.util.HashMap;
+import net.minecraft.item.ItemStack;
+
import gregtech.api.enums.SoundResource;
import gregtech.api.util.GT_Recipe.GT_Recipe_Map;
@@ -38,4 +40,11 @@ public class GT_ProcessingArray_Manager {
}
return null;
}
+
+ public static String getMachineName(ItemStack stack) {
+ int length = stack.getUnlocalizedName()
+ .length();
+ return stack.getUnlocalizedName()
+ .substring(17, length - 8); // trim "gt.blockmachines." and ".tier.xx"
+ }
}
diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java
index 748b922b44..d26b8105cf 100644
--- a/src/main/java/gregtech/api/util/GT_Recipe.java
+++ b/src/main/java/gregtech/api/util/GT_Recipe.java
@@ -9,6 +9,7 @@ import static gregtech.api.enums.Mods.GTPlusPlus;
import static gregtech.api.enums.Mods.GregTech;
import static gregtech.api.enums.Mods.NEICustomDiagrams;
import static gregtech.api.enums.Mods.Railcraft;
+import static gregtech.api.recipe.check.FindRecipeResult.*;
import static gregtech.api.util.GT_RecipeBuilder.handleRecipeCollision;
import static gregtech.api.util.GT_RecipeConstants.ADDITIVE_AMOUNT;
import static gregtech.api.util.GT_RecipeMapUtil.FIRST_FLUIDSTACK_INPUT;
@@ -104,11 +105,11 @@ import gregtech.api.gui.modularui.FallbackableSteamTexture;
import gregtech.api.gui.modularui.GT_UITextures;
import gregtech.api.gui.modularui.SteamTexture;
import gregtech.api.interfaces.IGT_RecipeMap;
-import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.objects.ItemData;
import gregtech.api.objects.MaterialStack;
+import gregtech.api.recipe.check.FindRecipeResult;
import gregtech.api.util.extensions.ArrayExt;
import gregtech.common.gui.modularui.UIHelper;
import gregtech.common.items.GT_FluidDisplayItem;
@@ -3051,6 +3052,14 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
.orElse(Collections.emptyList())));
}
+ @Nullable
+ public static GT_Recipe_Map findRecipeMap(@Nonnull String unlocalizedName) {
+ return sMappings.stream()
+ .filter(m -> unlocalizedName.equals(m.mUnlocalizedName))
+ .findFirst()
+ .orElse(null);
+ }
+
/**
* HashMap of Recipes based on their Items
*/
@@ -3105,6 +3114,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
private boolean mUsesSpecialSlot = false;
/**
+ * Whether this recipemap checks for equality of special slot when searching recipe.
+ */
+ private boolean isSpecialSlotSensitive = false;
+
+ /**
* How many fluid inputs does this recipemap has at most. Currently used only for NEI slot placements and does
* not actually restrict number of fluids used in the recipe.
*/
@@ -3188,6 +3202,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
private int neiTextColorOverride = -1;
private INEISpecialInfoFormatter neiSpecialInfoFormatter;
+
private final boolean checkForCollision = true;
private boolean allowNoInput;
private boolean allowNoInputFluid;
@@ -3293,6 +3308,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
return this;
}
+ public GT_Recipe_Map setSpecialSlotSensitive(boolean isSpecialSlotSensitive) {
+ this.isSpecialSlotSensitive = isSpecialSlotSensitive;
+ return this;
+ }
+
public GT_Recipe_Map setNEIUnificateOutput(boolean mNEIUnificateOutput) {
this.mNEIUnificateOutput = mNEIUnificateOutput;
return this;
@@ -3882,12 +3902,14 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
return aFluid != null && mRecipeFluidNameMap.contains(aFluid.getName());
}
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated, long aVoltage,
+ @Nullable
+ public final GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated, long aVoltage,
FluidStack[] aFluids, ItemStack... aInputs) {
return findRecipe(aTileEntity, null, aNotUnificated, aVoltage, aFluids, null, aInputs);
}
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated,
+ @Nullable
+ public final GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated,
boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) {
return findRecipe(
aTileEntity,
@@ -3900,13 +3922,16 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aInputs);
}
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) {
+ @Nullable
+ public final GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe,
+ boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) {
return findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, null, aInputs);
}
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) {
+ @Nullable
+ public final GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe,
+ boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids,
+ ItemStack... aInputs) {
return findRecipe(
aTileEntity,
aRecipe,
@@ -3918,16 +3943,32 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aInputs);
}
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
+ @Nullable
+ public final GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe,
+ boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
return findRecipe(aTileEntity, aRecipe, aNotUnificated, false, aVoltage, aFluids, aSpecialSlot, aInputs);
}
+ // TODO: make this final after migrating BW
+ @SuppressWarnings("unused")
+ @Nullable
+ public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
+ FindRecipeResult result = findRecipeWithResult(
+ aRecipe,
+ aNotUnificated,
+ aDontCheckStackSizes,
+ aVoltage,
+ aFluids,
+ aSpecialSlot,
+ aInputs);
+ return result.isSuccessful() ? result.getRecipe() : null;
+ }
+
/**
* finds a Recipe matching the aFluid and ItemStack Inputs.
*
- * @param aTileEntity an Object representing the current coordinates of the executing
- * Block/Entity/Whatever. This may be null, especially during Startup.
* @param aRecipe in case this is != null it will try to use this Recipe first when looking things
* up.
* @param aNotUnificated if this is T the Recipe searcher will unificate the ItemStack Inputs
@@ -3938,13 +3979,14 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
* @param aSpecialSlot the content of the Special Slot, the regular Manager doesn't do anything with
* this, but some custom ones do.
* @param aInputs the Item Inputs
- * @return the Recipe it has found or null for no matching Recipe
+ * @return Result of the recipe search
*/
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
+ @Nonnull
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
ItemStack... aInputs) {
// No Recipes? Well, nothing to be found then.
- if (mRecipeList.isEmpty()) return null;
+ if (mRecipeList.isEmpty()) return NOT_FOUND;
// Some Recipe Classes require a certain amount of Inputs of certain kinds. Like "at least 1 Fluid + 1
// Stack" or "at least 2 Stacks" before they start searching for Recipes.
@@ -3952,16 +3994,16 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
// their Machines to select Sub Recipes.
if (GregTech_API.sPostloadFinished) {
if (mMinimalInputFluids > 0) {
- if (aFluids == null) return null;
+ if (aFluids == null) return NOT_FOUND;
int tAmount = 0;
for (FluidStack aFluid : aFluids) if (aFluid != null) tAmount++;
- if (tAmount < mMinimalInputFluids) return null;
+ if (tAmount < mMinimalInputFluids) return NOT_FOUND;
}
if (mMinimalInputItems > 0) {
- if (aInputs == null) return null;
+ if (aInputs == null) return NOT_FOUND;
int tAmount = 0;
for (ItemStack aInput : aInputs) if (aInput != null) tAmount++;
- if (tAmount < mMinimalInputItems) return null;
+ if (tAmount < mMinimalInputItems) return NOT_FOUND;
}
}
@@ -3970,19 +4012,37 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
// Check the Recipe which has been used last time in order to not have to search for it again, if possible.
if (aRecipe != null) if (!aRecipe.mFakeRecipe && aRecipe.mCanBeBuffered
- && aRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs))
- return aRecipe.mEnabled && aVoltage * mAmperage >= aRecipe.mEUt ? aRecipe : null;
+ && aRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) {
+ if (!isSpecialSlotSensitive
+ || GT_Utility.areStacksEqualOrNull((ItemStack) aRecipe.mSpecialItems, aSpecialSlot)) {
+ return aRecipe.mEnabled && aVoltage * mAmperage >= aRecipe.mEUt
+ ? FindRecipeResult.ofSuccess(aRecipe)
+ : FindRecipeResult.ofInsufficientVoltage(aRecipe);
+ }
+ }
// Now look for the Recipes inside the Item HashMaps, but only when the Recipes usually have Items.
if (mUsualInputCount > 0 && aInputs != null) for (ItemStack tStack : aInputs) if (tStack != null) {
Collection<GT_Recipe> tRecipes = mRecipeItemMap.get(new GT_ItemStack(tStack));
if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe
- && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs))
- return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null;
+ && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) {
+ if (!isSpecialSlotSensitive
+ || GT_Utility.areStacksEqualOrNull((ItemStack) tRecipe.mSpecialItems, aSpecialSlot)) {
+ return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt
+ ? FindRecipeResult.ofSuccess(tRecipe)
+ : FindRecipeResult.ofInsufficientVoltage(tRecipe);
+ }
+ }
tRecipes = mRecipeItemMap.get(new GT_ItemStack(tStack, true));
if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe
- && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs))
- return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null;
+ && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) {
+ if (!isSpecialSlotSensitive
+ || GT_Utility.areStacksEqualOrNull((ItemStack) tRecipe.mSpecialItems, aSpecialSlot)) {
+ return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt
+ ? FindRecipeResult.ofSuccess(tRecipe)
+ : FindRecipeResult.ofInsufficientVoltage(tRecipe);
+ }
+ }
}
// If the minimal Amount of Items for the Recipe is 0, then it could be a Fluid-Only Recipe, so check that
@@ -3990,12 +4050,18 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (mMinimalInputItems == 0 && aFluids != null) for (FluidStack aFluid : aFluids) if (aFluid != null) {
Collection<GT_Recipe> tRecipes = mRecipeFluidMap.get(aFluid.getFluid());
if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe
- && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs))
- return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null;
+ && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) {
+ if (!isSpecialSlotSensitive
+ || GT_Utility.areStacksEqualOrNull((ItemStack) tRecipe.mSpecialItems, aSpecialSlot)) {
+ return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt
+ ? FindRecipeResult.ofSuccess(tRecipe)
+ : FindRecipeResult.ofInsufficientVoltage(tRecipe);
+ }
+ }
}
// And nothing has been found.
- return null;
+ return NOT_FOUND;
}
protected GT_Recipe addToItemMap(GT_Recipe aRecipe) {
@@ -4854,24 +4920,28 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
+ if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return NOT_FOUND;
+ if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs))
+ return FindRecipeResult.ofSuccess(aRecipe);
ItemStack tOutput = GT_ModHandler.getSmeltingOutput(aInputs[0], false, null);
- return tOutput == null ? null
- : new GT_Recipe(
- false,
- new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
- new ItemStack[] { tOutput },
- null,
- null,
- null,
- null,
- 128,
- 4,
- 0);
+ return tOutput == null ? NOT_FOUND
+ : FindRecipeResult.ofSuccess(
+ new GT_Recipe(
+ false,
+ new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
+ new ItemStack[] { tOutput },
+ null,
+ null,
+ null,
+ null,
+ 128,
+ 4,
+ 0));
}
@Override
@@ -4907,25 +4977,30 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
+ if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return NOT_FOUND;
+ if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs))
+ return FindRecipeResult.ofSuccess(aRecipe);
ItemStack tOutput = GT_ModHandler.getSmeltingOutput(aInputs[0], false, null);
if (GT_Utility.areStacksEqual(aInputs[0], new ItemStack(Items.book, 1, W))) {
- return new GT_Recipe(
- false,
- new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
- new ItemStack[] { GT_Utility.getWrittenBook("Manual_Microwave", ItemList.Book_Written_03.get(1)) },
- null,
- null,
- null,
- null,
- 32,
- 4,
- 0);
+ return FindRecipeResult.ofSuccess(
+ new GT_Recipe(
+ false,
+ new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
+ new ItemStack[] {
+ GT_Utility.getWrittenBook("Manual_Microwave", ItemList.Book_Written_03.get(1)) },
+ null,
+ null,
+ null,
+ null,
+ 32,
+ 4,
+ 0));
}
// Check Container Item of Input since it is around the Input, then the Input itself, then Container Item of
@@ -4938,12 +5013,9 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
|| GT_Utility.areStacksEqual(tStack, new ItemStack(Items.firework_charge, 1, W), true)
|| GT_Utility.areStacksEqual(tStack, new ItemStack(Items.fireworks, 1, W), true)
|| GT_Utility.areStacksEqual(tStack, new ItemStack(Items.fire_charge, 1, W), true)) {
- if (aTileEntity instanceof IGregTechTileEntity) {
- GT_Log.exp.println(
- "Microwave Explosion due to TNT || EGG || FIREWORKCHARGE || FIREWORK || FIRE CHARGE");
- ((IGregTechTileEntity) aTileEntity).doExplosion(aVoltage * 4);
- }
- return null;
+ GT_Log.exp.println(
+ "Microwave Explosion due to TNT || EGG || FIREWORKCHARGE || FIREWORK || FIRE CHARGE");
+ return EXPLODE;
}
ItemData tData = GT_OreDictUnificator.getItemData(tStack);
@@ -4951,59 +5023,45 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (tData.mMaterial != null && tData.mMaterial.mMaterial != null) {
if (tData.mMaterial.mMaterial.contains(SubTag.METAL)
|| tData.mMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) {
- if (aTileEntity instanceof IGregTechTileEntity) {
- GT_Log.exp.println("Microwave Explosion due to METAL insertion");
- ((IGregTechTileEntity) aTileEntity).doExplosion(aVoltage * 4);
- }
- return null;
+ GT_Log.exp.println("Microwave Explosion due to METAL insertion");
+ return EXPLODE;
}
if (tData.mMaterial.mMaterial.contains(SubTag.FLAMMABLE)) {
- if (aTileEntity instanceof IGregTechTileEntity) {
- GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion");
- ((IGregTechTileEntity) aTileEntity).setOnFire();
- }
- return null;
+ GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion");
+ return ON_FIRE;
}
}
for (MaterialStack tMaterial : tData.mByProducts) if (tMaterial != null) {
if (tMaterial.mMaterial.contains(SubTag.METAL)
|| tMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) {
- if (aTileEntity instanceof IGregTechTileEntity) {
- GT_Log.exp.println("Microwave Explosion due to METAL insertion");
- ((IGregTechTileEntity) aTileEntity).doExplosion(aVoltage * 4);
- }
- return null;
+ GT_Log.exp.println("Microwave Explosion due to METAL insertion");
+ return EXPLODE;
}
if (tMaterial.mMaterial.contains(SubTag.FLAMMABLE)) {
- if (aTileEntity instanceof IGregTechTileEntity) {
- ((IGregTechTileEntity) aTileEntity).setOnFire();
- GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion");
- }
- return null;
+ GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion");
+ return ON_FIRE;
}
}
}
if (TileEntityFurnace.getItemBurnTime(tStack) > 0) {
- if (aTileEntity instanceof IGregTechTileEntity) {
- ((IGregTechTileEntity) aTileEntity).setOnFire();
- GT_Log.exp.println("Microwave INFLAMMATION due to BURNABLE insertion");
- }
- return null;
+ GT_Log.exp.println("Microwave INFLAMMATION due to BURNABLE insertion");
+ return ON_FIRE;
}
}
- return tOutput == null ? null
- : new GT_Recipe(
- false,
- new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
- new ItemStack[] { tOutput },
- null,
- null,
- null,
- null,
- 32,
- 4,
- 0);
+ return tOutput == null ? NOT_FOUND
+ : FindRecipeResult.ofSuccess(
+ new GT_Recipe(
+ false,
+ new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
+ new ItemStack[] { tOutput },
+ null,
+ null,
+ null,
+ null,
+ 32,
+ 4,
+ 0));
}
@Override
@@ -5039,14 +5097,29 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
if (aInputs == null || aInputs.length == 0 || !ItemList.IC2_Scrapbox.isStackEqual(aInputs[0], false, true))
- return super.findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, aSpecialSlot, aInputs);
+ return super.findRecipeWithResult(
+ aRecipe,
+ aNotUnificated,
+ aDontCheckStackSizes,
+ aVoltage,
+ aFluids,
+ aSpecialSlot,
+ aInputs);
ItemStack tOutput = GT_ModHandler.getRandomScrapboxDrop();
- if (tOutput == null)
- return super.findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, aSpecialSlot, aInputs);
+ if (tOutput == null) return super.findRecipeWithResult(
+ aRecipe,
+ aNotUnificated,
+ aDontCheckStackSizes,
+ aVoltage,
+ aFluids,
+ aSpecialSlot,
+ aInputs);
GT_Recipe rRecipe = new GT_Recipe(
false,
new ItemStack[] { ItemList.IC2_Scrapbox.get(1) },
@@ -5063,7 +5136,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
// Due to its randomness it is not good if there are Items in the Output Slot, because those Items could
// manipulate the outcome.
rRecipe.mNeedsEmptyOutput = true;
- return rRecipe;
+ return FindRecipeResult.ofSuccess(rRecipe);
}
@Override
@@ -5099,39 +5172,46 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- GT_Recipe rRecipe = super.findRecipe(
- aTileEntity,
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
+ FindRecipeResult result = super.findRecipeWithResult(
aRecipe,
aNotUnificated,
+ aDontCheckStackSizes,
aVoltage,
aFluids,
aSpecialSlot,
aInputs);
if (aInputs == null || aInputs.length == 0
|| aInputs[0] == null
- || rRecipe != null
- || !GregTech_API.sPostloadFinished) return rRecipe;
+ || result.isSuccessful()
+ || !GregTech_API.sPostloadFinished) return result;
+
if (aFluids != null && aFluids.length > 0 && aFluids[0] != null) {
ItemStack tOutput = GT_Utility.fillFluidContainer(aFluids[0], aInputs[0], false, true);
FluidStack tFluid = GT_Utility.getFluidForFilledItem(tOutput, true);
- if (tFluid != null) rRecipe = new GT_Recipe(
- false,
- new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
- new ItemStack[] { tOutput },
- null,
- null,
- new FluidStack[] { tFluid },
- null,
- Math.max(tFluid.amount / 64, 16),
- 1,
- 0);
+ if (tFluid != null) {
+ GT_Recipe recipe = new GT_Recipe(
+ false,
+ new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
+ new ItemStack[] { tOutput },
+ null,
+ null,
+ new FluidStack[] { tFluid },
+ null,
+ Math.max(tFluid.amount / 64, 16),
+ 1,
+ 0);
+ recipe.mCanBeBuffered = false;
+ return FindRecipeResult.ofSuccess(recipe);
+ }
}
- if (rRecipe == null) {
- FluidStack tFluid = GT_Utility.getFluidForFilledItem(aInputs[0], true);
- if (tFluid != null) rRecipe = new GT_Recipe(
+ FluidStack tFluid = GT_Utility.getFluidForFilledItem(aInputs[0], true);
+ if (tFluid != null) {
+ GT_Recipe recipe = new GT_Recipe(
false,
new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
new ItemStack[] { GT_Utility.getContainerItem(aInputs[0], true) },
@@ -5142,9 +5222,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
Math.max(tFluid.amount / 64, 16),
1,
0);
+ recipe.mCanBeBuffered = false;
+ return FindRecipeResult.ofSuccess(recipe);
}
- if (rRecipe != null) rRecipe.mCanBeBuffered = false;
- return rRecipe;
+ return NOT_FOUND;
}
@Override
@@ -5191,329 +5272,31 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- return new GT_Recipe(
- false,
- new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
- new ItemStack[] { GT_ModHandler.getRecyclerOutput(aInputs[0], 0) },
- null,
- new int[] { 1250 },
- null,
- null,
- 45,
- 1,
- 0);
- }
-
- @Override
- public boolean containsInput(ItemStack aStack) {
- return GT_ModHandler.getRecyclerOutput(aStack, 0) != null;
- }
- }
-
- /**
- * Special Class for Compressor Recipe handling.
- */
- public static class GT_Recipe_Map_Compressor extends GT_Recipe_Map_NonGTRecipes {
-
- public GT_Recipe_Map_Compressor(Collection<GT_Recipe> aRecipeList, String aUnlocalizedName, String aLocalName,
- String aNEIName, String aNEIGUIPath, int aUsualInputCount, int aUsualOutputCount, int aMinimalInputItems,
- int aMinimalInputFluids, int aAmperage, String aNEISpecialValuePre, int aNEISpecialValueMultiplier,
- String aNEISpecialValuePost, boolean aShowVoltageAmperageInNEI, boolean aNEIAllowed) {
- super(
- aRecipeList,
- aUnlocalizedName,
- aLocalName,
- aNEIName,
- aNEIGUIPath,
- aUsualInputCount,
- aUsualOutputCount,
- aMinimalInputItems,
- aMinimalInputFluids,
- aAmperage,
- aNEISpecialValuePre,
- aNEISpecialValueMultiplier,
- aNEISpecialValuePost,
- aShowVoltageAmperageInNEI,
- aNEIAllowed);
- }
-
- @Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
- ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(
- tComparedInput,
- ic2.api.recipe.Recipes.compressor.getRecipes(),
- true,
- new NBTTagCompound(),
- null,
- null,
- null);
- return GT_Utility.arrayContainsNonNull(tOutputItems)
- ? new GT_Recipe(
- false,
- new ItemStack[] {
- GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0]) },
- tOutputItems,
- null,
- null,
- null,
- null,
- 400,
- 2,
- 0)
- : null;
- }
-
- @Override
- public boolean containsInput(ItemStack aStack) {
- return GT_Utility.arrayContainsNonNull(
- GT_ModHandler.getMachineOutput(
- GT_Utility.copyAmount(64, aStack),
- ic2.api.recipe.Recipes.compressor.getRecipes(),
- false,
- new NBTTagCompound(),
- null,
- null,
- null));
- }
- }
-
- /**
- * Special Class for Extractor Recipe handling.
- */
- public static class GT_Recipe_Map_Extractor extends GT_Recipe_Map_NonGTRecipes {
-
- public GT_Recipe_Map_Extractor(Collection<GT_Recipe> aRecipeList, String aUnlocalizedName, String aLocalName,
- String aNEIName, String aNEIGUIPath, int aUsualInputCount, int aUsualOutputCount, int aMinimalInputItems,
- int aMinimalInputFluids, int aAmperage, String aNEISpecialValuePre, int aNEISpecialValueMultiplier,
- String aNEISpecialValuePost, boolean aShowVoltageAmperageInNEI, boolean aNEIAllowed) {
- super(
- aRecipeList,
- aUnlocalizedName,
- aLocalName,
- aNEIName,
- aNEIGUIPath,
- aUsualInputCount,
- aUsualOutputCount,
- aMinimalInputItems,
- aMinimalInputFluids,
- aAmperage,
- aNEISpecialValuePre,
- aNEISpecialValueMultiplier,
- aNEISpecialValuePost,
- aShowVoltageAmperageInNEI,
- aNEIAllowed);
- }
-
- @Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
- ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(
- tComparedInput,
- ic2.api.recipe.Recipes.extractor.getRecipes(),
- true,
- new NBTTagCompound(),
- null,
- null,
- null);
- return GT_Utility.arrayContainsNonNull(tOutputItems)
- ? new GT_Recipe(
- false,
- new ItemStack[] {
- GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0]) },
- tOutputItems,
- null,
- null,
- null,
- null,
- 400,
- 2,
- 0)
- : null;
- }
-
- @Override
- public boolean containsInput(ItemStack aStack) {
- return GT_Utility.arrayContainsNonNull(
- GT_ModHandler.getMachineOutput(
- GT_Utility.copyAmount(64, aStack),
- ic2.api.recipe.Recipes.extractor.getRecipes(),
- false,
- new NBTTagCompound(),
- null,
- null,
- null));
- }
- }
-
- /**
- * Special Class for Thermal Centrifuge Recipe handling.
- */
- public static class GT_Recipe_Map_ThermalCentrifuge extends GT_Recipe_Map_NonGTRecipes {
-
- public GT_Recipe_Map_ThermalCentrifuge(Collection<GT_Recipe> aRecipeList, String aUnlocalizedName,
- String aLocalName, String aNEIName, String aNEIGUIPath, int aUsualInputCount, int aUsualOutputCount,
- int aMinimalInputItems, int aMinimalInputFluids, int aAmperage, String aNEISpecialValuePre,
- int aNEISpecialValueMultiplier, String aNEISpecialValuePost, boolean aShowVoltageAmperageInNEI,
- boolean aNEIAllowed) {
- super(
- aRecipeList,
- aUnlocalizedName,
- aLocalName,
- aNEIName,
- aNEIGUIPath,
- aUsualInputCount,
- aUsualOutputCount,
- aMinimalInputItems,
- aMinimalInputFluids,
- aAmperage,
- aNEISpecialValuePre,
- aNEISpecialValueMultiplier,
- aNEISpecialValuePost,
- aShowVoltageAmperageInNEI,
- aNEIAllowed);
- }
-
- @Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
- ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(
- tComparedInput,
- ic2.api.recipe.Recipes.centrifuge.getRecipes(),
- true,
- new NBTTagCompound(),
- null,
- null,
- null);
- return GT_Utility.arrayContainsNonNull(tOutputItems)
- ? new GT_Recipe(
- false,
- new ItemStack[] {
- GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0]) },
- tOutputItems,
- null,
- null,
- null,
- null,
- 400,
- 48,
- 0)
- : null;
- }
-
- @Override
- public boolean containsInput(ItemStack aStack) {
- return GT_Utility.arrayContainsNonNull(
- GT_ModHandler.getMachineOutput(
- GT_Utility.copyAmount(64, aStack),
- ic2.api.recipe.Recipes.centrifuge.getRecipes(),
- false,
- new NBTTagCompound(),
- null,
- null,
- null));
- }
- }
-
- /**
- * Special Class for Ore Washer Recipe handling.
- */
- public static class GT_Recipe_Map_OreWasher extends GT_Recipe_Map_NonGTRecipes {
-
- public GT_Recipe_Map_OreWasher(Collection<GT_Recipe> aRecipeList, String aUnlocalizedName, String aLocalName,
- String aNEIName, String aNEIGUIPath, int aUsualInputCount, int aUsualOutputCount, int aMinimalInputItems,
- int aMinimalInputFluids, int aAmperage, String aNEISpecialValuePre, int aNEISpecialValueMultiplier,
- String aNEISpecialValuePost, boolean aShowVoltageAmperageInNEI, boolean aNEIAllowed) {
- super(
- aRecipeList,
- aUnlocalizedName,
- aLocalName,
- aNEIName,
- aNEIGUIPath,
- aUsualInputCount,
- aUsualOutputCount,
- aMinimalInputItems,
- aMinimalInputFluids,
- aAmperage,
- aNEISpecialValuePre,
- aNEISpecialValueMultiplier,
- aNEISpecialValuePost,
- aShowVoltageAmperageInNEI,
- aNEIAllowed);
- }
-
- @Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- if (aInputs == null || aInputs.length == 0
- || aInputs[0] == null
- || aFluids == null
- || aFluids.length < 1
- || !GT_ModHandler.isWater(aFluids[0])) return null;
- if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return aRecipe;
- ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]);
- NBTTagCompound aRecipeMetaData = new NBTTagCompound();
- ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput(
- tComparedInput,
- ic2.api.recipe.Recipes.oreWashing.getRecipes(),
- true,
- aRecipeMetaData,
- null,
- null,
- null);
- return GT_Utility.arrayContainsNonNull(tOutputItems)
- ? new GT_Recipe(
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
+ if (aInputs == null || aInputs.length == 0 || aInputs[0] == null) return NOT_FOUND;
+ if (aRecipe != null && aRecipe.isRecipeInputEqual(false, true, aFluids, aInputs))
+ return FindRecipeResult.ofSuccess(aRecipe);
+ return FindRecipeResult.ofSuccess(
+ new GT_Recipe(
false,
- new ItemStack[] {
- GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0]) },
- tOutputItems,
+ new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
+ new ItemStack[] { GT_ModHandler.getRecyclerOutput(aInputs[0], 0) },
null,
+ new int[] { 1250 },
null,
- new FluidStack[] { new FluidStack(
- aFluids[0].getFluid(),
- ((NBTTagCompound) aRecipeMetaData.getTag("return")).getInteger("amount")) },
null,
- 400,
- 16,
- 0)
- : null;
+ 45,
+ 1,
+ 0));
}
@Override
public boolean containsInput(ItemStack aStack) {
- return GT_Utility.arrayContainsNonNull(
- GT_ModHandler.getMachineOutput(
- GT_Utility.copyAmount(64, aStack),
- ic2.api.recipe.Recipes.oreWashing.getRecipes(),
- false,
- new NBTTagCompound(),
- null,
- null,
- null));
- }
-
- @Override
- public boolean containsInput(FluidStack aFluid) {
- return GT_ModHandler.isWater(aFluid);
- }
-
- @Override
- public boolean containsInput(Fluid aFluid) {
- return GT_ModHandler.isWater(new FluidStack(aFluid, 0));
+ return GT_ModHandler.getRecyclerOutput(aStack, 0) != null;
}
}
@@ -5544,20 +5327,36 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
if (aInputs == null || aInputs.length == 0 || aInputs[0] == null || !GregTech_API.sPostloadFinished)
- return super.findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, aSpecialSlot, aInputs);
- aRecipe = super.findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, aSpecialSlot, aInputs);
- if (aRecipe != null) return aRecipe;
+ return super.findRecipeWithResult(
+ aRecipe,
+ aNotUnificated,
+ aDontCheckStackSizes,
+ aVoltage,
+ aFluids,
+ aSpecialSlot,
+ aInputs);
+ FindRecipeResult result = super.findRecipeWithResult(
+ aRecipe,
+ aNotUnificated,
+ aDontCheckStackSizes,
+ aVoltage,
+ aFluids,
+ aSpecialSlot,
+ aInputs);
+ if (result.isSuccessful()) return result;
try {
List<ItemStack> tRecipeOutputs = mods.railcraft.api.crafting.RailcraftCraftingManager.rockCrusher
.getRecipe(GT_Utility.copyAmount(1, aInputs[0]))
.getRandomizedOuputs();
if (tRecipeOutputs != null) {
- aRecipe = new GT_Recipe(
+ GT_Recipe recipe = new GT_Recipe(
false,
new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
tRecipeOutputs.toArray(new ItemStack[0]),
@@ -5568,9 +5367,9 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
800,
2,
0);
- aRecipe.mCanBeBuffered = false;
- aRecipe.mNeedsEmptyOutput = true;
- return aRecipe;
+ recipe.mCanBeBuffered = false;
+ recipe.mNeedsEmptyOutput = true;
+ return FindRecipeResult.ofSuccess(recipe);
}
} catch (NoClassDefFoundError e) {
if (D1) GT_Log.err.println("Railcraft Not loaded");
@@ -5587,20 +5386,22 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
null,
null,
null);
- return GT_Utility.arrayContainsNonNull(tOutputItems)
- ? new GT_Recipe(
- false,
- new ItemStack[] {
- GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0]) },
- tOutputItems,
- null,
- null,
- null,
- null,
- 400,
- 2,
- 0)
- : null;
+ if (tComparedInput != null && GT_Utility.arrayContainsNonNull(tOutputItems)) {
+ return FindRecipeResult.ofSuccess(
+ new GT_Recipe(
+ false,
+ new ItemStack[] {
+ GT_Utility.copyAmount(aInputs[0].stackSize - tComparedInput.stackSize, aInputs[0]) },
+ tOutputItems,
+ null,
+ null,
+ null,
+ null,
+ 400,
+ 2,
+ 0));
+ }
+ return NOT_FOUND;
}
@Override
@@ -5644,11 +5445,20 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
- GT_Recipe rRecipe = super.findRecipe(aTileEntity, aRecipe, true, aVoltage, aFluids, aSpecialSlot, aInputs);
+ FindRecipeResult result = super.findRecipeWithResult(
+ aRecipe,
+ true,
+ aDontCheckStackSizes,
+ aVoltage,
+ aFluids,
+ aSpecialSlot,
+ aInputs);
/*
* Doesnt work, keep it as a reminder tho if (rRecipe == null){ Set<ItemStack> aInputs2 = new
* TreeSet<ItemStack>(); for (ItemStack aInput : aInputs) { aInputs2.add(aInput); } for (ItemStack aInput :
@@ -5662,9 +5472,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
*/
if (aInputs == null || aInputs.length == 0
|| aInputs[0] == null
- || rRecipe == null
- || !GregTech_API.sPostloadFinished) return rRecipe;
+ || !result.isSuccessful()
+ || !GregTech_API.sPostloadFinished) return result;
+ GT_Recipe rRecipe = result.getRecipeNonNull();
for (ItemStack aInput : aInputs) {
if (ItemList.Paper_Printed_Pages.isStackEqual(aInput, false, true)) {
rRecipe = rRecipe.copy();
@@ -5672,7 +5483,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
rRecipe.mOutputs[0].setTagCompound(aInput.getTagCompound());
}
}
- return rRecipe;
+ return FindRecipeResult.ofSuccess(rRecipe);
}
}
@@ -5703,12 +5514,12 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
ItemStack... aInputs) {
- GT_Recipe rRecipe = super.findRecipe(
- aTileEntity,
+ FindRecipeResult result = super.findRecipeWithResult(
aRecipe,
aNotUnificated,
aDontCheckStackSizes,
@@ -5716,8 +5527,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aFluids,
aSpecialSlot,
aInputs);
- if (aInputs == null || aInputs.length < 2 || !GregTech_API.sPostloadFinished) return rRecipe;
- if (rRecipe == null) return findRenamingRecipe(aInputs);
+ if (aInputs == null || aInputs.length < 2 || !GregTech_API.sPostloadFinished) return result;
+ if (!result.isSuccessful()) {
+ return findRenamingRecipe(aInputs);
+ }
for (ItemStack aMold : aInputs) {
if (ItemList.Shape_Mold_Credit.isStackEqual(aMold, false, true)) {
NBTTagCompound tNBT = aMold.getTagCompound();
@@ -5725,13 +5538,14 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
if (!tNBT.hasKey("credit_security_id")) tNBT.setLong("credit_security_id", System.nanoTime());
aMold.setTagCompound(tNBT);
+ GT_Recipe rRecipe = result.getRecipeNonNull();
rRecipe = rRecipe.copy();
rRecipe.mCanBeBuffered = false;
rRecipe.mOutputs[0].setTagCompound(tNBT);
- return rRecipe;
+ return FindRecipeResult.ofSuccess(rRecipe);
}
}
- return rRecipe;
+ return result;
}
private ItemStack findNameMoldIndex(ItemStack[] inputs) {
@@ -5749,12 +5563,14 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
return null;
}
- private GT_Recipe findRenamingRecipe(ItemStack[] inputs) {
+ @Nonnull
+ private FindRecipeResult findRenamingRecipe(ItemStack[] inputs) {
ItemStack mold = findNameMoldIndex(inputs);
- if (mold == null) return null;
+ if (mold == null) return NOT_FOUND;
ItemStack input = findStackToRename(inputs, mold);
- if (input == null) return null;
+ if (input == null) return NOT_FOUND;
ItemStack output = GT_Utility.copyAmount(1, input);
+ if (output == null) return NOT_FOUND;
output.setStackDisplayName(mold.getDisplayName());
GT_Recipe recipe = new GT_Recipe(
false,
@@ -5768,7 +5584,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
8,
0);
recipe.mCanBeBuffered = false;
- return recipe;
+ return FindRecipeResult.ofSuccess(recipe);
}
}
@@ -5799,13 +5615,15 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aNEIAllowed);
}
+ @Nonnull
@Override
- public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated,
- long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) {
- GT_Recipe rRecipe = super.findRecipe(
- aTileEntity,
+ public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated,
+ boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot,
+ ItemStack... aInputs) {
+ FindRecipeResult result = super.findRecipeWithResult(
aRecipe,
aNotUnificated,
+ aDontCheckStackSizes,
aVoltage,
aFluids,
aSpecialSlot,
@@ -5815,7 +5633,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
|| aFluids == null
|| aFluids.length == 0
|| aFluids[0] == null
- || !GregTech_API.sPostloadFinished) return rRecipe;
+ || !GregTech_API.sPostloadFinished) return result;
Dyes aDye = null;
for (Dyes tDye : Dyes.VALUES) if (tDye.isFluidDye(aFluids[0])) {
@@ -5823,11 +5641,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
break;
}
- if (aDye == null) return rRecipe;
+ if (aDye == null) return result;
- if (rRecipe == null) {
+ if (!result.isSuccessful()) {
ItemStack tOutput = GT_ModHandler.getAllRecipeOutput(
- aTileEntity == null ? null : aTileEntity.getWorld(),
+ null,
aInputs[0],
aInputs[0],
aInputs[0],
@@ -5837,67 +5655,72 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
aInputs[0],
aInputs[0],
aInputs[0]);
- if (tOutput != null) return addRecipe(
- new GT_Recipe(
- true,
- new ItemStack[] { GT_Utility.copyAmount(8, aInputs[0]) },
- new ItemStack[] { tOutput },
- null,
- null,
- new FluidStack[] { new FluidStack(aFluids[0].getFluid(), (int) L) },
- null,
- 256,
- 2,
- 0),
- false,
- false,
- true);
+ if (tOutput != null) {
+ GT_Recipe recipe = addRecipe(
+ new GT_Recipe(
+ true,
+ new ItemStack[] { GT_Utility.copyAmount(8, aInputs[0]) },
+ new ItemStack[] { tOutput },
+ null,
+ null,
+ new FluidStack[] { new FluidStack(aFluids[0].getFluid(), (int) L) },
+ null,
+ 256,
+ 2,
+ 0),
+ false,
+ false,
+ true);
+ return recipe != null ? FindRecipeResult.ofSuccess(recipe) : NOT_FOUND;
+ }
- tOutput = GT_ModHandler.getAllRecipeOutput(
- aTileEntity == null ? null : aTileEntity.getWorld(),
- aInputs[0],
- ItemList.DYE_ONLY_ITEMS[aDye.mIndex].get(1));
- if (tOutput != null) return addRecipe(
- new GT_Recipe(
- true,
- new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
- new ItemStack[] { tOutput },
- null,
- null,
- new FluidStack[] { new FluidStack(aFluids[0].getFluid(), (int) L) },
- null,
- 32,
- 2,
- 0),
- false,
- false,
- true);
+ tOutput = GT_ModHandler
+ .getAllRecipeOutput(null, aInputs[0], ItemList.DYE_ONLY_ITEMS[aDye.mIndex].get(1));
+ if (tOutput != null) {
+ GT_Recipe recipe = addRecipe(
+ new GT_Recipe(
+ true,
+ new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) },
+ new ItemStack[] { tOutput },
+ null,
+ null,
+ new FluidStack[] { new FluidStack(aFluids[0].getFluid(), (int) L) },
+ null,
+ 32,
+ 2,
+ 0),
+ false,
+ false,
+ true);
+ return recipe != null ? FindRecipeResult.ofSuccess(recipe) : NOT_FOUND;
+ }
} else {
+ GT_Recipe rRecipe = result.getRecipeNonNull();
if (aInputs[0].getItem() == Items.paper) {
- if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return null;
+ if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return NOT_FOUND;
NBTTagCompound tNBT = aSpecialSlot.getTagCompound();
if (tNBT == null || GT_Utility.isStringInvalid(tNBT.getString("title"))
- || GT_Utility.isStringInvalid(tNBT.getString("author"))) return null;
+ || GT_Utility.isStringInvalid(tNBT.getString("author"))) return NOT_FOUND;
rRecipe = rRecipe.copy();
rRecipe.mCanBeBuffered = false;
rRecipe.mOutputs[0].setTagCompound(tNBT);
- return rRecipe;
+ return FindRecipeResult.ofSuccess(rRecipe);
}
if (aInputs[0].getItem() == Items.map) {
- if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return null;
+ if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return NOT_FOUND;
NBTTagCompound tNBT = aSpecialSlot.getTagCompound();
- if (tNBT == null || !tNBT.hasKey("map_id")) return null;
+ if (tNBT == null || !tNBT.hasKey("map_id")) return NOT_FOUND;
rRecipe = rRecipe.copy();
rRecipe.mCanBeBuffered = false;
rRecipe.mOutputs[0].setItemDamage(tNBT.getShort("map_id"));
- return rRecipe;
+ return FindRecipeResult.ofSuccess(rRecipe);
}
if (ItemList.Paper_Punch_Card_Empty.isStackEqual(aInputs[0], false, true)) {
- if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return null;
+ if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return NOT_FOUND;
NBTTagCompound tNBT = aSpecialSlot.getTagCompound();
- if (tNBT == null || !tNBT.hasKey("GT.PunchCardData")) return null;
+ if (tNBT == null || !tNBT.hasKey("GT.PunchCardData")) return NOT_FOUND;
rRecipe = rRecipe.copy();
rRecipe.mCanBeBuffered = false;
@@ -5906,10 +5729,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> {
new NBTTagCompound(),
"GT.PunchCardData",
tNBT.getString("GT.PunchCardData")));
- return rRecipe;
+ return FindRecipeResult.ofSuccess(rRecipe);
}
}
- return rRecipe;
+ return result;
}
@Override
diff --git a/src/main/java/gregtech/api/util/GT_Single_Recipe_Check.java b/src/main/java/gregtech/api/util/GT_Single_Recipe_Check.java
deleted file mode 100644
index f939275e6c..0000000000
--- a/src/main/java/gregtech/api/util/GT_Single_Recipe_Check.java
+++ /dev/null
@@ -1,421 +0,0 @@
-package gregtech.api.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import javax.annotation.Nullable;
-
-import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTBase;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraftforge.common.util.Constants;
-import net.minecraftforge.fluids.Fluid;
-import net.minecraftforge.fluids.FluidRegistry;
-import net.minecraftforge.fluids.FluidStack;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-import gregtech.api.enums.GT_Values;
-import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
-
-/** Used by machines that are locked to a single recipe, for fast computation. */
-public class GT_Single_Recipe_Check {
-
- protected final GT_MetaTileEntity_MultiBlockBase multiBlockBase;
- protected final GT_Recipe recipe;
- protected final ImmutableMap<GT_Utility.ItemId, Integer> itemCost;
- protected final ImmutableMap<Fluid, Integer> fluidCost;
-
- protected final int totalItemCost;
- protected final int totalFluidCost;
-
- protected GT_Single_Recipe_Check(GT_MetaTileEntity_MultiBlockBase multiBlockBase, GT_Recipe recipe,
- ImmutableMap<GT_Utility.ItemId, Integer> itemCost, ImmutableMap<Fluid, Integer> fluidCost) {
- this.multiBlockBase = multiBlockBase;
- this.recipe = recipe;
- this.itemCost = itemCost;
- this.fluidCost = fluidCost;
-
- this.totalItemCost = itemCost.values()
- .stream()
- .mapToInt(Integer::intValue)
- .sum();
- this.totalFluidCost = fluidCost.values()
- .stream()
- .mapToInt(Integer::intValue)
- .sum();
- }
-
- public GT_Recipe getRecipe() {
- return recipe;
- }
-
- /**
- * Use this method if recipes cannot require more than a single stack of any item or fluid. In particular,
- * {@link GT_MetaTileEntity_MultiBlockBase#getCompactedInputs()} and
- * {@link GT_MetaTileEntity_MultiBlockBase#getCompactedFluids()} both enforce this single-stack restriction, so any
- * multi-block that calls those can use this method.
- */
- @SuppressWarnings("JavadocReference")
- public boolean checkRecipeInputsSingleStack(boolean consumeInputs) {
- Map<GT_Utility.ItemId, ItemStack> itemMap = null;
- if (totalItemCost > 0) {
- itemMap = new HashMap<>();
- for (ItemStack itemStack : multiBlockBase.getStoredInputs()) {
- itemMap.merge(
- GT_Utility.ItemId.createNoCopy(itemStack),
- itemStack,
- (a, b) -> a.stackSize >= b.stackSize ? a : b);
- }
-
- for (Map.Entry<GT_Utility.ItemId, Integer> entry : itemCost.entrySet()) {
- ItemStack itemStack = itemMap.get(entry.getKey());
- if (itemStack == null || itemStack.stackSize < entry.getValue()) {
- return false;
- }
- }
- }
-
- Map<Fluid, FluidStack> fluidMap = null;
- if (totalFluidCost > 0) {
- fluidMap = new HashMap<>();
- for (FluidStack fluidStack : multiBlockBase.getStoredFluids()) {
- fluidMap.merge(fluidStack.getFluid(), fluidStack, (a, b) -> a.amount >= b.amount ? a : b);
- }
-
- for (Map.Entry<Fluid, Integer> entry : fluidCost.entrySet()) {
- FluidStack fluidStack = fluidMap.get(entry.getKey());
- if (fluidStack == null || fluidStack.amount < entry.getValue()) {
- return false;
- }
- }
- }
-
- if (consumeInputs) {
- if (totalItemCost > 0) {
- for (Map.Entry<GT_Utility.ItemId, Integer> entry : itemCost.entrySet()) {
- itemMap.get(entry.getKey()).stackSize -= entry.getValue();
- }
- }
-
- if (totalFluidCost > 0) {
- for (Map.Entry<Fluid, Integer> entry : fluidCost.entrySet()) {
- fluidMap.get(entry.getKey()).amount -= entry.getValue();
- }
- }
- }
-
- return true;
- }
-
- /**
- * Use this method if recipes can require more than a single stack of any item or fluid. It is less efficient,
- * though.
- */
- public boolean checkRecipeInputs(boolean consumeInputs) {
- List<ItemStack> items = null;
- if (totalItemCost > 0) {
- items = multiBlockBase.getStoredInputs();
-
- Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>();
- for (ItemStack itemStack : items) {
- itemMap.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum);
- }
-
- for (Map.Entry<GT_Utility.ItemId, Integer> entry : itemCost.entrySet()) {
- if (itemMap.getOrDefault(entry.getKey(), 0) < entry.getValue()) {
- return false;
- }
- }
- }
-
- List<FluidStack> fluids = null;
- if (totalFluidCost > 0) {
- fluids = multiBlockBase.getStoredFluids();
-
- Map<Fluid, Integer> fluidMap = new HashMap<>();
- for (FluidStack fluidStack : fluids) {
- fluidMap.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
- }
-
- for (Map.Entry<Fluid, Integer> entry : fluidCost.entrySet()) {
- if (fluidMap.getOrDefault(entry.getKey(), 0) < entry.getValue()) {
- return false;
- }
- }
- }
-
- if (consumeInputs) {
- if (totalItemCost > 0) {
- int remainingItemCost = totalItemCost;
- Map<GT_Utility.ItemId, Integer> runningItemCost = Maps.newHashMap(itemCost);
- for (ItemStack itemStack : items) {
- GT_Utility.ItemId key = GT_Utility.ItemId.createNoCopy(itemStack);
- int runningCost = runningItemCost.getOrDefault(key, 0);
- int paid = Math.min(itemStack.stackSize, runningCost);
- itemStack.stackSize -= paid;
- runningItemCost.put(key, runningCost - paid);
-
- remainingItemCost -= paid;
- if (remainingItemCost <= 0) {
- break;
- }
- }
- }
-
- if (totalFluidCost > 0) {
- int remainingFluidCost = totalFluidCost;
- Map<Fluid, Integer> runningFluidCost = Maps.newHashMap(fluidCost);
- for (FluidStack fluidStack : fluids) {
- Fluid key = fluidStack.getFluid();
- int runningCost = runningFluidCost.getOrDefault(key, 0);
- int paid = Math.min(fluidStack.amount, runningCost);
- fluidStack.amount -= paid;
- runningFluidCost.put(key, runningCost - paid);
-
- remainingFluidCost -= paid;
- if (remainingFluidCost <= 0) {
- break;
- }
- }
- }
- }
-
- return true;
- }
-
- public NBTTagCompound writeToNBT() {
- // here we encode recipe input, output and all other important values
- // at load time we do a recipe check again, so in case the recipe is gone, we can stop tracking
- // of course the next step would be auto migrating to new recipe (if any), but given
- // we don't yet have a mean to uniquely name a recipe, this will have to make do.
- // consider move serialization code to GT_Recipe once this has been proven to work
- NBTTagCompound tag = new NBTTagCompound();
- if (recipe == null) return tag;
-
- if (recipe.mInputs != null) {
- tag.setTag("inputs", writeList(recipe.mInputs, GT_Utility::saveItem));
- }
- if (recipe.mOutputs != null) {
- tag.setTag("outputs", writeList(recipe.mOutputs, GT_Utility::saveItem));
- }
- if (recipe.mChances != null) {
- tag.setIntArray("chances", recipe.mChances);
- }
- if (recipe.mFluidInputs != null) {
- tag.setTag(
- "fInputs",
- writeList(
- recipe.mFluidInputs,
- s -> s == null ? new NBTTagCompound() : s.writeToNBT(new NBTTagCompound())));
- }
- if (recipe.mFluidOutputs != null) {
- tag.setTag(
- "fOutputs",
- writeList(
- recipe.mFluidOutputs,
- s -> s == null ? new NBTTagCompound() : s.writeToNBT(new NBTTagCompound())));
- }
- tag.setInteger("eut", recipe.mEUt);
- tag.setInteger("duration", recipe.mDuration);
- tag.setInteger("specialValue", recipe.mSpecialValue);
- if (itemCost != null) {
- tag.setTag("itemCost", writeList(itemCost.entrySet(), e -> {
- NBTTagCompound ret = new NBTTagCompound();
- ret.setTag(
- "id",
- e.getKey()
- .writeToNBT());
- ret.setInteger("count", e.getValue());
- return ret;
- }));
- }
- if (fluidCost != null) {
- tag.setTag("fluidCost", writeList(fluidCost.entrySet(), e -> {
- NBTTagCompound ret = new NBTTagCompound();
- ret.setString(
- "id",
- e.getKey()
- .getName());
- ret.setInteger("count", e.getValue());
- return ret;
- }));
- }
- return tag;
- }
-
- private static <T, NBT extends NBTBase> NBTTagList writeList(T[] arr, Function<T, NBT> ser) {
- return writeList(Arrays.asList(arr), ser);
- }
-
- private static <T, NBT extends NBTBase> NBTTagList writeList(Collection<T> arr, Function<T, NBT> ser) {
- NBTTagList l = new NBTTagList();
- for (T t : arr) {
- l.appendTag(ser.apply(t));
- }
- return l;
- }
-
- @Nullable
- public static GT_Single_Recipe_Check tryLoad(GT_MetaTileEntity_MultiBlockBase parent, NBTTagCompound tag) {
- return tryLoad(parent, parent.getRecipeMap(), tag);
- }
-
- @Nullable
-
- public static GT_Single_Recipe_Check tryLoad(GT_MetaTileEntity_MultiBlockBase parent,
- GT_Recipe.GT_Recipe_Map recipeMap, NBTTagCompound tag) {
- GT_Recipe found = tryFindRecipe(parent, recipeMap, tag);
- if (found == null) return null;
- return new GT_Single_Recipe_Check(parent, found, loadItemCost(tag), loadFluidCost(tag));
- }
-
- protected static ImmutableMap<Fluid, Integer> loadFluidCost(NBTTagCompound tag) {
- return GT_Utility.streamCompounds(tag.getTagList("fluidCost", Constants.NBT.TAG_COMPOUND))
- .collect(
- GT_Utility
- .toImmutableMapSerial(t -> FluidRegistry.getFluid(t.getString("id")), t -> t.getInteger("count")));
- }
-
- protected static ImmutableMap<GT_Utility.ItemId, Integer> loadItemCost(NBTTagCompound tag) {
- return GT_Utility.streamCompounds(tag.getTagList("itemCost", Constants.NBT.TAG_COMPOUND))
- .collect(
- GT_Utility.toImmutableMapSerial(
- t -> GT_Utility.ItemId.create(t.getCompoundTag("id")),
- t -> t.getInteger("count")));
- }
-
- protected static GT_Recipe tryFindRecipe(GT_MetaTileEntity_MultiBlockBase parent, GT_Recipe.GT_Recipe_Map recipeMap,
- NBTTagCompound tag) {
- if (tag == null || tag.hasNoTags()) return null;
- ItemStack[] inputs = GT_Utility.streamCompounds(tag.getTagList("inputs", Constants.NBT.TAG_COMPOUND))
- .map(GT_Utility::loadItem)
- .toArray(ItemStack[]::new);
- ItemStack[] outputs = GT_Utility.streamCompounds(tag.getTagList("outputs", Constants.NBT.TAG_COMPOUND))
- .map(GT_Utility::loadItem)
- .toArray(ItemStack[]::new);
- FluidStack[] fInputs = GT_Utility.streamCompounds(tag.getTagList("fInputs", Constants.NBT.TAG_COMPOUND))
- .map(FluidStack::loadFluidStackFromNBT)
- .toArray(FluidStack[]::new);
- FluidStack[] fOutputs = GT_Utility.streamCompounds(tag.getTagList("fOutputs", Constants.NBT.TAG_COMPOUND))
- .map(FluidStack::loadFluidStackFromNBT)
- .toArray(FluidStack[]::new);
- int eut = tag.getInteger("eut");
- GT_Recipe found = recipeMap
- .findRecipe(parent.getBaseMetaTileEntity(), false, GT_Values.V[GT_Utility.getTier(eut)], fInputs, inputs);
- int[] chances = tag.getIntArray("chances");
- if (chances.length == 0) chances = null;
- if (found == null || !GT_Utility.equals(inputs, found.mInputs)
- || !Arrays.equals(fInputs, found.mFluidInputs)
- || !GT_Utility.equals(outputs, found.mOutputs)
- || !Arrays.equals(fOutputs, found.mFluidOutputs)
- || !Arrays.equals(chances, found.mChances)
- || found.mDuration != tag.getInteger("duration")
- || found.mEUt != eut
- || found.mSpecialValue != tag.getInteger("specialValue")) return null;
- return found;
- }
-
- protected static Map<GT_Utility.ItemId, Integer> buildItemMap(GT_MetaTileEntity_MultiBlockBase multiBlockBase) {
- Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>();
- for (ItemStack itemStack : multiBlockBase.getStoredInputs()) {
- itemMap.merge(GT_Utility.ItemId.create(itemStack), itemStack.stackSize, Integer::sum);
- }
- return itemMap;
- }
-
- protected static Map<Fluid, Integer> buildFluidMap(GT_MetaTileEntity_MultiBlockBase multiBlockBase) {
- Map<Fluid, Integer> fluidMap = new HashMap<>();
- for (FluidStack fluidStack : multiBlockBase.getStoredFluids()) {
- fluidMap.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
- }
- return fluidMap;
- }
-
- public static Builder builder(GT_MetaTileEntity_MultiBlockBase multiBlockBase) {
- return new Builder(multiBlockBase);
- }
-
- public static final class Builder {
-
- private final GT_MetaTileEntity_MultiBlockBase multiBlockBase;
-
- // In order to compute which items and fluids are consumed by the recipe, we compare the
- // multi-block's items and fluids before and after inputs are consumed by the recipe.
- private Map<GT_Utility.ItemId, Integer> beforeItems;
- private Map<Fluid, Integer> beforeFluids;
- private Map<GT_Utility.ItemId, Integer> afterItems;
- private Map<Fluid, Integer> afterFluids;
-
- private GT_Recipe recipe;
-
- private Builder(GT_MetaTileEntity_MultiBlockBase multiBlockBase) {
- this.multiBlockBase = multiBlockBase;
- }
-
- /** Call this before inputs are consumed by the recipe. */
- public Builder setBefore(ItemStack[] inputs, FluidStack[] fluids) {
- beforeItems = buildItemMapDirect(inputs);
- beforeFluids = buildFluidMapDirect(fluids);
- return this;
- }
-
- /** Call this after inputs are consumed by the recipe. */
- public Builder setAfter(ItemStack[] inputs, FluidStack[] fluids) {
- afterItems = buildItemMapDirect(inputs);
- afterFluids = buildFluidMapDirect(fluids);
- return this;
- }
-
- public Builder setRecipe(GT_Recipe recipe) {
- this.recipe = recipe;
- return this;
- }
-
- static Map<GT_Utility.ItemId, Integer> buildItemMapDirect(ItemStack[] inputs) {
- Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>();
- for (ItemStack itemStack : inputs) {
- itemMap.merge(GT_Utility.ItemId.create(itemStack), itemStack.stackSize, Integer::sum);
- }
- return itemMap;
- }
-
- static Map<Fluid, Integer> buildFluidMapDirect(FluidStack[] fluids) {
- Map<Fluid, Integer> fluidMap = new HashMap<>();
- for (FluidStack fluidStack : fluids) {
- fluidMap.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
- }
- return fluidMap;
- }
-
- public GT_Single_Recipe_Check build() {
- ImmutableMap.Builder<GT_Utility.ItemId, Integer> itemCostBuilder = ImmutableMap.builder();
- for (Map.Entry<GT_Utility.ItemId, Integer> entry : beforeItems.entrySet()) {
- int cost = entry.getValue() - afterItems.getOrDefault(entry.getKey(), 0);
- if (cost > 0) {
- itemCostBuilder.put(entry.getKey(), cost);
- }
- }
-
- ImmutableMap.Builder<Fluid, Integer> fluidCostBuilder = ImmutableMap.builder();
- for (Map.Entry<Fluid, Integer> entry : beforeFluids.entrySet()) {
- int cost = entry.getValue() - afterFluids.getOrDefault(entry.getKey(), 0);
- if (cost > 0) {
- fluidCostBuilder.put(entry.getKey(), cost);
- }
- }
-
- return new GT_Single_Recipe_Check(
- multiBlockBase,
- recipe,
- itemCostBuilder.build(),
- fluidCostBuilder.build());
- }
- }
-}
diff --git a/src/main/java/gregtech/api/util/GT_Single_Recipe_Check_Processing_Array.java b/src/main/java/gregtech/api/util/GT_Single_Recipe_Check_Processing_Array.java
deleted file mode 100644
index ad0ca76a6d..0000000000
--- a/src/main/java/gregtech/api/util/GT_Single_Recipe_Check_Processing_Array.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package gregtech.api.util;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.annotation.Nullable;
-
-import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraftforge.fluids.Fluid;
-import net.minecraftforge.fluids.FluidStack;
-
-import com.google.common.collect.ImmutableMap;
-
-import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
-
-/** Processing Array-specialized version of {@link gregtech.api.util.GT_Single_Recipe_Check}. */
-public class GT_Single_Recipe_Check_Processing_Array extends GT_Single_Recipe_Check {
-
- protected final int recipeAmperage;
-
- /**
- * The machine type that the locked recipe is for. We will not allow running with other machines.
- */
- protected final ItemStack machineStack;
-
- protected GT_Single_Recipe_Check_Processing_Array(GT_MetaTileEntity_MultiBlockBase multiBlockBase, GT_Recipe recipe,
- ImmutableMap<GT_Utility.ItemId, Integer> itemCost, ImmutableMap<Fluid, Integer> fluidCost, int recipeAmperage,
- ItemStack machineStack) {
- super(multiBlockBase, recipe, itemCost, fluidCost);
-
- this.recipeAmperage = recipeAmperage;
- this.machineStack = machineStack;
- }
-
- public int getRecipeAmperage() {
- return recipeAmperage;
- }
-
- @Override
- public boolean checkRecipeInputsSingleStack(boolean consumeInputs) {
- throw new UnsupportedOperationException("Use checkRecipeInputs(boolean, int) instead.");
- }
-
- @Override
- public boolean checkRecipeInputs(boolean consumeInputs) {
- throw new UnsupportedOperationException("Use checkRecipeInputs(boolean, int) instead.");
- }
-
- /** Returns the number of parallel recipes, or 0 if recipe is not satisfied at all. */
- public int checkRecipeInputs(boolean consumeInputs, int maxParallel) {
- if (!GT_Utility.areStacksEqual(machineStack, multiBlockBase.mInventory[1])) {
- // Machine stack was modified. This is not allowed, so stop processing.
- return 0;
- }
- int parallel = maxParallel;
-
- List<ItemStack> items = null;
- if (totalItemCost > 0) {
- items = multiBlockBase.getStoredInputs();
-
- Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>();
- for (ItemStack itemStack : items) {
- itemMap.merge(GT_Utility.ItemId.createNoCopy(itemStack), itemStack.stackSize, Integer::sum);
- }
-
- for (Map.Entry<GT_Utility.ItemId, Integer> entry : itemCost.entrySet()) {
- parallel = Math.min(parallel, itemMap.getOrDefault(entry.getKey(), 0) / entry.getValue());
- if (parallel <= 0) {
- return 0;
- }
- }
- }
-
- List<FluidStack> fluids = null;
- if (totalFluidCost > 0) {
- fluids = multiBlockBase.getStoredFluids();
-
- Map<Fluid, Integer> fluidMap = new HashMap<>();
- for (FluidStack fluidStack : fluids) {
- fluidMap.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
- }
-
- for (Map.Entry<Fluid, Integer> entry : fluidCost.entrySet()) {
- parallel = Math.min(parallel, fluidMap.getOrDefault(entry.getKey(), 0) / entry.getValue());
- if (parallel <= 0) {
- return 0;
- }
- }
- }
-
- final int finalParallel = parallel;
- if (consumeInputs) {
- if (totalItemCost > 0) {
- int remainingItemCost = totalItemCost * finalParallel;
- Map<GT_Utility.ItemId, Integer> runningItemCost = itemCost.entrySet()
- .stream()
- .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue() * finalParallel));
-
- for (ItemStack itemStack : items) {
- GT_Utility.ItemId key = GT_Utility.ItemId.createNoCopy(itemStack);
- int runningCost = runningItemCost.getOrDefault(key, 0);
- int paid = Math.min(itemStack.stackSize, runningCost);
- itemStack.stackSize -= paid;
- runningItemCost.put(key, runningCost - paid);
-
- remainingItemCost -= paid;
- if (remainingItemCost <= 0) {
- break;
- }
- }
- }
-
- if (totalFluidCost > 0) {
- int remainingFluidCost = totalFluidCost * finalParallel;
- Map<Fluid, Integer> runningFluidCost = fluidCost.entrySet()
- .stream()
- .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue() * finalParallel));
-
- for (FluidStack fluidStack : fluids) {
- Fluid key = fluidStack.getFluid();
- int runningCost = runningFluidCost.getOrDefault(key, 0);
- int paid = Math.min(fluidStack.amount, runningCost);
- fluidStack.amount -= paid;
- runningFluidCost.put(key, runningCost - paid);
-
- remainingFluidCost -= paid;
- if (remainingFluidCost <= 0) {
- break;
- }
- }
- }
- }
-
- return finalParallel;
- }
-
- @Nullable
-
- public static GT_Single_Recipe_Check tryLoad(GT_MetaTileEntity_MultiBlockBase parent,
- GT_Recipe.GT_Recipe_Map recipeMap, NBTTagCompound tag, ItemStack machineStack) {
- if (recipeMap == null || machineStack == null) return null;
- GT_Recipe found = tryFindRecipe(parent, recipeMap, tag);
- if (found == null) return null;
- return new GT_Single_Recipe_Check_Processing_Array(
- parent,
- found,
- loadItemCost(tag),
- loadFluidCost(tag),
- recipeMap.mAmperage,
- machineStack.copy());
- }
-
- public static Builder processingArrayBuilder(GT_MetaTileEntity_MultiBlockBase multiBlockBase) {
- return new Builder(multiBlockBase);
- }
-
- public static final class Builder {
-
- private final GT_MetaTileEntity_MultiBlockBase multiBlockBase;
-
- // In order to compute which items and fluids are consumed by the recipe, we compare the
- // multi-block's items and fluids before and after inputs are consumed by the recipe.
- private Map<GT_Utility.ItemId, Integer> beforeItems;
- private Map<Fluid, Integer> beforeFluids;
- private Map<GT_Utility.ItemId, Integer> afterItems;
- private Map<Fluid, Integer> afterFluids;
-
- private GT_Recipe recipe;
- private int recipeAmperage;
-
- private Builder(GT_MetaTileEntity_MultiBlockBase multiBlockBase) {
- this.multiBlockBase = multiBlockBase;
- }
-
- /** Call this before inputs are consumed by the recipe. */
- public Builder setBefore(ItemStack[] inputs, FluidStack[] fluids) {
- beforeItems = buildItemMapDirect(inputs);
- beforeFluids = buildFluidMapDirect(fluids);
- return this;
- }
-
- static Map<GT_Utility.ItemId, Integer> buildItemMapDirect(ItemStack[] inputs) {
- Map<GT_Utility.ItemId, Integer> itemMap = new HashMap<>();
- for (ItemStack itemStack : inputs) {
- itemMap.merge(GT_Utility.ItemId.create(itemStack), itemStack.stackSize, Integer::sum);
- }
- return itemMap;
- }
-
- static Map<Fluid, Integer> buildFluidMapDirect(FluidStack[] fluids) {
- Map<Fluid, Integer> fluidMap = new HashMap<>();
- for (FluidStack fluidStack : fluids) {
- fluidMap.merge(fluidStack.getFluid(), fluidStack.amount, Integer::sum);
- }
- return fluidMap;
- }
-
- /** Call this after inputs are consumed by the recipe. */
- public Builder setAfter(ItemStack[] inputs, FluidStack[] fluids) {
- afterItems = buildItemMapDirect(inputs);
- afterFluids = buildFluidMapDirect(fluids);
- return this;
- }
-
- public Builder setRecipe(GT_Recipe recipe) {
- this.recipe = recipe;
- return this;
- }
-
- public Builder setRecipeAmperage(int recipeAmperage) {
- this.recipeAmperage = recipeAmperage;
- return this;
- }
-
- public GT_Single_Recipe_Check_Processing_Array build() {
- ImmutableMap.Builder<GT_Utility.ItemId, Integer> itemCostBuilder = ImmutableMap.builder();
- for (Map.Entry<GT_Utility.ItemId, Integer> entry : beforeItems.entrySet()) {
- int cost = entry.getValue() - afterItems.getOrDefault(entry.getKey(), 0);
- if (cost > 0) {
- itemCostBuilder.put(entry.getKey(), cost);
- }
- }
-
- ImmutableMap.Builder<Fluid, Integer> fluidCostBuilder = ImmutableMap.builder();
- for (Map.Entry<Fluid, Integer> entry : beforeFluids.entrySet()) {
- int cost = entry.getValue() - afterFluids.getOrDefault(entry.getKey(), 0);
- if (cost > 0) {
- fluidCostBuilder.put(entry.getKey(), cost);
- }
- }
-
- return new GT_Single_Recipe_Check_Processing_Array(
- multiBlockBase,
- recipe,
- itemCostBuilder.build(),
- fluidCostBuilder.build(),
- recipeAmperage,
- multiBlockBase.mInventory[1].copy());
- }
- }
-}
diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java
index d891545122..108b9dc2d9 100644
--- a/src/main/java/gregtech/api/util/GT_Utility.java
+++ b/src/main/java/gregtech/api/util/GT_Utility.java
@@ -493,6 +493,16 @@ public class GT_Utility {
return ceilDiv(voltage, GT_Values.V[tier]);
}
+ /**
+ * Rounds down partial voltage that exceeds tiered voltage, e.g. 4096 -> 2048 (EV)
+ */
+ public static long roundDownVoltage(long voltage) {
+ if (voltage > V[V.length - 1]) {
+ return voltage;
+ }
+ return V[GT_Utility.getTier(voltage)];
+ }
+
public static String getColoredTierNameFromVoltage(long voltage) {
return getColoredTierNameFromTier(getTier(voltage));
}
@@ -501,6 +511,9 @@ public class GT_Utility {
return GT_Values.TIER_COLORS[tier] + GT_Values.VN[tier] + EnumChatFormatting.RESET;
}
+ /**
+ * @return e.g. {@code " (LV)"}
+ */
@Nonnull
public static String getTierNameWithParentheses(long voltage) {
byte tier = getTier(voltage);
@@ -1713,6 +1726,10 @@ public class GT_Utility {
|| Items.feather.getDamage(aStack2) == W);
}
+ public static boolean areStacksEqualOrNull(ItemStack stack1, ItemStack stack2) {
+ return (stack1 == null && stack2 == null) || GT_Utility.areStacksEqual(stack1, stack2);
+ }
+
/**
* Treat both null list, or both null item stack at same list position as equal.
* <p>
diff --git a/src/main/java/gregtech/api/util/VoidProtectionHelper.java b/src/main/java/gregtech/api/util/VoidProtectionHelper.java
index 94c2dfcaaf..3ca9621f06 100644
--- a/src/main/java/gregtech/api/util/VoidProtectionHelper.java
+++ b/src/main/java/gregtech/api/util/VoidProtectionHelper.java
@@ -243,6 +243,8 @@ public class VoidProtectionHelper {
Map<ItemStack, ParallelData> tParallels = new ItemStackMap<>();
int tSlotsFree = 0;
for (ItemStack tItem : itemOutputs) {
+ // GT_RecipeBuilder doesn't handle null item output
+ if (tItem == null) continue;
tItemOutputMap.merge(tItem, tItem.stackSize, Integer::sum);
tParallels.put(tItem, new ParallelData(0, 0));
}