PrepareItemCraftEvent

Discussion in 'Plugin Development' started by ILostAChromosome, Jul 27, 2019.

Thread Status:
Not open for further replies.
  1. Hi, I am trying to develop a plugin and I can't figure out how to make custom recipes with named items. I made a couple ItemStack methods for the materials and the result, I made a recipe that you input the material type and get the result, which all works fine, though I am using the PrepareItemCraftEvent and trying to check whether the crafting materials are the ItemStacks with the custom names for the recipe, and that part isn't working. The attached code is my PrepareItemCraftEvent (I did make sure to register the event).

    Code:
        @EventHandler
        public void onPrepareItemCraft(PrepareItemCraftEvent event) {
            if (event.getInventory().getResult() == Arcane.sword()) {
                if (event.getRecipe() != null) {
                    ItemStack[] items = new ItemStack[]{Arcane.ingot(), Arcane.ingot(), new ItemStack(Material.BLAZE_ROD)};
                    if (!event.getInventory().getMatrix().equals(items)) {
                        event.getInventory().setResult(new ItemStack(Material.AIR));
                    }
                }
            }
        }
     
  2. Offline

    Kars

    @ILostAChromosome You need to compare the entries in the getMatrix array one by one, the way you are doing it will not work.

    This code is wat i used for testing and it works.
    PHP:
    @EventHandler
    public void onCraftingEvent(PrepareItemCraftEvent event) {
        
    CraftingInventory inventory event.getInventory();
        
    ItemStack[] items inventory.getMatrix();

        if (
    items[0] == null
                
    && items[1] != null && items[1].getType() == Material.OAK_PLANKS
                
    && items[2] == null
                
    && items[3] != null && items[3].getType() == Material.OAK_PLANKS
                
    && items[4] == null
                
    && items[5] != null && items[5].getType() == Material.OAK_PLANKS
                
    && items[6] == null
                
    && items[5] != null && items[5].getType() == Material.OAK_PLANKS
                
    && items[8] == null) {
            
    event.getInventory().setResult(new ItemStack(Material.BEDROCK1));
        }
    }
    An important note though.
    This way of creating custom crafting recipes does not remove the materials once the result is taken out. Effectively making the result infinite. Using my code, if you put more than 1 oak plank in each of the crafting slot and shift click the result, your entire inventory gets filled with bedrock.

    This requires additional code that removes the ingredient items to work properly. I plan on figuring this out when i have some free time.
     
  3. If inventory.getMatrix(); returns a 3x3 matrix that is the crafting recipe, does the ItemStack array go by rows or columns? For example, does items[0] gets the first slot and items[1] gets the slot to the right of it, or does items[0] gets the first slot and items[1] gets the slot underneath it?
     
  4. Offline

    Machine Maker

    @ILostAChromosome getMatrix() returns an array of length 9 where 0 is the top left, and the numbers go to the right and down. 8 is the bottom right.
    Code:
    0|1|2
    3|4|5
    6|7|8
    
     
  5. I assumed that, though I can't figure out why this isn't working then. There is a custom recipe that I can craft this item with the materials, and I'm trying to make sure the materials they use are my Arcane.ingots

    Code:
        @EventHandler
        public void onPrepareItemCraft(PrepareItemCraftEvent event) {
            if (event.getInventory().getResult() == Arcane.sword1()) {
                CraftingInventory inv = event.getInventory();
                ItemStack[] items = inv.getMatrix();
                if (items[1] != Arcane.ingot() || items[4] != Arcane.ingot()
                        || items[7] != new ItemStack(Material.BLAZE_ROD)) {
                    event.getInventory().setResult(new ItemStack(Material.AIR));
                }
            }
        }
     
  6. Offline

    Kars

    @ILostAChromosome
    Given that your first if statement returns true (which i assume it doesn't, but lets move on), you are comparing items[1] (an object) to ingot (another object). The two are not the same object so this returns false by default. You need to compare their types with .getType.
     
  7. If I wanted to just use .getType() I would use a ShapedRecipe, which uses MaterialData already. I want to craft where the items in the recipe has MetaData. The if statement should return true because I have already have a ShapedRecipe that returns my result. What I am trying to do here is make sure that the recipe contains the specific ItemStack that have meta data, not create a new recipe with normal minecraft items.
     
  8. Offline

    Machine Maker

    @ILostAChromosome Then you will need to compare the exact parts of the item meta that you want to be the same.
    So compare the type, and then each part of the item meta you want to compare.
     
  9. Do you mean like this
    Code:
        @EventHandler
        public void onPrepareItemCraft(PrepareItemCraftEvent event) {
            if (event.getInventory().getResult() == Arcane.sword1()) {
                CraftingInventory inv = event.getInventory();
                ItemStack[] items = inv.getMatrix();
                if (items[1].getItemMeta().getDisplayName() != ChatColor.DARK_PURPLE + "Arcane Ingot"
                        || items[4].getItemMeta().getDisplayName() != ChatColor.DARK_PURPLE + "Arcane Ingot"
                        || items[7].getType() != Material.BLAZE_ROD) {
                    event.getInventory().setResult(new ItemStack(Material.AIR));
                }
            }
        }
    
    or like this
    Code:
        @EventHandler
        public void onPrepareItemCraft(PrepareItemCraftEvent event) {
            if (event.getInventory().getResult() == Arcane.sword1()) {
                CraftingInventory inv = event.getInventory();
                ItemStack[] items = inv.getMatrix();
                if (items[1].getItemMeta().getDisplayName() != Arcane.ingot().getItemMeta().getDisplayName()
                        || items[4].getItemMeta().getDisplayName() != Arcane.ingot().getItemMeta().getDisplayName()
                        || items[7].getType() != Material.BLAZE_ROD) {
                    event.getInventory().setResult(new ItemStack(Material.AIR));
                }
            }
        }
     
  10. Offline

    Kars

    @ILostAChromosome
    We compare String objects with .equals for their content, or you will again run into the same problem that String 1 and String 2 == not the same object, hence your != will always return true.
     
  11. Thanks for the help.
     
Thread Status:
Not open for further replies.

Share This Page