aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api')
-rw-r--r--src/main/java/gregtech/api/enums/HeatingCoilLevel.java31
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java3
-rw-r--r--src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java19
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java5
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java34
-rw-r--r--src/main/java/gregtech/api/logic/ProcessingLogic.java308
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java12
-rw-r--r--src/main/java/gregtech/api/metatileentity/MetaTileEntity.java6
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java16
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java69
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java236
-rw-r--r--src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java7
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java16
-rw-r--r--src/main/java/gregtech/api/recipe/check/CheckRecipeResult.java42
-rw-r--r--src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java111
-rw-r--r--src/main/java/gregtech/api/recipe/check/FindRecipeResult.java107
-rw-r--r--src/main/java/gregtech/api/recipe/check/ResultInsufficientHeat.java57
-rw-r--r--src/main/java/gregtech/api/recipe/check/ResultInsufficientMachineTier.java54
-rw-r--r--src/main/java/gregtech/api/recipe/check/ResultInsufficientPower.java56
-rw-r--r--src/main/java/gregtech/api/recipe/check/SimpleCheckRecipeResult.java78
-rw-r--r--src/main/java/gregtech/api/recipe/check/SingleRecipeCheck.java404
-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
29 files changed, 2094 insertions, 1313 deletions
diff --git a/src/main/java/gregtech/api/enums/HeatingCoilLevel.java b/src/main/java/gregtech/api/enums/HeatingCoilLevel.java
index f80f8139c6..f281695d5a 100644
--- a/src/main/java/gregtech/api/enums/HeatingCoilLevel.java
+++ b/src/main/java/gregtech/api/enums/HeatingCoilLevel.java
@@ -1,5 +1,7 @@
package gregtech.api.enums;
+import javax.annotation.Nonnull;
+
import net.minecraft.util.StatCollector;
public enum HeatingCoilLevel {
@@ -32,7 +34,7 @@ public enum HeatingCoilLevel {
}
/**
- * @return the coil tier, used for discount in the Pyrolyse Oven for example.
+ * @return the coil tier, used for discount in the Pyrolyse Oven for example. LV == 0
*/
public byte getTier() {
return (byte) (this.ordinal() - 2);
@@ -52,16 +54,43 @@ public enum HeatingCoilLevel {
return 1 << Math.max(0, this.ordinal() - 5);
}
+ /**
+ * @return Translated name of this coil
+ */
public String getName() {
return StatCollector.translateToLocal("GT5U.coil." + this);
}
+ @Nonnull
public static HeatingCoilLevel getFromTier(byte tier) {
if (tier < 0 || tier > getMaxTier()) return HeatingCoilLevel.None;
return VALUES[tier + 2];
}
+ /**
+ * @param applyColor Whether to apply tiered color
+ * @return Translated coil name. Heat exceeding MAX is represented as "Eternal+".
+ */
+ @Nonnull
+ public static String getDisplayNameFromHeat(int heat, boolean applyColor) {
+ for (HeatingCoilLevel heatLevel : VALUES) {
+ if (heatLevel == HeatingCoilLevel.None || heatLevel == HeatingCoilLevel.ULV) continue;
+ if (heatLevel.getHeat() >= heat) {
+ String name = heatLevel.getName();
+ if (applyColor) {
+ name = GT_Values.TIER_COLORS[heatLevel.getTier() + 1] + name;
+ }
+ return name;
+ }
+ }
+ String name = HeatingCoilLevel.MAX.getName() + "+";
+ if (applyColor) {
+ name = GT_Values.TIER_COLORS[HeatingCoilLevel.MAX.getTier() + 1] + name;
+ }
+ return name;
+ }
+
public static int size() {
return VALUES.length;
}
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
index 9a60092121..7b29f185c6 100644
--- a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
@@ -298,8 +298,7 @@ public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHand
void receiveClientEvent(byte aEventID, byte aValue);
/**
- * Called to actually play the Sound. Do not insert Client/Server checks. That is already done for you. Do not
- * use @playSoundEffect, Minecraft doesn't like that at all. Use @playSound instead.
+ * Called to actually play the sound on client side. Client/Server check is already done.
*/
void doSound(byte aIndex, double aX, double aY, double aZ);
diff --git a/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java b/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java
index 9f862e254d..3d4ed80f67 100644
--- a/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java
+++ b/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java
@@ -20,6 +20,7 @@ import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
import gregtech.api.enums.SoundResource;
import gregtech.api.enums.VoidingMode;
import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.api.interfaces.tileentity.IRecipeLockable;
import gregtech.api.interfaces.tileentity.IVoidable;
/**
@@ -33,7 +34,7 @@ import gregtech.api.interfaces.tileentity.IVoidable;
* <li>Recipe locking</li>
* </ul>
*/
-public interface ControllerWithOptionalFeatures extends IVoidable {
+public interface ControllerWithOptionalFeatures extends IVoidable, IRecipeLockable {
boolean isAllowedToWork();
@@ -233,22 +234,6 @@ public interface ControllerWithOptionalFeatures extends IVoidable {
return (ButtonWidget) button;
}
- /**
- * Override this if you are a multi-block that has added support for single recipe locking.
- */
- boolean supportsSingleRecipeLocking();
-
- /**
- * @return true if recipe locking is enabled, else false. This is getter is used for displaying the icon in the GUI
- */
- boolean isRecipeLockingEnabled();
-
- void setRecipeLocking(boolean enabled);
-
- default boolean getDefaultRecipeLockingMode() {
- return false;
- }
-
Pos2d getRecipeLockingButtonPos();
default ButtonWidget createLockToSingleRecipeButton(IWidgetBuilder<?> builder) {
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java b/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java
index 64d206aff7..6d81d5c401 100644
--- a/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IHasWorldObjectAndCoords.java
@@ -136,8 +136,9 @@ public interface IHasWorldObjectAndCoords {
boolean isDead();
/**
- * Sends a Block Event to the Client TileEntity, the byte Parameters are only for validation as Minecraft doesn't
- * properly write Packet Data.
+ * Sends a Block Event to the Client TileEntity.
+ *
+ * @param aValue value to sync
*/
void sendBlockEvent(byte aID, byte aValue);
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java b/src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java
new file mode 100644
index 0000000000..f793221a50
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IRecipeLockable.java
@@ -0,0 +1,34 @@
+package gregtech.api.interfaces.tileentity;
+
+import gregtech.api.recipe.check.SingleRecipeCheck;
+import gregtech.api.util.GT_Recipe;
+
+/**
+ * Machines implementing this interface can have logic to lock to a single recipe.
+ */
+public interface IRecipeLockable {
+
+ /**
+ * @return if this machine supports single recipe locking.
+ */
+ boolean supportsSingleRecipeLocking();
+
+ /**
+ * @return true if recipe locking is enabled, else false. This is getter is used for displaying the icon in the GUI
+ */
+ boolean isRecipeLockingEnabled();
+
+ void setRecipeLocking(boolean enabled);
+
+ default boolean getDefaultRecipeLockingMode() {
+ return false;
+ }
+
+ default SingleRecipeCheck getSingleRecipeCheck() {
+ return null;
+ }
+
+ default void setSingleRecipeCheck(SingleRecipeCheck recipeCheck) {}
+
+ GT_Recipe.GT_Recipe_Map getRecipeMap();
+}
diff --git a/src/main/java/gregtech/api/logic/ProcessingLogic.java b/src/main/java/gregtech/api/logic/ProcessingLogic.java
index fa0d285401..db97ac151f 100644
--- a/src/main/java/gregtech/api/logic/ProcessingLogic.java
+++ b/src/main/java/gregtech/api/logic/ProcessingLogic.java
@@ -1,39 +1,89 @@
package gregtech.api.logic;
+import java.util.List;
+import java.util.function.Supplier;
+
+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.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.recipe.check.FindRecipeResult;
+import gregtech.api.recipe.check.SingleRecipeCheck;
+import gregtech.api.util.GT_OverclockCalculator;
+import gregtech.api.util.GT_ParallelHelper;
+import gregtech.api.util.GT_Recipe;
import gregtech.api.util.GT_Recipe.GT_Recipe_Map;
-public abstract class ProcessingLogic {
+/**
+ * Logic class to calculate result of recipe check from inputs, based on recipemap.
+ */
+@SuppressWarnings({ "unused", "UnusedReturnValue" })
+public class ProcessingLogic {
- protected GT_Recipe_Map recipeMap;
+ protected IVoidable machine;
+ protected IRecipeLockable recipeLockableMachine;
+ protected Supplier<GT_Recipe_Map> recipeMapSupplier;
+ protected GT_Recipe lastRecipe;
protected ItemStack[] inputItems;
protected ItemStack[] outputItems;
protected ItemStack[] currentOutputItems;
protected FluidStack[] inputFluids;
protected FluidStack[] outputFluids;
protected FluidStack[] currentOutputFluids;
- protected long eut;
- protected long duration;
+ protected long calculatedEut;
+ protected int duration;
+ protected long availableVoltage;
+ protected long availableAmperage;
+ protected int overClockTimeReduction = 1;
+ protected int overClockPowerIncrease = 2;
+ protected boolean protectItems;
+ protected boolean protectFluids;
+ protected boolean isRecipeLocked;
+ protected int maxParallel = 1;
+ protected int calculatedParallels = 0;
+ protected Supplier<Integer> maxParallelSupplier;
+ protected int batchSize = 1;
public ProcessingLogic() {}
+ // region Setters
+
public ProcessingLogic setInputItems(ItemStack... itemInputs) {
this.inputItems = itemInputs;
return this;
}
+ public ProcessingLogic setInputItems(List<ItemStack> itemOutputs) {
+ this.inputItems = itemOutputs.toArray(new ItemStack[0]);
+ return this;
+ }
+
public ProcessingLogic setInputFluids(FluidStack... fluidInputs) {
this.inputFluids = fluidInputs;
return this;
}
+ public ProcessingLogic setInputFluids(List<FluidStack> fluidInputs) {
+ this.inputFluids = fluidInputs.toArray(new FluidStack[0]);
+ return this;
+ }
+
+ /**
+ * Overwrites item output result of the calculation.
+ */
public ProcessingLogic setOutputItems(ItemStack... itemOutputs) {
this.outputItems = itemOutputs;
return this;
}
+ /**
+ * Overwrites fluid output result of the calculation.
+ */
public ProcessingLogic setOutputFluids(FluidStack... fluidOutputs) {
this.outputFluids = fluidOutputs;
return this;
@@ -49,35 +99,263 @@ public abstract class ProcessingLogic {
return this;
}
+ /**
+ * Enables single recipe locking mode.
+ */
+ public ProcessingLogic setRecipeLocking(IRecipeLockable recipeLockableMachine, boolean isRecipeLocked) {
+ this.recipeLockableMachine = recipeLockableMachine;
+ this.isRecipeLocked = isRecipeLocked;
+ return this;
+ }
+
+ /**
+ * Sets max amount of parallel.
+ */
+ public ProcessingLogic setMaxParallel(int maxParallel) {
+ this.maxParallel = maxParallel;
+ return this;
+ }
+
+ /**
+ * Sets method to get max amount of parallel.
+ */
+ public ProcessingLogic setMaxParallelSupplier(Supplier<Integer> supplier) {
+ this.maxParallelSupplier = supplier;
+ return this;
+ }
+
+ /**
+ * Sets batch size for batch mode.
+ */
+ public ProcessingLogic setBatchSize(int size) {
+ this.batchSize = size;
+ return this;
+ }
+
public ProcessingLogic setRecipeMap(GT_Recipe_Map recipeMap) {
- this.recipeMap = recipeMap;
+ return setRecipeMapSupplier(() -> recipeMap);
+ }
+
+ public ProcessingLogic setRecipeMapSupplier(Supplier<GT_Recipe_Map> supplier) {
+ this.recipeMapSupplier = supplier;
+ return this;
+ }
+
+ /**
+ * Sets machine used for void protection logic.
+ */
+ public ProcessingLogic setMachine(IVoidable machine) {
+ this.machine = machine;
return this;
}
- public ProcessingLogic setDuration(long duration) {
+ /**
+ * Overwrites duration result of the calculation.
+ */
+ public ProcessingLogic setDuration(int duration) {
this.duration = duration;
return this;
}
- public ProcessingLogic setEut(long eut) {
- this.eut = eut;
+ /**
+ * Overwrites EU/t result of the calculation.
+ */
+ public ProcessingLogic setCalculatedEut(long calculatedEut) {
+ this.calculatedEut = calculatedEut;
+ return this;
+ }
+
+ /**
+ * Sets voltage of the machine. It doesn't need to be actual voltage (excluding amperage) of the machine;
+ * For example, most of the multiblock machines set maximum possible input power (including amperage) as voltage
+ * and 1 as amperage. That way recipemap search will be executed with overclocked voltage.
+ */
+ public ProcessingLogic setAvailableVoltage(long voltage) {
+ availableVoltage = voltage;
+ return this;
+ }
+
+ /**
+ * Sets amperage of the machine. This amperage doesn't involve in EU/t when searching recipemap.
+ * Useful for preventing tier skip but still considering amperage for parallel.
+ */
+ public ProcessingLogic setAvailableAmperage(long amperage) {
+ availableAmperage = amperage;
return this;
}
+ public ProcessingLogic setVoidProtection(boolean protectItems, boolean protectFluids) {
+ this.protectItems = protectItems;
+ this.protectFluids = protectFluids;
+ return this;
+ }
+
+ /**
+ * Sets custom overclock ratio. 2/4 by default.
+ * Parameters represent number of bit shift, so 1 -> 2x, 2 -> 4x.
+ */
+ public ProcessingLogic setOverclock(int timeReduction, int powerIncrease) {
+ this.overClockTimeReduction = timeReduction;
+ this.overClockPowerIncrease = powerIncrease;
+ return this;
+ }
+
+ /**
+ * Sets overclock ratio to 4/4.
+ */
+ public ProcessingLogic enablePerfectOverclock() {
+ return this.setOverclock(2, 2);
+ }
+
/**
- * Clears everything stored in the Processing Logic other than the Recipe map used
+ * Clears calculated results and provided machine inputs to prepare for the next machine operation.
*/
public ProcessingLogic clear() {
this.inputItems = null;
this.inputFluids = null;
this.outputItems = null;
this.outputFluids = null;
- this.eut = 0;
+ this.calculatedEut = 0;
this.duration = 0;
+ this.calculatedParallels = 0;
return this;
}
- public abstract boolean process();
+ // endregion
+
+ // region Logic
+
+ /**
+ * Executes the recipe check: Find recipe from recipemap, Calculate parallel, overclock and outputs.
+ */
+ @Nonnull
+ public CheckRecipeResult process() {
+ if (recipeMapSupplier == null) return CheckRecipeResultRegistry.NO_RECIPE;
+
+ GT_Recipe_Map recipeMap = recipeMapSupplier.get();
+ if (recipeMap == null) return CheckRecipeResultRegistry.NO_RECIPE;
+
+ if (maxParallelSupplier != null) {
+ maxParallel = maxParallelSupplier.get();
+ }
+
+ FindRecipeResult findRecipeResult;
+ if (isRecipeLocked && recipeLockableMachine != null && recipeLockableMachine.getSingleRecipeCheck() != null) {
+ // Recipe checker is already built, we'll use it
+ SingleRecipeCheck singleRecipeCheck = recipeLockableMachine.getSingleRecipeCheck();
+ // Validate recipe here, otherwise machine will show "not enough output space"
+ // even if recipe cannot be found
+ if (singleRecipeCheck.checkRecipeInputs(false, 1, inputItems, inputFluids) == 0) {
+ return CheckRecipeResultRegistry.NO_RECIPE;
+ }
+ findRecipeResult = FindRecipeResult.ofSuccess(
+ recipeLockableMachine.getSingleRecipeCheck()
+ .getRecipe());
+ } else {
+ findRecipeResult = recipeMap
+ .findRecipeWithResult(lastRecipe, false, false, availableVoltage, inputFluids, null, inputItems);
+ }
+
+ GT_Recipe recipe;
+ if (findRecipeResult.isSuccessful()) {
+ recipe = findRecipeResult.getRecipeNonNull();
+ CheckRecipeResult result = validateRecipe(recipe);
+ if (!result.wasSuccessful()) {
+ return result;
+ } else {
+ lastRecipe = recipe;
+ }
+ } else {
+ if (findRecipeResult.getState() == FindRecipeResult.State.INSUFFICIENT_VOLTAGE) {
+ return CheckRecipeResultRegistry.insufficientPower(findRecipeResult.getRecipeNonNull().mEUt);
+ } else {
+ return CheckRecipeResultRegistry.NO_RECIPE;
+ }
+ }
+
+ GT_ParallelHelper helper = createParallelHelper(recipe);
+
+ helper.build();
+
+ if (helper.getCurrentParallel() <= 0) return CheckRecipeResultRegistry.OUTPUT_FULL;
+
+ calculatedParallels = helper.getCurrentParallel();
+
+ GT_OverclockCalculator calculator = createOverclockCalculator(recipe, helper);
+
+ calculator.calculate();
+ if (calculator.getConsumption() == Long.MAX_VALUE) {
+ return CheckRecipeResultRegistry.POWER_OVERFLOW;
+ }
+ if (calculator.getDuration() == Integer.MAX_VALUE) {
+ return CheckRecipeResultRegistry.DURATION_OVERFLOW;
+ }
+
+ calculatedEut = calculator.getConsumption();
+
+ double finalDuration = calculateDuration(recipe, helper, calculator);
+ if (finalDuration >= Integer.MAX_VALUE) {
+ return CheckRecipeResultRegistry.DURATION_OVERFLOW;
+ }
+ duration = (int) finalDuration;
+
+ outputItems = helper.getItemOutputs();
+ outputFluids = helper.getFluidOutputs();
+
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+
+ /**
+ * Override to tweak final duration that will be set as a result of this logic class.
+ */
+ protected double calculateDuration(@Nonnull GT_Recipe recipe, @Nonnull GT_ParallelHelper helper,
+ @Nonnull GT_OverclockCalculator calculator) {
+ return calculator.getDuration() * helper.getDurationMultiplierDouble();
+ }
+
+ /**
+ * Override to tweak parallel logic if needed.
+ */
+ @Nonnull
+ protected GT_ParallelHelper createParallelHelper(@Nonnull GT_Recipe recipe) {
+ return new GT_ParallelHelper().setRecipe(recipe)
+ .setItemInputs(inputItems)
+ .setFluidInputs(inputFluids)
+ .setAvailableEUt(availableVoltage * availableAmperage)
+ .setMachine(machine, protectItems, protectFluids)
+ .setRecipeLocked(recipeLockableMachine, isRecipeLocked)
+ .setMaxParallel(maxParallel)
+ .enableBatchMode(batchSize)
+ .enableConsumption()
+ .enableOutputCalculation();
+ }
+
+ /**
+ * Override to do additional check for finding recipe if needed, mainly for special value of the recipe.
+ */
+ @Nonnull
+ protected CheckRecipeResult validateRecipe(@Nonnull GT_Recipe recipe) {
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+
+ /**
+ * Override to tweak overclock logic if needed.
+ */
+ @Nonnull
+ protected GT_OverclockCalculator createOverclockCalculator(@Nonnull GT_Recipe recipe,
+ @Nonnull GT_ParallelHelper helper) {
+ return new GT_OverclockCalculator().setRecipeEUt(recipe.mEUt)
+ .setParallel((int) Math.floor(helper.getCurrentParallel() / helper.getDurationMultiplierDouble()))
+ .setDuration(recipe.mDuration)
+ .setAmperage(availableAmperage)
+ .setEUt(availableVoltage)
+ .setDurationDecreasePerOC(overClockTimeReduction)
+ .setEUtIncreasePerOC(overClockPowerIncrease);
+ }
+
+ // endregion
+
+ // region Getters
public ItemStack[] getOutputItems() {
return outputItems;
@@ -87,11 +365,13 @@ public abstract class ProcessingLogic {
return outputFluids;
}
- public long getDuration() {
+ public int getDuration() {
return duration;
}
- public long getEut() {
- return eut;
+ public long getCalculatedEut() {
+ return calculatedEut;
}
+
+ // endregion
}
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
index a23fbd8a85..72ca9f9124 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
@@ -595,6 +595,12 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity
} catch (Throwable e) {
e.printStackTrace();
e.printStackTrace(GT_Log.err);
+ try {
+ mMetaTileEntity.onTickFail(this, mTickTimer);
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ ex.printStackTrace(GT_Log.err);
+ }
}
if (aSideServer && hasValidMetaTileEntity()) {
@@ -1020,6 +1026,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity
@Override
public void disableWorking() {
mWorks = false;
+ if (hasValidMetaTileEntity()) {
+ mMetaTileEntity.onDisableWorking();
+ }
}
@Override
@@ -1060,6 +1069,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity
@Override
public void setActive(boolean aActive) {
mActive = aActive;
+ if (hasValidMetaTileEntity()) {
+ mMetaTileEntity.onSetActive(aActive);
+ }
}
@Override
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 453849923d..1ac42a2ea1 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -319,6 +319,12 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei
}
}
+ public void onTickFail(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {}
+
+ public void onSetActive(boolean active) {}
+
+ public void onDisableWorking() {}
+
@Override
public void inValidate() {
/* Do nothing */
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java
index f251b5c02f..ac037b7919 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java
@@ -69,6 +69,7 @@ import gregtech.api.interfaces.modularui.IAddGregtechLogo;
import gregtech.api.interfaces.modularui.IAddUIWidgets;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.recipe.check.FindRecipeResult;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_ClientPreference;
import gregtech.api.util.GT_CoverBehaviorBase;
@@ -1085,15 +1086,24 @@ public abstract class GT_MetaTileEntity_BasicMachine extends GT_MetaTileEntity_B
public int checkRecipe(boolean skipOC) {
GT_Recipe_Map tMap = getRecipeList();
if (tMap == null) return DID_NOT_FIND_RECIPE;
- GT_Recipe tRecipe = tMap.findRecipe(
- getBaseMetaTileEntity(),
+ FindRecipeResult result = tMap.findRecipeWithResult(
mLastRecipe,
false,
+ false,
V[mTier],
new FluidStack[] { getFillableStack() },
getSpecialSlot(),
getAllInputs());
- if (tRecipe == null) return DID_NOT_FIND_RECIPE;
+ if (result.getState() == FindRecipeResult.State.EXPLODE && getBaseMetaTileEntity() != null) {
+ getBaseMetaTileEntity().doExplosion(V[mTier] * 4);
+ return DID_NOT_FIND_RECIPE;
+ }
+ if (result.getState() == FindRecipeResult.State.ON_FIRE && getBaseMetaTileEntity() != null) {
+ getBaseMetaTileEntity().setOnFire();
+ return DID_NOT_FIND_RECIPE;
+ }
+ if (!result.isSuccessful()) return DID_NOT_FIND_RECIPE;
+ GT_Recipe tRecipe = result.getRecipeNonNull();
if (GT_Mod.gregtechproxy.mLowGravProcessing && (tRecipe.mSpecialValue == -100 || tRecipe.mSpecialValue == -300)
&& !isValidForLowGravity(tRecipe, getBaseMetaTileEntity().getWorld().provider.dimensionId))
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java
index 47dd69ba6c..ef3f587c01 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java
@@ -5,6 +5,8 @@ import static gregtech.api.enums.GT_Values.VN;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Nonnull;
+
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -14,6 +16,9 @@ import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.ProcessingLogic;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
import gregtech.api.util.GT_ExoticEnergyInputHelper;
import gregtech.api.util.GT_Utility;
@@ -127,6 +132,70 @@ public abstract class GT_MetaTileEntity_ExtendedPowerMultiBlockBase<T extends GT
}
@Override
+ public @Nonnull CheckRecipeResult checkProcessing() {
+ // If no logic is found, try legacy checkRecipe
+ if (processingLogic == null) {
+ // noinspection deprecation
+ return checkRecipe(mInventory[1]) ? CheckRecipeResultRegistry.SUCCESSFUL
+ : CheckRecipeResultRegistry.NO_RECIPE;
+ }
+
+ CheckRecipeResult result = CheckRecipeResultRegistry.NO_RECIPE;
+
+ processingLogic.clear();
+ processingLogic.setMachine(this);
+ processingLogic.setRecipeMapSupplier(this::getRecipeMap);
+ processingLogic.setVoidProtection(protectsExcessItem(), protectsExcessFluid());
+ processingLogic.setBatchSize(isBatchModeEnabled() ? getMaxBatchSize() : 1);
+ processingLogic.setRecipeLocking(this, isRecipeLockingEnabled());
+ processingLogic.setInputFluids(getStoredFluids());
+ setProcessingLogicPower(processingLogic);
+ if (isInputSeparationEnabled()) {
+ for (GT_MetaTileEntity_Hatch_InputBus bus : mInputBusses) {
+ List<ItemStack> inputItems = new ArrayList<>();