Solved Setting items into player's crafting slots.

Discussion in 'Spigot Plugin Development' started by PvPNiK, Mar 21, 2018.

  1. I am trying to place items into the player's crafting slots, but nothing works.
    tried: 80 - 83 slots, not worked.
    and tried: 0 - 4 slots, but it just the slots in the hot bar..

    have any solution?

    Version: 1.12.2

    Code (Text):
    package com.castleOfEssver.systems.menu;

    import org.bukkit.GameMode;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.inventory.InventoryType;
    import org.bukkit.event.inventory.InventoryType.SlotType;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.PlayerInventory;

    import com.castleOfEssver.utils.ChatUtil;

    import net.md_5.bungee.api.chat.ClickEvent;
    import net.md_5.bungee.api.chat.TextComponent;
    import net.md_5.bungee.api.chat.ClickEvent.Action;

    public class MenuListener implements Listener {
     
        @EventHandler
        public void onClick(InventoryClickEvent e) {
            if (!(e.getWhoClicked() instanceof Player))
                return;
       
            if (e.getClickedInventory() == null)
                return;
       
            if (e.getClickedInventory().getType() != InventoryType.PLAYER)
                return;
       
            Player p = (Player) e.getWhoClicked();
       
            if (p.getGameMode() == GameMode.CREATIVE || p.getGameMode() == GameMode.SPECTATOR)
                return;
       
            setItems(p);
       
            if (e.getSlotType() != SlotType.CRAFTING)
                return;
       
            e.setCancelled(true);
       
            ItemStack is = e.getCurrentItem();
       
            if (is == null)
                return;
       
            p.sendMessage(is.getItemMeta().getDisplayName());
        }
     
        private void setItems(Player p) {
            p.getInventory().setItem(0, MenuItems.toHub());

            p.getInventory().setItem(1, MenuItems.playerMenu());
            p.getInventory().setItem(2, MenuItems.settings());
            p.getInventory().setItem(3, MenuItems.shop());
            p.getInventory().setItem(4, MenuItems.website());
       
    //      p.getInventory().setItem(80, MenuItems.playerMenu());
    //      p.getInventory().setItem(81, MenuItems.settings());
    //      p.getInventory().setItem(82, MenuItems.shop());
    //      p.getInventory().setItem(83, MenuItems.website());
       
            p.updateInventory();
        }
     
    }
     
     
    #1 PvPNiK, Mar 21, 2018
    Last edited: Mar 23, 2018
    1. The 5 crafting slots belong to InventoryType.CRAFTING and not InventoryType.PLAYER (your 3rd if)
    2. p.getInventory() does not include the crafting slots; only the hotbar, inventory, armor and offhand slot. Thus slot 0-5 are not the crafting slots but instead the hotbar.
      e.getClickedInventory() works though and returns the correct crafting inventory (slot 0-5).
     
  2. I programmed the exact same thing for my GUI library here on Github.
    The slots 0-5 should be right but when setting the crafting slots, you need to update them a lot because the client clears them automatically when the inventory is closed so you need to set the items every few ticks (Or I recently saw an interesting way of detecting when the player is opened by catching the Open Inventory Advancement/Achievement but that has the drawback that it has to be reset everytime and no other vanilla achievements work.)
     
  3. thanks it works, but it not was my point, sorry that i do not explained my self good enough.


    i wanted to check if player opens his own inventory but in 1.12.2 it is not impossible,
    in 1.8 every time the client opens his own inventory it sends to the server open inventory achievement (even if he already owned it) so you could listen to the packet and know when player opens his inventory.
    but the achievement system have been changed and it does not working any more.

    so my idea was:
    1) in the resource-pack to draw the items in the crafting slots.
    AND
    2) every time the player clicks on his own inventory it will set the items into the crafting slots.

    now i'm stuck in the second part, how do i put items into the crafting slots when player click on his own inventory?
     
  4. Sounds a bit weird to me, I'm not fully understanding your thoughts there but if you want to put items into the crafting slots when the player clicks on his inventory, listen for the inventory click event, check if the top inventory of the current open inventory (player.getOpenInventory().getTopInventory()) is an instance of CraftInventoryCrafting and then send the items which are in the crafting slots via a packet.
     
  5. thanks it worked.

    final code:


    Code (Text):
    public class MenuListener implements Listener {
       
        @EventHandler
        public void onClick(InventoryClickEvent e) {
            if (!(e.getWhoClicked() instanceof Player))
                return;
           
            if (e.getClickedInventory() == null)
                return;
           
            Player p = (Player) e.getWhoClicked();
           
            if (p.getGameMode() == GameMode.CREATIVE || p.getGameMode() == GameMode.SPECTATOR)
                return;
           
            Inventory inv = p.getOpenInventory().getTopInventory();
           
            if (inv == null)
                return;
           
            if (inv.getType() != InventoryType.CRAFTING)
                return;
           
            setItems(inv);
        }
       
        @EventHandler
        public void onInvClose(InventoryCloseEvent e) {
            if (e.getInventory().getType() != InventoryType.CRAFTING)
                return;
           
            Player p = (Player) e.getPlayer();
           
            if (p.getGameMode() == GameMode.CREATIVE || p.getGameMode() == GameMode.SPECTATOR)
                return;
           
            removeItems(e.getInventory());
        }
       
        private void setItems(Inventory inv) {
            if (inv.getItem(1) != null)
                return;
           
            inv.setItem(0, MenuItems.toHub());
           
            inv.setItem(1, MenuItems.playerMenu());
            inv.setItem(2, MenuItems.settings());
            inv.setItem(3, MenuItems.shop());
            inv.setItem(4, MenuItems.website());
        }
       
        private void removeItems( Inventory inv) {
            inv.setItem(0, null);
           
            inv.setItem(1, null);
            inv.setItem(2, null);
            inv.setItem(3, null);
            inv.setItem(4, null);
        }
       
    }