ShapedRecipe与Lore?

时间:2016-07-28 09:01:49

标签: java minecraft bukkit

我正在为我的服务器编写一个CraftBukkit插件。但我找不到如何检查成分项目是否有传说

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.getServer().addRecipe(packedice);

2 个答案:

答案 0 :(得分:1)

而不是ShapedRecipe packedice = new ShapedRecipe(new ItemStack(Material.PACKED_ICE)); 你需要更多的代码:

ItemStack i = new ItemStack(Material.PACKED_ICE);
ItemMeta m = i.getItemMeta();
m.setDisplayName("CustomDisplayName")
List<String> l = new ArrayList<String>();
l.add("Line 1");
l.add("Line 2");
m.setLore(l);
i.setItemMeta(m);
ShapedRecipe packedice = new ShapedRecipe(i);

希望有所帮助

//编辑: 对不起,我先想念你,这将检查右上角的项目是否有传说"Line1"

@EventHandler
public void onCraft(CraftItemEvent e) {
    ShapedRecipe packedice = YOURRECIPE;
    if(e.getInventory().getSize() == 10 && e.getInventory().getResult().equals(packedice.getResult())) {
        if(e.getRawSlot() == 0) {
            ItemStack upleft = e.getInventory().getItem(1);
            if(upleft != null && upleft.hasItemMeta() && upleft.getItemMeta().hasLore()) {
                List<String> l = upleft.getItemMeta().getLore();
                if(!l.get(0).equals("Line 1")) {
                    e.setCancelled(true);
                }
            }
        }
    }
}

答案 1 :(得分:0)

不幸的是,Bukkit API没有提供使用自定义ItemMeta(存储传说和NBT数据的项目部分)注册配方成分的方法,但是您可以通过两种方式规避该限制:

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

2)您可以超越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);
}