| package li.cil.oc.util |
| |
| import java.util.Random |
| |
| import li.cil.oc.Constants |
| import li.cil.oc.OpenComputers |
| import li.cil.oc.Settings |
| import li.cil.oc.api |
| import li.cil.oc.common.Tier |
| import net.minecraft.block.Block |
| import net.minecraft.item.Item |
| import net.minecraft.item.ItemBlock |
| import net.minecraft.item.ItemBucket |
| import net.minecraft.item.ItemStack |
| import net.minecraft.item.crafting.CraftingManager |
| import net.minecraft.item.crafting.IRecipe |
| import net.minecraft.item.crafting.ShapedRecipes |
| import net.minecraft.item.crafting.ShapelessRecipes |
| import net.minecraftforge.oredict.ShapedOreRecipe |
| import net.minecraftforge.oredict.ShapelessOreRecipe |
| |
| import scala.collection.convert.WrapAsScala._ |
| import scala.collection.mutable |
| |
| object ItemUtils { |
| def caseTier(stack: ItemStack) = { |
| val descriptor = api.Items.get(stack) |
| if (descriptor == api.Items.get(Constants.BlockName.CaseTier1)) Tier.One |
| else if (descriptor == api.Items.get(Constants.BlockName.CaseTier2)) Tier.Two |
| else if (descriptor == api.Items.get(Constants.BlockName.CaseTier3)) Tier.Three |
| else if (descriptor == api.Items.get(Constants.BlockName.CaseCreative)) Tier.Four |
| else if (descriptor == api.Items.get(Constants.ItemName.MicrocontrollerCaseTier1)) Tier.One |
| else if (descriptor == api.Items.get(Constants.ItemName.MicrocontrollerCaseTier2)) Tier.Two |
| else if (descriptor == api.Items.get(Constants.ItemName.MicrocontrollerCaseCreative)) Tier.Four |
| else if (descriptor == api.Items.get(Constants.ItemName.DroneCaseTier1)) Tier.One |
| else if (descriptor == api.Items.get(Constants.ItemName.DroneCaseTier2)) Tier.Two |
| else if (descriptor == api.Items.get(Constants.ItemName.DroneCaseCreative)) Tier.Four |
| else if (descriptor == api.Items.get(Constants.ItemName.ServerTier1)) Tier.One |
| else if (descriptor == api.Items.get(Constants.ItemName.ServerTier2)) Tier.Two |
| else if (descriptor == api.Items.get(Constants.ItemName.ServerTier3)) Tier.Three |
| else if (descriptor == api.Items.get(Constants.ItemName.ServerCreative)) Tier.Four |
| else if (descriptor == api.Items.get(Constants.ItemName.TabletCaseTier1)) Tier.One |
| else if (descriptor == api.Items.get(Constants.ItemName.TabletCaseTier2)) Tier.Two |
| else if (descriptor == api.Items.get(Constants.ItemName.TabletCaseCreative)) Tier.Four |
| else Tier.None |
| } |
| |
| def caseNameWithTierSuffix(name: String, tier: Int) = name + (if (tier == Tier.Four) "Creative" else (tier + 1).toString) |
| |
| def getIngredients(stack: ItemStack): Array[ItemStack] = try { |
| def getFilteredInputs(inputs: Iterable[ItemStack], outputSize: Int) = (inputs.filter(input => |
| input != null && |
| input.getItem != null && |
| input.stackSize / outputSize > 0 && |
| // Strip out buckets, because those are returned when crafting, and |
| // we have no way of returning the fluid only (and I can't be arsed |
| // to make it output fluids into fluiducts or such, sorry). |
| !input.getItem.isInstanceOf[ItemBucket]).toArray, outputSize) |
| def getOutputSize(recipe: IRecipe) = recipe.getRecipeOutput.stackSize |
| def isInputBlacklisted(stack: ItemStack) = stack.getItem match { |
| case item: ItemBlock => Settings.get.disassemblerInputBlacklist.contains(Block.blockRegistry.getNameForObject(item.field_150939_a)) |
| case item: Item => Settings.get.disassemblerInputBlacklist.contains(Item.itemRegistry.getNameForObject(item)) |
| case _ => false |
| } |
| |
| val (ingredients, count) = CraftingManager.getInstance.getRecipeList.map(_.asInstanceOf[IRecipe]). |
| filter(recipe => recipe.getRecipeOutput != null && recipe.getRecipeOutput.isItemEqual(stack)).collect { |
| case recipe: ShapedRecipes => getFilteredInputs(recipe.recipeItems.toIterable, getOutputSize(recipe)) |
| case recipe: ShapelessRecipes => getFilteredInputs(recipe.recipeItems.map(_.asInstanceOf[ItemStack]), getOutputSize(recipe)) |
| case recipe: ShapedOreRecipe => getFilteredInputs(resolveOreDictEntries(recipe.getInput), getOutputSize(recipe)) |
| case recipe: ShapelessOreRecipe => getFilteredInputs(resolveOreDictEntries(recipe.getInput), getOutputSize(recipe)) |
| }.collectFirst { |
| case (inputs, outputSize) if !inputs.exists(isInputBlacklisted) => (inputs, outputSize) |
| } match { |
| case Some((inputs, outputSize)) => (inputs, outputSize) |
| case _ => return Array.empty |
| } |
| |
| // Avoid positive feedback loops. |
| if (ingredients.exists(ingredient => ingredient.isItemEqual(stack))) { |
| return Array.empty[ItemStack] |
| } |
| // Merge equal items for size division by output size. |
| val merged = mutable.ArrayBuffer.empty[ItemStack] |
| for (ingredient <- ingredients) { |
| merged.find(_.isItemEqual(ingredient)) match { |
| case Some(entry) => entry.stackSize += ingredient.stackSize |
| case _ => merged += ingredient.copy() |
| } |
| } |
| merged.foreach(_.stackSize /= count) |
| // Split items up again to 'disassemble them individually'. |
| val distinct = mutable.ArrayBuffer.empty[ItemStack] |
| for (ingredient <- merged) { |
| val size = ingredient.stackSize max 1 |
| ingredient.stackSize = 1 |
| for (i <- 0 until size) { |
| distinct += ingredient.copy() |
| } |
| } |
| distinct.toArray |
| } |
| catch { |
| case t: Throwable => |
| OpenComputers.log.warn("Whoops, something went wrong when trying to figure out an item's parts.", t) |
| Array.empty[ItemStack] |
| } |
| |
| private lazy val rng = new Random() |
| |
| private def resolveOreDictEntries[T](entries: Iterable[T]) = entries.collect { |
| case stack: ItemStack => stack |
| case list: java.util.ArrayList[ItemStack]@unchecked if !list.isEmpty => list.get(rng.nextInt(list.size)) |
| } |
| |
| } |