不幸的是,Bukkit API不提供方式与自定义ItemMeta
(项目存储知识和NBT数据部分)注册配方ingredientes,但你可以绕过这一限制在两个方面:
1)注册没有自定义元的配方,并检查它是否存在,当玩家尝试创建它们时,该项目将显示在输出槽中,但玩家将无法获得它。 视频显示进度这个例子:)https://youtu.be/zbSf_wATaGk
public void onEnable()
{
final ShapedRecipe packedice = new ShapedRecipe(new ItemStack(Material.PACKED_ICE));
packedice.shape(new String[]{"aba","bcb","aba"}).setIngredient('a', Material.PRISMARINE_SHARD).setIngredient('b', Material.GOLD_BLOCK).setIngredient('c', Material.SNOW_BALL);
Bukkit.addRecipe(packedice);
Bukkit.getPluginManager().registerEvents(new Listener()
{
@EventHandler
void onCraft(CraftItemEvent event)
{
// Check if it's being crafted with your custom recipe
// You can check only the event.getRecipe().getResult() if you are not worried about recipe conflicts.
if(!matches(packedice, event.getInventory().getMatrix()))
return;
// The lore that will be required in all prismarine shards
List<String> neededLore = Arrays.asList("Line1","Line2");
// Check if all prismarine shares has that lore,
// you can check only one of them or whatever item you want
// The indexes are:
// 0 1 2 | Shard Gold Shard
// 3 4 5 | Gold Snow Gold
// 4 7 8 | Shard Gold Shard
ItemStack[] matrix = event.getInventory().getMatrix();
for(ItemStack item: matrix)
if(item != null && item.getType() == Material.PRISMARINE_SHARD)
if(!neededLore.equals(item.getItemMeta().getLore()))
{
event.setCancelled(true);
return;
}
}
}, this);
}
/**
* Checks if a crafting matrix matches a recipe
*/
public static boolean matches(ShapedRecipe recipe, ItemStack[] matrix)
{
String[] shapeStr = recipe.getShape();
int len = 0;
for(String line : shapeStr)
len += line.length();
char[] shape = new char[len];
int shapeIndex = 0;
for(String line : shapeStr)
for(char c: line.toCharArray())
shape[shapeIndex++] = c;
for(int i = 0; i < shape.length; i++)
{
ItemStack required = recipe.getIngredientMap().get(shape[i]);
ItemStack found = matrix[i];
if(found == null || !required.getData().equals(found.getData()))
return false;
}
return true;
}
可以超越Bukkit API和使用CraftBukkit和的Minecraft对象进行登记,检查的NBT标签定制的配方对象,这样玩家就不会看到任何输出,除非他使用与配方中注册的完全相同的项目,您还可以注册重命名或附魔对象的配方。 视频展示这个例子中的进展:https://youtu.be/Gr3ADckGBUA
public void onEnable()
{
ItemStack shard = new ItemStack(Material.PRISMARINE_SHARD);
ItemMeta itemMeta = shard.getItemMeta();
itemMeta.setLore(Arrays.asList("Line1", "Line2"));
shard.setItemMeta(itemMeta);
registerShapedRecipe(new ItemStack(Material.PACKED_ICE),
"aba", "bcb", "aba",
'a', shard,
'b', new ItemStack(Material.GOLD_BLOCK),
'c', new ItemStack(Material.SNOW_BALL)
);
}
/**
* Register a recipe that checks for NBT Tags.
*
* Require these imports:
* import net.minecraft.server.v1_8_R3.*;
* import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
*
* Change v1_8_R3 to match your craftbukkit version
*/
public static void registerShapedRecipe(ItemStack result, Object... data)
{
String s = "";
int index = 0;
int height = 0;
int width = 0;
if(data[index] instanceof String[])
{
String[] strings = (String[])data[index++];
for(String shapedRecipes : strings)
{
++width;
height = shapedRecipes.length();
s = s + shapedRecipes;
}
}
else
{
while(data[index] instanceof String) {
String str = (String)data[index++];
++width;
height = str.length();
s = s + str;
}
}
HashMap<Character, net.minecraft.server.v1_8_R3.ItemStack> charMap;
for(charMap = Maps.newHashMap(); index < data.length; index += 2)
{
Character c = (Character)data[index];
net.minecraft.server.v1_8_R3.ItemStack stack = null;
if(data[index + 1] instanceof ItemStack)
stack = CraftItemStack.asNMSCopy((ItemStack) data[index + 1]);
else if(data[index + 1] instanceof Item)
stack = new net.minecraft.server.v1_8_R3.ItemStack((Item)data[index + 1]);
else if(data[index + 1] instanceof net.minecraft.server.v1_8_R3.Block)
stack = new net.minecraft.server.v1_8_R3.ItemStack((net.minecraft.server.v1_8_R3.Block)data[index + 1], 1, Short.MAX_VALUE);
else if(data[index + 1] instanceof net.minecraft.server.v1_8_R3.ItemStack)
stack = (net.minecraft.server.v1_8_R3.ItemStack)data[index + 1];
charMap.put(c, stack);
}
net.minecraft.server.v1_8_R3.ItemStack[] ingredients = new net.minecraft.server.v1_8_R3.ItemStack[height * width];
for(int j = 0; j < height * width; ++j)
{
char c = s.charAt(j);
if(charMap.containsKey(c))
ingredients[j] = charMap.get(c).cloneItemStack();
else
ingredients[j] = null;
}
ShapedRecipes recipe = new ShapedRecipes(height, width, ingredients, CraftItemStack.asNMSCopy(result))
{
/**
* The method name can change depending on your CraftBukkit version!
*/
@Override
public boolean a(InventoryCrafting inventory, World world)
{
for(int i = 0; i < ingredients.length; i++)
{
net.minecraft.server.v1_8_R3.ItemStack ingredient = ingredients[i];
net.minecraft.server.v1_8_R3.ItemStack found = inventory.getItem(i);
if(ingredient == null)
{
if(found == null)
continue;
else
return false;
}
if(found == null)
return false;
if(ingredient.getItem() != found.getItem() || ingredient.getData() != found.getData())
return false;
if(ingredient.hasTag())
{
if(!found.hasTag())
return false;
if(!ingredient.getTag().equals(found.getTag()))
return false;
}
}
return true;
}
};
CraftingManager.getInstance().recipes.add(recipe);
}
做到这一点的代码检查,如果项目还没有绝杀,没有手艺? – drhopeness