Inventory for hub selecting

Discussion in 'Spigot Plugin Development' started by avighnash, May 11, 2016.

  1. Hello everyone! I have been working on a hub selector for my server. I have 9 worlds (lobbies) and I want to be able to let the player teleport to there. So I made an itemstack:
    Code (Text):
    package us.universalpvp.te.cosmetics;

    import java.util.Arrays;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.Inventory;

    import us.universalpvp.te.utils.ItemBuilder;

    public class SwitchHub {

        private final Player p;

        public SwitchHub(Player p) {
            this.p = p;
        }

        private String lobbyName;

        public void switchHubInv() {

            Inventory inv = Bukkit.createInventory(null, 45, ChatColor.DARK_GRAY + "Lobby Selector");

            ItemBuilder lobby = new ItemBuilder(Material.QUARTZ_BLOCK);
            String connection = null;
            if (p.getWorld().getPlayers().contains(p)) {
                connection = ChatColor.RED + "Already connected!";
            } else {
                connection = ChatColor.YELLOW + "Click to connect!";
            }
            lobby.setLore(
                    Arrays.asList(ChatColor.GRAY + "Players: " + Bukkit.getServer().getWorld(lobbyName).getPlayers().size(),
                            " ", connection));

        }

    }
     
    and now I want 9 copies. Each copy would have its own number indicating what lobby number it is.
    Would this work?:
    Code (Text):
    for (int i = 0; i < 9; i++) {
                lobby.setName("Main Lobby #" + i);
            }
     
  2. Plus, please don't use this horrible code <3
     
  3. set the location of the other world's lobby then save it to a flatfile or sql then if they clicked certain item they'll teleported to the location setted to the flatfile or sql.
     
  4. This will only apply the name of the last lobby and there will only one ItemStack.

    You have to use a for statement to loop through your 9 lobbies.
    For each lobby (inside the loop), create an ItemStack as you did above and apply the correct name and information.
    Still in the loop, add it to the inventory at the correct slot or use Inventory#addItem(ItemStack).
    You can also re-use the ItemStack (so put it out of the loop), and only set the name each time.
     
  5. I will try this right now! :)
     
  6. Like this? (For the for loop part only)
    Code (Text):
    for (int i = 9; Bukkit.getServer().getWorlds().size() <= i; i++) {

                item = new ItemStack(Material.SKULL);
                ItemMeta meta = item.getItemMeta();

                SkullMeta skullMeta = (SkullMeta) meta;
                skullMeta.setDisplayName(ChatColor.DARK_AQUA + "Statistics:");
                skullMeta.setLore(Arrays.asList(ChatColor.WHITE + "Unique Joins: " + ChatColor.GREEN + players.size()));
                skullMeta.setOwner(p.getName());
            }
     
  7. It should be int i = 0, not 9. Also since you start at 0, you have to put i < Bukkit.getServer().getWorlds().size().
    If you start at one, you could put "<=" instead of 0, your lobbies would start at 1, then 2, 3... up to 9 (and not 8).
    And you have to set the item in the inventory in the loop too.

    Also since you define the item above the loop, you should put the meta thing in it too.
    Inside the loop should only be the thing that change between each hub, so maybe the lore and the display name.
     
  8. Oh yeah! I'm so stupid, I forgot to remember that java starts at 0 xD
     
  9. So basically this is it?
    Code (Text):
    for (int i = 0; Bukkit.getServer().getWorlds().size() < i; i++) {

                ItemStack lobby = new ItemStack(Material.QUARTZ_BLOCK);
                ItemMeta meta = lobby.getItemMeta();

                if (p.getWorld().getPlayers().contains(p)) {
                    connection = ChatColor.RED + "Already connected!";
                } else {
                    connection = ChatColor.YELLOW + "Click to connect!";
                }

                meta.setDisplayName(ChatColor.GREEN + "Main Lobby #" + i);

                meta.setLore(Arrays.asList(
                        ChatColor.GRAY + "Players: " + Bukkit.getServer().getWorld(lobbyName).getPlayers().size(), " ",
                        connection));
            }
     
  10. i < Bukkit.getServer().getWorlds().size()
     
  11. Oops :p
     
  12. At the end of the loop (below meta.setLore), use inventory.setItem(i, lobby); "i" being the slot and lobby the item.
    Also that will make it so that it would be "Main Lobby#0", "Main Lobby#1", "Main Lobby#3", ..., "Main Lobby#8"
    If you want it to start at 1 and finish at 9, use: ChatColor.GREEN + "Main Lobby #" + (i+1)
     
  13. Okay now.
    What would I do here? (Look down) I want it so when the player clicks the itemstack, it would teleport them to the designated area.
    Here is what I have:
    Code (Text):
    package us.universalpvp.te.cosmetics;

    import java.util.Arrays;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;

    public class HubSelector {

        private final Player p;

        private Inventory inv = null;

        private ItemStack lobby = null;

        public HubSelector(Player p) {
            this.p = p;
        }

        private String lobbyName;

        public void switchHubInv() {

            inv = Bukkit.createInventory(null, 45, ChatColor.DARK_GRAY + "Lobby Selector");

            String connection = null;

            for (int i = 0; i < Bukkit.getServer().getWorlds().size(); i++) {

                lobby = new ItemStack(Material.QUARTZ_BLOCK);
                ItemMeta meta = lobby.getItemMeta();

                if (p.getWorld().getPlayers().contains(p)) {
                    connection = ChatColor.RED + "Already connected!";
                } else {
                    connection = ChatColor.YELLOW + "Click to connect!";
                }

                meta.setDisplayName(ChatColor.GREEN + "Main Lobby #" + i);

                meta.setLore(Arrays.asList(
                        ChatColor.GRAY + "Players: " + Bukkit.getServer().getWorld(lobbyName).getPlayers().size(), " ",
                        connection));

                for (int slots = 0; slots < 9; slots++) {
                    inv.setItem(slots, lobby);
                }

            }

        }

        @EventHandler
        public void onInventoryClick(InventoryClickEvent e) {
            if (!e.getInventory().getName().equalsIgnoreCase(this.inv.getName())) {
                return;
            }
            e.setCancelled(true);

            ItemStack currentItem = e.getCurrentItem();
            if ((currentItem == null) || (!currentItem.hasItemMeta())) {
                return;
            }
            ItemMeta currentItemMeta = currentItem.getItemMeta();
            if (!currentItemMeta.hasDisplayName()) {
                return;
            }
            String name = currentItemMeta.getDisplayName();

            name = ChatColor.stripColor(name);

            Player player = (Player) e.getWhoClicked();
            if (name.equals("itemstack name")) {

                player.teleport((Location) Bukkit.getWorld("Hub#")); // i want to
                                                                        // teleport
                                                                        // the
                                                                        // player to
                                                                        // Hub# +
                                                                        // whatever
                                                                        // int was
                                                                        // defined
                                                                        // in
                                                                        // switchHubInv

            }
        }
    }
     
  14. Code (Text):
    if (!e.getInventory().getName().equalsIgnoreCase(this.inv.getName())) {
                return;
            }
     
    This will return null if your GUI is not opened by the player. InventoryClickEvent runs on all inventories. Manually type the name in there instead of doing that or change your private Inventory inv = null; to Inventory inv = Bukkit.createInventory(null, 45, ChatColor.DARK_GRAY + "Lobby Selector");
     
    • Agree Agree x 1
  15. You could maybe use a switch statement:
    Code (Java):
    switch (name) {
    case ChatColor.GREEN + "Main Lobby #1":
        player.teleport(Bukkit.getWorld("Hub#1").getSpawnLocation());
        break;
    case ChatColor.GREEN + "Main Lobby #2":
        player.teleport(Bukkit.getWorld("Hub#2").getSpawnLocation());
        break;
    case ChatColor.GREEN + "Main Lobby #3":
        player.teleport(Bukkit.getWorld("Hub#3").getSpawnLocation());
        break;
    }
     
    But if it's always the same thing, I don't recommend doing that. You could use:
    Code (Java):
    name = name.replace(ChatColor.GREEN + "Main Lobby ", "Hub");
    player.teleport(Bukkit.getWorld(name).getSpawnLocation());
    It will replace "┬žaMain Lobby #1" by "Hub#1", "┬žaMain Lobby #2" by "Hub#2", etc.
    Only works if you don't change the names (of the items and the worlds), of course.
     
  16. Done that. So what should I do now?
     
  17. I need this urgently.
     
  18. Now you build your plugin, use InventoryClickEvent with name checks and null checks and do whatever you want, go wild! :)
     
  19. That's what I need help with. The name checks. Right now, I am using a for loop to make the itemstacks. Now, I need to get the name of the itemstack, which I don't know how to do because it has a integer
    Code:
    Code (Text):
    package us.universalpvp.te.cosmetics;

    import java.util.Arrays;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.Statistic;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;

    public class HubSelector {

        private final Player p;

        private Inventory inv = Bukkit.createInventory(null, 45, ChatColor.DARK_GRAY + "Lobby Selector");;

        private ItemStack lobby = null;

        public HubSelector(Player p) {
            this.p = p;
        }

        private String lobbyName;

        public void switchHubInv() {

            String connection = null;

            for (int i = 0; i < Bukkit.getServer().getWorlds().size(); i++) {

                lobby = new ItemStack(Material.QUARTZ_BLOCK);
                ItemMeta meta = lobby.getItemMeta();

                if (p.getWorld().getPlayers().contains(p)) {
                    connection = ChatColor.RED + "Already connected!";
                } else {
                    connection = ChatColor.YELLOW + "Click to connect!";
                }

                meta.setDisplayName(ChatColor.GREEN + "Main Lobby #" + i);

                meta.setLore(Arrays.asList(
                        ChatColor.GRAY + "Players: " + Bukkit.getServer().getWorld(lobbyName).getPlayers().size(), " ",
                        connection));

                for (int slots = 0; slots < Bukkit.getServer().getWorlds().size(); slots++) {
                    inv.setItem(slots, lobby);
                }

            }

        }

        @EventHandler
        public void onInventoryClick(InventoryClickEvent e) {
            if (!e.getInventory().getName().equalsIgnoreCase(this.inv.getName())) {
                return;
            }
            e.setCancelled(true);

            ItemStack currentItem = e.getCurrentItem();
            if ((currentItem == null) || (!currentItem.hasItemMeta())) {
                return;
            }
            ItemMeta currentItemMeta = currentItem.getItemMeta();
            if (!currentItemMeta.hasDisplayName()) {
                return;
            }
            String name = currentItemMeta.getDisplayName();

            name = ChatColor.stripColor(name);

            Player player = (Player) e.getWhoClicked();
            if (name.contains("Main Lobby")) {

                player.teleport((Location) Bukkit.getWorld("Hub#" + /*the number */));

            }
        }
    }
     
  20. Would this work? I made a integer field that I used in the for loop too
    Code (Text):

        @EventHandler
        public void onInventoryClick(InventoryClickEvent e) {
            if (!e.getInventory().getName().equalsIgnoreCase(this.inv.getName())) {
                return;
            }
            e.setCancelled(true);

            ItemStack currentItem = e.getCurrentItem();
            if ((currentItem == null) || (!currentItem.hasItemMeta())) {
                return;
            }
            ItemMeta currentItemMeta = currentItem.getItemMeta();
            if (!currentItemMeta.hasDisplayName()) {
                return;
            }
            String name = currentItemMeta.getDisplayName();

            name = ChatColor.stripColor(name);

            Player player = (Player) e.getWhoClicked();
            if (name.contains("Main Lobby")) {
                player.teleport((Location) Bukkit.getWorld("Hub#" + i));
            }
        }
    }
     
    #20 avighnash, May 12, 2016
    Last edited: May 12, 2016