package dev.loki.phase; import dev.loki.config.GameConfig; import dev.loki.core.GameSession; import dev.loki.player.BasePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.entity.Player; /** * Лобби-фаза: ждёт минимум 4 игроков. * При 4 игроках таймер 45 сек, при 5 — сбрасывается до 15 сек. */ public class LobbyPhase implements Phase { private final GameConfig config; private int tickSub; // счётчик тиков внутри текущей секунды private int secondsLeft; private boolean started; private boolean forced; private int lastPlayerCount; // для отслеживания изменения кол-ва игроков public LobbyPhase(GameConfig config) { this.config = config; this.secondsLeft = config.getCountdown4Players(); // начальный таймер this.tickSub = 0; this.started = false; this.forced = false; this.lastPlayerCount = 0; } @Override public void enter(GameSession session) { // Телепортируем тех кто уже в сессии (если есть) var lobbyManager = session.getPlugin().getLobbyManager(); for (var player : session.getPlayers().values()) { var p = player.getPlayer(); if (p != null && p.isOnline()) { p.setGameMode(org.bukkit.GameMode.ADVENTURE); lobbyManager.teleportToLobby(p); p.sendMessage(Component.text("[DBD] Лобби открыто! Ожидание игроков...", NamedTextColor.GREEN)); } } } @Override public void tick(GameSession session) { if (forced) { started = true; return; } int playerCount = session.getPlayerCount(); int minPlayers = config.getMinPlayers(); // 4 int maxPlayers = config.getMaxPlayers(); // 5 // Недостаточно игроков — сбрасываем таймер if (playerCount < minPlayers) { secondsLeft = config.getCountdown4Players(); tickSub = 0; lastPlayerCount = playerCount; sendActionBarToAll(session, Component.text("⏳ Ожидание игроков: " + playerCount + "/" + minPlayers, NamedTextColor.YELLOW)); return; } // Когда количество игроков меняется — обновляем нужный таймер if (playerCount != lastPlayerCount) { lastPlayerCount = playerCount; if (playerCount >= maxPlayers) { // При максимуме игроков сокращаем таймер до countdown-5-players int fast = config.getCountdown5Players(); if (secondsLeft > fast) { secondsLeft = fast; tickSub = 0; Bukkit.broadcast(Component.text( "[DBD] Все игроки вошли! Старт через " + fast + " сек!", NamedTextColor.GREEN)); } } } // Тикаем таймер tickSub++; if (tickSub >= 20) { tickSub = 0; secondsLeft--; // Анонс вслух на ключевых секундах if (secondsLeft == 30 || secondsLeft == 15 || secondsLeft == 10 || secondsLeft == 5 || secondsLeft == 3 || secondsLeft == 2 || secondsLeft == 1) { Bukkit.broadcast(Component.text( "[DBD] До начала: " + secondsLeft + " сек.", NamedTextColor.YELLOW)); } } // ActionBar всем (на русском, без прогресс-бара) NamedTextColor barColor = (playerCount >= maxPlayers) ? NamedTextColor.GREEN : NamedTextColor.YELLOW; sendActionBarToAll(session, Component.text(">>> Начало через: " + secondsLeft + "с (" + playerCount + "/" + minPlayers + ")", barColor)); if (secondsLeft <= 0) { started = true; } } private void sendActionBarToAll(GameSession session, Component msg) { for (BasePlayer bp : session.getPlayers().values()) { Player p = bp.getPlayer(); if (p != null && p.isOnline()) { p.sendActionBar(msg); } } } private String buildCountdownBar(int current, int total) { int filled = total > 0 ? (int) (10.0 * current / total) : 0; int empty = 10 - filled; return "§a" + "#".repeat(Math.max(0, filled)) + "§7" + "-".repeat(Math.max(0, empty)); } @Override public void exit(GameSession session) { for (BasePlayer bp : session.getPlayers().values()) { Player p = bp.getPlayer(); if (p != null && p.isOnline()) p.sendActionBar(Component.empty()); } Bukkit.broadcast(Component.text("[DBD] Игра начинается!", NamedTextColor.GREEN)); } @Override public void onPlayerJoined(GameSession session, Player player) { player.setGameMode(org.bukkit.GameMode.ADVENTURE); session.getPlugin().getLobbyManager().teleportToLobby(player); int playerCount = session.getPlayerCount(); int minPlayers = config.getMinPlayers(); // Сообщаем только участникам этой сессии, не всему серверу Component msg = Component.text( "[DBD] " + player.getName() + " присоединился! (" + playerCount + "/" + minPlayers + ")", NamedTextColor.YELLOW); for (BasePlayer bp : session.getPlayers().values()) { Player p = bp.getPlayer(); if (p != null && p.isOnline()) p.sendMessage(msg); } } @Override public boolean isComplete() { return started; } public void forceStart() { this.forced = true; } public int getSecondsLeft() { return secondsLeft; } }