package org.bukkit.inventory; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.material.MaterialData; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Represents a shapeless recipe, where the arrangement of the ingredients on * the crafting grid does not matter. */ public class ShapelessRecipe implements Recipe { private ItemStack output; private List<ItemStack> ingredients = new ArrayList<ItemStack>(); /** * Create a shapeless recipe to craft the specified ItemStack. The * constructor merely determines the result and type; to set the actual * recipe, you'll need to call the appropriate methods. * * @param result The item you want the recipe to create. * @see ShapelessRecipe#addIngredient(Material) * @see ShapelessRecipe#addIngredient(MaterialData) * @see ShapelessRecipe#addIngredient(Material, int) * @see ShapelessRecipe#addIngredient(int, Material) * @see ShapelessRecipe#addIngredient(int, MaterialData) * @see ShapelessRecipe#addIngredient(int, Material, int) */ public ShapelessRecipe(ItemStack result) { this.output = new ItemStack(result); } /** * Adds the specified ingredient. * * @param ingredient The ingredient to add. * @return The changed recipe, so you can chain calls. */ public ShapelessRecipe addIngredient(MaterialData ingredient) { return addIngredient(1, ingredient); } /** * Adds the specified ingredient. * * @param ingredient The ingredient to add. * @return The changed recipe, so you can chain calls. */ public ShapelessRecipe addIngredient(Material ingredient) { return addIngredient(1, ingredient, 0); } /** * Adds the specified ingredient. * * @param ingredient The ingredient to add. * @param rawdata The data value, or -1 to allow any data value. * @return The changed recipe, so you can chain calls. * @deprecated Magic value */ @Deprecated public ShapelessRecipe addIngredient(Material ingredient, int rawdata) { return addIngredient(1, ingredient, rawdata); } /** * Adds multiples of the specified ingredient. * * @param count How many to add (can't be more than 9!) * @param ingredient The ingredient to add. * @return The changed recipe, so you can chain calls. */ public ShapelessRecipe addIngredient(int count, MaterialData ingredient) { return addIngredient(count, ingredient.getItemType(), ingredient.getData()); } /** * Adds multiples of the specified ingredient. * * @param count How many to add (can't be more than 9!) * @param ingredient The ingredient to add. * @return The changed recipe, so you can chain calls. */ public ShapelessRecipe addIngredient(int count, Material ingredient) { return addIngredient(count, ingredient, 0); } /** * Adds multiples of the specified ingredient. * * @param count How many to add (can't be more than 9!) * @param ingredient The ingredient to add. * @param rawdata The data value, or -1 to allow any data value. * @return The changed recipe, so you can chain calls. * @deprecated Magic value */ @Deprecated public ShapelessRecipe addIngredient(int count, Material ingredient, int rawdata) { Validate.isTrue(ingredients.size() + count <= 9, "Shapeless recipes cannot have more than 9 ingredients"); // -1 is the old wildcard, map to Short.MAX_VALUE as the new one if(rawdata == -1) { rawdata = Short.MAX_VALUE; } while(count-- > 0) { ingredients.add(new ItemStack(ingredient, 1, (short) rawdata)); } return this; } /** * Removes an ingredient from the list. If the ingredient occurs multiple * times, only one instance of it is removed. Only removes exact matches, * with a data value of 0. * * @param ingredient The ingredient to remove * @return The changed recipe. */ public ShapelessRecipe removeIngredient(Material ingredient) { return removeIngredient(ingredient, 0); } /** * Removes an ingredient from the list. If the ingredient occurs multiple * times, only one instance of it is removed. If the data value is -1, * only ingredients with a -1 data value will be removed. * * @param ingredient The ingredient to remove * @return The changed recipe. */ public ShapelessRecipe removeIngredient(MaterialData ingredient) { return removeIngredient(ingredient.getItemType(), ingredient.getData()); } /** * Removes multiple instances of an ingredient from the list. If there are * less instances then specified, all will be removed. Only removes exact * matches, with a data value of 0. * * @param count The number of copies to remove. * @param ingredient The ingredient to remove * @return The changed recipe. */ public ShapelessRecipe removeIngredient(int count, Material ingredient) { return removeIngredient(count, ingredient, 0); } /** * Removes multiple instances of an ingredient from the list. If there are * less instances then specified, all will be removed. If the data value * is -1, only ingredients with a -1 data value will be removed. * * @param count The number of copies to remove. * @param ingredient The ingredient to remove. * @return The changed recipe. */ public ShapelessRecipe removeIngredient(int count, MaterialData ingredient) { return removeIngredient(count, ingredient.getItemType(), ingredient.getData()); } /** * Removes an ingredient from the list. If the ingredient occurs multiple * times, only one instance of it is removed. If the data value is -1, * only ingredients with a -1 data value will be removed. * * @param ingredient The ingredient to remove * @param rawdata The data value; * @return The changed recipe. * @deprecated Magic value */ @Deprecated public ShapelessRecipe removeIngredient(Material ingredient, int rawdata) { return removeIngredient(1, ingredient, rawdata); } /** * Removes multiple instances of an ingredient from the list. If there are * less instances then specified, all will be removed. If the data value * is -1, only ingredients with a -1 data value will be removed. * * @param count The number of copies to remove. * @param ingredient The ingredient to remove. * @param rawdata The data value. * @return The changed recipe. * @deprecated Magic value */ @Deprecated public ShapelessRecipe removeIngredient(int count, Material ingredient, int rawdata) { Iterator<ItemStack> iterator = ingredients.iterator(); while(count > 0 && iterator.hasNext()) { ItemStack stack = iterator.next(); if(stack.getType() == ingredient && stack.getDurability() == rawdata) { iterator.remove(); count--; } } return this; } /** * Get the result of this recipe. * * @return The result stack. */ public ItemStack getResult() { return output.clone(); } /** * Get the list of ingredients used for this recipe. * * @return The input list */ public List<ItemStack> getIngredientList() { ArrayList<ItemStack> result = new ArrayList<ItemStack>(ingredients.size()); for(ItemStack ingredient : ingredients) { result.add(ingredient.clone()); } return result; } }