2016-07-28 41 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); 
}