[Shaped/Shapeless Recipes] Ensuring input item has exact (or no) meta

Discussion in 'Plugin Development' started by Dudemister1999, Oct 14, 2014.

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

    Dudemister1999

    Hello! I'm making an API for my up-and-coming project, but I have stumbled across a problem! If I try to craft a special item, with special input items, it'll accept any crummy item with identical materials! I cannot allow that. Normally, I'd use PrepareItemCraftEvent or CraftItemEvent, but seeing as it's an API, I have to check for anything outside the norm. Here's my current code, which does nothing:

    Show Spoiler

    Code:java
    1. @EventHandler(priority = EventPriority.LOWEST)
    2. public void onCraft(PrepareItemCraftEvent event)
    3. {
    4. CraftingInventory ci = event.getInventory();
    5. ItemStack result = ci.getResult();
    6.  
    7. for(Recipe recipe : Bukkit.getRecipesFor(result))
    8. {
    9. Recipe currentRecipe = ci.getRecipe();
    10.  
    11. if(recipe instanceof ShapedRecipe)
    12. {
    13. ShapedRecipe rec = ((ShapedRecipe)recipe);
    14. ShapedRecipe curRec = ((ShapedRecipe)currentRecipe);
    15.  
    16. for(ItemStack in : rec.getIngredientMap().values())
    17. {
    18. if(!isCorrectShaped(result, rec, curRec))
    19. {
    20. ci.setResult(null);
    21. }
    22. }
    23. }
    24. else if(recipe instanceof ShapelessRecipe)
    25. {
    26. ShapelessRecipe rec = ((ShapelessRecipe)recipe);
    27. ShapelessRecipe curRec = ((ShapelessRecipe)currentRecipe);
    28.  
    29. for(ItemStack in : rec.getIngredientList())
    30. {
    31. if(!isCorrectShapeless(result, rec, curRec))
    32. {
    33. ci.setResult(null);
    34. }
    35. }
    36. }
    37. else
    38. {
    39.  
    40. }
    41. }
    42. }
    43.  
    44. public boolean isCorrectShapeless(ItemStack out, ShapelessRecipe in, ShapelessRecipe expected)
    45. {
    46. for(ItemStack inI : in.getIngredientList())
    47. {
    48. for(ItemStack inE : expected.getIngredientList())
    49. {
    50. if(inI.getType() == inE.getType())
    51. {
    52. if(inE.hasItemMeta())
    53. {
    54. if(inI.hasItemMeta())
    55. {
    56. if(inE.getItemMeta().hasDisplayName())
    57. {
    58. if(inI.getItemMeta().hasDisplayName())
    59. {
    60. ItemMeta iM = inI.getItemMeta();
    61. ItemMeta iE = inE.getItemMeta();
    62.  
    63. if(sameName(iM.getDisplayName(), iE.getDisplayName()))
    64. {
    65. return sameLore((String[])iM.getLore().toArray(), (String[])iE.getLore().toArray());
    66. }
    67. else
    68. {
    69. return false;
    70. }
    71. }
    72. else
    73. {
    74. return false;
    75. }
    76.  
    77. }
    78. else
    79. {
    80. if(!inI.getItemMeta().hasDisplayName())
    81. {
    82. return false;
    83. }
    84. }
    85. }
    86. else
    87. {
    88. return false;
    89. }
    90. }
    91. else
    92. {
    93. if(inI.hasItemMeta())
    94. {
    95. return false;
    96. }
    97. }
    98. }
    99. }
    100. }
    101. return true;
    102. }
    103.  
    104. public boolean isCorrectShaped(ItemStack out, ShapedRecipe in, ShapedRecipe expected)
    105. {
    106. for(ItemStack inI : in.getIngredientMap().values())
    107. {
    108. for(ItemStack inE : expected.getIngredientMap().values())
    109. {
    110. if(inI != null && inE != null)
    111. {
    112. if(inI.getType() == inE.getType())
    113. {
    114. if(inE.hasItemMeta())
    115. {
    116. if(inI.hasItemMeta())
    117. {
    118. if(inE.getItemMeta().hasDisplayName())
    119. {
    120. if(inI.getItemMeta().hasDisplayName())
    121. {
    122. ItemMeta iM = inI.getItemMeta();
    123. ItemMeta iE = inE.getItemMeta();
    124.  
    125. if(sameName(iM.getDisplayName(), iE.getDisplayName()))
    126. {
    127. return sameLore((String[])iM.getLore().toArray(), (String[])iE.getLore().toArray());
    128. }
    129. else
    130. {
    131. return false;
    132. }
    133. }
    134. else
    135. {
    136. return false;
    137. }
    138.  
    139. }
    140. else
    141. {
    142. if(!inI.getItemMeta().hasDisplayName())
    143. {
    144. return false;
    145. }
    146. }
    147. }
    148. else
    149. {
    150. return false;
    151. }
    152. }
    153. else
    154. {
    155. if(inI.hasItemMeta())
    156. {
    157. return false;
    158. }
    159. }
    160. }
    161. }
    162. }
    163. }
    164. return true;
    165. }
    166.  
    167. public static boolean sameName(String in, String ex)
    168. {
    169. return in.equals(ex);
    170. }
    171.  
    172. public static boolean sameLore(String[] lore, String[] ex)
    173. {
    174. return lore == ex;
    175. }



    It's registered as a listener, I am absolutely positive. It just doesn't function. For instance, I have a recipe to craft Aluminum. It requires redstone, and renamed iron ingots. It'll accept both plain iron and iron with any metadata. That is not what I'd like it to do.

    Tl;dr I need to non-specifically force either no OR exact metadata when crafting an item.

    Thanks!
    - Hydroxocobalamin (OCHbl)
     
  2. Offline

    Dudemister1999

    23 hour bump! Still valid according to the subforum rules!
     
  3. Offline

    fireblast709

    Dudemister1999 as long as the ingredients don't use the datavalue (like tools, dyes), you could give them a datavalue and use that same datavalue in the recipe.
     
  4. Offline

    Dudemister1999

    fireblast709 I currently have something similar, though not quite. In my code above, I check for an instance of ItemMeta inside the item, and return false if not existent in the inputted item (And vice versa). Will MaterialData work, if ItemMeta does not?
     
  5. Offline

    fireblast709

    Dudemister1999 In your example, your renamed iron ingots would have a datavalue different from 0. Then, in the recipe, you would use the same datavalue. That way, only iron ingots with that specific datavalue would work in the recipe.
     
  6. Offline

    Dudemister1999

  7. Offline

    Dudemister1999

    fireblast709 Alright, I seem to have some trouble implementing it. I decided to create a custom MaterialData for the purposes of instanceof checks, but I think I am overcomplicating things. I'll post my code in a few minutes, if I can't figure it out. :p
     
  8. Offline

    Dudemister1999

    I'm going to have to bump this. I still can't get it to work. I can't do Item data, because I need to use dyes in some recipes. I have new code, which I can post if neccesary.
     
  9. Offline

    Dudemister1999

    23 hour bump. I've tried using this:
    Code:java
    1. bandage.setIngredient('P', ItemRegistry.getItem("ci_paste").createItem(1).getData());


    And it works, but it still allows any old item that has the same material.
     
  10. Offline

    Barinade

    Use inventory click event
     
  11. Offline

    Dudemister1999

    Here's a mix of a bump and an update. Here's my code:

    Code:java
    1. @EventHandler
    2. public void preCraft(PrepareItemCraftEvent event)
    3. {
    4. Recipe recipe = event.getRecipe();
    5. ItemStack result = recipe.getResult();
    6.  
    7. for(Recipe rec : Bukkit.getRecipesFor(result))
    8. {
    9. if(rec == null) return;
    10.  
    11. if(recipe instanceof ShapedRecipe)
    12. {
    13. if(!(rec instanceof ShapedRecipe))
    14. {
    15. return;
    16. }
    17.  
    18. ShapedRecipe expectedRecipe = (ShapedRecipe)rec;
    19.  
    20. for (int i = 0; i < 8; i++)
    21. {
    22. ItemStack currentIn = event.getInventory().getMatrix()[i];
    23. ItemStack expectedIn = (ItemStack)expectedRecipe.getIngredientMap().values().toArray()[i];
    24.  
    25. System.out.println(currentIn);
    26. System.out.println(expectedIn);
    27.  
    28. if(expectedIn == null) return;
    29. if(currentIn == null) return;
    30.  
    31. if(ItemUtil.hasDisplayName(currentIn))
    32. {
    33. System.out.println("Current item's name: " + currentIn.getItemMeta().getDisplayName());
    34. }
    35.  
    36. if(ItemUtil.hasDisplayName(expectedIn))
    37. {
    38. System.out.println("Expected item's name: " + expectedIn.getItemMeta().getDisplayName());
    39. }
    40.  
    41. if(!ItemUtil.isCorrectItem(currentIn, expectedIn))
    42. {
    43. System.out.println("Incorrect items!");
    44. event.getInventory().setResult(null);
    45. return;
    46. }
    47. else
    48. {
    49. System.out.println("Correct items, move along please!");
    50. return;
    51. }
    52. }
    53. }
    54. }
    55. }[/i][/i]


    Problem is, it always returns null.
     
  12. Offline

    Dudemister1999

    Yet another bump. I most likely messed something up, but I cannot see it.

    EDIT: And what I meant by null, is it always fires the System.out.println("Incorrect items!");
     
Thread Status:
Not open for further replies.

Share This Page