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();
-