package com.lifeknight.relaymchub.miscellaneous; import com.lifeknight.relaymchub.ExtraListeners; import com.lifeknight.relaymchub.Main; import com.lifeknight.relaymchub.player.HubPlayer; import com.lifeknight.relaymcutils.player.*; import com.lifeknight.relaymcutils.player.settings.GameSettings; import com.lifeknight.relayutils.RelayUtils; import com.lifeknight.relayutils.basic.Miscellaneous; import com.lifeknight.relayutils.basic.Text; import com.lifeknight.relayutils.data.QueueData; import com.lifeknight.relayutils.game.GameType; import com.lifeknight.relayutils.game.MainGame; import com.lifeknight.relayutils.player.Group; import com.lifeknight.relayutils.utilities.ItemUtilities; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; import static org.bukkit.ChatColor.*; public class SmartGUIUtils { public static List<QueueData> currentGames; public static List<QueueData> queuedGames; private static Map<GameType, Integer> counts = new HashMap<>(); public static void initialize() { } public static final SmartGUI MAIN_GUI = new SmartGUI("Relay", 3, false); static { MAIN_GUI.add( 0, Material.COMPASS, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).sendToMainHub(), YELLOW + "Main Lobby", AQUA + "Go to the Main lobby."); MAIN_GUI.add( 18, Material.COMPARATOR, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).showSettingsGui(), YELLOW + "Settings", AQUA + "Edit your server settings."); fillMainGui(); MAIN_GUI.add(26, Material.PINK_DYE, (player, b, b1) -> { HubPlayer.getHubPlayer(player).togglePlayers(); }, YELLOW + "Toggle Players", AQUA + "Show or hide players in the lobby."); MAIN_GUI.fillEmptySpots(); for (GameType value : GameType.getGameTypes()) { setGuiForGameType(new SmartGUI(value.getFullPrettyName(), 1, false), value); } for (MainGame mainGame : MainGame.values()) { List<GameType> types = Miscellaneous.filter(mainGame.getGameTypes(), gameType -> gameType.isEnabled() && gameType.isMainType()); SmartGUI gameModes = new SmartGUI(mainGame.getName() + " Modes", 1, false); setForGameModes(gameModes, types); } } public static final SmartItem NAVIGATOR = new SmartItem(Material.COMPASS, YELLOW + "Navigator"); public static final SmartItem PLAY = new SmartItem(Material.DIAMOND_SWORD, BLUE + "Play"); public static final SmartItem REQUEUE = new SmartItem(Material.REDSTONE, LIGHT_PURPLE + "Requeue"); public static final SmartItem COSMETICS = new SmartItem(Material.EMERALD, GREEN + "Cosmetics"); public static final SmartItem MENU_OPEN = new SmartItem(Material.EMERALD, GREEN + "Menu"); public static final SmartItem HIDE_PLAYERS = new SmartItem(Material.LIME_DYE, GREEN + "Hide Players"); public static final SmartItem SHOW_PLAYERS = new SmartItem(Material.GRAY_DYE, GRAY + "Show Players"); public static final SmartItem LOBBY_SELECTOR = new SmartItem(Material.NETHER_STAR, GOLD + "Lobby Selector"); public static final SmartItem STATISTICS = new SmartItem(Material.PAPER, AQUA + "Statistics"); public static final SmartItem KIT_EDITOR = new SmartItem(Material.BOOK, LIGHT_PURPLE + "Kits"); public static final SmartItem KIT_SELECTOR = new SmartItem(Material.FIREWORK_STAR, GOLD + "Kit Selector"); public static final SmartItem CUSTOM_MAP_MENU = new SmartItem(Material.NETHER_STAR, AQUA + "Menu"); public static final SmartItem SPAWN = new SmartItem(Material.FEATHER, RED + "Back to Spawn"); public static final SmartGUI LOBBY_SELECTOR_GUI = new SmartGUI("Lobby Selector", 1); public static final SmartGUI PARTY_MODES = new SmartGUI("Party Modes", 5); public static final SmartGUI MENU = new SmartGUI("Menu", 1, false); public static final SmartGUI CUSTOM_KITS_QUEUE = new SmartGUI("Custom Kits", 6, false); public static final HashMap<GameType, SmartGUI> GAME_QUEUES = new HashMap<>(); static { for (GameType gameType : Miscellaneous.getList(GameType.DUELS_AXE, GameType.DUELS_CRYSTAL, GameType.MANHUNT_1V1, GameType.DUELS_SWORD, GameType.DUELS_NETHERITE_POT, GameType.DUELS_UHC, GameType.DUELS_DIAMOND_POT)) { GAME_QUEUES.put(gameType, new SmartGUI(gameType.getFullPrettyName(), 4, false)); } if (Main.isDuelsLobby()) { GAME_QUEUES.put(GameType.DUELS_CUSTOM, CUSTOM_KITS_QUEUE); } } public static final SmartItem PREVIEW_KIT = new SmartItem(Material.NETHER_STAR, GOLD + "Preview Kit"); public static final SmartItem ACCEPT_KIT = new SmartItem(Material.GREEN_TERRACOTTA, GOLD + "Accept Kit"); public static final SmartItem CANCEL_KIT = new SmartItem(Material.RED_TERRACOTTA, GOLD + "Return to Browsing"); public static final SmartItem LEAVE_QUEUE = new SmartItem(Material.FEATHER, RED + "Leave Queue"); public static final SmartItem CANCEL_MAP = new SmartItem(Material.RED_TERRACOTTA, RED + "Cancel", DARK_GRAY + "Cancel selecting this map."); public static final SmartItem ACCEPT_MAP = new SmartItem(Material.GREEN_TERRACOTTA, GREEN + "Accept", DARK_GRAY + "Select this map for your kit."); public static final SmartItem ADD_TO_MAP_LIBRARY = new SmartItem(Material.WRITTEN_BOOK, AQUA + "Add to Your Library", DARK_GRAY + "Add a copy of this map to your library."); public static final SmartItem MAP_INFO = new SmartItem(Material.PAPER, AQUA + "Map Info", DARK_GRAY + "View information for this custom map."); static { MENU.add(2, Material.EMERALD, (player, b, b2) -> HubPlayer.getHubPlayer(player).openCosmeticsGui(), GREEN + "Cosmetics"); MENU.add(4, Material.BOOK, (player, b, b2) -> HubPlayer.getHubPlayer(player).openDefaultKitListGui(), LIGHT_PURPLE + "Kits"); MENU.add(6, Material.PAPER, (player, b, b2) -> HubPlayer.getHubPlayer(player).showStatistics(), AQUA + "Statistics"); KIT_SELECTOR.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).showLobbyKitSelect()); } static { NAVIGATOR.onPlayerClick((player, rightClick, shift) -> MAIN_GUI.open(player)); PLAY.onPlayerClick((player, rightClick, shift) -> getGameModeGUI().open(player)); REQUEUE.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).reQueue()); MENU_OPEN.onPlayerClick((player, b, b2) -> HubPlayer.getHubPlayer(player).openGui(MENU)); STATISTICS.onPlayerClick((player, b, b2) -> HubPlayer.getHubPlayer(player).showStatistics()); HIDE_PLAYERS.onPlayerClick((player, b, b2) -> HubPlayer.getHubPlayer(player).hidePlayers()); COSMETICS.onPlayerClick((player, b, b2) -> HubPlayer.getHubPlayer(player).openCosmeticsGui()); SHOW_PLAYERS.onPlayerClick((player, b, b2) -> HubPlayer.getHubPlayer(player).showPlayers()); KIT_EDITOR.onPlayerClick((player, b, b2) -> HubPlayer.getHubPlayer(player).openDefaultKitListGui()); LOBBY_SELECTOR.onPlayerClick((player, b, b2) -> LOBBY_SELECTOR_GUI.open(player)); CUSTOM_MAP_MENU.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).showCustomMapMenu()); SPAWN.onPlayerClick((player, b, b1) -> { HubPlayer hubPlayer = HubPlayer.getHubPlayer(player); if (hubPlayer.isCollaboratingCustomMap()) { hubPlayer.leaveCustomMap(); } else { player.chat("/spawn"); } }); PREVIEW_KIT.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).previewKit()); ACCEPT_KIT.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).acceptKit()); CANCEL_KIT.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).cancelKit(true)); ACCEPT_MAP.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).acceptMap()); CANCEL_MAP.onPlayerClick(((player, b, b1) -> HubPlayer.getHubPlayer(player).cancelMap())); ADD_TO_MAP_LIBRARY.onPlayerClick(((player, b, b1) -> HubPlayer.getHubPlayer(player).addToMapLibrary())); MAP_INFO.onPlayerClick((p, b, b1) -> HubPlayer.getHubPlayer(p).showMapInfo()); LEAVE_QUEUE.onPlayerClick(((player, b, b1) -> HubPlayer.getHubPlayer(player).cancelQueue())); } public static final SmartItem CHECKPOINT = new SmartItem(Material.HEAVY_WEIGHTED_PRESSURE_PLATE, GREEN + "Teleport to Last Checkpoint"); public static final SmartItem RESET = new SmartItem(Material.RED_BED, YELLOW + "Reset"); public static final SmartItem EXIT = new SmartItem(Material.FEATHER, RED + "Exit"); static { CHECKPOINT.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).teleportToParkourCheckpoint()); RESET.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).resetParkour()); EXIT.onPlayerClick((player, b, b1) -> HubPlayer.getHubPlayer(player).exitParkour()); } public static void setGuiForGameType(SmartGUI smartGUI, GameType gameType) { if (gameType.getMainGame().getPartyGameType() != null) { if (gameType == GameType.DUELS_CUSTOM) { smartGUI.add( 2, Material.DIAMOND_AXE, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType, new QueueData().attachData("other", false)), GOLD + BOLD.toString() + "YOUR KIT", GRAY + "Play duels with your custom kit."); smartGUI.add( 4, Material.FEATHER, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).cancel(gameType), RED + "Leave Queue", GRAY + RelayUtils.format("Leave the %s queue.", gameType.getFullPrettyName())); smartGUI.add( 6, Material.NETHERITE_AXE, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType, new QueueData().attachData("other", true)), GOLD + BOLD.toString() + "ANOTHER'S KIT", GRAY + "Play duels with someone else's custom kit."); } else { smartGUI.add( 3, Material.COMPASS, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType), YELLOW + "Play " + GREEN + gameType.getPrefix(), GRAY + RelayUtils.format("Click to queue for %s.", gameType.getFullPrettyName())); smartGUI.add( 5, Material.FEATHER, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).cancel(gameType), RED + "Leave Queue", GRAY + RelayUtils.format("Leave the %s queue.", gameType.getFullPrettyName())); } } else { smartGUI.add( 3, Material.COMPASS, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType), YELLOW + "Play " + GREEN + gameType.getPrefix().toUpperCase(), GRAY + RelayUtils.format("Click to queue for public %s.", gameType.getFullPrettyName())); smartGUI.add( 5, gameType.getRepresentative(), (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).partyQueue(gameType), DARK_RED + "PRIVATE " + GREEN + gameType.getPrefix().toUpperCase(), GRAY + RelayUtils.format("Click to play %sprivate %s with custom game settings!.", RED, gameType.getPrefix())); } smartGUI.fillEmptySpots(); } public static void setForGameModes(SmartGUI smartGUI, List<GameType> types) { types = Miscellaneous.firstFew(5, types); int index = 4 - types.size() + 1; int iteration = 0; for (GameType type : types) { if (counts != null) { Integer count = counts.getOrDefault(type, -1); smartGUI.add( index, getMaterialForIteration(iteration), (player, rightClick, shift) -> queueGui(SmartPlayer.getSmartPlayer(player), type), GOLD + type.getSuffix(), YELLOW.toString() + count + " playing"); } else { smartGUI.add( index, getMaterialForIteration(iteration), (player, rightClick, shift) -> selectGameMode(player, type), GOLD + type.getSuffix()); } index += 2; iteration++; } smartGUI.fillEmptySpots(); } public static void onPlayerCount(Map<GameType, Integer> counts) { SmartGUIUtils.counts = counts; for (MainGame mainGame : MainGame.values()) { List<GameType> types = Miscellaneous.filter(mainGame.getGameTypes(), gameType -> gameType.isEnabled() && gameType.isMainType()); SmartGUI gameModes = SmartGUI.getByName(mainGame.getName() + " Modes"); if (gameModes != null) { setForGameModes(gameModes, types); } } fillMainGui(); } public static void selectGameMode(Player player, GameType gameType) { HubPlayer hubPlayer = HubPlayer.getHubPlayer(player); SmartGUI smartGUI = new SmartGUI(gameType.getFullPrettyName(), 1, true); if (gameType.isExplicitParty()) { ItemStack privateQueue = new ItemStack(Material.COMPASS); privateQueue.setAmount(gameType.getTotalPlayerCount()); ItemUtilities.enchanted(privateQueue); smartGUI.add( 4, privateQueue, (player1, b, b1) -> hubPlayer.partyQueue(gameType), RelayUtils.format("%s%sPRIVATE %s%s%s", DARK_RED, BOLD, GREEN, BOLD, gameType.getPrefix().toUpperCase()), GRAY + RelayUtils.format("Click to play %sprivate%s %s with custom game settings!", RED, GRAY, gameType.getFullPrettyName()), " ", RelayUtils.format("%sPREMIUM %srequired to play.", GOLD, DARK_GRAY), RelayUtils.format("%s%s", DARK_GREEN, getPlayerCountLine(gameType))); } else { ItemStack publicQueue = gameType.getRepresentative().clone(); publicQueue.setAmount(Math.min(64, hubPlayer.getPartySize())); smartGUI.add( 3, publicQueue, (player1, b, b1) -> hubPlayer.queue(gameType), RelayUtils.format("%sPlay %s%s%s", YELLOW, GREEN, BOLD, gameType.getPrefix().toUpperCase()), GRAY + RelayUtils.format("Click to queue for public %s.", gameType.getFullPrettyName()), " ", RelayUtils.format("%sTwo players required to start.", DARK_GRAY), RelayUtils.format("%s%s", DARK_GREEN, getPlayerCountLine(gameType))); boolean shouldShowFeather = gameType.getMainGame().getPartyGameType() != null; ItemStack privateQueue = new ItemStack(Material.COMPASS); privateQueue.setAmount(gameType.getTotalPlayerCount()); ItemUtilities.enchanted(privateQueue); if (shouldShowFeather) { smartGUI.add( 5, Material.FEATHER, (p, rightClick, shift) -> hubPlayer.cancel(gameType), RED + "Leave Queue", GRAY + RelayUtils.format("Leave the %s queue.", gameType.getFullPrettyName())); } else { smartGUI.add( 5, privateQueue, (player1, b, b1) -> hubPlayer.partyQueue(gameType), RelayUtils.format("%s%sPRIVATE %s%s%s", DARK_RED, BOLD, GREEN, BOLD, gameType.getPrefix().toUpperCase()), GRAY + RelayUtils.format("Click to play %sprivate%s %s with custom game settings!", RED, GRAY, gameType.getFullPrettyName()), " ", RelayUtils.format("%sPREMIUM %srequired to play.", GOLD, DARK_GRAY), RelayUtils.format("%s%s", DARK_GREEN, getPlayerCountLine(gameType))); } } hubPlayer.openGui(smartGUI); } private static String getPlayerCountLine(GameType gameType) { return counts.getOrDefault(gameType, 0) + " playing"; } public static void fillMainGui() { List<MainGame> elements = Miscellaneous.getList(MainGame.MANHUNT, MainGame.DUELS, MainGame.PARTY); int row = 1; final int maxRowSize = 5; int index = 4 - Math.min(elements.size(), maxRowSize) / 2; int rowIndex = 1; for (MainGame mainGame : elements) { MAIN_GUI.add( row * 9 + index, mainGame.getRepresentative(), (player, b, b1) -> { if (mainGame == MainGame.PARTY) { getPartyModesGui().open(player); } else { if (Main.mainGame == mainGame) { ExtraListeners.spawnPlayer(player); } else { SmartPlayer.getSmartPlayer(player).sendToServer(mainGame.getComparableName()); } } }, GREEN + (mainGame == MainGame.PARTY ? "Other Modes" : mainGame.getName()), Miscellaneous.with(Miscellaneous.processList(Miscellaneous.getList(mainGame.getDescription().split("\n")), s -> WHITE + s), YELLOW + getTotalPlayerCount(mainGame))); index++; rowIndex++; if (rowIndex > maxRowSize) { row++; rowIndex = 1; index = 4 - Math.min(elements.size() - (row - 1) * maxRowSize, maxRowSize) / 2; } } } public static List<String> getDescription(GameType gameType, int playingCount) { List<String> description = new ArrayList<>(); String descriptionString; if (gameType == GameType.BLOCK_SHUFFLE) { descriptionString = "Players must stand on a given block before\n" + "time runs out. The player who lasts the most\n" + "rounds wins!"; } else if (gameType == GameType.RANDOM_ITEMS) { descriptionString = "Battle royale where each player gets random items\n" + "every round. Blocks do not drop items."; } else if (gameType == GameType.DEATH_SWAP) { descriptionString = "Every 5 minutes players swap places, kill\n" + "the other player before they kill you!"; } else if (gameType == GameType.DEATH_SHUFFLE) { descriptionString = "Players must die a certain way before the\n" + "time runs out. The player who lasts the most\n" + "rounds wins!"; } else if (gameType == GameType.MANSAVE) { descriptionString = "The runner must die before the time runs out\n" + "while the saver is trying to stop them."; } else if (gameType == GameType.BINGO) { descriptionString = "Complete the challenges on a bingo board \n" + "horizontally, vertically, or diagonally to win!"; } else { descriptionString = "The hunter must punch the runner before the \n" + "time runs out, while the runner must survive."; } description.addAll(Miscellaneous.processList(o -> GRAY + o, descriptionString.split(Pattern.quote("\n")))); description.add(YELLOW.toString() + playingCount + " playing"); return description; } public static SmartGUI getPartyModesGui() { SmartGUI smartGUI = new SmartGUI("Other Modes", 3, false); List<GameType> elements = Miscellaneous.getList(GameType.BLOCK_SHUFFLE, GameType.RANDOM_ITEMS, GameType.DEATH_SWAP, GameType.DEATH_SHUFFLE, GameType.MANSAVE, GameType.ULTIMATE_TAG, GameType.BINGO); int index = 10; for (GameType gameType : elements) { smartGUI.add(index++, gameType.getRepresentative(), (player, b, b1) -> selectGameMode(player, gameType), YELLOW + gameType.getPrefix(), getDescription(gameType, counts.getOrDefault(gameType, 0))); } /* int row = 1; final int maxRowSize = 8; int index = 4 - Math.min(elements.size(), maxRowSize) / 2; int rowIndex = 0; for (GameType gameType : elements) { smartGUI.add( row * 9 + index, gameType.getRepresentative(), (player, b, b1) -> selectGameMode(player, gameType), YELLOW + gameType.getPrefix(), GRAY + "Play " + gameType.getPrefix() + ".", YELLOW.toString() + counts.getOrDefault(gameType, 0) + " playing"); index++; rowIndex++; if (rowIndex > maxRowSize) { row++; rowIndex = 1; index = 4 - Math.min(elements.size() - (row - 1) * maxRowSize, maxRowSize) / 2; } } */ smartGUI.fillEmptySpots(); return smartGUI; } public static String getTotalPlayerCount(MainGame mainGame) { AtomicInteger count = new AtomicInteger(); counts.forEach((gameType, integer) -> { if (gameType.getMainGame() == mainGame) { count.addAndGet(integer); } }); return count.get() + " playing"; } private static Material getMaterialForIteration(int iteration) { switch (iteration) { case 0: return Material.IRON_INGOT; case 1: return Material.GOLD_INGOT; case 2: return Material.DIAMOND; case 3: return Material.EMERALD; } return Material.NETHERITE_INGOT; } public static ItemStack getItemStackForSettingName(String name) { name = Text.toComparable(name); switch (name) { case "anybody": case "low": return new ItemStack(Material.GREEN_TERRACOTTA); case "friendsoffriends": case "medium": return new ItemStack(Material.YELLOW_TERRACOTTA); case "friends": case "high": return new ItemStack(Material.RED_TERRACOTTA); } return new ItemStack(Material.BLACK_TERRACOTTA); } public static SmartGUI getGameModeGUI() { if (Main.isGameLobby()) { return SmartGUI.getByName(Main.getMainGame().getName() + " Modes"); } return null; } public static void onHubs(Map<String, Integer> hubs) { int index = 0; LOBBY_SELECTOR_GUI.clearAll(); for (String hubName : hubs.keySet()) { int count = hubs.get(hubName); String countLine = (count >= RelayUtils.HUB_DEFAULT_MAX_SIZE ? RED.toString() + count : YELLOW.toString() + count) + AQUA + "/" + RelayUtils.HUB_DEFAULT_MAX_SIZE; Material representative; if (count >= RelayUtils.HUB_DEFAULT_MAX_SIZE) { representative = count >= RelayUtils.HUB_EXTENDED_MAX_SIZE ? Material.REDSTONE_BLOCK : Material.IRON_BLOCK; } else { representative = Material.IRON_BLOCK; } LOBBY_SELECTOR_GUI.add(index, hubName.equalsIgnoreCase(RelayUtils.getName()) ? ItemUtilities.enchanted(representative) : new ItemStack(representative), (player, b, b2) -> { HubPlayer hubPlayer = HubPlayer.getHubPlayer(player); if (count >= RelayUtils.HUB_DEFAULT_MAX_SIZE) { if (hubPlayer.isInGroupOrHigher(Group.TIERIII)) { if (count >= RelayUtils.HUB_EXTENDED_MAX_SIZE) { if (hubPlayer.isStaff()) { hubPlayer.sendToServer(hubName); } else { hubPlayer.sendErrorMessage("That lobby has reached maximum capacity!"); hubPlayer.playErrorSound(); } } else { hubPlayer.sendToServer(hubName); } } else { hubPlayer.sendErrorMessage("That lobby has reached maximum capacity! Upgrade to Tier III to join lobbies with more than %d players!", RelayUtils.HUB_EXTENDED_MAX_SIZE); hubPlayer.playErrorSound(); } } else { hubPlayer.sendToServer(hubName); } }, YELLOW + getPrettyName(Main.hubType) + " Lobby " + (index + 1), getHubInfoLines(countLine, hubName)); index++; } } public static String[] getHubInfoLines(String countLine, String hubName) { if (hubName.equalsIgnoreCase(RelayUtils.getName())) { return new String[]{countLine, GREEN + "Connected"}; } return new String[]{countLine}; } public static String getPrettyName(String codeName) { if ("main".equals(Text.toComparable(codeName))) { return "Main"; } return MainGame.getMainGame(Main.hubType).getName(); } public static void queueGui(SmartPlayer smartPlayer, GameType gameType) { HubPlayer hubPlayer = HubPlayer.getHubPlayer(smartPlayer); if (hubPlayer.isInParty() && !GAME_QUEUES.containsKey(gameType)) { hubPlayer.partyQueue(gameType); return; } else { if (GAME_QUEUES.containsKey(gameType)) { hubPlayer.openGui(GAME_QUEUES.get(gameType)); return; } } SmartGUI smartGUI = new SmartGUI(gameType.getFullPrettyName(), 1, true); if (gameType.getMainGame().getPartyGameType() != null) { if (gameType == GameType.DUELS_CUSTOM) { smartGUI.add( 2, Material.DIAMOND_AXE, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType, new QueueData().attachData("other", false)), GOLD + BOLD.toString() + "YOUR KIT", GRAY + "Play duels with your custom kit."); smartGUI.add( 4, Material.FEATHER, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).cancel(gameType), RED + "Leave Queue", GRAY + RelayUtils.format("Leave the %s queue.", gameType.getFullPrettyName())); smartGUI.add( 6, Material.NETHERITE_AXE, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType, new QueueData().attachData("other", true)), GOLD + BOLD.toString() + "ANOTHER'S KIT", GRAY + "Play duels with someone else's custom kit."); } else { SmartGUI smartGUI1 = GAME_QUEUES.get(gameType); if (smartGUI1 != null) { smartPlayer.openGui(smartGUI1); return; } smartGUI.add( 3, Material.COMPASS, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType), YELLOW + "Play " + GREEN + gameType.getPrefix(), GRAY + RelayUtils.format("Click to queue for %s.", gameType.getFullPrettyName())); smartGUI.add( 5, Material.FEATHER, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).cancel(gameType), RED + "Leave Queue", GRAY + RelayUtils.format("Leave the %s queue.", gameType.getFullPrettyName())); } } else { smartGUI.add( 3, Material.COMPASS, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).queue(gameType), YELLOW + "Play " + GREEN + gameType.getPrefix().toUpperCase(), GRAY + RelayUtils.format("Click to queue for public %s.", gameType.getFullPrettyName())); smartGUI.add( 5, gameType.getRepresentative(), (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).partyQueue(gameType), DARK_RED + "PRIVATE " + GREEN + gameType.getPrefix().toUpperCase(), GRAY + RelayUtils.format("Click to play %sprivate %s with custom game settings!.", RED, gameType.getPrefix())); } smartGUI.fillEmptySpots(); smartPlayer.openGui(smartGUI); } public static void updateQueueGUIs(List<QueueData> currentGames, List<QueueData> queuedGames) { for (Game game : GAMES) { if (Miscellaneous.match(queuedGames, queueData -> queueData.hasData("owner") && queueData.getData("owner").equals(game.ownerUUID)) == null) { HubPlayer.onCustomQueueRemoved(game.ownerUUID); } } GAMES.removeIf(game -> { QueueData current = Miscellaneous.match(currentGames, queueData -> queueData.hasData("owner") && queueData.getData("owner").equals(game.ownerUUID)); QueueData queued = Miscellaneous.match(queuedGames, queueData -> queueData.hasData("owner") && queueData.getData("owner").equals(game.ownerUUID)); if (current == null && queued == null) { return true; } if (queued != null && Text.comparablyEquals(queued.getData("gameType"), game.gameType)) { return true; } return false; }); GAME_QUEUES.forEach((gameType, smartGUI) -> updateQueuesGUI(gameType, smartGUI, currentGames, queuedGames)); for (QueueData liveGame : currentGames) { if (liveGame.hasData("index")) { Game game = getGame(liveGame); try { updateCurrentGame(game, liveGame); } catch (Exception e) { RelayUtils.printError("couldn't do the live one man", e, 5); } } } } private static void updateQueuesGUI(GameType gameType, SmartGUI smartGUI, List<QueueData> currentGames, List<QueueData> queuedGames) { smartGUI.clearAll(); smartGUI.fillEmptySpots(); for (int i = 9; i < (gameType == GameType.DUELS_CUSTOM ? 54 : 36); i++) { int finalI = i; smartGUI.add(i, Material.POLISHED_BLACKSTONE_BUTTON, (player, b, b1) -> HubPlayer.getHubPlayer(player).createQueue(finalI, gameType), GREEN + BOLD.toString() + "QUEUE " + gameType.getDisplaySuffix().toUpperCase()); } if (gameType.getMainGame() != MainGame.MANHUNT) { smartGUI.add(3, Material.OAK_SIGN, (player, b, b1) -> HubPlayer.getHubPlayer(player).changePreferredSize(smartGUI, gameType), LIGHT_PURPLE + (gameType == GameType.DUELS_CUSTOM ? "Size" : "Public Settings"), GRAY + (gameType == GameType.DUELS_CUSTOM ? "Change the size of the game you want to play in." : "Change the settings of your public game.")); smartGUI.add( 5, Material.COMPASS, (player, rightClick, shift) -> HubPlayer.getHubPlayer(player).partyQueue(gameType), DARK_RED + "Private " + AQUA + (gameType.getMainGame() == MainGame.MANHUNT ? "Manhunt" : gameType.getDisplaySuffix()), DARK_GRAY + RelayUtils.format("Click to play %s with your party.", gameType.getMainGame() == MainGame.MANHUNT ? "Private Manhunt" : gameType.getDisplaySuffix() + " Duels")); } else { smartGUI.add(4, Material.OAK_SIGN, (player, b, b1) -> HubPlayer.getHubPlayer(player).changePreferredSize(smartGUI, gameType), LIGHT_PURPLE + (gameType == GameType.DUELS_CUSTOM ? "Size" : "Public Settings"), GRAY + (gameType == GameType.DUELS_CUSTOM ? "Change the size of the game you want to play in." : "Change the settings of your public game.")); } for (QueueData queuedGame : queuedGames) { if (queuedGame.hasData("owner") && GameType.getGameType(queuedGame.getData("gameType")) == gameType) { List<UUID> ready = Miscellaneous.processList(Text.separateCSV(queuedGame.getData("queued")), UUID::fromString); for (QueueData game : queuedGames) { if (game.hasData("with") && game.getData("with").equals(queuedGame.getData("owner"))) { ready.addAll(Miscellaneous.processList(Text.separateCSV(game.getData("queued")), UUID::fromString)); } } Game game = getGame(queuedGame); if (gameType == GameType.DUELS_CUSTOM) { updateQueuedKit(game, queuedGame, ready); } else { updateQueuedGame(game, queuedGame, gameType, smartGUI, ready); } } } } private static void updateQueuedGame(Game game, QueueData queuedGame, GameType gameType, SmartGUI smartGUI, List<UUID> ready) { SmartPlayer owner = SmartPlayer.getOrCreate(UUID.fromString(queuedGame.getData("owner"))); if (owner == null) { Main.error("owner null for %s", queuedGame.getData("owner")); return; } ItemStack representative = gameType.getRepresentative(); int playersNeeded = queuedGame.getInt("size"); ItemStack toShow = new ItemStack(representative); List<String> playersDescription = new ArrayList<>(); playersDescription.add(""); playersDescription.add(AQUA.toString() + ready.size() + "/" + playersNeeded + DARK_AQUA + " Players"); for (UUID uuid : ready) { playersDescription.add(DARK_GRAY + SmartPlayer.getOrCreate(uuid).getName()); } if (gameType.getMainGame() == MainGame.DUELS) { int teamSize = playersNeeded / 2; List<String> description = new ArrayList<>(); if (queuedGame.hasData("map")) { description.add(YELLOW + "Map: " + GRAY + Main.getMaps(gameType).get(queuedGame.getInt("map")).getName()); } if (queuedGame.hasData("rounds")) { description.add(YELLOW + "Rounds: " + GRAY + queuedGame.getData("rounds")); } toShow = ItemUtilities.edit(toShow, DARK_GREEN + "Play " + gameType.getDisplaySuffix() + GREEN + " " + teamSize + "v" + teamSize + ".", Miscellaneous.with(description, playersDescription)); smartGUI.add(game.id, toShow, (player, b, b1) -> HubPlayer.getHubPlayer(player).onClickQueuedGame(queuedGame, gameType, playersNeeded, ready.size())); } else { int runners = queuedGame.getInt("runners"); int hunters = queuedGame.getInt("hunters"); List<String> description = new ArrayList<>(); description.add(GRAY + "Runners: " + YELLOW + runners); description.add(GRAY + "Hunters: " + YELLOW + hunters); description.add(""); if (queuedGame.hasData("release")) { description.add(GRAY + "Hunter Release: " + YELLOW + queuedGame.getInt("release") + " seconds"); } if (queuedGame.hasData("dropRate")) { int rate = queuedGame.getInt("dropRate"); description.add(GRAY + "Drops: " + YELLOW + (rate == 1 ? "Boosted" : "Normal")); } if (queuedGame.hasData("tradeRate")) { int rate = queuedGame.getInt("tradeRate"); description.add(GRAY + "Trading: " + YELLOW + (rate == 0 ? "1.16" : (rate == 1 ? "1.19" : "Boosted"))); } description.addAll(playersDescription); toShow = ItemUtilities.edit(toShow, DARK_GREEN + "Play Manhunt " + GREEN + runners + "v" + hunters, description); smartGUI.add(game.id, toShow, (player, b, b1) -> HubPlayer.getHubPlayer(player).onClickQueuedGame(queuedGame, gameType, playersNeeded, ready.size())); } } private static void updateCurrentGame(Game game, QueueData currentGame) { try { List<String> description = new ArrayList<>(); GameType gameType = GameType.getGameType(currentGame.getData("gameType")); if (currentGame.hasData("players")) { if (currentGame.hasData("map")) { description.add(DARK_GRAY + "Map: " + YELLOW + currentGame.getData("map")); } if (currentGame.hasData("rounds")) { description.add(DARK_GRAY + "Rounds Remaining: " + YELLOW + currentGame.getData("rounds")); } description.add(DARK_GRAY + "Players:"); List<String> players = Text.separateCSV(currentGame.getData("players")); for (String player : players) { description.add(YELLOW + "- " + player); } } else { if (gameType == GameType.MANHUNT_1V1) { if (currentGame.hasData("livingRunners")) { description.add(GREEN + "Runners:"); for (String livingRunner : Text.separateCSV(currentGame.getData("livingRunners"))) { description.add(DARK_GRAY + " - " + livingRunner); } if (currentGame.hasData("hunters")) { description.add(RED + "Hunters:"); for (String hunter : Text.separateCSV(currentGame.getData("hunters"))) { description.add(DARK_GRAY + " - " + hunter); } } } else { description.add(DARK_GRAY + "Pre-game"); description.add(DARK_GRAY + "Wait to spectate..."); } } else { description.add(DARK_GRAY + "Pre-game"); description.add(DARK_GRAY + "Wait to spectate..."); } } ItemStack representative = ItemUtilities.getItemStack(Material.GRAY_DYE, AQUA + BOLD.toString() + "Spectate " + (gameType.getMainGame() == MainGame.DUELS ? "Duel" : "Manhunt"), description); SmartGUI smartGUI = GAME_QUEUES.get(GameType.getGameType(currentGame.getData("gameType"))); if (smartGUI != null) { smartGUI.add(game.id, representative, (player, b, b1) -> HubPlayer.getHubPlayer(player).spectate(currentGame.getData("owner"))); } } catch (Exception e) { e.printStackTrace(); } } private static void updateQueuedKit(Game game, QueueData queuedGame, List<UUID> ready) { SmartPlayer owner = SmartPlayer.getOrCreate(UUID.fromString(queuedGame.getData("owner"))); if (owner == null) { Main.error("owner null for %s", queuedGame.getData("owner")); return; } if (!queuedGame.hasData("size")) { return; } CustomDuelsKit customDuelsKit = owner.getSelectedCustomDuelsKit(); List<String> description = new ArrayList<>(); description.add(DARK_GRAY + "Right-Click to preview"); description.add(GRAY + "Kit: " + YELLOW + (customDuelsKit == null ? "Loading..." : customDuelsKit.getKit().name)); int playersNeeded = queuedGame.getInt("size"); if (customDuelsKit != null) { String map = customDuelsKit.getMaps().get(0); if (DuelMap.getDuelMap(map) == null) { CustomMap customMap = CustomMap.CODE_TO_MAP.get(map); String val; if (customMap != null) { val = customMap.getName(); } else { val = map; } description.add(GRAY + "Map: " + YELLOW + val + DARK_AQUA + " (Custom)"); } else { description.add(GRAY + "Map: " + YELLOW + DuelMap.getDuelMap(map).getName()); } GameSettings gameSettings = HubPlayer.getDefaultCustomDuelsGameSettings(); gameSettings.applyFromJson(customDuelsKit.getGameSettings()); description.add(GRAY + "Max Rounds: " + YELLOW + gameSettings.getInteger("rounds_to_win")); description.add(GRAY + "Items:"); int itemCount = customDuelsKit.getKit().items.size(); int j = 0; for (KitItem item : customDuelsKit.getKit().items) { ItemStack itemStack = item.itemStack; int count = itemStack.getAmount(); Material material = itemStack.getType(); description.add(DARK_GRAY + "- " + Text.prettify(material) + (count > 1 ? (" x" + count) : "")); j++; if (j >= 5) break; } if (itemCount > 5) { int remaining = itemCount - 5; description.add(DARK_GRAY + "..." + remaining + " More Item" + (remaining > 1 ? "s" : "") + "..."); } description.add(""); description.add(AQUA.toString() + ready.size() + "/" + playersNeeded + DARK_AQUA + " Players"); for (UUID uuid : ready) { description.add(DARK_GRAY + SmartPlayer.getOrCreate(uuid).getName()); } } ItemStack representative = ItemUtilities.getItemStack(customDuelsKit == null ? Material.RED_BANNER : customDuelsKit.getKit().representative.itemStack.getType(), AQUA + "Play " + Text.getPossessiveName(owner.getFormattedName()) + AQUA + " Kit", description); CUSTOM_KITS_QUEUE.add(game.id, representative, (player, b, b1) -> HubPlayer.getHubPlayer(player).onClickQueuedGame(queuedGame, b, customDuelsKit, playersNeeded, ready.size())); } private static Game getGame(QueueData queueData) { GameType gameType = GameType.getGameType(queueData.getData("gameType")); for (Game game : GAMES) { if (game.ownerUUID.equals(queueData.getData("owner")) && game.gameType == gameType) { return game; } } Game game = new Game(queueData.hasData("index") ? queueData.getInt("index") : getAvailableIndex(gameType), queueData.getData("owner"), GameType.getGameType(queueData.getData("gameType"))); GAMES.add(game); return game; } public static int getAvailableIndex(GameType gameType) { for (int i = 9; i < 36; i++) { boolean canUse = true; for (Game game : GAMES) { if (game.gameType == gameType && game.id == i) { canUse = false; break; } } if (canUse) { return i; } } return 0; } private static final List<Game> GAMES = new ArrayList<>(); private record Game(int id, String ownerUUID, GameType gameType) { } }