001 package org.bukkit.inventory; 002 003 import java.util.ArrayList; 004 import java.util.Iterator; 005 import java.util.List; 006 007 import org.apache.commons.lang.Validate; 008 009 import org.bukkit.Material; 010 import org.bukkit.material.MaterialData; 011 012 /** 013 * Represents a shapeless recipe, where the arrangement of the ingredients on 014 * the crafting grid does not matter. 015 */ 016 public class ShapelessRecipe implements Recipe { 017 private ItemStack output; 018 private List<ItemStack> ingredients = new ArrayList<ItemStack>(); 019 020 /** 021 * Create a shapeless recipe to craft the specified ItemStack. The 022 * constructor merely determines the result and type; to set the actual 023 * recipe, you'll need to call the appropriate methods. 024 * 025 * @param result The item you want the recipe to create. 026 * @see ShapelessRecipe#addIngredient(Material) 027 * @see ShapelessRecipe#addIngredient(MaterialData) 028 * @see ShapelessRecipe#addIngredient(Material,int) 029 * @see ShapelessRecipe#addIngredient(int,Material) 030 * @see ShapelessRecipe#addIngredient(int,MaterialData) 031 * @see ShapelessRecipe#addIngredient(int,Material,int) 032 */ 033 public ShapelessRecipe(ItemStack result) { 034 this.output = new ItemStack(result); 035 } 036 037 /** 038 * Adds the specified ingredient. 039 * 040 * @param ingredient The ingredient to add. 041 * @return The changed recipe, so you can chain calls. 042 */ 043 public ShapelessRecipe addIngredient(MaterialData ingredient) { 044 return addIngredient(1, ingredient); 045 } 046 047 /** 048 * Adds the specified ingredient. 049 * 050 * @param ingredient The ingredient to add. 051 * @return The changed recipe, so you can chain calls. 052 */ 053 public ShapelessRecipe addIngredient(Material ingredient) { 054 return addIngredient(1, ingredient, 0); 055 } 056 057 /** 058 * Adds the specified ingredient. 059 * 060 * @param ingredient The ingredient to add. 061 * @param rawdata The data value, or -1 to allow any data value. 062 * @return The changed recipe, so you can chain calls. 063 * @deprecated Magic value 064 */ 065 @Deprecated 066 public ShapelessRecipe addIngredient(Material ingredient, int rawdata) { 067 return addIngredient(1, ingredient, rawdata); 068 } 069 070 /** 071 * Adds multiples of the specified ingredient. 072 * 073 * @param count How many to add (can't be more than 9!) 074 * @param ingredient The ingredient to add. 075 * @return The changed recipe, so you can chain calls. 076 */ 077 public ShapelessRecipe addIngredient(int count, MaterialData ingredient) { 078 return addIngredient(count, ingredient.getItemType(), ingredient.getData()); 079 } 080 081 /** 082 * Adds multiples of the specified ingredient. 083 * 084 * @param count How many to add (can't be more than 9!) 085 * @param ingredient The ingredient to add. 086 * @return The changed recipe, so you can chain calls. 087 */ 088 public ShapelessRecipe addIngredient(int count, Material ingredient) { 089 return addIngredient(count, ingredient, 0); 090 } 091 092 /** 093 * Adds multiples of the specified ingredient. 094 * 095 * @param count How many to add (can't be more than 9!) 096 * @param ingredient The ingredient to add. 097 * @param rawdata The data value, or -1 to allow any data value. 098 * @return The changed recipe, so you can chain calls. 099 * @deprecated Magic value 100 */ 101 @Deprecated 102 public ShapelessRecipe addIngredient(int count, Material ingredient, int rawdata) { 103 Validate.isTrue(ingredients.size() + count <= 9, "Shapeless recipes cannot have more than 9 ingredients"); 104 105 // -1 is the old wildcard, map to Short.MAX_VALUE as the new one 106 if (rawdata == -1) { 107 rawdata = Short.MAX_VALUE; 108 } 109 110 while (count-- > 0) { 111 ingredients.add(new ItemStack(ingredient, 1, (short) rawdata)); 112 } 113 return this; 114 } 115 116 /** 117 * Removes an ingredient from the list. If the ingredient occurs multiple 118 * times, only one instance of it is removed. Only removes exact matches, 119 * with a data value of 0. 120 * 121 * @param ingredient The ingredient to remove 122 * @return The changed recipe. 123 */ 124 public ShapelessRecipe removeIngredient(Material ingredient) { 125 return removeIngredient(ingredient, 0); 126 } 127 128 /** 129 * Removes an ingredient from the list. If the ingredient occurs multiple 130 * times, only one instance of it is removed. If the data value is -1, 131 * only ingredients with a -1 data value will be removed. 132 * 133 * @param ingredient The ingredient to remove 134 * @return The changed recipe. 135 */ 136 public ShapelessRecipe removeIngredient(MaterialData ingredient) { 137 return removeIngredient(ingredient.getItemType(), ingredient.getData()); 138 } 139 140 /** 141 * Removes multiple instances of an ingredient from the list. If there are 142 * less instances then specified, all will be removed. Only removes exact 143 * matches, with a data value of 0. 144 * 145 * @param count The number of copies to remove. 146 * @param ingredient The ingredient to remove 147 * @return The changed recipe. 148 */ 149 public ShapelessRecipe removeIngredient(int count, Material ingredient) { 150 return removeIngredient(count, ingredient, 0); 151 } 152 153 /** 154 * Removes multiple instances of an ingredient from the list. If there are 155 * less instances then specified, all will be removed. If the data value 156 * is -1, only ingredients with a -1 data value will be removed. 157 * 158 * @param count The number of copies to remove. 159 * @param ingredient The ingredient to remove. 160 * @return The changed recipe. 161 */ 162 public ShapelessRecipe removeIngredient(int count, MaterialData ingredient) { 163 return removeIngredient(count, ingredient.getItemType(), ingredient.getData()); 164 } 165 166 /** 167 * Removes an ingredient from the list. If the ingredient occurs multiple 168 * times, only one instance of it is removed. If the data value is -1, 169 * only ingredients with a -1 data value will be removed. 170 * 171 * @param ingredient The ingredient to remove 172 * @param rawdata The data value; 173 * @return The changed recipe. 174 * @deprecated Magic value 175 */ 176 @Deprecated 177 public ShapelessRecipe removeIngredient(Material ingredient, int rawdata) { 178 return removeIngredient(1, ingredient, rawdata); 179 } 180 181 /** 182 * Removes multiple instances of an ingredient from the list. If there are 183 * less instances then specified, all will be removed. If the data value 184 * is -1, only ingredients with a -1 data value will be removed. 185 * 186 * @param count The number of copies to remove. 187 * @param ingredient The ingredient to remove. 188 * @param rawdata The data value. 189 * @return The changed recipe. 190 * @deprecated Magic value 191 */ 192 @Deprecated 193 public ShapelessRecipe removeIngredient(int count, Material ingredient, int rawdata) { 194 Iterator<ItemStack> iterator = ingredients.iterator(); 195 while (count > 0 && iterator.hasNext()) { 196 ItemStack stack = iterator.next(); 197 if (stack.getType() == ingredient && stack.getDurability() == rawdata) { 198 iterator.remove(); 199 count--; 200 } 201 } 202 return this; 203 } 204 205 /** 206 * Get the result of this recipe. 207 * 208 * @return The result stack. 209 */ 210 public ItemStack getResult() { 211 return output.clone(); 212 } 213 214 /** 215 * Get the list of ingredients used for this recipe. 216 * 217 * @return The input list 218 */ 219 public List<ItemStack> getIngredientList() { 220 ArrayList<ItemStack> result = new ArrayList<ItemStack>(ingredients.size()); 221 for (ItemStack ingredient : ingredients) { 222 result.add(ingredient.clone()); 223 } 224 return result; 225 } 226 }