2016-07-28 39 views
1

我正在为我的服务器写一个CraftBukkit插件。但我找不到如何检查的成分项目有绝杀ShapedRecipe与Lore?

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

回答

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

希望它可以帮助

// EDIT : 对不起,我错过了你第一次,这将检查是否在右上角的物品有传说"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); 
       } 
      } 
     } 
    } 
} 
+0

做到这一点的代码检查,如果项目还没有绝杀,没有手艺? – drhopeness

0

不幸的是,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); 
}