1.16.5 setIngredient with enchanted knockback book

Discussion in 'Spigot Plugin Development' started by EinShervin, Sep 29, 2020.

  1. Hello

    I would like to make my own Minecraft crafting recipe:

    [​IMG]

    But i dont figure out how i can add an ingredient with enchantment.

    [​IMG]

    [​IMG]

    Code (Text):
    package de.shervin.Stanley.crafting;

    import java.util.ArrayList;
    import java.util.List;

    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapedRecipe;
    import org.bukkit.inventory.meta.ItemMeta;

    public class KnockbackStick {
     
        public void registerRecipes() {
            ItemStack KnockbackStick = new ItemStack(Material.STICK);
            ItemMeta KnockbackStickMeta = KnockbackStick.getItemMeta();
            KnockbackStickMeta.addEnchant(Enchantment.KNOCKBACK, 10, true);
            KnockbackStickMeta.setDisplayName("§f§l§[email protected]§5§l§oKnockback§5§lStick§f§l§[email protected]");
            List<String> lore = new ArrayList<>();
            lore.add("§fDer §f§l§[email protected]§5§l§oUltimative§f§l§[email protected] §fKnockbackStick");
            KnockbackStickMeta.setLore(lore);
            KnockbackStick.setItemMeta(KnockbackStickMeta);
         
            ShapedRecipe KnockbackStickRecipe = new ShapedRecipe(KnockbackStick);
            KnockbackStickRecipe.shape("BNZ","ASA","DLD");
            KnockbackStickRecipe.setIngredient('B', Material.ENCHANTED_BOOK);
            KnockbackStickRecipe.setIngredient('N', Material.NETHER_STAR);
            KnockbackStickRecipe.setIngredient('Z', Material.DIAMOND_AXE);
            KnockbackStickRecipe.setIngredient('A', Material.BLAZE_ROD);
            KnockbackStickRecipe.setIngredient('S', Material.STICK);
            KnockbackStickRecipe.setIngredient('D', Material.DIAMOND);
            KnockbackStickRecipe.setIngredient('L', Material.LAVA_BUCKET);
         
            Bukkit.addRecipe(KnockbackStickRecipe);
        }
     
    }
    It works when i replace the Potion and de Enchanted Book
     
  2. Well this is technically impossible but there are two workarounds if you're willing to be cheeky about it.

    One requires using the deprecated method which requires the data value (setIngredient(key char, Material ingredient, int raw)) of the potion (in this case strength 2 which is 8233), not sure about you but I don't really like using deprecation so I try to avoid it. Also not even sure if enchanted books have data values per enchantment type so this solution may not work for both items.

    The other way is a little more tricky which requires you to work with the PrepareItemCraftEvent (used for the display of the item being crafted) and maybe even the CraftItemEvent (used for the actual crafting of the item). You would then loop through the items in the inventory using event#getInventory() and check if the itemstack metas equal your desired PotionMeta and EnchantmentStorageMeta and from there then check if getStoredEnchants() is knockback 2 and getBasePotionData()#getType() is strength and getBasePotionData()#isUpgraded() is true for level 2. After that you'd forcefully set the result to that recipe.

    These are the only two ways I can see this being achievable since recipe's ingredient method requires a material parameter rather than a itemstack.
     
    #2 Swiftlicious, Sep 29, 2020
    Last edited: Sep 30, 2020
    • Like Like x 1
  3. I searched a sec and Book do have a Data Value but hmm little bit wired

    [​IMG]

    First i was like: YEAH IT WORKS.. but huh look :D

    [​IMG]

    [​IMG]

    Code (Text):
            ShapedRecipe KnockbackStickRecipe = new ShapedRecipe(KnockbackStick);
            KnockbackStickRecipe.shape("BNZ","ASA","DLD");
            KnockbackStickRecipe.setIngredient('B', Material.ENCHANTED_BOOK, 19);
            KnockbackStickRecipe.setIngredient('N', Material.NETHER_STAR);
            KnockbackStickRecipe.setIngredient('Z', Material.POTION, 8233);
            KnockbackStickRecipe.setIngredient('A', Material.BLAZE_ROD);
            KnockbackStickRecipe.setIngredient('S', Material.STICK);
            KnockbackStickRecipe.setIngredient('D', Material.DIAMOND);
            KnockbackStickRecipe.setIngredient('L', Material.LAVA_BUCKET)
    So this does not work.
     
  4. In this case you'll either have to the Exact choice solution posted by the user below my above post or the other solution I gave you.
     
  5. Do I have to create a new listener class now or can I put it into the same class?
     
  6. You can put it in the same class just have to implement it as a Listener if it's not already.
     
  7. I don't think I can do this o_O
     
  8. I could give you an example to test around with if you're willing to wait a bit
     
    • Friendly Friendly x 1
  9. Yes, this would be the best, tank you :love:(y)
     
  10. so from testing this out it doesn't seem to actually work the way I suspected using the events I said to so instead I'm gonna test it out with the InventoryClickEvent (which may not be the best idea but i'll just try it).

    This is sorta in the direction I was thinking:
    Code (Java):
        @EventHandler
        public void onCustomCraftClick(InventoryClickEvent e) {
     
            if (e.getWhoClicked() instanceof Player) {
                if (e.getClickedInventory() != null && e.getClickedInventory() instanceof CraftingInventory) {
                    CraftingInventory inv = (CraftingInventory) e.getClickedInventory();
                    if (inv.getItem(1) != null && inv.getItem(1).getType() == Material.ENCHANTED_BOOK) {
                        ItemStack enchantedBook = inv.getItem(1);
                        if (enchantedBook.hasItemMeta() && enchantedBook.getItemMeta() instanceof EnchantmentStorageMeta) {
                            EnchantmentStorageMeta enchantedMeta = (EnchantmentStorageMeta) enchantedBook.getItemMeta();
                            if (enchantedMeta.getStoredEnchants().size() == 1 && enchantedMeta.hasStoredEnchant(Enchantment.KNOCKBACK) && enchantedMeta.getStoredEnchantLevel(Enchantment.KNOCKBACK) == 2) {
                                // continue with rest of recipe
                            }
                        }
                    }
                }
            }
        }
    Code (Java):
        @EventHandler
        public void onCustomCraftClick(InventoryClickEvent e) {
         
            if (e.getWhoClicked() instanceof Player) {
                if (e.getClickedInventory() != null && e.getClickedInventory() instanceof CraftingInventory) {
                    if (e.getInventory().equals(e.getView().getTopInventory())) {
                        CraftingInventory inv = (CraftingInventory) e.getClickedInventory();
                        if (inv.getItem(1) != null && inv.getItem(1).getType() == Material.ENCHANTED_BOOK) {
                            ItemStack enchantedBook = inv.getItem(1);
                            if (enchantedBook.hasItemMeta() && enchantedBook.getItemMeta() instanceof EnchantmentStorageMeta) {
                                EnchantmentStorageMeta enchantedMeta = (EnchantmentStorageMeta) enchantedBook.getItemMeta();
                                if (enchantedMeta.getStoredEnchants().size() == 1 && enchantedMeta.hasStoredEnchant(Enchantment.KNOCKBACK) && enchantedMeta.getStoredEnchantLevel(Enchantment.KNOCKBACK) == 2) {
                                    if (inv.getItem(2) != null && inv.getItem(2).getType() == Material.NETHER_STAR) {
                                        if (inv.getItem(3) != null && inv.getItem(3).getType() == Material.POTION) {
                                            ItemStack strengthPotion = inv.getItem(3);
                                            if (strengthPotion.hasItemMeta() && strengthPotion.getItemMeta() instanceof PotionMeta) {
                                                PotionMeta potionMeta = (PotionMeta) strengthPotion.getItemMeta();
                                                if (potionMeta.getBasePotionData().getType() == PotionType.STRENGTH && potionMeta.getBasePotionData().isUpgraded()) {
                                                    if (inv.getItem(4) != null && inv.getItem(4).getType() == Material.BLAZE_ROD) {
                                                        if (inv.getItem(5) != null && inv.getItem(5).getType() == Material.STICK) {
                                                            if (inv.getItem(6) != null && inv.getItem(6).getType() == Material.BLAZE_ROD) {
                                                                if (inv.getItem(7) != null && inv.getItem(7).getType() == Material.DIAMOND) {
                                                                    if (inv.getItem(8) != null && inv.getItem(8).getType() == Material.LAVA_BUCKET) {
                                                                        if (inv.getItem(9) != null && inv.getItem(9).getType() == Material.DIAMOND) {
                                                                            ItemStack knockbackStick = new ItemStack(Material.STICK);
                                                                            ItemMeta knockbackStickMeta = knockbackStick.getItemMeta();
                                                                            knockbackStickMeta.addEnchant(Enchantment.KNOCKBACK, 10, true);
                                                                            knockbackStickMeta.setDisplayName("§f§l§[email protected]§5§l§oKnockback§5§lStick§f§l§[email protected]");
                                                                            List<String> lore = new ArrayList<>();
                                                                            lore.add("§fDer §f§l§[email protected]§5§l§oUltimative§f§l§[email protected] §fKnockbackStick");
                                                                            knockbackStickMeta.setLore(lore);
                                                                            knockbackStick.setItemMeta(knockbackStickMeta);
                                                                         
                                                                            new BukkitRunnable() {
                                                                             
                                                                                @Override
                                                                                public void run() {
                                                                                    inv.setResult(knockbackStick);
                                                                                }
                                                                            }.runTaskLater(plugin, 2L);
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    [​IMG]
    [​IMG] [​IMG]

    Be aware this isn't really the most efficient solution since I didn't have a lot of time to write it but it does work how you want it to. I tested to see if it worked with just any enchanted book or potion and it didn't. It might be a little buggy since it's using an InventoryClickEvent sorry about that but this is the only way I thought of off the top of my head lol.

    So the only other way I can see this being achieved from googling slightly is using NMS since other people have had this same issue with wanting to use potions in recipes but not being able to use them in shaped recipes. The code I sent above does work to do what you wish just probably not the best way, hopefully it gets you in the right direction though.
     
    #11 Swiftlicious, Oct 1, 2020
    Last edited: Oct 1, 2020
    • Winner Winner x 1
  11. Nice! Thank you very much, in Germany we whould call you a "Ehrenmann" :D.

    But one question: What does "plugin" mean?

    Code (Text):
     new BukkitRunnable() {
                                                                         
                                                                                @Override
                                                                                public void run() {
                                                                                    inv.setResult(knockbackStick);
                                                                                }
                                                                            }.runTaskLater(plugin, 2L);
                                                                        }
     
    #12 EinShervin, Oct 1, 2020
    Last edited: Oct 1, 2020
  12. A reference to your main class that extends JavaPlugin, if it's in the same class you can use the key word "this" instead.