package gregtech.api.util;
import static gregtech.GT_Mod.GT_FML_LOGGER;
import static gregtech.api.enums.GT_Values.B;
import static gregtech.api.enums.GT_Values.D1;
import static gregtech.api.enums.GT_Values.DW;
import static gregtech.api.enums.GT_Values.E;
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.recipe.RecipeMaps.alloySmelterRecipes;
import static gregtech.api.recipe.RecipeMaps.oreWasherRecipes;
import static gregtech.api.util.GT_RecipeBuilder.SECONDS;
import static gregtech.api.util.GT_RecipeBuilder.TICKS;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.ShapedOreRecipe;
import net.minecraftforge.oredict.ShapelessOreRecipe;
import cpw.mods.fml.common.registry.GameRegistry;
import gregtech.api.GregTech_API;
import gregtech.api.enums.GT_Values;
import gregtech.api.enums.ItemList;
import gregtech.api.enums.Materials;
import gregtech.api.enums.OreDictNames;
import gregtech.api.enums.OrePrefixes;
import gregtech.api.enums.ToolDictNames;
import gregtech.api.interfaces.IDamagableItem;
import gregtech.api.interfaces.IItemContainer;
import gregtech.api.interfaces.internal.IGT_CraftingRecipe;
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;
import ic2.api.reactor.IReactorComponent;
import ic2.api.recipe.IRecipeInput;
import ic2.api.recipe.RecipeInputItemStack;
import ic2.api.recipe.RecipeOutput;
import ic2.core.item.ItemToolbox;
/**
* NEVER INCLUDE THIS FILE IN YOUR MOD!!!
*
* This is the Interface I use for interacting with other Mods.
*
* Due to the many imports, this File can cause compile Problems if not all the APIs are installed
*/
public class GT_ModHandler {
public static final List sSingleNonBlockDamagableRecipeList = new ArrayList<>(1000);
private static final Map sIC2ItemMap = new HashMap<>();
// public for bartworks
public static final List sAllRecipeList = new ArrayList<>(5000), sBufferRecipeList = new ArrayList<>(1000);
private static final List delayedRemovalByOutput = new ArrayList<>();
private static final List delayedRemovalByRecipe = new ArrayList<>();
public static Collection sNativeRecipeClasses = new HashSet<>(), sSpecialRecipeClasses = new HashSet<>();
public static GT_HashSet sNonReplaceableItems = new GT_HashSet<>();
public static Object sBoxableWrapper = new GT_IBoxableWrapper();
public static Collection sBoxableItems = new ArrayList<>();
private static final Map emptyRecipeMap = new HashMap<>();
private static Set recyclerWhitelist;
private static Set recyclerBlacklist;
private static boolean sBufferCraftingRecipes = true;
public static List sSingleNonBlockDamagableRecipeList_list = new ArrayList<>(100);
private static final boolean sSingleNonBlockDamagableRecipeList_create = true;
private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0);
private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R";
private static final ItemStack[][] sShapes1 = new ItemStack[][] {
{ sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null },
{ sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1 },
{ null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1 },
{ sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null },
{ sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1 },
{ sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1 },
{ null, null, null, sMt1, null, sMt1, sMt1, null, sMt1 },
{ null, sMt1, null, null, sMt1, null, null, sMt2, null },
{ sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null },
{ null, sMt1, null, null, sMt2, null, null, sMt2, null },
{ sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null },
{ null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null },
{ sMt1, sMt1, null, null, sMt2, null, null, sMt2, null },
{ null, sMt1, sMt1, null, sMt2, null, null, sMt2, null },
{ null, sMt1, null, sMt1, null, null, null, sMt1, sMt2 },
{ null, sMt1, null, null, null, sMt1, sMt2, sMt1, null },
{ null, sMt1, null, sMt1, null, sMt1, null, null, sMt2 },
{ null, sMt1, null, sMt1, null, sMt1, sMt2, null, null },
{ null, sMt2, null, null, sMt1, null, null, sMt1, null },
{ null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1 },
{ null, sMt2, null, null, sMt2, null, null, sMt1, null },
{ null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null },
{ null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1 },
{ null, sMt2, null, null, sMt2, null, sMt1, sMt1, null },
{ sMt1, null, null, null, sMt2, null, null, null, sMt2 },
{ null, null, sMt1, null, sMt2, null, sMt2, null, null },
{ sMt1, null, null, null, sMt2, null, null, null, null },
{ null, null, sMt1, null, sMt2, null, null, null, null },
{ sMt1, sMt2, null, null, null, null, null, null, null },
{ sMt2, sMt1, null, null, null, null, null, null, null },
{ sMt1, null, null, sMt2, null, null, null, null, null },
{ sMt2, null, null, sMt1, null, null, null, null, null },
{ sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null },
{ sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null },
{ null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1 },
{ null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1 },
{ sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null },
{ sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null },
{ null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1 },
{ null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1 },
{ sMt1, null, null, null, sMt1, null, null, null, null },
{ null, sMt1, null, sMt1, null, null, null, null, null },
{ sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null },
{ null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2 } };
public static List sSingleNonBlockDamagableRecipeList_validsShapes1 = new ArrayList<>(44);
public static boolean sSingleNonBlockDamagableRecipeList_validsShapes1_update = false;
public static List sSingleNonBlockDamagableRecipeList_warntOutput = new ArrayList<>(50);
public static List sVanillaRecipeList_warntOutput = new ArrayList<>(50);
public static final List sSingleNonBlockDamagableRecipeList_verified = new ArrayList<>(1000);
public static List sAnySteamFluidIDs = new ArrayList<>();
public static List sSuperHeatedSteamFluidIDs = new ArrayList<>();
static {
sNativeRecipeClasses.add(ShapedRecipes.class.getName());
sNativeRecipeClasses.add(ShapedOreRecipe.class.getName());
sNativeRecipeClasses.add(GT_Shaped_Recipe.class.getName());
sNativeRecipeClasses.add(ShapelessRecipes.class.getName());
sNativeRecipeClasses.add(ShapelessOreRecipe.class.getName());
sNativeRecipeClasses.add(GT_Shapeless_Recipe.class.getName());
sNativeRecipeClasses.add(ic2.core.AdvRecipe.class.getName());
sNativeRecipeClasses.add(ic2.core.AdvShapelessRecipe.class.getName());
sNativeRecipeClasses.add("appeng.recipes.game.ShapedRecipe");
sNativeRecipeClasses.add("appeng.recipes.game.ShapelessRecipe");
sNativeRecipeClasses.add("forestry.core.utils.ShapedRecipeCustom");
// Recipe Classes, which should never be removed.
sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipeFireworks.class.getName());
sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesArmorDyes.class.getName());
sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipeBookCloning.class.getName());
sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesMapCloning.class.getName());
sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesMapExtending.class.getName());
sSpecialRecipeClasses.add("jds.bibliocraft.BiblioSpecialRecipes");
sSpecialRecipeClasses.add("dan200.qcraft.shared.EntangledQBlockRecipe");
sSpecialRecipeClasses.add("dan200.qcraft.shared.EntangledQuantumComputerRecipe");
sSpecialRecipeClasses.add("dan200.qcraft.shared.QBlockRecipe");
sSpecialRecipeClasses.add("appeng.recipes.game.FacadeRecipe");
sSpecialRecipeClasses.add("appeng.recipes.game.DisassembleRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.carts.LocomotivePaintingRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RotorRepairRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RoutingTableCopyRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RoutingTicketCopyRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.TankCartFilterRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.emblems.LocomotiveEmblemRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.emblems.EmblemPostColorRecipe");
sSpecialRecipeClasses.add("mods.railcraft.common.emblems.EmblemPostEmblemRecipe");
sSpecialRecipeClasses.add("mods.immibis.redlogic.interaction.RecipeDyeLumarButton");
sSpecialRecipeClasses.add("thaumcraft.common.items.armor.RecipesRobeArmorDyes");
sSpecialRecipeClasses.add("thaumcraft.common.items.armor.RecipesVoidRobeArmorDyes");
sSpecialRecipeClasses.add("thaumcraft.common.lib.crafting.ShapelessNBTOreRecipe");
sSpecialRecipeClasses.add("twilightforest.item.TFMapCloningRecipe");
sSpecialRecipeClasses.add("forestry.lepidopterology.MatingRecipe");
sSpecialRecipeClasses.add("micdoodle8.mods.galacticraft.planets.asteroids.recipe.CanisterRecipes");
sSpecialRecipeClasses.add("shedar.mods.ic2.nuclearcontrol.StorageArrayRecipe");
}
/**
* Returns if that Liquid is Water or Distilled Water
*/
public static boolean isWater(FluidStack aFluid) {
if (aFluid == null) return false;
return aFluid.isFluidEqual(getWater(1)) || aFluid.isFluidEqual(getDistilledWater(1));
}
/**
* Returns a Liquid Stack with given amount of Water.
*/
public static FluidStack getWater(long aAmount) {
return FluidRegistry.getFluidStack("water", (int) aAmount);
}
/**
* Returns a Liquid Stack with given amount of distilled Water.
*/
public static FluidStack getDistilledWater(long aAmount) {
FluidStack tFluid = FluidRegistry.getFluidStack("ic2distilledwater", (int) aAmount);
if (tFluid == null) tFluid = getWater(aAmount);
return tFluid;
}
/**
* Returns if that Liquid is Lava
*/
public static boolean isLava(FluidStack aFluid) {
if (aFluid == null) return false;
return aFluid.isFluidEqual(getLava(1));
}
/**
* Returns a Liquid Stack with given amount of Lava.
*/
public static FluidStack getLava(long aAmount) {
return FluidRegistry.getFluidStack("lava", (int) aAmount);
}
/**
* Returns if that Liquid is Steam
*/
public static boolean isSteam(FluidStack aFluid) {
if (aFluid == null) return false;
return aFluid.isFluidEqual(getSteam(1));
}
/**
* Returns if that Liquid is Any Steam (including other mods)
*/
public static boolean isAnySteam(FluidStack aFluid) {
return (aFluid != null && (isSteam(aFluid) || sAnySteamFluidIDs.contains(aFluid.getFluidID())));
}
/**
* Returns if that Liquid is Super Heated Steam (including other mods)
*/
public static boolean isSuperHeatedSteam(FluidStack aFluid) {
return (aFluid != null && sSuperHeatedSteamFluidIDs.contains(aFluid.getFluidID()));
}
/**
* Returns a Liquid Stack with given amount of Steam.
*/
public static FluidStack getSteam(long aAmount) {
return FluidRegistry.getFluidStack("steam", (int) aAmount);
}
/**
* Returns if that Liquid is Milk
*/
public static boolean isMilk(FluidStack aFluid) {
if (aFluid == null) return false;
return aFluid.isFluidEqual(getMilk(1));
}
/**
* Returns a Liquid Stack with given amount of Milk.
*/
public static FluidStack getMilk(long aAmount) {
return FluidRegistry.getFluidStack("milk", (int) aAmount);
}
@Deprecated
public static ItemStack getEmptyFuelCan(long aAmount) {
return null;
}
public static ItemStack getEmptyCell(long aAmount) {
return ItemList.Cell_Empty.get(aAmount);
}
public static ItemStack getAirCell(long aAmount) {
return ItemList.Cell_Air.get(aAmount);
}
public static ItemStack getWaterCell(long aAmount) {
return ItemList.Cell_Water.get(aAmount);
}
public static ItemStack getLavaCell(long aAmount) {
return ItemList.Cell_Lava.get(aAmount);
}
/**
* @param aValue the Value of this Stack, when burning inside a Furnace (200 = 1 Burn Process = 500 EU, max = 32767
* (that is 81917.5 EU)), limited to Short because the vanilla Furnace otherwise can't handle it
* properly, stupid Mojang...
*/
public static ItemStack setFuelValue(ItemStack aStack, short aValue) {
aStack.setTagCompound(GT_Utility.getNBTContainingShort(aStack.getTagCompound(), "GT.ItemFuelValue", aValue));
return aStack;
}
/**
* @return the Value of this Stack, when burning inside a Furnace (200 = 1 Burn Process = 500 EU, max = 32767 (that
* is 81917.5 EU)), limited to Short because the vanilla Furnace otherwise can't handle it properly, stupid
* Mojang...
*/
public static int getFuelValue(ItemStack aStack) {
return TileEntityFurnace.getItemBurnTime(aStack);
}
/**
* @param aValue Fuel value in EU
*/
@Deprecated
public static ItemStack getFuelCan(int aValue) {
return null;
}
/**
* @param aFuelCan the Item you want to check
* @return the exact Value in EU the Fuel Can is worth if its even a Fuel Can.
*/
@Deprecated
public static int getFuelCanValue(ItemStack aFuelCan) {
return 0;
}
/**
* Gets an Item from IndustrialCraft, and returns a Replacement Item if not possible
*/
public static ItemStack getIC2Item(String aItem, long aAmount, ItemStack aReplacement) {
if (GT_Utility.isStringInvalid(aItem) || !GregTech_API.sPreloadStarted) return null;
// if (D1) GT_Log.out.println("Requested the Item '" + aItem + "' from the IC2-API");
if (!sIC2ItemMap.containsKey(aItem)) try {
ItemStack tStack = IC2Items.getItem(aItem);
sIC2ItemMap.put(aItem, tStack);
if (tStack == null && D1) GT_Log.err.println(aItem + " is not found in the IC2 Items!");
} catch (Throwable e) {
/* Do nothing */
}
return GT_Utility.copyAmount(aAmount, sIC2ItemMap.get(aItem), aReplacement);
}
/**
* Gets an Item from IndustrialCraft, but the Damage Value can be specified, and returns a Replacement Item with the
* same Damage if not possible
*/
public static ItemStack getIC2Item(String aItem, long aAmount, int aMeta, ItemStack aReplacement) {
ItemStack rStack = getIC2Item(aItem, aAmount, aReplacement);
if (rStack == null) return null;
Items.feather.setDamage(rStack, aMeta);
return rStack;
}
/**
* Gets an Item from IndustrialCraft, but the Damage Value can be specified
*/
public static ItemStack getIC2Item(String aItem, long aAmount, int aMeta) {
return getIC2Item(aItem, aAmount, aMeta, null);
}
/**
* Gets an Item from IndustrialCraft
*/
public static ItemStack getIC2Item(String aItem, long aAmount) {
return getIC2Item(aItem, aAmount, null);
}
/**
* Gets an Item from the specified mod
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount) {
return getModItem(aModID, aItem, aAmount, null);
}
/**
* Gets an Item from the specified mod, and returns a Replacement Item if not possible
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount, ItemStack aReplacement) {
ItemStack result;
if (GT_Utility.isStringInvalid(aItem) || !GregTech_API.sPreloadStarted) {
result = null;
} else {
result = GT_Utility
.copyAmount(aAmount, GameRegistry.findItemStack(aModID, aItem, (int) aAmount), aReplacement);
}
if (result == null) {
String reason;
if (GT_Utility.isStringInvalid(aItem)) {
reason = "the name of the item is an invalid string";
} else if (!GregTech_API.sPreloadStarted) {
reason = "the GT5U preloading phase has not yet started";
} else {
reason = "the item was not found in the game registry";
}
String log_message = "getModItem call: object \"" + aItem
+ "\" with mod id \""
+ aModID
+ "\" has returned null because "
+ reason;
GT_Log.out.println(log_message);
new Exception().printStackTrace(GT_Log.out);
}
return result;
}
/**
* Gets an Item from the specified mod, but the Damage Value can be specified
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta) {
ItemStack rStack = getModItem(aModID, aItem, aAmount);
if (rStack == null) return null;
Items.feather.setDamage(rStack, aMeta);
return rStack;
}
/**
* Gets an Item from the specified mod, but the Damage Value can be specified, and returns a Replacement Item with
* the same Damage if not possible
*/
public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta, ItemStack aReplacement) {
ItemStack rStack = getModItem(aModID, aItem, aAmount, aReplacement);
if (rStack == null) return null;
Items.feather.setDamage(rStack, aMeta);
return rStack;
}
/**
* OUT OF ORDER
*/
@Deprecated
public static boolean getModeKeyDown(EntityPlayer aPlayer) {
return false;
}
/**
* OUT OF ORDER
*/
@Deprecated
public static boolean getBoostKeyDown(EntityPlayer aPlayer) {
return false;
}
/**
* OUT OF ORDER
*/
@Deprecated
public static boolean getJumpKeyDown(EntityPlayer aPlayer) {
return false;
}
/**
* Adds a Valuable Ore to the Miner
*/
public static boolean addValuableOre(Block aBlock, int aMeta, int aValue) {
if (aValue <= 0) return false;
try {
Class.forName("ic2.core.IC2")
.getMethod("addValuableOre", IRecipeInput.class, int.class)
.invoke(null, new RecipeInputItemStack(new ItemStack(aBlock, 1, aMeta)), aValue);
} catch (Throwable e) {
/* Do nothing */
}
return true;
}
/**
* Adds a Scrapbox Drop. Fails at April first for the "suddenly Hoes"-Feature of IC2
*/
public static boolean addScrapboxDrop(float aChance, ItemStack aOutput) {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aOutput == null || aChance <= 0) return false;
aOutput.stackSize = 1;
if (GT_Config.troll && !GT_Utility.areStacksEqual(aOutput, new ItemStack(Items.wooden_hoe, 1, 0))) return false;
try {
GT_Utility.callMethod(
GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true),
"addDrop",
true,
false,
true,
GT_Utility.copyOrNull(aOutput),
aChance);
GT_Utility.callMethod(
GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true),
"addRecipe",
true,
true,
false,
GT_Utility.copyOrNull(aOutput),
aChance);
} catch (Throwable e) {
/* Do nothing */
}
return true;
}
/**
* Adds an Item to the Recycler Blacklist
*/
public static boolean addToRecyclerBlackList(ItemStack aRecycledStack) {
if (aRecycledStack == null) return false;
try {
ic2.api.recipe.Recipes.recyclerBlacklist.add(new RecipeInputItemStack(aRecycledStack));
} catch (Throwable e) {
/* Do nothing */
}
return true;
}
/**
* Just simple Furnace smelting. Unbelievable how Minecraft fails at making a simple ItemStack->ItemStack mapping...
*/
public static boolean addSmeltingRecipe(ItemStack aInput, ItemStack aOutput) {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aInput == null || aOutput == null) return false;
FurnaceRecipes.smelting()
.func_151394_a(aInput, GT_Utility.copyOrNull(aOutput), 0.0F);
return true;
}
/**
* Adds to Furnace AND Alloy Smelter
*/
public static boolean addSmeltingAndAlloySmeltingRecipe(ItemStack aInput, ItemStack aOutput, boolean hidden) {
if (aInput == null || aOutput == null) {
return false;
}
boolean temp = aInput.stackSize == 1 && addSmeltingRecipe(aInput, aOutput);
ItemStack input2 = OrePrefixes.ingot.contains(aOutput) ? ItemList.Shape_Mold_Ingot.get(0)
: OrePrefixes.block.contains(aOutput) ? ItemList.Shape_Mold_Block.get(0)
: OrePrefixes.nugget.contains(aOutput) ? ItemList.Shape_Mold_Nugget.get(0) : null;
if (Materials.Graphite.contains(aInput)) {
return false;
}
if ((input2 == null) && ((OrePrefixes.ingot.contains(aInput)) || (OrePrefixes.dust.contains(aInput))
|| (OrePrefixes.gem.contains(aInput)))) {
return false;
}
GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder();
if (input2 == null) {
recipeBuilder.itemInputs(aInput);
} else {
recipeBuilder.itemInputs(aInput, input2);
}
recipeBuilder.itemOutputs(aOutput)
.duration(6 * SECONDS + 10 * TICKS)
.eut(3)
.recipeCategory(RecipeCategories.alloySmelterRecycling);
if (hidden) {
recipeBuilder.hidden();
}
recipeBuilder.addTo(alloySmelterRecipes);
return true;
}
/**
* Adds GT versions of the IC2 recipes from the supplied IC2RecipeList.
*/
public static void addIC2RecipesToGT(Map aIC2RecipeList, RecipeMap> aGTRecipeMap,
boolean aAddGTRecipe, boolean aRemoveIC2Recipe, boolean aExcludeGTIC2Items) {
Map aRecipesToRemove = new HashMap<>();
for (Entry iRecipeInputRecipeOutputEntry : aIC2RecipeList.entrySet()) {
if (iRecipeInputRecipeOutputEntry.getValue().items.isEmpty()) {
continue;
}
for (ItemStack tStack : (iRecipeInputRecipeOutputEntry.getKey()).getInputs()) {
if (!GT_Utility.isStackValid(tStack)) {
continue;
}
if (aAddGTRecipe) {
try {
if (aExcludeGTIC2Items && ((tStack.getUnlocalizedName()
.contains("gt.metaitem.01")
|| tStack.getUnlocalizedName()
.contains("gt.blockores")
|| tStack.getUnlocalizedName()
.contains("ic2.itemCrushed")
|| tStack.getUnlocalizedName()
.contains("ic2.itemPurifiedCrushed"))))
continue;
switch (aGTRecipeMap.unlocalizedName) {
case "gt.recipe.macerator", "gt.recipe.extractor", "gt.recipe.compressor" -> GT_Values.RA
.stdBuilder()
.itemInputs(
GT_Utility.copyAmount(
iRecipeInputRecipeOutputEntry.getKey()
.getAmount(),
tStack))
.itemOutputs(iRecipeInputRecipeOutputEntry.getValue().items.toArray(new ItemStack[0]))
.duration(15 * SECONDS)
.eut(2)
.addTo(aGTRecipeMap);
case "gt.recipe.thermalcentrifuge" -> GT_Values.RA.stdBuilder()
.itemInputs(
GT_Utility.copyAmount(
iRecipeInputRecipeOutputEntry.getKey()
.getAmount(),
tStack))
.itemOutputs(iRecipeInputRecipeOutputEntry.getValue().items.toArray(new ItemStack[0]))
.duration(25 * SECONDS)
.eut(48)
.addTo(aGTRecipeMap);
}
} catch (Exception e) {
e.printStackTrace(GT_Log.err);
}
}
if (aRemoveIC2Recipe) {
aRecipesToRemove.put(tStack, iRecipeInputRecipeOutputEntry.getValue().items.get(0));
}
}
}
GT_Utility.bulkRemoveSimpleIC2MachineRecipe(aRecipesToRemove, aIC2RecipeList);
}
public static Map getExtractorRecipeList() {
try {
return ic2.api.recipe.Recipes.extractor.getRecipes();
} catch (Throwable e) {
/* Do nothing */
}
return emptyRecipeMap;
}
public static Map getCompressorRecipeList() {
try {
return ic2.api.recipe.Recipes.compressor.getRecipes();
} catch (Throwable e) {
/* Do nothing */
}
return emptyRecipeMap;
}
public static Map getMaceratorRecipeList() {
try {
return ic2.api.recipe.Recipes.macerator.getRecipes();
} catch (Throwable e) {
/* Do nothing */
}
return emptyRecipeMap;
}
public static Map getThermalCentrifugeRecipeList() {
try {
return ic2.api.recipe.Recipes.centrifuge.getRecipes();
} catch (Throwable e) {
/* Do nothing */
}
return emptyRecipeMap;
}
public static Map getOreWashingRecipeList() {
try {
return ic2.api.recipe.Recipes.oreWashing.getRecipes();
} catch (Throwable e) {
/* Do nothing */
}
return emptyRecipeMap;
}
/**
* IC2-OreWasher Recipe. Overloads old Recipes automatically
*/
@Deprecated
public static boolean addOreWasherRecipe(ItemStack aInput, int[] aChances, int aWaterAmount, Object... aOutput) {
if (aInput == null || aOutput == null || aOutput.length == 0 || aOutput[0] == null) return false;
RA.stdBuilder()
.itemInputs(aInput)
.itemOutputs((ItemStack) aOutput[0], (ItemStack) aOutput[1], (ItemStack) aOutput[2])
.outputChances(aChances)
.fluidInputs(GT_ModHandler.getWater(aWaterAmount))
.duration(25 * SECONDS)
.eut(16)
.addTo(oreWasherRecipes);
RA.stdBuilder()
.itemInputs(aInput)
.itemOutputs((ItemStack) aOutput[0], (ItemStack) aOutput[1], (ItemStack) aOutput[2])
.outputChances(aChances)
.fluidInputs(GT_ModHandler.getDistilledWater(aWaterAmount / 5))
.duration(15 * SECONDS)
.eut(16)
.addTo(oreWasherRecipes);
return true;
}
public static void stopBufferingCraftingRecipes() {
sBufferCraftingRecipes = false;
bulkRemoveRecipeByOutput(delayedRemovalByOutput);
bulkRemoveByRecipe(delayedRemovalByRecipe);
sBufferRecipeList.forEach(GameRegistry::addRecipe);
delayedRemovalByOutput.clear();
delayedRemovalByRecipe.clear();
sBufferRecipeList.clear();
}
/**
* Shapeless Crafting Recipes. Deletes conflicting Recipes too.
*/
public static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded,
int[] aEnchantmentLevelsAdded, Object[] aRecipe) {
return addCraftingRecipe(
aResult,
aEnchantmentsAdded,
aEnchantmentLevelsAdded,
false,
true,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
aRecipe);
}
/**
* Regular Crafting Recipes. Deletes conflicting Recipes too.
*
* You can insert instances of IItemContainer into the Recipe Input Array directly without having to call "get(1)"
* on them.
*
* Enums are automatically getting their "name()"-Method called in order to deliver an OreDict String.
*
* Lowercase Letters are reserved for Tools. They are as follows:
*
* 'b' ToolDictNames.craftingToolBlade 'c' ToolDictNames.craftingToolCrowbar, 'd'
* ToolDictNames.craftingToolScrewdriver, 'f' ToolDictNames.craftingToolFile, 'h'
* ToolDictNames.craftingToolHardHammer, 'i' ToolDictNames.craftingToolSolderingIron, 'j'
* ToolDictNames.craftingToolSolderingMetal, 'k' ToolDictNames.craftingToolKnive 'm'
* ToolDictNames.craftingToolMortar, 'p' ToolDictNames.craftingToolDrawplate, 'r'
* ToolDictNames.craftingToolSoftHammer, 's' ToolDictNames.craftingToolSaw, 'w' ToolDictNames.craftingToolWrench,
* 'x' ToolDictNames.craftingToolWireCutter,
*/
public static boolean addCraftingRecipe(ItemStack aResult, Object[] aRecipe) {
return addCraftingRecipe(aResult, 0, aRecipe);
}
/**
* Regular Crafting Recipes. Deletes conflicting Recipes too.
*
* You can insert instances of IItemContainer into the Recipe Input Array directly without having to call "get(1)"
* on them.
*
* Enums are automatically getting their "name()"-Method called in order to deliver an OreDict String.
*
* Lowercase Letters are reserved for Tools. They are as follows:
*
* 'b' ToolDictNames.craftingToolBlade 'c' ToolDictNames.craftingToolCrowbar, 'd'
* ToolDictNames.craftingToolScrewdriver, 'f' ToolDictNames.craftingToolFile, 'h'
* ToolDictNames.craftingToolHardHammer, 'i' ToolDictNames.craftingToolSolderingIron, 'j'
* ToolDictNames.craftingToolSolderingMetal, 'k' ToolDictNames.craftingToolKnive 'm'
* ToolDictNames.craftingToolMortar, 'p' ToolDictNames.craftingToolDrawplate, 'r'
* ToolDictNames.craftingToolSoftHammer, 's' ToolDictNames.craftingToolSaw, 'w' ToolDictNames.craftingToolWrench,
* 'x' ToolDictNames.craftingToolWireCutter,
*/
public static boolean addCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) {
return addCraftingRecipe(
aResult,
new Enchantment[0],
new int[0],
(aBitMask & RecipeBits.MIRRORED) != 0,
(aBitMask & RecipeBits.BUFFERED) != 0,
(aBitMask & RecipeBits.KEEPNBT) != 0,
(aBitMask & RecipeBits.DISMANTLEABLE) != 0,
(aBitMask & RecipeBits.NOT_REMOVABLE) == 0,
(aBitMask & RecipeBits.REVERSIBLE) != 0,
(aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES) != 0,
(aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT) != 0,
(aBitMask & RecipeBits.DELETE_ALL_OTHER_SHAPED_RECIPES) != 0,
(aBitMask & RecipeBits.DELETE_ALL_OTHER_NATIVE_RECIPES) != 0,
(aBitMask & RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS) == 0,
(aBitMask & RecipeBits.ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT) != 0,
(aBitMask & RecipeBits.ONLY_ADD_IF_RESULT_IS_NOT_NULL) != 0,
aRecipe);
}
/**
* Internal realisation of the Crafting Recipe adding Process.
*/
private static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded,
int[] aEnchantmentLevelsAdded, boolean aMirrored, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable,
boolean aRemovable, boolean aReversible, boolean aRemoveAllOthersWithSameOutput,
boolean aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, boolean aRemoveAllOtherShapedsWithSameOutput,
boolean aRemoveAllOtherNativeRecipes, boolean aCheckForCollisions,
boolean aOnlyAddIfThereIsAnyRecipeOutputtingThis, boolean aOnlyAddIfResultIsNotNull, Object[] aRecipe) {
aResult = GT_OreDictUnificator.get(true, aResult);
if (aOnlyAddIfResultIsNotNull && aResult == null) return false;
if (aResult != null && Items.feather.getDamage(aResult) == W) Items.feather.setDamage(aResult, 0);
if (aRecipe == null || aRecipe.length == 0) return false;
// The renamed variable clarifies what's happening
// noinspection UnnecessaryLocalVariable
boolean tDoWeCareIfThereWasARecipe = aOnlyAddIfThereIsAnyRecipeOutputtingThis;
boolean tThereWasARecipe = false;
for (byte i = 0; i < aRecipe.length; i++) {
if (aRecipe[i] instanceof IItemContainer) aRecipe[i] = ((IItemContainer) aRecipe[i]).get(1);
else if (aRecipe[i] instanceof Enum) aRecipe[i] = ((Enum>) aRecipe[i]).name();
else if (!(aRecipe[i] == null || aRecipe[i] instanceof ItemStack
|| aRecipe[i] instanceof ItemData
|| aRecipe[i] instanceof String
|| aRecipe[i] instanceof Character)) aRecipe[i] = aRecipe[i].toString();
}
try {
StringBuilder shape = new StringBuilder(E);
int idx = 0;
if (aRecipe[idx] instanceof Boolean) {
throw new IllegalArgumentException();
}
ArrayList