package net.t7seven7t.craftfx.recipe; import com.google.common.base.Joiner; import net.t7seven7t.craftfx.CraftFX; import net.t7seven7t.craftfx.item.ItemRegistry; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ShapelessRecipe; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * Wrapper for Bukkit's ShapelessRecipe that allows setting ingredients with ItemStack data */ public class FXShapelessRecipe extends ShapelessRecipe implements FXRecipe { private final List<ItemStack> ingredients = new ArrayList<>(); /** * {@inheritDoc} */ public FXShapelessRecipe(final ItemStack result) { super(result); } /** * Adds a number of ingredients to the recipe */ public FXShapelessRecipe addIngredient(int count, final ItemStack item) { Validate.isTrue(ingredients.size() + count <= 9, "Shapeless recipes cannot have more than 9 ingredients."); while (count-- > 0) { ingredients.add(item); } return this; } FXShapelessRecipe addIngredient(Ingredient ingredient) { return addIngredient(ingredient.amount, ingredient.item); } /** * Removes a number of ingredients from the recipe */ public FXShapelessRecipe removeIngredient(int count, final ItemStack item) { final Iterator<ItemStack> it = ingredients.iterator(); final ItemRegistry registry = CraftFX.instance().getItemRegistry(); while (count > 0 && it.hasNext()) { ItemStack i = it.next(); if (registry.isSimilar(i, item)) { it.remove(); count--; } } return this; } /** * {@inheritDoc} */ @Override public List<ItemStack> getIngredientList() { return ingredients.stream().map(ItemStack::clone).collect(Collectors.toList()); } @Override public String toString() { final Map<ItemStack, Integer> amounts = new HashMap<>(); for (ItemStack is : ingredients) { if (!amounts.containsKey(is)) amounts.put(is, 0); amounts.put(is, amounts.get(is) + 1); } final String ingredients = Joiner.on(", ").join(amounts.entrySet().stream().map(e -> { if (e.getKey().hasItemMeta() && e.getKey().getItemMeta().hasDisplayName()) return e.getKey().getItemMeta().getDisplayName() + " x" + e.getValue(); return e.getKey().getType() + " x" + e.getValue(); }).collect(Collectors.toList())); return "FXShapelessRecipe{" + "result=" + getResult().getItemMeta().getDisplayName() + ", ingredients=" + ingredients + '}'; } /** * Compares an ItemMatrix with the expected input for this recipe */ public boolean matches(ItemStack[] matrix) { final ItemRegistry registry = CraftFX.instance().getItemRegistry(); final List<ItemStack> ingredients = new ArrayList<>(this.ingredients); for (ItemStack item : matrix) { if (item != null && item.getType() != Material.AIR) { final Iterator<ItemStack> it = ingredients.iterator(); boolean exit = true; while (it.hasNext()) { if (registry.isSimilar(it.next(), item)) { it.remove(); exit = false; break; } } if (exit) return false; } } return ingredients.isEmpty(); } }