Solved Check if an item was placed into a GUI

Discussion in 'Spigot Plugin Development' started by irvinglink, Jan 13, 2020.

  1. Hello Spigot Community! I have an issue with InventoryActions in InventoryClickEvent, I'm trying to make a custom Anvil with a GUI, but the problem is how can I verify the recipe is correct by the InventoryClickEvent like the plugin AdvancedCraftingTable.

    My code:
    Code (Java):
    package me.RandomSurvival.Listeners;

    import me.RandomSurvival.MClass;
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockState;
    import org.bukkit.block.Skull;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.EventPriority;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryAction;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.player.AsyncPlayerChatEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.InventoryView;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.scheduler.BukkitRunnable;

    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;

    import static me.RandomSurvival.Utils.chatManager.Chat;

    public class AnvilRecipeListener implements Listener {

        private Map<UUID, Inventory> inventories = new HashMap();
        private boolean renameBoolean = false;
        private String rename = "";

        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
            Player player = event.getPlayer();
            inventories.put(player.getUniqueId(), customAnvil(player));
        }

        @EventHandler(priority = EventPriority.HIGHEST)
        public void interactEvent(PlayerInteractEvent event) {
            if (event.getClickedBlock() == null) return;
            Player player = event.getPlayer();
            Block block = event.getClickedBlock();
            if (block.getType().equals(Material.PLAYER_HEAD)) {
                BlockState state = block.getState();
                Skull skull = (Skull) state;
                if (skull.getOwner().equalsIgnoreCase("fin95")) {
                    player.openInventory(inventories.get(player.getUniqueId()));
                }
            }
        }

        @EventHandler
        public void clickInventory(InventoryClickEvent event) {
            Player player = (Player) event.getWhoClicked();
            InventoryView inv = event.getView();
            if (inv.getTitle().equals(Chat("&b&lRandom &e&lAnvil"))) {
                Inventory inventory = inventories.get(player.getUniqueId());
                if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR) return;
                ItemStack itemClicked = event.getCurrentItem();
                Material itemType = itemClicked.getType();

                if (itemType.equals(Material.BLACK_STAINED_GLASS_PANE)
                        || itemType.equals(Material.LIME_STAINED_GLASS_PANE))event.setCancelled(true);


                InventoryAction action = event.getAction();

                /*new BukkitRunnable() {
                        @Override
                        public void run() {
                            Player player = (Player) event.getWhoClicked();
                            if (event.getView().getTitle().equals(Chat("&b&lRandom &e&lYAnvil"))) {
                                try {
                                    checkRecipes(player);
                                } catch (NullPointerException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }.runTask(MClass.plugin);*/


                /////////
                //RENAME
                if (event.getSlot() == 18 && itemClicked.getType().equals(Material.NAME_TAG)) {
                    event.setCancelled(true);
                    player.closeInventory();
                    player.sendMessage(Chat("&aSet a name for your item...", true));
                    this.renameBoolean = true;
                }

                ///////
                //GET RESULT
                if (event.getSlot() == 15 && itemClicked != null) {
                    inventory.clear(11);
                    inventory.clear(13);
                    new BukkitRunnable() {
                        @Override
                        public void run() {
                            player.updateInventory();
                        }
                    }.runTask(MClass.plugin);
                }
            }
        }

        @EventHandler
        public void setRename(AsyncPlayerChatEvent event) {
            Player player = event.getPlayer();
            if (this.renameBoolean == true) {
                this.rename = event.getMessage();
                player.sendMessage(Chat("&aSaved Name! &f" + this.rename, true));
                this.renameBoolean = false;
                event.setCancelled(true);

                if (this.rename != null) {
                    Inventory inv = inventories.get(player.getUniqueId());
                    ItemStack item = inv.getItem(18);
                    ItemMeta itemMeta = item.getItemMeta();
                    itemMeta.setDisplayName(Chat("&bRename &7= &f" + this.rename));
                    item.setItemMeta(itemMeta);
                }
            }
        }

        public void checkRecipes(Player player) {
            Inventory inventory = inventories.get(player.getUniqueId());
            ItemStack item1 = inventory.getItem(11);
            ItemStack item2 = inventory.getItem(13);

            if (item2.getType().equals(Material.CYAN_DYE)) {
                if (item1 == null) return;
                ItemStack itemR = item1.clone();
                ItemMeta itemMeta = itemR.getItemMeta();
                itemMeta.setDisplayName(Chat("&b" + this.rename));
                itemR.setItemMeta(itemMeta);
                inventory.setItem(15, itemR);
            } else return;
            player.updateInventory();
        }

        public Inventory customAnvil(Player player) {
            Inventory customAnvil = Bukkit.createInventory(player, 27, Chat("&b&lRandom &e&lAnvil"));
            for (int i = 0; i <= 26; i++) {
                if ((i == 14)) {
                    ItemStack glassG = new ItemStack(Material.LIME_STAINED_GLASS_PANE);
                    ItemMeta glassGMeta = glassG.getItemMeta();
                    glassGMeta.setDisplayName(Chat("&a&n->"));
                    glassG.setItemMeta(glassGMeta);
                    customAnvil.setItem(i, glassG);
                } else if ((i == 18)) {
                    ItemStack nametag = new ItemStack(Material.NAME_TAG);
                    ItemMeta nametagMeta = nametag.getItemMeta();
                    nametagMeta.setDisplayName(Chat("&bRename"));
                    nametag.setItemMeta(nametagMeta);
                    customAnvil.setItem(i, nametag);
                } else if ((i == 11) || (i == 13) || (i == 15)) {
                    ItemStack air = new ItemStack(Material.AIR);
                    customAnvil.setItem(i, air);
                } else {
                    ItemStack glass = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
                    ItemMeta glassMeta = glass.getItemMeta();
                    glassMeta.setDisplayName("");
                    glass.setItemMeta(glassMeta);
                    customAnvil.setItem(i, glass);
                }
            }
            return customAnvil;
        }
    }
     
    Random Anvil.png
     
    #1 irvinglink, Jan 13, 2020
    Last edited: Jan 13, 2020
    • Like Like x 1
  2. You will have a lot of problems when multiple people use your custom anvil GUI.
    The will rename each others items.
    private boolean renameBoolean = false;
    private String rename = "";
    those are defined in the wrong scope.

    However...
    In order to implement custom recipes with two items that should be combined (or a item with a matrix) i would create a new
    abstract class CustomAnvilRecipe. with a method that takes (ItemStack, ItemStack) and returns a boolean.
    Like this:
    Screenshot_13.png


    Then you just need some classes that implement your custom recipe and manage them a bit like this:
    Screenshot_14.png



    Then you get the two items from the InventoryClickEvent
    call customAnvilRecipeHandler.getRecipeForInput(left, right);
    check if optional.isPresent();
    optional.get().getResult(left, right);
    remove items left and right;
    set the output slot with the getResult() item.

    There are easier ways but this one is clean, pretty fast (you could implement interesting hash methods and use those) and very modular.
     
    • Useful Useful x 1
  3. I'll try thanks bro. It's really useful, and the problem with the private boolean I'll already now that, I was thinking to saved into a hashmap, but I like your idea. But this doesn't fix my problem with the result, I need to make it appear into the GUI when you put the items into the slots. Something needs to detect that the recipe is correct.
     
    • Agree Agree x 1
  4. And how I can define the result ?
     
    • Agree Agree x 1