From 326091c130657294157d137895663ad2924c0b95 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 23 Jul 2011 23:16:14 -0400 Subject: [PATCH] [Bleeding] Recipe API improvements and fixes. Addresses BUKKIT-738 and BUKKIT-624 Add a recipe iterator to make it possible to retrieve and remove recipes (BUKKIT-738), and updated the recipe classes to not clip the data to 127 (BUKKIT-624) --- .../net/minecraft/server/CraftingManager.java | 13 +++- .../net/minecraft/server/CraftingRecipe.java | 4 ++ .../net/minecraft/server/FurnaceRecipes.java | 4 +- .../net/minecraft/server/ShapedRecipes.java | 62 +++++++++++++++++++ .../minecraft/server/ShapelessRecipes.java | 20 ++++++ .../org/bukkit/craftbukkit/CraftServer.java | 40 +++++++++++- .../inventory/CraftFurnaceRecipe.java | 15 ++--- .../inventory/CraftShapedRecipe.java | 29 ++++++--- .../inventory/CraftShapelessRecipe.java | 24 ++++--- .../craftbukkit/inventory/RecipeIterator.java | 49 +++++++++++++++ 10 files changed, 227 insertions(+), 33 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java index 45923c1313..c785425b16 100644 --- a/src/main/java/net/minecraft/server/CraftingManager.java +++ b/src/main/java/net/minecraft/server/CraftingManager.java @@ -8,13 +8,13 @@ import java.util.List; public class CraftingManager { private static final CraftingManager a = new CraftingManager(); - private List b = new ArrayList(); + public List b = new ArrayList(); // CraftBukkit - private -> public public static final CraftingManager getInstance() { return a; } - private CraftingManager() { + public CraftingManager() { // CraftBukkit - private -> public (new RecipesTools()).a(this); (new RecipesWeapons()).a(this); (new RecipeIngots()).a(this); @@ -91,10 +91,17 @@ public class CraftingManager { this.registerShapedRecipe(new ItemStack(Item.BED, 1), new Object[] { "###", "XXX", Character.valueOf('#'), Block.WOOL, Character.valueOf('X'), Block.WOOD}); this.registerShapedRecipe(new ItemStack(Block.ENCHANTMENT_TABLE, 1), new Object[] { " B ", "D#D", "###", Character.valueOf('#'), Block.OBSIDIAN, Character.valueOf('B'), Item.BOOK, Character.valueOf('D'), Item.DIAMOND}); this.registerShapelessRecipe(new ItemStack(Item.EYE_OF_ENDER, 1), new Object[] { Item.ENDER_PEARL, Item.BLAZE_POWDER}); - Collections.sort(this.b, new RecipeSorter(this)); + //Collections.sort(this.b, new RecipeSorter(this)); // CraftBukkit - removed; see below + this.sort(); // CraftBukkit - moved sort to a separate method System.out.println(this.b.size() + " recipes"); } + // CraftBukkit start + public void sort() { + Collections.sort(this.b, new RecipeSorter(this)); + } + // CraftBukkit end + public void registerShapedRecipe(ItemStack itemstack, Object... aobject) { // CraftBukkit - default -> public String s = ""; int i = 0; diff --git a/src/main/java/net/minecraft/server/CraftingRecipe.java b/src/main/java/net/minecraft/server/CraftingRecipe.java index dee3749cd9..28c2526d1d 100644 --- a/src/main/java/net/minecraft/server/CraftingRecipe.java +++ b/src/main/java/net/minecraft/server/CraftingRecipe.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import org.bukkit.inventory.Recipe; // CraftBukkit + public interface CraftingRecipe { boolean a(InventoryCrafting inventorycrafting); @@ -9,4 +11,6 @@ public interface CraftingRecipe { int a(); ItemStack b(); + + Recipe toBukkitRecipe(); // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/FurnaceRecipes.java b/src/main/java/net/minecraft/server/FurnaceRecipes.java index 8d4bd61b69..e0c4f1e343 100644 --- a/src/main/java/net/minecraft/server/FurnaceRecipes.java +++ b/src/main/java/net/minecraft/server/FurnaceRecipes.java @@ -6,13 +6,13 @@ import java.util.Map; public class FurnaceRecipes { private static final FurnaceRecipes a = new FurnaceRecipes(); - private Map b = new HashMap(); + public Map b = new HashMap(); // CraftBukkit - private -> public public static final FurnaceRecipes getInstance() { return a; } - private FurnaceRecipes() { + public FurnaceRecipes() { // CraftBukkit - private -> public this.registerRecipe(Block.IRON_ORE.id, new ItemStack(Item.IRON_INGOT)); this.registerRecipe(Block.GOLD_ORE.id, new ItemStack(Item.GOLD_INGOT)); this.registerRecipe(Block.DIAMOND_ORE.id, new ItemStack(Item.DIAMOND)); diff --git a/src/main/java/net/minecraft/server/ShapedRecipes.java b/src/main/java/net/minecraft/server/ShapedRecipes.java index 6fde0c73bd..eccfd47e5e 100644 --- a/src/main/java/net/minecraft/server/ShapedRecipes.java +++ b/src/main/java/net/minecraft/server/ShapedRecipes.java @@ -1,5 +1,11 @@ package net.minecraft.server; +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; +import org.bukkit.inventory.ShapedRecipe; +// CraftBukkit end + public class ShapedRecipes implements CraftingRecipe { private int b; @@ -16,6 +22,62 @@ public class ShapedRecipes implements CraftingRecipe { this.e = itemstack; } + // CraftBukkit start + public ShapedRecipe toBukkitRecipe() { + CraftItemStack result = new CraftItemStack(this.e); + CraftShapedRecipe recipe = new CraftShapedRecipe(result, this); + switch (this.b) { + case 1: + switch (this.c) { + case 1: + recipe.shape("a"); + break; + case 2: + recipe.shape("ab"); + break; + case 3: + recipe.shape("abc"); + break; + } + break; + case 2: + switch (this.c) { + case 1: + recipe.shape("a","b"); + break; + case 2: + recipe.shape("ab","cd"); + break; + case 3: + recipe.shape("abc","def"); + break; + } + break; + case 3: + switch (this.c) { + case 1: + recipe.shape("a","b","c"); + break; + case 2: + recipe.shape("ab","cd","ef"); + break; + case 3: + recipe.shape("abc","def","ghi"); + break; + } + break; + } + char c = 'a'; + for (ItemStack stack : this.d) { + if (stack != null) { + recipe.setIngredient(c, org.bukkit.Material.getMaterial(stack.id), stack.getData()); + } + c++; + } + return recipe; + } + // CraftBukkit end + public ItemStack b() { return this.e; } diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java index d38896a4af..bea33ccf77 100644 --- a/src/main/java/net/minecraft/server/ShapelessRecipes.java +++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java @@ -4,6 +4,12 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; +import org.bukkit.inventory.ShapelessRecipe; +// CraftBukkit end + public class ShapelessRecipes implements CraftingRecipe { private final ItemStack a; @@ -14,6 +20,20 @@ public class ShapelessRecipes implements CraftingRecipe { this.b = list; } + // CraftBukkit start + @SuppressWarnings("unchecked") + public ShapelessRecipe toBukkitRecipe() { + CraftItemStack result = new CraftItemStack(this.a); + CraftShapelessRecipe recipe = new CraftShapelessRecipe(result, this); + for (ItemStack stack : (List) this.b) { + if (stack != null) { + recipe.addIngredient(org.bukkit.Material.getMaterial(stack.id), stack.getData()); + } + } + return recipe; + } + // CraftBukkit end + public ItemStack b() { return this.a; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 933aa0bc76..a855d57646 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -18,13 +19,14 @@ import java.util.logging.Logger; import net.minecraft.server.ChunkCoordinates; import net.minecraft.server.ConvertProgressUpdater; import net.minecraft.server.Convertable; +import net.minecraft.server.CraftingManager; import net.minecraft.server.Enchantment; import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityTracker; +import net.minecraft.server.FurnaceRecipes; import net.minecraft.server.IProgressUpdate; import net.minecraft.server.IWorldAccess; import net.minecraft.server.Item; -import net.minecraft.server.ItemStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.MobEffectList; import net.minecraft.server.PropertyManager; @@ -60,6 +62,7 @@ import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe; import org.bukkit.craftbukkit.inventory.CraftRecipe; import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; +import org.bukkit.craftbukkit.inventory.RecipeIterator; import org.bukkit.craftbukkit.map.CraftMapView; import org.bukkit.craftbukkit.potion.CraftPotionBrewer; import org.bukkit.craftbukkit.scheduler.CraftScheduler; @@ -74,6 +77,7 @@ import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.FurnaceRecipe; +import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; @@ -463,6 +467,7 @@ public final class CraftServer implements Server { pluginManager.clearPlugins(); commandMap.clearCommands(); + resetRecipes(); int pollCount = 0; @@ -780,9 +785,40 @@ public final class CraftServer implements Server { } } toAdd.addToCraftingManager(); + CraftingManager.getInstance().sort(); return true; } + public List getRecipesFor(ItemStack result) { + List results = new ArrayList(); + Iterator iter = recipeIterator(); + while (iter.hasNext()) { + Recipe recipe = iter.next(); + ItemStack stack = recipe.getResult(); + if (stack.getType() != result.getType()) { + continue; + } + if (result.getDurability() == -1 || result.getDurability() == stack.getDurability()) { + results.add(recipe); + } + } + return results; + } + + public Iterator recipeIterator() { + return new RecipeIterator(); + } + + public void clearRecipes() { + CraftingManager.getInstance().b.clear(); + FurnaceRecipes.getInstance().b().clear(); + } + + public void resetRecipes() { + CraftingManager.getInstance().b = new CraftingManager().b; + FurnaceRecipes.getInstance().b = new FurnaceRecipes().b; + } + @SuppressWarnings("unchecked") public Map getCommandAliases() { ConfigurationSection section = configuration.getConfigurationSection("aliases"); @@ -866,7 +902,7 @@ public final class CraftServer implements Server { } public CraftMapView createMap(World world) { - ItemStack stack = new ItemStack(Item.MAP, 1, -1); + net.minecraft.server.ItemStack stack = new net.minecraft.server.ItemStack(Item.MAP, 1, -1); WorldMap worldmap = Item.MAP.getSavedMap(stack, ((CraftWorld) world).getHandle()); return worldmap.mapView; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java index 5afab7d81a..8f67b6f170 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java @@ -2,18 +2,12 @@ package org.bukkit.craftbukkit.inventory; import net.minecraft.server.FurnaceRecipes; -import org.bukkit.Material; import org.bukkit.inventory.FurnaceRecipe; import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; public class CraftFurnaceRecipe extends FurnaceRecipe implements CraftRecipe { - public CraftFurnaceRecipe(ItemStack result, Material source) { - super(result, source); - } - - public CraftFurnaceRecipe(ItemStack result, MaterialData source) { - super(result, source); + public CraftFurnaceRecipe(ItemStack result, ItemStack source) { + super(result, source.getType(), source.getDurability()); } public static CraftFurnaceRecipe fromBukkitRecipe(FurnaceRecipe recipe) { @@ -24,7 +18,8 @@ public class CraftFurnaceRecipe extends FurnaceRecipe implements CraftRecipe { } public void addToCraftingManager() { - MaterialData input = this.getInput(); - FurnaceRecipes.getInstance().registerRecipe(input.getItemTypeId(), CraftItemStack.createNMSItemStack(this.getResult())); + ItemStack result = this.getResult(); + ItemStack input = this.getInput(); + FurnaceRecipes.getInstance().registerRecipe(input.getTypeId(), CraftItemStack.createNMSItemStack(result)); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java index 3af12516de..5d89d79df0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java @@ -1,17 +1,25 @@ package org.bukkit.craftbukkit.inventory; -import java.util.HashMap; +import java.util.Map; import net.minecraft.server.CraftingManager; +import net.minecraft.server.ShapedRecipes; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ShapedRecipe; -import org.bukkit.material.MaterialData; public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { + // TODO: Could eventually use this to add a matches() method or some such + private ShapedRecipes recipe; + public CraftShapedRecipe(ItemStack result) { super(result); } + + public CraftShapedRecipe(ItemStack result, ShapedRecipes recipe) { + this(result); + this.recipe = recipe; + } public static CraftShapedRecipe fromBukkitRecipe(ShapedRecipe recipe) { if (recipe instanceof CraftShapedRecipe) { @@ -20,8 +28,12 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { CraftShapedRecipe ret = new CraftShapedRecipe(recipe.getResult()); String[] shape = recipe.getShape(); ret.shape(shape); - for (char c : recipe.getIngredientMap().keySet()) { - ret.setIngredient(c, recipe.getIngredientMap().get(c)); + Map ingredientMap = recipe.getIngredientMap(); + for (char c : ingredientMap.keySet()) { + ItemStack stack = ingredientMap.get(c); + if (stack != null) { + ret.setIngredient(c, stack.getType(), stack.getDurability()); + } } return ret; } @@ -29,7 +41,7 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { public void addToCraftingManager() { Object[] data; String[] shape = this.getShape(); - HashMap ingred = this.getIngredientMap(); + Map ingred = this.getIngredientMap(); int datalen = shape.length; datalen += ingred.size() * 2; int i = 0; @@ -38,11 +50,12 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { data[i] = shape[i]; } for (char c : ingred.keySet()) { + ItemStack mdata = ingred.get(c); + if (mdata == null) continue; data[i] = c; i++; - MaterialData mdata = ingred.get(c); - int id = mdata.getItemTypeId(); - byte dmg = mdata.getData(); + int id = mdata.getTypeId(); + short dmg = mdata.getDurability(); data[i] = new net.minecraft.server.ItemStack(id, 1, dmg); i++; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java index cef7187c92..54287b9221 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java @@ -1,36 +1,44 @@ package org.bukkit.craftbukkit.inventory; -import java.util.ArrayList; +import java.util.List; import net.minecraft.server.CraftingManager; +import net.minecraft.server.ShapelessRecipes; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ShapelessRecipe; -import org.bukkit.material.MaterialData; public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe { + // TODO: Could eventually use this to add a matches() method or some such + private ShapelessRecipes recipe; + public CraftShapelessRecipe(ItemStack result) { super(result); } + + public CraftShapelessRecipe(ItemStack result, ShapelessRecipes recipe) { + this(result); + this.recipe = recipe; + } public static CraftShapelessRecipe fromBukkitRecipe(ShapelessRecipe recipe) { if (recipe instanceof CraftShapelessRecipe) { return (CraftShapelessRecipe) recipe; } CraftShapelessRecipe ret = new CraftShapelessRecipe(recipe.getResult()); - for (MaterialData ingred : recipe.getIngredientList()) { - ret.addIngredient(ingred); + for (ItemStack ingred : recipe.getIngredientList()) { + ret.addIngredient(ingred.getType(), ingred.getDurability()); } return ret; } public void addToCraftingManager() { - ArrayList ingred = this.getIngredientList(); + List ingred = this.getIngredientList(); Object[] data = new Object[ingred.size()]; int i = 0; - for (MaterialData mdata : ingred) { - int id = mdata.getItemTypeId(); - byte dmg = mdata.getData(); + for (ItemStack mdata : ingred) { + int id = mdata.getTypeId(); + short dmg = mdata.getDurability(); data[i] = new net.minecraft.server.ItemStack(id, 1, dmg); i++; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java new file mode 100644 index 0000000000..7cb6b47588 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java @@ -0,0 +1,49 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Iterator; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; + +import net.minecraft.server.CraftingManager; +import net.minecraft.server.CraftingRecipe; +import net.minecraft.server.FurnaceRecipes; + +public class RecipeIterator implements Iterator { + private Iterator recipes; + private Iterator smelting; + private Iterator removeFrom = null; + + public RecipeIterator() { + this.recipes = CraftingManager.getInstance().b().iterator(); + this.smelting = FurnaceRecipes.getInstance().b().keySet().iterator(); + } + + public boolean hasNext() { + if (recipes.hasNext()) { + return true; + } else { + return smelting.hasNext(); + } + } + + public Recipe next() { + if (recipes.hasNext()) { + removeFrom = recipes; + return recipes.next().toBukkitRecipe(); + } else { + removeFrom = smelting; + int id = smelting.next(); + CraftItemStack stack = new CraftItemStack(FurnaceRecipes.getInstance().a(id)); + CraftFurnaceRecipe recipe = new CraftFurnaceRecipe(stack, new ItemStack(id, 1, (short) -1)); + return recipe; + } + } + + public void remove() { + if (removeFrom == null) { + throw new IllegalStateException(); + } + removeFrom.remove(); + } +}