diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/CommandManager.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/CommandManager.kt index c66fdea..4f03509 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/CommandManager.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/CommandManager.kt @@ -5,7 +5,6 @@ import de.moritzruth.spigot_ttt.game.InfoCommand import de.moritzruth.spigot_ttt.game.ReviveCommand import de.moritzruth.spigot_ttt.game.StartCommand import de.moritzruth.spigot_ttt.game.worlds.AddSpawnLocationCommand -import de.moritzruth.spigot_ttt.game.worlds.VotingCommand object CommandManager { fun initializeCommands() { @@ -16,6 +15,5 @@ object CommandManager { ResourcepackCommand() ReloadTTTConfigCommand() InfoCommand() - VotingCommand() } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/AbortCommand.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/AbortCommand.kt index ddd7059..38c1538 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/AbortCommand.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/AbortCommand.kt @@ -1,6 +1,7 @@ package de.moritzruth.spigot_ttt.game import de.moritzruth.spigot_ttt.COMMAND_RESPONSE_PREFIX +import de.moritzruth.spigot_ttt.game.worlds.MapVoting import de.moritzruth.spigot_ttt.plugin import de.moritzruth.spigot_ttt.utils.EmptyTabCompleter import org.bukkit.ChatColor @@ -18,10 +19,10 @@ class AbortCommand: CommandExecutor { override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { if (GameManager.phase == null) { - val tttWorld = GameManager.tttWorld - if (tttWorld == null) + val voting = MapVoting.current + if (voting == null) sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Zurzeit läuft kein Spiel.") - else tttWorld.unload() + else voting.cancel() } else GameManager.abortGame(true) return true diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/GameManager.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/GameManager.kt index 5c5f89d..b2ea34e 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/GameManager.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/GameManager.kt @@ -95,8 +95,13 @@ object GameManager { } fun reset() { - CorpseManager.destroyAll() - ItemManager.reset() + val tttWorld = tttWorld + if (tttWorld != null) { + CorpseManager.destroyAll() + ItemManager.reset() + tttWorld.unload() + this.tttWorld = null + } } fun abortGame(broadcast: Boolean = false) { @@ -108,9 +113,7 @@ object GameManager { PlayerManager.resetAfterGame() reset() - if (broadcast) { - GameMessenger.aborted() - } + if (broadcast) GameMessenger.aborted() } fun startPreparingPhase() { diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/StartCommand.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/StartCommand.kt index 87cbd35..45ce766 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/StartCommand.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/StartCommand.kt @@ -2,6 +2,7 @@ package de.moritzruth.spigot_ttt.game import de.moritzruth.spigot_ttt.COMMAND_RESPONSE_PREFIX import de.moritzruth.spigot_ttt.game.players.PlayerManager +import de.moritzruth.spigot_ttt.game.worlds.MapVoting import de.moritzruth.spigot_ttt.plugin import de.moritzruth.spigot_ttt.utils.EmptyTabCompleter import org.bukkit.ChatColor @@ -17,20 +18,19 @@ class StartCommand: CommandExecutor { } override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { - if (GameManager.phase === null) { - if (GameManager.tttWorld == null) { - sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Bitte starte zuerst das Map-Voting mit " + - "${ChatColor.WHITE}/voting") + if (GameManager.phase == null) { + val voting = MapVoting.current - return true - } - - try { - GameManager.startPreparingPhase() - } catch (e: PlayerManager.NotEnoughPlayersException) { - sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Es sind nicht genügend Spieler online. " + - "\nBenötigt: ${ChatColor.WHITE}${e.required}${ChatColor.RED}\nTatsächlich: ${ChatColor.WHITE}${e.actual}") - } + if (voting == null) { + try { + PlayerManager.checkEnoughPlayers() + MapVoting.start() + } catch (e: PlayerManager.NotEnoughPlayersException) { + sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Es sind nicht genügend Spieler " + + "online.\nBenötigt: ${ChatColor.WHITE}${e.required}${ChatColor.RED}" + + "\nTatsächlich: ${ChatColor.WHITE}${e.actual}") + } + } else sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Das Map-Voting läuft bereits.") } else { sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Das Spiel läuft bereits.") } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt index dbdf708..0f5e485 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt @@ -21,7 +21,7 @@ object PlayerManager { val tttPlayers = mutableListOf() fun isAvailable(player: Player): Boolean { - return player.gameMode === GameMode.SURVIVAL + return player.gameMode == GameMode.SURVIVAL || player.gameMode == GameMode.CREATIVE } fun getAvailablePlayers() = plugin.server.onlinePlayers.filter { isAvailable(it) } @@ -64,6 +64,7 @@ object PlayerManager { player.teleportToWorldSpawn() player.gameMode = GameMode.SURVIVAL } else { + player.teleport(GameManager.world.spawnLocation) player.gameMode = GameMode.SPECTATOR playersJoinedDuringRound.add(player) player.sendMessage("${TTTPlugin.prefix}${ChatColor.GREEN}Du schaust jetzt zu.") @@ -99,10 +100,7 @@ object PlayerManager { } } - fun createTTTPlayers() { - val playersWithoutRole = getAvailablePlayers().toMutableSet() - val playerCount = playersWithoutRole.count() - + fun checkEnoughPlayers(playerCount: Int = getAvailablePlayers().count()) { if (Settings.traitorCount < 1) throw IllegalStateException("roles.traitor.count may not be lower than 1") var requiredPlayerCount = Settings.traitorCount @@ -110,6 +108,12 @@ object PlayerManager { if (Settings.jackalMode != JackalMode.NEVER) requiredPlayerCount += 1 requiredPlayerCount += 1 // Innocent if (playerCount < requiredPlayerCount) throw NotEnoughPlayersException(playerCount, requiredPlayerCount) + } + + fun createTTTPlayers() { + val playersWithoutRole = getAvailablePlayers().toMutableSet() + val playerCount = playersWithoutRole.count() + checkEnoughPlayers(playerCount) val classesIterator = TTTClassManager.createClassesIterator(playerCount) diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/MapVoting.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/MapVoting.kt index 44aae0d..96318be 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/MapVoting.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/MapVoting.kt @@ -1,7 +1,6 @@ package de.moritzruth.spigot_ttt.game.worlds import de.moritzruth.spigot_ttt.Settings -import de.moritzruth.spigot_ttt.TTTPlugin import de.moritzruth.spigot_ttt.game.GameManager import de.moritzruth.spigot_ttt.game.players.PlayerManager import de.moritzruth.spigot_ttt.plugin @@ -25,7 +24,7 @@ import kotlin.math.max class MapVoting private constructor() { private var secondsRemaining = Settings.mapVotingDuration private val maps = WorldManager.tttWorlds.toList() - private var timerTask: BukkitTask + private var timerTask: BukkitTask? = null private val inventory = plugin.server.createInventory( null, @@ -48,22 +47,27 @@ class MapVoting private constructor() { } init { - maps.forEachIndexed { index, map -> inventory.setItem(index, createMapItemStack(map)) } + when (maps.count()) { + 0 -> throw Error("There are no worlds available") + 1 -> finish(maps[0]) + else -> { + current = this + maps.forEachIndexed { index, map -> inventory.setItem(index, createMapItemStack(map)) } - timerTask = plugin.server.scheduler.runTaskTimer(plugin, fun() { - if (secondsRemaining == 0) { - finish() - } else { - inventory.setItem(26, ItemStack(Material.CLOCK, secondsRemaining).applyMeta { - setDisplayName("${ChatColor.GREEN}Verbleibende Zeit: ${ChatColor.WHITE}${secondsRemaining}s") - }) - secondsRemaining -= 1 + timerTask = plugin.server.scheduler.runTaskTimer(plugin, fun() { + if (secondsRemaining == 0) { + finish() + } else { + inventory.setItem(26, ItemStack(Material.CLOCK, secondsRemaining).applyMeta { + setDisplayName("${ChatColor.GREEN}Verbleibende Zeit: ${ChatColor.WHITE}${secondsRemaining}s") + }) + secondsRemaining -= 1 + } + }, 0, secondsToTicks(1).toLong()) + + PlayerManager.getAvailablePlayers().forEach(::giveVoteItem) + plugin.broadcast("${ChatColor.GREEN}Das Map-Voting wurde gestartet.") } - }, 0, secondsToTicks(1).toLong()) - - PlayerManager.getAvailablePlayers().forEach { - giveVoteItem(it) - it.sendMessage("${TTTPlugin.prefix}${ChatColor.GREEN}Das Map-Voting wurde gestartet.") } } @@ -75,14 +79,12 @@ class MapVoting private constructor() { } fun cancel() { - PlayerManager.getAvailablePlayers().forEach { - it.sendMessage("${TTTPlugin.prefix}${ChatColor.RED}Das Map-Voting wurde abgebrochen.") - } + plugin.broadcast("${ChatColor.RED}Das Map-Voting wurde abgebrochen.") stop() } private fun stop() { - timerTask.cancel() + timerTask?.cancel() current = null PlayerManager.getAvailablePlayers().forEach { removeVoteItem(it) } plugin.server.onlinePlayers.forEach { if (it.openInventory.topInventory === inventory) it.closeInventory() } @@ -95,14 +97,21 @@ class MapVoting private constructor() { else votedMaps.sortedBy { votedMap -> votedMaps.count { it === votedMap } }[0] } - plugin.broadcast("${ChatColor.GREEN}Ausgewählte Map: " + - winnerMap.config.getString("title")) + if (runCatching { PlayerManager.checkEnoughPlayers() }.isFailure) { + plugin.broadcast( + "${ChatColor.RED}Das Spiel konnte nicht gestartet werden, da nicht genügend " + + "Spieler online sind." + ) + } else { + plugin.broadcast("${ChatColor.GREEN}Ausgewählte Map: " + + winnerMap.config.getString("title")) - if (winnerMap.world != null) winnerMap.unload() - winnerMap.load() - GameManager.tttWorld = winnerMap - plugin.server.onlinePlayers.forEach { - it.teleport(winnerMap.world!!.spawnLocation) + if (winnerMap.world != null) winnerMap.unload() + winnerMap.load() + + GameManager.tttWorld = winnerMap + plugin.server.onlinePlayers.forEach { it.teleport(winnerMap.world!!.spawnLocation) } + GameManager.startPreparingPhase() } } @@ -124,7 +133,7 @@ class MapVoting private constructor() { fun start(): MapVoting? { if (current != null) throw IllegalStateException("There is already a map voting in progress") - return MapVoting().also { current = it } + return MapVoting() } private val listener = object : Listener { diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/VotingCommand.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/VotingCommand.kt deleted file mode 100644 index 0d0ce05..0000000 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/worlds/VotingCommand.kt +++ /dev/null @@ -1,45 +0,0 @@ -package de.moritzruth.spigot_ttt.game.worlds - -import de.moritzruth.spigot_ttt.COMMAND_RESPONSE_PREFIX -import de.moritzruth.spigot_ttt.game.GameManager -import de.moritzruth.spigot_ttt.game.GamePhase -import de.moritzruth.spigot_ttt.plugin -import de.moritzruth.spigot_ttt.utils.EmptyTabCompleter -import org.bukkit.ChatColor -import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor -import org.bukkit.command.CommandSender - -class VotingCommand: CommandExecutor { - init { - val command = plugin.getCommand("voting")!! - command.setExecutor(this) - command.tabCompleter = EmptyTabCompleter - } - - override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { - if (args.count() == 1 && args[0].equals("cancel", true)) { - val voting = MapVoting.current - if (voting == null) { - sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Zurzeit läuft kein Map-Voting.") - } else { - voting.cancel() - } - - return true - } - - if (MapVoting.current == null) { - if (GameManager.phase == null || GameManager.phase == GamePhase.OVER) { - MapVoting.start() - } else { - sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Du kannst das Map-Voting nicht starten, " + - "während das Spiel läuft.") - } - } else { - sender.sendMessage("$COMMAND_RESPONSE_PREFIX${ChatColor.RED}Es läuft bereits ein Map-Voting.") - } - - return true - } -} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 31aa46a..7033ebc 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,20 +8,15 @@ depend: - ArmorEquipEvent commands: - voting: - usage: /voting ['cancel'] - permission: ttt.voting - description: Start (or cancel) the map voting - start: usage: /start permission: ttt.start - description: Start the TTT game + description: Start the map voting abort: usage: /abort permission: ttt.abort - description: Go back to the lobby world and abort the TTT game, if it is running + description: Cancel the map voting or the current game addspawnlocation: usage: /addspawnlocation <'item'|'player'>