Prepare craft item event help

Discussion in 'Spigot Plugin Development' started by maxim_Vla., Jul 12, 2019.

  1. I am making some recipes for a plugin, and I have one simple question, inside the prepare craft item event, how would you test what is in what slot, and what are the slots numbered?
    My second question is how would you set the result of the crafting recipe?
    Is all of this possible inside the prepare craft item event?

    Thank you
    ItsMaximCraft
     
  2. See this:
    https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/PrepareItemCraftEvent.html
    with that you can solve all your questions
     
  3. Still unsure about slot numbering
     
  4. If you're unsure, you can make 9 different ItemStacks and give each one a different name (i.e a number) and then use CraftingInventory#setMatrix to set the matrix - you can then see which item is where.
     
  5. You need to get the CraftingInventory from the event, like this:
    Code (Java):
    CraftingInventory inventory = event.getInventory();
    Then, when you have that you get the matrix of items inside that inventory, like this:
    Code (Java):
    ItemStack[] matrix = inventory.getMatrix();
    The matrix is an array of ItemStacks. Crafting tables have an inventory in this pattern:
    Code (Text):
    A B C
    D E F
    G H I
    Which, when flattened into an array looks like this:
    Code (Text):
    [A, B, C, D, E, F, G, H, I]
    So depending on which slot you want to check, you need to get the array index that matches it. So, for example, if you wanted to get the item in the top left slot (in the example above, item A), you'd do:
    Code (Text):
    ItemStack item = matrix[0];
     
  6. Very useful information, will report back if has an error
     
  7. It doesn't work. Here is the code

    Listener (I only included the relevant part)

    Code (Java):
    @EventHandler
        public void handleCustomCrafting(PrepareItemCraftEvent e) {
            CraftingInventory inventory = e.getInventory();
         
            ItemStack S = new ItemStack(Material.DIAMOND);
            ItemMeta diamondMeta = S.getItemMeta();
            List<String> diamondLore = new ArrayList<>();
            diamondLore.add(Utils.chat("&bUsed to craft Enchanted diamond."));
            diamondLore.add(" ");
            diamondLore.add(Utils.chat("&bThis is a &9&lRARE &r&bitem."));
            diamondMeta.setDisplayName(Utils.chat("&bShiny diamond"));
            diamondMeta.setLore(diamondLore);
            diamondMeta.addEnchant(Enchantment.ARROW_DAMAGE, 1, true);
            diamondMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
            S.setItemMeta(diamondMeta);
            ItemStack air = new ItemStack(Material.AIR);
           
            ItemStack[] matrix = inventory.getMatrix();
            ItemStack a = matrix[0];
            ItemStack b = matrix[1];
            ItemStack c = matrix[2];
            ItemStack d = matrix[3];
            ItemStack E = matrix[4];
            ItemStack f = matrix[5];
            ItemStack g = matrix[6];
            ItemStack h = matrix[7];
            ItemStack i = matrix[8];

            if (a == S && b == S && c == S && d == S && E == air && f == S && g == S && h == S && i == S) {
                ItemStack EnDiamond = new ItemStack(Material.DIAMOND);
                ItemMeta EnDiamondMeta = EnDiamond.getItemMeta();
                List<String> EnDiamondLore = new ArrayList<>();
                EnDiamondLore.add(Utils.chat("&bUsed to craft Enchanted diamond block."));
                EnDiamondLore.add("");
                EnDiamondLore.add(Utils.chat("&bThis is a &7&lVERY RARE &r&bitem."));
                EnDiamondMeta.setDisplayName(Utils.chat("&bEnchanted diamond"));
                EnDiamondMeta.setLore(EnDiamondLore);
                EnDiamondMeta.addEnchant(Enchantment.ARROW_DAMAGE, 2, true);
                EnDiamondMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
                EnDiamond.setItemMeta(EnDiamondMeta);
                e.getInventory().setResult(EnDiamond);
            }
        }
    Main.java

    Code (Java):
    package net.hyperfire.kitPvP;

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

    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemFlag;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapedRecipe;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Score;
    import org.bukkit.scoreboard.Scoreboard;
    import org.bukkit.scoreboard.Team;

    import net.md_5.bungee.api.ChatColor;

    //By ItsMaximCraft, Owner of HyperFire

    public class Main extends JavaPlugin {
       
        public HashMap <Player, String> PlayerArea1;
        public HashMap <Player, String> PlayerArea2;
        public HashMap <Player, Integer> Streak;

        @Override
        public void onEnable() {
            PlayerArea1 = new HashMap<>();
            PlayerArea2 = new HashMap<>();
            Streak = new HashMap<>();
           
            diamond();
           
            this.getConfig().options().copyDefaults();
            saveDefaultConfig();
           
            Bukkit.getPluginManager().registerEvents(new SidebarListener(this), this);
            getCommand("area").setExecutor(new AreaCommand());
           
        }
       
        private void diamond() {
            ItemStack diamond = new ItemStack(Material.DIAMOND);
            ItemMeta diamondMeta = diamond.getItemMeta();
            List<String> diamondLore = new ArrayList<>();
            diamondLore.add(Utils.chat("&bUsed to craft Enchanted diamond."));
            diamondLore.add(" ");
            diamondLore.add(Utils.chat("&bThis is a &9&lRARE &r&bitem."));
            diamondMeta.setDisplayName(Utils.chat("&bShiny diamond"));
            diamondMeta.setLore(diamondLore);
            diamondMeta.addEnchant(Enchantment.ARROW_DAMAGE, 1, true);
            diamondMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
            diamond.setItemMeta(diamondMeta);
           
            /*
             * < - diamond
             */

            ShapedRecipe Sdiamond = new ShapedRecipe(diamond);
            Sdiamond.shape("<<<", "< <", "<<<");
            Sdiamond.setIngredient('<', Material.DIAMOND);
           
            this.getServer().addRecipe(Sdiamond);
           
        }
       
        public void buildSidebar(Player player) {
           
            //BEGINNING
           
            Scoreboard kitPvP = Bukkit.getScoreboardManager().getNewScoreboard();
           
            //OBJECTIVE
           
            Objective title = kitPvP.registerNewObjective("title", "dummy");
            title.setDisplayName(ChatColor.YELLOW.toString() + ChatColor.BOLD + "HYPERFIRE KITPVP");
            title.setDisplaySlot(DisplaySlot.SIDEBAR);
           
            //SCORES
           
            Score website = title.getScore(ChatColor.YELLOW + "hyperfire.net");
            website.setScore(1);
           
            Score blank = title.getScore(" ");
            blank.setScore(2);
           
            Score bugLink = title.getScore(ChatColor.YELLOW + "hyperfire.net/bugs");
            bugLink.setScore(3);
           
            Score report = title.getScore(ChatColor.WHITE + "Report bugs at:");
            report.setScore(4);
           
            Score blank2 = title.getScore("  ");
            blank2.setScore(5);
           
            Team PArea = kitPvP.registerNewTeam("Area");
            PArea.addEntry(ChatColor.AQUA.toString());
            PArea.setPrefix(ChatColor.DARK_GRAY + ">" + PlayerArea1.get(player));
            PArea.setSuffix(PlayerArea2.get(player));
            title.getScore(ChatColor.AQUA.toString()).setScore(6);
           
            Score Area = title.getScore(ChatColor.WHITE + "Area:");
            Area.setScore(7);
           
            Score blank3 = title.getScore("   ");
            blank3.setScore(8);
           
            Score Coins = title.getScore(ChatColor.AQUA + "Coins: " + ChatColor.GOLD + "[COINS]");
            Coins.setScore(9);
           
            Team streak = kitPvP.registerNewTeam("Streak");
            streak.addEntry(ChatColor.RED.toString());
            streak.setPrefix(ChatColor.AQUA + "Kill streak:");
            streak.setSuffix(Utils.chat("&c " + Streak.get(player)));
            title.getScore(ChatColor.RED.toString()).setScore(10);
           
            Score NXP = title.getScore(ChatColor.AQUA + "Needed XP: " + ChatColor.GREEN + "[NXP]");
            NXP.setScore(11);
           
            Score Level = title.getScore(ChatColor.AQUA + "Level: " + ChatColor.GREEN + "[LVL]");
            Level.setScore(12);
           
            Score blank4 = title.getScore("    ");
            blank4.setScore(13);
           
            Score server = title.getScore(ChatColor.WHITE + "Server: " + ChatColor.DARK_GRAY + "mini1B");
            server.setScore(14);
           
            //FINAL
           
            player.setScoreboard(kitPvP);
           
        }
       
       
    }
     
     
  8. You can't compare two ItemStacks with ==. What that does is check if they're referring to the same instance. Since you've just created a new instance, that will never be true.

    Instead, you need to use ItemStack#isSimilar if you don't care about the amount and ItemStack#equals if the amount must also be the same.
     
  9. So how exactly do you use it, will it be
    Code (Java):
    if (a.isSimilar(S)) {}
     
  10. I wouldn't recommend doing it this way since the contents of the matrix may be null. Do it the other way around. (i.e S.isSimilar(a))
     
  11. Code (Text):
    if (S.isSimilar(a)) {}
     
  12. Also does the equals matter if only 1 item is needed per slot?
     
  13. If you're checking #equals and someone has put 2 items instead of one, it'll say that they're not the same. If that's how you think it should work, then go for it. But generally, crafting lets you put more than the required items and only removes the items that were required for the crafting.
    Of course, if we're talking about unstackable items, it's a different story since they don't stack anyway.

    Furthermore, bare in mind that if you're talking about weapons/armor/tools that can take durability, #isSimilar will return false if the two items have different durability.
     
  14. it is just the drops of ores, and I do want it to only take 1 if they put 2.
     
  15. Still doesn't work... it doesn't show me the result
     
  16. Debug your code. See what runs and what doesn't. See which conditions (if any) are met and which are not.

    I.e add debug messages every here and there to see which part of the code was reached. If it's the if clause that returns false even though you think it shouldn't, you can just output each of its conditions, i.e getLogger().info("C1:" + (/*condition 1*/) + " ;C2:" + (/*condition 2*/)); and so on.