Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[Bleeding] Add ways to retrieve and delete crafting recipes and fixed…

… some issues with the existing recipe API.

- New recipe iterator which enables deleting specific recipes
- Functions to delete all recipes or revert to vanilla recipe set
- Fixed the recipes API; you should now be able to define recipes that take brewed potions!
- Fetch all recipes that result in a specific item
  • Loading branch information...
commit 3604da1f55d241d6649ef2844b0fdfbd1a980a95 1 parent 870d10b
@CelticMinstrel CelticMinstrel authored EvilSeph committed
View
18 src/main/java/org/bukkit/Bukkit.java
@@ -1,6 +1,7 @@
package org.bukkit;
import java.io.File;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -11,6 +12,7 @@
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.map.MapView;
import org.bukkit.plugin.PluginManager;
@@ -192,6 +194,22 @@ public static boolean addRecipe(Recipe recipe) {
return server.addRecipe(recipe);
}
+ public List<Recipe> getRecipesFor(ItemStack result) {
+ return server.getRecipesFor(result);
+ }
+
+ public Iterator<Recipe> recipeIterator() {
+ return server.recipeIterator();
+ }
+
+ public void clearRecipes() {
+ server.clearRecipes();
+ }
+
+ public void resetRecipes() {
+ server.resetRecipes();
+ }
+
public static Map<String, String[]> getCommandAliases() {
return server.getCommandAliases();
}
View
30 src/main/java/org/bukkit/Server.java
@@ -1,6 +1,7 @@
package org.bukkit;
import java.io.File;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -12,6 +13,7 @@
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.map.MapView;
import org.bukkit.plugin.PluginManager;
@@ -382,11 +384,37 @@
* Adds a recipe to the crafting manager.
*
* @param recipe The recipe to add.
- * @return True to indicate that the recipe was added.
+ * @return True if the recipe was added, false if it wasn't for some reason.
*/
public boolean addRecipe(Recipe recipe);
/**
+ * Get a list of all recipes for a given item. The stack size is ignored in comparisons.
+ * If the durability is -1, it will match any data value.
+ *
+ * @param result The item whose recipes you want
+ * @return The list of recipes
+ */
+ public List<Recipe> getRecipesFor(ItemStack result);
+
+ /**
+ * Get an iterator through the list of crafting recipes.
+ *
+ * @return The iterator.
+ */
+ public Iterator<Recipe> recipeIterator();
+
+ /**
+ * Clears the list of crafting recipes.
+ */
+ public void clearRecipes();
+
+ /**
+ * Resets the list of crafting recipes to the default.
+ */
+ public void resetRecipes();
+
+ /**
* Gets a list of command aliases defined in the server properties.
*
* @return Map of aliases to command names
View
47 src/main/java/org/bukkit/inventory/FurnaceRecipe.java
@@ -8,7 +8,7 @@
*/
public class FurnaceRecipe implements Recipe {
private ItemStack output;
- private MaterialData ingredient;
+ private ItemStack ingredient;
/**
* Create a furnace recipe to craft the specified ItemStack.
@@ -17,10 +17,7 @@
* @param source The input material.
*/
public FurnaceRecipe(ItemStack result, Material source) {
- this(result, source.getNewData((byte) 0));
- if (this.ingredient == null) {
- setInput(new MaterialData(source));
- }
+ this(result, source, 0);
}
/**
@@ -30,8 +27,19 @@ public FurnaceRecipe(ItemStack result, Material source) {
* @param source The input material.
*/
public FurnaceRecipe(ItemStack result, MaterialData source) {
- this.output = result;
- this.ingredient = source;
+ this(result, source.getItemType(), source.getData());
+ }
+
+ /**
+ * Create a furnace recipe to craft the specified ItemStack.
+ *
+ * @param result The item you want the recipe to create.
+ * @param source The input material.
+ * @param data The data value. (Note: This is currently ignored by the CraftBukkit server.)
+ */
+ public FurnaceRecipe(ItemStack result, Material source, int data) {
+ this.output = new ItemStack(result);
+ this.ingredient = new ItemStack(source, 1, (short) data);
}
/**
@@ -41,8 +49,7 @@ public FurnaceRecipe(ItemStack result, MaterialData source) {
* @return The changed recipe, so you can chain calls.
*/
public FurnaceRecipe setInput(MaterialData input) {
- this.ingredient = input;
- return this;
+ return setInput(input.getItemType(), input.getData());
}
/**
@@ -52,10 +59,18 @@ public FurnaceRecipe setInput(MaterialData input) {
* @return The changed recipe, so you can chain calls.
*/
public FurnaceRecipe setInput(Material input) {
- setInput(input.getNewData((byte) 0));
- if (this.ingredient == null) {
- setInput(new MaterialData(input));
- }
+ return setInput(input, 0);
+ }
+
+ /**
+ * Sets the input of this furnace recipe.
+ *
+ * @param input The input material.
+ * @param data The data value. (Note: This is currently ignored by the CraftBukkit server.)
+ * @return The changed recipe, so you can chain calls.
+ */
+ public FurnaceRecipe setInput(Material input, int data) {
+ this.ingredient = new ItemStack(input, 1, (short) data);
return this;
}
@@ -64,8 +79,8 @@ public FurnaceRecipe setInput(Material input) {
*
* @return The input material.
*/
- public MaterialData getInput() {
- return ingredient;
+ public ItemStack getInput() {
+ return this.ingredient.clone();
}
/**
@@ -74,6 +89,6 @@ public MaterialData getInput() {
* @return The resulting stack.
*/
public ItemStack getResult() {
- return output;
+ return output.clone();
}
}
View
10 src/main/java/org/bukkit/inventory/ItemStack.java
@@ -57,6 +57,16 @@ public ItemStack(final Material type, final int amount, final short damage, fina
this(type.getId(), amount, damage, data);
}
+ public ItemStack(final ItemStack stack) {
+ this.type = stack.type;
+ this.amount = stack.amount;
+ this.durability = stack.durability;
+ if (stack.data != null) {
+ this.data = stack.data.clone();
+ }
+ enchantments.putAll(stack.enchantments);
+ }
+
/**
* Gets the type of this item
*
View
83 src/main/java/org/bukkit/inventory/ShapedRecipe.java
@@ -1,6 +1,9 @@
package org.bukkit.inventory;
import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.material.MaterialData;
@@ -11,7 +14,7 @@
public class ShapedRecipe implements Recipe {
private ItemStack output;
private String[] rows;
- private HashMap<Character, MaterialData> ingredients = new HashMap<Character, MaterialData>();
+ private Map<Character, ItemStack> ingredients = new HashMap<Character, ItemStack>();
/**
* Create a shaped recipe to craft the specified ItemStack. The constructor merely determines the
@@ -24,7 +27,7 @@
* @see ShapedRecipe#setIngredient(char, MaterialData)
*/
public ShapedRecipe(ItemStack result) {
- this.output = result;
+ this.output = new ItemStack(result);
}
/**
@@ -34,26 +37,28 @@ public ShapedRecipe(ItemStack result) {
* @param shape The rows of the recipe (up to 3 rows).
* @return The changed recipe, so you can chain calls.
*/
- public ShapedRecipe shape(String... shape) {
- if (shape == null || shape.length > 3 || shape.length < 1) {
- throw new IllegalArgumentException("Crafting recipes should be 1, 2, or 3 rows.");
- }
+ public ShapedRecipe shape(final String... shape) {
+ Validate.notNull(shape, "Must provide a shape");
+ Validate.isTrue(shape.length > 0 && shape.length < 4, "Crafting recipes should be 1, 2, 3 rows, not ", shape.length);
+
for (String row : shape) {
- if (row == null || row.length() > 3 || row.length() < 1) {
- throw new IllegalArgumentException("Crafting rows should be 1, 2, or 3 characters.");
- }
+ Validate.notNull(row, "Shape cannot have null rows");
+ Validate.isTrue(row.length() > 0 && row.length() < 4, "Crafting rows should be 1, 2, or 3 characters, not ", row.length());
+ }
+ this.rows = new String[shape.length];
+ for (int i = 0; i < shape.length; i++) {
+ this.rows[i] = shape[i];
}
- this.rows = shape;
// Remove character mappings for characters that no longer exist in the shape
- HashMap<Character, MaterialData> ingredientsTemp = this.ingredients;
-
- this.ingredients = new HashMap<Character, MaterialData>();
- for (char key : ingredientsTemp.keySet()) {
- try {
- setIngredient(key, ingredientsTemp.get(key));
- } catch (IllegalArgumentException e) {}
+ HashMap<Character, ItemStack> newIngredients = new HashMap<Character, ItemStack>();
+ for (String row : shape) {
+ for (Character c : row.toCharArray()) {
+ newIngredients.put(c, ingredients.get(c));
+ }
}
+ this.ingredients = newIngredients;
+
return this;
}
@@ -65,11 +70,7 @@ public ShapedRecipe shape(String... shape) {
* @return The changed recipe, so you can chain calls.
*/
public ShapedRecipe setIngredient(char key, MaterialData ingredient) {
- if (!hasKey(key)) {
- throw new IllegalArgumentException("Symbol " + key + " does not appear in the shape.");
- }
- ingredients.put(key, ingredient);
- return this;
+ return setIngredient(key, ingredient.getItemType(), ingredient.getData());
}
/**
@@ -92,32 +93,26 @@ public ShapedRecipe setIngredient(char key, Material ingredient) {
* @return The changed recipe, so you can chain calls.
*/
public ShapedRecipe setIngredient(char key, Material ingredient, int raw) {
- MaterialData data = ingredient.getNewData((byte) raw);
-
- if (data == null) {
- data = new MaterialData(ingredient, (byte) raw);
- }
- return setIngredient(key, data);
- }
-
- private boolean hasKey(char c) {
- String key = Character.toString(c);
-
- for (String row : rows) {
- if (row.contains(key)) {
- return true;
- }
- }
- return false;
+ Validate.isTrue(ingredients.containsKey(key), "Symbol does not appear in the shape:", key);
+ ingredients.put(key, new ItemStack(ingredient, 1, (short) raw));
+ return this;
}
/**
- * Get the ingredients map.
+ * Get a copy of the ingredients map.
*
* @return The mapping of character to ingredients.
*/
- public HashMap<Character, MaterialData> getIngredientMap() {
- return ingredients;
+ public Map<Character, ItemStack> getIngredientMap() {
+ HashMap<Character, ItemStack> result = new HashMap<Character, ItemStack>();
+ for (Map.Entry<Character, ItemStack> ingredient : ingredients.entrySet()) {
+ if (ingredient.getValue() == null) {
+ result.put(ingredient.getKey(), null);
+ } else {
+ result.put(ingredient.getKey(), ingredient.getValue().clone());
+ }
+ }
+ return result;
}
/**
@@ -126,7 +121,7 @@ private boolean hasKey(char c) {
* @return The recipe's shape.
*/
public String[] getShape() {
- return rows;
+ return rows.clone();
}
/**
@@ -135,6 +130,6 @@ private boolean hasKey(char c) {
* @return The result stack.
*/
public ItemStack getResult() {
- return output;
+ return output.clone();
}
}
View
119 src/main/java/org/bukkit/inventory/ShapelessRecipe.java
@@ -1,6 +1,10 @@
package org.bukkit.inventory;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.material.MaterialData;
@@ -11,7 +15,7 @@
*/
public class ShapelessRecipe implements Recipe {
private ItemStack output;
- private ArrayList<MaterialData> ingredients = new ArrayList<MaterialData>();
+ private List<ItemStack> ingredients = new ArrayList<ItemStack>();
/**
* Create a shapeless recipe to craft the specified ItemStack. The constructor merely determines the
@@ -20,9 +24,13 @@
* @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 = result;
+ this.output = new ItemStack(result);
}
/**
@@ -49,7 +57,7 @@ public ShapelessRecipe addIngredient(Material ingredient) {
* Adds the specified ingredient.
*
* @param ingredient The ingredient to add.
- * @param rawdata The data value.
+ * @param rawdata The data value, or -1 to allow any data value.
* @return The changed recipe, so you can chain calls.
*/
public ShapelessRecipe addIngredient(Material ingredient, int rawdata) {
@@ -64,13 +72,7 @@ public ShapelessRecipe addIngredient(Material ingredient, int rawdata) {
* @return The changed recipe, so you can chain calls.
*/
public ShapelessRecipe addIngredient(int count, MaterialData ingredient) {
- if (ingredients.size() + count > 9) {
- throw new IllegalArgumentException("Shapeless recipes cannot have more than 9 ingredients");
- }
- while (count-- > 0) {
- ingredients.add(ingredient);
- }
- return this;
+ return addIngredient(count, ingredient.getItemType(), ingredient.getData());
}
/**
@@ -89,27 +91,100 @@ public ShapelessRecipe addIngredient(int count, Material ingredient) {
*
* @param count How many to add (can't be more than 9!)
* @param ingredient The ingredient to add.
- * @param rawdata The data value.
+ * @param rawdata The data value, or -1 to allow any data value.
* @return The changed recipe, so you can chain calls.
*/
public ShapelessRecipe addIngredient(int count, Material ingredient, int rawdata) {
- MaterialData data = ingredient.getNewData((byte) rawdata);
+ Validate.isTrue(ingredients.size() + count <= 9, "Shapeless recipes cannot have more than 9 ingredients");
- if (data == null) {
- data = new MaterialData(ingredient, (byte) rawdata);
+ while (count-- > 0) {
+ ingredients.add(new ItemStack(ingredient, 1, (short) rawdata));
}
- return addIngredient(count, data);
+ 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.
+ * 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) {
- this.ingredients.remove(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.
+ */
+ 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.
+ */
+ 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;
}
@@ -119,7 +194,7 @@ public ShapelessRecipe removeIngredient(MaterialData ingredient) {
* @return The result stack.
*/
public ItemStack getResult() {
- return output;
+ return output.clone();
}
/**
@@ -127,7 +202,11 @@ public ItemStack getResult() {
*
* @return The input list
*/
- public ArrayList<MaterialData> getIngredientList() {
- return ingredients;
+ public List<ItemStack> getIngredientList() {
+ ArrayList<ItemStack> result = new ArrayList<ItemStack>(ingredients.size());
+ for (ItemStack ingredient : ingredients) {
+ result.add(ingredient.clone());
+ }
+ return result;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.