package gregtech.api.util; import static gregtech.api.enums.GT_Values.*; import gregtech.api.GregTech_API; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords; import gregtech.api.objects.GT_ItemStack; import gtPlusPlus.core.util.Utils; import gtPlusPlus.core.util.item.ItemUtils; import java.util.*; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; /** * NEVER INCLUDE THIS FILE IN YOUR MOD!!! *

* 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. *

* 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 Recipe_GT extends GT_Recipe{ public static volatile int VERSION = 508; protected Recipe_GT(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { super(aOptimize, aInputs, aOutputs, aSpecialItems, aChances, aFluidInputs, aFluidOutputs, aDuration, aEUt, aSpecialValue); Utils.LOG_SPECIFIC_WARNING(this.getClass().getName()+" | [GregtechRecipe]", "Created new recipe instance for "+ItemUtils.getArrayStackNames(aInputs), 167); } public Recipe_GT(ItemStack aInput1, ItemStack aOutput1, int aFuelValue, int aType) { this(aInput1, aOutput1, null, null, null, aFuelValue, aType); } // aSpecialValue = EU per Liter! If there is no Liquid for this Object, then it gets multiplied with 1000! public Recipe_GT(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, int aSpecialValue, int aType) { this(true, new ItemStack[]{aInput1}, new ItemStack[]{aOutput1, aOutput2, aOutput3, aOutput4}, null, null, null, null, 0, 0, Math.max(1, aSpecialValue)); Utils.LOG_INFO("Switch case method for adding fuels"); if (mInputs.length > 0 && aSpecialValue > 0) { switch (aType) { // Diesel Generator case 0: Utils.LOG_INFO("Added fuel "+aInput1.getDisplayName()+" is ROCKET FUEL - continuing"); Gregtech_Recipe_Map.sRocketFuels.addRecipe(this); break; // Gas Turbine case 1: Gregtech_Recipe_Map.sGeoThermalFuels.addRecipe(this); break; // Thermal Generator case 2: //Gregtech_Recipe_Map.sHotFuels.addRecipe(this); break; // Plasma Generator case 4: //Gregtech_Recipe_Map.sPlasmaFuels.addRecipe(this); break; // Magic Generator case 5: //Gregtech_Recipe_Map.sMagicFuels.addRecipe(this); break; // Fluid Generator. Usually 3. Every wrong Type ends up in the Semifluid Generator default: //Gregtech_Recipe_Map.sDenseLiquidFuels.addRecipe(this); break; } } } //Custom Recipe Handlers public Recipe_GT(ItemStack aInput, FluidStack aFluid, ItemStack[] aOutput, int aDuration, int aEUt) { this(true, new ItemStack[]{aInput}, aOutput.clone(), null, null, new FluidStack[]{aFluid}, null, aDuration, aEUt, 0); if (mInputs.length > 0 && mOutputs[0] != null) { Gregtech_Recipe_Map.sChemicalDehydratorRecipes.addRecipe(this); } } public Recipe_GT(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) { Gregtech_Recipe_Map.sLiquidFluorineThoriumReactorRecipes.addRecipe(this); } } public Recipe_GT( FluidStack aInput1, FluidStack aInput2, FluidStack aInput3, FluidStack aInput4, FluidStack aInput5, FluidStack aInput6, FluidStack aInput7, FluidStack aInput8, FluidStack aInput9, FluidStack aOutput1, FluidStack aOutput2, int aDuration, int aEUt) { this(true, null, null, null, null, new FluidStack[]{aInput1, aInput2, aInput3, aInput4, aInput5, aInput6, aInput7, aInput8, aInput9}, new FluidStack[]{aOutput1, aOutput2}, Math.max(aDuration, 1), aEUt, 0); if (mInputs.length > 1) { CustomRecipeMap.sFissionFuelProcessing.addRecipe(this); } } /*public GregtechRecipe(ItemStack aInput, FluidStack aFluid, ItemStack[] aOutput, int aDuration, int aEUt) { this(true, new ItemStack[]{aInput}, aOutput.clone(), null, null, new FluidStack[]{aFluid}, null, aDuration, aEUt, 0); if (mInputs.length > 0 && mOutputs[0] != null) { Gregtech_Recipe_Map.sChemicalDehydratorRecipes.addRecipe(this); } }*/ public static void reInit() { GT_Log.out.println("GT_Mod: Re-Unificating Recipes."); for (Gregtech_Recipe_Map tMapEntry : Gregtech_Recipe_Map.sMappings) tMapEntry.reInit(); } @Override public ItemStack getRepresentativeInput(int aIndex) { if (aIndex < 0 || aIndex >= mInputs.length) return null; return GT_Utility.copy(mInputs[aIndex]); } @Override public ItemStack getOutput(int aIndex) { if (aIndex < 0 || aIndex >= mOutputs.length) return null; return GT_Utility.copy(mOutputs[aIndex]); } @Override public int getOutputChance(int aIndex) { if (aIndex < 0 || aIndex >= mChances.length) return 10000; return mChances[aIndex]; } @Override public FluidStack getRepresentativeFluidInput(int aIndex) { if (aIndex < 0 || aIndex >= mFluidInputs.length || mFluidInputs[aIndex] == null) return null; return mFluidInputs[aIndex].copy(); } @Override public FluidStack getFluidOutput(int aIndex) { if (aIndex < 0 || aIndex >= mFluidOutputs.length || mFluidOutputs[aIndex] == null) return null; return mFluidOutputs[aIndex].copy(); } @Override public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, FluidStack[] aFluidInputs, ItemStack... aInputs) { return isRecipeInputEqual(aDecreaseStacksizeBySuccess, false, aFluidInputs, aInputs); } @Override public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes, FluidStack[] aFluidInputs, ItemStack... aInputs) { if (mFluidInputs.length > 0 && aFluidInputs == null) return false; for (FluidStack tFluid : mFluidInputs) if (tFluid != null) { boolean temp = true; for (FluidStack aFluid : aFluidInputs) if (aFluid != null && aFluid.isFluidEqual(tFluid) && (aDontCheckStackSizes || aFluid.amount >= tFluid.amount)) { temp = false; break; } if (temp) return false; } if (mInputs.length > 0 && aInputs == null) return false; for (ItemStack tStack : mInputs) if (tStack != null) { boolean temp = true; for (ItemStack aStack : aInputs) if ((GT_Utility.areUnificationsEqual(aStack, tStack, true) || GT_Utility.areUnificationsEqual(GT_OreDictUnificator.get(false, aStack), tStack, true)) && (aDontCheckStackSizes || aStack.stackSize >= tStack.stackSize)) { temp = false; break; } if (temp) return false; } if (aDecreaseStacksizeBySuccess) { if (aFluidInputs != null) { for (FluidStack tFluid : mFluidInputs) if (tFluid != null) { for (FluidStack aFluid : aFluidInputs) if (aFluid != null && aFluid.isFluidEqual(tFluid) && (aDontCheckStackSizes || aFluid.amount >= tFluid.amount)) { aFluid.amount -= tFluid.amount; break; } } } if (aInputs != null) { for (ItemStack tStack : mInputs) if (tStack != null) { for (ItemStack aStack : aInputs) if ((GT_Utility.areUnificationsEqual(aStack, tStack, true) || GT_Utility.areUnificationsEqual(GT_OreDictUnificator.get(false, aStack), tStack, true)) && (aDontCheckStackSizes || aStack.stackSize >= tStack.stackSize)) { aStack.stackSize -= tStack.stackSize; break; } } } } return true; } public static class Gregtech_Recipe_Map { /** * Contains all Recipe Maps */ public static final Collection sMappings = new ArrayList(); //public static final GT_Recipe_Map sChemicalBathRecipes = new GT_Recipe_Map(new HashSet(200), "gt.recipe.chemicalbath", "Chemical Bath", null, RES_PATH_GUI + "basicmachines/ChemicalBath", 1, 3, 1, 1, 1, E, 1, E, true, true); public static final GT_Recipe_Map sCokeOvenRecipes = new GT_Recipe_Map(new HashSet(200), "gt.recipe.cokeoven", "Coke Oven", null, RES_PATH_GUI + "basicmachines/Dehydrator", 2, 2, 1, 0, 1, E, 1, E, true, true); public static final GT_Recipe_Map sMatterFab2Recipes = new GT_Recipe_Map(new HashSet(200), "gt.recipe.matterfab2", "Matter Fabricator", null, RES_PATH_GUI + "basicmachines/Default", 1, 1, 0, 0, 1, E, 1, E, true, true); //public static final Gregtech_Recipe_Map sMatterFabRecipes = new Gregtech_Recipe_Map(new HashSet(200), "gt.recipe.matterfab", "Matter Fabricator", null, RES_PATH_GUI + "basicmachines/Massfabricator", 1, 3, 1, 1, 1, E, 1, E, true, true); public static final Gregtech_Recipe_Map_Fuel sRocketFuels = new Gregtech_Recipe_Map_Fuel(new HashSet(10), "gt.recipe.rocketenginefuel", "Rocket Engine Fuel", null, RES_PATH_GUI + "basicmachines/Default", 1, 1, 0, 0, 1, "Fuel Value: ", 3000, " EU", true, true); public static final Gregtech_Recipe_Map_Fuel sGeoThermalFuels = new Gregtech_Recipe_Map_Fuel(new HashSet(10), "gt.recipe.geothermalfuel", "GeoThermal Fuel", null, RES_PATH_GUI + "basicmachines/Default", 1, 1, 0, 0, 1, "Fuel Value: ", 1000, " EU", true, true); public static final GT_Recipe_Map sChemicalDehydratorRecipes = new GT_Recipe_Map(new HashSet(200), "gt.recipe.chemicaldehydrator", "Chemical Dehydrator", null, RES_PATH_GUI + "basicmachines/Dehydrator", 2, 9, 0, 0, 1, E, 1, E, true, true); public static final GT_Recipe_Map sAlloyBlastSmelterRecipes = new GT_Recipe_Map(new HashSet(200), "gt.recipe.alloyblastsmelter", "Alloy Blast Smelter", null, RES_PATH_GUI + "basicmachines/BlastSmelter", 9, 1, 1, 0, 1, E, 1, E, true, true); //LFTR recipes public static final GT_Recipe_Map sLiquidFluorineThoriumReactorRecipes = new GT_Recipe_Map(new HashSet(50), "gt.recipe.lftr", "Liquid Fluoride Thorium Reactor", null, RES_PATH_GUI + "basicmachines/LFTR", 0, 0, 0, 2, 1, "Start: ", 1, " EU", true, true); //Fission Fuel Plant Recipes //public static final GT_Recipe_Map sFissionFuelProcessing = new GT_Recipe_Map(new HashSet(50), "gt.recipe.fissionfuel", "Fission Fuel Processing", null, RES_PATH_GUI + "basicmachines/LFTR", 0, 0, 0, 9, 1, E, 1, E, true, true); /** * HashMap of Recipes based on their Items */ public final Map> mRecipeItemMap = new HashMap>(); /** * HashMap of Recipes based on their Fluids */ public final Map> mRecipeFluidMap = new HashMap>(); /** * The List of all Recipes */ public final Collection 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; /** * 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 the displayed Name inside the NEI Recipe GUI. * @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 Gregtech_Recipe_Map(Collection 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.sFluidMappings.add(mRecipeFluidMap); GregTech_API.sItemStackMappings.add(mRecipeItemMap); GT_LanguageManager.addStringLocalization(mUnlocalizedName = aUnlocalizedName, aLocalName); } 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(boolean aOptimize, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { return addRecipe(new GT_Recipe(aOptimize, null, null, null, null, aFluidInputs, aFluidOutputs, aDuration, aEUt, aSpecialValue)); } /*public GregtechRecipe addRecipe(boolean aOptimize, FluidStack aInput1, FluidStack aOutput1, ItemStack[] bInput1, ItemStack[] bOutput1, int aDuration, int aEUt, int aSpecialValue) { return addRecipe(new GregtechRecipe(aOptimize, aInput1, aOutput1, bInput1,bOutput1, aDuration, aEUt, aSpecialValue)); }*/ public GT_Recipe addRecipe(GT_Recipe aRecipe) { Utils.LOG_INFO("Adding Recipe Method 1"); return addRecipe(aRecipe, true, false, false); } protected GT_Recipe addRecipe(GT_Recipe aRecipe, boolean aCheckForCollisions, boolean aFakeRecipe, boolean aHidden) { Utils.LOG_INFO("Adding Recipe Method 2 - This Checks if hidden, fake or if duplicate recipes exists, I think."); aRecipe.mHidden = aHidden; aRecipe.mFakeRecipe = aFakeRecipe; Utils.LOG_INFO("Logging some data about this method: GregtechRecipe["+aRecipe.toString()+"] | aCheckForCollisions["+aCheckForCollisions+"] | aFakeRecipe["+aFakeRecipe+"] | aHidden["+aHidden+"]"); Utils.LOG_INFO("Logging some data about this method: mMinimalInputFluids["+mMinimalInputFluids+"] | mMinimalInputItems["+mMinimalInputItems+"] | aRecipe.mFluidInputs.length["+aRecipe.mFluidInputs.length+"] | aRecipe.mInputs.length["+aRecipe.mInputs.length+"]"); if (aRecipe.mFluidInputs.length < mMinimalInputFluids && aRecipe.mInputs.length < mMinimalInputItems){ Utils.LOG_INFO("Step 2 failed"); return null;} Utils.LOG_INFO("Logging some data about this method: aCheckForCollisions["+aCheckForCollisions+"] | findRecipe != null ["+(findRecipe(null, false, Long.MAX_VALUE, aRecipe.mFluidInputs, aRecipe.mInputs) != null)+"]"); if (aCheckForCollisions && findRecipe(null, false, Long.MAX_VALUE, aRecipe.mFluidInputs, aRecipe.mInputs) != null){ Utils.LOG_INFO("Step 2 failed - 2"); 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)); } /** * 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 add(GT_Recipe aRecipe) { Utils.LOG_INFO("Adding Recipe Method 3"); mRecipeList.add(aRecipe); for (FluidStack aFluid : aRecipe.mFluidInputs) if (aFluid != null) { Utils.LOG_INFO("Fluid is valid - getting some kind of fluid instance to add to the recipe hashmap."); Collection tList = mRecipeFluidMap.get(aFluid.getFluid()); if (tList == null) mRecipeFluidMap.put(aFluid.getFluid(), tList = new HashSet(1)); tList.add(aRecipe); } return addToItemMap(aRecipe); } public void reInit() { Map> tMap = mRecipeItemMap; if (tMap != null) tMap.clear(); for (GT_Recipe tRecipe : mRecipeList) { GT_OreDictUnificator.setStackArray(true, tRecipe.mInputs); GT_OreDictUnificator.setStackArray(true, tRecipe.mOutputs); if (tMap != null) 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(GT_Utility.copyMetaData(W, aStack)))); } /** * @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 && mRecipeFluidMap.containsKey(aFluid); } public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) { return findRecipe(aTileEntity, null, aNotUnificated, aVoltage, aFluids, null, aInputs); } public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack... aInputs) { return findRecipe(aTileEntity, aRecipe, aNotUnificated, aVoltage, aFluids, null, aInputs); } /** * finds a Recipe matching the aFluid and ItemStack Inputs. * * @param aTileEntity an Object representing the current coordinates of the executing Block/Entity/Whatever. This may be null, especially during Startup. * @param aRecipe in case this is != null it will try to use this Recipe first when looking things up. * @param aNotUnificated if this is T the Recipe searcher will unificate the ItemStack Inputs * @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 the Recipe it has found or null for no matching Recipe */ public GT_Recipe findRecipe(IHasWorldObjectAndCoords aTileEntity, GT_Recipe aRecipe, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, ItemStack aSpecialSlot, ItemStack... aInputs) { // No Recipes? Well, nothing to be found then. if (mRecipeList.isEmpty()) return null; // 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 null; int tAmount = 0; for (FluidStack aFluid : aFluids) if (aFluid != null) tAmount++; if (tAmount < mMinimalInputFluids) return null; } if (mMinimalInputItems > 0) { if (aInputs == null) return null; int tAmount = 0; for (ItemStack aInput : aInputs) if (aInput != null) tAmount++; if (tAmount < mMinimalInputItems) return null; } } // 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, true, aFluids, aInputs)) return aRecipe.mEnabled && aVoltage * mAmperage >= aRecipe.mEUt ? aRecipe : null; // 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 tRecipes = mRecipeItemMap.get(new GT_ItemStack(tStack)); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; tRecipes = mRecipeItemMap.get(new GT_ItemStack(GT_Utility.copyMetaData(W, tStack))); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; } // 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 tRecipes = mRecipeFluidMap.get(aFluid.getFluid()); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; } // And nothing has been found. return null; } protected GT_Recipe addToItemMap(GT_Recipe aRecipe) { Utils.LOG_INFO("Adding Recipe Method 4"); for (ItemStack aStack : aRecipe.mInputs) if (aStack != null) { Utils.LOG_INFO("Method 4 - Manipulating "+aStack.getDisplayName()); GT_ItemStack tStack = new GT_ItemStack(aStack); Utils.LOG_INFO("Method 4 - Made gt stack of item "+tStack.toStack().getDisplayName()); Collection tList = mRecipeItemMap.get(tStack); if (tList != null){ Utils.LOG_INFO("Method 4 - Gt Recipe Hashmap: "+tList.toString()); } if (tList == null){ Utils.LOG_INFO("Method 4 - brrr list was NUll"); mRecipeItemMap.put(tStack, tList = new HashSet(1)); Utils.LOG_INFO("Method 4 - Attemping backup method for Gt Recipe Hashmap:"); while (tList.iterator().hasNext()){ Utils.LOG_INFO(tList.iterator().next().toString()); } } tList.add(aRecipe); Utils.LOG_INFO("Method 4 - Added recipe to map? I think."); } return aRecipe; } public GT_Recipe findRecipe(IGregTechTileEntity baseMetaTileEntity, GT_Recipe aRecipe, boolean aNotUnificated, long aVoltage, FluidStack[] aFluids, FluidStack[] fluidStacks) { ItemStack aInputs[] = null; // No Recipes? Well, nothing to be found then. if (mRecipeList.isEmpty()) return null; // 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 null; int tAmount = 0; for (FluidStack aFluid : aFluids) if (aFluid != null) tAmount++; if (tAmount < mMinimalInputFluids) return null; } if (mMinimalInputItems > 0) { if (aInputs == null) return null; int tAmount = 0; for (ItemStack aInput : aInputs) if (aInput != null) tAmount++; if (tAmount < mMinimalInputItems) return null; } } // 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, true, aFluids, aInputs)) return aRecipe.mEnabled && aVoltage * mAmperage >= aRecipe.mEUt ? aRecipe : null; // 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 tRecipes = mRecipeItemMap.get(new GT_ItemStack(tStack)); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; tRecipes = mRecipeItemMap.get(new GT_ItemStack(GT_Utility.copyMetaData(W, tStack))); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; } // 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 tRecipes = mRecipeFluidMap.get(aFluid.getFluid()); if (tRecipes != null) for (GT_Recipe tRecipe : tRecipes) if (!tRecipe.mFakeRecipe && tRecipe.isRecipeInputEqual(false, true, aFluids, aInputs)) return tRecipe.mEnabled && aVoltage * mAmperage >= tRecipe.mEUt ? tRecipe : null; } // And nothing has been found. return null; } } // ----------------------------------------------------------------------------------------------------------------- // Here are a few Classes I use for Special Cases in some Machines without having to write a separate Machine Class. // ----------------------------------------------------------------------------------------------------------------- /** * Abstract Class for general Recipe Handling of non GT Recipes */ public static abstract class GT_Recipe_Map_NonGTRecipes extends Gregtech_Recipe_Map { public GT_Recipe_Map_NonGTRecipes(Collection 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 Recipe_GT 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, 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 Gregtech_Recipe_Map_Fuel extends Gregtech_Recipe_Map { public Gregtech_Recipe_Map_Fuel(Collection 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); } public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, int aFuelValueInEU) { Utils.LOG_INFO("Adding Fuel using method 1"); return addFuel(aInput, aOutput, null, null, 10000, aFuelValueInEU); } public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, int aChance, int aFuelValueInEU) { Utils.LOG_INFO("Adding Fuel using method 2"); return addFuel(aInput, aOutput, null, null, aChance, aFuelValueInEU); } public GT_Recipe addFuel(FluidStack aFluidInput, FluidStack aFluidOutput, int aFuelValueInEU) { Utils.LOG_INFO("Adding Fuel using method 3"); return addFuel(null, null, aFluidInput, aFluidOutput, 10000, aFuelValueInEU); } public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput, int aFuelValueInEU) { Utils.LOG_INFO("Adding Fuel using method 4"); return addFuel(aInput, aOutput, aFluidInput, aFluidOutput, 10000, aFuelValueInEU); } public GT_Recipe addFuel(ItemStack aInput, ItemStack aOutput, FluidStack aFluidInput, FluidStack aFluidOutput, int aChance, int aFuelValueInEU) { Utils.LOG_INFO("Adding Fuel using method 5"); return addRecipe(true, new ItemStack[]{aInput}, new ItemStack[]{aOutput}, null, new int[]{aChance}, new FluidStack[]{aFluidInput}, new FluidStack[]{aFluidOutput}, 0, 0, aFuelValueInEU); } } }