Custom recipes plugin using new itemstack with ShapedRecipe

Discussion in 'Plugin Development' started by Ozeir, Jul 23, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Ozeir

    How can I use a new itemstack with a shapedrecipe?
    The iron_ingot has to be a steel ingot

    Code:
    Code:
    package me.braedenh.conquestarmor;
     
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapedRecipe;
    import org.bukkit.inventory.ShapelessRecipe;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.material.MaterialData;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class Main extends JavaPlugin{
     
     
        {
            Bukkit.getServer().clearRecipes();
        }
     
        public void onEnable() {
            srecipe();
            shrecipe();
        }
        private void shrecipe() {
            ItemStack steelhelmet = new ItemStack(Material.CHAINMAIL_HELMET, 1);
            ItemMeta meta = steelhelmet.getItemMeta();
            meta.setDisplayName(ChatColor.GRAY + "Steel Helmet");
            steelhelmet.setItemMeta(meta);
       
            ShapedRecipe shrecipe = new ShapedRecipe(steelhelmet);
            shrecipe.shape("SSS",
                          "S S",
                          "  ");
            shrecipe.setIngredient('S', new MaterialData(Material.IRON_INGOT));
            Bukkit.getServer().addRecipe(shrecipe);
       
       
        }
        private void srecipe() {
            ItemStack steel = new ItemStack(Material.IRON_INGOT, 1);
            ItemMeta meta = steel.getItemMeta();
            meta.setDisplayName(ChatColor.GRAY + "Steel Ingot");
            steel.setItemMeta(meta);
       
            ShapelessRecipe srecipe = new ShapelessRecipe(steel);
            srecipe.addIngredient(1, Material.IRON_BLOCK);
            srecipe.addIngredient(1, Material.GOLD_BLOCK);
            srecipe.addIngredient(3, Material.FLINT);
            Bukkit.getServer().addRecipe(srecipe);
       
       
       
        }
        public void onDisable() {
       
        }
     
     
    }
    
     
  2. Ozeir Create a method which returns a new ItemStack (SteelIngot).
    Code:
    public ItemStack steelIngot() {
        ItemStack steel = new ItemStack(Material.IRON_INGOT, 1);
        ItemMeta meta = steel.getItemMeta();
        meta.setDisplayName(ChatColor.GRAY + "Steel Ingot");
        steel.setItemMeta(meta);
        return steel;
    }
    Then use that for the ItemStack for the ShapedRecipe.
     
  3. Offline

    desht

    Since there's no ShapedRecipe setIngredient() method which accepts ItemStack as an ingredient type, that isn't going to work too well.

    Ozeir correct solution: use the PrepareItemCraftEvent - see https://forums.bukkit.org/threads/create-crafting-recipe-custom-ingredients.232664/
     
    DJSkepter likes this.
  4. Offline

    Ozeir

    desht like this?

    Code:java
    1.  
    2.  
    3. private static final Object shrecipe = null;
    4. private static final Object srecipe = null;
    5. {
    6.  
    7. }
    8.  
    9. @EventHandler
    10. public void restrictCrafting(PrepareItemCraftEvent event) {
    11. CraftingInventory ci = event.getInventory();
    12. if (ci.getResult().hasItemMeta() && shrecipe.equals(ci.getResult().getItemMeta().hasDisplayName())) {
    13. boolean found = false;
    14. for (ItemStack item : ci.getMatrix()) {
    15. if (item != null && item.hasItemMeta()) {
    16. if (srecipe.equals(item.getItemMeta().hasDisplayName())) {
    17. found = true;
    18. }
    19. }
    20. if (!found) {
    21. ci.setResult(null);
    22. }
    23. }


    Still not working ;/
     
  5. Offline

    desht


    What on earth are those private static final Object variables doing there? Of course that won't work; there's no way your code will do anything other than throw an NPE.

    Steps:
    1. In your event handler, check if event.getInventory().getResult() is your custom steel armour item. No need to compare recipes here, just check if the item has meta data and a display name matching your item's.
    2. If so, loop through the ingredient list (which you can get with event.getInventory().getMatrix()), and check that the ingredient is also one of your custom steel ingots. Same deal: check if it has metadata and that the display name matches your custom item name.
    3. If any ingredient doesn't match, then stop the crafting with event.getInventory().setResult(null).
    There's no need to compares recipes or anything here; it's all about checking & comparing ItemStack item meta.
     
    Garris0n likes this.
  6. Offline

    Ozeir

    desht
    What am I doing wrong here?
    Code:java
    1. @EventHandler
    2. public void restrictCrafting(PrepareItemCraftEvent event) {
    3. CraftingInventory ci = event.getInventory();
    4. if (ci.getResult() != null) {
    5. boolean found = false;
    6. for (ItemStack item : ci.getMatrix()) {
    7. if (item != null && item.hasItemMeta()) {
    8. if (item.getItemMeta().hasDisplayName()) {
    9. found = true;
    10. }
    11. }
     
  7. Offline

    desht

    Ozeir you're not checking for the specific names of your custom items, just for the presence of any item meta (and you're not even checking for the presence of item meta on the result item at all). Go back and read what I wrote in my last post.

    Since what you posted only looks like half the method, I can't tell you if you're doing anything wrong with the found flag that you're setting.
     
  8. Offline

    Ozeir

    desht
    What's the problem now?

    Code:java
    1. @EventHandler
    2. public void restrictCrafting(PrepareItemCraftEvent event) {
    3. CraftingInventory ci = event.getInventory();
    4. if (ci.getResult().hasItemMeta() && ci.getResult().getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Helmet")) {
    5. boolean found = false;
    6. for (ItemStack item : ci.getMatrix()) {
    7. if (item != null && item.hasItemMeta()) {
    8. if (item.getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Ingot")) {
    9. found = true;
    10. }
    11. }
    12. if (!found) {
    13. ci.setResult(null);
    14. }
    15. }
    16. }


    but what do I have to add here:?
    Code:java
    1. private void shrecipe() {
    2. ItemStack steelhelmet = new ItemStack(Material.CHAINMAIL_HELMET, 1);
    3. ItemMeta meta = steelhelmet.getItemMeta();
    4. meta.setDisplayName(ChatColor.GRAY + "Steel Helmet");
    5. steelhelmet.setItemMeta(meta);
    6.  
    7. ShapedRecipe shrecipe = new ShapedRecipe(steelhelmet);
    8. shrecipe.shape("SSS",
    9. "S S",
    10. " ");
    11. //setingredient Steel Ingot
    12. Bukkit.getServer().addRecipe(shrecipe);
     
  9. Offline

    Ozeir

    bump
     
  10. Offline

    Ozeir

    Still need help...
     
  11. Offline

    fireblast709

    Ozeir use an iron ingot with datavalue 1 as steel ingot, and use
    Code:Java
    1. new MaterialData(Material.IRON_INGOT, 1)
    as the ingredient. This 'trick' should work for every item that does not use datavalue.

    ( desht any objections or stuff I overlooked?)
     
  12. Offline

    desht

    Yeah, that would work too. A possible drawback is that clashes with other plugins which add "custom" items are more likely when using damage values than if you use item meta. And there's always the risk (probably small) of Mojang using those data values in some later MC release. And as you point out, it doesn't work for items that use damage values already (mainly tools/weapons/armour but also items like wood, coal etc.)
     
  13. Offline

    Ozeir

  14. Offline

    fireblast709

    Ozeir cast the int to byte ;). For the NPE, check if the ItemMeta and display name are null for every ItemStack, even in the for loop :3
     
  15. Offline

    Ozeir

    fireblast709
    I already tried cast int to byte didn't work :/
     
  16. Offline

    fireblast709

  17. Offline

    Ozeir

    fireblast709
    Code:java
    1. package me.braedenh.conquestarmor;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Material;
    6. import org.bukkit.event.EventHandler;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.event.inventory.PrepareItemCraftEvent;
    9. import org.bukkit.inventory.CraftingInventory;
    10. import org.bukkit.inventory.ItemStack;
    11. import org.bukkit.inventory.ShapedRecipe;
    12. import org.bukkit.inventory.ShapelessRecipe;
    13. import org.bukkit.inventory.meta.ItemMeta;
    14. import org.bukkit.material.MaterialData;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16.  
    17. public class Main extends JavaPlugin implements Listener{
    18.  
    19.  
    20. {
    21.  
    22. }
    23.  
    24. @EventHandler
    25. public void restrictCrafting(PrepareItemCraftEvent event) {
    26. CraftingInventory ci = event.getInventory();
    27. if (ci.getResult().getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Helmet")) {
    28. for (ItemStack item : ci.getMatrix()) {
    29. if (item.getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Ingot") && item.hasItemMeta()) {
    30. }
    31. ci.setResult(null);
    32. }
    33. }
    34. }
    35.  
    36.  
    37.  
    38.  
    39.  
    40. public void onEnable() {
    41. Bukkit.getServer().getPluginManager().registerEvents(this, this);
    42. srecipe();
    43. shrecipe();
    44. }
    45.  
    46. private void srecipe() {
    47. ItemStack steel = new ItemStack(Material.IRON_INGOT, 1);
    48. ItemMeta meta = steel.getItemMeta();
    49. meta.setDisplayName(ChatColor.GRAY + "Steel Ingot");
    50. steel.setItemMeta(meta);
    51.  
    52. ShapelessRecipe srecipe = new ShapelessRecipe(steel);
    53. srecipe.addIngredient(1, Material.IRON_BLOCK);
    54. srecipe.addIngredient(1, Material.GOLD_BLOCK);
    55. srecipe.addIngredient(3, Material.FLINT);
    56. Bukkit.getServer().addRecipe(srecipe);{
    57. }
    58. }
    59.  
    60. @SuppressWarnings("deprecation")
    61. private void shrecipe() {
    62. ItemStack steelhelmet = new ItemStack(Material.CHAINMAIL_HELMET, 1);
    63. ItemMeta meta = steelhelmet.getItemMeta();
    64. meta.setDisplayName(ChatColor.GRAY + "Steel Helmet");
    65. steelhelmet.setItemMeta(meta);
    66.  
    67. ShapedRecipe shrecipe = new ShapedRecipe(steelhelmet);
    68. shrecipe.shape("SSS",
    69. "S S",
    70. " ");
    71. shrecipe.setIngredient('S', new MaterialData(Material.IRON_INGOT, (byte) 1));
    72. Bukkit.getServer().addRecipe(shrecipe);
    73.  
    74. }
    75. public void onDisable() {
    76.  
    77. }
    78.  
    79.  
    80. }
     
  18. Offline

    fireblast709

    Ozeir the code itself looks fine, apart that you craft iron ingots with a name instead of iron ingots with a name and datavalue 1
     
  19. Offline

    Ozeir

  20. Offline

    fireblast709

  21. Offline

    Ozeir

    Huh.. but line 47 is itemstack steel = New itemstack(material.iron_ingot, 1)
    And 1 is the datavalue so whats wrong..? fireblast709
     
  22. Offline

    fireblast709

  23. Offline

    Ozeir

    fireblast709 i've got this:
    Code:java
    1. package me.braedenh.conquestarmor;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Material;
    6. import org.bukkit.event.EventHandler;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.event.inventory.PrepareItemCraftEvent;
    9. import org.bukkit.inventory.CraftingInventory;
    10. import org.bukkit.inventory.ItemStack;
    11. import org.bukkit.inventory.ShapedRecipe;
    12. import org.bukkit.inventory.ShapelessRecipe;
    13. import org.bukkit.inventory.meta.ItemMeta;
    14. import org.bukkit.material.MaterialData;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16.  
    17. public class Main extends JavaPlugin implements Listener{
    18.  
    19.  
    20. {
    21.  
    22. }
    23.  
    24. @EventHandler
    25. public void restrictCrafting(PrepareItemCraftEvent event) {
    26. CraftingInventory ci = event.getInventory();
    27. if (ci.getResult().getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Helmet")) {
    28. for (ItemStack item : ci.getMatrix()) {
    29. if (item.getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Ingot") && item.hasItemMeta()) {
    30. }
    31. ci.setResult(null);
    32. }
    33. }
    34. }
    35.  
    36.  
    37.  
    38.  
    39.  
    40. public void onEnable() {
    41. Bukkit.getServer().getPluginManager().registerEvents(this, this);
    42. srecipe();
    43. shrecipe();
    44. }
    45.  
    46. private void srecipe() {
    47. ItemStack steel = new ItemStack(Material.IRON_INGOT, (byte) 1);
    48. ItemMeta meta = steel.getItemMeta();
    49. meta.setDisplayName(ChatColor.GRAY + "Steel Ingot");
    50. steel.setItemMeta(meta);
    51.  
    52. ShapelessRecipe srecipe = new ShapelessRecipe(steel);
    53. srecipe.addIngredient(1, Material.IRON_BLOCK);
    54. srecipe.addIngredient(1, Material.GOLD_BLOCK);
    55. srecipe.addIngredient(3, Material.FLINT);
    56. Bukkit.getServer().addRecipe(srecipe);{
    57. }
    58. }
    59.  
    60. @SuppressWarnings("deprecation")
    61. private void shrecipe() {
    62. ItemStack steelhelmet = new ItemStack(Material.CHAINMAIL_HELMET, 1);
    63. ItemMeta meta = steelhelmet.getItemMeta();
    64. meta.setDisplayName(ChatColor.GRAY + "Steel Helmet");
    65. steelhelmet.setItemMeta(meta);
    66.  
    67. ShapedRecipe shrecipe = new ShapedRecipe(steelhelmet);
    68. shrecipe.shape("SSS",
    69. "S S",
    70. " ");
    71. shrecipe.setIngredient('S', new MaterialData(Material.IRON_INGOT, (byte) 1));
    72. Bukkit.getServer().addRecipe(shrecipe);
    73.  
    74. }
    75. public void onDisable() {
    76.  
    77. }
    78.  
    79.  
    80. }
    81.  


    When I do the recipe it gives me an error code in the console:
    http://pastebin.com/Bp6Bmtdr

    It shows an iron helmet instead of a "Steel Helmet"
    http://gyazo.com/76a9a26ecb43998e655e7c08ba097014
     
  24. Offline

    fireblast709

    Ozeir you still have the wrong constructor. Its Material, amount, data ;)

    The NPE is caused by the event. Check if the itemstacks or the names are null, and do the hasItemMeta() check before you use getItemMeta()
     
  25. Offline

    Ozeir

    fireblast709
    Same error....
    http://pastebin.com/aHBYkUDu
    Code:java
    1. package me.braedenh.conquestarmor;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Material;
    6. import org.bukkit.event.EventHandler;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.event.inventory.PrepareItemCraftEvent;
    9. import org.bukkit.inventory.CraftingInventory;
    10. import org.bukkit.inventory.ItemStack;
    11. import org.bukkit.inventory.ShapedRecipe;
    12. import org.bukkit.inventory.ShapelessRecipe;
    13. import org.bukkit.inventory.meta.ItemMeta;
    14. import org.bukkit.material.MaterialData;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16.  
    17. public class Main extends JavaPlugin implements Listener{
    18.  
    19.  
    20. {
    21.  
    22. }
    23.  
    24. @EventHandler
    25. public void restrictCrafting(PrepareItemCraftEvent event) {
    26. CraftingInventory ci = event.getInventory();
    27. ci.getResult().getItemMeta().getDisplayName().equals(null);
    28. if (ci.getResult().getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Helmet")) {
    29. for (ItemStack item : ci.getMatrix()) {
    30. if(item.hasItemMeta()) {
    31. if (item.getItemMeta().getDisplayName().contains(ChatColor.GRAY + "Steel Ingot") && item.hasItemMeta()) {
    32. }
    33. ci.setResult(null);
    34. }
    35. }
    36. }
    37. }
    38.  
    39.  
    40.  
    41.  
    42.  
    43.  
    44. public void onEnable() {
    45. Bukkit.getServer().getPluginManager().registerEvents(this, this);
    46. srecipe();
    47. shrecipe();
    48. }
    49.  
    50. private void srecipe() {
    51. ItemStack steel = new ItemStack(Material.IRON_INGOT, 1, (short)1);
    52. ItemMeta meta = steel.getItemMeta();
    53. meta.setDisplayName(ChatColor.GRAY + "Steel Ingot");
    54. steel.setItemMeta(meta);
    55.  
    56. ShapelessRecipe srecipe = new ShapelessRecipe(steel);
    57. srecipe.addIngredient(1, Material.IRON_BLOCK);
    58. srecipe.addIngredient(1, Material.GOLD_BLOCK);
    59. srecipe.addIngredient(3, Material.FLINT);
    60. Bukkit.getServer().addRecipe(srecipe);{
    61. }
    62. }
    63.  
    64. @SuppressWarnings("deprecation")
    65. private void shrecipe() {
    66. ItemStack steelhelmet = new ItemStack(Material.CHAINMAIL_HELMET, 1);
    67. ItemMeta meta = steelhelmet.getItemMeta();
    68. meta.setDisplayName(ChatColor.GRAY + "Steel Helmet");
    69. steelhelmet.setItemMeta(meta);
    70.  
    71. ShapedRecipe shrecipe = new ShapedRecipe(steelhelmet);
    72. shrecipe.shape("SSS",
    73. "S S",
    74. " ");
    75. shrecipe.setIngredient('S', new MaterialData(Material.IRON_INGOT, (byte) 1));
    76. Bukkit.getServer().addRecipe(shrecipe);
    77.  
    78. }
    79. public void onDisable() {
    80.  
    81. }
    82.  
    83.  
    84. }
     
  26. Offline

    fireblast709

    Ozeir getResult() can be null, getItemMeta() can be null, getDisplayName() can be null, item in for loop can be null. Note that equals(null) implies NullPointerException (NPE would be thrown instead of returning true)
     
  27. Offline

    Ozeir

    fireblast709 That won't work it gives remove argument to match getItemMeta(), GetDisplayName(), getResult()...
     
  28. Offline

    fireblast709

    Ozeir those methods can return null
     
  29. Offline

    Ozeir

  30. Offline

    fireblast709

    Ozeir no you need to check if its not null before using it
     
Thread Status:
Not open for further replies.

Share This Page