From e9ea1b2ecf15fd6b46e8519f65925deabde56d23 Mon Sep 17 00:00:00 2001 From: Fortern Date: Mon, 27 Jan 2025 23:12:12 +0800 Subject: [PATCH] init 2 --- build.gradle.kts | 2 +- .../kotlin/xyz/fortern/minehunt/Console.kt | 75 +++++++++++++++++-- .../minehunt/listener/PlayerListener.kt | 9 ++- .../xyz/fortern/minehunt/rule/RuleItem.kt | 32 ++++++++ 4 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/xyz/fortern/minehunt/rule/RuleItem.kt diff --git a/build.gradle.kts b/build.gradle.kts index 08e49f3..0fcfff8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,7 +20,7 @@ dependencies { // Paper API compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT") // Adventure API - compileOnly("net.kyori:adventure-api:4.14.0") + compileOnly("net.kyori:adventure-api:4.18.0") // Kotlin Stdlib https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib implementation(kotlin("stdlib")) } diff --git a/src/main/kotlin/xyz/fortern/minehunt/Console.kt b/src/main/kotlin/xyz/fortern/minehunt/Console.kt index a8221ac..9eb726a 100644 --- a/src/main/kotlin/xyz/fortern/minehunt/Console.kt +++ b/src/main/kotlin/xyz/fortern/minehunt/Console.kt @@ -5,9 +5,13 @@ import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.title.Title import org.bukkit.Bukkit import org.bukkit.Difficulty +import org.bukkit.GameMode import org.bukkit.GameRule +import org.bukkit.Location +import org.bukkit.entity.Player import org.bukkit.scheduler.BukkitTask import org.bukkit.scoreboard.Team +import xyz.fortern.minehunt.rule.RuleItem /** * 游戏控制台 @@ -31,17 +35,28 @@ class Console { */ private val spectatorTeam: Team + /** + * 用于遍历的速通者列表 + */ + val speedrunnerList: MutableList = ArrayList() + + /** + * 插件维护的猎人玩家集合 + */ + val hunterSet: MutableSet = HashSet() + + /** + * 插件维护的旁观者玩家集合 + */ + val spectatorSet: MutableSet = HashSet() + /** * 猎人持有的指南针指向的速通者在speedrunnerList中的index */ val trackRunnerMap: Map = HashMap() - /** - * 用于遍历的速通者列表 - */ - val speedrunnerList: MutableList = ArrayList() - - private var countdownTask: BukkitTask? = null + var countdownTask: BukkitTask? = null + private set companion object { @JvmStatic @@ -79,15 +94,17 @@ class Console { fun tryStart(): Boolean { if (speedrunnerTeam.size == 0) return false if (Bukkit.getOnlinePlayers().count { it.isDead } > 0) return false - + countdownToStart() return true } fun countdownToStart() { + // 进行开始前的倒计时 countdownTask = Bukkit.getScheduler().runTaskTimerAsynchronously(Minehunt.instance(), object : Runnable { private var countdown = 6 override fun run() { if (--countdown > 0) { + // 倒计时期间,每秒显示一次标题 Bukkit.getOnlinePlayers().forEach { val title = Title.title( Component.text(countdown.toString(), NamedTextColor.DARK_PURPLE), @@ -96,6 +113,7 @@ class Console { it.showTitle(title) } } else { + // 倒计时结束后开始游戏 countdownTask = null start() } @@ -103,8 +121,49 @@ class Console { }, 0, 20) } + /** + * 开始游戏 + */ fun start() { - + // 修改游戏规则 + val world = Bukkit.getWorld("world")!! + world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, true) + world.setGameRule(GameRule.DO_WEATHER_CYCLE, true) + world.setGameRule(GameRule.DO_MOB_SPAWNING, true) + world.setGameRule(GameRule.KEEP_INVENTORY, false) + world.setGameRule(GameRule.SPAWN_RADIUS, 10) + world.difficulty = Difficulty.HARD + + val spawnLocation = world.spawnLocation + + // 重置所有玩家状态 + Bukkit.getOnlinePlayers().forEach { + it.gameMode = GameMode.SPECTATOR + it.health = 20.0 + it.inventory.clear() + it.saturation = 20.0f + it.foodLevel = 20 + it.level = 0 + it.teleport(spawnLocation) + } + + // 通过Team遍历玩家很麻烦 + + // 速通者更改为生存模式 + speedrunnerList.forEach { it.gameMode = GameMode.SURVIVAL } + // 将猎人传送到世界底部 + hunterSet.forEach { it.teleport(Location(world, 0.0, -64.0, 0.0)) } + + val scheduler = Bukkit.getScheduler() + val task = scheduler.runTaskTimerAsynchronously(Minehunt.instance(), Runnable { + hunterSet.forEach { + it.sendMessage(Component.text("你已到达出生点", NamedTextColor.RED)) + it.gameMode = GameMode.SURVIVAL + it.teleport(spawnLocation) + } + }, 0, RuleItem.HUNTER_READY_CD.value * 20L) + + } diff --git a/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt b/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt index a074e9e..4a170b9 100644 --- a/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt +++ b/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt @@ -20,8 +20,13 @@ class PlayerListener( val stage = console.stage if (stage == Console.GameStage.PREPARING) { player.gameMode = GameMode.ADVENTURE + console.spectatorSet.add(player) + // 在开始倒计时阶段,所有玩家都是无敌状态 + if (console.countdownTask != null) { + player.isInvulnerable = true + } } else if (stage == Console.GameStage.PROCESSING && console.speedrunnerTeam.hasEntry(player.name)) { - console.speedrunnerList.add(player.name) + console.speedrunnerList.add(player) } } @@ -32,7 +37,7 @@ class PlayerListener( if (stage == Console.GameStage.PREPARING) { player.scoreboard.teams.forEach { it.removeEntry(player.name) } } else if (stage == Console.GameStage.PROCESSING && console.speedrunnerTeam.hasEntry(player.name)) { - console.speedrunnerList.remove(player.name) + console.speedrunnerList.remove(player) } player.spigot().respawn() diff --git a/src/main/kotlin/xyz/fortern/minehunt/rule/RuleItem.kt b/src/main/kotlin/xyz/fortern/minehunt/rule/RuleItem.kt new file mode 100644 index 0000000..5d797de --- /dev/null +++ b/src/main/kotlin/xyz/fortern/minehunt/rule/RuleItem.kt @@ -0,0 +1,32 @@ +package xyz.fortern.minehunt.rule + +/** + * 描述一个规则项的类 + */ +class RuleItem( + /** + * 这项规则的名称 + */ + val name: String, + + /** + * 这项规则的描述 + */ + val info: String, + + /** + * 这项规则的具体值 + */ + val value: T +) { + /** + * 此伴生对象存放当前的游戏配置 + * + * 这些配置是可以修改的 + */ + companion object { + var HUNTER_RESPAWN_CD = RuleItem("hunter_respawn_cd", "猎人重生倒计时(秒)", 30) + var HUNTER_READY_CD = RuleItem("hunter_ready_cd", "猎人出生倒计时(秒)", 30) + var FRIENDLY_FIRE = RuleItem("friendly_fire", "队友之间是否有伤害", true) + } +}