CraftItemEvent Not Handling ItemMeta (Sounds unintelligent, I know)

Discussion in 'Plugin Development' started by AppleBabies, Mar 7, 2016.

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

    AppleBabies

    So I have come up with a system for having recipes use ItemStacks with ItemMeta...works great! However, you can still use regular ItemStacks.

    For example, I have a recipe book with meta. But you can still use a regular book to craft the recipe.

    Here is my recipe:
    Code:
    public ShapelessRecipe grappleHookSL() {
            ShapelessRecipe recipe = new ShapelessRecipe(Main.getPlugin().getRItems().grapple);
            recipe.addIngredient(1, Material.FISHING_ROD);
            recipe.addIngredient(1, Material.BOOK);
            return recipe;
        }
    I add it with this. I run this onEnable():

    Code:
        public void doRecipes(){
        Main.getPlugin().getServer().addRecipe(grappleHookSL());
        }
    And here is where I check the crafting recipe.
    Code:
    @EventHandler
        public void craft(CraftItemEvent e){
        if(e.getInventory() instanceof CraftingInventory){
        CraftingInventory inv = (CraftingInventory) e.getInventory();
        if(inv.getSize() != 4){
        ItemStack[] itm = inv.getMatrix();
        for(int i=0; i<8; i++){
            if(itm[i].getType() == Material.AIR){
                continue;
            } else {
        if(itm[i].getItemMeta().getDisplayName().toString().toLowerCase().equals(Main.getPlugin().getRItems().grappleBook.getItemMeta().getDisplayName().toString().toLowerCase())){
        inv.setResult(Main.getPlugin().getRItems().grapple);
        return;
        }
        else{
        inv.setResult(null);
        e.setCancelled(true);
        }
        }
        }
        }
        }
        }
    Any help would be greatly appreciated!
     
  2. Offline

    AppleBabies

    Bump....anybody?
     
  3. Offline

    87pen

    @AppleBabies Your solution is in your explanation. You are using a normal itemstack. Which means it's display name is null. You never make sure it's not null.
     
  4. Offline

    AppleBabies

    @87pen Did this and it's still not being conventional.
    Code:
    @EventHandler
        public void craft(CraftItemEvent e){
        if(e.getInventory() instanceof CraftingInventory){
        CraftingInventory inv = (CraftingInventory) e.getInventory();
        if(inv.getSize() != 4){
        ItemStack[] itm = inv.getMatrix();
        for(int i=0; i<8; i++){
            if(itm[i].getType() == Material.AIR || itm[i].getItemMeta().getDisplayName() == null){
                continue;
            } else {
        if(itm[i].getItemMeta().getDisplayName().toString().toLowerCase().equals(Main.getPlugin().getRItems().grappleBook.getItemMeta().getDisplayName().toString().toLowerCase())){
        inv.setResult(Main.getPlugin().getRItems().grapple);
        return;
        }
        else{
        inv.setResult(null);
        e.setCancelled(true);
        }
        }
        }
        }
        }
        }
     
  5. Offline

    87pen

    Check if the itemHasMeta, if the displayname is null
    It would look like this. if(itm.hasItemMeta && item.getItemMeta().getDisplayname !=null && itm.getItemMeta().getDisplayName().toString().toLowerCase().equals(Main.getPlugin().getRItems().grappleBook.getItemMeta().getDisplayName().toString().toLowerCase())){
     
  6. Offline

    AppleBabies

    @87pen Still not working...I am very confused now. You can still use regular ItemStacks...I don't know why this isn't working.
    Code:
    @EventHandler
        public void craft(CraftItemEvent e){
        if(e.getInventory() instanceof CraftingInventory){
        CraftingInventory inv = (CraftingInventory) e.getInventory();
        if(inv.getSize() != 4){
        ItemStack[] itm = inv.getMatrix();
        for(int i=0; i<9; i++){
            if(itm[i].getType() == Material.AIR){
                continue;
            } else {
        if(itm[i].hasItemMeta() && itm[i].getItemMeta().getDisplayName() != null && itm[i].getItemMeta().getDisplayName().toString().toLowerCase().equals(Main.getPlugin().getRItems().grappleBook.getItemMeta().getDisplayName().toString().toLowerCase())){
        inv.setResult(Main.getPlugin().getRItems().grapple);
        return;
        }
        else{
        inv.setResult(null);
        e.setCancelled(true);
        }
        }
        }
        }
        }
        }
     
  7. Offline

    87pen

    hmmmm I've never played around with craftEvent before, looks interesting, Is there any errors in your console when you try crafting with a normal item? If not, why do you add a crafting recipe then create your own custom one? I believe there is two routes to making custom recipes you can do it with addShapedRecipe which only uses normal itemstacks as ingredients since it only check material types in the workbench. or you can check every spot on the workbench in the craft event, which would let you list for metadata. You are trying to do both which would allow crafting of an item without the need for custom metadata items. Am I making sense? @Zombie_Striker @AppleBabies Does this make sense or do I sound crazy?
     
  8. Offline

    AppleBabies

    @87pen Makes sense. I have a shapeless recipe set up and that's the only one registered, I have an un-registered shaped one I could try too.

    Hmmm...no errors, but I just noticed something interesting. Now, even with the right meta items, you can't take out the item at ALL from the result slot.
     
  9. Offline

    Zombie_Striker

    @87pen @AppleBabies
    https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/PrepareItemCraftEvent.html
    Called wherever a new ingredient has been added to crafting table.

    https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/CraftItemEvent.html
    Called when all the ingredients for a recipe have been added.

    I would recommend adding your recipe to the sever and using CraftItemEvent. Inside the event, test if all the itememetas are correct. If they are not, then set the crafted item to air.
     
  10. Offline

    87pen

    I see, I'm not completely sure, I suggest doing it the way @Zombie_Striker recommended, I'm not really sure where to go from there off of my head. I would love to test it out when I get home.
     
  11. Offline

    AppleBabies

    @Zombie_Striker Isn't that close to what I do? I add the recipe to the server, check the metas, and if it's not correct, make it null.
     
  12. Offline

    AppleBabies

    @Zombie_Striker @87pen I still don't get why this won't work...
    Code:
    @EventHandler
        public void craft(CraftItemEvent e){
        if(e.getInventory() instanceof CraftingInventory){
        CraftingInventory inv = (CraftingInventory) e.getInventory();
        ItemStack[] itm = inv.getMatrix();
        for(int i=0; i<9; i++){
            ItemStack current = itm[i];
            if(!current.hasItemMeta() && current.getItemMeta().getDisplayName() == null){
                    if(i == 8){
                    inv.setResult(null);
                    break;
                    }
                inv.setResult(null);
                continue;
            }
         // String name = current.getItemMeta().getDisplayName().toLowerCase();
          if(current == Main.getPlugin().getRItems().grappleBook) {
        inv.setResult(Main.getPlugin().getRItems().grapple);
        break;
        }
        }
        }
        }
     
  13. Offline

    Zombie_Striker

    This is most likely your problem:
    1. Simply using "getItemMeta" creates the itemmeta. Almost always an item will have item meta (especially if other plugins are not coded correctly)
    2. If I remember covertly, the display name will never be null, as at the very least the display name will be the name of the material.
    An easier way of approaching this would be to create an arraylist which will be the same as the matrix except it would contain the necessary itemstacks for the recipe. You would use a for loop to get all the items in a matrix array, and see if the item in that matrix array is the same as the one from the other array. If the displayname/material type/lore/ect from the matrix is not the same as the one from the other array, then set the result to null.

    BTW: If I remember correctly, the event is cancel-able.
     
Thread Status:
Not open for further replies.

Share This Page