diff options
Diffstat (limited to 'src/main/java/gregtech/api/util')
17 files changed, 558 insertions, 6069 deletions
diff --git a/src/main/java/gregtech/api/util/FieldsAreNonnullByDefault.java b/src/main/java/gregtech/api/util/FieldsAreNonnullByDefault.java new file mode 100644 index 0000000000..1f51aa39a7 --- /dev/null +++ b/src/main/java/gregtech/api/util/FieldsAreNonnullByDefault.java @@ -0,0 +1,18 @@ +package gregtech.api.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierDefault; + +/** + * This annotation can be applied to a package or class to indicate that + * the fields in that element are nonnull by default unless there is an explicit nullness annotation. + * </ul> + */ +@Nonnull +@TypeQualifierDefault({ ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface FieldsAreNonnullByDefault {} diff --git a/src/main/java/gregtech/api/util/GT_Config.java b/src/main/java/gregtech/api/util/GT_Config.java index 36585559c2..dc56def68f 100644 --- a/src/main/java/gregtech/api/util/GT_Config.java +++ b/src/main/java/gregtech/api/util/GT_Config.java @@ -139,6 +139,20 @@ public class GT_Config implements Runnable { return rResult; } + public String getWithValidValues(Object aCategory, String aName, String[] validValues, String aDefault) { + if (GT_Utility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + aName.replaceAll("\\|", "_"), + aDefault, + null, + validValues); + String rResult = tProperty.getString(); + if (!tProperty.wasRead() && GregTech_API.sPostloadFinished) mConfig.save(); + return rResult; + } + @Override public void run() { mConfig.save(); diff --git a/src/main/java/gregtech/api/util/GT_Forestry_Compat.java b/src/main/java/gregtech/api/util/GT_Forestry_Compat.java index 933c379db1..427703e6f7 100644 --- a/src/main/java/gregtech/api/util/GT_Forestry_Compat.java +++ b/src/main/java/gregtech/api/util/GT_Forestry_Compat.java @@ -11,12 +11,13 @@ import forestry.api.recipes.RecipeManagers; import gregtech.api.enums.GT_Values; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; +import gregtech.api.recipe.RecipeMaps; public class GT_Forestry_Compat { public static void populateFakeNeiRecipes() { if (ItemList.FR_Bee_Drone.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Bee_Drone.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Bee_Drone.getWithName(1L, "Scanned Drone") }, @@ -28,7 +29,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Bee_Princess.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Bee_Princess.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Bee_Princess.getWithName(1L, "Scanned Princess") }, @@ -40,7 +41,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Bee_Queen.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Bee_Queen.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Bee_Queen.getWithName(1L, "Scanned Queen") }, @@ -52,7 +53,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Tree_Sapling.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Tree_Sapling.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Tree_Sapling.getWithName(1L, "Scanned Sapling") }, @@ -64,7 +65,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Butterfly.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Butterfly.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Butterfly.getWithName(1L, "Scanned Butterfly") }, @@ -76,7 +77,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Larvae.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Larvae.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Larvae.getWithName(1L, "Scanned Larvae") }, @@ -88,7 +89,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Serum.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Serum.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Serum.getWithName(1L, "Scanned Serum") }, @@ -100,7 +101,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_Caterpillar.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_Caterpillar.getWildcard(1L) }, new ItemStack[] { ItemList.FR_Caterpillar.getWithName(1L, "Scanned Caterpillar") }, @@ -112,7 +113,7 @@ public class GT_Forestry_Compat { 0); } if (ItemList.FR_PollenFertile.get(1L) != null) { - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { ItemList.FR_PollenFertile.getWildcard(1L) }, new ItemStack[] { ItemList.FR_PollenFertile.getWithName(1L, "Scanned Pollen") }, @@ -138,7 +139,7 @@ public class GT_Forestry_Compat { .copy(); i++; } - GT_Recipe.GT_Recipe_Map.sCentrifugeRecipes.addRecipe( + RecipeMaps.centrifugeRecipes.addRecipe( true, new ItemStack[] { tRecipe.getInput() }, tOutputs, @@ -149,7 +150,7 @@ public class GT_Forestry_Compat { 128, 5, 0); - GT_Recipe.GT_Recipe_Map.sMultiblockCentrifugeRecipes.addRecipe( + RecipeMaps.centrifugeNonCellRecipes.addRecipe( true, new ItemStack[] { tRecipe.getInput() }, tOutputs, @@ -172,7 +173,7 @@ public class GT_Forestry_Compat { try { for (ISqueezerRecipe tRecipe : RecipeManagers.squeezerManager.recipes()) { if ((tRecipe.getResources().length == 1) && (tRecipe.getFluidOutput() != null)) { - GT_Recipe.GT_Recipe_Map.sFluidExtractionRecipes.addRecipe( + RecipeMaps.fluidExtractionRecipes.addRecipe( true, new ItemStack[] { tRecipe.getResources()[0] }, new ItemStack[] { tRecipe.getRemnants() }, diff --git a/src/main/java/gregtech/api/util/GT_LanguageManager.java b/src/main/java/gregtech/api/util/GT_LanguageManager.java index 76e59eed22..ed82befbcc 100644 --- a/src/main/java/gregtech/api/util/GT_LanguageManager.java +++ b/src/main/java/gregtech/api/util/GT_LanguageManager.java @@ -315,7 +315,6 @@ public class GT_LanguageManager { addStringLocalization("Interaction_DESCRIPTION_Index_151.2", "Outputs 1 specific Fluid"); addStringLocalization("Interaction_DESCRIPTION_Index_151.4", "Successfully locked Fluid to %s"); addStringLocalization("Interaction_DESCRIPTION_Index_152", "Total: "); - addStringLocalization("Interaction_DESCRIPTION_Index_152.1", "Max EU: "); addStringLocalization("Interaction_DESCRIPTION_Index_153", "Usage: "); addStringLocalization("Interaction_DESCRIPTION_Index_154", "Voltage: "); addStringLocalization("Interaction_DESCRIPTION_Index_155", "Amperage: "); diff --git a/src/main/java/gregtech/api/util/GT_ModHandler.java b/src/main/java/gregtech/api/util/GT_ModHandler.java index e16e559360..b83c70d7de 100644 --- a/src/main/java/gregtech/api/util/GT_ModHandler.java +++ b/src/main/java/gregtech/api/util/GT_ModHandler.java @@ -9,9 +9,9 @@ import static gregtech.api.enums.GT_Values.M; import static gregtech.api.enums.GT_Values.RA; import static gregtech.api.enums.GT_Values.V; import static gregtech.api.enums.GT_Values.W; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sAlloySmelterRecipes; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sExtractorRecipes; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sOreWasherRecipes; +import static gregtech.api.recipe.RecipeMaps.alloySmelterRecipes; +import static gregtech.api.recipe.RecipeMaps.extractorRecipes; +import static gregtech.api.recipe.RecipeMaps.oreWasherRecipes; import static gregtech.api.util.GT_RecipeBuilder.SECONDS; import static gregtech.api.util.GT_RecipeBuilder.TICKS; @@ -70,6 +70,8 @@ import gregtech.api.items.GT_MetaBase_Item; import gregtech.api.objects.GT_HashSet; import gregtech.api.objects.GT_ItemStack; import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeCategories; +import gregtech.api.recipe.RecipeMap; import ic2.api.item.IBoxable; import ic2.api.item.IC2Items; import ic2.api.item.IElectricItem; @@ -569,11 +571,12 @@ public class GT_ModHandler { } recipeBuilder.itemOutputs(aOutput) .duration(duration * TICKS) - .eut(3); + .eut(3) + .recipeCategory(RecipeCategories.alloySmelterRecycling); if (hidden) { recipeBuilder.hidden(); } - recipeBuilder.addTo(sAlloySmelterRecipes); + recipeBuilder.addTo(alloySmelterRecipes); return true; } @@ -617,7 +620,7 @@ public class GT_ModHandler { .itemOutputs(aOutput) .duration(15 * SECONDS) .eut(2) - .addTo(sExtractorRecipes); + .addTo(extractorRecipes); return true; } @@ -733,7 +736,7 @@ public class GT_ModHandler { .itemOutputs(aOutput1) .duration(aDuration) .eut(aEUt) - .addTo(sAlloySmelterRecipes); + .addTo(alloySmelterRecipes); return true; } @@ -759,9 +762,8 @@ public class GT_ModHandler { /** * Adds GT versions of the IC2 recipes from the supplied IC2RecipeList. */ - public static void addIC2RecipesToGT(Map<IRecipeInput, RecipeOutput> aIC2RecipeList, - GT_Recipe.GT_Recipe_Map aGTRecipeMap, boolean aAddGTRecipe, boolean aRemoveIC2Recipe, - boolean aExcludeGTIC2Items) { + public static void addIC2RecipesToGT(Map<IRecipeInput, RecipeOutput> aIC2RecipeList, RecipeMap<?> aGTRecipeMap, + boolean aAddGTRecipe, boolean aRemoveIC2Recipe, boolean aExcludeGTIC2Items) { Map<ItemStack, ItemStack> aRecipesToRemove = new HashMap<>(); for (Entry<IRecipeInput, RecipeOutput> iRecipeInputRecipeOutputEntry : aIC2RecipeList.entrySet()) { if (iRecipeInputRecipeOutputEntry.getValue().items.isEmpty()) { @@ -773,7 +775,7 @@ public class GT_ModHandler { continue; } - if (aAddGTRecipe && (aGTRecipeMap.findRecipe(null, false, Long.MAX_VALUE, null, tStack) == null)) { + if (aAddGTRecipe) { try { if (aExcludeGTIC2Items && ((tStack.getUnlocalizedName() .contains("gt.metaitem.01") @@ -784,7 +786,7 @@ public class GT_ModHandler { || tStack.getUnlocalizedName() .contains("ic2.itemPurifiedCrushed")))) continue; - switch (aGTRecipeMap.mUnlocalizedName) { + switch (aGTRecipeMap.unlocalizedName) { case "gt.recipe.macerator", "gt.recipe.extractor", "gt.recipe.compressor" -> aGTRecipeMap .addRecipe( true, @@ -928,7 +930,7 @@ public class GT_ModHandler { .fluidInputs(GT_ModHandler.getWater(aWaterAmount)) .duration(25 * SECONDS) .eut(16) - .addTo(sOreWasherRecipes); + .addTo(oreWasherRecipes); RA.stdBuilder() .itemInputs(aInput) @@ -937,7 +939,7 @@ public class GT_ModHandler { .fluidInputs(GT_ModHandler.getDistilledWater(aWaterAmount / 5)) .duration(15 * SECONDS) .eut(16) - .addTo(sOreWasherRecipes); + .addTo(oreWasherRecipes); return true; } @@ -950,7 +952,7 @@ public class GT_ModHandler { .fluidInputs(GT_ModHandler.getWater(aWaterAmount)) .duration(25 * SECONDS) .eut(16) - .addTo(sOreWasherRecipes); + .addTo(oreWasherRecipes); RA.stdBuilder() .itemInputs(aInput) @@ -958,7 +960,7 @@ public class GT_ModHandler { .fluidInputs(GT_ModHandler.getDistilledWater(aWaterAmount / 5)) .duration(15 * SECONDS) .eut(16) - .addTo(sOreWasherRecipes); + .addTo(oreWasherRecipes); return true; } diff --git a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java index 582b65e7ec..8e896fd8de 100644 --- a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java +++ b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java @@ -198,14 +198,6 @@ public class GT_OverclockCalculator { } /** - * Use {@link #setHeatOC(boolean)} - */ - @Deprecated - public GT_OverclockCalculator enableHeatOC() { - return setHeatOC(true); - } - - /** * Set if we should be calculating overclocking using EBF's perfectOC */ public GT_OverclockCalculator setHeatOC(boolean heatOC) { @@ -214,14 +206,6 @@ public class GT_OverclockCalculator { } /** - * Use {@link #setHeatDiscount(boolean)} - */ - @Deprecated - public GT_OverclockCalculator enableHeatDiscount() { - return setHeatDiscount(true); - } - - /** * Sets if we should add a heat discount at the end of calculating an overclock, just like the EBF */ public GT_OverclockCalculator setHeatDiscount(boolean heatDiscount) { @@ -238,14 +222,6 @@ public class GT_OverclockCalculator { } /** - * Use {@link #setMachineHeat(int)} - */ - @Deprecated - public GT_OverclockCalculator setMultiHeat(int machineHeat) { - return setMachineHeat(machineHeat); - } - - /** * Sets the heat of the coils on the machine */ public GT_OverclockCalculator setMachineHeat(int machineHeat) { @@ -313,14 +289,6 @@ public class GT_OverclockCalculator { } /** - * Use {@link #setOneTickDiscount(boolean)} - */ - @Deprecated - public GT_OverclockCalculator enableOneTickDiscount() { - return setOneTickDiscount(true); - } - - /** * Set One Tick Discount on EUt based on Duration Decrease Per Overclock. This functions the same as single * blocks. */ @@ -556,7 +524,7 @@ public class GT_OverclockCalculator { /** * Returns the EUt consumption one would get from overclocking under 1 tick * This Doesn't count as calculating - * + * * @param originalMaxParallel Parallels which are of the actual machine before the overclocking extra ones */ public long calculateEUtConsumptionUnderOneTick(int originalMaxParallel, int currentParallel) { diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java index d3921b613d..8a5cd0b9f8 100644 --- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java +++ b/src/main/java/gregtech/api/util/GT_ParallelHelper.java @@ -10,8 +10,8 @@ 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.RecipeMap; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.recipe.check.SingleRecipeCheck; @@ -124,27 +124,6 @@ public class GT_ParallelHelper { public GT_ParallelHelper() {} /** - * Sets MetaTE controller, with current configuration for void protection mode. - * - * @deprecated Use {@link #setMachine(IVoidable)} - */ - @Deprecated - public GT_ParallelHelper setController(GT_MetaTileEntity_MultiBlockBase machineMeta) { - return setMachine(machineMeta, machineMeta.protectsExcessItem(), machineMeta.protectsExcessFluid()); - } - - /** - * Sets MetaTE controller, with void protection mode forcibly. - * - * @deprecated Use {@link #setMachine(IVoidable, boolean, boolean)} - */ - @Deprecated - public GT_ParallelHelper setController(GT_MetaTileEntity_MultiBlockBase machineMeta, boolean protectExcessItem, - boolean protectExcessFluid) { - return setMachine(machineMeta, protectExcessItem, protectExcessFluid); - } - - /** * Sets machine, with current configuration for void protection mode. */ public GT_ParallelHelper setMachine(IVoidable machine) { @@ -213,14 +192,6 @@ public class GT_ParallelHelper { } /** - * Use {@link #setConsumption(boolean)} - */ - @Deprecated - public GT_ParallelHelper enableConsumption() { - return setConsumption(true); - } - - /** * Set if we should consume inputs or not when trying for parallels * * @param consume Should we consume inputs @@ -249,14 +220,6 @@ public class GT_ParallelHelper { } /** - * Use {@link #setOutputCalculation(boolean)} - */ - @Deprecated - public GT_ParallelHelper enableOutputCalculation() { - return setOutputCalculation(true); - } - - /** * Sets if we should calculate outputs with the parallels we found or not * * @param calculateOutputs Should we calculate outputs with the helper or not @@ -339,14 +302,6 @@ public class GT_ParallelHelper { } /** - * @deprecated Use {@link #getDurationMultiplierDouble()} - */ - @Deprecated - public float getDurationMultiplier() { - return (float) getDurationMultiplierDouble(); - } - - /** * @return The ItemOutputs from the recipe */ @Nonnull @@ -382,23 +337,6 @@ public class GT_ParallelHelper { } /** - * @deprecated Use {@link #setMaxParallelCalculator} and {@link #setInputConsumer} - */ - @Deprecated - protected boolean tryConsumeRecipeInputs(GT_Recipe recipe, FluidStack[] fluids, ItemStack[] items) { - return false; - } - - /** - * @deprecated Use {@link #setMaxParallelCalculator} and {@link #setInputConsumer} - */ - @Deprecated - protected boolean tryConsumeRecipeInputs(GT_Recipe recipe, FluidStack[] fluids, ItemStack[] items, - int minParallel) { - return false; - } - - /** * Called by build(). Determines the parallels and everything else that needs to be done at build time */ protected void determineParallel() { @@ -446,7 +384,7 @@ public class GT_ParallelHelper { 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(); + RecipeMap<?> recipeMap = singleRecipeMachine.getRecipeMap(); if (recipeMap != null) { tSingleRecipeCheckBuilder = SingleRecipeCheck.builder(recipeMap) .setBefore(itemInputs, fluidInputs); 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 7ff37a927c..ead9393d0e 100644 --- a/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java +++ b/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java @@ -5,24 +5,24 @@ import java.util.HashMap; import net.minecraft.item.ItemStack; import gregtech.api.enums.SoundResource; -import gregtech.api.util.GT_Recipe.GT_Recipe_Map; +import gregtech.api.recipe.RecipeMap; @Deprecated public class GT_ProcessingArray_Manager { - private static final HashMap<String, GT_Recipe_Map> mRecipeSaves = new HashMap<>(); + private static final HashMap<String, RecipeMap<?>> mRecipeSaves = new HashMap<>(); private static final HashMap<String, SoundResource> machineSounds = new HashMap<>(); // Adds recipe Maps to the PA using the machines unlocalized name. // Example: basicmachine.electrolyzer, with its recipe map will add the electrolyzer's recipe map to the PA - public static void addRecipeMapToPA(String aMachineName, GT_Recipe_Map aMap) { + public static void addRecipeMapToPA(String aMachineName, RecipeMap<?> aMap) { if (aMachineName != null) { mRecipeSaves.put(aMachineName, aMap); } } // Allows the PA to extract the recipe map for the machine inside it. - public static GT_Recipe_Map giveRecipeMap(String aMachineName) { + public static RecipeMap<?> giveRecipeMap(String aMachineName) { if (aMachineName != null) { return mRecipeSaves.get(aMachineName); } diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index 535da25934..a444a16ef2 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -1,148 +1,38 @@ package gregtech.api.util; -import static gregtech.api.enums.GT_Values.D1; import static gregtech.api.enums.GT_Values.D2; -import static gregtech.api.enums.GT_Values.E; -import static gregtech.api.enums.GT_Values.L; -import static gregtech.api.enums.GT_Values.W; -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.EXPLODE; -import static gregtech.api.recipe.check.FindRecipeResult.NOT_FOUND; -import static gregtech.api.recipe.check.FindRecipeResult.ON_FIRE; -import static gregtech.api.recipe.check.FindRecipeResult.ofSuccess; -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; -import static gregtech.api.util.GT_RecipeMapUtil.FIRST_FLUIDSTACK_OUTPUT; -import static gregtech.api.util.GT_RecipeMapUtil.FIRST_FLUID_OUTPUT; -import static gregtech.api.util.GT_RecipeMapUtil.FIRST_ITEM_INPUT; -import static gregtech.api.util.GT_RecipeMapUtil.FIRST_ITEM_OR_FLUID_INPUT; -import static gregtech.api.util.GT_RecipeMapUtil.FIRST_ITEM_OR_FLUID_OUTPUT; -import static gregtech.api.util.GT_RecipeMapUtil.FIRST_ITEM_OUTPUT; -import static gregtech.api.util.GT_RecipeMapUtil.GT_RecipeTemplate; -import static gregtech.api.util.GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES; -import static gregtech.api.util.GT_RecipeMapUtil.asTemplate; -import static gregtech.api.util.GT_RecipeMapUtil.buildOrEmpty; -import static gregtech.api.util.GT_Utility.formatNumbers; -import static gregtech.api.util.GT_Utility.isArrayEmptyOrNull; -import static gregtech.api.util.GT_Utility.isArrayOfLength; -import static net.minecraft.util.EnumChatFormatting.GRAY; -import static net.minecraft.util.StatCollector.translateToLocal; -import java.awt.Rectangle; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidContainerRegistry; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidContainerItem; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Contract; -import com.google.common.collect.Iterables; -import com.gtnewhorizons.modularui.api.GlStateManager; -import com.gtnewhorizons.modularui.api.ModularUITextures; -import com.gtnewhorizons.modularui.api.drawable.FallbackableUITexture; -import com.gtnewhorizons.modularui.api.drawable.IDrawable; -import com.gtnewhorizons.modularui.api.drawable.UITexture; -import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; -import com.gtnewhorizons.modularui.api.math.Alignment; -import com.gtnewhorizons.modularui.api.math.Pos2d; -import com.gtnewhorizons.modularui.api.math.Size; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.ProgressBar; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; - -import appeng.util.ReadableNumberConverter; -import codechicken.lib.gui.GuiDraw; -import codechicken.nei.PositionedStack; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; -import gnu.trove.map.TByteObjectMap; -import gnu.trove.map.hash.TByteObjectHashMap; import gregtech.GT_Mod; import gregtech.api.GregTech_API; -import gregtech.api.enums.ConfigCategories; -import gregtech.api.enums.Dyes; -import gregtech.api.enums.Element; -import gregtech.api.enums.GT_Values; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.SteamVariant; -import gregtech.api.enums.SubTag; -import gregtech.api.gui.GT_GUIColorOverride; -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.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.recipe.RecipeCategory; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.EmptyRecipeMetadataStorage; +import gregtech.api.recipe.metadata.IRecipeMetadataStorage; import gregtech.api.util.extensions.ArrayExt; -import gregtech.common.gui.modularui.UIHelper; -import gregtech.common.items.GT_FluidDisplayItem; -import gregtech.common.misc.spaceprojects.SpaceProjectManager; -import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject; -import gregtech.common.power.EUPower; -import gregtech.common.power.Power; -import gregtech.common.power.UnspecifiedEUPower; -import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_Replicator; -import gregtech.nei.FusionSpecialValueFormatter; -import gregtech.nei.GT_NEI_DefaultHandler; -import gregtech.nei.HeatingCoilSpecialValueFormatter; -import gregtech.nei.INEISpecialInfoFormatter; -import gregtech.nei.NEIRecipeInfo; import ic2.core.Ic2Items; -import mods.railcraft.common.blocks.aesthetics.cube.EnumCube; -import mods.railcraft.common.items.RailcraftToolItems; -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - * <p/> - * This File contains the functions used for Recipes. Please do not include this File AT ALL in your Moddownload as it - * ruins compatibility This is just the Core of my Recipe System, if you just want to GET the Recipes I add, then you - * can access this File. Do NOT add Recipes using the Constructors inside this Class, The GregTech_API File calls the - * correct Functions for these Constructors. - * <p/> - * I know this File causes some Errors, because of missing Main Functions, but if you just need to compile Stuff, then - * remove said erroreous Functions. - */ public class GT_Recipe implements Comparable<GT_Recipe> { /** @@ -200,13 +90,24 @@ public class GT_Recipe implements Comparable<GT_Recipe> { */ private String[] neiDesc = null; /** + * Holds a set of metadata for this recipe. + */ + @Nonnull + private final IRecipeMetadataStorage metadataStorage; + /** + * Category this recipe belongs to. Recipes belonging to recipemap are forced to have non-null category when added, + * otherwise it can be null. + */ + private RecipeCategory recipeCategory; + /** * Stores which mod added this recipe */ public List<ModContainer> owners = new ArrayList<>(); /** * Stores stack traces where this recipe was added */ - public List<List<StackTraceElement>> stackTraces = new ArrayList<>(); + // BW wants to overwrite it, so no final + public List<List<String>> stackTraces = new ArrayList<>(); private GT_Recipe(GT_Recipe aRecipe, boolean shallow) { mInputs = shallow ? aRecipe.mInputs : GT_Utility.copyItemArray(aRecipe.mInputs); @@ -219,18 +120,23 @@ public class GT_Recipe implements Comparable<GT_Recipe> { mSpecialValue = aRecipe.mSpecialValue; mEUt = aRecipe.mEUt; mNeedsEmptyOutput = aRecipe.mNeedsEmptyOutput; + isNBTSensitive = aRecipe.isNBTSensitive; mCanBeBuffered = aRecipe.mCanBeBuffered; mFakeRecipe = aRecipe.mFakeRecipe; mEnabled = aRecipe.mEnabled; mHidden = aRecipe.mHidden; + metadataStorage = EmptyRecipeMetadataStorage.INSTANCE; owners = new ArrayList<>(aRecipe.owners); reloadOwner(); } - // only used for GT_RecipeBuilder. Should not be called otherwise + /** + * Only for {@link GT_RecipeBuilder}. + */ GT_Recipe(ItemStack[] mInputs, ItemStack[] mOutputs, FluidStack[] mFluidInputs, FluidStack[] mFluidOutputs, int[] mChances, Object mSpecialItems, int mDuration, int mEUt, int mSpecialValue, boolean mEnabled, - boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, boolean mNeedsEmptyOutput, String[] neiDesc) { + boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, boolean mNeedsEmptyOutput, boolean nbtSensitive, + String[] neiDesc, @Nullable IRecipeMetadataStorage metadataStorage, RecipeCategory recipeCategory) { this.mInputs = mInputs; this.mOutputs = mOutputs; this.mFluidInputs = mFluidInputs; @@ -245,7 +151,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> { this.mFakeRecipe = mFakeRecipe; this.mCanBeBuffered = mCanBeBuffered; this.mNeedsEmptyOutput = mNeedsEmptyOutput; + this.isNBTSensitive = nbtSensitive; this.neiDesc = neiDesc; + this.metadataStorage = metadataStorage == null ? EmptyRecipeMetadataStorage.INSTANCE : metadataStorage.copy(); + this.recipeCategory = recipeCategory; reloadOwner(); } @@ -311,19 +220,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> { mDuration = aDuration; mSpecialValue = aSpecialValue; mEUt = aEUt; + metadataStorage = EmptyRecipeMetadataStorage.INSTANCE; // checkCellBalance(); reloadOwner(); } - public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, int aFuelValue, int aType) { - this(aInput1, aOutput1, null, null, null, aFuelValue, aType); - } - - private static FluidStack[] tryGetFluidInputsFromCells(ItemStack aInput) { - FluidStack tFluid = GT_Utility.getFluidForFilledItem(aInput, true); - return tFluid == null ? null : new FluidStack[] { tFluid }; - } - // aSpecialValue = EU per Liter! If there is no Liquid for this Object, then it gets multiplied with 1000! public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, int aSpecialValue, int aType) { @@ -343,208 +244,32 @@ public class GT_Recipe implements Comparable<GT_Recipe> { switch (aType) { // Diesel Generator case 0 -> { - GT_Recipe_Map.sDieselFuels.addRecipe(this); - GT_Recipe_Map.sLargeBoilerFakeFuels.addDieselRecipe(this); + RecipeMaps.dieselFuels.addRecipe(this); + RecipeMaps.largeBoilerFakeFuels.getBackend() + .addDieselRecipe(this); } // Gas Turbine - case 1 -> GT_Recipe_Map.sTurbineFuels.addRecipe(this); + case 1 -> RecipeMaps.gasTurbineFuels.addRecipe(this); // Thermal Generator - case 2 -> GT_Recipe_Map.sHotFuels.addRecipe(this); + case 2 -> RecipeMaps.hotFuels.addRecipe(this); // Plasma Generator - case 4 -> GT_Recipe_Map.sPlasmaFuels.addRecipe(this); + case 4 -> RecipeMaps.plasmaFuels.addRecipe(this); // Magic Generator - case 5 -> GT_Recipe_Map.sMagicFuels.addRecipe(this); + case 5 -> RecipeMaps.magicFuels.addRecipe(this); // Fluid Generator. Usually 3. Every wrong Type ends up in the Semifluid Generator default -> { - GT_Recipe_Map.sDenseLiquidFuels.addRecipe(this); - GT_Recipe_Map.sLargeBoilerFakeFuels.addDenseLiquidRecipe(this); + RecipeMaps.denseLiquidFuels.addRecipe(this); + RecipeMaps.largeBoilerFakeFuels.getBackend() + .addDenseLiquidRecipe(this); } } } } - public GT_Recipe(FluidStack aInput1, FluidStack aInput2, FluidStack aOutput1, int aDuration, int aEUt, - int aSpecialValue) { - this( - true, - null, - null, - null, - null, - new FluidStack[] { aInput1, aInput2 }, - new FluidStack[] { aOutput1 }, - Math.max(aDuration, 1), - aEUt, - Math.max(Math.min(aSpecialValue, 160000000), 0)); - if (mInputs.length > 1) { - GT_Recipe_Map.sFusionRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, int aDuration, int aEUt) { - this( - true, - new ItemStack[] { aInput1 }, - new ItemStack[] { aOutput1, aOutput2 }, - null, - null, - null, - null, - aDuration, - aEUt, - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sLatheRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, int aCellAmount, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, - ItemStack aOutput4, int aDuration, int aEUt) { - this( - true, - new ItemStack[] { aInput1, - aCellAmount > 0 ? ItemList.Cell_Empty.get(Math.min(64, Math.max(1, aCellAmount))) : null }, - new ItemStack[] { aOutput1, aOutput2, aOutput3, aOutput4 }, - null, - null, - null, - null, - Math.max(aDuration, 1), - Math.max(aEUt, 1), - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sDistillationRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, int aInput2, ItemStack aOutput1, ItemStack aOutput2) { - this( - true, - new ItemStack[] { aInput1, - GT_ModHandler.getIC2Item( - "industrialTnt", - aInput2 > 0 ? Math.min(aInput2, 64) : 1, - new ItemStack(Blocks.tnt, aInput2 > 0 ? Math.min(aInput2, 64) : 1)) }, - new ItemStack[] { aOutput1, aOutput2 }, - null, - null, - null, - null, - 20, - 30, - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sImplosionRecipes.addRecipe(this); - } - } - - public GT_Recipe(int aEUt, int aDuration, ItemStack aInput1, ItemStack aOutput1) { - this( - true, - new ItemStack[] { aInput1, ItemList.Circuit_Integrated.getWithDamage(0, aInput1.stackSize) }, - new ItemStack[] { aOutput1 }, - null, - null, - null, - null, - Math.max(aDuration, 1), - Math.max(aEUt, 1), - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sBenderRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, ItemStack aInput2, int aEUt, int aDuration, ItemStack aOutput1) { - this( - true, - aInput2 == null ? new ItemStack[] { aInput1 } : new ItemStack[] { aInput1, aInput2 }, - new ItemStack[] { aOutput1 }, - null, - null, - null, - null, - Math.max(aDuration, 1), - Math.max(aEUt, 1), - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sAlloySmelterRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, int aEUt, ItemStack aInput2, int aDuration, ItemStack aOutput1, - ItemStack aOutput2) { - this( - true, - aInput2 == null ? new ItemStack[] { aInput1 } : new ItemStack[] { aInput1, aInput2 }, - new ItemStack[] { aOutput1, aOutput2 }, - null, - null, - null, - null, - Math.max(aDuration, 1), - Math.max(aEUt, 1), - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sCannerRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, int aDuration) { - this( - true, - new ItemStack[] { aInput1 }, - new ItemStack[] { aOutput1 }, - null, - null, - null, - null, - Math.max(aDuration, 1), - 120, - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sVacuumRecipes.addRecipe(this); - } - } - - public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, int aDuration, int aEUt, int VACUUM) { - this( - true, - new ItemStack[] { aInput1 }, - new ItemStack[] { aOutput1 }, - null, - null, - null, - null, - Math.max(aDuration, 1), - aEUt, - 0); - if (mInputs.length > 0 && mOutputs[0] != null) { - GT_Recipe_Map.sVacuumRecipes.addRecipe(this); - } - } - - public GT_Recipe(FluidStack aInput1, FluidStack aOutput1, int aDuration, int aEUt) { - this( - false, - null, - null, - null, - null, - new FluidStack[] { aInput1 }, - new FluidStack[] { aOutput1 }, - Math.max(aDuration, 1), - aEUt, - 0); - if (mFluidInputs.length > 0 && mFluidOutputs[0] != null) { - GT_Recipe_Map.sVacuumRecipes.addRecipe(this); - } - } - // Dummy GT_Recipe maker... public GT_Recipe(ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { @@ -561,15 +286,17 @@ public class GT_Recipe implements Comparable<GT_Recipe> { aSpecialValue); } + /** + * Re-unificates all the items present in recipes. + */ public static void reInit() { GT_Log.out.println("GT_Mod: Re-Unificating Recipes."); - for (GT_Recipe_Map tMapEntry : GT_Recipe_Map.sMappings) tMapEntry.reInit(); + for (RecipeMap<?> map : RecipeMap.ALL_RECIPE_MAPS.values()) { + map.getBackend() + .reInit(); + } } - // ----- - // Old Constructors, do not use! - // ----- - public ItemStack getRepresentativeInput(int aIndex) { if (aIndex < 0 || aIndex >= mInputs.length) return null; return GT_Utility.copyOrNull(mInputs[aIndex]); @@ -580,16 +307,14 @@ public class GT_Recipe implements Comparable<GT_Recipe> { return GT_Utility.copyOrNull(mOutputs[aIndex]); } - /*** + /** * Dictates the ItemStacks displayed in the output slots of any NEI page handled by the default GT NEI handler. * Override to make shown items differ from a GT_Recipe's item output array * * @see gregtech.nei.GT_NEI_DefaultHandler * @param i Slot index * @return ItemStack to be displayed in the slot - * */ - // public ItemStack getRepresentativeOutput(int i) { return getOutput(i); } @@ -851,59 +576,100 @@ public class GT_Recipe implements Comparable<GT_Recipe> { /** * Sets description shown on NEI. <br> * If you have a large number of recipes for the recipemap, this is not efficient memory wise, so use - * {@link GT_Recipe_Map#setNEISpecialInfoFormatter} instead. + * {@link gregtech.api.recipe.RecipeMapBuilder#neiSpecialInfoFormatter} instead. */ - protected void setNeiDesc(String... neiDesc) { + public void setNeiDesc(String... neiDesc) { this.neiDesc = neiDesc; } + // region metadata + + // Don't try implementing setMetadata, as metadataStorage can be EmptyRecipeMetadataStorage + + /** + * Gets metadata associated with this recipe. Can return null. Use + * {@link #getMetadataOrDefault(RecipeMetadataKey, Object)} + * if you want to specify default value. + */ + @Nullable + public <T> T getMetadata(RecipeMetadataKey<T> key) { + return key.cast(metadataStorage.getMetadata(key)); + } + /** - * Use {@link GT_Recipe_Map#getItemInputPositions} or {@link GT_Recipe_Map#getSpecialItemPosition} or - * {@link GT_Recipe_Map#getFluidInputPositions} instead + * Gets metadata associated with this recipe with default value. Does not return null unless default value is null. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - public ArrayList<PositionedStack> getInputPositionedStacks() { - return null; + @Contract("_, !null -> !null") + @Nullable + public <T> T getMetadataOrDefault(RecipeMetadataKey<T> key, @Nullable T defaultValue) { + return key.cast(metadataStorage.getMetadataOrDefault(key, defaultValue)); + } + + @Nonnull + public IRecipeMetadataStorage getMetadataStorage() { + return metadataStorage; + } + + // endregion + + public RecipeCategory getRecipeCategory() { + return recipeCategory; } /** - * Use {@link GT_Recipe_Map#getItemOutputPositions} or {@link GT_Recipe_Map#getFluidOutputPositions} instead + * Exists only for recipe copying from external. For ordinal use case, use {@link GT_RecipeBuilder#recipeCategory}. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - public ArrayList<PositionedStack> getOutputPositionedStacks() { - return null; + public void setRecipeCategory(RecipeCategory recipeCategory) { + this.recipeCategory = recipeCategory; } + private static final List<String> excludedStacktraces = Arrays.asList( + "java.lang.Thread", + "gregtech.api.interfaces.IRecipeMap", + "gregtech.api.interfaces.IRecipeMap$1", + "gregtech.api.recipe.RecipeMap", + "gregtech.api.recipe.RecipeMapBackend", + "gregtech.api.recipe.RecipeMapBackendPropertiesBuilder", + "gregtech.api.util.GT_Recipe", + "gregtech.api.util.GT_RecipeBuilder", + "gregtech.api.util.GT_RecipeConstants", + "gregtech.api.util.GT_RecipeMapUtil", + "gregtech.common.GT_RecipeAdder"); + public void reloadOwner() { setOwner( Loader.instance() .activeModContainer()); - final List<String> excludedClasses = Arrays.asList( - "java.lang.Thread", - "gregtech.api.util.GT_Recipe", - "gregtech.api.util.GT_RecipeBuilder", - "gregtech.api.util.GT_Recipe$GT_Recipe_Map", - "gregtech.common.GT_RecipeAdder"); if (GT_Mod.gregtechproxy.mNEIRecipeOwnerStackTrace) { - List<StackTraceElement> toAdd = new ArrayList<>(); + List<String> toAdd = new ArrayList<>(); for (StackTraceElement stackTrace : Thread.currentThread() .getStackTrace()) { - if (excludedClasses.stream() + if (excludedStacktraces.stream() .noneMatch( c -> stackTrace.getClassName() .equals(c))) { - toAdd.add(stackTrace); + toAdd.add(formatStackTrace(stackTrace)); } } stackTraces.add(toAdd); } } + private static String formatStackTrace(StackTraceElement stackTraceElement) { + String raw = stackTraceElement.toString(); + int startParen = raw.lastIndexOf('('); + int colon = raw.lastIndexOf(':'); + if (colon == -1) { + // native or unknown source + return raw; + } + // strip class name and leave line number, as class name is already shown + return raw.substring(0, startParen + 1) + raw.substring(colon); + } + public void setOwner(ModContainer newOwner) { - ModContainer oldOwner = owners.size() > 0 ? this.owners.get(owners.size() - 1) : null; + ModContainer oldOwner = !owners.isEmpty() ? this.owners.get(owners.size() - 1) : null; if (newOwner != null && newOwner != oldOwner) { owners.add(newOwner); } @@ -1144,5146 +910,19 @@ public class GT_Recipe implements Comparable<GT_Recipe> { } } - @SuppressWarnings("StaticInitializerReferencesSubClass") - public static class GT_Recipe_Map implements IGT_RecipeMap { - - /** - * Contains all Recipe Maps - */ - public static final Collection<GT_Recipe_Map> sMappings = new ArrayList<>(); - /** - * All recipe maps indexed by their {@link #mUniqueIdentifier}. - */ - public static final Map<String, GT_Recipe_Map> sIndexedMappings = new HashMap<>(); - - static final String TEXTURES_GUI_BASICMACHINES = "textures/gui/basicmachines"; - public static final GT_Recipe_Map sOreWasherRecipes = new GT_Recipe_Map( - new HashSet<>(500), - "gt.recipe.orewasher", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "OreWasher"), - 1, - 3, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeConfigFile("orewasher", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_BATH, ProgressBar.Direction.CIRCULAR_CW); - public static final GT_Recipe_Map sThermalCentrifugeRecipes = new GT_Recipe_Map( - new HashSet<>(1000), - "gt.recipe.thermalcentrifuge", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "ThermalCentrifuge"), - 1, - 3, - 1, - 0, - 2, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeConfigFile("thermalcentrifuge", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sCompressorRecipes = new GT_Recipe_Map( - new HashSet<>(750), - "gt.recipe.compressor", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Compressor"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_COMPRESSOR) - .setRecipeConfigFile("compressor", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_COMPRESS, ProgressBar.Direction.RIGHT) - .setSlotOverlaySteam(false, GT_UITextures.OVERLAY_SLOT_COMPRESSOR_STEAM) - .setProgressBarSteam(GT_UITextures.PROGRESSBAR_COMPRESS_STEAM); - public static final GT_Recipe_Map sExtractorRecipes = new GT_Recipe_Map( - new HashSet<>(250), - "gt.recipe.extractor", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Extractor"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CENTRIFUGE) - .setRecipeConfigFile("extractor", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_EXTRACT, ProgressBar.Direction.RIGHT) - .setSlotOverlaySteam(false, GT_UITextures.OVERLAY_SLOT_CENTRIFUGE_STEAM) - .setProgressBarSteam(GT_UITextures.PROGRESSBAR_EXTRACT_STEAM); - public static final GT_Recipe_Map sRecyclerRecipes = new GT_Recipe_Map_Recycler( - new HashSet<>(0), - "ic.recipe.recycler", - null, - "ic2.recycler", - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Recycler"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - false).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_RECYCLE) - .setProgressBar(GT_UITextures.PROGRESSBAR_RECYCLE, ProgressBar.Direction.CIRCULAR_CW); - public static final GT_Recipe_Map sFurnaceRecipes = new GT_Recipe_Map_Furnace( - new HashSet<>(0), - "mc.recipe.furnace", - "Furnace", - "smelting", - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "E_Furnace"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - false).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_FURNACE) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setSlotOverlaySteam(false, GT_UITextures.OVERLAY_SLOT_FURNACE_STEAM) - .setProgressBarSteam(GT_UITextures.PROGRESSBAR_ARROW_STEAM); - public static final GT_Recipe_Map sMicrowaveRecipes = new GT_Recipe_Map_Microwave( - new HashSet<>(0), - "gt.recipe.microwave", - null, - "smelting", - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "E_Furnace"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - false).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_FURNACE) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - - public static final GT_Recipe_Map sScannerFakeRecipes = new GT_Recipe_Map( - new HashSet<>(300), - "gt.recipe.scanner", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Scanner"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_MICROSCOPE) - .setSlotOverlay(false, false, true, true, GT_UITextures.OVERLAY_SLOT_DATA_ORB) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sRockBreakerFakeRecipes = new GT_Recipe_Map( - new HashSet<>(200), - "gt.recipe.rockbreaker", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "RockBreaker"), - 2, - 1, - 0, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_DUST) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) - .setProgressBar(GT_UITextures.PROGRESSBAR_MACERATE, ProgressBar.Direction.RIGHT); - @Deprecated - public static final GT_Recipe_Map sByProductList = new GT_Recipe_Map( - new HashSet<>(1000), - "gt.recipe.byproductlist", - "Ore Byproduct List", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 6, - 1, - 0, - 1, - E, - 1, - E, - true, - false).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sReplicatorFakeRecipes = new ReplicatorFakeMap( - new HashSet<>(100), - "gt.recipe.replicator", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Replicator"), - 0, - 1, - 0, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CANISTER) - .setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_UUM) - .setSlotOverlay(false, false, true, true, GT_UITextures.OVERLAY_SLOT_DATA_ORB) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sAssemblylineVisualRecipes = new GT_Recipe_Map_AssemblyLineFake( - new HashSet<>(110), - "gt.recipe.fakeAssemblylineProcess", - "Assemblyline Process", - null, - GregTech.getResourcePath("textures", "gui", "FakeAssemblyline"), - 16, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, true, GT_UITextures.OVERLAY_SLOT_DATA_ORB) - .setUsualFluidInputCount(4) - .setDisableOptimize(true); - /** - * Usually, but not always, you should use {@link GT_RecipeConstants#UniversalArcFurnace} instead. - */ - public static final GT_Recipe_Map sPlasmaArcFurnaceRecipes = new GT_Recipe_Map( - new HashSet<>(20000), - "gt.recipe.plasmaarcfurnace", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "PlasmaArcFurnace"), - 1, - 9, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("arcfurnace", FIRST_ITEM_INPUT); - /** - * Usually, but not always, you should use {@link GT_RecipeConstants#UniversalArcFurnace} instead. - */ - public static final GT_Recipe_Map sArcFurnaceRecipes = new GT_Recipe_Map( - new HashSet<>(20000), - "gt.recipe.arcfurnace", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "ArcFurnace"), - 1, - 9, - 1, - 1, - 3, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("arcfurnace", FIRST_ITEM_INPUT); - public static final GT_Recipe_Map sPrinterRecipes = new GT_Recipe_Map_Printer( - new HashSet<>(5), - "gt.recipe.printer", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Printer"), - 1, - 1, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_PAGE_BLANK) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_PAGE_PRINTED) - .setSlotOverlay(false, false, true, true, GT_UITextures.OVERLAY_SLOT_DATA_STICK) - .setRecipeConfigFile("printer", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sSifterRecipes = new GT_Recipe_Map( - new HashSet<>(105), - "gt.recipe.sifter", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Sifter"), - 1, - 9, - 0, - 0, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_SIFT, ProgressBar.Direction.DOWN) - .setRecipeConfigFile("sifter", FIRST_ITEM_INPUT); - public static final GT_Recipe_Map sPressRecipes = new GT_Recipe_Map_FormingPress( - new HashSet<>(300), - "gt.recipe.press", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Press3"), - 6, - 1, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_PRESS_1) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_PRESS_2) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_PRESS_3) - .setRecipeConfigFile("press", FIRST_ITEM_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_COMPRESS, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sLaserEngraverRecipes = new GT_Recipe_Map( - new HashSet<>(810), - "gt.recipe.laserengraver", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LaserEngraver2"), - 4, - 4, - 0, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_LENS) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("laserengraving", FIRST_ITEM_OUTPUT) - .setUsualFluidInputCount(2) - .setUsualFluidOutputCount(2); - public static final GT_Recipe_Map sMixerRecipes = new GT_Recipe_Map( - new HashSet<>(900), - "gt.recipe.mixer", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Mixer6"), - 9, - 4, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_DUST) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeConfigFile("mixer", FIRST_ITEM_OR_FLUID_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_MIXER, ProgressBar.Direction.CIRCULAR_CW); - public static final GT_Recipe_Map sAutoclaveRecipes = new GT_Recipe_Map( - new HashSet<>(300), - "gt.recipe.autoclave", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Autoclave4"), - 2, - 4, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_DUST) - .setSlotOverlay(false, true, true, GT_UITextures.OVERLAY_SLOT_GEM) - .setSlotOverlay(false, true, false, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeConfigFile("autoclave", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sElectroMagneticSeparatorRecipes = new GT_Recipe_Map( - new HashSet<>(50), - "gt.recipe.electromagneticseparator", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "ElectromagneticSeparator"), - 1, - 3, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeConfigFile("electromagneticseparator", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_MAGNET, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sPolarizerRecipes = new GT_Recipe_Map( - new HashSet<>(300), - "gt.recipe.polarizer", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Polarizer"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_MAGNET, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("polarizer", FIRST_ITEM_INPUT); - public static final GT_Recipe_Map sMaceratorRecipes = new GT_Recipe_Map_Macerator( - new HashSet<>(16600), - "gt.recipe.macerator", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Macerator4"), - 1, - 4, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_DUST) - .setProgressBar(GT_UITextures.PROGRESSBAR_MACERATE, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("pulveriser", FIRST_ITEM_INPUT) - .setSlotOverlaySteam(false, GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE_STEAM) - .setSlotOverlaySteam(true, GT_UITextures.OVERLAY_SLOT_DUST_STEAM) - .setProgressBarSteam(GT_UITextures.PROGRESSBAR_MACERATE_STEAM); - public static final GT_Recipe_Map sChemicalBathRecipes = new GT_Recipe_Map( - new HashSet<>(2550), - "gt.recipe.chemicalbath", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "ChemicalBath"), - 1, - 3, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_BATH, ProgressBar.Direction.CIRCULAR_CW) - .setRecipeConfigFile("chemicalbath", FIRST_ITEM_INPUT); - public static final GT_Recipe_Map sFluidCannerRecipes = new GT_Recipe_Map_FluidCanner( - new HashSet<>(2100), - "gt.recipe.fluidcanner", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "FluidCanner"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CANISTER) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_CANISTER) - .setRecipeConfigFile("canning", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_CANNER, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sBrewingRecipes = new GT_Recipe_Map( - new HashSet<>(450), - "gt.recipe.brewer", - "Brewing Machine", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "PotionBrewer"), - 1, - 0, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CAULDRON) - .setRecipeConfigFile("brewing", FIRST_FLUIDSTACK_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sFluidHeaterRecipes = new GT_Recipe_Map( - new HashSet<>(10), - "gt.recipe.fluidheater", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "FluidHeater"), - 1, - 0, - 0, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_HEATER_1) - .setSlotOverlay(true, true, GT_UITextures.OVERLAY_SLOT_HEATER_2) - .setRecipeConfigFile("fluidheater", FIRST_FLUIDSTACK_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sDistilleryRecipes = new GT_Recipe_Map( - new HashSet<>(400), - "gt.recipe.distillery", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Distillery"), - 1, - 1, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_BEAKER_1) - .setSlotOverlay(true, true, GT_UITextures.OVERLAY_SLOT_BEAKER_2) - .setRecipeConfigFile("distillery", FIRST_FLUIDSTACK_OUTPUT) - .setRecipeSpecialHandler(r -> { - int aInput = r.mFluidInputs[0].amount, aOutput = r.mFluidOutputs[0].amount, aDuration = r.mDuration; - - // reduce the batch size if fluid amount is exceeding - int tScale = (Math.max(aInput, aOutput) + 999) / 1000; - if (tScale <= 0) tScale = 1; - if (tScale > 1) { - // trying to find whether there is a better factor - for (int i = tScale; i <= 5; i++) { - if (aInput % i == 0 && aDuration % i == 0) { - tScale = i; - break; - } - } - for (int i = tScale; i <= 5; i++) { - if (aInput % i == 0 && aDuration % i == 0 && aOutput % i == 0) { - tScale = i; - break; - } - } - aInput = (aInput + tScale - 1) / tScale; - aOutput = aOutput / tScale; - if (!isArrayEmptyOrNull(r.mOutputs)) { - ItemData tData = GT_OreDictUnificator.getItemData(r.mOutputs[0]); - if (tData != null && (tData.mPrefix == OrePrefixes.dust - || OrePrefixes.dust.mFamiliarPrefixes.contains(tData.mPrefix))) { - r.mOutputs[0] = GT_OreDictUnificator.getDust( - tData.mMaterial.mMaterial, - tData.mMaterial.mAmount * r.mOutputs[0].stackSize / tScale); - } else { - if (r.mOutputs[0].stackSize / tScale == 0) r.mOutputs[0] = GT_Values.NI; - else r.mOutputs[0] = GT_Utility - .copyAmount(r.mOutputs[0].stackSize / tScale, r.mOutputs[0]); - } - } - aDuration = (aDuration + tScale - 1) / tScale; - r.mFluidInputs[0] = GT_Utility.copyAmount(aInput, r.mFluidInputs[0]); - r.mFluidOutputs[0] = GT_Utility.copyAmount(aOutput, r.mFluidOutputs[0]); - r.mDuration = aDuration; - } - }) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sFermentingRecipes = new GT_Recipe_Map( - new HashSet<>(50), - "gt.recipe.fermenter", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Fermenter"), - 0, - 0, - 0, - 1, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("fermenting", FIRST_FLUIDSTACK_OUTPUT); - public static final GT_Recipe_Map sFluidSolidficationRecipes = new GT_Recipe_Map( - new HashSet<>(35000), - "gt.recipe.fluidsolidifier", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "FluidSolidifier"), - 1, - 1, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_MOLD) - .setRecipeConfigFile("fluidsolidifier", FIRST_ITEM_OUTPUT) - .setRecipeSpecialHandler(r -> { - if (ArrayUtils.isNotEmpty(r.mFluidInputs)) { - if (Materials.PhasedGold.getMolten(1) - .isFluidEqual(r.mFluidInputs[0])) - r.mFluidInputs = new FluidStack[] { - Materials.VibrantAlloy.getMolten(r.mFluidInputs[0].amount) }; - else if (Materials.PhasedIron.getMolten(1) - .isFluidEqual(r.mFluidInputs[0])) - r.mFluidInputs = new FluidStack[] { - Materials.PulsatingIron.getMolten(r.mFluidInputs[0].amount) }; - } - }) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sFluidExtractionRecipes = new GT_Recipe_Map( - new HashSet<>(15000), - "gt.recipe.fluidextractor", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "FluidExtractor"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CENTRIFUGE) - .setRecipeConfigFile("fluidextractor", FIRST_ITEM_INPUT) - .setRecipeSpecialHandler(r -> { - if (ArrayUtils.isNotEmpty(r.mFluidInputs)) { - if (Materials.PhasedGold.getMolten(1) - .isFluidEqual(r.mFluidInputs[0])) - r.mFluidInputs = new FluidStack[] { - Materials.VibrantAlloy.getMolten(r.mFluidInputs[0].amount) }; - else if (Materials.PhasedIron.getMolten(1) - .isFluidEqual(r.mFluidInputs[0])) - r.mFluidInputs = new FluidStack[] { - Materials.PulsatingIron.getMolten(r.mFluidInputs[0].amount) }; - } - }) - .setProgressBar(GT_UITextures.PROGRESSBAR_EXTRACT, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sBoxinatorRecipes = new GT_Recipe_Map( - new HashSet<>(2500), - "gt.recipe.packager", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Packager"), - 2, - 1, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_BOX) - .setRecipeConfigFile("boxing", FIRST_ITEM_OUTPUT) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_BOXED) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sUnboxinatorRecipes = new GT_Recipe_Map_Unboxinator( - new HashSet<>(2500), - "gt.recipe.unpackager", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Unpackager"), - 1, - 2, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_BOXED) - .setRecipeConfigFile("unboxing", FIRST_ITEM_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - /** - * Usually, but not always, you should use {@link GT_RecipeConstants#Fusion} instead. - */ - public static final GT_Recipe_Map sFusionRecipes = new GT_Recipe_Map_FluidOnly( - new HashSet<>(50), - "gt.recipe.fusionreactor", - "Fusion Reactor", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "FusionReactor"), - 0, - 0, - 0, - 2, - 1, - "Start: ", - 1, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .useComparatorForNEI(true) - .setUsualFluidInputCount(2) - .setRecipeConfigFile("fusion", FIRST_FLUID_OUTPUT) - .setDisableOptimize(true) - .setNEISpecialInfoFormatter(FusionSpecialValueFormatter.INSTANCE); - /** - * Usually, but not always, you should use {@link GT_RecipeConstants#Fusion} instead. - */ - public static final GT_Recipe_Map sComplexFusionRecipes = new GT_Recipe_Map_ComplexFusion( - new HashSet<>(50), - "gt.recipe.complexfusionreactor", - "Complex Fusion Reactor", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "ComplexFusionReactor"), - 3, - 0, - 0, - 2, - 1, - "Start: ", - 1, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setUsualFluidInputCount(16) - .setUsualFluidOutputCount(16) - .setNEITransferRect(new Rectangle(79, 34, 18, 18)) - .setLogoPos(80, 61) - .setNEISpecialInfoFormatter(FusionSpecialValueFormatter.INSTANCE) - .setDisableOptimize(true); - public static final GT_Recipe_Map sCentrifugeRecipes = new GT_Recipe_Map( - new HashSet<>(1200), - "gt.recipe.centrifuge", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Centrifuge"), - 2, - 6, - 0, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_CENTRIFUGE) - .setRecipeConfigFile("centrifuge", FIRST_ITEM_OR_FLUID_INPUT) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_CANISTER) - .setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_CENTRIFUGE_FLUID) - .setProgressBar(GT_UITextures.PROGRESSBAR_EXTRACT, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sElectrolyzerRecipes = new GT_Recipe_Map( - new HashSet<>(300), - "gt.recipe.electrolyzer", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Electrolyzer"), - 2, - 6, - 0, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_CHARGER) - .setRecipeConfigFile("electrolyzer", FIRST_ITEM_OR_FLUID_INPUT) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_CANISTER) - .setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_CHARGER_FLUID) - .setProgressBar(GT_UITextures.PROGRESSBAR_EXTRACT, ProgressBar.Direction.RIGHT); - /** - * Use {@link GT_RecipeConstants#COIL_HEAT} as heat level. - */ - public static final GT_Recipe_Map sBlastRecipes = new GT_Recipe_Map( - new HashSet<>(800), - "gt.recipe.blastfurnace", - "Blast Furnace", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 6, - 6, - 1, - 0, - 1, - "Heat Capacity: ", - 1, - " K", - false, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("blastfurnace", FIRST_ITEM_INPUT) - .setNEISpecialInfoFormatter(HeatingCoilSpecialValueFormatter.INSTANCE); - /** - * Use {@link GT_RecipeConstants#COIL_HEAT} as heat level. - */ - public static final GT_Recipe_Map sPlasmaForgeRecipes = new GT_Recipe_Map_LargeNEI( - new HashSet<>(20), - "gt.recipe.plasmaforge", - "DTPF", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "PlasmaForge"), - 9, - 9, - 0, - 0, - 1, - "Heat Capacity: ", - 1, - " K", - false, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setUsualFluidInputCount(9) - .setUsualFluidOutputCount(9) - .setDisableOptimize(true) - .setNEISpecialInfoFormatter(HeatingCoilSpecialValueFormatter.INSTANCE); - - public static final GT_Recipe_Map sTranscendentPlasmaMixerRecipes = new TranscendentPlasmaMixerRecipeMap( - new HashSet<>(20), - "gt.recipe.transcendentplasmamixerrecipes", - "Transcendent Plasma Mixer", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "PlasmaForge"), - 1, - 0, - 0, - 0, - 1, - "", - 0, - "", - false, - true).setDisableOptimize(true); - - public static class GT_FakeSpaceProjectRecipe extends GT_Recipe { - - public final String projectName; - - public GT_FakeSpaceProjectRecipe(boolean aOptimize, ItemStack[] aInputs, FluidStack[] aFluidInputs, - int aDuration, int aEUt, int aSpecialValue, String projectName) { - super(aOptimize, aInputs, null, null, null, aFluidInputs, null, aDuration, aEUt, aSpecialValue); - this.projectName = projectName; - } - } - - public static final GT_Recipe_Map sFakeSpaceProjectRecipes = new GT_Recipe_Map( - new HashSet<>(20), - "gt.recipe.fakespaceprojects", - "Space Projects", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 12, - 0, - 0, - 0, - 1, - translateToLocal("gt.specialvalue.stages") + " ", - 1, - "", - false, - true) { - - IDrawable projectTexture; - - @Override - public ModularWindow.Builder createNEITemplate(IItemHandlerModifiable itemInputsInventory, - IItemHandlerModifiable itemOutputsInventory, IItemHandlerModifiable specialSlotInventory, - IItemHandlerModifiable fluidInputsInventory, IItemHandlerModifiable fluidOutputsInventory, - Supplier<Float> progressSupplier, Pos2d windowOffset) { - ModularWindow.Builder builder = super.createNEITemplate( - itemInputsInventory, - itemOutputsInventory, - specialSlotInventory, - fluidInputsInventory, - fluidOutputsInventory, - progressSupplier, - windowOffset); - addRecipeSpecificDrawable( - builder, - windowOffset, - () -> projectTexture, - new Pos2d(124, 28), - new Size(18, 18)); - return builder; - } - - @Override - public List<Pos2d> getItemInputPositions(int itemInputCount) { - return UIHelper.getGridPositions(itemInputCount, 16, 28, 3); - } - - @Override - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getGridPositions(fluidInputCount, 88, 28, 1); - } - - @Override - protected List<String> handleNEIItemInputTooltip(List<String> currentTip, - GT_NEI_DefaultHandler.FixedPositionedStack pStack) { - super.handleNEIItemOutputTooltip(currentTip, pStack); - if (pStack.item != null && pStack.item.getItem() instanceof GT_FluidDisplayItem) return currentTip; - currentTip.add(GRAY + translateToLocal("Item Count: ") + formatNumbers(pStack.realStackSize)); - return currentTip; - } - - @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { - for (PositionedStack stack : neiCachedRecipe.mInputs) { - if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack && stack.item != null - && !(stack.item.getItem() instanceof GT_FluidDisplayItem)) { - int stackSize = ((GT_NEI_DefaultHandler.FixedPositionedStack) stack).realStackSize; - String displayString; - if (stack.item.stackSize > 9999) { - displayString = ReadableNumberConverter.INSTANCE.toWideReadableForm(stackSize); - } else { - displayString = String.valueOf(stackSize); - } - drawNEIOverlayText(displayString, stack, 0xffffff, 0.5f, true, Alignment.BottomRight); - } - } - if (neiCachedRecipe.mRecipe instanceof GT_FakeSpaceProjectRecipe) { - ISpaceProject project = SpaceProjectManager - .getProject(((GT_FakeSpaceProjectRecipe) neiCachedRecipe.mRecipe).projectName); - if (project != null) { - projectTexture = project.getTexture(); - GuiDraw - .drawStringC(EnumChatFormatting.BOLD + project.getLocalizedName(), 85, 0, 0x404040, false); - } - } - } - - @Override - public void addProgressBarUI(ModularWindow.Builder builder, Supplier<Float> progressSupplier, - Pos2d windowOffset) { - int bar1Width = 17; - int bar2Width = 18; - builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, 17) - .setDirection(ProgressBar.Direction.RIGHT) - .setProgress(() -> progressSupplier.get() * ((float) (bar1Width + bar2Width) / bar1Width)) - .setSynced(false, false) - .setPos(new Pos2d(70, 28).add(windowOffset)) - .setSize(bar1Width, 72)); - builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, 18) - .setDirection(ProgressBar.Direction.RIGHT) - .setProgress( - () -> (progressSupplier.get() - ((float) bar1Width / (bar1Width + bar2Width))) - * ((float) (bar1Width + bar2Width) / bar2Width)) - .setSynced(false, false) - .setPos(new Pos2d(106, 28).add(windowOffset)) - .setSize(bar2Width, 72)); - } - }.useModularUI(true) - .setRenderRealStackSizes(false) - .setUsualFluidInputCount(4) - .setNEIBackgroundOffset(2, 23) - .setLogoPos(152, 83) - .setDisableOptimize(true); - - public static class TranscendentPlasmaMixerRecipeMap extends GT_Recipe_Map { - - public TranscendentPlasmaMixerRecipeMap(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); - useModularUI(true); - setUsualFluidInputCount(20); - setUsualFluidOutputCount(1); - setProgressBarPos(86, 44); - setNEITransferRect( - new Rectangle( - progressBarPos.x - (16 / 2), - progressBarPos.y, - progressBarSize.width + 16, - progressBarSize.height)); - setLogoPos(87, 99); - setNEIBackgroundSize(172, 118); - } - - @Override - public List<Pos2d> getItemInputPositions(int itemInputCount) { - return UIHelper.getGridPositions(itemInputCount, 60, 8, 1); - } - - @Override - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getGridPositions(fluidInputCount, 6, 26, 4, 5); - } - - @Override - public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { - return UIHelper.getGridPositions(fluidOutputCount, 114, 44, 1); - } - - @Override - protected void drawNEIEnergyInfo(NEIRecipeInfo recipeInfo) { - // These look odd because recipeInfo.recipe.mEUt is actually the EU per litre of fluid processed, not - // the EU/t. - drawNEIText( - recipeInfo, - GT_Utility.trans("152", "Total: ") - + formatNumbers(1000L * recipeInfo.recipe.mDuration / 100L * recipeInfo.recipe.mEUt) - + " EU"); - // 1000 / (20 ticks * 5 seconds) = 10L/t. 10L/t * x EU/L = 10 * x EU/t. - long averageUsage = 10L * recipeInfo.recipe.mEUt; - drawNEIText( - recipeInfo, - "Average: " + formatNumbers(averageUsage) - + " EU/t" - + GT_Utility.getTierNameWithParentheses(averageUsage)); - } - } - - /** - * Uses {@link GT_RecipeConstants#ADDITIVE_AMOUNT} for coal/charcoal amount. - */ - public static final GT_Recipe_Map sPrimitiveBlastRecipes = new GT_Recipe_Map( - new HashSet<>(200), - "gt.recipe.primitiveblastfurnace", - "Primitive Blast Furnace", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 3, - 3, - 1, - 0, - 1, - E, - 1, - E, - false, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setRecipeEmitter(builder -> { - Optional<GT_Recipe> rr = builder.validateInputCount(1, 2) - .validateOutputCount(1, 2) - .validateNoInputFluid() - .validateNoOutputFluid() - .noOptimize() - .build(); - if (!rr.isPresent()) return Collections.emptyList(); - ItemStack aInput1 = builder.getItemInputBasic(0); - ItemStack aInput2 = builder.getItemInputBasic(1); - ItemStack aOutput1 = builder.getItemOutput(0); - ItemStack aOutput2 = builder.getItemOutput(1); - if ((aInput1 == null && aInput2 == null) || (aOutput1 == null && aOutput2 == null)) - return Collections.emptyList(); - int aCoalAmount = builder.getMetadata(ADDITIVE_AMOUNT); - if (aCoalAmount <= 0) return Collections.emptyList(); - GT_RecipeTemplate coll = asTemplate(rr.get()); - for (Materials coal : new Materials[] { Materials.Coal, Materials.Charcoal }) { - coll.derive() - .setInputs(aInput1, aInput2, coal.getGems(aCoalAmount)) - .setOutputs(aOutput1, aOutput2, Materials.DarkAsh.getDustTiny(aCoalAmount)); - coll.derive() - .setInputs(aInput1, aInput2, coal.getDust(aCoalAmount)) - .setOutputs(aOutput1, aOutput2, Materials.DarkAsh.getDustTiny(aCoalAmount)); - } - int aDuration = builder.duration; - if (Railcraft.isModLoaded()) { - coll.derive() - .setInputs(aInput1, aInput2, RailcraftToolItems.getCoalCoke(aCoalAmount / 2)) - .setOutputs(aOutput1, aOutput2, Materials.Ash.getDustTiny(aCoalAmount / 2)) - .setDuration(aDuration * 2 / 3); - } - if (GTPlusPlus.isModLoaded()) { - ItemStack cactusCoke = GT_ModHandler - .getModItem(GTPlusPlus.ID, "itemCactusCoke", aCoalAmount * 2L); - ItemStack sugarCoke = GT_ModHandler - .getModItem(GTPlusPlus.ID, "itemSugarCoke", aCoalAmount * 2L); - coll.derive() - .setInputs(aInput1, aInput2, cactusCoke) - .setOutputs(aOutput1, aOutput2, Materials.Ash.getDustTiny(aCoalAmount * 2)) - .setDuration(aDuration * 2 / 3); - coll.derive() - .setInputs(aInput1, aInput2, sugarCoke) - .setOutputs(aOutput1, aOutput2, Materials.Ash.getDustTiny(aCoalAmount * 2)) - .setDuration(aDuration * 2 / 3); - } - if ((aInput1 == null || aInput1.stackSize <= 6) && (aInput2 == null || aInput2.stackSize <= 6) - && (aOutput1 == null || aOutput1.stackSize <= 6) - && (aOutput2 == null || aOutput2.stackSize <= 6)) { - // we don't use GT_Utility.mul() here. It does not have the truncating we need here. - aInput1 = GT_Utility.multiplyStack(10, aInput1); - aInput2 = GT_Utility.multiplyStack(10, aInput2); - aOutput1 = GT_Utility.multiplyStack(10, aOutput1); - aOutput2 = GT_Utility.multiplyStack(10, aOutput2); - for (Materials coal : new Materials[] { Materials.Coal, Materials.Charcoal }) { - coll.derive() - .setInputs(aInput1, aInput2, coal.getBlocks(aCoalAmount)) - .setOutputs(aOutput1, aOutput2, Materials.DarkAsh.getDust(aCoalAmount)) - .setDuration(aDuration * 10); - coll.derive() - .setInputs(aInput1, aInput2, coal.getBlocks(aCoalAmount)) - .setOutputs(aOutput1, aOutput2, Materials.DarkAsh.getDust(aCoalAmount)) - .setDuration(aDuration * 10); - } - if (Railcraft.isModLoaded()) { - coll.derive() - .setInputs(aInput1, aInput2, EnumCube.COKE_BLOCK.getItem(aCoalAmount / 2)) - .setOutputs(aOutput1, aOutput2, Materials.Ash.getDust(aCoalAmount / 2)) - .setDuration(aDuration * 20 / 3); - } - } - return coll.getAll(); - }) - .setRecipeConfigFile("primitiveblastfurnace", FIRST_ITEM_INPUT); - /** - * Uses {@link GT_RecipeConstants#ADDITIVE_AMOUNT} for TNT/ITNT/... amount. Value is truncated to [0, 64] - */ - public static final GT_Recipe_Map sImplosionRecipes = new GT_Recipe_Map( - new HashSet<>(900), - "gt.recipe.implosioncompressor", - "Implosion Compressor", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 2, - 2, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_IMPLOSION) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_EXPLOSIVE) - .setRecipeConfigFile("implosion", FIRST_ITEM_INPUT) - .setRecipeEmitter(b -> { - switch (b.getItemInputsBasic().length) { - case 0: - return Collections.emptyList(); - case 1: - break; - default: - return b.build() - .map(Collections::singletonList) - .orElse(Collections.emptyList()); - } - Optional<GT_Recipe> t = b.noOptimize() - .duration(20) - .eut(30) - .validateInputCount(1, 1) - .validateOutputCount(1, 2) - .build(); - if (!t.isPresent()) return Collections.emptyList(); - ItemStack input = b.getItemInputBasic(0); - GT_RecipeTemplate coll = asTemplate(t.get()); - int tExplosives = Math.min(b.getMetadata(ADDITIVE_AMOUNT), 64); - int tGunpowder = tExplosives << 1; // Worst - int tDynamite = Math.max(1, tExplosives >> 1); // good - @SuppressWarnings("UnnecessaryLocalVariable") - int tTNT = tExplosives; // Slightly better - int tITNT = Math.max(1, tExplosives >> 2); // the best - if (tGunpowder < 65) coll.derive() - .setInputs(input, ItemList.Block_Powderbarrel.get(tGunpowder)); - if (tDynamite < 17) coll.derive() - .setInputs(input, GT_ModHandler.getIC2Item("dynamite", tDynamite, null)); - coll.derive() - .setInputs(input, new ItemStack(Blocks.tnt, tTNT)); - coll.derive() - .setInputs(input, GT_ModHandler.getIC2Item("industrialTnt", tITNT, null)); - return coll.getAll(); - }) - .setDisableOptimize(true) - .setProgressBar(GT_UITextures.PROGRESSBAR_COMPRESS, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sVacuumRecipes = new GT_Recipe_Map( - new HashSet<>(305), - "gt.recipe.vacuumfreezer", - "Vacuum Freezer", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - E, - 1, - E, - false, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setRecipeConfigFile("vacuumfreezer", FIRST_ITEM_INPUT) - .setRecipeEmitter(b -> { - b.noOptimize(); - FluidStack in, out; - if (isArrayOfLength(b.getItemInputsBasic(), 1) && isArrayOfLength(b.getItemOutputs(), 1) - && isArrayEmptyOrNull(b.getFluidInputs()) - && isArrayEmptyOrNull(b.getFluidOutputs()) - && (in = GT_Utility.getFluidForFilledItem(b.getItemInputBasic(0), true)) != null - && (out = GT_Utility.getFluidForFilledItem(b.getItemOutput(0), true)) != null) { - return Arrays.asList( - b.build() - .get(), - b.itemInputs() - .itemOutputs() - .fluidInputs(in) - .fluidOutputs(out) - .build() - .get()); - } - return buildOrEmpty(b); - }) - .setUsualFluidInputCount(2); - /** - * using {@code .addTo(sChemicalRecipes)} will cause the recipe to be added to single block recipe map ONLY! - * use {@link GT_RecipeConstants#UniversalChemical} to add to both. - */ - public static final GT_Recipe_Map sChemicalRecipes = new GT_Recipe_Map( - new HashSet<>(1170), - "gt.recipe.chemicalreactor", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "ChemicalReactor"), - 2, - 2, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_MOLECULAR_1) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_MOLECULAR_2) - .setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_MOLECULAR_3) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_VIAL_1) - .setSlotOverlay(true, true, GT_UITextures.OVERLAY_SLOT_VIAL_2) - .setRecipeConfigFile("chemicalreactor", FIRST_ITEM_OR_FLUID_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT) - .setDisableOptimize(true); - /** - * using {@code .addTo(sMultiblockChemicalRecipes)} will cause the recipe to be added to multiblock recipe map - * ONLY! - * use {@link GT_RecipeConstants#UniversalChemical} to add to both. - */ - public static final GT_Recipe_Map sMultiblockChemicalRecipes = // - new GT_Recipe_Map_LargeChemicalReactor() - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT) - .setUsualFluidInputCount(6) - .setUsualFluidOutputCount(6) - .setDisableOptimize(true); - public static final GT_Recipe_Map sDistillationRecipes = // - new GT_Recipe_Map_DistillationTower().setRecipeConfigFile("distillation", FIRST_FLUIDSTACK_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT) - .setUsualFluidOutputCount(11) - .setDisableOptimize(true); - public static final GT_Recipe_Map_OilCracker sCrackingRecipes = (GT_Recipe_Map_OilCracker) // - new GT_Recipe_Map_OilCracker().setRecipeConfigFile("cracking", FIRST_FLUIDSTACK_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE, ProgressBar.Direction.RIGHT) - .setUsualFluidInputCount(2); - /** - * @deprecated Use sCrackingRecipes instead - */ - @Deprecated - public static final GT_Recipe_Map sCrakingRecipes = sCrackingRecipes; - - public static final GT_Recipe_Map sPyrolyseRecipes = new GT_Recipe_Map( - new HashSet<>(150), - "gt.recipe.pyro", - "Pyrolyse Oven", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 2, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setDisableOptimize(true) - .setRecipeConfigFile("pyrolyse", FIRST_ITEM_INPUT); - public static final GT_Recipe_Map sWiremillRecipes = new GT_Recipe_Map( - new HashSet<>(450), - "gt.recipe.wiremill", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Wiremill"), - 2, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_WIREMILL) - .setRecipeConfigFile("wiremill", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_WIREMILL, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sBenderRecipes = new GT_Recipe_Map( - new HashSet<>(5000), - "gt.recipe.metalbender", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Bender"), - 2, - 1, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_BENDER) - .setRecipeConfigFile("bender", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_BENDING, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sAlloySmelterRecipes = new GT_Recipe_Map( - new HashSet<>(12000), - "gt.recipe.alloysmelter", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "AlloySmelter"), - 2, - 1, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_FURNACE) - .setRecipeEmitter(b -> { - if (Materials.Graphite.contains(b.getItemInputBasic(0))) return Collections.emptyList(); - if (GT_Utility.isArrayOfLength(b.getItemInputsBasic(), 1)) { - ItemStack aInput1 = b.getItemInputBasic(0); - if (((OrePrefixes.ingot.contains(aInput1)) || (OrePrefixes.dust.contains(aInput1)) - || (OrePrefixes.gem.contains(aInput1)))) return Collections.emptyList(); - } - return buildOrEmpty( - b.validateNoInputFluid() - .validateNoOutputFluid() - .validateInputCount(1, 2) - .validateOutputCount(1, 1)); - }) - .setRecipeConfigFile( - "alloysmelting", - r -> GT_Config - .getStackConfigName(GT_Utility.isArrayOfLength(r.mInputs, 1) ? r.mInputs[0] : r.mOutputs[0])) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setSlotOverlaySteam(false, GT_UITextures.OVERLAY_SLOT_FURNACE_STEAM) - .setProgressBarSteam(GT_UITextures.PROGRESSBAR_ARROW_STEAM); - public static final GT_Recipe_Map sAssemblerRecipes = new GT_Recipe_Map_Assembler( - new HashSet<>(8200), - "gt.recipe.assembler", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Assembler2"), - 9, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CIRCUIT) - .setRecipeConfigFile("assembling", FIRST_ITEM_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_ASSEMBLE, ProgressBar.Direction.RIGHT) - .setDisableOptimize(true); - public static final GT_Recipe_Map sCircuitAssemblerRecipes = new GT_Recipe_Map_Assembler( - new HashSet<>(605), - "gt.recipe.circuitassembler", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "CircuitAssembler"), - 6, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setNEIUnificateOutput(!NEICustomDiagrams.isModLoaded()) - .setRecipeConfigFile("circuitassembler", FIRST_ITEM_OUTPUT) - .setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CIRCUIT) - .setProgressBar(GT_UITextures.PROGRESSBAR_CIRCUIT_ASSEMBLER, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sCannerRecipes = new GT_Recipe_Map( - new HashSet<>(900), - "gt.recipe.canner", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Canner"), - 2, - 2, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_CANNER) - .setRecipeConfigFile("canning", FIRST_ITEM_INPUT) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_CANISTER) - .setProgressBar(GT_UITextures.PROGRESSBAR_CANNER, ProgressBar.Direction.RIGHT); - @Deprecated - public static final GT_Recipe_Map sCNCRecipes = new GT_Recipe_Map( - new HashSet<>(100), - "gt.recipe.cncmachine", - "CNC Machine", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 2, - 1, - 2, - 1, - 1, - E, - 1, - E, - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sLatheRecipes = new GT_Recipe_Map( - new HashSet<>(1150), - "gt.recipe.lathe", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Lathe"), - 1, - 2, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_ROD_1) - .setSlotOverlay(false, true, true, GT_UITextures.OVERLAY_SLOT_ROD_2) - .setSlotOverlay(false, true, false, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeConfigFile("lathe", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_LATHE, ProgressBar.Direction.RIGHT) - .addSpecialTexture(5, 18, 98, 24, GT_UITextures.PROGRESSBAR_LATHE_BASE); - public static final GT_Recipe_Map sCutterRecipes = new GT_Recipe_Map( - new HashSet<>(5125), - "gt.recipe.cuttingsaw", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Cutter4"), - 2, - 4, - 1, - 1, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_BOX) - .setSlotOverlay(false, true, true, GT_UITextures.OVERLAY_SLOT_CUTTER_SLICED) - .setSlotOverlay(false, true, false, GT_UITextures.OVERLAY_SLOT_DUST) - .setRecipeEmitter(b -> { - b.validateInputCount(1, 2) - .validateOutputCount(1, 4) - .validateNoOutputFluid(); - if ((b.getFluidInputs() != null && b.getFluidInputs().length > 0) || !b.isValid()) - return buildOrEmpty(b.validateInputFluidCount(1, 1)); - int aDuration = b.getDuration(), aEUt = b.getEUt(); - Collection<GT_Recipe> ret = new ArrayList<>(); - b.copy() - .fluidInputs(Materials.Water.getFluid(GT_Utility.clamp(aDuration * aEUt / 320, 4, 1000))) - .duration(aDuration * 2) - .build() - .ifPresent(ret::add); - b.copy() - .fluidInputs(GT_ModHandler.getDistilledWater(GT_Utility.clamp(aDuration * aEUt / 426, 3, 750))) - .duration(aDuration * 2) - .build() - .ifPresent(ret::add); - b.fluidInputs(Materials.Lubricant.getFluid(GT_Utility.clamp(aDuration * aEUt / 1280, 1, 250))) - .duration(aDuration) - .build() - .ifPresent(ret::add); - return ret; - }) - .setRecipeConfigFile("cutting", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_CUT, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sSlicerRecipes = new GT_Recipe_Map( - new HashSet<>(20), - "gt.recipe.slicer", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Slicer"), - 2, - 1, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_SQUARE) - .setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_SLICE_SHAPE) - .setSlotOverlay(false, true, GT_UITextures.OVERLAY_SLOT_SLICER_SLICED) - .setRecipeConfigFile("slicer", FIRST_ITEM_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_SLICE, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sExtruderRecipes = new GT_Recipe_Map( - new HashSet<>(13000), - "gt.recipe.extruder", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Extruder"), - 2, - 1, - 2, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, false, GT_UITextures.OVERLAY_SLOT_EXTRUDER_SHAPE) - .setRecipeConfigFile("extruder", FIRST_ITEM_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_EXTRUDE, ProgressBar.Direction.RIGHT); - - public static final GT_Recipe_Map sHammerRecipes = new GT_Recipe_Map( - new HashSet<>(3800), - "gt.recipe.hammer", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Hammer"), - 2, - 2, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setUsualFluidInputCount(2) - .setUsualFluidOutputCount(2) - .setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_HAMMER) - .setRecipeConfigFile("forgehammer", FIRST_ITEM_OUTPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_HAMMER, ProgressBar.Direction.DOWN) - .addSpecialTexture(20, 6, 78, 42, GT_UITextures.PROGRESSBAR_HAMMER_BASE) - .setSlotOverlaySteam(false, GT_UITextures.OVERLAY_SLOT_HAMMER_STEAM) - .setProgressBarSteam(GT_UITextures.PROGRESSBAR_HAMMER_STEAM) - .addSpecialTextureSteam(20, 6, 78, 42, GT_UITextures.PROGRESSBAR_HAMMER_BASE_STEAM); - public static final GT_Recipe_Map sAmplifiers = new GT_Recipe_Map( - new HashSet<>(2), - "gt.recipe.uuamplifier", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Amplifabricator"), - 1, - 0, - 1, - 0, - 1, - E, - 1, - E, - true, - true).setSlotOverlay(false, false, GT_UITextures.OVERLAY_SLOT_CENTRIFUGE) - .setSlotOverlay(true, true, GT_UITextures.OVERLAY_SLOT_UUA) - .setRecipeConfigFile("amplifier", FIRST_ITEM_INPUT) - .setProgressBar(GT_UITextures.PROGRESSBAR_EXTRACT, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sMassFabFakeRecipes = new GT_Recipe_Map( - new HashSet<>(2), - "gt.recipe.massfab", - null, - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Massfabricator"), - 1, - 0, - 1, - 0, - 8, - E, - 1, - E, - true, - true).setSlotOverlay(true, false, GT_UITextures.OVERLAY_SLOT_UUA) - .setSlotOverlay(true, true, GT_UITextures.OVERLAY_SLOT_UUM) - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sDieselFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(20), - "gt.recipe.dieselgeneratorfuel", - "Combustion Generator Fuels", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sExtremeDieselFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(20), - "gt.recipe.extremedieselgeneratorfuel", - "Extreme Diesel Engine Fuel", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sTurbineFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(25), - "gt.recipe.gasturbinefuel", - "Gas Turbine Fuel", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sHotFuels = new GT_Recipe_Map_Fuel( - new HashSet<>(10), - "gt.recipe.thermalgeneratorfuel", - "Thermal Generator Fuels", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - false); - public static final GT_Recipe_Map_Fuel sDenseLiquidFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(15), - "gt.recipe.semifluidboilerfuels", - "Semifluid Boiler Fuels", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sPlasmaFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(100), - "gt.recipe.plasmageneratorfuels", - "Plasma Generator Fuels", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sMagicFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(100), - "gt.recipe.magicfuels", - "Magic Energy Absorber Fuels", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sSmallNaquadahReactorFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(1), - "gt.recipe.smallnaquadahreactor", - "Naquadah Reactor MkI", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sLargeNaquadahReactorFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(1), - "gt.recipe.largenaquadahreactor", - "Naquadah Reactor MkII", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sHugeNaquadahReactorFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(1), - "gt.recipe.fluidnaquadahreactor", - "Naquadah Reactor MkIII", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sExtremeNaquadahReactorFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(1), - "gt.recipe.hugenaquadahreactor", - "Naquadah Reactor MkIV", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sUltraHugeNaquadahReactorFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(1), - "gt.recipe.extrahugenaquadahreactor", - "Naquadah Reactor MkV", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map_Fuel sFluidNaquadahReactorFuels = (GT_Recipe_Map_Fuel) new GT_Recipe_Map_Fuel( - new HashSet<>(1), - "gt.recipe.fluidfuelnaquadahreactor", - "Fluid Naquadah Reactor", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 0, - 0, - 1, - "Fuel Value: ", - 1000, - " EU", - true, - true).setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - public static final GT_Recipe_Map sMultiblockElectrolyzerRecipes = new GT_Recipe_Map( - new HashSet<>(300), - "gt.recipe.largeelectrolyzer", - "Large(PA) Electrolyzer", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LCRNEI"), - 1, - 9, - 0, - 0, - 1, - "", - 0, - "", - true, - false).setRecipeEmitter(GT_RecipeMapUtil::buildRecipeForMultiblock); - - public static final GT_Recipe_Map sMultiblockCentrifugeRecipes = new GT_Recipe_Map( - new HashSet<>(1200), - "gt.recipe.largecentrifuge", - "Large(PA) Centrifuge", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LCRNEI"), - 1, - 9, - 0, - 0, - 1, - "", - 0, - "", - true, - false).setRecipeEmitter(GT_RecipeMapUtil::buildRecipeForMultiblock) - .setDisableOptimize(true); - public static final GT_Recipe_Map sMultiblockMixerRecipes = new GT_Recipe_Map( - new HashSet<>(900), - "gt.recipe.largemixer", - "Large(PA) Mixer", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LCRNEI"), - 9, - 3, - 0, - 0, - 1, - "", - 0, - "", - true, - false).setRecipeEmitter(GT_RecipeMapUtil::buildRecipeForMultiblockNoCircuit) - .setDisableOptimize(true); - public static final GT_Recipe_Map_LargeBoilerFakeFuels sLargeBoilerFakeFuels = (GT_Recipe_Map_LargeBoilerFakeFuels) new GT_Recipe_Map_LargeBoilerFakeFuels() - .setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT) - .setDisableOptimize(true); - - public static final GT_Recipe_Map sNanoForge = new GT_Recipe_Map( - new HashSet<>(10), - "gt.recipe.nanoforge", - "Nano Forge", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LCRNEI"), - 6, - 2, - 2, - 1, - 1, - "Tier: ", - 1, - "", - false, - true).useModularUI(true) - .setUsualFluidInputCount(3) - .setDisableOptimize(true) - .setSlotOverlay(false, false, true, GT_UITextures.OVERLAY_SLOT_LENS) - .setProgressBar(GT_UITextures.PROGRESSBAR_ASSEMBLE, ProgressBar.Direction.RIGHT); - - public static final GT_Recipe_Map sPCBFactory = new GT_Recipe_Map( - new HashSet<>(10), - "gt.recipe.pcbfactory", - "PCB Factory", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LCRNEI"), - 6, - 9, - 3, - 1, - 1, - E, - 0, - E, - true, - true).useModularUI(true) - .setUsualFluidInputCount(3) - .setUsualFluidOutputCount(0) - .setDisableOptimize(true) - .setProgressBar(GT_UITextures.PROGRESSBAR_ASSEMBLE, ProgressBar.Direction.RIGHT) - .setNEISpecialInfoFormatter((recipeInfo, applyPrefixAndSuffix) -> { - List<String> result = new ArrayList<>(); - int bitmap = recipeInfo.recipe.mSpecialValue; - if ((bitmap & 0b1) > 0) { - result.add(GT_Utility.trans("336", "PCB Factory Tier: ") + 1); - } else if ((bitmap & 0b10) > 0) { - result.add(GT_Utility.trans("336", "PCB Factory Tier: ") + 2); - } else if ((bitmap & 0b100) > 0) { - result.add(GT_Utility.trans("336", "PCB Factory Tier: ") + 3); - } - if ((bitmap & 0b1000) > 0) { - result.add(GT_Utility.trans("337", "Upgrade Required: ") + GT_Utility.trans("338", "Bio")); - } - return result; - }); - - public static final GT_Recipe_Map_IC2NuclearFake sIC2NuclearFakeRecipe = (GT_Recipe_Map_IC2NuclearFake) new GT_Recipe_Map_IC2NuclearFake() - .setDisableOptimize(true); - - static { - sCentrifugeRecipes.addDownstream(sMultiblockCentrifugeRecipes.deepCopyInput()); - sMixerRecipes.addDownstream(sMultiblockMixerRecipes.deepCopyInput()); - sElectrolyzerRecipes.addDownstream(sMultiblockElectrolyzerRecipes.deepCopyInput()); - sDieselFuels.addDownstream( - IGT_RecipeMap.newRecipeMap( - b -> b.build() - .map(sLargeBoilerFakeFuels::addDieselRecipe) - .map(Collections::singletonList) - .orElse(Collections.emptyList()))); - sDenseLiquidFuels.addDownstream( - IGT_RecipeMap.newRecipeMap( - b -> b.build() - .map(sLargeBoilerFakeFuels::addDenseLiquidRecipe) - .map(Collections::singletonList) - .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 - */ - public final Map<GT_ItemStack, Collection<GT_Recipe>> mRecipeItemMap = new /* Concurrent */ HashMap<>(); - /** - * HashMap of Recipes based on their Fluids - */ - public final Map<String, Collection<GT_Recipe>> mRecipeFluidMap = new HashMap<>(); - - public final HashSet<String> mRecipeFluidNameMap = new HashSet<>(); - /** - * The List of all Recipes - */ - public final Collection<GT_Recipe> mRecipeList; - /** - * String used as an unlocalised Name. - */ - public final String mUnlocalizedName; - /** - * String used in NEI for the Recipe Lists. If null it will use the unlocalised Name instead - */ - public final String mNEIName; - /** - * GUI used for NEI Display. Usually the GUI of the Machine itself - */ - public final String mNEIGUIPath; - - public final String mNEISpecialValuePre, mNEISpecialValuePost; - public final int mUsualInputCount, mUsualOutputCount, mNEISpecialValueMultiplier, mMinimalInputItems, - mMinimalInputFluids, mAmperage; - public final boolean mNEIAllowed, mShowVoltageAmperageInNEI; - - /** - * Whether to show oredict equivalent outputs when NEI is queried to show recipe - */ - public boolean mNEIUnificateOutput = true; - - /** - * Unique identifier for this recipe map. Generated from aUnlocalizedName and a few other parameters. See - * constructor for details. - */ - public final String mUniqueIdentifier; - - /** - * Whether this recipe map contains any fluid outputs. - */ - private boolean mHasFluidOutputs = false; - - /** - * Whether this recipe map contains special slot inputs. - */ - 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. - */ - private int usualFluidInputCount; - - /** - * How many fluid outputs 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. - */ - private int usualFluidOutputCount; - - /** - * Whether to use ModularUI for slot placements. - */ - public boolean useModularUI = false; - - /** - * Overlays used for GUI. 1 = If it's fluid slot. 2 = If it's output slot. 4 = If it's first slot in the same - * section, e.g. first slot in the item output slots 8 = If it's special item slot. - */ - private final TByteObjectMap<IDrawable> slotOverlays = new TByteObjectHashMap<>(); - - /** - * Overlays used for GUI on steam machine. 1 = If it's fluid slot. 2 = If it's output slot. 4 = If it's first - * slot in the same section, e.g. first slot in the item output slots 8 = If it's special item slot. - */ - private final TByteObjectMap<SteamTexture> slotOverlaysSteam = new TByteObjectHashMap<>(); - - /** - * Progressbar used for BasicMachine GUI and/or NEI. Unless specified, size should be (20, 36), consisting of - * two parts; First is (20, 18) size of "empty" image at the top, Second is (20, 18) size of "filled" image at - * the bottom. - */ - private FallbackableUITexture progressBarTexture; - - /** - * Progressbar used for steam machine GUI and/or NEI. Unless specified, size should be (20, 36), consisting of - * two parts; First is (20, 18) size of "empty" image at the top, Second is (20, 18) size of "filled" image at - * the bottom. - */ - private FallbackableSteamTexture progressBarTextureSteam; - - public ProgressBar.Direction progressBarDirection = ProgressBar.Direction.RIGHT; - - public Size progressBarSize = new Size(20, 18); - - public Pos2d progressBarPos = new Pos2d(78, 24); - - public Rectangle neiTransferRect = new Rectangle( - progressBarPos.x - (16 / 2), - progressBarPos.y, - progressBarSize.width + 16, - progressBarSize.height); - - /** - * Image size in direction of progress. Used for non-smooth rendering. - */ - private int progressBarImageSize; - - /** - * Additional textures shown on GUI. - */ - public final List<Pair<IDrawable, Pair<Size, Pos2d>>> specialTextures = new ArrayList<>(); - - /** - * Additional textures shown on steam machine GUI. - */ - public final List<Pair<SteamTexture, Pair<Size, Pos2d>>> specialTexturesSteam = new ArrayList<>(); - - public IDrawable logo = GT_UITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT; - - public Pos2d logoPos = new Pos2d(152, 63); - - public Size logoSize = new Size(17, 17); - - public Pos2d neiBackgroundOffset = new Pos2d(2, 3); - - public Size neiBackgroundSize = new Size(172, 82); - - protected final GT_GUIColorOverride colorOverride; - private int neiTextColorOverride = -1; - - private INEISpecialInfoFormatter neiSpecialInfoFormatter; - - private final boolean checkForCollision = true; - private boolean allowNoInput; - private boolean allowNoInputFluid; - private boolean allowNoOutput; - private boolean allowNoOutputFluid; - private boolean disableOptimize = false; - private Function<? super GT_RecipeBuilder, ? extends Iterable<? extends GT_Recipe>> recipeEmitter = this::defaultBuildRecipe; - private Function<? super GT_Recipe, ? extends GT_Recipe> specialHandler; - private String recipeConfigCategory; - private Function<? super GT_Recipe, String> recipeConfigKeyConvertor; - private final List<IGT_RecipeMap> downstreams = new ArrayList<>(0); - - /** - * Flag if a comparator should be used to search the recipe in NEI (which is defined in {@link Power}). Else - * only the voltage will be used to find recipes - */ - public boolean useComparatorForNEI; - - /** - * Whether to render the actual size of stacks or a size of 1. - */ - public boolean renderRealStackSizes = true; - - /** - * Initialises a new type of Recipe Handler. - * - * @param aRecipeList a List you specify as Recipe List. Usually just an ArrayList with a - * pre-initialised Size. - * @param aUnlocalizedName the unlocalised Name of this Recipe Handler, used mainly for NEI. - * @param aLocalName @deprecated the displayed Name inside the NEI Recipe GUI for optionally - * registering aUnlocalizedName - * with the language manager - * @param aNEIGUIPath the displayed GUI Texture, usually just a Machine GUI. Auto-Attaches ".png" - * if forgotten. - * @param aUsualInputCount the usual amount of Input Slots this Recipe Class has. - * @param aUsualOutputCount the usual amount of Output Slots this Recipe Class has. - * @param aNEISpecialValuePre the String in front of the Special Value in NEI. - * @param aNEISpecialValueMultiplier the Value the Special Value is getting Multiplied with before displaying - * @param aNEISpecialValuePost the String after the Special Value. Usually for a Unit or something. - * @param aNEIAllowed if NEI is allowed to display this Recipe Handler in general. - */ - public GT_Recipe_Map(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) { - sMappings.add(this); - mNEIAllowed = aNEIAllowed; - mShowVoltageAmperageInNEI = aShowVoltageAmperageInNEI; - mRecipeList = aRecipeList; - mNEIName = aNEIName == null ? aUnlocalizedName : aNEIName; - mNEIGUIPath = aNEIGUIPath.endsWith(".png") ? aNEIGUIPath : aNEIGUIPath + ".png"; - mNEISpecialValuePre = aNEISpecialValuePre; - mNEISpecialValueMultiplier = aNEISpecialValueMultiplier; - mNEISpecialValuePost = aNEISpecialValuePost; - mAmperage = aAmperage; - mUsualInputCount = aUsualInputCount; - mUsualOutputCount = aUsualOutputCount; - mMinimalInputItems = aMinimalInputItems; - mMinimalInputFluids = aMinimalInputFluids; - GregTech_API.sItemStackMappings.add(mRecipeItemMap); - mUnlocalizedName = aUnlocalizedName; - if (aLocalName != null) { - GT_LanguageManager.addStringLocalization(mUnlocalizedName, aLocalName); - } - mUniqueIdentifier = String.format( - "%s_%d_%d_%d_%d_%d", - aUnlocalizedName, - aAmperage, - aUsualInputCount, - aUsualOutputCount, - aMinimalInputFluids, - aMinimalInputItems); - progressBarTexture = new FallbackableUITexture( - UITexture.fullImage(GregTech.ID, "gui/progressbar/" + mUnlocalizedName), - GT_UITextures.PROGRESSBAR_ARROW); - colorOverride = GT_GUIColorOverride.get(ModularUITextures.VANILLA_BACKGROUND.location); - if (sIndexedMappings.put(mUniqueIdentifier, this) != null) - throw new IllegalArgumentException("Duplicate recipe map registered: " + mUniqueIdentifier); - } - - @Deprecated - public GT_Recipe_Map(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, - boolean aNEIUnificateOutput) { - this( - aRecipeList, - aUnlocalizedName, - aLocalName, - aNEIName, - aNEIGUIPath, - aUsualInputCount, - aUsualOutputCount, - aMinimalInputItems, - aMinimalInputFluids, - aAmperage, - aNEISpecialValuePre, - aNEISpecialValueMultiplier, - aNEISpecialValuePost, - aShowVoltageAmperageInNEI, - aNEIAllowed); - setNEIUnificateOutput(aNEIUnificateOutput); - } - - public GT_Recipe_Map setDisableOptimize(boolean disableOptimize) { - this.disableOptimize = disableOptimize; - 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; - } - - public GT_Recipe_Map useComparatorForNEI(boolean use) { - this.useComparatorForNEI = use; - return this; - } - - public GT_Recipe_Map setRenderRealStackSizes(boolean renderRealStackSizes) { - this.renderRealStackSizes = renderRealStackSizes; - return this; - } - - public GT_Recipe_Map useModularUI(boolean use) { - this.useModularUI = use; - return this; - } - - public GT_Recipe_Map setSlotOverlay(boolean isFluid, boolean isOutput, boolean isFirst, boolean isSpecial, - IDrawable slotOverlay) { - useModularUI(true); - this.slotOverlays.put( - (byte) ((isFluid ? 1 : 0) + (isOutput ? 2 : 0) + (isFirst ? 4 : 0) + (isSpecial ? 8 : 0)), - slotOverlay); - return this; - } - - public GT_Recipe_Map setSlotOverlay(boolean isFluid, boolean isOutput, boolean isFirst, IDrawable slotOverlay) { - return setSlotOverlay(isFluid, isOutput, isFirst, false, slotOverlay); - } - - public GT_Recipe_Map setSlotOverlay(boolean isFluid, boolean isOutput, IDrawable slotOverlay) { - return setSlotOverlay(isFluid, isOutput, true, slotOverlay) - .setSlotOverlay(isFluid, isOutput, false, slotOverlay); - } - - public GT_Recipe_Map setSlotOverlaySteam(boolean isFluid, boolean isOutput, boolean isFirst, boolean isSpecial, - SteamTexture slotOverlay) { - useModularUI(true); - this.slotOverlaysSteam.put( - (byte) ((isFluid ? 1 : 0) + (isOutput ? 2 : 0) + (isFirst ? 4 : 0) + (isSpecial ? 8 : 0)), - slotOverlay); - return this; - } - - public GT_Recipe_Map setSlotOverlaySteam(boolean isOutput, boolean isFirst, SteamTexture slotOverlay) { - return setSlotOverlaySteam(false, isOutput, isFirst, false, slotOverlay); - } - - public GT_Recipe_Map setSlotOverlaySteam(boolean isOutput, SteamTexture slotOverlay) { - return setSlotOverlaySteam(false, isOutput, true, false, slotOverlay) - .setSlotOverlaySteam(false, isOutput, false, false, slotOverlay); - } - - public GT_Recipe_Map setProgressBar(UITexture progressBarTexture, ProgressBar.Direction progressBarDirection) { - return setProgressBarWithFallback( - new FallbackableUITexture( - UITexture.fullImage(GregTech.ID, "gui/progressbar/" + mUnlocalizedName), - progressBarTexture), - progressBarDirection); - } - - public GT_Recipe_Map setProgressBar(UITexture progressBarTexture) { - return setProgressBar(progressBarTexture, ProgressBar.Direction.RIGHT); - } - - /** - * Some resource packs want to use custom progress bar textures even for plain arrow. This method allows them to - * add unique textures, yet other packs don't need to make textures for every recipemap. - */ - public GT_Recipe_Map setProgressBarWithFallback(FallbackableUITexture progressBarTexture, - ProgressBar.Direction progressBarDirection) { - useModularUI(true); - this.progressBarTexture = progressBarTexture; - this.progressBarDirection = progressBarDirection; - return this; - } - - public GT_Recipe_Map setProgressBarSteam(SteamTexture progressBarTexture) { - return setProgressBarSteamWithFallback( - new FallbackableSteamTexture( - SteamTexture.fullImage(GregTech.ID, "gui/progressbar/" + mUnlocalizedName + "_%s"), - progressBarTexture)); - } - - public GT_Recipe_Map setProgressBarSteamWithFallback(FallbackableSteamTexture progressBarTexture) { - this.progressBarTextureSteam = progressBarTexture; - return this; - } - - public GT_Recipe_Map setProgressBarSize(int x, int y) { - useModularUI(true); - this.progressBarSize = new Size(x, y); - return this; - } - - public GT_Recipe_Map setProgressBarPos(int x, int y) { - useModularUI(true); - this.progressBarPos = new Pos2d(x, y); - return this; - } - - public GT_Recipe_Map setProgressBarImageSize(int progressBarImageSize) { - useModularUI(true); - this.progressBarImageSize = progressBarImageSize; - return this; - } - - public GT_Recipe_Map setNEITransferRect(Rectangle neiTransferRect) { - useModularUI(true); - this.neiTransferRect = neiTransferRect; - return this; - } - - public GT_Recipe_Map addSpecialTexture(int width, int height, int x, int y, IDrawable texture) { - useModularUI(true); - specialTextures - .add(new ImmutablePair<>(texture, new ImmutablePair<>(new Size(width, height), new Pos2d(x, y)))); - return this; - } - - public GT_Recipe_Map addSpecialTextureSteam(int width, int height, int x, int y, SteamTexture texture) { - useModularUI(true); - specialTexturesSteam - .add(new ImmutablePair<>(texture, new ImmutablePair<>(new Size(width, height), new Pos2d(x, y)))); - return this; - } - - public GT_Recipe_Map setUsualFluidInputCount(int usualFluidInputCount) { - useModularUI(true); - this.usualFluidInputCount = usualFluidInputCount; - return this; - } - - public GT_Recipe_Map setUsualFluidOutputCount(int usualFluidOutputCount) { - useModularUI(true); - this.usualFluidOutputCount = usualFluidOutputCount; - return this; - } - - public GT_Recipe_Map setLogo(IDrawable logo) { - useModularUI(true); - this.logo = logo; - return this; - } - - public GT_Recipe_Map setLogoPos(int x, int y) { - useModularUI(true); - this.logoPos = new Pos2d(x, y); - return this; - } - - public GT_Recipe_Map setLogoSize(int width, int height) { - useModularUI(true); - this.logoSize = new Size(width, height); - return this; - } - - public GT_Recipe_Map setNEIBackgroundOffset(int x, int y) { - useModularUI(true); - this.neiBackgroundOffset = new Pos2d(x, y); - return this; - } - - public GT_Recipe_Map setNEIBackgroundSize(int width, int height) { - useModularUI(true); - this.neiBackgroundSize = new Size(width, height); - return this; - } - - public GT_Recipe_Map setNEISpecialInfoFormatter(INEISpecialInfoFormatter neiSpecialInfoFormatter) { - this.neiSpecialInfoFormatter = neiSpecialInfoFormatter; - return this; - } - - /** - * Change how recipes are emitted by a particular recipe builder. Can emit multiple recipe per builder. - */ - public GT_Recipe_Map setRecipeEmitter( - Function<? super GT_RecipeBuilder, ? extends Iterable<? extends GT_Recipe>> func) { - this.recipeEmitter = func; - return this; - } - - /** - * Change how recipes are emitted by a particular recipe builder. Can emit multiple recipe per builder. - * <p> - * Unlike {@link #setRecipeEmitter(Function)}, this one does not clear the existing recipe being emitted, if any - */ - public GT_Recipe_Map combineRecipeEmitter( - Function<? super GT_RecipeBuilder, ? extends Iterable<? extends GT_Recipe>> func) { - // move recipeEmitter to local variable, so lambda capture the function itself instead of this - Function<? super GT_RecipeBuilder, ? extends Iterable<? extends GT_Recipe>> cur = recipeEmitter; - this.recipeEmitter = b -> Iterables.concat(cur.apply(b), func.apply(b)); - return this; - } - - /** - * Change how recipes are emitted by a particular recipe builder. Should not return null. - */ - public GT_Recipe_Map setRecipeEmitterSingle(Function<? super GT_RecipeBuilder, ? extends GT_Recipe> func) { - return setRecipeEmitter(func.andThen(Collections::singletonList)); - } - - /** - * Change how recipes are emitted by a particular recipe builder. Effectively add a new recipe per recipe added. - * func must not return null. - * <p> - * Unlike {@link #setRecipeEmitter(Function)}, this one does not clear the existing recipe being emitted, if any - */ - public GT_Recipe_Map combineRecipeEmitterSingle(Function<? super GT_RecipeBuilder, ? extends GT_Recipe> func) { - return combineRecipeEmitter(func.andThen(Collections::singletonList)); - } - - private static <T> Function<? super T, ? extends T> withIdentityReturn(Consumer<T> func) { - return r -> { - func.accept(r); - return r; - }; - } - - /** - * Run a custom hook on all recipes added <b>via builder</b>. For more complicated behavior subclass this, then - * override {@link #doAdd(GT_RecipeBuilder)} - * - * Recipes added via one of the overloads of addRecipe will NOT be affected by this function. - */ - public GT_Recipe_Map setRecipeSpecialHandler(Function<? super GT_Recipe, ? extends GT_Recipe> func) { - this.specialHandler = func; - return this; - } - - /** - * Run a custom hook on all recipes added <b>via builder</b>. For more complicated behavior, create a subclass - * and override {@link #doAdd(GT_RecipeBuilder)} - * - * Recipes added via one of the overloads of addRecipe will NOT be affected by this function. - */ - public GT_Recipe_Map setRecipeSpecialHandler(Consumer<GT_Recipe> func) { - return setRecipeSpecialHandler(withIdentityReturn(func)); - } - - /** - * Run a custom hook on all recipes added <b>via builder</b>. For more complicated behavior subclass this, then - * override {@link #doAdd(GT_RecipeBuilder)}. - * <p> - * Recipes added via one of the overloads of addRecipe will NOT be affected by this function. - * <p> - * Unlike {@link #setRecipeSpecialHandler(Function)}, this one will not replace the existing special handler. - * The supplied function will be given the output of existing handler when a recipe is added. - */ - public GT_Recipe_Map chainRecipeSpecialHandler(Function<? super GT_Recipe, ? extends GT_Recipe> func) { - this.specialHandler = specialHandler == null ? func : specialHandler.andThen(func); - return this; - } - - /** - * Run a custom hook on all recipes added <b>via builder</b>. For more complicated behavior subclass this, then - * override {@link #doAdd(GT_RecipeBuilder)}. - * <p> - * Recipes added via one of the overloads of addRecipe will NOT be affected by this function. - * <p> - * Unlike {@link #setRecipeSpecialHandler(Function)}, this one will not replace the existing special handler. - * The supplied function will be given the output of existing handler when a recipe is added. - */ - public GT_Recipe_Map chainRecipeSpecialHandler(Consumer<GT_Recipe> func) { - return chainRecipeSpecialHandler(withIdentityReturn(func)); - } - - public GT_Recipe_Map setRecipeConfigFile(String category, Function<? super GT_Recipe, String> keyConvertor) { - if (StringUtils.isBlank(category) || keyConvertor == null) throw new IllegalArgumentException(); - this.recipeConfigCategory = category; - this.recipeConfigKeyConvertor = keyConvertor; - return this; - } - - @Override - public void addDownstream(IGT_RecipeMap downstream) { - this.downstreams.add(downstream); - } - - public GT_Recipe addRecipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecial, - int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue) { - return addRecipe( - new GT_Recipe( - aOptimize, - aInputs, - aOutputs, - aSpecial, - aOutputChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue)); - } - - public GT_Recipe addRecipe(int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, - int aDuration, int aEUt, int aSpecialValue) { - return addRecipe( - new GT_Recipe( - false, - null, - null, - null, - aOutputChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue), - false, - false, - false); - } - - public GT_Recipe addRecipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecial, - FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { - return addRecipe( - new GT_Recipe( - aOptimize, - aInputs, - aOutputs, - aSpecial, - null, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue)); - } - - public GT_Recipe addRecipe(GT_Recipe aRecipe) { - return addRecipe(aRecipe, true, false, false); - } - - protected GT_Recipe addRecipe(GT_Recipe aRecipe, boolean aCheckForCollisions, boolean aFakeRecipe, - boolean aHidden) { - aRecipe.mHidden = aHidden; - aRecipe.mFakeRecipe = aFakeRecipe; - if (aRecipe.mFluidInputs.length < mMinimalInputFluids && aRecipe.mInputs.length < mMinimalInputItems) - return null; - if (aCheckForCollisions - && findRecipe(null, false, true, Long.MAX_VALUE, aRecipe.mFluidInputs, aRecipe.mInputs) != null) - return null; - return add(aRecipe); - } - - /** - * Only used for fake Recipe Handlers to show something in NEI, do not use this for adding actual Recipes! - * findRecipe wont find fake Recipes, containsInput WILL find fake Recipes - */ - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, - int aEUt, int aSpecialValue) { - return addFakeRecipe( - aCheckForCollisions, - new GT_Recipe( - false, - aInputs, - aOutputs, - aSpecial, - aOutputChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue)); - } - - /** - * Only used for fake Recipe Handlers to show something in NEI, do not use this for adding actual Recipes! - * findRecipe wont find fake Recipes, containsInput WILL find fake Recipes - */ - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue) { - return addFakeRecipe( - aCheckForCollisions, - new GT_Recipe( - false, - aInputs, - aOutputs, - aSpecial, - null, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue)); - } - - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue, boolean hidden) { - return addFakeRecipe( - aCheckForCollisions, - new GT_Recipe( - false, - aInputs, - aOutputs, - aSpecial, - null, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue), - hidden); - } - - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue, ItemStack[][] aAlt, boolean hidden) { - return addFakeRecipe( - aCheckForCollisions, - new GT_Recipe_WithAlt( - false, - aInputs, - aOutputs, - aSpecial, - null, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue, - aAlt), - hidden); - } - - /** - * Only used for fake Recipe Handlers to show something in NEI, do not use this for adding actual Recipes! - * findRecipe wont find fake Recipes, containsInput WILL find fake Recipes - */ - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, GT_Recipe aRecipe) { - return addRecipe(aRecipe, aCheckForCollisions, true, false); - } - - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, GT_Recipe aRecipe, boolean hidden) { - return addRecipe(aRecipe, aCheckForCollisions, true, hidden); - } - - @Nonnull - @Override - public Collection<GT_Recipe> doAdd(GT_RecipeBuilder builder) { - Iterable<? extends GT_Recipe> recipes = recipeEmitter.apply(builder); - Collection<GT_Recipe> ret = new ArrayList<>(); - for (GT_Recipe r : recipes) { - if (recipeConfigCategory != null) { - String configKey = recipeConfigKeyConvertor.apply(r); - if (configKey != null - && (r.mDuration = GregTech_API.sRecipeFile.get(recipeConfigCategory, configKey, r.mDuration)) - <= 0) { - continue; - } - } - if (r.mFluidInputs.length < mMinimalInputFluids && r.mInputs.length < mMinimalInputItems) return null; - if (r.mSpecialValue == 0) { - // new style cleanroom/lowgrav handling - int specialValue = 0; - if (builder.getMetadata(GT_RecipeConstants.LOW_GRAVITY, false)) specialValue -= 100; - if (builder.getMetadata(GT_RecipeConstants.CLEANROOM, false)) specialValue -= 200; - for (GT_RecipeBuilder.MetadataIdentifier<Integer> ident : SPECIAL_VALUE_ALIASES) { - Integer metadata = builder.getMetadata(ident, null); - if (metadata != null) { - specialValue = metadata; - break; - } - } - r.mSpecialValue = specialValue; - } - if (specialHandler != null) r = specialHandler.apply(r); - if (r == null) continue; - if (checkForCollision - && findRecipe(null, false, true, Long.MAX_VALUE, r.mFluidInputs, r.mInputs) != null) { - StringBuilder errorInfo = new StringBuilder(); - boolean hasAnEntry = false; - for (FluidStack fStack : r.mFluidInputs) { - if (fStack == null) { - continue; - } - String s = fStack.getLocalizedName(); - if (s == null) { - continue; - } - if (hasAnEntry) { - errorInfo.append("+") - .append(s); - } else { - errorInfo.append(s); - } - hasAnEntry = true; - } - for (ItemStack iStack : r.mInputs) { - if (iStack == null) { - continue; - } - String s = iStack.getDisplayName(); - if (hasAnEntry) { - errorInfo.append("+") - .append(s); - } else { - errorInfo.append(s); - } - hasAnEntry = true; - } - handleRecipeCollision(errorInfo.toString()); - continue; - } - ret.add(add(r)); - } - if (!ret.isEmpty()) { - builder.clearInvalid(); - for (IGT_RecipeMap downstream : downstreams) { - downstream.doAdd(builder); - } - } - return ret; - } - - public final Iterable<? extends GT_Recipe> defaultBuildRecipe(GT_RecipeBuilder builder) { - // TODO sensible validation - GT_RecipeBuilder b = builder; - if (disableOptimize && builder.optimize) { - b = copy(builder, b).noOptimize(); - } - return buildOrEmpty(b); - } - - private static GT_RecipeBuilder copy(GT_RecipeBuilder original, GT_RecipeBuilder b) { - return b == original ? b.copy() : b; - } - - public GT_Recipe add(GT_Recipe aRecipe) { - mRecipeList.add(aRecipe); - for (FluidStack aFluid : aRecipe.mFluidInputs) { - if (aFluid != null) { - Collection<GT_Recipe> tList = mRecipeFluidMap.computeIfAbsent( - aFluid.getFluid() - .getName(), - k -> new HashSet<>(1)); - tList.add(aRecipe); - mRecipeFluidNameMap.add( - aFluid.getFluid() - .getName()); - } - } - if (aRecipe.mFluidOutputs.length != 0) { - this.mHasFluidOutputs = true; - } - if (aRecipe.mSpecialItems != null) { - this.mUsesSpecialSlot = true; - } - return addToItemMap(aRecipe); - } - - public void reInit() { - mRecipeItemMap.clear(); - for (GT_Recipe tRecipe : mRecipeList) { - GT_OreDictUnificator.setStackArray(true, tRecipe.mInputs); - GT_OreDictUnificator.setStackArray(true, tRecipe.mOutputs); - addToItemMap(tRecipe); - } - } - - /** - * @return if this Item is a valid Input for any for the Recipes - */ - public boolean containsInput(ItemStack aStack) { - return aStack != null && (mRecipeItemMap.containsKey(new GT_ItemStack(aStack)) - || mRecipeItemMap.containsKey(new GT_ItemStack(aStack, true))); - } - - /** - * @return if this Fluid is a valid Input for any for the Recipes - */ - public boolean containsInput(FluidStack aFluid) { - return aFluid != null && containsInput(aFluid.getFluid()); - } - - /** - * @return if this Fluid is a valid Input for any for the Recipes - */ - public boolean containsInput(Fluid aFluid) { - return aFluid != null && mRecipeFluidNameMap.contains(aFluid.getName()); - } - - @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); - } - - @Nullable - public final GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated, - boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) { - return findRecipe( - aTileEntity, - null, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - null, - 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); - } - - @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, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - null, - 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 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 - * @param aDontCheckStackSizes if set to false will only return recipes that can be executed at least once with - * the provided input - * @param aVoltage Voltage of the Machine or Long.MAX_VALUE if it has no Voltage - * @param aFluids the Fluid Inputs - * @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 Result of the recipe search - */ - @Nonnull - public final FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, boolean aNotUnificated, - boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, - ItemStack... aInputs) { - return findRecipeWithResult( - aRecipe, - recipe -> aVoltage * mAmperage >= recipe.mEUt, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - aInputs); - } - - /** - * finds a Recipe matching the aFluid and ItemStack Inputs. - * - * @param aRecipe in case this is != null it will try to use this Recipe first when looking things - * up. - * @param aIsValidRecipe predicate to help identify, if the recipe matches our machine - * @param aNotUnificated if this is T the Recipe searcher will unificate the ItemStack Inputs - * @param aDontCheckStackSizes if set to false will only return recipes that can be executed at least once with - * the provided input - * @param aVoltage Voltage of the Machine or Long.MAX_VALUE if it has no Voltage - * @param aFluids the Fluid Inputs - * @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 Result of the recipe search - */ - @Nonnull - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, - ItemStack aSpecialSlot, ItemStack... aInputs) { - // No Recipes? Well, nothing to be found then. - 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. - // This improves Performance massively, especially if people leave things like Circuits, Molds or Shapes in - // their Machines to select Sub Recipes. - if (GregTech_API.sPostloadFinished) { - if (mMinimalInputFluids > 0) { - if (aFluids == null) return NOT_FOUND; - int tAmount = 0; - for (FluidStack aFluid : aFluids) if (aFluid != null) tAmount++; - if (tAmount < mMinimalInputFluids) return NOT_FOUND; - } - if (mMinimalInputItems > 0) { - if (aInputs == null) return NOT_FOUND; - int tAmount = 0; - for (ItemStack aInput : aInputs) if (aInput != null) tAmount++; - if (tAmount < mMinimalInputItems) return NOT_FOUND; - } - } - - // Unification happens here in case the Input isn't already unificated. - if (aNotUnificated) aInputs = GT_OreDictUnificator.getStackArray(true, (Object[]) aInputs); - - // 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)) { - if (!isSpecialSlotSensitive - || GT_Utility.areStacksEqualOrNull((ItemStack) aRecipe.mSpecialItems, aSpecialSlot)) { - if (aRecipe.mEnabled && aIsValidRecipe.test(aRecipe)) { - return ofSuccess(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)) { - if (!isSpecialSlotSensitive - || GT_Utility.areStacksEqualOrNull((ItemStack) tRecipe.mSpecialItems, aSpecialSlot)) { - if (tRecipe.mEnabled && aIsValidRecipe.test(tRecipe)) { - return ofSuccess(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)) { - if (!isSpecialSlotSensitive - || GT_Utility.areStacksEqualOrNull((ItemStack) tRecipe.mSpecialItems, aSpecialSlot)) { - if (tRecipe.mEnabled && aIsValidRecipe.test(tRecipe)) { - return ofSuccess(tRecipe); - } - } - } - } - - // If the minimal Amount of Items for the Recipe is 0, then it could be a Fluid-Only Recipe, so check that - // Map too. - if (mMinimalInputItems == 0 && aFluids != null) for (FluidStack aFluid : aFluids) if (aFluid != null) { - Collection<GT_Recipe> tRecipes = mRecipeFluidMap.get( - aFluid.getFluid() - .getName()); - if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe - && tRecipe.isRecipeInputEqual(false, aDontCheckStackSizes, aFluids, aInputs)) { - if (!isSpecialSlotSensitive - || GT_Utility.areStacksEqualOrNull((ItemStack) tRecipe.mSpecialItems, aSpecialSlot)) { - if (tRecipe.mEnabled && aIsValidRecipe.test(tRecipe)) { - return ofSuccess(tRecipe); - } - } - } - } - - // And nothing has been found. - return NOT_FOUND; - } - - protected GT_Recipe addToItemMap(GT_Recipe aRecipe) { - for (ItemStack aStack : aRecipe.mInputs) if (aStack != null) { - GT_ItemStack tStack = new GT_ItemStack(aStack); - Collection<GT_Recipe> tList = mRecipeItemMap.computeIfAbsent(tStack, k -> new HashSet<>(1)); - tList.add(aRecipe); - } - return aRecipe; - } - - /** - * Whether this recipe map contains any fluid outputs. - */ - public boolean hasFluidOutputs() { - return mHasFluidOutputs; - } - - /** - * Whether this recipe map contains any fluid inputs. - */ - public boolean hasFluidInputs() { - return mRecipeFluidNameMap.size() != 0; - } - - /** - * Whether this recipe map contains special slot inputs. - */ - public boolean usesSpecialSlot() { - return mUsesSpecialSlot; - } - - public int getUsualFluidInputCount() { - return Math.max(usualFluidInputCount, hasFluidInputs() ? 1 : 0); - } - - public int getUsualFluidOutputCount() { - return Math.max(usualFluidOutputCount, hasFluidOutputs() ? 1 : 0); - } - - @Nullable - public IDrawable getOverlayForSlot(boolean isFluid, boolean isOutput, int index, boolean isSpecial) { - byte overlayKey = (byte) ((isFluid ? 1 : 0) + (isOutput ? 2 : 0) - + (index == 0 ? 4 : 0) - + (isSpecial ? 8 : 0)); - if (slotOverlays.containsKey(overlayKey)) { - return slotOverlays.get(overlayKey); - } - return null; - } - - @Nullable - public SteamTexture getOverlayForSlotSteam(boolean isFluid, boolean isOutput, int index, boolean isSpecial) { - byte overlayKey = (byte) ((isFluid ? 1 : 0) + (isOutput ? 2 : 0) - + (index == 0 ? 4 : 0) - + (isSpecial ? 8 : 0)); - if (slotOverlaysSteam.containsKey(overlayKey)) { - return slotOverlaysSteam.get(overlayKey); - } - return null; - } - - @Nullable - public SteamTexture getOverlayForSlotSteam(boolean isOutput, boolean isFirst) { - byte overlayKey = (byte) ((isOutput ? 2 : 0) + (isFirst ? 4 : 0)); - if (slotOverlaysSteam.containsKey(overlayKey)) { - return slotOverlaysSteam.get(overlayKey); - } - return null; - } - - public UITexture getProgressBarTexture() { - return progressBarTexture.get(); - } - - public FallbackableUITexture getProgressBarTextureRaw() { - return progressBarTexture; - } - - public UITexture getProgressBarTextureSteam(SteamVariant steamVariant) { - return progressBarTextureSteam.get(steamVariant); - } - - public int getProgressBarImageSize() { - if (progressBarImageSize != 0) { - return progressBarImageSize; - } - return switch (progressBarDirection) { - case UP, DOWN -> progressBarSize.height; - case CIRCULAR_CW -> Math.max(progressBarSize.width, progressBarSize.height); - default -> progressBarSize.width; - }; - } - - /** - * Adds slot backgrounds, progressBar, etc. - */ - public ModularWindow.Builder createNEITemplate(IItemHandlerModifiable itemInputsInventory, - IItemHandlerModifiable itemOutputsInventory, IItemHandlerModifiable specialSlotInventory, - IItemHandlerModifiable fluidInputsInventory, IItemHandlerModifiable fluidOutputsInventory, - Supplier<Float> progressSupplier, Pos2d windowOffset) { - ModularWindow.Builder builder = ModularWindow.builder(neiBackgroundSize) - .setBackground(ModularUITextures.VANILLA_BACKGROUND); - - UIHelper.forEachSlots( - (i, backgrounds, pos) -> builder.widget( - SlotWidget.phantom(itemInputsInventory, i) - .setBackground(backgrounds) - .setPos(pos) - .setSize(18, 18)), - (i, backgrounds, pos) -> builder.widget( - SlotWidget.phantom(itemOutputsInventory, i) - .setBackground(backgrounds) - .setPos(pos) - .setSize(18, 18)), - (i, backgrounds, pos) -> { - if (usesSpecialSlot()) builder.widget( - SlotWidget.phantom(specialSlotInventory, 0) - .setBackground(backgrounds) - .setPos(pos) - .setSize(18, 18)); - }, - (i, backgrounds, pos) -> builder.widget( - SlotWidget.phantom(fluidInputsInventory, i) - .setBackground(backgrounds) - .setPos(pos) - .setSize(18, 18)), - (i, backgrounds, pos) -> builder.widget( - SlotWidget.phantom(fluidOutputsInventory, i) - .setBackground(backgrounds) - .setPos(pos) - .setSize(18, 18)), - ModularUITextures.ITEM_SLOT, - ModularUITextures.FLUID_SLOT, - this, - mUsualInputCount, - mUsualOutputCount, - getUsualFluidInputCount(), - getUsualFluidOutputCount(), - SteamVariant.NONE, - windowOffset); - - addProgressBarUI(builder, progressSupplier, windowOffset); - addGregTechLogoUI(builder, windowOffset); - - for (Pair<IDrawable, Pair<Size, Pos2d>> specialTexture : specialTextures) { - builder.widget( - new DrawableWidget().setDrawable(specialTexture.getLeft()) - .setSize( - specialTexture.getRight() - .getLeft()) - .setPos( - specialTexture.getRight() - .getRight() - .add(windowOffset))); - } - - return builder; - } - - public void addProgressBarUI(ModularWindow.Builder builder, Supplier<Float> progressSupplier, - Pos2d windowOffset) { - builder.widget( - new ProgressBar().setTexture(getProgressBarTexture(), 20) - .setDirection(progressBarDirection) - .setProgress(progressSupplier) - .setSynced(false, false) - .setPos(progressBarPos.add(windowOffset)) - .setSize(progressBarSize)); - } - - public void addGregTechLogoUI(ModularWindow.Builder builder, Pos2d windowOffset) { - builder.widget( - new DrawableWidget().setDrawable(logo) - .setSize(logoSize) - .setPos(logoPos.add(windowOffset))); - } - - public void addRecipeSpecificDrawable(ModularWindow.Builder builder, Pos2d windowOffset, - Supplier<IDrawable> supplier, Pos2d pos, Size size) { - builder.widget( - new DrawableWidget().setDrawable(supplier) - .setSize(size) - .setPos(pos.add(windowOffset))); - } - - /** - * Overriding this method allows custom NEI stack placement - */ - public List<Pos2d> getItemInputPositions(int itemInputCount) { - return UIHelper.getItemInputPositions(itemInputCount); - } - - /** - * Overriding this method allows custom NEI stack placement - */ - public List<Pos2d> getItemOutputPositions(int itemOutputCount) { - return UIHelper.getItemOutputPositions(itemOutputCount); - } - - /** - * Overriding this method allows custom NEI stack placement - */ - public Pos2d getSpecialItemPosition() { - return UIHelper.getSpecialItemPosition(); - } - - /** - * Overriding this method allows custom NEI stack placement - */ - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getFluidInputPositions(fluidInputCount); - } - - /** - * Overriding this method allows custom NEI stack placement - */ - public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { - return UIHelper.getFluidOutputPositions(fluidOutputCount); - } - - public void drawNEIDescription(NEIRecipeInfo recipeInfo) { - drawNEIEnergyInfo(recipeInfo); - drawNEIDurationInfo(recipeInfo); - drawNEISpecialInfo(recipeInfo); - drawNEIRecipeOwnerInfo(recipeInfo); - } - - protected void drawNEIEnergyInfo(NEIRecipeInfo recipeInfo) { - GT_Recipe recipe = recipeInfo.recipe; - Power power = recipeInfo.power; - if (power.getEuPerTick() > 0) { - drawNEIText(recipeInfo, GT_Utility.trans("152", "Total: ") + power.getTotalPowerString()); - - String amperage = power.getAmperageString(); - String powerUsage = power.getPowerUsageString(); - if (amperage == null || amperage.equals("unspecified") || powerUsage.contains("(OC)")) { - drawNEIText(recipeInfo, GT_Utility.trans("153", "Usage: ") + powerUsage); - if (GT_Mod.gregtechproxy.mNEIOriginalVoltage) { - Power originalPower = getPowerFromRecipeMap(); - if (!(originalPower instanceof UnspecifiedEUPower)) { - originalPower.computePowerUsageAndDuration(recipe.mEUt, recipe.mDuration); - drawNEIText( - recipeInfo, - GT_Utility.trans("275", "Original voltage: ") + originalPower.getVoltageString()); - } - } - if (amperage != null && !amperage.equals("unspecified") && !amperage.equals("1")) { - drawNEIText(recipeInfo, GT_Utility.trans("155", "Amperage: ") + amperage); - } - } else if (amperage.equals("1")) { - drawNEIText(recipeInfo, GT_Utility.trans("154", "Voltage: ") + power.getVoltageString()); - } else { - drawNEIText(recipeInfo, GT_Utility.trans("153", "Usage: ") + powerUsage); - drawNEIText(recipeInfo, GT_Utility.trans("154", "Voltage: ") + power.getVoltageString()); - drawNEIText(recipeInfo, GT_Utility.trans("155", "Amperage: ") + amperage); - } - } - } - - protected void drawNEIDurationInfo(NEIRecipeInfo recipeInfo) { - Power power = recipeInfo.power; - if (power.getDurationTicks() > 0) { - String textToDraw = GT_Utility.trans("158", "Time: "); - if (GT_Mod.gregtechproxy.mNEIRecipeSecondMode) { - textToDraw += power.getDurationStringSeconds(); - if (power.getDurationSeconds() <= 1.0d) { - textToDraw += String.format(" (%s)", power.getDurationStringTicks()); - } - } else { - textToDraw += power.getDurationStringTicks(); - } - drawNEIText(recipeInfo, textToDraw); - } - } - - protected void drawNEISpecialInfo(NEIRecipeInfo recipeInfo) { - String[] recipeDesc = recipeInfo.recipe.getNeiDesc(); - if (recipeDesc != null) { - for (String s : recipeDesc) { - drawOptionalNEIText(recipeInfo, s); - } - } else if (neiSpecialInfoFormatter != null) { - drawNEITextMultipleLines( - recipeInfo, - neiSpecialInfoFormatter.format(recipeInfo, this::formatSpecialValue)); - } else { - drawOptionalNEIText(recipeInfo, getNEISpecialInfo(recipeInfo.recipe.mSpecialValue)); - } - } - - protected String getNEISpecialInfo(int specialValue) { - if (specialValue == -100 && GT_Mod.gregtechproxy.mLowGravProcessing) { - return GT_Utility.trans("159", "Needs Low Gravity"); - } else if (specialValue == -200 && GT_Mod.gregtechproxy.mEnableCleanroom) { - return GT_Utility.trans("160", "Needs Cleanroom"); - } else if (specialValue == -201) { - return GT_Utility.trans("206", "Scan for Assembly Line"); - } else if (specialValue == -300 && GT_Mod.gregtechproxy.mEnableCleanroom) { - return GT_Utility.trans("160.1", "Needs Cleanroom & LowGrav"); - } else if (specialValue == -400) { - return GT_Utility.trans("216", "Deprecated Recipe"); - } else if (hasSpecialValueFormat()) { - return formatSpecialValue(specialValue); - } - return null; - } - - private boolean hasSpecialValueFormat() { - return (GT_Utility.isStringValid(mNEISpecialValuePre)) || (GT_Utility.isStringValid(mNEISpecialValuePost)); - } - - protected String formatSpecialValue(int specialValue) { - return mNEISpecialValuePre + formatNumbers((long) specialValue * mNEISpecialValueMultiplier) - + mNEISpecialValuePost; - } - - protected void drawNEIRecipeOwnerInfo(NEIRecipeInfo recipeInfo) { - GT_Recipe recipe = recipeInfo.recipe; - if (GT_Mod.gregtechproxy.mNEIRecipeOwner) { - if (recipe.owners.size() > 1) { - drawNEIText( - recipeInfo, - EnumChatFormatting.ITALIC + GT_Utility.trans("273", "Original Recipe by: ") - + recipe.owners.get(0) - .getName()); - for (int i = 1; i < recipe.owners.size(); i++) { - drawNEIText( - recipeInfo, - EnumChatFormatting.ITALIC + GT_Utility.trans("274", "Modified by: ") - + recipe.owners.get(i) - .getName()); - } - } else if (recipe.owners.size() > 0) { - drawNEIText( - recipeInfo, - EnumChatFormatting.ITALIC + GT_Utility.trans("272", "Recipe by: ") - + recipe.owners.get(0) - .getName()); - } - } - if (GT_Mod.gregtechproxy.mNEIRecipeOwnerStackTrace && recipe.stackTraces != null - && !recipe.stackTraces.isEmpty()) { - drawNEIText(recipeInfo, "stackTrace:"); - // todo: good way to show all stacktraces - for (StackTraceElement stackTrace : recipe.stackTraces.get(0)) { - drawNEIText(recipeInfo, stackTrace.toString()); - } - } - } - - protected void drawNEIText(NEIRecipeInfo recipeInfo, String text) { - drawNEIText(recipeInfo, text, 10); - } - - /** - * Draws text on NEI recipe. - * - * @param yShift y position to shift after this text - */ - @SuppressWarnings("SameParameterValue") - protected void drawNEIText(NEIRecipeInfo recipeInfo, String text, int yShift) { - drawNEIText(recipeInfo, text, 10, yShift); - } - - /** - * Draws text on NEI recipe. - * - * @param xStart x position to start drawing - * @param yShift y position to shift after this text - */ - @SuppressWarnings("SameParameterValue") - protected void drawNEIText(NEIRecipeInfo recipeInfo, String text, int xStart, int yShift) { - Minecraft.getMinecraft().fontRenderer.drawString( - text, - xStart, - recipeInfo.yPos, - neiTextColorOverride != -1 ? neiTextColorOverride : 0x000000); - recipeInfo.yPos += yShift; - } - - protected void drawOptionalNEIText(NEIRecipeInfo recipeInfo, String text) { - if (GT_Utility.isStringValid(text) && !text.equals("unspecified")) { - drawNEIText(recipeInfo, text, 10); - } - } - - protected void drawNEITextMultipleLines(NEIRecipeInfo recipeInfo, List<String> texts) { - for (String text : texts) { - drawNEIText(recipeInfo, text, 10); - } - } - - public List<String> handleNEIItemTooltip(ItemStack stack, List<String> currentTip, - GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { - for (PositionedStack pStack : neiCachedRecipe.mInputs) { - if (stack == pStack.item) { - if (pStack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { - currentTip = handleNEIItemInputTooltip( - currentTip, - (GT_NEI_DefaultHandler.FixedPositionedStack) pStack); - } - break; - } - } - for (PositionedStack pStack : neiCachedRecipe.mOutputs) { - if (stack == pStack.item) { - if (pStack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { - currentTip = handleNEIItemOutputTooltip( - currentTip, - (GT_NEI_DefaultHandler.FixedPositionedStack) pStack); - } - break; - } - } - return currentTip; - } - - protected List<String> handleNEIItemInputTooltip(List<String> currentTip, - GT_NEI_DefaultHandler.FixedPositionedStack pStack) { - if (pStack.isNotConsumed()) { - currentTip.add(GRAY + GT_Utility.trans("151", "Does not get consumed in the process")); - } - return currentTip; - } - - protected List<String> handleNEIItemOutputTooltip(List<String> currentTip, - GT_NEI_DefaultHandler.FixedPositionedStack pStack) { - if (pStack.isChanceBased()) { - currentTip.add(GRAY + GT_Utility.trans("150", "Chance: ") + pStack.getChanceText()); - } - return currentTip; - } - - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { - for (PositionedStack stack : neiCachedRecipe.mInputs) { - if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { - drawNEIOverlayForInput((GT_NEI_DefaultHandler.FixedPositionedStack) stack); - } - } - for (PositionedStack stack : neiCachedRecipe.mOutputs) { - if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { - drawNEIOverlayForOutput((GT_NEI_DefaultHandler.FixedPositionedStack) stack); - } - } - } - - protected void drawNEIOverlayForInput(GT_NEI_DefaultHandler.FixedPositionedStack stack) { - if (stack.isNotConsumed()) { - drawNEIOverlayText("NC", stack); - } - } - - protected void drawNEIOverlayForOutput(GT_NEI_DefaultHandler.FixedPositionedStack stack) { - if (stack.isChanceBased()) { - drawNEIOverlayText(stack.getChanceText(), stack); - } - } - - @SuppressWarnings("SameParameterValue") - protected void drawNEIOverlayText(String text, PositionedStack stack, int color, float scale, boolean shadow, - Alignment alignment) { - FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; - int width = fontRenderer.getStringWidth(text); - int x = (int) ((stack.relx + 8 + 8 * alignment.x) / scale) - (width / 2 * (alignment.x + 1)); - int y = (int) ((stack.rely + 8 + 8 * alignment.y) / scale) - - (fontRenderer.FONT_HEIGHT / 2 * (alignment.y + 1)) - - (alignment.y - 1) / 2; - - GlStateManager.pushMatrix(); - GlStateManager.scale(scale, scale, 1); - fontRenderer.drawString(text, x, y, color, shadow); - GlStateManager.popMatrix(); - } - - protected void drawNEIOverlayText(String text, PositionedStack stack) { - drawNEIOverlayText( - text, - stack, - colorOverride.getTextColorOrDefault("nei_overlay_yellow", 0xFDD835), - 0.5f, - false, - Alignment.TopLeft); - } - - public void updateNEITextColorOverride() { - neiTextColorOverride = colorOverride.getTextColorOrDefault("nei", -1); - } - - public Power getPowerFromRecipeMap() { - // By default, assume generic EU LV power with no overclocks - Power power; - if (mShowVoltageAmperageInNEI) { - power = new EUPower((byte) 1, mAmperage); - } else { - power = new UnspecifiedEUPower((byte) 1, mAmperage); - } - return power; - } - - /** - * Use {@link #getItemInputPositions} or {@link #getSpecialItemPosition} or {@link #getFluidInputPositions} - * instead - */ - @Deprecated - public ArrayList<PositionedStack> getInputPositionedStacks(GT_Recipe recipe) { - return null; - } - - /** - * Use {@link #getItemOutputPositions} or {@link #getFluidOutputPositions} instead - */ - @Deprecated - public ArrayList<PositionedStack> getOutputPositionedStacks(GT_Recipe recipe) { - return null; - } - - public void addRecipe(Object o, FluidStack[] fluidInputArray, FluidStack[] fluidOutputArray) {} - } - - // ----------------------------------------------------------------------------------------------------------------- - // Here are a few Classes I use for Special Cases in some Machines without having to write a separate Machine Class. - // ----------------------------------------------------------------------------------------------------------------- - - /** - * Nicely display NEI with many items and fluids. Remember to call {@link GT_Recipe_Map#setUsualFluidInputCount} and - * {@link GT_Recipe_Map#setUsualFluidOutputCount}. If row count >= 6, it doesn't fit in 2 recipes per page, so - * change it via IMC. - */ - public static class GT_Recipe_Map_LargeNEI extends GT_Recipe_Map { - - private static final int xDirMaxCount = 3; - private static final int yOrigin = 8; - - public GT_Recipe_Map_LargeNEI(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); - useModularUI(true); - setLogoPos(80, 62); - } - - @Override - public List<Pos2d> getItemInputPositions(int itemInputCount) { - return UIHelper.getGridPositions(itemInputCount, 16, yOrigin, xDirMaxCount); - } - - @Override - public List<Pos2d> getItemOutputPositions(int itemOutputCount) { - return UIHelper.getGridPositions(itemOutputCount, 106, yOrigin, xDirMaxCount); - } - - @Override - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getGridPositions(fluidInputCount, 16, yOrigin + getItemRowCount() * 18, xDirMaxCount); - } - - @Override - public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { - return UIHelper.getGridPositions(fluidOutputCount, 106, yOrigin + getItemRowCount() * 18, xDirMaxCount); - } - - @Override - public ModularWindow.Builder createNEITemplate(IItemHandlerModifiable itemInputsInventory, - IItemHandlerModifiable itemOutputsInventory, IItemHandlerModifiable specialSlotInventory, - IItemHandlerModifiable fluidInputsInventory, IItemHandlerModifiable fluidOutputsInventory, - Supplier<Float> progressSupplier, Pos2d windowOffset) { - // Delay setter so that calls to #setUsualFluidInputCount and #setUsualFluidOutputCount are considered - setNEIBackgroundSize(172, 82 + (Math.max(getItemRowCount() + getFluidRowCount() - 4, 0)) * 18); - return super.createNEITemplate( - itemInputsInventory, - itemOutputsInventory, - specialSlotInventory, - fluidInputsInventory, - fluidOutputsInventory, - progressSupplier, - windowOffset); - } - - private int getItemRowCount() { - return (Math.max(mUsualInputCount, mUsualOutputCount) - 1) / xDirMaxCount + 1; - } - - private int getFluidRowCount() { - return (Math.max(getUsualFluidInputCount(), getUsualFluidOutputCount()) - 1) / xDirMaxCount + 1; - } - } - - /** - * Display fluids where normally items are placed on NEI. - */ - public static class GT_Recipe_Map_FluidOnly extends GT_Recipe_Map { - - public GT_Recipe_Map_FluidOnly(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); - useModularUI(true); - } - - @Override - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getItemInputPositions(fluidInputCount); - } - - @Override - public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { - return UIHelper.getItemOutputPositions(fluidOutputCount); - } - } - - /** - * Abstract Class for general Recipe Handling of non GT Recipes - */ - public abstract static class GT_Recipe_Map_NonGTRecipes extends GT_Recipe_Map { - - public GT_Recipe_Map_NonGTRecipes(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 boolean containsInput(ItemStack aStack) { - return false; - } - - @Override - public boolean containsInput(FluidStack aFluid) { - return false; - } - - @Override - public boolean containsInput(Fluid aFluid) { - return false; - } - - @Override - public GT_Recipe addRecipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecial, - int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue) { - return null; - } - - @Override - public GT_Recipe addRecipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecial, - FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { - return null; - } - - @Override - public GT_Recipe addRecipe(GT_Recipe aRecipe) { - return null; - } - - @Override - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, - int aEUt, int aSpecialValue) { - return null; - } - - @Override - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue) { - return null; - } - - @Override - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue, boolean hidden) { - return null; - } - - @Override - public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, GT_Recipe aRecipe) { - return null; - } - - @Override - public GT_Recipe add(GT_Recipe aRecipe) { - return null; - } - - @Override - public void reInit() { - /**/ - } - - @Override - protected GT_Recipe addToItemMap(GT_Recipe aRecipe) { - return null; - } - } - - /** - * Just a Recipe Map with Utility specifically for Fuels. - */ - public static class GT_Recipe_Map_Fuel extends GT_Recipe_Map { - - private final Map<String, GT_Recipe> mRecipesByFluidInput = new HashMap<>(); - - public GT_Recipe_Map_Fuel(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); - setDisableOptimize(true); - } - - public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, int aFuelValueInEU) { - return addFuel(aInput, aOutput, null, null, 10000, aFuelValueInEU); - } - - public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, int aChance, int aFuelValueInEU) { - return addFuel(aInput, aOutput, null, null, aChance, aFuelValueInEU); - } - - public GT_Recipe addFuel(FluidStack aFluidInput, FluidStack aFluidOutput, int aFuelValueInEU) { - return addFuel(null, null, aFluidInput, aFluidOutput, 10000, aFuelValueInEU); - } - - public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput, - int aFuelValueInEU) { - return addFuel(aInput, aOutput, aFluidInput, aFluidOutput, 10000, aFuelValueInEU); - } - - public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput, - int aChance, int aFuelValueInEU) { - return addRecipe( - true, - new ItemStack[] { aInput }, - new ItemStack[] { aOutput }, - null, - new int[] { aChance }, - new FluidStack[] { aFluidInput }, - new FluidStack[] { aFluidOutput }, - 0, - 0, - aFuelValueInEU); - } - - @Override - public GT_Recipe add(GT_Recipe aRecipe) { - aRecipe = super.add(aRecipe); - if (aRecipe.mInputs != null && GT_Utility.getNonnullElementCount(aRecipe.mInputs) == 1 - && (aRecipe.mFluidInputs == null || GT_Utility.getNonnullElementCount(aRecipe.mFluidInputs) == 0)) { - FluidStack tFluid = GT_Utility.getFluidForFilledItem(aRecipe.mInputs[0], true); - if (tFluid != null) { - tFluid.amount = 0; - mRecipesByFluidInput.put(tFluid.getUnlocalizedName(), aRecipe); - } - } else if ((aRecipe.mInputs == null || GT_Utility.getNonnullElementCount(aRecipe.mInputs) == 0) - && aRecipe.mFluidInputs != null - && GT_Utility.getNonnullElementCount(aRecipe.mFluidInputs) == 1 - && aRecipe.mFluidInputs[0] != null) { - mRecipesByFluidInput.put(aRecipe.mFluidInputs[0].getUnlocalizedName(), aRecipe); - } - return aRecipe; - } - - public GT_Recipe findFuel(FluidStack aFluidInput) { - return mRecipesByFluidInput.get(aFluidInput.getUnlocalizedName()); - } - } - - /** - * Special Class for Furnace Recipe handling. - */ - public static class GT_Recipe_Map_Furnace extends GT_Recipe_Map_NonGTRecipes { - - public GT_Recipe_Map_Furnace(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - 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 ? 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 - public boolean containsInput(ItemStack aStack) { - return GT_ModHandler.getSmeltingOutput(aStack, false, null) != null; - } - } - - /** - * Special Class for Microwave Recipe handling. - */ - public static class GT_Recipe_Map_Microwave extends GT_Recipe_Map_NonGTRecipes { - - public GT_Recipe_Map_Microwave(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - 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 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 - // Output and last check the Output itself - for (ItemStack tStack : new ItemStack[] { GT_Utility.getContainerItem(aInputs[0], true), aInputs[0], - GT_Utility.getContainerItem(tOutput, true), tOutput }) if (tStack != null) { - if (GT_Utility.areStacksEqual(tStack, new ItemStack(Blocks.netherrack, 1, W), true) - || GT_Utility.areStacksEqual(tStack, new ItemStack(Blocks.tnt, 1, W), true) - || GT_Utility.areStacksEqual(tStack, new ItemStack(Items.egg, 1, W), true) - || 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)) { - GT_Log.exp.println( - "Microwave Explosion due to TNT || EGG || FIREWORKCHARGE || FIREWORK || FIRE CHARGE"); - return EXPLODE; - } - ItemData tData = GT_OreDictUnificator.getItemData(tStack); - - if (tData != null) { - if (tData.mMaterial != null && tData.mMaterial.mMaterial != null) { - if (tData.mMaterial.mMaterial.contains(SubTag.METAL) - || tData.mMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) { - GT_Log.exp.println("Microwave Explosion due to METAL insertion"); - return EXPLODE; - } - if (tData.mMaterial.mMaterial.contains(SubTag.FLAMMABLE)) { - 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)) { - GT_Log.exp.println("Microwave Explosion due to METAL insertion"); - return EXPLODE; - } - if (tMaterial.mMaterial.contains(SubTag.FLAMMABLE)) { - GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); - return ON_FIRE; - } - } - } - if (TileEntityFurnace.getItemBurnTime(tStack) > 0) { - GT_Log.exp.println("Microwave INFLAMMATION due to BURNABLE insertion"); - return ON_FIRE; - } - } - - 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 - public boolean containsInput(ItemStack aStack) { - return GT_ModHandler.getSmeltingOutput(aStack, false, null) != null; - } - } - - /** - * Special Class for Unboxinator handling. - */ - public static class GT_Recipe_Map_Unboxinator extends GT_Recipe_Map { - - public GT_Recipe_Map_Unboxinator(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - 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.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - aInputs); - ItemStack tOutput = GT_ModHandler.getRandomScrapboxDrop(); - if (tOutput == null) return super.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - aInputs); - GT_Recipe rRecipe = new GT_Recipe( - false, - new ItemStack[] { ItemList.IC2_Scrapbox.get(1) }, - new ItemStack[] { tOutput }, - null, - null, - null, - null, - 16, - 1, - 0); - // It is not allowed to be buffered due to the random Output - rRecipe.mCanBeBuffered = false; - // 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 FindRecipeResult.ofSuccess(rRecipe); - } - - @Override - public boolean containsInput(ItemStack aStack) { - return ItemList.IC2_Scrapbox.isStackEqual(aStack, false, true) || super.containsInput(aStack); - } - } - - /** - * Special Class for Fluid Canner handling. - */ - public static class GT_Recipe_Map_FluidCanner extends GT_Recipe_Map { - - public GT_Recipe_Map_FluidCanner(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, - ItemStack aSpecialSlot, ItemStack... aInputs) { - FindRecipeResult result = super.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - aInputs); - if (aInputs == null || aInputs.length == 0 - || aInputs[0] == null - || 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) { - 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); - } - } - 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) }, - null, - null, - null, - new FluidStack[] { tFluid }, - Math.max(tFluid.amount / 64, 16), - 1, - 0); - recipe.mCanBeBuffered = false; - return FindRecipeResult.ofSuccess(recipe); - } - return NOT_FOUND; - } - - @Override - public boolean containsInput(ItemStack aStack) { - return aStack != null && (super.containsInput(aStack) || (aStack.getItem() instanceof IFluidContainerItem - && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0)); - } - - @Override - public boolean containsInput(FluidStack aFluid) { - return true; - } - - @Override - public boolean containsInput(Fluid aFluid) { - return true; - } - } - - /** - * Special Class for Recycler Recipe handling. - */ - public static class GT_Recipe_Map_Recycler extends GT_Recipe_Map_NonGTRecipes { - - public GT_Recipe_Map_Recycler(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - 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(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 Macerator/RockCrusher Recipe handling. - */ - public static class GT_Recipe_Map_Macerator extends GT_Recipe_Map { - - public GT_Recipe_Map_Macerator(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - 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.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - aInputs); - FindRecipeResult result = super.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - 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) { - GT_Recipe recipe = new GT_Recipe( - false, - new ItemStack[] { GT_Utility.copyAmount(1, aInputs[0]) }, - tRecipeOutputs.toArray(new ItemStack[0]), - null, - null, - null, - null, - 800, - 2, - 0); - recipe.mCanBeBuffered = false; - recipe.mNeedsEmptyOutput = true; - return FindRecipeResult.ofSuccess(recipe); - } - } catch (NoClassDefFoundError e) { - if (D1) GT_Log.err.println("Railcraft Not loaded"); - } catch (NullPointerException e) { - /**/ - } - - ItemStack tComparedInput = GT_Utility.copyOrNull(aInputs[0]); - ItemStack[] tOutputItems = GT_ModHandler.getMachineOutput( - tComparedInput, - ic2.api.recipe.Recipes.macerator.getRecipes(), - true, - new NBTTagCompound(), - null, - null, - 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 - public boolean containsInput(ItemStack aStack) { - return super.containsInput(aStack) || GT_Utility.arrayContainsNonNull( - GT_ModHandler.getMachineOutput( - GT_Utility.copyAmount(64, aStack), - ic2.api.recipe.Recipes.macerator.getRecipes(), - false, - new NBTTagCompound(), - null, - null, - null)); - } - } - - /** - * Special Class for Assembler handling. - */ - public static class GT_Recipe_Map_Assembler extends GT_Recipe_Map { - - public GT_Recipe_Map_Assembler(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, - ItemStack aSpecialSlot, ItemStack... aInputs) { - - FindRecipeResult result = super.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - 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 : - * aInputs) { aInputs2.remove(aInput); int[] oredictIDs = OreDictionary.getOreIDs(aInput); if ( - * oredictIDs.length > 1){ for (final int i : oredictIDs){ final ItemStack[] oredictIS = (ItemStack[]) - * OreDictionary.getOres(OreDictionary.getOreName(i)).toArray(); if (oredictIS != null && oredictIS.length > - * 1){ for (final ItemStack IS : oredictIS){ aInputs2.add(IS); ItemStack[] temp = (ItemStack[]) - * aInputs2.toArray(); rRecipe = super.findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, - * aSpecialSlot,temp); if(rRecipe!= null){ break; } else { aInputs2.remove(IS); } } if(rRecipe!= null) - * break; } } if(rRecipe!= null) break; }else aInputs2.add(aInput); if(rRecipe!= null) break; } } - */ - if (aInputs == null || aInputs.length == 0 - || aInputs[0] == null - || !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(); - rRecipe.mCanBeBuffered = false; - rRecipe.mOutputs[0].setTagCompound(aInput.getTagCompound()); - } - } - return FindRecipeResult.ofSuccess(rRecipe); - } - } - - /** - * Special Class for Forming Press handling. - */ - public static class GT_Recipe_Map_FormingPress extends GT_Recipe_Map { - - public GT_Recipe_Map_FormingPress(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, - ItemStack aSpecialSlot, ItemStack... aInputs) { - FindRecipeResult result = super.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - 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(); - if (tNBT == null) tNBT = new NBTTagCompound(); - 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 FindRecipeResult.ofSuccess(rRecipe); - } - } - return result; - } - - private ItemStack findNameMoldIndex(ItemStack[] inputs) { - for (ItemStack stack : inputs) { - if (ItemList.Shape_Mold_Name.isStackEqual(stack, false, true)) return stack; - } - return null; - } - - private ItemStack findStackToRename(ItemStack[] inputs, ItemStack mold) { - for (ItemStack stack : inputs) { - if (stack == mold || stack == null) continue; - return stack; - } - return null; - } - - @Nonnull - private FindRecipeResult findRenamingRecipe(ItemStack[] inputs) { - ItemStack mold = findNameMoldIndex(inputs); - if (mold == null) return NOT_FOUND; - ItemStack input = findStackToRename(inputs, mold); - 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, - new ItemStack[] { GT_Utility.copyAmount(0, mold), GT_Utility.copyAmount(1, input) }, - new ItemStack[] { output }, - null, - null, - null, - null, - 128, - 8, - 0); - recipe.mCanBeBuffered = false; - recipe.isNBTSensitive = true; - return FindRecipeResult.ofSuccess(recipe); - } - } - - /** - * Special Class for Printer handling. - */ - public static class GT_Recipe_Map_Printer extends GT_Recipe_Map { - - public GT_Recipe_Map_Printer(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); - } - - @Nonnull - @Override - public FindRecipeResult findRecipeWithResult(GT_Recipe aRecipe, Predicate<GT_Recipe> aIsValidRecipe, - boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, FluidStack[] aFluids, - ItemStack aSpecialSlot, ItemStack... aInputs) { - FindRecipeResult result = super.findRecipeWithResult( - aRecipe, - aIsValidRecipe, - aNotUnificated, - aDontCheckStackSizes, - aVoltage, - aFluids, - aSpecialSlot, - aInputs); - if (aInputs == null || aInputs.length == 0 - || aInputs[0] == null - || aFluids == null - || aFluids.length == 0 - || aFluids[0] == null - || !GregTech_API.sPostloadFinished) return result; - - Dyes aDye = null; - for (Dyes tDye : Dyes.VALUES) if (tDye.isFluidDye(aFluids[0])) { - aDye = tDye; - break; - } - - if (aDye == null) return result; - - if (!result.isSuccessful()) { - ItemStack tOutput = GT_ModHandler.getAllRecipeOutput( - null, - aInputs[0], - aInputs[0], - aInputs[0], - aInputs[0], - ItemList.DYE_ONLY_ITEMS[aDye.mIndex].get(1), - aInputs[0], - aInputs[0], - aInputs[0], - aInputs[0]); - 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(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 NOT_FOUND; - NBTTagCompound tNBT = aSpecialSlot.getTagCompound(); - if (tNBT == null || GT_Utility.isStringInvalid(tNBT.getString("title")) - || GT_Utility.isStringInvalid(tNBT.getString("author"))) return NOT_FOUND; - - rRecipe = rRecipe.copy(); - rRecipe.mCanBeBuffered = false; - rRecipe.mOutputs[0].setTagCompound(tNBT); - return FindRecipeResult.ofSuccess(rRecipe); - } - if (aInputs[0].getItem() == Items.map) { - if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return NOT_FOUND; - NBTTagCompound tNBT = aSpecialSlot.getTagCompound(); - 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 FindRecipeResult.ofSuccess(rRecipe); - } - if (ItemList.Paper_Punch_Card_Empty.isStackEqual(aInputs[0], false, true)) { - if (!ItemList.Tool_DataStick.isStackEqual(aSpecialSlot, false, true)) return NOT_FOUND; - NBTTagCompound tNBT = aSpecialSlot.getTagCompound(); - if (tNBT == null || !tNBT.hasKey("GT.PunchCardData")) return NOT_FOUND; - - rRecipe = rRecipe.copy(); - rRecipe.mCanBeBuffered = false; - rRecipe.mOutputs[0].setTagCompound( - GT_Utility.getNBTContainingString( - new NBTTagCompound(), - "GT.PunchCardData", - tNBT.getString("GT.PunchCardData"))); - return FindRecipeResult.ofSuccess(rRecipe); - } - } - return result; - } - - @Override - public boolean containsInput(ItemStack aStack) { - return true; - } - - @Override - public boolean containsInput(FluidStack aFluid) { - return super.containsInput(aFluid) || Dyes.isAnyFluidDye(aFluid); - } - - @Override - public boolean containsInput(Fluid aFluid) { - return super.containsInput(aFluid) || Dyes.isAnyFluidDye(aFluid); - } - } - - public static class GT_Recipe_Map_LargeBoilerFakeFuels extends GT_Recipe_Map { - - private static final List<String> ALLOWED_SOLID_FUELS = Arrays.asList( - GregTech_API.sMachineFile.mConfig.getStringList( - "LargeBoiler.allowedFuels", - ConfigCategories.machineconfig.toString(), - new String[] { "gregtech:gt.blockreinforced:6", "gregtech:gt.blockreinforced:7" }, - "Allowed fuels for the Large Titanium Boiler and Large Tungstensteel Boiler")); - - public GT_Recipe_Map_LargeBoilerFakeFuels() { - super( - new HashSet<>(55), - "gt.recipe.largeboilerfakefuels", - "Large Boiler", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true); - GT_Recipe explanatoryRecipe = new GT_Recipe( - true, - new ItemStack[] {}, - new ItemStack[] {}, - null, - null, - null, - null, - 1, - 1, - 1); - explanatoryRecipe.setNeiDesc( - "Not all solid fuels are listed.", - "Any item that burns in a", - "vanilla furnace will burn in", - "a Large Bronze or Steel Boiler."); - addRecipe(explanatoryRecipe); - } - - public static boolean isAllowedSolidFuel(ItemStack stack) { - return isAllowedSolidFuel(Item.itemRegistry.getNameForObject(stack.getItem()), stack.getItemDamage()); - } - - public static boolean isAllowedSolidFuel(String itemRegistryName, int meta) { - return ALLOWED_SOLID_FUELS.contains(itemRegistryName + ":" + meta); - } - - public static boolean addAllowedSolidFuel(ItemStack stack) { - return addAllowedSolidFuel(Item.itemRegistry.getNameForObject(stack.getItem()), stack.getItemDamage()); - } - - public static boolean addAllowedSolidFuel(String itemregistryName, int meta) { - return ALLOWED_SOLID_FUELS.add(itemregistryName + ":" + meta); - } - - public GT_Recipe addDenseLiquidRecipe(GT_Recipe recipe) { - return addRecipe(recipe, ((double) recipe.mSpecialValue) / 10); - } - - public GT_Recipe addDieselRecipe(GT_Recipe recipe) { - return addRecipe(recipe, ((double) recipe.mSpecialValue) / 40); - } - - public void addSolidRecipes(ItemStack... itemStacks) { - for (ItemStack itemStack : itemStacks) { - addSolidRecipe(itemStack); - } - } - - public GT_Recipe addSolidRecipe(ItemStack fuelItemStack) { - boolean allowedFuel = false; - if (fuelItemStack != null) { - String registryName = Item.itemRegistry.getNameForObject(fuelItemStack.getItem()); - allowedFuel = ALLOWED_SOLID_FUELS.contains(registryName + ":" + fuelItemStack.getItemDamage()); - } - return addRecipe( - new GT_Recipe( - true, - new ItemStack[] { fuelItemStack }, - new ItemStack[] {}, - null, - null, - null, - null, - 1, - 0, - GT_ModHandler.getFuelValue(fuelItemStack) / 1600), - ((double) GT_ModHandler.getFuelValue(fuelItemStack)) / 1600, - allowedFuel); - } - - private GT_Recipe addRecipe(GT_Recipe recipe, double baseBurnTime, boolean isAllowedFuel) { - recipe = new GT_Recipe(recipe, true); - // Some recipes will have a burn time like 15.9999999 and % always rounds down - double floatErrorCorrection = 0.0001; - - double bronzeBurnTime = baseBurnTime * 2 + floatErrorCorrection; - bronzeBurnTime -= bronzeBurnTime % 0.05; - double steelBurnTime = baseBurnTime + floatErrorCorrection; - steelBurnTime -= steelBurnTime % 0.05; - double titaniumBurnTime = baseBurnTime * 0.3 + floatErrorCorrection; - titaniumBurnTime -= titaniumBurnTime % 0.05; - double tungstensteelBurnTime = baseBurnTime * 0.15 + floatErrorCorrection; - tungstensteelBurnTime -= tungstensteelBurnTime % 0.05; - - if (isAllowedFuel) { - recipe.setNeiDesc( - "Burn time in seconds:", - String.format("Bronze Boiler: %.4f", bronzeBurnTime), - String.format("Steel Boiler: %.4f", steelBurnTime), - String.format("Titanium Boiler: %.4f", titaniumBurnTime), - String.format("Tungstensteel Boiler: %.4f", tungstensteelBurnTime)); - } else { - recipe.setNeiDesc( - "Burn time in seconds:", - String.format("Bronze Boiler: %.4f", bronzeBurnTime), - String.format("Steel Boiler: %.4f", steelBurnTime), - "Titanium Boiler: Not allowed", - "Tungstenst. Boiler: Not allowed"); - } - - return super.addRecipe(recipe); - } - - private GT_Recipe addRecipe(GT_Recipe recipe, double baseBurnTime) { - recipe = new GT_Recipe(recipe, true); - // Some recipes will have a burn time like 15.9999999 and % always rounds down - double floatErrorCorrection = 0.0001; - - double bronzeBurnTime = baseBurnTime * 2 + floatErrorCorrection; - bronzeBurnTime -= bronzeBurnTime % 0.05; - double steelBurnTime = baseBurnTime + floatErrorCorrection; - steelBurnTime -= steelBurnTime % 0.05; - - recipe.setNeiDesc( - "Burn time in seconds:", - String.format("Bronze Boiler: %.4f", bronzeBurnTime), - String.format("Steel Boiler: %.4f", steelBurnTime), - "Titanium Boiler: Not allowed", - "Tungstenst. Boiler: Not allowed"); - - return super.addRecipe(recipe); - } - } - - public static class GT_Recipe_Map_IC2NuclearFake extends GT_Recipe_Map { - - public GT_Recipe_Map_IC2NuclearFake() { - super( - new HashSet<>(10), - "gt.recipe.ic2nuke", - "Fission", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "Default"), - 1, - 1, - 1, - 0, - 1, - E, - 1, - E, - true, - true); - setLogo(GT_UITextures.PICTURE_RADIATION_WARNING); - setLogoPos(152, 24); - setNEIBackgroundSize(172, 60); - setProgressBar(GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT); - } - - /** - * Add a breeder cell. - * - * @param input raw stack. should be undamaged. - * @param output breed output - * @param heatMultiplier bonus progress per neutron pulse per heat step - * @param heatStep divisor for hull heat - * @param reflector true if also acts as a neutron reflector, false otherwise. - * @param requiredPulses progress required to complete breeding - * @return added fake recipe - */ - public GT_Recipe addBreederCell(ItemStack input, ItemStack output, boolean reflector, int heatStep, - int heatMultiplier, int requiredPulses) { - return addFakeRecipe( - input, - output, - reflector ? "Neutron reflecting breeder cell" : "Heat neutral Breeder Cell", - String.format("Every %d reactor hull heat", heatStep), - String.format("increase speed by %d00%%", heatMultiplier), - String.format("Required pulses: %d", requiredPulses)); - } - - public GT_Recipe addFakeRecipe(ItemStack input, ItemStack output, String... neiDesc) { - GT_Recipe r = new GT_Recipe( - new ItemStack[] { input }, - new ItemStack[] { output }, - null, - new int[] { 10000 }, - null, - null, - 0, - 0, - 0); - r.setNeiDesc(neiDesc); - return addRecipe(r, true, true, false); - } - } - - public static class GT_Recipe_Map_LargeChemicalReactor extends GT_Recipe_Map_LargeNEI { - - private static final int TOTAL_INPUT_COUNT = 6; - private static final int OUTPUT_COUNT = 6; - - public GT_Recipe_Map_LargeChemicalReactor() { - super( - new HashSet<>(1000), - "gt.recipe.largechemicalreactor", - "Large Chemical Reactor", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "LCRNEI"), - TOTAL_INPUT_COUNT, - OUTPUT_COUNT, - 0, - 0, - 1, - E, - 1, - E, - true, - true); - } - - @Override - public GT_Recipe addRecipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecial, - int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue) { - aOptimize = false; - ArrayList<ItemStack> adjustedInputs = new ArrayList<>(); - ArrayList<ItemStack> adjustedOutputs = new ArrayList<>(); - ArrayList<FluidStack> adjustedFluidInputs = new ArrayList<>(); - ArrayList<FluidStack> adjustedFluidOutputs = new ArrayList<>(); - - if (aInputs == null) { - aInputs = new ItemStack[0]; - } else { - aInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new); - } - - for (ItemStack input : aInputs) { - FluidStack inputFluidContent = FluidContainerRegistry.getFluidForFilledItem(input); - if (inputFluidContent != null) { - inputFluidContent.amount *= input.stackSize; - if (inputFluidContent.getFluid() - .getName() - .equals("ic2steam")) { - inputFluidContent = GT_ModHandler.getSteam(inputFluidContent.amount); - } - adjustedFluidInputs.add(inputFluidContent); - } else { - ItemData itemData = GT_OreDictUnificator.getItemData(input); - if (itemData != null && itemData.hasValidPrefixMaterialData() - && itemData.mMaterial.mMaterial == Materials.Empty) { - continue; - } else { - if (itemData != null && itemData.hasValidPrefixMaterialData() - && itemData.mPrefix == OrePrefixes.cell) { - ItemStack dustStack = itemData.mMaterial.mMaterial.getDust(input.stackSize); - if (dustStack != null) { - adjustedInputs.add(dustStack); - } else { - adjustedInputs.add(input); - } - } else { - adjustedInputs.add(input); - } - } - } - - if (aFluidInputs == null) { - aFluidInputs = new FluidStack[0]; - } - } - Collections.addAll(adjustedFluidInputs, aFluidInputs); - aInputs = adjustedInputs.toArray(new ItemStack[0]); - aFluidInputs = adjustedFluidInputs.toArray(new FluidStack[0]); - - if (aOutputs == null) { - aOutputs = new ItemStack[0]; - } else { - aOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new); - } - - for (ItemStack output : aOutputs) { - FluidStack outputFluidContent = FluidContainerRegistry.getFluidForFilledItem(output); - if (outputFluidContent != null) { - outputFluidContent.amount *= output.stackSize; - if (outputFluidContent.getFluid() - .getName() - .equals("ic2steam")) { - outputFluidContent = GT_ModHandler.getSteam(outputFluidContent.amount); - } - adjustedFluidOutputs.add(outputFluidContent); - } else { - ItemData itemData = GT_OreDictUnificator.getItemData(output); - if (!(itemData != null && itemData.hasValidPrefixMaterialData() - && itemData.mMaterial.mMaterial == Materials.Empty)) { - adjustedOutputs.add(output); - } - } - } - if (aFluidOutputs == null) { - aFluidOutputs = new FluidStack[0]; - } - Collections.addAll(adjustedFluidOutputs, aFluidOutputs); - aOutputs = adjustedOutputs.toArray(new ItemStack[0]); - aFluidOutputs = adjustedFluidOutputs.toArray(new FluidStack[0]); - - return super.addRecipe( - aOptimize, - aInputs, - aOutputs, - aSpecial, - aOutputChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue); - } - } - - public static class GT_Recipe_Map_DistillationTower extends GT_Recipe_Map { - - public GT_Recipe_Map_DistillationTower() { - super( - new HashSet<>(110), - "gt.recipe.distillationtower", - "Distillation Tower", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "DistillationTower"), - 2, - 1, - 0, - 0, - 1, - E, - 1, - E, - true, - true); - setLogoPos(80, 62); - } - - @Override - public IDrawable getOverlayForSlot(boolean isFluid, boolean isOutput, int index, boolean isSpecial) { - if (isOutput) { - if (isFluid) { - return GT_UITextures.OVERLAY_SLOTS_NUMBER[index + 1]; - } else { - return GT_UITextures.OVERLAY_SLOTS_NUMBER[0]; - } - } - return super.getOverlayForSlot(isFluid, false, index, isSpecial); - } - - @Override - public List<Pos2d> getItemOutputPositions(int itemOutputCount) { - return Collections.singletonList(new Pos2d(106, 62)); - } - - @Override - public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { - List<Pos2d> results = new ArrayList<>(); - for (int i = 1; i < fluidOutputCount + 1; i++) { - results.add(new Pos2d(106 + (i % 3) * 18, 62 - (i / 3) * 18)); - } - return results; - } - } - - public static class GT_Recipe_Map_OilCracker extends GT_Recipe_Map { - - private final Set<String> mValidCatalystFluidNames = new HashSet<>(); - - public GT_Recipe_Map_OilCracker() { - super( - new HashSet<>(70), - "gt.recipe.craker", - "Oil Cracker", - null, - GregTech.getResourcePath(TEXTURES_GUI_BASICMACHINES, "OilCracker"), - 1, - 1, - 1, - 2, - 1, - E, - 1, - E, - true, - true); - } - - @Override - public GT_Recipe add(GT_Recipe aRecipe) { - GT_Recipe ret = super.add(aRecipe); - if (ret != null && ret.mFluidInputs != null && ret.mFluidInputs.length > 1 && ret.mFluidInputs[1] != null) { - mValidCatalystFluidNames.add( - ret.mFluidInputs[1].getFluid() - .getName()); - } - return ret; - } - - public boolean isValidCatalystFluid(FluidStack aFluidStack) { - return mValidCatalystFluidNames.contains( - aFluidStack.getFluid() - .getName()); - } - } - public static class GT_Recipe_WithAlt extends GT_Recipe { ItemStack[][] mOreDictAlt; + /** + * Only for {@link GT_RecipeBuilder}. + */ GT_Recipe_WithAlt(ItemStack[] mInputs, ItemStack[] mOutputs, FluidStack[] mFluidInputs, FluidStack[] mFluidOutputs, int[] mChances, Object mSpecialItems, int mDuration, int mEUt, int mSpecialValue, boolean mEnabled, boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, - boolean mNeedsEmptyOutput, String[] neiDesc, ItemStack[][] mOreDictAlt) { + boolean mNeedsEmptyOutput, boolean nbtSensitive, String[] neiDesc, + @Nullable IRecipeMetadataStorage metadataStorage, RecipeCategory recipeCategory, + ItemStack[][] mOreDictAlt) { super( mInputs, mOutputs, @@ -6299,7 +938,10 @@ public class GT_Recipe implements Comparable<GT_Recipe> { mFakeRecipe, mCanBeBuffered, mNeedsEmptyOutput, - neiDesc); + nbtSensitive, + neiDesc, + metadataStorage, + recipeCategory); this.mOreDictAlt = mOreDictAlt; } @@ -6335,191 +977,4 @@ public class GT_Recipe implements Comparable<GT_Recipe> { return GT_Utility.copyOrNull(mInputs[aIndex]); } } - - private static class ReplicatorFakeMap extends GT_Recipe_Map { - - public ReplicatorFakeMap(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 addFakeRecipe(boolean aCheckForCollisions, ItemStack[] aInputs, ItemStack[] aOutputs, - Object aSpecial, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue) { - AtomicInteger ai = new AtomicInteger(); - Optional.ofNullable(GT_OreDictUnificator.getAssociation(aOutputs[0])) - .map(itemData -> itemData.mMaterial) - .map(materialsStack -> materialsStack.mMaterial) - .map(materials -> materials.mElement) - .map(Element::getMass) - .ifPresent(e -> { - aFluidInputs[0].amount = (int) GT_MetaTileEntity_Replicator.cubicFluidMultiplier(e); - ai.set(GT_Utility.safeInt(aFluidInputs[0].amount * 512L, 1)); - }); - return addFakeRecipe( - aCheckForCollisions, - new GT_Recipe( - false, - aInputs, - aOutputs, - aSpecial, - null, - aFluidInputs, - aFluidOutputs, - ai.get(), - aEUt, - aSpecialValue)); - } - } - - public static class GT_Recipe_Map_ComplexFusion extends GT_Recipe_Map { - - public GT_Recipe_Map_ComplexFusion(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 addRecipe(int[] aOutputChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, - int aDuration, int aEUt, int aSpecialValue) { - return addRecipe( - new GT_Recipe( - false, - null, - null, - null, - aOutputChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue), - false, - false, - false); - } - - @Override - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getGridPositions(fluidInputCount, 7, 9, 4); - } - - @Override - public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { - return UIHelper.getGridPositions(fluidOutputCount, 97, 9, 4); - } - } - - public static class GT_Recipe_Map_AssemblyLineFake extends GT_Recipe_Map { - - public GT_Recipe_Map_AssemblyLineFake(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); - setNEITransferRect(new Rectangle(146, 26, 10, 18)); - } - - @Override - public List<Pos2d> getItemInputPositions(int itemInputCount) { - return UIHelper.getGridPositions(itemInputCount, 16, 8, 4); - } - - @Override - public List<Pos2d> getItemOutputPositions(int itemOutputCount) { - return Collections.singletonList(new Pos2d(142, 8)); - } - - @Override - public Pos2d getSpecialItemPosition() { - return new Pos2d(142, 44); - } - - @Override - public List<Pos2d> getFluidInputPositions(int fluidInputCount) { - return UIHelper.getGridPositions(fluidInputCount, 106, 8, 1); - } - - @Override - public void addProgressBarUI(ModularWindow.Builder builder, Supplier<Float> progressSupplier, - Pos2d windowOffset) { - int bar1Width = 17; - int bar2Width = 18; - builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, 17) - .setDirection(ProgressBar.Direction.RIGHT) - .setProgress(() -> progressSupplier.get() * ((float) (bar1Width + bar2Width) / bar1Width)) - .setSynced(false, false) - .setPos(new Pos2d(88, 8).add(windowOffset)) - .setSize(bar1Width, 72)); - builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, 18) - .setDirection(ProgressBar.Direction.RIGHT) - .setProgress( - () -> (progressSupplier.get() - ((float) bar1Width / (bar1Width + bar2Width))) - * ((float) (bar1Width + bar2Width) / bar2Width)) - .setSynced(false, false) - .setPos(new Pos2d(124, 8).add(windowOffset)) - .setSize(bar2Width, 72)); - builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_3, 18) - .setDirection(ProgressBar.Direction.UP) - .setProgress(progressSupplier) - .setSynced(false, false) - .setPos(new Pos2d(146, 26).add(windowOffset)) - .setSize(10, 18)); - } - } } diff --git a/src/main/java/gregtech/api/util/GT_RecipeBuilder.java b/src/main/java/gregtech/api/util/GT_RecipeBuilder.java index 3fa8d91da0..271ea28d87 100644 --- a/src/main/java/gregtech/api/util/GT_RecipeBuilder.java +++ b/src/main/java/gregtech/api/util/GT_RecipeBuilder.java @@ -1,30 +1,34 @@ package gregtech.api.util; +import static gregtech.api.util.GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES; import static gregtech.api.util.GT_Utility.copyFluidArray; import static gregtech.api.util.GT_Utility.copyItemArray; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Function; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.minecraft.item.ItemStack; import net.minecraft.launchwrapper.Launch; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Contract; + import gregtech.GT_Mod; -import gregtech.api.interfaces.IGT_RecipeMap; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.recipe.RecipeCategory; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.IRecipeMetadataStorage; +import gregtech.api.recipe.metadata.RecipeMetadataStorage; import gregtech.api.util.extensions.ArrayExt; -@SuppressWarnings("unused") +@SuppressWarnings({ "unused", "UnusedReturnValue" }) public class GT_RecipeBuilder { // debug mode expose problems. panic mode help you check nothing is wrong-ish without you actively monitoring @@ -86,9 +90,13 @@ public class GT_RecipeBuilder { protected boolean fakeRecipe = false; protected boolean mCanBeBuffered = true; protected boolean mNeedsEmptyOutput = false; + protected boolean nbtSensitive = false; protected String[] neiDesc; + protected RecipeCategory recipeCategory; protected boolean optimize = true; - protected Map<MetadataIdentifier<?>, Object> additionalData = new HashMap<>(); + @Nullable + protected IRecipeMetadataStorage metadataStorage; + protected boolean checkForCollision = true; protected boolean valid = true; GT_RecipeBuilder() {} @@ -96,8 +104,8 @@ public class GT_RecipeBuilder { private GT_RecipeBuilder(ItemStack[] inputsBasic, Object[] inputsOreDict, ItemStack[] outputs, ItemStack[][] alts, FluidStack[] fluidInputs, FluidStack[] fluidOutputs, int[] chances, Object special, int duration, int eut, int specialValue, boolean enabled, boolean hidden, boolean fakeRecipe, boolean mCanBeBuffered, - boolean mNeedsEmptyOutput, String[] neiDesc, boolean optimize, - Map<MetadataIdentifier<?>, Object> additionalData, boolean valid) { + boolean mNeedsEmptyOutput, boolean nbtSensitive, String[] neiDesc, RecipeCategory recipeCategory, + boolean optimize, @Nullable IRecipeMetadataStorage metadataStorage, boolean checkForCollision, boolean valid) { this.inputsBasic = inputsBasic; this.inputsOreDict = inputsOreDict; this.outputs = outputs; @@ -114,9 +122,15 @@ public class GT_RecipeBuilder { this.fakeRecipe = fakeRecipe; this.mCanBeBuffered = mCanBeBuffered; this.mNeedsEmptyOutput = mNeedsEmptyOutput; + this.nbtSensitive = nbtSensitive; this.neiDesc = neiDesc; + this.recipeCategory = recipeCategory; this.optimize = optimize; - this.additionalData.putAll(additionalData); + this.metadataStorage = metadataStorage; + if (this.metadataStorage != null) { + this.metadataStorage = this.metadataStorage.copy(); + } + this.checkForCollision = checkForCollision; this.valid = valid; } @@ -137,6 +151,14 @@ public class GT_RecipeBuilder { return new GT_RecipeBuilder(); } + /** + * Creates empty builder where only duration and EU/t are set to 0. + */ + public static GT_RecipeBuilder empty() { + return new GT_RecipeBuilder().duration(0) + .eut(0); + } + private static boolean containsNull(Object[] arr) { return arr == null || Arrays.stream(arr) .anyMatch(Objects::isNull); @@ -156,7 +178,7 @@ public class GT_RecipeBuilder { return DEBUG_MODE_NULL || PANIC_MODE_NULL; } - private static void handleInvalidRecipe() { + public static void handleInvalidRecipe() { if (!DEBUG_MODE_INVALID && !PANIC_MODE_INVALID) { return; } @@ -247,14 +269,6 @@ public class GT_RecipeBuilder { return noOptimize(); } - /** - * @deprecated You don't need to call this method, RecipeBuilder now takes empty item input array by default. - */ - @Deprecated - public GT_RecipeBuilder noItemInputs() { - return this; - } - public GT_RecipeBuilder itemOutputs(ItemStack... outputs) { if (debugNull() && containsNull(outputs)) handleNullRecipeComponents("itemOutputs"); this.outputs = outputs; @@ -278,50 +292,18 @@ public class GT_RecipeBuilder { return this; } - /** - * @deprecated You don't need to call this method, RecipeBuilder now takes empty item output array by default. - */ - @Deprecated - public GT_RecipeBuilder noItemOutputs() { - return this; - } - public GT_RecipeBuilder fluidInputs(FluidStack... fluidInputs) { if (debugNull() && containsNull(fluidInputs)) handleNullRecipeComponents("fluidInputs"); this.fluidInputs = fix(fluidInputs); return this; } - /** - * @deprecated You don't need to call this method, RecipeBuilder now takes empty fluid input array by default. - */ - @Deprecated - public GT_RecipeBuilder noFluidInputs() { - return this; - } - public GT_RecipeBuilder fluidOutputs(FluidStack... fluidOutputs) { if (debugNull() && containsNull(fluidOutputs)) handleNullRecipeComponents("fluidOutputs"); this.fluidOutputs = fix(fluidOutputs); return this; } - /** - * @deprecated You don't need to call this method, RecipeBuilder now takes empty fluid output array by default. - */ - @Deprecated - public GT_RecipeBuilder noFluidOutputs() { - return this; - } - - /** - * @deprecated You don't need to call this method, RecipeBuilder now takes empty arrays by default. - */ - @Deprecated - public GT_RecipeBuilder noOutputs() { - return this; - } - public GT_RecipeBuilder outputChances(int... chances) { if (outputs != null && chances.length != outputs.length) { throw new IllegalArgumentException("Output chances array and items array length differs"); @@ -398,11 +380,21 @@ public class GT_RecipeBuilder { return this; } + public GT_RecipeBuilder nbtSensitive() { + this.nbtSensitive = true; + return this; + } + public GT_RecipeBuilder setNEIDesc(String... neiDesc) { this.neiDesc = neiDesc; return this; } + public GT_RecipeBuilder recipeCategory(RecipeCategory recipeCategory) { + this.recipeCategory = recipeCategory; + return this; + } + /** * Prevent the resulting recipe from optimizing recipe, which is a process that reduce recipe batch size. */ @@ -411,17 +403,51 @@ public class GT_RecipeBuilder { return this; } - public <T> GT_RecipeBuilder metadata(MetadataIdentifier<T> key, T value) { - additionalData.put(key, value); + /** + * Prevents checking collision with existing recipes when adding the built recipe. + */ + public GT_RecipeBuilder ignoreCollision() { + this.checkForCollision = false; return this; } - public <T> T getMetadata(MetadataIdentifier<T> key) { - return key.cast(additionalData.get(key)); + /** + * Sets metadata of the recipe. It can be used for recipe emitter to do special things, or for being stored in the + * built recipe and used for actual recipe processing. + * <p> + * {@link GT_RecipeConstants} has a series of metadata keys. Or you can create one by yourself. + */ + public <T> GT_RecipeBuilder metadata(RecipeMetadataKey<T> key, T value) { + if (metadataStorage == null) { + metadataStorage = new RecipeMetadataStorage(); + } + metadataStorage.store(key, value); + return this; + } + + /** + * Gets metadata already set for this builder. Can return null. Use + * {@link #getMetadataOrDefault(RecipeMetadataKey, Object)} + * if you want to specify default value. + */ + @Nullable + public <T> T getMetadata(RecipeMetadataKey<T> key) { + if (metadataStorage == null) { + return null; + } + return key.cast(metadataStorage.getMetadata(key)); } - public <T> T getMetadata(MetadataIdentifier<T> key, T defaultValue) { - return key.cast(additionalData.getOrDefault(key, defaultValue)); + /** + * Gets metadata already set for this builder with default value. Does not return null unless default value is null. + */ + @Contract("_, !null -> !null") + @Nullable + public <T> T getMetadataOrDefault(RecipeMetadataKey<T> key, T defaultValue) { + if (metadataStorage == null) { + return defaultValue; + } + return key.cast(metadataStorage.getMetadataOrDefault(key, defaultValue)); } public GT_RecipeBuilder requiresCleanRoom() { @@ -466,9 +492,12 @@ public class GT_RecipeBuilder { fakeRecipe, mCanBeBuffered, mNeedsEmptyOutput, + nbtSensitive, copy(neiDesc), + recipeCategory, optimize, - additionalData, + metadataStorage, + checkForCollision, valid); } @@ -493,9 +522,12 @@ public class GT_RecipeBuilder { fakeRecipe, mCanBeBuffered, mNeedsEmptyOutput, + nbtSensitive, copy(neiDesc), + recipeCategory, optimize, - Collections.emptyMap(), + null, + checkForCollision, valid); } @@ -553,6 +585,18 @@ public class GT_RecipeBuilder { return eut; } + public RecipeCategory getRecipeCategory() { + return recipeCategory; + } + + public boolean isOptimize() { + return optimize; + } + + public boolean isCheckForCollision() { + return checkForCollision; + } + // endregion // region validator @@ -581,7 +625,7 @@ public class GT_RecipeBuilder { /** * Validate if input item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateNoInput() { return GT_Utility.isArrayEmptyOrNull(inputsBasic) ? this : invalidate(); @@ -589,7 +633,7 @@ public class GT_RecipeBuilder { /** * Validate if input fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateNoInputFluid() { return GT_Utility.isArrayEmptyOrNull(fluidInputs) ? this : invalidate(); @@ -597,7 +641,7 @@ public class GT_RecipeBuilder { /** * Validate if output item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateNoOutput() { return GT_Utility.isArrayEmptyOrNull(outputs) ? this : invalidate(); @@ -605,7 +649,7 @@ public class GT_RecipeBuilder { /** * Validate if output fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateNoOutputFluid() { return GT_Utility.isArrayEmptyOrNull(fluidOutputs) ? this : invalidate(); @@ -613,7 +657,7 @@ public class GT_RecipeBuilder { /** * Validate if input item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateInputCount(int min, int max) { if (inputsBasic == null) return min < 0 ? this : invalidate(); @@ -622,7 +666,7 @@ public class GT_RecipeBuilder { /** * Validate if input fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateInputFluidCount(int min, int max) { if (fluidInputs == null) return min < 0 ? this : invalidate(); @@ -631,7 +675,7 @@ public class GT_RecipeBuilder { /** * Validate if output item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateOutputCount(int min, int max) { if (outputs == null) return min < 0 ? this : invalidate(); @@ -640,7 +684,7 @@ public class GT_RecipeBuilder { /** * Validate if output fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IGT_RecipeMap and not client code. + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. */ public GT_RecipeBuilder validateOutputFluidCount(int min, int max) { if (fluidOutputs == null) return min < 0 ? this : invalidate(); @@ -669,6 +713,12 @@ public class GT_RecipeBuilder { // endregion + /** + * Builds new recipe, without custom behavior of recipemaps. For adding recipe to recipemap, + * use {@link #addTo} instead. + * + * @return Built recipe. Returns empty if failed to build. + */ public Optional<GT_Recipe> build() { if (!valid) { handleInvalidRecipe(); @@ -693,7 +743,10 @@ public class GT_RecipeBuilder { fakeRecipe, mCanBeBuffered, mNeedsEmptyOutput, - neiDesc))); + nbtSensitive, + neiDesc, + metadataStorage, + recipeCategory))); } public GT_RecipeBuilder forceOreDictInput() { @@ -728,7 +781,10 @@ public class GT_RecipeBuilder { fakeRecipe, mCanBeBuffered, mNeedsEmptyOutput, + nbtSensitive, neiDesc, + metadataStorage, + recipeCategory, alts))); } @@ -769,18 +825,36 @@ public class GT_RecipeBuilder { r.mHidden = hidden; r.mCanBeBuffered = mCanBeBuffered; r.mNeedsEmptyOutput = mNeedsEmptyOutput; + r.isNBTSensitive = nbtSensitive; r.mFakeRecipe = fakeRecipe; r.mEnabled = enabled; if (neiDesc != null) r.setNeiDesc(neiDesc); + applyDefaultSpecialValues(r); return r; } - public Collection<GT_Recipe> addTo(IGT_RecipeMap recipeMap) { + private void applyDefaultSpecialValues(GT_Recipe recipe) { + if (recipe.mSpecialValue != 0) return; + + int specialValue = 0; + if (getMetadataOrDefault(GT_RecipeConstants.LOW_GRAVITY, false)) specialValue -= 100; + if (getMetadataOrDefault(GT_RecipeConstants.CLEANROOM, false)) specialValue -= 200; + for (RecipeMetadataKey<Integer> ident : SPECIAL_VALUE_ALIASES) { + Integer metadata = getMetadataOrDefault(ident, null); + if (metadata != null) { + specialValue = metadata; + break; + } + } + recipe.mSpecialValue = specialValue; + } + + public Collection<GT_Recipe> addTo(IRecipeMap recipeMap) { return recipeMap.doAdd(this); } public GT_RecipeBuilder reset() { - additionalData.clear(); + metadataStorage = null; alts = null; chances = null; duration = -1; @@ -794,7 +868,9 @@ public class GT_RecipeBuilder { inputsOreDict = null; mCanBeBuffered = true; mNeedsEmptyOutput = false; + nbtSensitive = false; neiDesc = null; + recipeCategory = null; optimize = true; outputs = null; special = null; @@ -802,45 +878,4 @@ public class GT_RecipeBuilder { valid = true; return this; } - - public final static class MetadataIdentifier<T> { - - private static final Map<MetadataIdentifier<?>, MetadataIdentifier<?>> allIdentifiers = Collections - .synchronizedMap(new HashMap<>()); - private final Class<T> clazz; - private final String identifier; - - private MetadataIdentifier(Class<T> clazz, String identifier) { - this.clazz = clazz; - this.identifier = identifier; - } - - public static <T> MetadataIdentifier<T> create(Class<T> clazz, String identifier) { - MetadataIdentifier<T> key = new MetadataIdentifier<>(clazz, identifier); - // noinspection unchecked // The class uses type T to fill allIdentifiers - return (MetadataIdentifier<T>) allIdentifiers.computeIfAbsent(key, Function.identity()); - } - - public T cast(Object o) { - return clazz.cast(o); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - MetadataIdentifier<?> that = (MetadataIdentifier<?>) o; - - if (!clazz.equals(that.clazz)) return false; - return identifier.equals(that.identifier); - } - - @Override - public int hashCode() { - int result = clazz.hashCode(); - result = 31 * result + identifier.hashCode(); - return result; - } - } } diff --git a/src/main/java/gregtech/api/util/GT_RecipeConstants.java b/src/main/java/gregtech/api/util/GT_RecipeConstants.java index 2b92615c5f..8e728030f2 100644 --- a/src/main/java/gregtech/api/util/GT_RecipeConstants.java +++ b/src/main/java/gregtech/api/util/GT_RecipeConstants.java @@ -17,8 +17,11 @@ import cpw.mods.fml.common.registry.GameRegistry; import gregtech.api.GregTech_API; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; -import gregtech.api.interfaces.IGT_RecipeMap; -import gregtech.api.util.GT_Recipe.GT_Recipe_Map; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.recipe.RecipeCategories; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.SimpleRecipeMetadataKey; // this class is intended to be import-static-ed on every recipe script // so take care to not put unrelated stuff here! @@ -28,72 +31,77 @@ public class GT_RecipeConstants { * Set to true to signal the recipe require low gravity. do nothing if recipe set specialValue explicitly. Can * coexist with CLEANROOM just fine */ - public static final GT_RecipeBuilder.MetadataIdentifier<Boolean> LOW_GRAVITY = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Boolean> LOW_GRAVITY = SimpleRecipeMetadataKey .create(Boolean.class, "low_gravity"); /** * Set to true to signal the recipe require cleanroom. do nothing if recipe set specialValue explicitly. Can coexist * with LOW_GRAVITY just fine */ - public static final GT_RecipeBuilder.MetadataIdentifier<Boolean> CLEANROOM = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Boolean> CLEANROOM = SimpleRecipeMetadataKey .create(Boolean.class, "cleanroom"); /** * Common additive to use in recipe, e.g. for PBF, this is coal amount. */ - public static final GT_RecipeBuilder.MetadataIdentifier<Integer> ADDITIVE_AMOUNT = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Integer> ADDITIVE_AMOUNT = SimpleRecipeMetadataKey .create(Integer.class, "additives"); /** * Used for fusion reactor. Denotes ignition threshold. */ - public static final GT_RecipeBuilder.MetadataIdentifier<Integer> FUSION_THRESHOLD = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Integer> FUSION_THRESHOLD = SimpleRecipeMetadataKey .create(Integer.class, "fusion_threshold"); /** * Research time in a scanner used in ticks. */ - public static final GT_RecipeBuilder.MetadataIdentifier<Integer> RESEARCH_TIME = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Integer> RESEARCH_TIME = SimpleRecipeMetadataKey .create(Integer.class, "research_time"); /** * Fuel type. TODO should we use enum directly? */ - public static final GT_RecipeBuilder.MetadataIdentifier<Integer> FUEL_TYPE = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Integer> FUEL_TYPE = SimpleRecipeMetadataKey .create(Integer.class, "fuel_type"); /** * Fuel value. */ - public static final GT_RecipeBuilder.MetadataIdentifier<Integer> FUEL_VALUE = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Integer> FUEL_VALUE = SimpleRecipeMetadataKey .create(Integer.class, "fuel_value"); /** - * Fuel value. + * Required heat for heating coil (Kelvin). */ - public static final GT_RecipeBuilder.MetadataIdentifier<Integer> COIL_HEAT = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Integer> COIL_HEAT = SimpleRecipeMetadataKey .create(Integer.class, "coil_heat"); /** * Research item used by assline recipes. */ - public static final GT_RecipeBuilder.MetadataIdentifier<ItemStack> RESEARCH_ITEM = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<ItemStack> RESEARCH_ITEM = SimpleRecipeMetadataKey .create(ItemStack.class, "research_item"); /** * For assembler. It accepts a single item as oredict. It looks like no one uses this anyway... */ - public static final GT_RecipeBuilder.MetadataIdentifier<Object> OREDICT_INPUT = GT_RecipeBuilder.MetadataIdentifier + public static final RecipeMetadataKey<Object> OREDICT_INPUT = SimpleRecipeMetadataKey .create(Object.class, "oredict_input"); - /** - * Add fusion recipes. Dispatcher between complex fusion (which accepts arbitrarily many input/outputs) and classic - * fusion (2 in 1 out). + * Replicator output material. */ - public static final IGT_RecipeMap Fusion = IGT_RecipeMap.newRecipeMap(builder -> { - if (GT_Utility.isArrayEmptyOrNull(builder.getFluidInputs()) - || GT_Utility.isArrayEmptyOrNull(builder.getFluidOutputs())) return Collections.emptyList(); - if (builder.getFluidInputs().length > 2 || builder.getFluidOutputs().length > 2) - return GT_Recipe_Map.sComplexFusionRecipes.doAdd(builder); - return GT_Recipe_Map.sFusionRecipes.doAdd(builder); - }); + public static final RecipeMetadataKey<Materials> MATERIAL = SimpleRecipeMetadataKey + .create(Materials.class, "material"); + /** + * Marker for {@link #UniversalArcFurnace} to tell that the recipe belongs to recycling category. + */ + public static final RecipeMetadataKey<Boolean> RECYCLE = SimpleRecipeMetadataKey.create(Boolean.class, "recycle"); + /** + * For Microwave. + */ + public static final RecipeMetadataKey<Boolean> EXPLODE = SimpleRecipeMetadataKey.create(Boolean.class, "explode"); + /** + * For Microwave. + */ + public static final RecipeMetadataKey<Boolean> ON_FIRE = SimpleRecipeMetadataKey.create(Boolean.class, "on_fire"); /** * Add a arc furnace recipe. Adds to both normal arc furnace and plasma arc furnace. * Will override the fluid input with oxygen/plasma for the respective recipe maps, so there is no point setting it. */ - public static final IGT_RecipeMap UniversalArcFurnace = IGT_RecipeMap.newRecipeMap(builder -> { + public static final IRecipeMap UniversalArcFurnace = IRecipeMap.newRecipeMap(builder -> { if (!GT_Utility.isArrayOfLength(builder.getItemInputsBasic(), 1) || GT_Utility.isArrayEmptyOrNull(builder.getItemOutputs())) return Collections.emptyList(); int aDuration = builder.getDuration(); @@ -101,39 +109,45 @@ public class GT_RecipeConstants { return Collections.emptyList(); } builder.duration(aDuration); + boolean recycle = builder.getMetadataOrDefault(RECYCLE, false); Collection<GT_Recipe> ret = new ArrayList<>(); for (Materials mat : new Materials[] { Materials.Argon, Materials.Nitrogen }) { int tPlasmaAmount = (int) Math.max(1L, aDuration / (mat.getMass() * 16L)); - GT_RecipeBuilder b2 = builder.copy(); - b2.fluidInputs(mat.getPlasma(tPlasmaAmount)) + GT_RecipeBuilder plasmaBuilder = builder.copy() + .fluidInputs(mat.getPlasma(tPlasmaAmount)) .fluidOutputs(mat.getGas(tPlasmaAmount)); - ret.addAll(GT_Recipe_Map.sPlasmaArcFurnaceRecipes.doAdd(b2)); + if (recycle) { + plasmaBuilder.recipeCategory(RecipeCategories.plasmaArcFurnaceRecycling); + } + ret.addAll(RecipeMaps.plasmaArcFurnaceRecipes.doAdd(plasmaBuilder)); } - ret.addAll( - GT_Recipe_Map.sArcFurnaceRecipes.doAdd( - builder.copy() - .fluidInputs(Materials.Oxygen.getGas(aDuration)))); + GT_RecipeBuilder arcBuilder = builder.copy() + .fluidInputs(Materials.Oxygen.getGas(aDuration)); + if (recycle) { + arcBuilder.recipeCategory(RecipeCategories.arcFurnaceRecycling); + } + ret.addAll(RecipeMaps.arcFurnaceRecipes.doAdd(arcBuilder)); return ret; }); /** * Add a chemical reactor recipe to both LCR and singleblocks. */ - public static final IGT_RecipeMap UniversalChemical = IGT_RecipeMap.newRecipeMap(builder -> { + public static final IRecipeMap UniversalChemical = IRecipeMap.newRecipeMap(builder -> { for (ItemStack input : builder.getItemInputsBasic()) { // config >= 10 -> this is a special chemical recipe that output fluid/canned fluid variant. // it doesn't belong to multiblocks if (GT_Utility.isAnyIntegratedCircuit(input) && input.getItemDamage() >= 10) { - return builder.addTo(GT_Recipe_Map.sChemicalRecipes); + return builder.addTo(RecipeMaps.chemicalReactorRecipes); } } return GT_Utility.concat( builder.copy() - .addTo(GT_Recipe_Map.sChemicalRecipes), + .addTo(RecipeMaps.chemicalReactorRecipes), convertCellToFluid(builder, false) // LCR does not need cleanroom. .metadata(CLEANROOM, false) - .addTo(GT_Recipe_Map.sMultiblockChemicalRecipes)); + .addTo(RecipeMaps.multiblockChemicalReactorRecipes)); }); /** @@ -141,18 +155,22 @@ public class GT_RecipeConstants { * Uses {@link #RESEARCH_ITEM} metadata as research item, and {@link #RESEARCH_TIME} metadata as research time, unit * in ticks. */ - public static final IGT_RecipeMap AssemblyLine = IGT_RecipeMap.newRecipeMap(builder -> { + public static final IRecipeMap AssemblyLine = IRecipeMap.newRecipeMap(builder -> { Optional<GT_Recipe.GT_Recipe_WithAlt> rr = builder.forceOreDictInput() .validateInputCount(4, 16) .validateOutputCount(1, 1) .validateOutputFluidCount(-1, 0) .validateInputFluidCount(0, 4) .buildWithAlt(); + // noinspection SimplifyOptionalCallChains if (!rr.isPresent()) return Collections.emptyList(); GT_Recipe.GT_Recipe_WithAlt r = rr.get(); ItemStack[][] mOreDictAlt = r.mOreDictAlt; Object[] inputs = builder.getItemInputsOreDict(); ItemStack aResearchItem = builder.getMetadata(RESEARCH_ITEM); + if (aResearchItem == null) { + return Collections.emptyList(); + } ItemStack aOutput = r.mOutputs[0]; int tPersistentHash = 1; for (int i = 0, mOreDictAltLength = mOreDictAlt.length; i < mOreDictAltLength; i++) { @@ -198,13 +216,13 @@ public class GT_RecipeConstants { if (fluidInput == null) continue; tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(fluidInput, true, false); } - int aResearchTime = builder.getMetadata(RESEARCH_TIME); + int aResearchTime = builder.getMetadataOrDefault(RESEARCH_TIME, 0); tPersistentHash = tPersistentHash * 31 + aResearchTime; tPersistentHash = tPersistentHash * 31 + r.mDuration; tPersistentHash = tPersistentHash * 31 + r.mEUt; Collection<GT_Recipe> ret = new ArrayList<>(3); ret.add( - GT_Recipe.GT_Recipe_Map.sScannerFakeRecipes.addFakeRecipe( + RecipeMaps.scannerFakeRecipes.addFakeRecipe( false, new ItemStack[] { aResearchItem }, new ItemStack[] { aOutput }, @@ -216,7 +234,7 @@ public class GT_RecipeConstants { -201)); // means it's scanned ret.add( - GT_Recipe.GT_Recipe_Map.sAssemblylineVisualRecipes.addFakeRecipe( + RecipeMaps.assemblylineVisualRecipes.addFakeRecipe( false, r.mInputs, new ItemStack[] { aOutput }, @@ -248,13 +266,13 @@ public class GT_RecipeConstants { * Just like any normal assembler recipe, however it accepts one input item to be oredicted. Pass in the item to * oredict via {@link #OREDICT_INPUT}. It will be used along all other item inputs as input of this recipe. */ - public static IGT_RecipeMap AssemblerOD = IGT_RecipeMap.newRecipeMap(builder -> { + public static IRecipeMap AssemblerOD = IRecipeMap.newRecipeMap(builder -> { Collection<GT_Recipe> ret = new ArrayList<>(); for (ItemStack input : GT_OreDictUnificator.getOresImmutable(builder.getMetadata(OREDICT_INPUT))) { ret.addAll( builder.copy() .itemInputs(GT_RecipeMapUtil.appendArray(builder.getItemInputsBasic(), input)) - .addTo(GT_Recipe_Map.sAssemblerRecipes)); + .addTo(RecipeMaps.assemblerRecipes)); } return ret; }); @@ -265,17 +283,18 @@ public class GT_RecipeConstants { * Can use {@link FuelType#ordinal()} as a human-readable form of what FUEL_TYPE should be. * You can bypass this and add to relevant fuel maps directly if you wish. */ - public static IGT_RecipeMap Fuel = IGT_RecipeMap.newRecipeMap(builder -> { + public static IRecipeMap Fuel = IRecipeMap.newRecipeMap(builder -> { builder.validateInputCount(1, 1) .validateNoInputFluid() .validateOutputCount(-1, 1) .validateNoOutputFluid(); if (!builder.isValid()) return Collections.emptyList(); - int fuelType = builder.getMetadata(FUEL_TYPE); + Integer fuelType = builder.getMetadata(FUEL_TYPE); + if (fuelType == null) return Collections.emptyList(); builder.metadata( FUEL_VALUE, GregTech_API.sRecipeFile - .get("fuel_" + fuelType, builder.getItemInputBasic(0), builder.getMetadata(FUEL_VALUE))); + .get("fuel_" + fuelType, builder.getItemInputBasic(0), builder.getMetadataOrDefault(FUEL_VALUE, 0))); return FuelType.get(fuelType) .getTarget() .doAdd(builder); @@ -284,18 +303,18 @@ public class GT_RecipeConstants { public enum FuelType { // ORDER MATTERS. DO NOT INSERT ELEMENT BETWEEN EXISTING ONES - DieselFuel(GT_Recipe_Map.sDieselFuels), - GasTurbine(GT_Recipe_Map.sTurbineFuels), + DieselFuel(RecipeMaps.dieselFuels), + GasTurbine(RecipeMaps.gasTurbineFuels), // appears unused - HotFuel(GT_Recipe_Map.sHotFuels), - SemiFluid(GT_Recipe_Map.sDenseLiquidFuels), - PlasmaTurbine(GT_Recipe_Map.sPlasmaFuels), - Magic(GT_Recipe_Map.sMagicFuels),; + HotFuel(RecipeMaps.hotFuels), + SemiFluid(RecipeMaps.denseLiquidFuels), + PlasmaTurbine(RecipeMaps.plasmaFuels), + Magic(RecipeMaps.magicFuels),; private static final FuelType[] VALUES = values(); - private final IGT_RecipeMap target; + private final IRecipeMap target; - FuelType(IGT_RecipeMap target) { + FuelType(IRecipeMap target) { this.target = target; } @@ -304,7 +323,7 @@ public class GT_RecipeConstants { return VALUES[fuelType]; } - public IGT_RecipeMap getTarget() { + public IRecipeMap getTarget() { return target; } } diff --git a/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java b/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java index 577f91a170..3e97b56f84 100644 --- a/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java +++ b/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java @@ -26,12 +26,12 @@ import com.google.common.collect.Multimap; import cpw.mods.fml.common.Loader; import gnu.trove.list.TIntList; import gnu.trove.list.array.TIntArrayList; -import gregtech.api.interfaces.IGT_RecipeMap; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.recipe.RecipeMetadataKey; /** * Define helpers useful in the creation of recipe maps. */ -// Do not place arbitrary stuff here! These are all statically imported in GT_Recipe.java file. public class GT_RecipeMapUtil { public static final Function<GT_Recipe, GT_Recipe> ALL_FAKE_RECIPE = r -> { @@ -65,10 +65,13 @@ public class GT_RecipeMapUtil { : r.mFluidOutputs[0].getFluid() .getName() : getStackConfigName(r.mOutputs[0]); - private static final Map<String, IGT_RecipeMap> addonRecipeMaps = new HashMap<>(); - private static final Multimap<String, Consumer<IGT_RecipeMap>> delayedActions = ArrayListMultimap.create(); + private static final Map<String, IRecipeMap> addonRecipeMaps = new HashMap<>(); + private static final Multimap<String, Consumer<IRecipeMap>> delayedActions = ArrayListMultimap.create(); - public static final Set<GT_RecipeBuilder.MetadataIdentifier<Integer>> SPECIAL_VALUE_ALIASES = new HashSet<>(); + /** + * Set of metadata that work as alias for special values. + */ + public static final Set<RecipeMetadataKey<Integer>> SPECIAL_VALUE_ALIASES = new HashSet<>(); public static <T> T[] appendArray(T[] arr, T val) { T[] newArr = Arrays.copyOf(arr, arr.length + 1); @@ -143,8 +146,7 @@ public class GT_RecipeMapUtil { * Currently unused, but you are advised to fill them, so that when The Day (tm) comes we don't * end up with a bunch of weird concurrency bugs. */ - public static void registerRecipeMap(String identifier, IGT_RecipeMap recipeMap, - RecipeMapDependency... dependencies) { + public static void registerRecipeMap(String identifier, IRecipeMap recipeMap, RecipeMapDependency... dependencies) { String modId = Loader.instance() .activeModContainer() .getModId(); @@ -152,7 +154,7 @@ public class GT_RecipeMapUtil { "do not register recipe map under the name of gregtech! do it in your own preinit!"); String id = modId + "@" + identifier; addonRecipeMaps.put(id, recipeMap); - for (Consumer<IGT_RecipeMap> action : delayedActions.get(id)) { + for (Consumer<IRecipeMap> action : delayedActions.get(id)) { action.accept(recipeMap); } } @@ -167,9 +169,9 @@ public class GT_RecipeMapUtil { * @param registerAction DO NOT ADD RECIPES TO MAPS OTHER THAN THE ONE PASSED TO YOU. DO NOT DO ANYTHING OTHER THAN * ADDING RECIPES TO THIS R */ - public static void registerRecipesFor(String modid, String identifier, Consumer<IGT_RecipeMap> registerAction) { + public static void registerRecipesFor(String modid, String identifier, Consumer<IRecipeMap> registerAction) { String id = modid + "@" + identifier; - IGT_RecipeMap map = addonRecipeMaps.get(id); + IRecipeMap map = addonRecipeMaps.get(id); if (map == null) delayedActions.put(id, registerAction); else registerAction.accept(map); } @@ -205,10 +207,10 @@ public class GT_RecipeMapUtil { public static final class RecipeMapDependency { - private final IGT_RecipeMap obj; + private final IRecipeMap obj; private final String id; - public RecipeMapDependency(IGT_RecipeMap obj, String id) { + public RecipeMapDependency(IRecipeMap obj, String id) { this.obj = obj; this.id = id; } @@ -217,7 +219,7 @@ public class GT_RecipeMapUtil { return new RecipeMapDependency(null, id); } - public static RecipeMapDependency create(IGT_RecipeMap obj) { + public static RecipeMapDependency create(IRecipeMap obj) { return new RecipeMapDependency(obj, null); } } diff --git a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java index c057cf0b2f..560d26c41d 100644 --- a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java +++ b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java @@ -19,12 +19,13 @@ import static gregtech.api.enums.Materials.Steel; import static gregtech.api.enums.Materials.Steeleaf; import static gregtech.api.enums.Materials.Thaumium; import static gregtech.api.enums.Materials.Void; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sFluidExtractionRecipes; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sHammerRecipes; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sMaceratorRecipes; -import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sWiremillRecipes; +import static gregtech.api.recipe.RecipeMaps.fluidExtractionRecipes; +import static gregtech.api.recipe.RecipeMaps.hammerRecipes; +import static gregtech.api.recipe.RecipeMaps.maceratorRecipes; +import static gregtech.api.recipe.RecipeMaps.wiremillRecipes; import static gregtech.api.util.GT_RecipeBuilder.SECONDS; import static gregtech.api.util.GT_RecipeBuilder.TICKS; +import static gregtech.api.util.GT_RecipeConstants.RECYCLE; import static gregtech.api.util.GT_RecipeConstants.UniversalArcFurnace; import static gregtech.api.util.GT_Utility.calculateRecipeEU; @@ -61,6 +62,7 @@ import gregtech.api.enums.SubTag; import gregtech.api.enums.TierEU; import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; +import gregtech.api.recipe.RecipeCategories; import ic2.api.reactor.IReactorComponent; /** @@ -205,15 +207,6 @@ public class GT_RecipeRegistrator { || aMaterial.mSmeltInto.mStandardMoltenFluid == null || !aMaterial.contains(SubTag.SMELTING_TO_FLUID) || (L * aMaterialAmount) / (M * aStack.stackSize) <= 0) return; - ItemData tData = GT_OreDictUnificator.getItemData(aStack); - boolean tHide = aStack.getUnlocalizedName() - .startsWith("gt.blockmachines") && (GT_Mod.gregtechproxy.mHideRecyclingRecipes); - if (GT_Mod.gregtechproxy.mHideRecyclingRecipes && tData != null - && tData.hasValidPrefixData() - && !(tData.mPrefix == OrePrefixes.dust || tData.mPrefix == OrePrefixes.ingot - || tData.mPrefix == OrePrefixes.block | tData.mPrefix == OrePrefixes.plate)) { - tHide = true; - } ItemStack recipeOutput = aByproduct == null ? null : aByproduct.mMaterial.contains(SubTag.NO_SMELTING) || !aByproduct.mMaterial.contains(SubTag.METAL) @@ -224,22 +217,16 @@ public class GT_RecipeRegistrator { : null : GT_OreDictUnificator.getIngotOrDust(aByproduct.mMaterial.mSmeltInto, aByproduct.mAmount); + GT_RecipeBuilder builder = RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, aStack)); if (recipeOutput != null) { - RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, aStack)) - .itemOutputs(recipeOutput) - .fluidOutputs(aMaterial.mSmeltInto.getMolten((L * aMaterialAmount) / (M * aStack.stackSize))) - .duration((int) Math.max(1, (24 * aMaterialAmount) / M)) - .eut(Math.max(8, (int) Math.sqrt(2 * aMaterial.mSmeltInto.mStandardMoltenFluid.getTemperature()))) - .addTo(sFluidExtractionRecipes); - } else { - RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, aStack)) - .fluidOutputs(aMaterial.mSmeltInto.getMolten((L * aMaterialAmount) / (M * aStack.stackSize))) - .duration((int) Math.max(1, (24 * aMaterialAmount) / M)) - .eut(Math.max(8, (int) Math.sqrt(2 * aMaterial.mSmeltInto.mStandardMoltenFluid.getTemperature()))) - .addTo(sFluidExtractionRecipes); + builder.itemOutputs(recipeOutput); } + builder.fluidOutputs(aMaterial.mSmeltInto.getMolten((L * aMaterialAmount) / (M * aStack.stackSize))) + .duration((int) Math.max(1, (24 * aMaterialAmount) / M)) + .eut(Math.max(8, (int) Math.sqrt(2 * aMaterial.mSmeltInto.mStandardMoltenFluid.getTemperature()))) + .recipeCategory(RecipeCategories.fluidExtractorRecycling) + .addTo(fluidExtractionRecipes); } /** @@ -259,11 +246,10 @@ public class GT_RecipeRegistrator { aMaterialAmount /= aStack.stackSize; - boolean tHide = (aMaterial != Materials.Iron) && (GT_Mod.gregtechproxy.mHideRecyclingRecipes); if (aAllowAlloySmelter) GT_ModHandler.addSmeltingAndAlloySmeltingRecipe( GT_Utility.copyAmount(1, aStack), GT_OreDictUnificator.getIngot(aMaterial.mSmeltInto, aMaterialAmount), - tHide); + false); else GT_ModHandler.addSmeltingRecipe( GT_Utility.copyAmount(1, aStack), GT_OreDictUnificator.getIngot(aMaterial.mSmeltInto, aMaterialAmount)); @@ -285,12 +271,19 @@ public class GT_RecipeRegistrator { aData = new ItemData(aData); if (!aData.hasValidMaterialData()) return; - boolean tIron = false; + boolean isRecycle = true; for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { if (tMaterial.mMaterial == Materials.Iron || tMaterial.mMaterial == Materials.Copper || tMaterial.mMaterial == Materials.WroughtIron - || tMaterial.mMaterial == Materials.AnnealedCopper) tIron = true; + || tMaterial.mMaterial == Materials.AnnealedCopper) { + ItemData stackData = GT_OreDictUnificator.getItemData(aStack); + if (stackData != null + && (stackData.mPrefix == OrePrefixes.ingot || stackData.mPrefix == OrePrefixes.dust)) { + // iron ingot/dust -> wrought iron, copper ingot/dust -> annealed copper + isRecycle = false; + } + } if (tMaterial.mMaterial.contains(SubTag.UNBURNABLE)) { tMaterial.mMaterial = tMaterial.mMaterial.mSmeltInto.mArcSmeltInto; @@ -334,7 +327,6 @@ public class GT_RecipeRegistrator { for (MaterialStack tMaterial : aData.getAllMaterialStacks()) tAmount += tMaterial.mAmount * tMaterial.mMaterial.getMass(); - boolean tHide = !tIron && GT_Mod.gregtechproxy.mHideRecyclingRecipes; ArrayList<ItemStack> outputs = new ArrayList<>(); if (GT_OreDictUnificator.getIngotOrDust(aData.mMaterial) != null) { outputs.add(GT_OreDictUnificator.getIngotOrDust(aData.mMaterial)); @@ -344,18 +336,15 @@ public class GT_RecipeRegistrator { outputs.add(GT_OreDictUnificator.getIngotOrDust(aData.getByProduct(i))); } } - if (outputs.size() != 0) { - ItemStack[] outputsArray = outputs.toArray(new ItemStack[0]); + if (!outputs.isEmpty()) { GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder(); recipeBuilder.itemInputs(aStack) - .itemOutputs(outputsArray) + .itemOutputs(outputs.toArray(new ItemStack[0])) .fluidInputs(Materials.Oxygen.getGas((int) Math.max(16, tAmount / M))) .duration(((int) Math.max(16, tAmount / M)) * TICKS) - .eut(90); - if (tHide) { - recipeBuilder.hidden(); - } - recipeBuilder.addTo(UniversalArcFurnace); + .eut(90) + .metadata(RECYCLE, isRecycle) + .addTo(UniversalArcFurnace); } } @@ -391,8 +380,6 @@ public class GT_RecipeRegistrator { } { - boolean tHide = (aData.mMaterial.mMaterial != Materials.Iron) - && (GT_Mod.gregtechproxy.mHideRecyclingRecipes); ArrayList<ItemStack> outputs = new ArrayList<>(); if (GT_OreDictUnificator.getDust(aData.mMaterial) != null) { outputs.add(GT_OreDictUnificator.getDust(aData.mMaterial)); @@ -402,18 +389,16 @@ public class GT_RecipeRegistrator { outputs.add(GT_OreDictUnificator.getDust(aData.getByProduct(i))); } } - if (outputs.size() != 0) { + if (!outputs.isEmpty()) { ItemStack[] outputsArray = outputs.toArray(new ItemStack[0]); GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder(); recipeBuilder.itemInputs(aStack) .itemOutputs(outputsArray) .duration( (aData.mMaterial.mMaterial == Materials.Marble ? 1 : (int) Math.max(16, tAmount / M)) * TICKS) - .eut(4); - if (tHide) { - recipeBuilder.hidden(); - } - recipeBuilder.addTo(sMaceratorRecipes); + .eut(4) + .recipeCategory(RecipeCategories.maceratorRecycling) + .addTo(maceratorRecipes); } } @@ -430,8 +415,8 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.getDust(aData.mMaterial)) .duration(10 * SECONDS) .eut(TierEU.RECIPE_LV) - .addTo(sHammerRecipes); - + .recipeCategory(RecipeCategories.forgeHammerRecycling) + .addTo(hammerRecipes); break; } } @@ -687,7 +672,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, multiplier)) .duration(baseDuration * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix1, aMaterial, 2L / multiplier), @@ -695,7 +680,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt02, aMaterial, 1L)) .duration(((int) (baseDuration * 1.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix1, aMaterial, 4L / multiplier), @@ -703,7 +688,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt04, aMaterial, 1L)) .duration(baseDuration * 2 * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix1, aMaterial, 8L / multiplier), @@ -711,7 +696,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt08, aMaterial, 1L)) .duration(((int) (baseDuration * 2.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix1, aMaterial, 12L / multiplier), @@ -719,7 +704,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt12, aMaterial, 1L)) .duration(baseDuration * 3 * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix1, aMaterial, 16L / multiplier), @@ -727,7 +712,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt16, aMaterial, 1L)) .duration(((int) (baseDuration * 3.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); } if (GT_OreDictUnificator.get(prefix2, aMaterial, 1L) != null @@ -737,7 +722,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 2L / multiplier)) .duration(((int) (baseDuration * 0.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix2, aMaterial, 4L / multiplier), @@ -745,7 +730,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt02, aMaterial, 1L)) .duration(baseDuration * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix2, aMaterial, 8L / multiplier), @@ -753,7 +738,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt04, aMaterial, 1L)) .duration(((int) (baseDuration * 1.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix2, aMaterial, 16L / multiplier), @@ -761,7 +746,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt08, aMaterial, 1L)) .duration(baseDuration * 2 * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix2, aMaterial, 24L / multiplier), @@ -769,7 +754,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt12, aMaterial, 1L)) .duration(((int) (baseDuration * 2.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); GT_Values.RA.stdBuilder() .itemInputs( GT_OreDictUnificator.get(prefix2, aMaterial, 32L / multiplier), @@ -777,7 +762,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt16, aMaterial, 1L)) .duration(baseDuration * 3 * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); } if (GT_OreDictUnificator.get(prefix1, aMaterial, 1L) != null && GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 1L) != null) { @@ -786,7 +771,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 4L * multiplier)) .duration(baseDuration * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); } if (GT_OreDictUnificator.get(prefix2, aMaterial, 1L) != null && GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 1L) != null) { @@ -795,7 +780,7 @@ public class GT_RecipeRegistrator { .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 2L * multiplier)) .duration(((int) (baseDuration * 0.5f)) * TICKS) .eut(aEUt) - .addTo(sWiremillRecipes); + .addTo(wiremillRecipes); } } diff --git a/src/main/java/gregtech/api/util/GT_StreamUtil.java b/src/main/java/gregtech/api/util/GT_StreamUtil.java new file mode 100644 index 0000000000..c29e611c4e --- /dev/null +++ b/src/main/java/gregtech/api/util/GT_StreamUtil.java @@ -0,0 +1,44 @@ +package gregtech.api.util; + +import java.util.Arrays; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public final class GT_StreamUtil { + + /** + * Backport of {@link Stream#ofNullable}. + */ + public static <T> Stream<T> ofNullable(@Nullable T value) { + return value == null ? Stream.empty() : Stream.of(value); + } + + /** + * Returns a sequential ordered {@code Stream} whose elements are the specified values, + * if {@code condition} is true, otherwise returns an empty {@code Stream}. + * + * @param <T> the type of stream elements + * @param values the elements of the new stream + * @return the new stream + */ + public static <T> Stream<T> ofConditional(boolean condition, T[] values) { + return condition ? Arrays.stream(values) : Stream.empty(); + } + + /** + * Returns a sequential {@code Stream} containing a single element, which will be lazily evaluated from supplier. + * + * @param <T> the type of stream elements + * @param supplier the supplier for single stream element + * @return the new stream + */ + public static <T> Stream<T> ofSupplier(Supplier<T> supplier) { + return Stream.generate(supplier) + .limit(1); + } +} diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java index 755dc0286e..13ce66ddbf 100644 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ b/src/main/java/gregtech/api/util/GT_Utility.java @@ -115,6 +115,7 @@ import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; +import com.google.common.collect.SetMultimap; import com.gtnewhorizon.structurelib.alignment.IAlignment; import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; import com.mojang.authlib.GameProfile; @@ -158,6 +159,7 @@ import gregtech.api.objects.CollectorUtils; import gregtech.api.objects.GT_ItemStack; import gregtech.api.objects.GT_ItemStack2; import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeMaps; import gregtech.api.threads.GT_Runnable_Sound; import gregtech.api.util.extensions.ArrayExt; import gregtech.common.GT_Pollution; @@ -500,14 +502,6 @@ public class GT_Utility { } /** - * Do not use. It is rounding up voltage - */ - @Deprecated - public static long roundDownVoltage(long voltage) { - return roundUpVoltage(voltage); - } - - /** * Rounds up partial voltage that exceeds tiered voltage, e.g. 4,096 -> 8,192(IV) */ public static long roundUpVoltage(long voltage) { @@ -3133,6 +3127,20 @@ public class GT_Utility { return aMap; } + /** + * re-maps all Keys of a Map after the Keys were weakened. + */ + public static <X, Y> SetMultimap<X, Y> reMap(SetMultimap<X, Y> aMap) { + @SuppressWarnings("unchecked") + Map.Entry<X, Y>[] entries = aMap.entries() + .toArray(new Map.Entry[0]); + aMap.clear(); + for (Map.Entry<X, Y> entry : entries) { + aMap.put(entry.getKey(), entry.getValue()); + } + return aMap; + } + public static <X, Y extends Comparable<Y>> LinkedHashMap<X, Y> sortMapByValuesAcending(Map<X, Y> map) { return map.entrySet() .stream() @@ -4866,7 +4874,8 @@ public class GT_Utility { public static int getPlasmaFuelValueInEUPerLiterFromFluid(FluidStack aLiquid) { if (aLiquid == null) return 0; - GT_Recipe tFuel = GT_Recipe.GT_Recipe_Map.sPlasmaFuels.findFuel(aLiquid); + GT_Recipe tFuel = RecipeMaps.plasmaFuels.getBackend() + .findFuel(aLiquid); if (tFuel != null) return tFuel.mSpecialValue; return 0; } diff --git a/src/main/java/gregtech/api/util/MethodsReturnNonnullByDefault.java b/src/main/java/gregtech/api/util/MethodsReturnNonnullByDefault.java new file mode 100644 index 0000000000..2b2c310695 --- /dev/null +++ b/src/main/java/gregtech/api/util/MethodsReturnNonnullByDefault.java @@ -0,0 +1,22 @@ +package gregtech.api.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierDefault; + +/** + * This annotation can be applied to a package or class to indicate that + * the methods in that element are nonnull by default unless there is: + * <ul> + * <li>An explicit nullness annotation + * <li>The method overrides a method in a superclass (in which case the + * annotation of the corresponding method in the superclass applies) + * </ul> + */ +@Nonnull +@TypeQualifierDefault({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface MethodsReturnNonnullByDefault {} diff --git a/src/main/java/gregtech/api/util/VoidProtectionHelper.java b/src/main/java/gregtech/api/util/VoidProtectionHelper.java index 67e412bc83..440d8e63ef 100644 --- a/src/main/java/gregtech/api/util/VoidProtectionHelper.java +++ b/src/main/java/gregtech/api/util/VoidProtectionHelper.java @@ -13,7 +13,6 @@ import com.gtnewhorizon.gtnhlib.util.map.ItemStackMap; import gregtech.api.interfaces.fluid.IFluidStore; import gregtech.api.interfaces.tileentity.IVoidable; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase; /** * Helper class to calculate how many parallels of items / fluids can fit in the output buses / hatches. @@ -52,27 +51,6 @@ public class VoidProtectionHelper { public VoidProtectionHelper() {} /** - * Sets MetaTE controller, with current configuration for void protection mode. - * - * @deprecated Use {@link #setMachine(IVoidable)} - */ - @Deprecated - public VoidProtectionHelper setController(GT_MetaTileEntity_MultiBlockBase machineMeta) { - return setMachine(machineMeta, machineMeta.protectsExcessItem(), machineMeta.protectsExcessFluid()); - } - - /** - * Sets MetaTE controller, with void protection mode forcibly. - * - * @deprecated Use {@link #setMachine(IVoidable, boolean, boolean)} - */ - @Deprecated - public VoidProtectionHelper setController(GT_MetaTileEntity_MultiBlockBase machineMeta, boolean protectExcessItem, - boolean protectExcessFluid) { - return setMachine(machineMeta, protectExcessItem, protectExcessFluid); - } - - /** * Sets machine, with current configuration for void protection mode. */ public VoidProtectionHelper setMachine(IVoidable machine) { |