From 8baddf0ea579bc36cc6566aa9f8f6494b2ddba09 Mon Sep 17 00:00:00 2001 From: Jared Date: Tue, 20 Sep 2016 10:01:02 +0200 Subject: [PATCH] potential fix for #23 --- .../minetweaker/api/item/IIngredient.java | 64 +- .../api/recipes/IRecipeManager.java | 2 +- .../minetweaker/mc1102/item/MCItemStack.java | 22 + .../mc1102/recipes/MCRecipeManager.java | 193 ++--- .../minetweaker/mc1710/item/MCItemStack.java | 23 + .../mc1710/recipes/MCRecipeManager.java | 791 +++++++++--------- .../minetweaker/mc18/item/MCItemStack.java | 22 + .../mc18/recipes/MCRecipeManager.java | 193 ++--- 8 files changed, 693 insertions(+), 617 deletions(-) diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java index 38e575c..39f1eb6 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java @@ -1,22 +1,19 @@ package minetweaker.api.item; -import java.util.List; import minetweaker.api.liquid.ILiquidStack; import minetweaker.api.player.IPlayer; -import stanhebben.zenscript.annotations.OperatorType; -import stanhebben.zenscript.annotations.ZenClass; -import stanhebben.zenscript.annotations.ZenGetter; -import stanhebben.zenscript.annotations.ZenMethod; -import stanhebben.zenscript.annotations.ZenOperator; +import stanhebben.zenscript.annotations.*; + +import java.util.List; /** * Represents a recipe ingredient. An ingredient can be an item, an ore * dictionary entry, an item stack, an ore dictionary entry multiplied with an * amount, or other kinds of ingredients as offered by the API. - * + * * There is no guarantee that every mod will respect the conditions or * transformations, or that every mod will support every kind of ingredient. - * + * * @author Stan Hebben */ @ZenClass("minetweaker.item.IIngredient") @@ -24,7 +21,7 @@ public interface IIngredient { /** * Gets the mark of the ingredient. Ingredients can be marked so they can be * used in crafting functions. - * + * * @return ingredient mark */ @ZenGetter("mark") @@ -32,10 +29,10 @@ public interface IIngredient { /** * Gets the amount. - * + * * Should return -1 if no amount is available and 1 for a single item. * Stacks return the stack size. - * + * * @return stack size */ @ZenGetter("amount") @@ -43,10 +40,10 @@ public interface IIngredient { /** * Gets all possible items for this ingredient. - * + * * If there is no item list (for example, it is the <*> wildcard item) * null should be returned. - * + * * @return the items for this ingredient, or null */ @ZenGetter("items") @@ -54,10 +51,10 @@ public interface IIngredient { /** * Gets all possible liquids for this ingredient. - * + * * If there is no liquid list (for example, it is the <*&ft; wildcard * item) null should be returned. - * + * * @return the liquids for this ingredient, or null */ @ZenGetter("liquids") @@ -65,7 +62,7 @@ public interface IIngredient { /** * Returns a new ingredient with the given stack size. - * + * * @param amount new stack size * @return modified ingredient */ @@ -76,7 +73,7 @@ public interface IIngredient { /** * Combines multiple ingredients into a single one. Note that ore dictionary * entries are preferred to or statements. - * + * * @param ingredient ingredient to combine with * @return or-ed ingredient */ @@ -86,7 +83,7 @@ public interface IIngredient { /** * Returns a new ingredient with the given transform added to it. - * + * * @param transformer transformer to add * @return modified ingredient */ @@ -95,7 +92,7 @@ public interface IIngredient { /** * Returns a new ingredient with the given condition added to it. - * + * * @param condition condition to add * @return modified ingredient */ @@ -104,7 +101,7 @@ public interface IIngredient { /** * Returns a new ingredient marked with the given name. - * + * * @param mark mark to apply * @return modified ingredient */ @@ -114,16 +111,27 @@ public interface IIngredient { /** * Checks if this ingredient matches the given item. For liquids, will match * the item if it is a valid container. - * + * * @param item item to check * @return true if the item matches */ @ZenMethod public boolean matches(IItemStack item); - /** + /** + * Checks if this ingredient matches the given item. For liquids, will match + * the item if it is a valid container. + * + * @param item item to check + * @return true if the item matches + */ + @ZenMethod + public boolean matchesExact(IItemStack item); + + + /** * Checks if this ingredient matches the given liquid. - * + * * @param liquid * @return */ @@ -133,7 +141,7 @@ public interface IIngredient { /** * Check if this ingredient contains all possible values for the given * ingredient. - * + * * @param ingredient ingredient to check * @return true if the ingredient contains the given one */ @@ -142,7 +150,7 @@ public interface IIngredient { /** * Applies transformations after crafting, if any, to the given item. - * + * * @param item item to transform * @param byPlayer player performing the crafting operation * @return transformed item @@ -152,7 +160,7 @@ public interface IIngredient { /** * Checks if this ingredient has (or could have) any transformatiosns. - * + * * @return true if there are (or could be) any transformations false * otherwise. */ @@ -161,11 +169,11 @@ public interface IIngredient { /** * Gets the internal item backing this ingredient. - * + * * The value is implementation-dependent and should only be handled by the * internal code. Don't use this value - instead, use the version-specific * helper methods. - * + * * @return internal item */ public Object getInternal(); diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java index 9fd3621..b48e189 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeManager.java @@ -42,7 +42,7 @@ public interface IRecipeManager { * @return number of removed recipes */ @ZenMethod - public int remove(IIngredient output); + public int remove(IIngredient output, @Optional boolean nbtMatch); /** * Adds a shaped recipe. diff --git a/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/item/MCItemStack.java b/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/item/MCItemStack.java index 0d24616..8116f52 100644 --- a/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/item/MCItemStack.java +++ b/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/item/MCItemStack.java @@ -287,6 +287,28 @@ public class MCItemStack implements IItemStack{ return internal != null && stack != null && internal.getItem() == stack.getItem() && (wildcardSize || internal.stackSize >= stack.stackSize) && (stack.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack.getItemDamage() == internal.getItemDamage() || (!stack.getHasSubtypes() && !stack.getItem().isDamageable())); } + @Override + public boolean matchesExact(IItemStack item) { + ItemStack internal = getItemStack(item); + if (internal.getTagCompound() != null && stack.getTagCompound() == null) { + return false; + } + if (internal.getTagCompound() == null && stack.getTagCompound() != null) { + return false; + } + if (internal.getTagCompound() == null && stack.getTagCompound() == null) { + return stack.getItem() == internal.getItem() && (internal.getMetadata() == 32767 || stack.getMetadata() == internal.getMetadata()); + } + if (internal.getTagCompound().getKeySet().equals(stack.getTagCompound().getKeySet())) { + for (String s : internal.getTagCompound().getKeySet()) { + if (!internal.getTagCompound().getTag(s).equals(stack.getTagCompound().getTag(s))) { + return false; + } + } + } + return stack.getItem() == internal.getItem() && (internal.getMetadata() == 32767 || stack.getMetadata() == internal.getMetadata()); + } + @Override public boolean matches(ILiquidStack liquid){ return false; diff --git a/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/recipes/MCRecipeManager.java b/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/recipes/MCRecipeManager.java index d0d0597..e95a379 100644 --- a/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC1102-Main/src/main/java/minetweaker/mc1102/recipes/MCRecipeManager.java @@ -18,6 +18,7 @@ import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; +import stanhebben.zenscript.annotations.Optional; import java.util.ArrayList; import java.util.List; @@ -27,25 +28,25 @@ import static minetweaker.api.minecraft.MineTweakerMC.*; /** * @author Stan */ -public class MCRecipeManager implements IRecipeManager{ +public class MCRecipeManager implements IRecipeManager { private final List recipes; private final List transformerRecipes; - public MCRecipeManager(){ + public MCRecipeManager() { recipes = CraftingManager.getInstance().getRecipeList(); transformerRecipes = new ArrayList(); } - private static boolean matches(Object input, IIngredient ingredient){ - if((input == null) != (ingredient == null)){ + private static boolean matches(Object input, IIngredient ingredient) { + if ((input == null) != (ingredient == null)) { return false; - }else if(ingredient != null){ - if(input instanceof ItemStack){ - if(!ingredient.matches(getIItemStack((ItemStack) input))){ + } else if (ingredient != null) { + if (input instanceof ItemStack) { + if (!ingredient.matches(getIItemStack((ItemStack) input))) { return false; } - }else if(input instanceof String){ - if(!ingredient.contains(getOreDict((String) input))){ + } else if (input instanceof String) { + if (!ingredient.contains(getOreDict((String) input))) { return false; } } @@ -54,13 +55,13 @@ public class MCRecipeManager implements IRecipeManager{ return true; } - public boolean hasTransformerRecipes(){ + public boolean hasTransformerRecipes() { return transformerRecipes.size() > 0; } - public void applyTransformations(ICraftingInventory inventory, IPlayer byPlayer){ - for(ICraftingRecipe recipe : transformerRecipes){ - if(recipe.matches(inventory)){ + public void applyTransformations(ICraftingInventory inventory, IPlayer byPlayer) { + for (ICraftingRecipe recipe : transformerRecipes) { + if (recipe.matches(inventory)) { recipe.applyTransformers(inventory, byPlayer); return; } @@ -68,11 +69,11 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public List getRecipesFor(IIngredient ingredient){ + public List getRecipesFor(IIngredient ingredient) { List results = new ArrayList(); - for(IRecipe recipe : recipes){ - if(ingredient.matches(MineTweakerMC.getIItemStack(recipe.getRecipeOutput()))){ + for (IRecipe recipe : recipes) { + if (ingredient.matches(MineTweakerMC.getIItemStack(recipe.getRecipeOutput()))) { ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); results.add(converted); } @@ -82,10 +83,10 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public List getAll(){ + public List getAll() { List results = new ArrayList(); - for(IRecipe recipe : recipes){ + for (IRecipe recipe : recipes) { ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); results.add(converted); } @@ -94,16 +95,16 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public int remove(IIngredient output){ + public int remove(IIngredient output, @Optional boolean nbtMatch) { List toRemove = new ArrayList(); List removeIndex = new ArrayList(); - for(int i = 0; i < recipes.size(); i++){ + for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); // certain special recipes have no predefined output. ignore those // since these cannot be removed with MineTweaker scripts - if(recipe.getRecipeOutput() != null){ - if(output.matches(getIItemStack(recipe.getRecipeOutput()))){ + if (recipe.getRecipeOutput() != null) { + if (nbtMatch ? output.matchesExact(getIItemStack(recipe.getRecipeOutput())) : output.matches(getIItemStack(recipe.getRecipeOutput()))) { toRemove.add(recipe); removeIndex.add(i); } @@ -115,31 +116,31 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function){ + public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { addShaped(output, ingredients, function, false); } @Override - public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function){ + public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { addShaped(output, ingredients, function, true); } @Override - public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function){ + public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); IRecipe irecipe = RecipeConverter.convert(recipe); MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); } @Override - public int removeShaped(IIngredient output, IIngredient[][] ingredients){ + public int removeShaped(IIngredient output, IIngredient[][] ingredients) { int ingredientsWidth = 0; int ingredientsHeight = 0; - if(ingredients != null){ + if (ingredients != null) { ingredientsHeight = ingredients.length; - for(int i = 0; i < ingredients.length; i++){ + for (int i = 0; i < ingredients.length; i++) { ingredientsWidth = Math.max(ingredientsWidth, ingredients[i].length); } } @@ -147,56 +148,56 @@ public class MCRecipeManager implements IRecipeManager{ List toRemove = new ArrayList(); List removeIndex = new ArrayList(); outer: - for(int i = 0; i < recipes.size(); i++){ + for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); - if(recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))){ + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { continue; } - if(ingredients != null){ - if(recipe instanceof ShapedRecipes){ + if (ingredients != null) { + if (recipe instanceof ShapedRecipes) { ShapedRecipes srecipe = (ShapedRecipes) recipe; - if(ingredientsWidth != srecipe.recipeWidth || ingredientsHeight != srecipe.recipeHeight){ + if (ingredientsWidth != srecipe.recipeWidth || ingredientsHeight != srecipe.recipeHeight) { continue; } - for(int j = 0; j < ingredientsHeight; j++){ + for (int j = 0; j < ingredientsHeight; j++) { IIngredient[] row = ingredients[j]; - for(int k = 0; k < ingredientsWidth; k++){ + for (int k = 0; k < ingredientsWidth; k++) { IIngredient ingredient = k > row.length ? null : row[k]; ItemStack recipeIngredient = srecipe.recipeItems[j * srecipe.recipeWidth + k]; - if(!matches(recipeIngredient, ingredient)){ + if (!matches(recipeIngredient, ingredient)) { continue outer; } } } - }else if(recipe instanceof ShapedOreRecipe){ + } else if (recipe instanceof ShapedOreRecipe) { ShapedOreRecipe srecipe = (ShapedOreRecipe) recipe; int recipeWidth = MineTweakerHacks.getShapedOreRecipeWidth(srecipe); int recipeHeight = srecipe.getRecipeSize() / recipeWidth; - if(ingredientsWidth != recipeWidth || ingredientsHeight != recipeHeight){ + if (ingredientsWidth != recipeWidth || ingredientsHeight != recipeHeight) { continue; } - for(int j = 0; j < ingredientsHeight; j++){ + for (int j = 0; j < ingredientsHeight; j++) { IIngredient[] row = ingredients[j]; - for(int k = 0; k < ingredientsWidth; k++){ + for (int k = 0; k < ingredientsWidth; k++) { IIngredient ingredient = k > row.length ? null : row[k]; Object input = srecipe.getInput()[j * recipeWidth + k]; - if(!matches(input, ingredient)){ + if (!matches(input, ingredient)) { continue outer; } } } } - }else{ - if(recipe instanceof ShapedRecipes){ + } else { + if (recipe instanceof ShapedRecipes) { - }else if(recipe instanceof ShapedOreRecipe){ + } else if (recipe instanceof ShapedOreRecipe) { - }else{ + } else { continue; } } @@ -210,52 +211,52 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public int removeShapeless(IIngredient output, IIngredient[] ingredients, boolean wildcard){ + public int removeShapeless(IIngredient output, IIngredient[] ingredients, boolean wildcard) { List toRemove = new ArrayList(); List removeIndex = new ArrayList(); outer: - for(int i = 0; i < recipes.size(); i++){ + for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); - if(recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))){ + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { continue; } - if(ingredients != null){ - if(recipe instanceof ShapelessRecipes){ + if (ingredients != null) { + if (recipe instanceof ShapelessRecipes) { ShapelessRecipes srecipe = (ShapelessRecipes) recipe; - if(ingredients.length > srecipe.getRecipeSize()){ + if (ingredients.length > srecipe.getRecipeSize()) { continue; - }else if(!wildcard && ingredients.length < srecipe.getRecipeSize()){ + } else if (!wildcard && ingredients.length < srecipe.getRecipeSize()) { continue; } checkIngredient: - for(int j = 0; j < ingredients.length; j++){ - for(int k = 0; k < srecipe.getRecipeSize(); k++){ - if(matches(srecipe.recipeItems.get(k), ingredients[j])){ + for (int j = 0; j < ingredients.length; j++) { + for (int k = 0; k < srecipe.getRecipeSize(); k++) { + if (matches(srecipe.recipeItems.get(k), ingredients[j])) { continue checkIngredient; } } continue outer; } - }else if(recipe instanceof ShapelessOreRecipe){ + } else if (recipe instanceof ShapelessOreRecipe) { ShapelessOreRecipe srecipe = (ShapelessOreRecipe) recipe; ArrayList inputs = srecipe.getInput(); - if(inputs.size() < ingredients.length){ + if (inputs.size() < ingredients.length) { continue; } - if(!wildcard && inputs.size() > ingredients.length){ + if (!wildcard && inputs.size() > ingredients.length) { continue; } checkIngredient: - for(int j = 0; j < ingredients.length; j++){ - for(int k = 0; k < srecipe.getRecipeSize(); k++){ - if(matches(inputs.get(k), ingredients[j])){ + for (int j = 0; j < ingredients.length; j++) { + for (int k = 0; k < srecipe.getRecipeSize(); k++) { + if (matches(inputs.get(k), ingredients[j])) { continue checkIngredient; } } @@ -263,12 +264,12 @@ public class MCRecipeManager implements IRecipeManager{ continue outer; } } - }else{ - if(recipe instanceof ShapelessRecipes){ + } else { + if (recipe instanceof ShapelessRecipes) { - }else if(recipe instanceof ShapelessOreRecipe){ + } else if (recipe instanceof ShapelessOreRecipe) { - }else{ + } else { continue; } } @@ -282,136 +283,136 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public IItemStack craft(IItemStack[][] contents){ + public IItemStack craft(IItemStack[][] contents) { Container container = new ContainerVirtual(); int width = 0; int height = contents.length; - for(IItemStack[] row : contents){ + for (IItemStack[] row : contents) { width = Math.max(width, row.length); } ItemStack[] iContents = new ItemStack[width * height]; - for(int i = 0; i < height; i++){ - for(int j = 0; j < contents[i].length; j++){ - if(contents[i][j] != null){ + for (int i = 0; i < height; i++) { + for (int j = 0; j < contents[i].length; j++) { + if (contents[i][j] != null) { iContents[i * width + j] = getItemStack(contents[i][j]); } } } InventoryCrafting inventory = new InventoryCrafting(container, width, height); - for(int i = 0; i < iContents.length; i++){ + for (int i = 0; i < iContents.length; i++) { inventory.setInventorySlotContents(i, iContents[i]); } ItemStack result = CraftingManager.getInstance().findMatchingRecipe(inventory, null); - if(result == null){ + if (result == null) { return null; - }else{ + } else { return getIItemStack(result); } } - private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored){ + private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); IRecipe irecipe = RecipeConverter.convert(recipe); MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); } - private class ContainerVirtual extends Container{ + private class ContainerVirtual extends Container { @Override - public boolean canInteractWith(EntityPlayer var1){ + public boolean canInteractWith(EntityPlayer var1) { return false; } } - private class ActionRemoveRecipes implements IUndoableAction{ + private class ActionRemoveRecipes implements IUndoableAction { private final List removingIndices; private final List removingRecipes; - public ActionRemoveRecipes(List recipes, List indices){ + public ActionRemoveRecipes(List recipes, List indices) { this.removingIndices = indices; this.removingRecipes = recipes; } @Override - public void apply(){ - for(int i = removingIndices.size() - 1; i >= 0; i--){ + public void apply() { + for (int i = removingIndices.size() - 1; i >= 0; i--) { recipes.remove((int) removingIndices.get(i)); } } @Override - public boolean canUndo(){ + public boolean canUndo() { return true; } @Override - public void undo(){ - for(int i = 0; i < removingIndices.size(); i++){ + public void undo() { + for (int i = 0; i < removingIndices.size(); i++) { int index = Math.min(recipes.size(), removingIndices.get(i)); recipes.add(index, removingRecipes.get(i)); } } @Override - public String describe(){ + public String describe() { return "Removing " + removingIndices.size() + " recipes"; } @Override - public String describeUndo(){ + public String describeUndo() { return "Restoring " + removingIndices.size() + " recipes"; } @Override - public Object getOverrideKey(){ + public Object getOverrideKey() { return null; } } - private class ActionAddRecipe implements IUndoableAction{ + private class ActionAddRecipe implements IUndoableAction { private final IRecipe recipe; private final ICraftingRecipe craftingRecipe; - public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe){ + public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { this.recipe = recipe; this.craftingRecipe = craftingRecipe; } @Override - public void apply(){ + public void apply() { recipes.add(recipe); - if(craftingRecipe.hasTransformers()){ + if (craftingRecipe.hasTransformers()) { transformerRecipes.add(craftingRecipe); } } @Override - public boolean canUndo(){ + public boolean canUndo() { return true; } @Override - public void undo(){ + public void undo() { recipes.remove(recipe); - if(craftingRecipe.hasTransformers()){ + if (craftingRecipe.hasTransformers()) { transformerRecipes.remove(craftingRecipe); } } @Override - public String describe(){ + public String describe() { return "Adding recipe for " + recipe.getRecipeOutput().getDisplayName(); } @Override - public String describeUndo(){ + public String describeUndo() { return "Removing recipe for " + recipe.getRecipeOutput().getDisplayName(); } @Override - public Object getOverrideKey(){ + public Object getOverrideKey() { return null; } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java index 76746d6..cd2535f 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java @@ -34,6 +34,7 @@ import net.minecraftforge.oredict.OreDictionary; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; @@ -287,6 +288,28 @@ public class MCItemStack implements IItemStack { return internal !=null && stack !=null &&internal.getItem() == stack.getItem() && (wildcardSize || internal.stackSize >= stack.stackSize) && (stack.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack.getItemDamage() == internal.getItemDamage() || (!stack.getHasSubtypes() && !stack.getItem().isDamageable())); } + @Override + public boolean matchesExact(IItemStack item) { + ItemStack internal = getItemStack(item); + if (internal.getTagCompound() != null && stack.getTagCompound() == null) { + return false; + } + if (internal.getTagCompound() == null && stack.getTagCompound() != null) { + return false; + } + if (internal.getTagCompound() == null && stack.getTagCompound() == null) { + return stack.getItem() == internal.getItem() && (internal.getItemDamage() == 32767 || stack.getItemDamage() == internal.getItemDamage()); + } + if (internal.getTagCompound().func_150296_c().equals(stack.getTagCompound().func_150296_c())) { + for (String s : (Set)internal.getTagCompound().func_150296_c()) { + if (!internal.getTagCompound().getTag(s).equals(stack.getTagCompound().getTag(s))) { + return false; + } + } + } + return stack.getItem() == internal.getItem() && (internal.getItemDamage() == 32767 || stack.getItemDamage() == internal.getItemDamage()); + } + @Override public boolean matches(ILiquidStack liquid) { return false; diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java index ed148a8..1ddeb4e 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java @@ -1,23 +1,13 @@ package minetweaker.mc1710.recipes; -import minetweaker.api.recipes.ShapedRecipe; -import minetweaker.api.recipes.ShapelessRecipe; -import java.util.ArrayList; -import java.util.List; import minetweaker.IUndoableAction; import minetweaker.MineTweakerAPI; -import minetweaker.mc1710.util.MineTweakerHacks; import minetweaker.api.item.IIngredient; import minetweaker.api.item.IItemStack; import minetweaker.api.minecraft.MineTweakerMC; -import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; -import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; -import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; import minetweaker.api.player.IPlayer; -import minetweaker.api.recipes.ICraftingInventory; -import minetweaker.api.recipes.ICraftingRecipe; -import minetweaker.api.recipes.IRecipeFunction; -import minetweaker.api.recipes.IRecipeManager; +import minetweaker.api.recipes.*; +import minetweaker.mc1710.util.MineTweakerHacks; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.InventoryCrafting; @@ -28,393 +18,402 @@ import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; +import stanhebben.zenscript.annotations.Optional; + +import java.util.ArrayList; +import java.util.List; + +import static minetweaker.api.minecraft.MineTweakerMC.*; /** - * * @author Stan */ public class MCRecipeManager implements IRecipeManager { - private final List recipes; - private final List transformerRecipes; - - public MCRecipeManager() { - recipes = (List) CraftingManager.getInstance().getRecipeList(); - transformerRecipes = new ArrayList(); - } - - public boolean hasTransformerRecipes() { - return transformerRecipes.size() > 0; - } - - public void applyTransformations(ICraftingInventory inventory, IPlayer byPlayer) { - for (ICraftingRecipe recipe : transformerRecipes) { - if (recipe.matches(inventory)) { - recipe.applyTransformers(inventory, byPlayer); - return; - } - } - } - - @Override - public List getRecipesFor(IIngredient ingredient) { - List results = new ArrayList(); - - for (IRecipe recipe : recipes) { - if (ingredient.matches(MineTweakerMC.getIItemStack(recipe.getRecipeOutput()))) { - ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); - results.add(converted); - } - } - - return results; - } - - @Override - public List getAll() { - List results = new ArrayList(); - - for (IRecipe recipe : recipes) { - ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); - results.add(converted); - } - - return results; - } - - @Override - public int remove(IIngredient output) { - List toRemove = new ArrayList(); - List removeIndex = new ArrayList(); - for (int i = 0; i < recipes.size(); i++) { - IRecipe recipe = recipes.get(i); - - // certain special recipes have no predefined output. ignore those - // since these cannot be removed with MineTweaker scripts - if (recipe.getRecipeOutput() != null) { - if (output.matches(getIItemStack(recipe.getRecipeOutput()))) { - toRemove.add(recipe); - removeIndex.add(i); - } - } - } - - MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); - return toRemove.size(); - } - - @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { - addShaped(output, ingredients, function, false); - } - - @Override - public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { - addShaped(output, ingredients, function, true); - } - - @Override - public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { - ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); - IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); - } - - @Override - public int removeShaped(IIngredient output, IIngredient[][] ingredients) { - int ingredientsWidth = 0; - int ingredientsHeight = 0; - - if (ingredients != null) { - ingredientsHeight = ingredients.length; - - for (int i = 0; i < ingredients.length; i++) { - ingredientsWidth = Math.max(ingredientsWidth, ingredients[i].length); - } - } - - List toRemove = new ArrayList(); - List removeIndex = new ArrayList(); - outer: for (int i = 0; i < recipes.size(); i++) { - IRecipe recipe = recipes.get(i); - - if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { - continue; - } - - if (ingredients != null) { - if (recipe instanceof ShapedRecipes) { - ShapedRecipes srecipe = (ShapedRecipes) recipe; - if (ingredientsWidth != srecipe.recipeWidth || ingredientsHeight != srecipe.recipeHeight) { - continue; - } - - for (int j = 0; j < ingredientsHeight; j++) { - IIngredient[] row = ingredients[j]; - for (int k = 0; k < ingredientsWidth; k++) { - IIngredient ingredient = k > row.length ? null : row[k]; - ItemStack recipeIngredient = srecipe.recipeItems[j * srecipe.recipeWidth + k]; - - if (!matches(recipeIngredient, ingredient)) { - continue outer; - } - } - } - } else if (recipe instanceof ShapedOreRecipe) { - ShapedOreRecipe srecipe = (ShapedOreRecipe) recipe; - int recipeWidth = MineTweakerHacks.getShapedOreRecipeWidth(srecipe); - int recipeHeight = srecipe.getRecipeSize() / recipeWidth; - if (ingredientsWidth != recipeWidth || ingredientsHeight != recipeHeight) { - continue; - } - - for (int j = 0; j < ingredientsHeight; j++) { - IIngredient[] row = ingredients[j]; - for (int k = 0; k < ingredientsWidth; k++) { - IIngredient ingredient = k > row.length ? null : row[k]; - Object input = srecipe.getInput()[j * recipeWidth + k]; - if (!matches(input, ingredient)) { - continue outer; - } - } - } - } - } else { - if (recipe instanceof ShapedRecipes) { - - } else if (recipe instanceof ShapedOreRecipe) { - - } else { - continue; - } - } - - toRemove.add(recipe); - removeIndex.add(i); - } - - MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); - return toRemove.size(); - } - - @Override - public int removeShapeless(IIngredient output, IIngredient[] ingredients, boolean wildcard) { - List toRemove = new ArrayList(); - List removeIndex = new ArrayList(); - outer: for (int i = 0; i < recipes.size(); i++) { - IRecipe recipe = recipes.get(i); - - if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { - continue; - } - - if (ingredients != null) { - if (recipe instanceof ShapelessRecipes) { - ShapelessRecipes srecipe = (ShapelessRecipes) recipe; - - if (ingredients.length > srecipe.getRecipeSize()) { - continue; - } else if (!wildcard && ingredients.length < srecipe.getRecipeSize()) { - continue; - } - - checkIngredient: for (int j = 0; j < ingredients.length; j++) { - for (int k = 0; k < srecipe.getRecipeSize(); k++) { - if (matches(srecipe.recipeItems.get(k), ingredients[j])) { - continue checkIngredient; - } - } - - continue outer; - } - } else if (recipe instanceof ShapelessOreRecipe) { - ShapelessOreRecipe srecipe = (ShapelessOreRecipe) recipe; - ArrayList inputs = srecipe.getInput(); - - if (inputs.size() < ingredients.length) { - continue; - } - if (!wildcard && inputs.size() > ingredients.length) { - continue; - } - - checkIngredient: for (int j = 0; j < ingredients.length; j++) { - for (int k = 0; k < srecipe.getRecipeSize(); k++) { - if (matches(inputs.get(k), ingredients[j])) { - continue checkIngredient; - } - } - - continue outer; - } - } - } else { - if (recipe instanceof ShapelessRecipes) { - - } else if (recipe instanceof ShapelessOreRecipe) { - - } else { - continue; - } - } - - toRemove.add(recipe); - removeIndex.add(i); - } - - MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); - return toRemove.size(); - } - - @Override - public IItemStack craft(IItemStack[][] contents) { - Container container = new ContainerVirtual(); - - int width = 0; - int height = contents.length; - for (IItemStack[] row : contents) { - width = Math.max(width, row.length); - } - - ItemStack[] iContents = new ItemStack[width * height]; - for (int i = 0; i < height; i++) { - for (int j = 0; j < contents[i].length; j++) { - if (contents[i][j] != null) { - iContents[i * width + j] = getItemStack(contents[i][j]); - } - } - } - - InventoryCrafting inventory = new InventoryCrafting(container, width, height); - for (int i = 0; i < iContents.length; i++) { - inventory.setInventorySlotContents(i, iContents[i]); - } - ItemStack result = CraftingManager.getInstance().findMatchingRecipe(inventory, null); - if (result == null) { - return null; - } else { - return getIItemStack(result); - } - } - - private class ContainerVirtual extends Container { - @Override - public boolean canInteractWith(EntityPlayer var1) { - return false; - } - } - - private class ActionRemoveRecipes implements IUndoableAction { - private final List removingIndices; - private final List removingRecipes; - - public ActionRemoveRecipes(List recipes, List indices) { - this.removingIndices = indices; - this.removingRecipes = recipes; - } - - @Override - public void apply() { - for (int i = removingIndices.size() - 1; i >= 0; i--) { - recipes.remove((int) removingIndices.get(i)); - } - } - - @Override - public boolean canUndo() { - return true; - } - - @Override - public void undo() { - for (int i = 0; i < removingIndices.size(); i++) { - int index = Math.min(recipes.size(), removingIndices.get(i)); - recipes.add(index, removingRecipes.get(i)); - } - } - - @Override - public String describe() { - return "Removing " + removingIndices.size() + " recipes"; - } - - @Override - public String describeUndo() { - return "Restoring " + removingIndices.size() + " recipes"; - } - - @Override - public Object getOverrideKey() { - return null; - } - } - - private class ActionAddRecipe implements IUndoableAction { - private final IRecipe recipe; - private final ICraftingRecipe craftingRecipe; - - public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { - this.recipe = recipe; - this.craftingRecipe = craftingRecipe; - } - - @Override - public void apply() { - recipes.add(recipe); - if (craftingRecipe.hasTransformers()) { - transformerRecipes.add(craftingRecipe); - } - } - - @Override - public boolean canUndo() { - return true; - } - - @Override - public void undo() { - recipes.remove(recipe); - if (craftingRecipe.hasTransformers()) { - transformerRecipes.remove(craftingRecipe); - } - } - - @Override - public String describe() { - return "Adding recipe for " + recipe.getRecipeOutput().getDisplayName(); - } - - @Override - public String describeUndo() { - return "Removing recipe for " + recipe.getRecipeOutput().getDisplayName(); - } - - @Override - public Object getOverrideKey() { - return null; - } - } - - private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { - ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); - IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); - } - - private static boolean matches(Object input, IIngredient ingredient) { - if ((input == null) != (ingredient == null)) { - return false; - } else if (ingredient != null) { - if (input instanceof ItemStack) { - if (!ingredient.matches(getIItemStack((ItemStack) input))) { - return false; - } - } else if (input instanceof String) { - if (!ingredient.contains(getOreDict((String) input))) { - return false; - } - } - } - - return true; - } + private final List recipes; + private final List transformerRecipes; + + public MCRecipeManager() { + recipes = (List) CraftingManager.getInstance().getRecipeList(); + transformerRecipes = new ArrayList(); + } + + public boolean hasTransformerRecipes() { + return transformerRecipes.size() > 0; + } + + public void applyTransformations(ICraftingInventory inventory, IPlayer byPlayer) { + for (ICraftingRecipe recipe : transformerRecipes) { + if (recipe.matches(inventory)) { + recipe.applyTransformers(inventory, byPlayer); + return; + } + } + } + + @Override + public List getRecipesFor(IIngredient ingredient) { + List results = new ArrayList(); + + for (IRecipe recipe : recipes) { + if (ingredient.matches(MineTweakerMC.getIItemStack(recipe.getRecipeOutput()))) { + ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); + results.add(converted); + } + } + + return results; + } + + @Override + public List getAll() { + List results = new ArrayList(); + + for (IRecipe recipe : recipes) { + ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); + results.add(converted); + } + + return results; + } + + @Override + public int remove(IIngredient output, @Optional boolean nbtMatch) { + List toRemove = new ArrayList(); + List removeIndex = new ArrayList(); + for (int i = 0; i < recipes.size(); i++) { + IRecipe recipe = recipes.get(i); + + // certain special recipes have no predefined output. ignore those + // since these cannot be removed with MineTweaker scripts + if (recipe.getRecipeOutput() != null) { + if (nbtMatch ? output.matchesExact(getIItemStack(recipe.getRecipeOutput())) : output.matches(getIItemStack(recipe.getRecipeOutput()))) { + toRemove.add(recipe); + removeIndex.add(i); + } + } + } + + MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); + return toRemove.size(); + } + + @Override + public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, function, false); + } + + @Override + public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { + addShaped(output, ingredients, function, true); + } + + @Override + public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { + ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); + IRecipe irecipe = RecipeConverter.convert(recipe); + MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + } + + @Override + public int removeShaped(IIngredient output, IIngredient[][] ingredients) { + int ingredientsWidth = 0; + int ingredientsHeight = 0; + + if (ingredients != null) { + ingredientsHeight = ingredients.length; + + for (int i = 0; i < ingredients.length; i++) { + ingredientsWidth = Math.max(ingredientsWidth, ingredients[i].length); + } + } + + List toRemove = new ArrayList(); + List removeIndex = new ArrayList(); + outer: + for (int i = 0; i < recipes.size(); i++) { + IRecipe recipe = recipes.get(i); + + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { + continue; + } + + if (ingredients != null) { + if (recipe instanceof ShapedRecipes) { + ShapedRecipes srecipe = (ShapedRecipes) recipe; + if (ingredientsWidth != srecipe.recipeWidth || ingredientsHeight != srecipe.recipeHeight) { + continue; + } + + for (int j = 0; j < ingredientsHeight; j++) { + IIngredient[] row = ingredients[j]; + for (int k = 0; k < ingredientsWidth; k++) { + IIngredient ingredient = k > row.length ? null : row[k]; + ItemStack recipeIngredient = srecipe.recipeItems[j * srecipe.recipeWidth + k]; + + if (!matches(recipeIngredient, ingredient)) { + continue outer; + } + } + } + } else if (recipe instanceof ShapedOreRecipe) { + ShapedOreRecipe srecipe = (ShapedOreRecipe) recipe; + int recipeWidth = MineTweakerHacks.getShapedOreRecipeWidth(srecipe); + int recipeHeight = srecipe.getRecipeSize() / recipeWidth; + if (ingredientsWidth != recipeWidth || ingredientsHeight != recipeHeight) { + continue; + } + + for (int j = 0; j < ingredientsHeight; j++) { + IIngredient[] row = ingredients[j]; + for (int k = 0; k < ingredientsWidth; k++) { + IIngredient ingredient = k > row.length ? null : row[k]; + Object input = srecipe.getInput()[j * recipeWidth + k]; + if (!matches(input, ingredient)) { + continue outer; + } + } + } + } + } else { + if (recipe instanceof ShapedRecipes) { + + } else if (recipe instanceof ShapedOreRecipe) { + + } else { + continue; + } + } + + toRemove.add(recipe); + removeIndex.add(i); + } + + MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); + return toRemove.size(); + } + + @Override + public int removeShapeless(IIngredient output, IIngredient[] ingredients, boolean wildcard) { + List toRemove = new ArrayList(); + List removeIndex = new ArrayList(); + outer: + for (int i = 0; i < recipes.size(); i++) { + IRecipe recipe = recipes.get(i); + + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { + continue; + } + + if (ingredients != null) { + if (recipe instanceof ShapelessRecipes) { + ShapelessRecipes srecipe = (ShapelessRecipes) recipe; + + if (ingredients.length > srecipe.getRecipeSize()) { + continue; + } else if (!wildcard && ingredients.length < srecipe.getRecipeSize()) { + continue; + } + + checkIngredient: + for (int j = 0; j < ingredients.length; j++) { + for (int k = 0; k < srecipe.getRecipeSize(); k++) { + if (matches(srecipe.recipeItems.get(k), ingredients[j])) { + continue checkIngredient; + } + } + + continue outer; + } + } else if (recipe instanceof ShapelessOreRecipe) { + ShapelessOreRecipe srecipe = (ShapelessOreRecipe) recipe; + ArrayList inputs = srecipe.getInput(); + + if (inputs.size() < ingredients.length) { + continue; + } + if (!wildcard && inputs.size() > ingredients.length) { + continue; + } + + checkIngredient: + for (int j = 0; j < ingredients.length; j++) { + for (int k = 0; k < srecipe.getRecipeSize(); k++) { + if (matches(inputs.get(k), ingredients[j])) { + continue checkIngredient; + } + } + + continue outer; + } + } + } else { + if (recipe instanceof ShapelessRecipes) { + + } else if (recipe instanceof ShapelessOreRecipe) { + + } else { + continue; + } + } + + toRemove.add(recipe); + removeIndex.add(i); + } + + MineTweakerAPI.apply(new ActionRemoveRecipes(toRemove, removeIndex)); + return toRemove.size(); + } + + @Override + public IItemStack craft(IItemStack[][] contents) { + Container container = new ContainerVirtual(); + + int width = 0; + int height = contents.length; + for (IItemStack[] row : contents) { + width = Math.max(width, row.length); + } + + ItemStack[] iContents = new ItemStack[width * height]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < contents[i].length; j++) { + if (contents[i][j] != null) { + iContents[i * width + j] = getItemStack(contents[i][j]); + } + } + } + + InventoryCrafting inventory = new InventoryCrafting(container, width, height); + for (int i = 0; i < iContents.length; i++) { + inventory.setInventorySlotContents(i, iContents[i]); + } + ItemStack result = CraftingManager.getInstance().findMatchingRecipe(inventory, null); + if (result == null) { + return null; + } else { + return getIItemStack(result); + } + } + + private class ContainerVirtual extends Container { + @Override + public boolean canInteractWith(EntityPlayer var1) { + return false; + } + } + + private class ActionRemoveRecipes implements IUndoableAction { + private final List removingIndices; + private final List removingRecipes; + + public ActionRemoveRecipes(List recipes, List indices) { + this.removingIndices = indices; + this.removingRecipes = recipes; + } + + @Override + public void apply() { + for (int i = removingIndices.size() - 1; i >= 0; i--) { + recipes.remove((int) removingIndices.get(i)); + } + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + for (int i = 0; i < removingIndices.size(); i++) { + int index = Math.min(recipes.size(), removingIndices.get(i)); + recipes.add(index, removingRecipes.get(i)); + } + } + + @Override + public String describe() { + return "Removing " + removingIndices.size() + " recipes"; + } + + @Override + public String describeUndo() { + return "Restoring " + removingIndices.size() + " recipes"; + } + + @Override + public Object getOverrideKey() { + return null; + } + } + + private class ActionAddRecipe implements IUndoableAction { + private final IRecipe recipe; + private final ICraftingRecipe craftingRecipe; + + public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { + this.recipe = recipe; + this.craftingRecipe = craftingRecipe; + } + + @Override + public void apply() { + recipes.add(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.add(craftingRecipe); + } + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + recipes.remove(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.remove(craftingRecipe); + } + } + + @Override + public String describe() { + return "Adding recipe for " + recipe.getRecipeOutput().getDisplayName(); + } + + @Override + public String describeUndo() { + return "Removing recipe for " + recipe.getRecipeOutput().getDisplayName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } + + private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { + ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); + IRecipe irecipe = RecipeConverter.convert(recipe); + MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); + } + + private static boolean matches(Object input, IIngredient ingredient) { + if ((input == null) != (ingredient == null)) { + return false; + } else if (ingredient != null) { + if (input instanceof ItemStack) { + if (!ingredient.matches(getIItemStack((ItemStack) input))) { + return false; + } + } else if (input instanceof String) { + if (!ingredient.contains(getOreDict((String) input))) { + return false; + } + } + } + + return true; + } } diff --git a/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/item/MCItemStack.java b/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/item/MCItemStack.java index a3ec635..bed0da4 100644 --- a/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/item/MCItemStack.java +++ b/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/item/MCItemStack.java @@ -286,6 +286,28 @@ public class MCItemStack implements IItemStack{ return internal != null && stack != null && internal.getItem() == stack.getItem() && (wildcardSize || internal.stackSize >= stack.stackSize) && (stack.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack.getItemDamage() == internal.getItemDamage() || (!stack.getHasSubtypes() && !stack.getItem().isDamageable())); } + @Override + public boolean matchesExact(IItemStack item) { + ItemStack internal = getItemStack(item); + if (internal.getTagCompound() != null && stack.getTagCompound() == null) { + return false; + } + if (internal.getTagCompound() == null && stack.getTagCompound() != null) { + return false; + } + if (internal.getTagCompound() == null && stack.getTagCompound() == null) { + return stack.getItem() == internal.getItem() && (internal.getMetadata() == 32767 || stack.getMetadata() == internal.getMetadata()); + } + if (internal.getTagCompound().getKeySet().equals(stack.getTagCompound().getKeySet())) { + for (String s : internal.getTagCompound().getKeySet()) { + if (!internal.getTagCompound().getTag(s).equals(stack.getTagCompound().getTag(s))) { + return false; + } + } + } + return stack.getItem() == internal.getItem() && (internal.getMetadata() == 32767 || stack.getMetadata() == internal.getMetadata()); + } + @Override public boolean matches(ILiquidStack liquid){ return false; diff --git a/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/recipes/MCRecipeManager.java b/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/recipes/MCRecipeManager.java index 5f9066c..0f8452b 100644 --- a/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC18-Main/src/main/java/minetweaker/mc18/recipes/MCRecipeManager.java @@ -18,6 +18,7 @@ import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; +import stanhebben.zenscript.annotations.Optional; import java.util.ArrayList; import java.util.List; @@ -27,25 +28,25 @@ import static minetweaker.api.minecraft.MineTweakerMC.*; /** * @author Stan */ -public class MCRecipeManager implements IRecipeManager{ +public class MCRecipeManager implements IRecipeManager { private final List recipes; private final List transformerRecipes; - public MCRecipeManager(){ + public MCRecipeManager() { recipes = CraftingManager.getInstance().getRecipeList(); transformerRecipes = new ArrayList(); } - private static boolean matches(Object input, IIngredient ingredient){ - if((input == null) != (ingredient == null)){ + private static boolean matches(Object input, IIngredient ingredient) { + if ((input == null) != (ingredient == null)) { return false; - }else if(ingredient != null){ - if(input instanceof ItemStack){ - if(!ingredient.matches(getIItemStack((ItemStack) input))){ + } else if (ingredient != null) { + if (input instanceof ItemStack) { + if (!ingredient.matches(getIItemStack((ItemStack) input))) { return false; } - }else if(input instanceof String){ - if(!ingredient.contains(getOreDict((String) input))){ + } else if (input instanceof String) { + if (!ingredient.contains(getOreDict((String) input))) { return false; } } @@ -54,13 +55,13 @@ public class MCRecipeManager implements IRecipeManager{ return true; } - public boolean hasTransformerRecipes(){ + public boolean hasTransformerRecipes() { return transformerRecipes.size() > 0; } - public void applyTransformations(ICraftingInventory inventory, IPlayer byPlayer){ - for(ICraftingRecipe recipe : transformerRecipes){ - if(recipe.matches(inventory)){ + public void applyTransformations(ICraftingInventory inventory, IPlayer byPlayer) { + for (ICraftingRecipe recipe : transformerRecipes) { + if (recipe.matches(inventory)) { recipe.applyTransformers(inventory, byPlayer); return; } @@ -68,11 +69,11 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public List getRecipesFor(IIngredient ingredient){ + public List getRecipesFor(IIngredient ingredient) { List results = new ArrayList(); - for(IRecipe recipe : recipes){ - if(ingredient.matches(MineTweakerMC.getIItemStack(recipe.getRecipeOutput()))){ + for (IRecipe recipe : recipes) { + if (ingredient.matches(MineTweakerMC.getIItemStack(recipe.getRecipeOutput()))) { ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); results.add(converted); } @@ -82,10 +83,10 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public List getAll(){ + public List getAll() { List results = new ArrayList(); - for(IRecipe recipe : recipes){ + for (IRecipe recipe : recipes) { ICraftingRecipe converted = RecipeConverter.toCraftingRecipe(recipe); results.add(converted); } @@ -94,16 +95,16 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public int remove(IIngredient output){ + public int remove(IIngredient output, @Optional boolean nbtMatch) { List toRemove = new ArrayList(); List removeIndex = new ArrayList(); - for(int i = 0; i < recipes.size(); i++){ + for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); // certain special recipes have no predefined output. ignore those // since these cannot be removed with MineTweaker scripts - if(recipe.getRecipeOutput() != null){ - if(output.matches(getIItemStack(recipe.getRecipeOutput()))){ + if (recipe.getRecipeOutput() != null) { + if (nbtMatch ? output.matchesExact(getIItemStack(recipe.getRecipeOutput())) : output.matches(getIItemStack(recipe.getRecipeOutput()))) { toRemove.add(recipe); removeIndex.add(i); } @@ -115,31 +116,31 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function){ + public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { addShaped(output, ingredients, function, false); } @Override - public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function){ + public void addShapedMirrored(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function) { addShaped(output, ingredients, function, true); } @Override - public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function){ + public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); IRecipe irecipe = RecipeConverter.convert(recipe); MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); } @Override - public int removeShaped(IIngredient output, IIngredient[][] ingredients){ + public int removeShaped(IIngredient output, IIngredient[][] ingredients) { int ingredientsWidth = 0; int ingredientsHeight = 0; - if(ingredients != null){ + if (ingredients != null) { ingredientsHeight = ingredients.length; - for(int i = 0; i < ingredients.length; i++){ + for (int i = 0; i < ingredients.length; i++) { ingredientsWidth = Math.max(ingredientsWidth, ingredients[i].length); } } @@ -147,56 +148,56 @@ public class MCRecipeManager implements IRecipeManager{ List toRemove = new ArrayList(); List removeIndex = new ArrayList(); outer: - for(int i = 0; i < recipes.size(); i++){ + for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); - if(recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))){ + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { continue; } - if(ingredients != null){ - if(recipe instanceof ShapedRecipes){ + if (ingredients != null) { + if (recipe instanceof ShapedRecipes) { ShapedRecipes srecipe = (ShapedRecipes) recipe; - if(ingredientsWidth != srecipe.recipeWidth || ingredientsHeight != srecipe.recipeHeight){ + if (ingredientsWidth != srecipe.recipeWidth || ingredientsHeight != srecipe.recipeHeight) { continue; } - for(int j = 0; j < ingredientsHeight; j++){ + for (int j = 0; j < ingredientsHeight; j++) { IIngredient[] row = ingredients[j]; - for(int k = 0; k < ingredientsWidth; k++){ + for (int k = 0; k < ingredientsWidth; k++) { IIngredient ingredient = k > row.length ? null : row[k]; ItemStack recipeIngredient = srecipe.recipeItems[j * srecipe.recipeWidth + k]; - if(!matches(recipeIngredient, ingredient)){ + if (!matches(recipeIngredient, ingredient)) { continue outer; } } } - }else if(recipe instanceof ShapedOreRecipe){ + } else if (recipe instanceof ShapedOreRecipe) { ShapedOreRecipe srecipe = (ShapedOreRecipe) recipe; int recipeWidth = MineTweakerHacks.getShapedOreRecipeWidth(srecipe); int recipeHeight = srecipe.getRecipeSize() / recipeWidth; - if(ingredientsWidth != recipeWidth || ingredientsHeight != recipeHeight){ + if (ingredientsWidth != recipeWidth || ingredientsHeight != recipeHeight) { continue; } - for(int j = 0; j < ingredientsHeight; j++){ + for (int j = 0; j < ingredientsHeight; j++) { IIngredient[] row = ingredients[j]; - for(int k = 0; k < ingredientsWidth; k++){ + for (int k = 0; k < ingredientsWidth; k++) { IIngredient ingredient = k > row.length ? null : row[k]; Object input = srecipe.getInput()[j * recipeWidth + k]; - if(!matches(input, ingredient)){ + if (!matches(input, ingredient)) { continue outer; } } } } - }else{ - if(recipe instanceof ShapedRecipes){ + } else { + if (recipe instanceof ShapedRecipes) { - }else if(recipe instanceof ShapedOreRecipe){ + } else if (recipe instanceof ShapedOreRecipe) { - }else{ + } else { continue; } } @@ -210,52 +211,52 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public int removeShapeless(IIngredient output, IIngredient[] ingredients, boolean wildcard){ + public int removeShapeless(IIngredient output, IIngredient[] ingredients, boolean wildcard) { List toRemove = new ArrayList(); List removeIndex = new ArrayList(); outer: - for(int i = 0; i < recipes.size(); i++){ + for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); - if(recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))){ + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { continue; } - if(ingredients != null){ - if(recipe instanceof ShapelessRecipes){ + if (ingredients != null) { + if (recipe instanceof ShapelessRecipes) { ShapelessRecipes srecipe = (ShapelessRecipes) recipe; - if(ingredients.length > srecipe.getRecipeSize()){ + if (ingredients.length > srecipe.getRecipeSize()) { continue; - }else if(!wildcard && ingredients.length < srecipe.getRecipeSize()){ + } else if (!wildcard && ingredients.length < srecipe.getRecipeSize()) { continue; } checkIngredient: - for(int j = 0; j < ingredients.length; j++){ - for(int k = 0; k < srecipe.getRecipeSize(); k++){ - if(matches(srecipe.recipeItems.get(k), ingredients[j])){ + for (int j = 0; j < ingredients.length; j++) { + for (int k = 0; k < srecipe.getRecipeSize(); k++) { + if (matches(srecipe.recipeItems.get(k), ingredients[j])) { continue checkIngredient; } } continue outer; } - }else if(recipe instanceof ShapelessOreRecipe){ + } else if (recipe instanceof ShapelessOreRecipe) { ShapelessOreRecipe srecipe = (ShapelessOreRecipe) recipe; ArrayList inputs = srecipe.getInput(); - if(inputs.size() < ingredients.length){ + if (inputs.size() < ingredients.length) { continue; } - if(!wildcard && inputs.size() > ingredients.length){ + if (!wildcard && inputs.size() > ingredients.length) { continue; } checkIngredient: - for(int j = 0; j < ingredients.length; j++){ - for(int k = 0; k < srecipe.getRecipeSize(); k++){ - if(matches(inputs.get(k), ingredients[j])){ + for (int j = 0; j < ingredients.length; j++) { + for (int k = 0; k < srecipe.getRecipeSize(); k++) { + if (matches(inputs.get(k), ingredients[j])) { continue checkIngredient; } } @@ -263,12 +264,12 @@ public class MCRecipeManager implements IRecipeManager{ continue outer; } } - }else{ - if(recipe instanceof ShapelessRecipes){ + } else { + if (recipe instanceof ShapelessRecipes) { - }else if(recipe instanceof ShapelessOreRecipe){ + } else if (recipe instanceof ShapelessOreRecipe) { - }else{ + } else { continue; } } @@ -282,136 +283,136 @@ public class MCRecipeManager implements IRecipeManager{ } @Override - public IItemStack craft(IItemStack[][] contents){ + public IItemStack craft(IItemStack[][] contents) { Container container = new ContainerVirtual(); int width = 0; int height = contents.length; - for(IItemStack[] row : contents){ + for (IItemStack[] row : contents) { width = Math.max(width, row.length); } ItemStack[] iContents = new ItemStack[width * height]; - for(int i = 0; i < height; i++){ - for(int j = 0; j < contents[i].length; j++){ - if(contents[i][j] != null){ + for (int i = 0; i < height; i++) { + for (int j = 0; j < contents[i].length; j++) { + if (contents[i][j] != null) { iContents[i * width + j] = getItemStack(contents[i][j]); } } } InventoryCrafting inventory = new InventoryCrafting(container, width, height); - for(int i = 0; i < iContents.length; i++){ + for (int i = 0; i < iContents.length; i++) { inventory.setInventorySlotContents(i, iContents[i]); } ItemStack result = CraftingManager.getInstance().findMatchingRecipe(inventory, null); - if(result == null){ + if (result == null) { return null; - }else{ + } else { return getIItemStack(result); } } - private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored){ + private void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); IRecipe irecipe = RecipeConverter.convert(recipe); MineTweakerAPI.apply(new ActionAddRecipe(irecipe, recipe)); } - private class ContainerVirtual extends Container{ + private class ContainerVirtual extends Container { @Override - public boolean canInteractWith(EntityPlayer var1){ + public boolean canInteractWith(EntityPlayer var1) { return false; } } - private class ActionRemoveRecipes implements IUndoableAction{ + private class ActionRemoveRecipes implements IUndoableAction { private final List removingIndices; private final List removingRecipes; - public ActionRemoveRecipes(List recipes, List indices){ + public ActionRemoveRecipes(List recipes, List indices) { this.removingIndices = indices; this.removingRecipes = recipes; } @Override - public void apply(){ - for(int i = removingIndices.size() - 1; i >= 0; i--){ + public void apply() { + for (int i = removingIndices.size() - 1; i >= 0; i--) { recipes.remove((int) removingIndices.get(i)); } } @Override - public boolean canUndo(){ + public boolean canUndo() { return true; } @Override - public void undo(){ - for(int i = 0; i < removingIndices.size(); i++){ + public void undo() { + for (int i = 0; i < removingIndices.size(); i++) { int index = Math.min(recipes.size(), removingIndices.get(i)); recipes.add(index, removingRecipes.get(i)); } } @Override - public String describe(){ + public String describe() { return "Removing " + removingIndices.size() + " recipes"; } @Override - public String describeUndo(){ + public String describeUndo() { return "Restoring " + removingIndices.size() + " recipes"; } @Override - public Object getOverrideKey(){ + public Object getOverrideKey() { return null; } } - private class ActionAddRecipe implements IUndoableAction{ + private class ActionAddRecipe implements IUndoableAction { private final IRecipe recipe; private final ICraftingRecipe craftingRecipe; - public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe){ + public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { this.recipe = recipe; this.craftingRecipe = craftingRecipe; } @Override - public void apply(){ + public void apply() { recipes.add(recipe); - if(craftingRecipe.hasTransformers()){ + if (craftingRecipe.hasTransformers()) { transformerRecipes.add(craftingRecipe); } } @Override - public boolean canUndo(){ + public boolean canUndo() { return true; } @Override - public void undo(){ + public void undo() { recipes.remove(recipe); - if(craftingRecipe.hasTransformers()){ + if (craftingRecipe.hasTransformers()) { transformerRecipes.remove(craftingRecipe); } } @Override - public String describe(){ + public String describe() { return "Adding recipe for " + recipe.getRecipeOutput().getDisplayName(); } @Override - public String describeUndo(){ + public String describeUndo() { return "Removing recipe for " + recipe.getRecipeOutput().getDisplayName(); } @Override - public Object getOverrideKey(){ + public Object getOverrideKey() { return null; } }