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 cpw.mods.fml.common.registry.GameRegistry;
import gregtech.api.GregTech_API;
import gregtech.api.enums.ConfigCategories;
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.objects.GT_HashSet;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.objects.ItemData;
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 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.Set;
import java.util.stream.Collectors;
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;
/**
* 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<>();
private 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 volatile int VERSION = 509;
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 sExtractorRecipes = new HashMap<>();
private static final Map sMaceratorRecipes = new HashMap<>();
private static final Map sCompressorRecipes = new HashMap<>();
private static final Map sOreWashingRecipes = new HashMap<>();
private static final Map sThermalCentrifugeRecipes = new HashMap<>();
private static final Map sMassfabRecipes = new HashMap<>();
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) {
if (GT_Utility.isStringInvalid(aItem) || !GregTech_API.sPreloadStarted) return null;
return GT_Utility.copyAmount(aAmount, GameRegistry.findItemStack(aModID, aItem, (int) aAmount), aReplacement);
}
/**
* 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
*/
public static boolean getModeKeyDown(EntityPlayer aPlayer) {
return false;
}
/**
* OUT OF ORDER
*/
public static boolean getBoostKeyDown(EntityPlayer aPlayer) {
return false;
}
/**
* OUT OF ORDER
*/
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;
aChance = (float) GregTech_API.sRecipeFile.get(ConfigCategories.Machines.scrapboxdrops, aOutput, aChance);
if (aChance <= 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 || GT_Utility.getContainerItem(aInput, false) != null) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.smelting, aInput, true)) return false;
FurnaceRecipes.smelting().func_151394_a(aInput, GT_Utility.copyOrNull(aOutput), 0.0F);
return true;
}
/**
* Adds to Furnace AND Alloysmelter AND Induction Smelter
*/
public static boolean addSmeltingAndAlloySmeltingRecipe(ItemStack aInput, ItemStack aOutput, boolean hidden) {
if (aInput == null || aOutput == null) return false;
boolean temp = false;
if (aInput.stackSize == 1 && addSmeltingRecipe(aInput, aOutput)) temp = true;
return (RA.addAlloySmelterRecipe(
aInput,
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,
aOutput,
130,
3,
hidden));
}
/**
* LiquidTransposer Recipe for both directions
*/
public static boolean addLiquidTransposerRecipe(
ItemStack aEmptyContainer, FluidStack aLiquid, ItemStack aFullContainer, int aMJ) {
return true;
}
/**
* LiquidTransposer Recipe for filling Containers
*/
public static boolean addLiquidTransposerFillRecipe(
ItemStack aEmptyContainer, FluidStack aLiquid, ItemStack aFullContainer, int aMJ) {
return true;
}
/**
* LiquidTransposer Recipe for emptying Containers
*/
public static boolean addLiquidTransposerEmptyRecipe(
ItemStack aFullContainer, FluidStack aLiquid, ItemStack aEmptyContainer, int aMJ) {
return true;
}
/**
* IC2-Extractor Recipe. Overloads old Recipes automatically
*/
public static boolean addExtractionRecipe(ItemStack aInput, ItemStack aOutput) {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aInput == null || aOutput == null) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.extractor, aInput, true)) return false;
RA.addExtractorRecipe(aInput, aOutput, 300, 2);
return true;
}
/**
* RC-BlastFurnace Recipes
*/
@Deprecated
public static boolean addRCBlastFurnaceRecipe(ItemStack aInput, ItemStack aOutput, int aTime) {
return true;
}
public static boolean addPulverisationRecipe(ItemStack aInput, ItemStack aOutput1) {
return addPulverisationRecipe(aInput, aOutput1, null, 0, false);
}
public static boolean addPulverisationRecipe(ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2) {
return addPulverisationRecipe(aInput, aOutput1, aOutput2, 100, false);
}
public static boolean addPulverisationRecipe(
ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, int aChance) {
return addPulverisationRecipe(aInput, aOutput1, aOutput2, aChance, false);
}
public static boolean addPulverisationRecipe(ItemStack aInput, ItemStack aOutput1, boolean aOverwrite) {
return addPulverisationRecipe(aInput, aOutput1, null, 0, aOverwrite);
}
public static boolean addPulverisationRecipe(
ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, boolean aOverwrite) {
return addPulverisationRecipe(aInput, aOutput1, aOutput2, 100, aOverwrite);
}
public static boolean addPulverisationRecipe(
ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, int aChance, boolean aOverwrite) {
return addPulverisationRecipe(aInput, aOutput1, aOutput2, aChance, null, 0, aOverwrite);
}
/**
* Adds Several Pulverizer-Type Recipes.
*/
public static boolean addPulverisationRecipe(
ItemStack aInput,
ItemStack aOutput1,
ItemStack aOutput2,
int aChance2,
ItemStack aOutput3,
int aChance3,
boolean aOverwrite) {
aOutput1 = GT_OreDictUnificator.get(true, aOutput1);
aOutput2 = GT_OreDictUnificator.get(true, aOutput2);
if (GT_Utility.isStackInvalid(aInput) || GT_Utility.isStackInvalid(aOutput1)) return false;
if (GT_Utility.getContainerItem(aInput, false) == null) {
RA.addPulveriserRecipe(
aInput,
new ItemStack[] {aOutput1, aOutput2, aOutput3},
new int[] {10000, aChance2 <= 0 ? 1000 : 100 * aChance2, aChance3 <= 0 ? 1000 : 100 * aChance3},
400,
2);
}
return true;
}
public static boolean addPulverisationRecipe(
ItemStack aInputItem, ItemStack[] aOutputArray, int[] aChanceArray, int aEUt, int aRecipeDurationInTicks) {
ItemStack[] aUnifiedOutputArray = new ItemStack[aOutputArray.length];
int counter = 0;
for (ItemStack item : aOutputArray) {
aUnifiedOutputArray[counter] = GT_OreDictUnificator.get(true, item);
counter++;
}
RA.addPulveriserRecipe(aInputItem, aOutputArray, aChanceArray, aRecipeDurationInTicks, aEUt);
return true;
}
public static boolean addImmersiveEngineeringRecipe(
ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, int aChance2, ItemStack aOutput3, int aChance3) {
return true;
}
public static boolean addMagneticraftRecipe(
ItemStack aInput, ItemStack aOutput1, ItemStack aOutput2, int aChance2, ItemStack aOutput3, int aChance3) {
return true;
}
/**
* Adds a Recipe to the Sawmills of ThermalCraft
*/
public static boolean addSawmillRecipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2) {
return true;
}
/**
* Induction Smelter Recipes and Alloy Smelter Recipes
*/
public static boolean addAlloySmelterRecipe(
ItemStack aInput1,
ItemStack aInput2,
ItemStack aOutput1,
int aDuration,
int aEUt,
boolean aAllowSecondaryInputEmpty) {
if (aInput1 == null || (aInput2 == null && !aAllowSecondaryInputEmpty) || aOutput1 == null) return false;
aOutput1 = GT_OreDictUnificator.get(true, aOutput1);
return RA.addAlloySmelterRecipe(aInput1, aInput2, aOutput1, aDuration, aEUt);
}
/**
* Induction Smelter Recipes for TE
*/
public static boolean addInductionSmelterRecipe(
ItemStack aInput1, ItemStack aInput2, ItemStack aOutput1, ItemStack aOutput2, int aEnergy, int aChance) {
return true;
}
/**
* Smelts Ores to Ingots
*/
public static boolean addOreToIngotSmeltingRecipe(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 GT versions of the IC2 recipes from the supplied IC2RecipeList.
*/
public static void addIC2RecipesToGT(
Map aIC2RecipeList,
GT_Recipe.GT_Recipe_Map aGTRecipeMap,
boolean aAddGTRecipe,
boolean aRemoveIC2Recipe,
boolean aExcludeGTIC2Items) {
Map aRecipesToRemove = new HashMap<>();
for (Entry iRecipeInputRecipeOutputEntry : aIC2RecipeList.entrySet()) {
if (!iRecipeInputRecipeOutputEntry.getValue().items.isEmpty()) {
for (ItemStack tStack : (iRecipeInputRecipeOutputEntry.getKey()).getInputs()) {
if (GT_Utility.isStackValid(tStack)) {
if (aAddGTRecipe
&& (aGTRecipeMap.findRecipe(null, false, Long.MAX_VALUE, null, tStack) == null)) {
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.mUnlocalizedName) {
case "gt.recipe.macerator":
case "gt.recipe.extractor":
case "gt.recipe.compressor":
aGTRecipeMap.addRecipe(
true,
new ItemStack[] {
GT_Utility.copyAmount(
iRecipeInputRecipeOutputEntry
.getKey()
.getAmount(),
tStack)
},
iRecipeInputRecipeOutputEntry
.getValue()
.items
.toArray(new ItemStack[0]),
null,
null,
null,
null,
300,
2,
0);
break;
case "gt.recipe.thermalcentrifuge":
aGTRecipeMap.addRecipe(
true,
new ItemStack[] {
GT_Utility.copyAmount(
iRecipeInputRecipeOutputEntry
.getKey()
.getAmount(),
tStack)
},
iRecipeInputRecipeOutputEntry
.getValue()
.items
.toArray(new ItemStack[0]),
null,
null,
null,
null,
500,
48,
0);
break;
}
} catch (Exception e) {
System.err.println(e);
}
}
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 sExtractorRecipes;
}
public static Map getCompressorRecipeList() {
try {
return ic2.api.recipe.Recipes.compressor.getRecipes();
} catch (Throwable e) {
/*Do nothing*/
}
return sCompressorRecipes;
}
public static Map getMaceratorRecipeList() {
try {
return ic2.api.recipe.Recipes.macerator.getRecipes();
} catch (Throwable e) {
/*Do nothing*/
}
return sMaceratorRecipes;
}
public static Map getThermalCentrifugeRecipeList() {
try {
return ic2.api.recipe.Recipes.centrifuge.getRecipes();
} catch (Throwable e) {
/*Do nothing*/
}
return sThermalCentrifugeRecipes;
}
public static Map getOreWashingRecipeList() {
try {
return ic2.api.recipe.Recipes.oreWashing.getRecipes();
} catch (Throwable e) {
/*Do nothing*/
}
return sOreWashingRecipes;
}
public static Map getMassFabricatorList() {
try {
return ic2.api.recipe.Recipes.matterAmplifier.getRecipes();
} catch (Throwable e) {
/*Do nothing*/
}
return sMassfabRecipes;
}
/**
* IC2-ThermalCentrifuge Recipe. Overloads old Recipes automatically
*/
public static boolean addThermalCentrifugeRecipe(ItemStack aInput, int[] aChances, int aHeat, Object... aOutput) {
if (aInput == null || aOutput == null || aOutput.length <= 0 || aOutput[0] == null) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.thermalcentrifuge, aInput, true)) return false;
RA.addThermalCentrifugeRecipe(
aInput,
aOutput.length >= 1 ? (ItemStack) aOutput[0] : null,
aOutput.length >= 2 ? (ItemStack) aOutput[1] : null,
aOutput.length >= 3 ? (ItemStack) aOutput[2] : null,
aChances,
500,
48);
return true;
}
public static boolean addThermalCentrifugeRecipe(ItemStack aInput, int aHeat, Object... aOutput) {
if (aInput == null || aOutput == null || aOutput.length <= 0 || aOutput[0] == null) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.thermalcentrifuge, aInput, true)) return false;
RA.addThermalCentrifugeRecipe(
aInput,
aOutput.length >= 1 ? (ItemStack) aOutput[0] : null,
aOutput.length >= 2 ? (ItemStack) aOutput[1] : null,
aOutput.length >= 3 ? (ItemStack) aOutput[2] : null,
500,
48);
return true;
}
/**
* IC2-OreWasher Recipe. Overloads old Recipes automatically
*/
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;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.orewashing, aInput, true)) return false;
RA.addOreWasherRecipe(
aInput,
(ItemStack) aOutput[0],
(ItemStack) aOutput[1],
(ItemStack) aOutput[2],
GT_ModHandler.getWater(aWaterAmount),
aChances,
500,
16);
RA.addOreWasherRecipe(
aInput,
(ItemStack) aOutput[0],
(ItemStack) aOutput[1],
(ItemStack) aOutput[2],
GT_ModHandler.getDistilledWater(aWaterAmount / 5),
aChances,
300,
16);
return true;
}
public static boolean addOreWasherRecipe(ItemStack aInput, int aWaterAmount, Object... aOutput) {
if (aInput == null || aOutput == null || aOutput.length <= 0 || aOutput[0] == null) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.orewashing, aInput, true)) return false;
RA.addOreWasherRecipe(
aInput,
(ItemStack) aOutput[0],
(ItemStack) aOutput[1],
(ItemStack) aOutput[2],
GT_ModHandler.getWater(aWaterAmount),
500,
16);
RA.addOreWasherRecipe(
aInput,
(ItemStack) aOutput[0],
(ItemStack) aOutput[1],
(ItemStack) aOutput[2],
GT_ModHandler.getDistilledWater(aWaterAmount / 5),
300,
16);
return true;
}
/**
* IC2-Compressor Recipe. Overloads old Recipes automatically
*/
public static boolean addCompressionRecipe(ItemStack aInput, ItemStack aOutput) {
return addCompressionRecipe(aInput, aOutput, 300, 2);
}
/**
* IC2-Compressor Recipe. Overloads old Recipes automatically
*/
public static boolean addCompressionRecipe(ItemStack aInput, ItemStack aOutput, int duration, int EUPerTick) {
aOutput = GT_OreDictUnificator.get(true, aOutput);
if (aInput == null || aOutput == null || GT_Utility.areStacksEqual(aInput, aOutput, true)) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.compression, aInput, true)) return false;
RA.addCompressorRecipe(aInput, aOutput, duration, EUPerTick);
return true;
}
/**
* @param aValue Scrap = 5000, Scrapbox = 45000, Diamond Dust 125000
*/
public static boolean addIC2MatterAmplifier(ItemStack aAmplifier, int aValue) {
if (aAmplifier == null || aValue <= 0) return false;
if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.massfabamplifier, aAmplifier, true)) return false;
try {
NBTTagCompound tNBT = new NBTTagCompound();
tNBT.setInteger("amplification", aValue);
GT_Utility.callMethod(
ic2.api.recipe.Recipes.matterAmplifier, "addRecipe", false, false, false, aAmplifier, tNBT);
} catch (Throwable e) {
/*Do nothing*/
}
return true;
}
/**
* Rolling Machine Crafting Recipe
*/
public static boolean addRollingMachineRecipe(ItemStack aResult, Object[] aRecipe) {
aResult = GT_OreDictUnificator.get(true, aResult);
if (aResult == null || aRecipe == null || aResult.stackSize <= 0) return false;
try {
mods.railcraft.api.crafting.RailcraftCraftingManager.rollingMachine
.getRecipeList()
.add(new ShapedOreRecipe(GT_Utility.copyOrNull(aResult), aRecipe));
} catch (Throwable e) {
return addCraftingRecipe(GT_Utility.copyOrNull(aResult), aRecipe);
}
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;
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