diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 1dc753c2b..c23a90f90 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -77,13 +77,14 @@ class Proxy { OpenComputers.channel.register(server.PacketHandler) Loot.init() - Recipes.init() Achievement.init() EntityRegistry.registerModEntity(classOf[Drone], "Drone", 0, OpenComputers, 80, 1, true) OpenComputers.log.info("Initializing mod integration.") Mods.init() + OpenComputers.log.info("Initializing Recipes.") + Recipes.init() } def postInit(e: FMLPostInitializationEvent) { diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala index 06dde6562..fe2328eb7 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -2,6 +2,7 @@ package li.cil.oc.common.recipe import java.io.File import java.io.FileReader +import java.util import com.typesafe.config._ import cpw.mods.fml.common.Loader @@ -22,6 +23,7 @@ import net.minecraft.item.ItemStack import net.minecraft.item.crafting.FurnaceRecipes import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.RegistryNamespaced +import net.minecraftforge.fluids.{Fluid, FluidRegistry} import net.minecraftforge.oredict.OreDictionary import net.minecraftforge.oredict.RecipeSorter import net.minecraftforge.oredict.RecipeSorter.Category @@ -34,6 +36,12 @@ object Recipes { val list = mutable.LinkedHashMap.empty[ItemStack, String] val oreDictEntries = mutable.LinkedHashMap.empty[String, ItemStack] var hadErrors = false + val recipeMap = mutable.LinkedHashMap.empty[String, (ItemStack, Config) => Unit] + + + def registerRecipe(name: String, recipe: (ItemStack, Config) => Unit): Unit = { + recipeMap += name -> recipe + } def addBlock(instance: Block, name: String, oreDict: String = null) = { Items.registerBlock(instance, name) @@ -254,21 +262,10 @@ object Recipes { val recipe = list.getConfig(name) val recipeType = tryGetType(recipe) try { - recipeType match { - case "shaped" => addShapedRecipe(output, recipe) - case "shapeless" => addShapelessRecipe(output, recipe) - case "furnace" => addFurnaceRecipe(output, recipe) - case "gt_assembler" => - if (Mods.GregTech.isAvailable) { - addGTAssemblingMachineRecipe(output, recipe) - } - else { - OpenComputers.log.error(s"Skipping GregTech assembler recipe for '$name' because GregTech is not present, you will not be able to craft this item.") - hadErrors = true - } - case other => - OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid recipe type '$other'.") - hadErrors = true + recipeMap.get(recipeType) match { + case Some(x) => x(output, recipe) + case _ => OpenComputers.log.error(s"Failed adding $recipeType recipe for '$name', you will not be able to craft this item!") + } } catch { @@ -291,106 +288,79 @@ object Recipes { hadErrors = true } } - catch { - case e: Throwable => - OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item.", e) - hadErrors = true + + // private def addRecipe(output: ItemStack, list: Config, name: String) = try { + // if (list.hasPath(name)) { + // val value = list.getValue(name) + // value.valueType match { + // case ConfigValueType.OBJECT => + // val recipe = list.getConfig(name) + // val recipeType = tryGetType(recipe) + // try { + // recipeType match { + // case "shaped" => addShapedRecipe(output, recipe) + // case "shapeless" => addShapelessRecipe(output, recipe) + // case "furnace" => addFurnaceRecipe(output, recipe) + // case "gt_assembler" => + // if (Mods.GregTech.isAvailable) { + // addGTAssemblingMachineRecipe(output, recipe) + // } + // else { + // OpenComputers.log.error(s"Skipping GregTech assembler recipe for '$name' because GregTech is not present, you will not be able to craft this item.") + // hadErrors = true + // } + // case "gt_alloysmelter" => + // if (Mods.GregTech.isAvailable) { + // addGTAlloySmelterRecipe(output, recipe) + // } + // else { + // OpenComputers.log.error(s"Skipping GregTech alloy smelter recipe for '$name' because GregTech is not present, you will not be able to craft this item.") + // hadErrors = true + // } + // case other => + // OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid recipe type '$other'.") + // hadErrors = true + // } + // } + // catch { + // case e: RecipeException => + // OpenComputers.log.error(s"Failed adding $recipeType recipe for '$name', you will not be able to craft this item! The error was: ${e.getMessage}") + // hadErrors = true + // } + // case ConfigValueType.BOOLEAN => + // // Explicitly disabled, keep in NEI if true. + // if (!value.unwrapped.asInstanceOf[Boolean]) { + // hide(output) + // } + // case _ => + // OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid value for recipe.") + // hadErrors = true + // } + // } + // else { + // OpenComputers.log.warn(s"No recipe for '$name', you will not be able to craft this item. To suppress this warning, disable the recipe (assign `false` to it).") + // hadErrors = true + // } + // } + // catch { + // case e: Throwable => + // OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item.", e) + // hadErrors = true + // } + + + def parseFluidIngredient(entry: AnyRef): Option[Fluid] = entry match { + case name: String => { + if (name == null || name.trim.isEmpty) None + else if (FluidRegistry.getFluid(name) != null) Option(FluidRegistry.getFluid(name)) + else None + } + case _ => None + } - private def addShapedRecipe(output: ItemStack, recipe: Config) { - val rows = recipe.getList("input").unwrapped().map { - case row: java.util.List[AnyRef]@unchecked => row.map(parseIngredient) - case other => throw new RecipeException(s"Invalid row entry for shaped recipe (not a list: $other).") - } - output.stackSize = tryGetCount(recipe) - var number = -1 - var shape = mutable.ArrayBuffer.empty[String] - val input = mutable.ArrayBuffer.empty[AnyRef] - for (row <- rows) { - val (pattern, ingredients) = row.foldLeft((new StringBuilder, Seq.empty[AnyRef]))((acc, ingredient) => { - val (pattern, ingredients) = acc - ingredient match { - case _@(_: ItemStack | _: String) => - number += 1 - (pattern.append(('a' + number).toChar), ingredients ++ Seq(Char.box(('a' + number).toChar), ingredient)) - case _ => (pattern.append(' '), ingredients) - } - }) - shape += pattern.toString - input ++= ingredients - } - if (input.size > 0 && output.stackSize > 0) { - GameRegistry.addRecipe(new ExtendedShapedOreRecipe(output, shape ++ input: _*)) - } - } - - private def addShapelessRecipe(output: ItemStack, recipe: Config) { - val input = recipe.getValue("input").unwrapped() match { - case list: java.util.List[AnyRef]@unchecked => list.map(parseIngredient) - case other => Seq(parseIngredient(other)) - } - output.stackSize = tryGetCount(recipe) - - if (input.size > 0 && output.stackSize > 0) { - GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(output, input: _*)) - } - } - - private def addGTAssemblingMachineRecipe(output: ItemStack, recipe: Config) { - val inputs = (recipe.getValue("input").unwrapped() match { - case list: java.util.List[AnyRef]@unchecked => list.map(parseIngredient) - case other => Seq(parseIngredient(other)) - }) map { - case null => Array.empty[ItemStack] - case stack: ItemStack => Array(stack) - case name: String => Array(OreDictionary.getOres(name): _*) - case other => throw new RecipeException(s"Invalid ingredient type: $other.") - } - output.stackSize = tryGetCount(recipe) - - if (inputs.size < 1 || inputs.size > 2) { - throw new RecipeException(s"Invalid recipe length: ${inputs.size}, should be 1 or 2.") - } - - val inputCount = recipe.getIntList("count") - if (inputCount.size() != inputs.size) { - throw new RecipeException(s"Ingredient and input count mismatch: ${inputs.size} != ${inputCount.size}.") - } - - val eu = recipe.getInt("eu") - val duration = recipe.getInt("time") - - (inputs, inputCount).zipped.foreach((stacks, count) => stacks.foreach(stack => if (stack != null && count > 0) stack.stackSize = stack.getMaxStackSize min count)) - inputs.padTo(2, null) - - if (inputs.head != null) { - for (input1 <- inputs.head) { - if (inputs.last != null) { - for (input2 <- inputs.last) - gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, input2, output, duration, eu) - } - else gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, null, output, duration, eu) - } - } - } - - private def addFurnaceRecipe(output: ItemStack, recipe: Config) { - val input = parseIngredient(recipe.getValue("input").unwrapped()) - output.stackSize = tryGetCount(recipe) - - input match { - case stack: ItemStack => - FurnaceRecipes.smelting.func_151394_a(stack, output, 0) - case name: String => - for (stack <- OreDictionary.getOres(name)) { - FurnaceRecipes.smelting.func_151394_a(stack, output, 0) - } - case _ => - } - } - - private def parseIngredient(entry: AnyRef) = entry match { + def parseIngredient(entry: AnyRef) = entry match { case map: java.util.Map[AnyRef, AnyRef]@unchecked => if (map.contains("oreDict")) { map.get("oreDict") match { @@ -453,7 +423,7 @@ object Recipes { private def tryGetType(recipe: Config) = if (recipe.hasPath("type")) recipe.getString("type") else "shaped" - private def tryGetCount(recipe: Config) = if (recipe.hasPath("output")) recipe.getInt("output") else 1 + def tryGetCount(recipe: Config) = if (recipe.hasPath("output")) recipe.getInt("output") else 1 private def tryGetId(ingredient: java.util.Map[AnyRef, AnyRef]): Int = if (ingredient.contains("subID")) ingredient.get("subID") match { @@ -492,6 +462,6 @@ object Recipes { } } - private class RecipeException(message: String) extends RuntimeException(message) + class RecipeException(message: String) extends RuntimeException(message) } diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index 49198bd73..dadd4cec3 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -40,7 +40,7 @@ object Mods { val Forestry = new SimpleMod(IDs.Forestry) val ForgeMultipart = new SimpleMod(IDs.ForgeMultipart) val Galacticraft = new SimpleMod(IDs.Galacticraft, providesPower = true) - val GregTech = new ClassBasedMod(IDs.GregTech,"gregtech.api.GregTech_API")() + val GregTech = new ClassBasedMod(IDs.GregTech, "gregtech.api.GregTech_API")() val IndustrialCraft2 = new SimpleMod(IDs.IndustrialCraft2, providesPower = true) val IndustrialCraft2Classic = new SimpleMod(IDs.IndustrialCraft2Classic, providesPower = true) val Mekanism = new SimpleMod(IDs.Mekanism, providesPower = true) @@ -155,7 +155,8 @@ object Mods { final val Factorization = "factorization" final val Forestry = "Forestry" final val ForgeMultipart = "ForgeMultipart" - final val DeepStorageUnit = "MineFactoryReloaded|DeepStorageUnit" // Doesn't really exist. + final val DeepStorageUnit = "MineFactoryReloaded|DeepStorageUnit" + // Doesn't really exist. final val Galacticraft = "Galacticraft API" final val GregTech = "gregtech" final val IndustrialCraft2 = "IC2" diff --git a/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala b/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala index 4ea66e917..a4400b938 100644 --- a/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala +++ b/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala @@ -15,5 +15,7 @@ object ModGregtech extends ModProxy { MinecraftForge.EVENT_BUS.register(EventHandlerGregTech) Driver.add(new DriverEnergyContainer) + + RecipeRegistry.init() } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/gregtech/RecipeRegistry.scala b/src/main/scala/li/cil/oc/integration/gregtech/RecipeRegistry.scala new file mode 100644 index 000000000..d5808e2ca --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/gregtech/RecipeRegistry.scala @@ -0,0 +1,236 @@ +package li.cil.oc.integration.gregtech + +import java.util + +import com.typesafe.config.Config +import li.cil.oc.common.recipe.Recipes +import li.cil.oc.common.recipe.Recipes.RecipeException +import net.minecraft.item.ItemStack +import net.minecraftforge.fluids.FluidStack +import net.minecraftforge.oredict.OreDictionary + +import scala.collection.convert.WrapAsScala._ + +object RecipeRegistry { + + def getGTRecipesWithEU(output: ItemStack, recipe: Config): (Array[ItemStack], Option[Array[ItemStack]], Option[FluidStack], Option[FluidStack], Option[ItemStack], Int, Int) = { + + val inputs = (recipe.getValue("input").unwrapped() match { + case list: util.List[AnyRef]@unchecked => list.map(Recipes.parseIngredient) + case other => Seq(Recipes.parseIngredient(other)) + }) map { + case null => Array.empty[ItemStack] + case stack: ItemStack => Array(stack) + case name: String => Array(OreDictionary.getOres(name): _*) + case other => throw new RecipeException(s"Invalid ingredient type: $other.") + } + output.stackSize = Recipes.tryGetCount(recipe) + + if (inputs.size < 1 || inputs.size > 2) { + throw new RecipeException(s"Invalid recipe length: ${inputs.size}, should be 1 or 2.") + } + + val inputCount = recipe.getIntList("count") + if (inputCount.size() != inputs.size) { + throw new RecipeException(s"Ingredient and input count mismatch: ${inputs.size} != ${inputCount.size}.") + } + + var inputFluidStack: Option[FluidStack] = None: Option[FluidStack] + if (recipe.hasPath("inputLiquid")) Recipes.parseFluidIngredient(recipe.getString("inputLiquid")) match { + case Some(fluid) => + var inputFluidAmount = 1000 + if (recipe.hasPath("inputFluidAmount")) inputFluidAmount = recipe.getInt("inputFluidAmount") + inputFluidStack = Option(new FluidStack(fluid, inputFluidAmount)) + case _ => + } + + var outputFluidStack: Option[FluidStack] = None: Option[FluidStack] + if (recipe.hasPath("outputLiquid")) Recipes.parseFluidIngredient(recipe.getString("outputLiquid")) match { + case Some(fluid) => + var fluidAmount = 1000 + if (recipe.hasPath("outputFluidAmount")) fluidAmount = recipe.getInt("outputFluidAmount") + outputFluidStack = Option(new FluidStack(fluid, fluidAmount)) + case _ => + } + + val eu = recipe.getInt("eu") + val duration = recipe.getInt("time") + + //TODO add output + val additionalOutput: Option[ItemStack] = None + + (inputs, inputCount).zipped.foreach((stacks, count) => stacks.foreach(stack => if (stack != null && count > 0) stack.stackSize = stack.getMaxStackSize min count)) + inputs.padTo(2, null) + val input = inputs.head + (input, Option(inputs.last), inputFluidStack, outputFluidStack, additionalOutput, eu, duration) + } + + def addGTAlloySmelterRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + for (input1 <- inputs1) { + inputs2 match { + case Some(inputs2List) => + for (input2 <- inputs2List) + gregtech.api.GregTech_API.sRecipeAdder.addAlloySmelterRecipe(input1, input2, output, duration, eu) + case None => + gregtech.api.GregTech_API.sRecipeAdder.addAlloySmelterRecipe(input1, null, output, duration, eu) + } + } + } + + def addGTAssemblingMachineRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + for (input1 <- inputs1) { + inputs2 match { + case Some(inputs2List) => + for (input2 <- inputs2List) + fluidStackIn match { + case Some(fluid) => + + gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, input2, fluid, output, duration, eu) + case None => + gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, input2, output, duration, eu) + } + + case None => + fluidStackIn match { + case Some(fluid) => + gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, null, fluid, output, duration, eu) + case None => + gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, null, output, duration, eu) + } + } + } + } + + def addGTBenderRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + for (input1 <- inputs1) { + gregtech.api.GregTech_API.sRecipeAdder.addBenderRecipe(input1, output, duration, eu) + } + } + + def addGTCutterRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + var add :ItemStack = null + additionalOutput match{ + case Some(a) => add = a + case _=> + } + for (input1 <- inputs1) { + fluidStackIn match { + case Some(fluid) => + gregtech.api.GregTech_API.sRecipeAdder.addCutterRecipe(input1, fluid, output, add, duration, eu) + + case None => + gregtech.api.GregTech_API.sRecipeAdder.addCutterRecipe(input1, output, add, duration, eu) + } + } + } + + def addGTCannerRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + var add :ItemStack = null + additionalOutput match{ + case Some(a) => add = a + case _=> + } + for (input1 <- inputs1) { + inputs2 match { + case Some(inputs2List) => + for (input2 <- inputs2List) + gregtech.api.GregTech_API.sRecipeAdder.addCannerRecipe(input1, input2, output, add, duration, eu) + case None => + gregtech.api.GregTech_API.sRecipeAdder.addCannerRecipe(input1, null, output, add, duration, eu) + + + } + } + } + + def addGTChemicalRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + for (input1 <- inputs1) { + inputs2 match { + case Some(inputs2List) => + for (input2 <- inputs2List) + fluidStackIn match { + case Some(fluid) => + fluidStackOut match { + case Some(fluidOut) => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, input2, fluid, fluidOut, output, duration) + + case _ => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, input2, fluid, null, output, duration) + } + case None => + fluidStackOut match { + case Some(fluidOut) => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, input2, null, fluidOut, output, duration) + case _ => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, input2, output, duration) + } + } + + case None => + fluidStackIn match { + case Some(fluid) => + fluidStackOut match { + case Some(fluidOut) => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, null, fluid, fluidOut, output, duration) + + case _ => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, null, fluid, null, output, duration) + } + case None => + fluidStackOut match { + case Some(fluidOut) => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, null, null, fluidOut, output, duration) + case _ => + gregtech.api.GregTech_API.sRecipeAdder.addChemicalRecipe(input1, null, output, duration) + } + } + } + } + } + + def addGTCNCRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + for (input1 <- inputs1) { + gregtech.api.GregTech_API.sRecipeAdder.addCNCRecipe(input1, output, duration, eu) + } + } + + def addGTLatheRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + var add :ItemStack = null + additionalOutput match{ + case Some(a) => add = a + case _=> + } + for (input1 <- inputs1) { + gregtech.api.GregTech_API.sRecipeAdder.addLatheRecipe(input1, output, add, duration, eu) + } + } + + def addGTWireMillRecipe(output: ItemStack, recipe: Config) { + val (inputs1, inputs2, fluidStackIn, fluidStackOut, additionalOutput, eu, duration) = getGTRecipesWithEU(output, recipe) + for (input1 <- inputs1) { + gregtech.api.GregTech_API.sRecipeAdder.addWiremillRecipe(input1, output, duration, eu) + } + } + + + def init(): Unit = { + Recipes.registerRecipe("gt_alloySmelter", addGTAlloySmelterRecipe) + Recipes.registerRecipe("gt_assembler", addGTAssemblingMachineRecipe) + Recipes.registerRecipe("gt_bender", addGTBenderRecipe) + Recipes.registerRecipe("gt_canner", addGTCannerRecipe) + Recipes.registerRecipe("gt_chemical", addGTChemicalRecipe) + Recipes.registerRecipe("gt_cnc", addGTCNCRecipe) + Recipes.registerRecipe("gt_cutter", addGTCutterRecipe) + Recipes.registerRecipe("gt_lathe", addGTLatheRecipe) + Recipes.registerRecipe("gt_wiremill", addGTWireMillRecipe) + + } +} diff --git a/src/main/scala/li/cil/oc/integration/vanilla/ModVanilla.scala b/src/main/scala/li/cil/oc/integration/vanilla/ModVanilla.scala index d428dc3a1..5aeae9039 100644 --- a/src/main/scala/li/cil/oc/integration/vanilla/ModVanilla.scala +++ b/src/main/scala/li/cil/oc/integration/vanilla/ModVanilla.scala @@ -34,5 +34,6 @@ object ModVanilla extends ModProxy { Driver.add(ConverterNBT) Driver.add(ConverterWorld) Driver.add(ConverterWorldProvider) + RecipeRegistry.init() } } diff --git a/src/main/scala/li/cil/oc/integration/vanilla/RecipeRegistry.scala b/src/main/scala/li/cil/oc/integration/vanilla/RecipeRegistry.scala new file mode 100644 index 000000000..007685b7b --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/vanilla/RecipeRegistry.scala @@ -0,0 +1,76 @@ +package li.cil.oc.integration.vanilla + +import com.typesafe.config.Config +import cpw.mods.fml.common.registry.GameRegistry +import li.cil.oc.common.recipe.Recipes.RecipeException +import li.cil.oc.common.recipe.{Recipes, ExtendedShapelessOreRecipe, ExtendedShapedOreRecipe} +import net.minecraft.item.ItemStack +import net.minecraft.item.crafting.FurnaceRecipes +import net.minecraftforge.oredict.OreDictionary + +import scala.collection.convert.WrapAsScala._ +import scala.collection.mutable + +object RecipeRegistry { + + def addShapedRecipe(output: ItemStack, recipe: Config) { + val rows = recipe.getList("input").unwrapped().map { + case row: java.util.List[AnyRef]@unchecked => row.map(Recipes.parseIngredient) + case other => throw new RecipeException(s"Invalid row entry for shaped recipe (not a list: $other).") + } + output.stackSize = Recipes.tryGetCount(recipe) + + var number = -1 + var shape = mutable.ArrayBuffer.empty[String] + val input = mutable.ArrayBuffer.empty[AnyRef] + for (row <- rows) { + val (pattern, ingredients) = row.foldLeft((new StringBuilder, Seq.empty[AnyRef]))((acc, ingredient) => { + val (pattern, ingredients) = acc + ingredient match { + case _@(_: ItemStack | _: String) => + number += 1 + (pattern.append(('a' + number).toChar), ingredients ++ Seq(Char.box(('a' + number).toChar), ingredient)) + case _ => (pattern.append(' '), ingredients) + } + }) + shape += pattern.toString + input ++= ingredients + } + if (input.size > 0 && output.stackSize > 0) { + GameRegistry.addRecipe(new ExtendedShapedOreRecipe(output, shape ++ input: _*)) + } + } + + def addShapelessRecipe(output: ItemStack, recipe: Config) { + val input = recipe.getValue("input").unwrapped() match { + case list: java.util.List[AnyRef]@unchecked => list.map(Recipes.parseIngredient) + case other => Seq(Recipes.parseIngredient(other)) + } + output.stackSize = Recipes.tryGetCount(recipe) + + if (input.size > 0 && output.stackSize > 0) { + GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(output, input: _*)) + } + } + + def addFurnaceRecipe(output: ItemStack, recipe: Config) { + val input = Recipes.parseIngredient(recipe.getValue("input").unwrapped()) + output.stackSize = Recipes.tryGetCount(recipe) + + input match { + case stack: ItemStack => + FurnaceRecipes.smelting.func_151394_a(stack, output, 0) + case name: String => + for (stack <- OreDictionary.getOres(name)) { + FurnaceRecipes.smelting.func_151394_a(stack, output, 0) + } + case _ => + } + } + + def init(): Unit = { + Recipes.registerRecipe("shaped", addShapedRecipe) + Recipes.registerRecipe("shapeless", addShapelessRecipe) + Recipes.registerRecipe("furnace", addFurnaceRecipe) + } +}