summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormd_5 <git@md-5.net>2018-09-01 11:04:43 +1000
committermd_5 <git@md-5.net>2018-09-01 11:04:43 +1000
commiteaf05a2ab257f19498826db6964039d9b1246afd (patch)
tree3086f9930d8dbdeab77c04ea3d2f71768f17e367
parent28237f03e476ca980c59a5146954649d489fe5bc (diff)
downloadbukkit-eaf05a2ab257f19498826db6964039d9b1246afd.tar
bukkit-eaf05a2ab257f19498826db6964039d9b1246afd.tar.gz
bukkit-eaf05a2ab257f19498826db6964039d9b1246afd.tar.lz
bukkit-eaf05a2ab257f19498826db6964039d9b1246afd.tar.xz
bukkit-eaf05a2ab257f19498826db6964039d9b1246afd.zip
Expand Recipe API to allow multiple Materials per slot
-rw-r--r--src/main/java/org/bukkit/inventory/RecipeChoice.java114
-rw-r--r--src/main/java/org/bukkit/inventory/ShapedRecipe.java28
-rw-r--r--src/main/java/org/bukkit/inventory/ShapelessRecipe.java38
3 files changed, 171 insertions, 9 deletions
diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java
new file mode 100644
index 00000000..2dd72242
--- /dev/null
+++ b/src/main/java/org/bukkit/inventory/RecipeChoice.java
@@ -0,0 +1,114 @@
+package org.bukkit.inventory;
+
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Predicate;
+import org.bukkit.Material;
+
+/**
+ * Represents a potential item match within a recipe. All choices within a
+ * recipe must be satisfied for it to be craftable.
+ *
+ * <b>This class is not legal for implementation by plugins!</b>
+ *
+ * @deprecated draft API
+ */
+@Deprecated
+public interface RecipeChoice extends Predicate<ItemStack>, Cloneable {
+
+ /**
+ * Gets a single item stack representative of this stack choice.
+ *
+ * @return a single representative item
+ * @deprecated for compatability only
+ */
+ @Deprecated
+ ItemStack getItemStack();
+
+ RecipeChoice clone();
+
+ /**
+ * Represents a choice of multiple matching Materials.
+ */
+ public static class MaterialChoice implements RecipeChoice {
+
+ private List<Material> choices;
+
+ public MaterialChoice(List<Material> choices) {
+ Preconditions.checkArgument(choices != null, "choices");
+ Preconditions.checkArgument(!choices.isEmpty(), "Must have at least one choice");
+ this.choices = choices;
+ }
+
+ @Override
+ public boolean test(ItemStack t) {
+ for (Material match : choices) {
+ if (t.getType() == match) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public ItemStack getItemStack() {
+ ItemStack stack = new ItemStack(choices.get(0));
+
+ // For compat
+ if (choices.size() > 1) {
+ stack.setDurability(Short.MAX_VALUE);
+ }
+
+ return stack;
+ }
+
+ public List<Material> getChoices() {
+ return Collections.unmodifiableList(choices);
+ }
+
+ @Override
+ public MaterialChoice clone() {
+ try {
+ MaterialChoice clone = (MaterialChoice) super.clone();
+ clone.choices = new ArrayList<>(choices);
+ return clone;
+ } catch (CloneNotSupportedException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 37 * hash + Objects.hashCode(this.choices);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final MaterialChoice other = (MaterialChoice) obj;
+ if (!Objects.equals(this.choices, other.choices)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "MaterialChoice{" + "choices=" + choices + '}';
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/inventory/ShapedRecipe.java b/src/main/java/org/bukkit/inventory/ShapedRecipe.java
index 398ac245..90d6d50c 100644
--- a/src/main/java/org/bukkit/inventory/ShapedRecipe.java
+++ b/src/main/java/org/bukkit/inventory/ShapedRecipe.java
@@ -1,6 +1,7 @@
package org.bukkit.inventory;
import com.google.common.base.Preconditions;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -18,7 +19,7 @@ public class ShapedRecipe implements Recipe, Keyed {
private final NamespacedKey key;
private final ItemStack output;
private String[] rows;
- private Map<Character, ItemStack> ingredients = new HashMap<Character, ItemStack>();
+ private Map<Character, RecipeChoice> ingredients = new HashMap<>();
private String group = "";
@Deprecated
@@ -75,7 +76,7 @@ public class ShapedRecipe implements Recipe, Keyed {
}
// Remove character mappings for characters that no longer exist in the shape
- HashMap<Character, ItemStack> newIngredients = new HashMap<Character, ItemStack>();
+ HashMap<Character, RecipeChoice> newIngredients = new HashMap<>();
for (String row : shape) {
for (Character c : row.toCharArray()) {
newIngredients.put(c, ingredients.get(c));
@@ -126,7 +127,14 @@ public class ShapedRecipe implements Recipe, Keyed {
raw = Short.MAX_VALUE;
}
- ingredients.put(key, new ItemStack(ingredient, 1, (short) raw));
+ ingredients.put(key, new RecipeChoice.MaterialChoice(Collections.singletonList(ingredient)));
+ return this;
+ }
+
+ public ShapedRecipe setIngredient(char key, RecipeChoice ingredient) {
+ Validate.isTrue(ingredients.containsKey(key), "Symbol does not appear in the shape:", key);
+
+ ingredients.put(key, ingredient);
return this;
}
@@ -137,7 +145,19 @@ public class ShapedRecipe implements Recipe, Keyed {
*/
public Map<Character, ItemStack> getIngredientMap() {
HashMap<Character, ItemStack> result = new HashMap<Character, ItemStack>();
- for (Map.Entry<Character, ItemStack> ingredient : ingredients.entrySet()) {
+ for (Map.Entry<Character, RecipeChoice> ingredient : ingredients.entrySet()) {
+ if (ingredient.getValue() == null) {
+ result.put(ingredient.getKey(), null);
+ } else {
+ result.put(ingredient.getKey(), ingredient.getValue().getItemStack().clone());
+ }
+ }
+ return result;
+ }
+
+ public Map<Character, RecipeChoice> getChoiceMap() {
+ Map<Character, RecipeChoice> result = new HashMap<>();
+ for (Map.Entry<Character, RecipeChoice> ingredient : ingredients.entrySet()) {
if (ingredient.getValue() == null) {
result.put(ingredient.getKey(), null);
} else {
diff --git a/src/main/java/org/bukkit/inventory/ShapelessRecipe.java b/src/main/java/org/bukkit/inventory/ShapelessRecipe.java
index 0c340c84..ea359c54 100644
--- a/src/main/java/org/bukkit/inventory/ShapelessRecipe.java
+++ b/src/main/java/org/bukkit/inventory/ShapelessRecipe.java
@@ -2,6 +2,7 @@ package org.bukkit.inventory;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -19,7 +20,7 @@ import org.bukkit.material.MaterialData;
public class ShapelessRecipe implements Recipe, Keyed {
private final NamespacedKey key;
private final ItemStack output;
- private final List<ItemStack> ingredients = new ArrayList<ItemStack>();
+ private final List<RecipeChoice> ingredients = new ArrayList<>();
private String group = "";
@Deprecated
@@ -121,11 +122,30 @@ public class ShapelessRecipe implements Recipe, Keyed {
}
while (count-- > 0) {
- ingredients.add(new ItemStack(ingredient, 1, (short) rawdata));
+ ingredients.add(new RecipeChoice.MaterialChoice(Collections.singletonList(ingredient)));
}
return this;
}
+ public ShapelessRecipe addIngredient(RecipeChoice ingredient) {
+ Validate.isTrue(ingredients.size() + 1 <= 9, "Shapeless recipes cannot have more than 9 ingredients");
+
+ ingredients.add(ingredient);
+ return this;
+ }
+
+ /**
+ * Removes an ingredient from the list.
+ *
+ * @param ingredient The ingredient to remove
+ * @return The changed recipe.
+ */
+ public ShapelessRecipe removeIngredient(RecipeChoice ingredient) {
+ ingredients.remove(ingredient);
+
+ 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,
@@ -204,9 +224,9 @@ public class ShapelessRecipe implements Recipe, Keyed {
*/
@Deprecated
public ShapelessRecipe removeIngredient(int count, Material ingredient, int rawdata) {
- Iterator<ItemStack> iterator = ingredients.iterator();
+ Iterator<RecipeChoice> iterator = ingredients.iterator();
while (count > 0 && iterator.hasNext()) {
- ItemStack stack = iterator.next();
+ ItemStack stack = iterator.next().getItemStack();
if (stack.getType() == ingredient && stack.getDurability() == rawdata) {
iterator.remove();
count--;
@@ -231,7 +251,15 @@ public class ShapelessRecipe implements Recipe, Keyed {
*/
public List<ItemStack> getIngredientList() {
ArrayList<ItemStack> result = new ArrayList<ItemStack>(ingredients.size());
- for (ItemStack ingredient : ingredients) {
+ for (RecipeChoice ingredient : ingredients) {
+ result.add(ingredient.getItemStack().clone());
+ }
+ return result;
+ }
+
+ public List<RecipeChoice> getChoiceList() {
+ List<RecipeChoice> result = new ArrayList<>(ingredients.size());
+ for (RecipeChoice ingredient : ingredients) {
result.add(ingredient.clone());
}
return result;