From 32149d7350ab8ddd77406885926adcd67735957b Mon Sep 17 00:00:00 2001 From: Alex 'mcmonkey' Goodwin Date: Fri, 27 Sep 2019 10:49:51 -0700 Subject: [PATCH] add an inexact recipe matcher option --- .../denizen/nms/interfaces/ItemHelper.java | 8 +-- .../containers/core/ItemScriptContainer.java | 1 + .../containers/core/ItemScriptHelper.java | 52 +++++++++++++++---- .../nms/v1_12/helpers/ItemHelperImpl.java | 6 +-- .../nms/v1_13/helpers/ItemHelperImpl.java | 21 +++++--- .../nms/v1_14/helpers/ItemHelperImpl.java | 25 +++++---- 6 files changed, 78 insertions(+), 35 deletions(-) diff --git a/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/ItemHelper.java b/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/ItemHelper.java index c07e8108fa..997f12c015 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/ItemHelper.java +++ b/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/ItemHelper.java @@ -19,15 +19,15 @@ public abstract class ItemHelper { public abstract void clearDenizenRecipes(); - public void registerStonecuttingRecipe(String keyName, String group, ItemStack result, ItemStack ingredient) { + public void registerStonecuttingRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, boolean exact) { throw new UnsupportedOperationException(); } - public abstract void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type); + public abstract void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type, boolean exact); - public abstract void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients); + public abstract void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients, boolean[] exact); - public abstract void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item); + public abstract void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item, boolean exact); public abstract String getInternalNameFromMaterial(Material material); diff --git a/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptContainer.java b/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptContainer.java index ffc6ba31de..5524d4a555 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptContainer.java +++ b/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptContainer.java @@ -85,6 +85,7 @@ public class ItemScriptContainer extends ScriptContainer { // # You must specify the input for the recipe. The below is a sample of a 3x3 shaped recipe. Other recipe types have a different format. // # You are allowed to have non-3x3 shapes (can be any value 1-3 x 1-3, so for example 1x3, 2x1, and 2x2 are fine). // # For an empty slot, use "air". + // # By default, items require an exact match. For a material-based match, use the format "material:MaterialNameHere" like "material:stick". // input: // - ItemTag|ItemTag|ItemTag // - ItemTag|ItemTag|ItemTag diff --git a/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptHelper.java b/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptHelper.java index 9d3818060e..c9b0d5b9d8 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptHelper.java +++ b/plugin/src/main/java/com/denizenscript/denizen/scripts/containers/core/ItemScriptHelper.java @@ -77,6 +77,7 @@ public void registerShapedRecipe(ItemScriptContainer container, ItemStack item, recipeList.set(n, TagManager.tag(ScriptBuilder.stripLinePrefix(recipeList.get(n)), new BukkitTagContext(null, null, new ScriptTag(container)))); } List ingredients = new ArrayList<>(); + List exacts = new ArrayList<>(); int width = 1; for (String recipeRow : recipeList) { String[] elements = recipeRow.split("\\|", 3); @@ -88,7 +89,15 @@ public void registerShapedRecipe(ItemScriptContainer container, ItemStack item, } for (String element : elements) { - ItemTag ingredient = ItemTag.valueOf(element.replaceAll("[iImM]@", ""), container); + String itemText = element.replaceAll("[iImM]@", ""); + if (itemText.startsWith("material:")) { + exacts.add(false); + itemText = itemText.substring("material:".length()); + } + else { + exacts.add(true); + } + ItemTag ingredient = ItemTag.valueOf(itemText, container); if (ingredient == null) { Debug.echoError("Invalid ItemTag ingredient, recipe will not be registered for item script '" + container.getName() + "': " + element); @@ -115,7 +124,7 @@ else if (recipeList.size() == 2) { recipe = recipe.shape(shape1); } for (int i = 0; i < ingredients.size(); i++) { - NMSHandler.getItemHelper().setShapedRecipeIngredient(recipe, itemChars.charAt(i), ingredients.get(i).getItemStack().clone()); + NMSHandler.getItemHelper().setShapedRecipeIngredient(recipe, itemChars.charAt(i), ingredients.get(i).getItemStack().clone(), exacts.get(i)); } Bukkit.addRecipe(recipe); } @@ -127,8 +136,17 @@ else if (recipeList.size() == 2) { public void registerShapelessRecipe(ItemScriptContainer container, ItemStack item, String shapelessString, String internalId, String group) { String list = TagManager.tag(shapelessString, new BukkitTagContext(null, null, new ScriptTag(container))); List ingredients = new ArrayList<>(); + List exacts = new ArrayList<>(); for (String element : ListTag.valueOf(list)) { - ItemTag ingredient = ItemTag.valueOf(element.replaceAll("[iImM]@", ""), container); + String itemText = element.replaceAll("[iImM]@", ""); + if (itemText.startsWith("material:")) { + exacts.add(false); + itemText = itemText.substring("material:".length()); + } + else { + exacts.add(true); + } + ItemTag ingredient = ItemTag.valueOf(itemText, container); if (ingredient == null) { Debug.echoError("Invalid ItemTag ingredient, shapeless recipe will not be registered for item script '" + container.getName() + "': " + element); @@ -141,7 +159,11 @@ public void registerShapelessRecipe(ItemScriptContainer container, ItemStack ite for (int i = 0; i < input.length; i++) { input[i] = ingredients.get(i).getItemStack().clone(); } - NMSHandler.getItemHelper().registerShapelessRecipe(internalId, group, item, input); + boolean[] bools = new boolean[exacts.size()]; + for (int i = 0; i < exacts.size(); i++) { + bools[i] = exacts.get(i); + } + NMSHandler.getItemHelper().registerShapelessRecipe(internalId, group, item, input, bools); } else { shapelessRecipesMap.put(container, ingredients); @@ -149,6 +171,11 @@ public void registerShapelessRecipe(ItemScriptContainer container, ItemStack ite } public void registerFurnaceRecipe(ItemScriptContainer container, ItemStack item, String furnaceItemString, float exp, int time, String type, String internalId, String group) { + boolean exact = true; + if (furnaceItemString.startsWith("material:")) { + exact = false; + furnaceItemString = furnaceItemString.substring("material:".length()); + } ItemTag furnace_item = ItemTag.valueOf(furnaceItemString, container); if (furnace_item == null) { Debug.echoError("Invalid item '" + furnaceItemString + "', furnace recipe will not be registered for item script '" + container.getName() + "'."); @@ -156,7 +183,7 @@ public void registerFurnaceRecipe(ItemScriptContainer container, ItemStack item, } if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_13)) { ItemStack input = furnace_item.getItemStack().clone(); - NMSHandler.getItemHelper().registerFurnaceRecipe(internalId, group, item, input, exp, time, type); + NMSHandler.getItemHelper().registerFurnaceRecipe(internalId, group, item, input, exp, time, type, exact); } else { FurnaceRecipe recipe = new FurnaceRecipe(item, furnace_item.getMaterial().getMaterial(), furnace_item.getItemStack().getDurability()); @@ -167,15 +194,20 @@ public void registerFurnaceRecipe(ItemScriptContainer container, ItemStack item, public void registerStonecuttingRecipe(ItemScriptContainer container, ItemStack item, String inputItemString, String internalId, String group) { if (!NMSHandler.getVersion().isAtLeast(NMSVersion.v1_14)) { - + return; } - ItemTag furnace_item = ItemTag.valueOf(inputItemString, container); - if (furnace_item == null) { + boolean exact = true; + if (inputItemString.startsWith("material:")) { + exact = false; + inputItemString = inputItemString.substring("material:".length()); + } + ItemTag stonecutting_item = ItemTag.valueOf(inputItemString, container); + if (stonecutting_item == null) { Debug.echoError("Invalid item '" + inputItemString + "', stonecutting recipe will not be registered for item script '" + container.getName() + "'."); return; } - ItemStack input = furnace_item.getItemStack().clone(); - NMSHandler.getItemHelper().registerStonecuttingRecipe(internalId, group, item, input); + ItemStack input = stonecutting_item.getItemStack().clone(); + NMSHandler.getItemHelper().registerStonecuttingRecipe(internalId, group, item, input, exact); } public void rebuildRecipes() { diff --git a/v1_12/src/main/java/com/denizenscript/denizen/nms/v1_12/helpers/ItemHelperImpl.java b/v1_12/src/main/java/com/denizenscript/denizen/nms/v1_12/helpers/ItemHelperImpl.java index 3291fd8431..39c9636680 100644 --- a/v1_12/src/main/java/com/denizenscript/denizen/nms/v1_12/helpers/ItemHelperImpl.java +++ b/v1_12/src/main/java/com/denizenscript/denizen/nms/v1_12/helpers/ItemHelperImpl.java @@ -34,17 +34,17 @@ public void clearDenizenRecipes() { } @Override - public void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item) { + public void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item, boolean exact) { throw new UnsupportedOperationException(); } @Override - public void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type) { + public void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type, boolean exact) { throw new UnsupportedOperationException(); } @Override - public void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients) { + public void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients, boolean[] exact) { throw new UnsupportedOperationException(); } diff --git a/v1_13/src/main/java/com/denizenscript/denizen/nms/v1_13/helpers/ItemHelperImpl.java b/v1_13/src/main/java/com/denizenscript/denizen/nms/v1_13/helpers/ItemHelperImpl.java index 0ba458a967..579b14a786 100644 --- a/v1_13/src/main/java/com/denizenscript/denizen/nms/v1_13/helpers/ItemHelperImpl.java +++ b/v1_13/src/main/java/com/denizenscript/denizen/nms/v1_13/helpers/ItemHelperImpl.java @@ -48,26 +48,31 @@ public void clearDenizenRecipes() { } @Override - public void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item) { - recipe.setIngredient(c, new RecipeChoice.ExactChoice(item)); + public void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item, boolean exact) { + if (exact) { + recipe.setIngredient(c, new RecipeChoice.ExactChoice(item)); + } + else { + recipe.setIngredient(c, item.getType()); + } } @Override - public void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type) { + public void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type, boolean exact) { MinecraftKey key = new MinecraftKey("denizen", keyName); RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredient))).stream()); - itemRecipe.exact = true; + itemRecipe.exact = exact; FurnaceRecipe recipe = new FurnaceRecipe(key, group, itemRecipe, CraftItemStack.asNMSCopy(result), exp, time); ((CraftServer) Bukkit.getServer()).getServer().getCraftingManager().a(recipe); } @Override - public void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients) { + public void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients, boolean[] exact) { MinecraftKey key = new MinecraftKey("denizen", keyName); ArrayList ingredientList = new ArrayList<>(); - for (ItemStack ingredient : ingredients) { - RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredient))).stream()); - itemRecipe.exact = true; + for (int i = 0; i < ingredients.length; i++) { + RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredients[i]))).stream()); + itemRecipe.exact = exact[i]; ingredientList.add(itemRecipe); } ShapelessRecipes recipe = new ShapelessRecipes(key, group, CraftItemStack.asNMSCopy(result), NonNullList.a(null, ingredientList.toArray(new RecipeItemStack[ingredientList.size()]))); diff --git a/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/helpers/ItemHelperImpl.java b/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/helpers/ItemHelperImpl.java index 0b0f8affee..2017006536 100644 --- a/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/helpers/ItemHelperImpl.java +++ b/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/helpers/ItemHelperImpl.java @@ -50,15 +50,20 @@ public void clearDenizenRecipes() { } @Override - public void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item) { - recipe.setIngredient(c, new RecipeChoice.ExactChoice(item)); + public void setShapedRecipeIngredient(ShapedRecipe recipe, char c, ItemStack item, boolean exact) { + if (exact) { + recipe.setIngredient(c, new RecipeChoice.ExactChoice(item)); + } + else { + recipe.setIngredient(c, item.getType()); + } } @Override - public void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type) { + public void registerFurnaceRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, float exp, int time, String type, boolean exact) { MinecraftKey key = new MinecraftKey("denizen", keyName); RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredient))).stream()); - itemRecipe.exact = true; + itemRecipe.exact = exact; RecipeCooking recipe; if (type.equalsIgnoreCase("smoker")) { recipe = new RecipeSmoking(key, group, itemRecipe, CraftItemStack.asNMSCopy(result), exp, time); @@ -76,21 +81,21 @@ else if (type.equalsIgnoreCase("campfire")) { } @Override - public void registerStonecuttingRecipe(String keyName, String group, ItemStack result, ItemStack ingredient) { + public void registerStonecuttingRecipe(String keyName, String group, ItemStack result, ItemStack ingredient, boolean exact) { MinecraftKey key = new MinecraftKey("denizen", keyName); RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredient))).stream()); - itemRecipe.exact = true; + itemRecipe.exact = exact; RecipeStonecutting recipe = new RecipeStonecutting(key, group, itemRecipe, CraftItemStack.asNMSCopy(result)); ((CraftServer) Bukkit.getServer()).getServer().getCraftingManager().addRecipe(recipe); } @Override - public void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients) { + public void registerShapelessRecipe(String keyName, String group, ItemStack result, ItemStack[] ingredients, boolean[] exact) { MinecraftKey key = new MinecraftKey("denizen", keyName); ArrayList ingredientList = new ArrayList<>(); - for (ItemStack ingredient : ingredients) { - RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredient))).stream()); - itemRecipe.exact = true; + for (int i = 0; i < ingredients.length; i++) { + RecipeItemStack itemRecipe = new RecipeItemStack(Arrays.asList(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingredients[i]))).stream()); + itemRecipe.exact = exact[i]; ingredientList.add(itemRecipe); } ShapelessRecipes recipe = new ShapelessRecipes(key, group, CraftItemStack.asNMSCopy(result), NonNullList.a(null, ingredientList.toArray(new RecipeItemStack[ingredientList.size()])));