[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)

By: Celtic Minstrel <celtic.minstrel.ca@some.place>
This commit is contained in:
CraftBukkit/Spigot 2011-07-23 23:16:14 -04:00
parent 39944f7043
commit bed15aa413
5 changed files with 129 additions and 28 deletions

View file

@ -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<Recipe> getRecipesFor(ItemStack result) {
List<Recipe> results = new ArrayList<Recipe>();
Iterator<Recipe> 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<Recipe> 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<String, String[]> 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;
}

View file

@ -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));
}
}

View file

@ -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<Character, ItemStack> 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<Character, MaterialData> ingred = this.getIngredientMap();
Map<Character, ItemStack> 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++;
}

View file

@ -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<MaterialData> ingred = this.getIngredientList();
List<ItemStack> 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++;
}

View file

@ -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<Recipe> {
private Iterator<CraftingRecipe> recipes;
private Iterator<Integer> 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();
}
}