| package mekanism.common.recipe; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import mekanism.api.gas.GasRegistry; |
| import mekanism.api.gas.GasStack; |
| import mekanism.api.gas.GasTank; |
| import mekanism.api.infuse.InfusionInput; |
| import mekanism.api.infuse.InfusionOutput; |
| import mekanism.api.recipe.AdvancedInput; |
| import mekanism.api.recipe.ChanceOutput; |
| import mekanism.api.recipe.ChemicalPair; |
| import mekanism.api.recipe.PressurizedProducts; |
| import mekanism.api.recipe.PressurizedReactants; |
| import mekanism.api.recipe.PressurizedRecipe; |
| import mekanism.api.util.StackUtils; |
| |
| import net.minecraft.item.ItemStack; |
| import net.minecraftforge.fluids.Fluid; |
| import net.minecraftforge.fluids.FluidStack; |
| import net.minecraftforge.fluids.FluidTank; |
| |
| /** |
| * Class used to handle machine recipes. This is used for both adding recipes and checking outputs. |
| * @author AidanBrady |
| * |
| */ |
| public final class RecipeHandler |
| { |
| public static void addRecipe(Recipe recipe, Object input, Object output) |
| { |
| recipe.put(input, output); |
| } |
| |
| /** |
| * Add an Enrichment Chamber recipe. |
| * @param input - input ItemStack |
| * @param output - output ItemStack |
| */ |
| public static void addEnrichmentChamberRecipe(ItemStack input, ItemStack output) |
| { |
| Recipe.ENRICHMENT_CHAMBER.put(input, output); |
| } |
| |
| /** |
| * Add an Osmium Compressor recipe. |
| * @param input - input ItemStack |
| * @param output - output ItemStack |
| */ |
| public static void addOsmiumCompressorRecipe(ItemStack input, ItemStack output) |
| { |
| Recipe.OSMIUM_COMPRESSOR.put(new AdvancedInput(input, GasRegistry.getGas("liquidOsmium")), output); |
| } |
| |
| /** |
| * Add a Combiner recipe. |
| * @param input - input ItemStack |
| * @param output - output ItemStack |
| */ |
| public static void addCombinerRecipe(ItemStack input, ItemStack output) |
| { |
| Recipe.COMBINER.put(new AdvancedInput(input, GasRegistry.getGas("liquidStone")), output); |
| } |
| |
| /** |
| * Add a Crusher recipe. |
| * @param input - input ItemStack |
| * @param output - output ItemStack |
| */ |
| public static void addCrusherRecipe(ItemStack input, ItemStack output) |
| { |
| Recipe.CRUSHER.put(input, output); |
| } |
| |
| /** |
| * Add a Purification Chamber recipe. |
| * @param input - input ItemStack |
| * @param output - output ItemStack |
| */ |
| public static void addPurificationChamberRecipe(ItemStack input, ItemStack output) |
| { |
| Recipe.PURIFICATION_CHAMBER.put(new AdvancedInput(input, GasRegistry.getGas("oxygen")), output); |
| } |
| |
| /** |
| * Add a Metallurgic Infuser recipe. |
| * @param input - input Infusion |
| * @param output - output ItemStack |
| */ |
| public static void addMetallurgicInfuserRecipe(InfusionInput input, ItemStack output) |
| { |
| Recipe.METALLURGIC_INFUSER.put(input, InfusionOutput.getInfusion(input, output)); |
| } |
| |
| /** |
| * Add a Chemical Infuser recipe. |
| * @param input - input ChemicalPair |
| * @param output - output GasStack |
| */ |
| public static void addChemicalInfuserRecipe(ChemicalPair input, GasStack output) |
| { |
| Recipe.CHEMICAL_INFUSER.put(input, output); |
| } |
| |
| /** |
| * Add a Chemical Oxidizer recipe. |
| * @param input - input ItemStack |
| * @param output - output GasStack |
| */ |
| public static void addChemicalOxidizerRecipe(ItemStack input, GasStack output) |
| { |
| Recipe.CHEMICAL_OXIDIZER.put(input, output); |
| } |
| |
| /** |
| * Add a Chemical Injection Chamber recipe. |
| * @param input - input ItemStack |
| * @param output - output ItemStack |
| */ |
| public static void addChemicalInjectionChamberRecipe(AdvancedInput input, ItemStack output) |
| { |
| Recipe.CHEMICAL_INJECTION_CHAMBER.put(input, output); |
| } |
| |
| /** |
| * Add an Electrolytic Separator recipe. |
| * @param fluid - FluidStack to electrolyze |
| * @param products - Pair of gases to produce when the fluid is electrolyzed |
| */ |
| public static void addElectrolyticSeparatorRecipe(FluidStack fluid, ChemicalPair products) |
| { |
| Recipe.ELECTROLYTIC_SEPARATOR.put(fluid, products); |
| } |
| |
| /** |
| * Add an Precision Sawmill recipe. |
| * @param input - input ItemStack |
| * @param output - output ChanceOutput |
| */ |
| public static void addPrecisionSawmillRecipe(ItemStack input, ChanceOutput output) |
| { |
| Recipe.PRECISION_SAWMILL.put(input, output); |
| } |
| |
| /** |
| * Add a Chemical Dissolution Chamber recipe. |
| * @param input - input ItemStack |
| * @param output - output GasStack |
| */ |
| public static void addChemicalDissolutionChamberRecipe(ItemStack input, GasStack output) |
| { |
| Recipe.CHEMICAL_DISSOLUTION_CHAMBER.put(input, output); |
| } |
| |
| /** |
| * Add a Chemical Washer recipe. |
| * @param input - input GasStack |
| * @param output - output GasStack |
| */ |
| public static void addChemicalWasherRecipe(GasStack input, GasStack output) |
| { |
| Recipe.CHEMICAL_WASHER.put(input, output); |
| } |
| |
| /** |
| * Add a Chemical Crystallizer recipe. |
| * @param input - input GasStack |
| * @param output - output ItemStack |
| */ |
| public static void addChemicalCrystallizerRecipe(GasStack input, ItemStack output) |
| { |
| Recipe.CHEMICAL_CRYSTALLIZER.put(input, output); |
| } |
| |
| /** |
| * Add a Pressurized Reaction Chamber recipe. |
| * @param input - input PressurizedReactants |
| * @param output - output PressurizedProducts |
| * @param extraEnergy - extra energy needed by the recipe |
| * @param ticks - amount of ticks it takes for this recipe to complete |
| */ |
| public static void addPRCRecipe(PressurizedReactants input, PressurizedProducts output, double extraEnergy, int ticks) |
| { |
| PressurizedRecipe recipe = new PressurizedRecipe(input, extraEnergy, output, ticks); |
| Recipe.PRESSURIZED_REACTION_CHAMBER.put(input, recipe); |
| } |
| |
| /** |
| * Gets the InfusionOutput of the InfusionInput in the parameters. |
| * @param infusion - input Infusion |
| * @param stackDecrease - whether or not to decrease the input slot's stack size AND the infuse amount |
| * @return InfusionOutput |
| */ |
| public static InfusionOutput getMetallurgicInfuserOutput(InfusionInput infusion, boolean stackDecrease) |
| { |
| if(infusion != null && infusion.inputStack != null) |
| { |
| HashMap<InfusionInput, InfusionOutput> recipes = Recipe.METALLURGIC_INFUSER.get(); |
| |
| for(Map.Entry<InfusionInput, InfusionOutput> entry : recipes.entrySet()) |
| { |
| InfusionInput input = (InfusionInput)entry.getKey(); |
| |
| if(StackUtils.equalsWildcard(input.inputStack, infusion.inputStack) && infusion.inputStack.stackSize >= input.inputStack.stackSize) |
| { |
| if(infusion.infusionType == input.infusionType) |
| { |
| if(stackDecrease) |
| { |
| infusion.inputStack.stackSize -= ((InfusionInput)entry.getKey()).inputStack.stackSize; |
| } |
| |
| return ((InfusionOutput)entry.getValue()).copy(); |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the GasStack of the ChemicalInput in the parameters. |
| * @param leftTank - first GasTank |
| * @param rightTank - second GasTank |
| * @param doRemove - actually remove the gases |
| * @return output GasStack |
| */ |
| public static GasStack getChemicalInfuserOutput(GasTank leftTank, GasTank rightTank, boolean doRemove) |
| { |
| ChemicalPair input = new ChemicalPair(leftTank.getGas(), rightTank.getGas()); |
| |
| if(input.isValid()) |
| { |
| HashMap<ChemicalPair, GasStack> recipes = Recipe.CHEMICAL_INFUSER.get(); |
| |
| for(Map.Entry<ChemicalPair, GasStack> entry : recipes.entrySet()) |
| { |
| ChemicalPair key = (ChemicalPair)entry.getKey(); |
| |
| if(key.meetsInput(input)) |
| { |
| if(doRemove) |
| { |
| key.draw(leftTank, rightTank); |
| } |
| |
| return entry.getValue().copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the Chemical Crystallizer ItemStack output of the defined GasTank input. |
| * @param gasTank - input GasTank |
| * @param removeGas - whether or not to use gas in the gas tank |
| * @return output ItemStack |
| */ |
| public static ItemStack getChemicalCrystallizerOutput(GasTank gasTank, boolean removeGas) |
| { |
| GasStack gas = gasTank.getGas(); |
| |
| if(gas != null) |
| { |
| HashMap<GasStack, ItemStack> recipes = Recipe.CHEMICAL_CRYSTALLIZER.get(); |
| |
| for(Map.Entry<GasStack, ItemStack> entry : recipes.entrySet()) |
| { |
| GasStack key = (GasStack)entry.getKey(); |
| |
| if(key != null && key.getGas() == gas.getGas() && gas.amount >= key.amount) |
| { |
| gasTank.draw(key.amount, removeGas); |
| |
| return entry.getValue().copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the Chemical Washer GasStack output of the defined GasTank input. |
| * @param gasTank - input GasTank |
| * @param removeGas - whether or not to use gas in the gas tank |
| * @return output GasStack |
| */ |
| public static GasStack getChemicalWasherOutput(GasTank gasTank, boolean removeGas) |
| { |
| GasStack gas = gasTank.getGas(); |
| |
| if(gas != null) |
| { |
| HashMap<GasStack, GasStack> recipes = Recipe.CHEMICAL_WASHER.get(); |
| |
| for(Map.Entry<GasStack, GasStack> entry : recipes.entrySet()) |
| { |
| GasStack key = (GasStack)entry.getKey(); |
| |
| if(key != null && key.getGas() == gas.getGas() && gas.amount >= key.amount) |
| { |
| gasTank.draw(key.amount, removeGas); |
| |
| return entry.getValue().copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the GasStack of the ItemStack in the parameters using a defined map. |
| * @param itemstack - input ItemStack |
| * @param stackDecrease - whether or not to decrease the input slot's stack size |
| * @return output GasStack |
| */ |
| public static GasStack getItemToGasOutput(ItemStack itemstack, boolean stackDecrease, HashMap<ItemStack, GasStack> recipes) |
| { |
| if(itemstack != null) |
| { |
| for(Map.Entry<ItemStack, GasStack> entry : recipes.entrySet()) |
| { |
| ItemStack stack = (ItemStack)entry.getKey(); |
| |
| if(StackUtils.equalsWildcard(stack, itemstack) && itemstack.stackSize >= stack.stackSize) |
| { |
| if(stackDecrease) |
| { |
| itemstack.stackSize -= stack.stackSize; |
| } |
| |
| return entry.getValue().copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the output ChanceOutput of the ItemStack in the parameters. |
| * @param itemstack - input ItemStack |
| * @param stackDecrease - whether or not to decrease the input slot's stack size |
| * @param recipes - Map of recipes |
| * @return output ChanceOutput |
| */ |
| public static ChanceOutput getChanceOutput(ItemStack itemstack, boolean stackDecrease, Map<ItemStack, ChanceOutput> recipes) |
| { |
| if(itemstack != null) |
| { |
| for(Map.Entry entry : recipes.entrySet()) |
| { |
| ItemStack stack = (ItemStack)entry.getKey(); |
| |
| if(StackUtils.equalsWildcard(stack, itemstack) && itemstack.stackSize >= stack.stackSize) |
| { |
| if(stackDecrease) |
| { |
| itemstack.stackSize -= stack.stackSize; |
| } |
| |
| return ((ChanceOutput)entry.getValue()).copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the output ItemStack of the ItemStack in the parameters. |
| * @param itemstack - input ItemStack |
| * @param stackDecrease - whether or not to decrease the input slot's stack size |
| * @param recipes - Map of recipes |
| * @return output ItemStack |
| */ |
| public static ItemStack getOutput(ItemStack itemstack, boolean stackDecrease, Map<ItemStack, ItemStack> recipes) |
| { |
| if(itemstack != null) |
| { |
| for(Map.Entry entry : recipes.entrySet()) |
| { |
| ItemStack stack = (ItemStack)entry.getKey(); |
| |
| if(StackUtils.equalsWildcard(stack, itemstack) && itemstack.stackSize >= stack.stackSize) |
| { |
| if(stackDecrease) |
| { |
| itemstack.stackSize -= stack.stackSize; |
| } |
| |
| return ((ItemStack)entry.getValue()).copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| /** |
| * Gets the output ItemStack of the AdvancedInput in the parameters. |
| * @param input - input AdvancedInput |
| * @param stackDecrease - whether or not to decrease the input slot's stack size |
| * @param recipes - Map of recipes |
| * @return output ItemStack |
| */ |
| public static ItemStack getOutput(AdvancedInput input, boolean stackDecrease, Map<AdvancedInput, ItemStack> recipes) |
| { |
| if(input != null && input.isValid()) |
| { |
| for(Map.Entry<AdvancedInput, ItemStack> entry : recipes.entrySet()) |
| { |
| if(entry.getKey().matches(input)) |
| { |
| if(stackDecrease) |
| { |
| input.itemStack.stackSize -= entry.getKey().itemStack.stackSize; |
| } |
| |
| return entry.getValue().copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get the result of electrolysing a given fluid |
| * @param fluidTank - the FluidTank to electrolyse fluid from |
| */ |
| public static ChemicalPair getElectrolyticSeparatorOutput(FluidTank fluidTank, boolean doRemove) |
| { |
| FluidStack fluid = fluidTank.getFluid(); |
| |
| if(fluid != null) |
| { |
| HashMap<FluidStack, ChemicalPair> recipes = Recipe.ELECTROLYTIC_SEPARATOR.get(); |
| |
| for(Map.Entry<FluidStack, ChemicalPair> entry : recipes.entrySet()) |
| { |
| FluidStack key = (FluidStack)entry.getKey(); |
| |
| if(fluid.containsFluid(key)) |
| { |
| fluidTank.drain(key.amount, doRemove); |
| |
| return entry.getValue().copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public static PressurizedRecipe getPRCOutput(ItemStack inputItem, FluidTank inputFluidTank, GasTank inputGasTank) |
| { |
| FluidStack inputFluid = inputFluidTank.getFluid(); |
| GasStack inputGas = inputGasTank.getGas(); |
| |
| if(inputFluid != null && inputGas != null) |
| { |
| HashMap<PressurizedReactants, PressurizedRecipe> recipes = Recipe.PRESSURIZED_REACTION_CHAMBER.get(); |
| |
| for(PressurizedRecipe recipe : recipes.values()) |
| { |
| PressurizedReactants reactants = recipe.reactants; |
| |
| if(reactants.meetsInput(inputItem, inputFluid, inputGas)) |
| { |
| return recipe.copy(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets the output ItemStack of the ItemStack in the parameters. |
| * @param itemstack - input ItemStack |
| * @param recipes - Map of recipes |
| * @return whether the item can be used in a recipe |
| */ |
| public static boolean isInRecipe(ItemStack itemstack, Map<ItemStack, ItemStack> recipes) |
| { |
| if(itemstack != null) |
| { |
| for(Map.Entry entry : recipes.entrySet()) |
| { |
| ItemStack stack = (ItemStack)entry.getKey(); |
| |
| if(StackUtils.equalsWildcard(stack, itemstack)) |
| { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| public static boolean isInPressurizedRecipe(ItemStack stack) |
| { |
| if(stack != null) |
| { |
| for(PressurizedReactants key : (Set<PressurizedReactants>)Recipe.PRESSURIZED_REACTION_CHAMBER.get().keySet()) |
| { |
| if(key.containsType(stack)) |
| { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| public static enum Recipe |
| { |
| ENRICHMENT_CHAMBER(new HashMap<ItemStack, ItemStack>()), |
| OSMIUM_COMPRESSOR(new HashMap<AdvancedInput, ItemStack>()), |
| COMBINER(new HashMap<AdvancedInput, ItemStack>()), |
| CRUSHER(new HashMap<ItemStack, ItemStack>()), |
| PURIFICATION_CHAMBER(new HashMap<AdvancedInput, ItemStack>()), |
| METALLURGIC_INFUSER(new HashMap<InfusionInput, InfusionOutput>()), |
| CHEMICAL_INFUSER(new HashMap<ChemicalPair, GasStack>()), |
| CHEMICAL_OXIDIZER(new HashMap<ItemStack, GasStack>()), |
| CHEMICAL_INJECTION_CHAMBER(new HashMap<AdvancedInput, ItemStack>()), |
| ELECTROLYTIC_SEPARATOR(new HashMap<FluidStack, ChemicalPair>()), |
| PRECISION_SAWMILL(new HashMap<ItemStack, ChanceOutput>()), |
| CHEMICAL_DISSOLUTION_CHAMBER(new HashMap<ItemStack, FluidStack>()), |
| CHEMICAL_WASHER(new HashMap<GasStack, GasStack>()), |
| CHEMICAL_CRYSTALLIZER(new HashMap<GasStack, ItemStack>()), |
| PRESSURIZED_REACTION_CHAMBER(new HashMap<PressurizedReactants, PressurizedRecipe>()); |
| |
| private HashMap recipes; |
| |
| private Recipe(HashMap map) |
| { |
| recipes = map; |
| } |
| |
| public void put(Object input, Object output) |
| { |
| recipes.put(input, output); |
| } |
| |
| public boolean containsRecipe(ItemStack input) |
| { |
| for(Object obj : get().entrySet()) |
| { |
| if(obj instanceof Map.Entry) |
| { |
| Map.Entry entry = (Map.Entry)obj; |
| |
| if(entry.getKey() instanceof ItemStack) |
| { |
| ItemStack stack = (ItemStack)entry.getKey(); |
| |
| if(StackUtils.equalsWildcard(stack, input)) |
| { |
| return true; |
| } |
| } |
| else if(entry.getKey() instanceof FluidStack) |
| { |
| if(((FluidStack)entry.getKey()).isFluidEqual(input)) |
| { |
| return true; |
| } |
| } |
| else if(entry.getKey() instanceof AdvancedInput) |
| { |
| ItemStack stack = ((AdvancedInput)entry.getKey()).itemStack; |
| |
| if(StackUtils.equalsWildcard(stack, input)) |
| { |
| return true; |
| } |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| public boolean containsRecipe(Fluid input) |
| { |
| for(Object obj : get().entrySet()) |
| { |
| if(obj instanceof Map.Entry) |
| { |
| Map.Entry entry = (Map.Entry)obj; |
| |
| if(entry.getKey() instanceof FluidStack) |
| { |
| if(((FluidStack)entry.getKey()).getFluid() == input) |
| { |
| return true; |
| } |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| public HashMap get() |
| { |
| return recipes; |
| } |
| } |
| } |