From 78e9bfcd7462bb14055ad5e75544b0fad29e6c57 Mon Sep 17 00:00:00 2001 From: Fortern Date: Mon, 17 Feb 2025 02:47:37 +0800 Subject: [PATCH] init 10 --- build.gradle.kts | 2 +- .../kotlin/xyz/fortern/minehunt/Console.kt | 84 ++++++++++++- .../minehunt/command/MinehuntCommand.kt | 112 +++++++++++++----- 3 files changed, 165 insertions(+), 33 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0fcf278..48327f1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ repositories { dependencies { // Paper API - compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT") // https://mvnrepository.com/artifact/net.kyori/adventure-api compileOnly("net.kyori:adventure-api:4.18.0") // Kotlin Stdlib https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib diff --git a/src/main/kotlin/xyz/fortern/minehunt/Console.kt b/src/main/kotlin/xyz/fortern/minehunt/Console.kt index 19ef905..92f7ba9 100644 --- a/src/main/kotlin/xyz/fortern/minehunt/Console.kt +++ b/src/main/kotlin/xyz/fortern/minehunt/Console.kt @@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap class Console { var stage: GameStage = GameStage.PREPARING + private set private var overworld = Bukkit.getWorld("world")!! @@ -60,6 +61,16 @@ class Console { */ private val spectatorSet: MutableSet = HashSet() + /** + * 终止游戏的投票统计 + */ + private val votingEndMap: MutableMap = HashMap() + + /** + * 投票计数 + */ + private var votingCount: Int = 0 + /** * 速通者列表,用于指南针指向的遍历 */ @@ -102,6 +113,8 @@ class Console { */ private val hunterRespawnTasks: MutableMap = HashMap() + // bukkit task start + /** * 游戏开始前的倒计时任务 */ @@ -119,6 +132,13 @@ class Console { */ private var compassRefreshTask: BukkitTask? = null + /** + * 投票倒计时 + */ + private var voteTask: BukkitTask? = null + + // bukkit task end + companion object { @JvmStatic private lateinit var instance: Console @@ -209,7 +229,7 @@ class Console { * 游戏开始前的倒计时 */ private fun countdownToStart() { - beginningCountdown = Bukkit.getScheduler().runTaskTimerAsynchronously(Minehunt.instance(), object : Runnable { + beginningCountdown = Bukkit.getScheduler().runTaskTimer(Minehunt.instance(), object : Runnable { private var countdown = 6 override fun run() { if (--countdown > 0) { @@ -236,7 +256,7 @@ class Console { * * 游戏阶段由 PREPARING 变为 PROCESSING */ - fun start() { + private fun start() { if (speedrunnerSet.isEmpty()) throw RuntimeException("No Speedrunner") // 修改游戏规则 @@ -299,7 +319,7 @@ class Console { } // 猎人出生倒计时Task - hunterSpawnCD = Bukkit.getScheduler().runTaskTimer(Minehunt.instance(), Runnable { + hunterSpawnCD = Bukkit.getScheduler().runTaskLater(Minehunt.instance(), Runnable { // 猎人设置初始状态 hunterSet.forEach { it.sendMessage(Component.text("你已到达出生点", NamedTextColor.RED)) @@ -313,14 +333,68 @@ class Console { // 通知速通者 speedrunnerSet.forEach { it.sendMessage(Component.text("猎人开始追杀", NamedTextColor.RED)) } - }, RuleItem.HUNTER_READY_CD.value * 20L, 0) + }, RuleItem.HUNTER_READY_CD.value * 20L) } + /** + * 投票结束游戏 + */ + fun voteForStop(player: Player) { + if (stage != GameStage.PROCESSING) { + player.sendMessage(Component.text("只有游戏中才能投票", NamedTextColor.RED)) + return + } + if (!isHunter(player) && !isSpeedrunner(player)) { + player.sendMessage(Component.text("只有游戏中的玩家才能投票")) + return + } + val name = player.name + if (voteTask == null) { + // 投票发起 + voteTask = Bukkit.getScheduler().runTaskLater(Minehunt.instance(), Runnable { + voteTask = null + votingEndMap.clear() + votingCount = 0 + }, 60) + // 统计参与投票的玩家 + speedrunnerSet.forEach { + // 生存模式的速通者统计进来 + if (it.isOnline && it.gameMode == GameMode.SURVIVAL) { + votingEndMap[it.name] = false + } + } + hunterSet.forEach { + if (it.isOnline) { + votingEndMap[it.name] = false + } + } + Bukkit.getOnlinePlayers().forEach { + it.sendMessage(Component.text("${name}发起了终止游戏的投,如果赞成请在60秒内执行 /minehunt stop")) + } + } + // 玩家投票 + if (!votingEndMap.containsKey(name)) { + player.sendMessage(Component.text("你不在可投票的名单中", NamedTextColor.RED)) + return + } + votingEndMap[name] = true + votingCount++ + player.sendMessage(Component.text("voting (${votingCount}/${votingEndMap.size})", NamedTextColor.RED)) + if (votingCount != votingEndMap.size) { + return + } + // 投票完成,游戏结束 + Bukkit.getOnlinePlayers().forEach { + it.sendMessage(Component.text("投票完成,游戏结束", NamedTextColor.GOLD)) + } + end() + } + /** * 结束处理 */ - fun end() { + private fun end() { // TODO 延迟传送至出生点 // 取消剩余的复活任务 diff --git a/src/main/kotlin/xyz/fortern/minehunt/command/MinehuntCommand.kt b/src/main/kotlin/xyz/fortern/minehunt/command/MinehuntCommand.kt index 4f90234..4e9d454 100644 --- a/src/main/kotlin/xyz/fortern/minehunt/command/MinehuntCommand.kt +++ b/src/main/kotlin/xyz/fortern/minehunt/command/MinehuntCommand.kt @@ -1,19 +1,22 @@ package xyz.fortern.minehunt.command import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.command.TabExecutor +import org.bukkit.entity.Player import xyz.fortern.minehunt.Console /** * 主命令 minehunt */ class MinehuntCommand( - val console: Console + private val console: Console ) : TabExecutor { private val subCommand: List = listOf("help", "join", "leave", "rule", "stat", "stop") + private val teams: List = listOf("hunter", "speedrunner", "spectator") /** * 执行命令 @@ -60,21 +63,21 @@ class MinehuntCommand( } "leave" -> { - onLeave(sender, args, flag) - } - - "start" -> { - onStart(sender, args, flag) - } - - "stop" -> { - onStop(sender, args, flag) + onLeave(sender, flag) } "rule" -> { onRule(sender, args, flag) } + "start" -> { + onStart(sender, flag) + } + + "stop" -> { + onStop(sender, flag) + } + else -> { if (flag) { sender.sendMessage(Component.text("错误的子命令")) @@ -87,38 +90,93 @@ class MinehuntCommand( } /** - * 查看或修改游戏规则 + * 玩家加入队伍 */ - private fun onRule(sender: CommandSender, args: List, execute: Boolean): List? { - TODO("Not yet implemented") + private fun onJoin(sender: CommandSender, args: List, flag: Boolean): List? { + if (args.size == 1) { + if (flag) { + sender.sendMessage(Component.text("输入正确的队伍名称", NamedTextColor.RED)) + } + return null + } + val teamName = args[1] + if (flag) { + if (sender !is Player) { + sender.sendMessage(Component.text("The sender is not a player.", NamedTextColor.RED)) + return null + } + when (teamName) { + "hunter" -> { + console.joinHunter(sender) + } + "speedrunner" -> { + console.joinSpeedrunner(sender) + } + "spectator" -> { + console.joinSpectator(sender) + } + else -> { + sender.sendMessage(Component.text("输入正确的队伍名称", NamedTextColor.RED)) + } + } + return null + } else { + if (args.size == 2) { + return teams.filter { it.startsWith(args[0]) } + } + } + + return null } /** - * 游戏结束 + * 玩家离开队伍 */ - private fun onStop(sender: CommandSender, args: List, execute: Boolean): List? { + private fun onLeave(sender: CommandSender, flag: Boolean): List? { + if (flag) { + if (sender !is Player) { + sender.sendMessage(Component.text("The sender is not a player.", NamedTextColor.RED)) + } else { + console.joinSpectator(sender) + } + } + return null + } + + /** + * 查看或修改游戏规则 + */ + private fun onRule(sender: CommandSender, args: List, flag: Boolean): List? { TODO("Not yet implemented") } /** * 游戏开始 */ - private fun onStart(sender: CommandSender, args: List, execute: Boolean): List? { - TODO("Not yet implemented") + private fun onStart(sender: CommandSender, flag: Boolean): List? { + if (flag) { + // TODO 正在编辑规则时,也不能开始 + if (console.stage == Console.GameStage.PREPARING) { + console.tryStart() + } else { + sender.sendMessage("游戏已经开始或已经结束") + } + } + return null } /** - * 玩家离开队伍 + * 游戏结束 */ - private fun onLeave(sender: CommandSender, args: List, execute: Boolean): List? { - TODO("Not yet implemented") - } - - /** - * 玩家加入队伍 - */ - private fun onJoin(sender: CommandSender, args: List, execute: Boolean): List? { - TODO("Not yet implemented") + private fun onStop(sender: CommandSender, flag: Boolean): List? { + if (flag) { + if (sender is Player) { + console.voteForStop(sender) + } else { + sender.sendMessage(Component.text("只有游戏中的玩家才能投票")) + } + } + return null } /**