From 2a8f395ae9d047e04a1bc233559cc193a66cd3ae Mon Sep 17 00:00:00 2001 From: Fortern Date: Tue, 11 Feb 2025 01:36:48 +0800 Subject: [PATCH] init 7 --- .../kotlin/xyz/fortern/minehunt/Console.kt | 94 ++++++++++++++----- .../minehunt/listener/PlayerListener.kt | 20 ++-- 2 files changed, 78 insertions(+), 36 deletions(-) diff --git a/src/main/kotlin/xyz/fortern/minehunt/Console.kt b/src/main/kotlin/xyz/fortern/minehunt/Console.kt index 5c5888a..2fccc70 100644 --- a/src/main/kotlin/xyz/fortern/minehunt/Console.kt +++ b/src/main/kotlin/xyz/fortern/minehunt/Console.kt @@ -3,12 +3,7 @@ package xyz.fortern.minehunt import net.kyori.adventure.text.Component 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.Material +import org.bukkit.* import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack @@ -26,6 +21,8 @@ class Console { var stage: GameStage = GameStage.PREPARING + var overworld = Bukkit.getWorld("world")!! + /** * 速通者队伍 */ @@ -95,6 +92,11 @@ class Console { itemMeta.addEnchant(Enchantment.VANISHING_CURSE, 1, false) } + /** + * 猎人重生Task,保留这些引用方便在游戏结束时取消这些任务 + */ + private val hunterRespawnTasks: MutableMap = HashMap() + /** * 游戏开始前的倒计时任务 */ @@ -123,15 +125,14 @@ class Console { init { instance = this // 初始化游戏规则 - val world = Bukkit.getWorld("world")!! - world.worldBorder.size = 32.0 - world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false) - world.setGameRule(GameRule.DO_WEATHER_CYCLE, false) - world.setGameRule(GameRule.DO_MOB_SPAWNING, false) - world.setGameRule(GameRule.KEEP_INVENTORY, true) - world.setGameRule(GameRule.SPAWN_RADIUS, 0) - world.setGameRule(GameRule.SPECTATORS_GENERATE_CHUNKS, false) - world.difficulty = Difficulty.HARD + overworld.worldBorder.size = 32.0 + overworld.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false) + overworld.setGameRule(GameRule.DO_WEATHER_CYCLE, false) + overworld.setGameRule(GameRule.DO_MOB_SPAWNING, false) + overworld.setGameRule(GameRule.KEEP_INVENTORY, true) + overworld.setGameRule(GameRule.SPAWN_RADIUS, 0) + overworld.setGameRule(GameRule.SPECTATORS_GENERATE_CHUNKS, false) + overworld.difficulty = Difficulty.HARD // 初始化队伍 val scoreboard = Bukkit.getScoreboardManager().mainScoreboard @@ -202,7 +203,7 @@ class Console { /** * 游戏开始前的倒计时 */ - fun countdownToStart() { + private fun countdownToStart() { beginningCountdown = Bukkit.getScheduler().runTaskTimerAsynchronously(Minehunt.instance(), object : Runnable { private var countdown = 6 override fun run() { @@ -262,7 +263,7 @@ class Console { // 将猎人传送到世界底部,且指南针开始有所指向 hunterSet.forEach { it.teleport(Location(world, 0.0, -64.0, 0.0)) - trackRunnerMap.put(it.name, 0) + trackRunnerMap[it.name] = 0 } // 创建指南针更新任务 @@ -270,17 +271,17 @@ class Console { override fun run() { hunterSet.forEach { if (!it.isOnline) return@forEach - var i = (trackRunnerMap[it.name] ?: return@forEach) % speedrunnerList.size + val i = (trackRunnerMap[it.name] ?: return@forEach) % speedrunnerList.size val speedrunner = speedrunnerList[i] val items = it.inventory.all(hunterCompass) var flag = false - items.forEach { k, v -> + items.forEach { (k, v) -> val lore = v.lore() // 避免玩家身上有多个猎人指南针 if (flag) { it.inventory.clear(k) } - if (lore != null && lore.isNotEmpty() && lore[0].equals(compassFlag)) { + if (!lore.isNullOrEmpty() && lore[0].equals(compassFlag)) { flag = true // 让指南针指向某一个猎人 val meta = v.itemMeta as CompassMeta @@ -311,6 +312,26 @@ class Console { } + /** + * 结束处理 + */ + fun end() { + // TODO 延迟传送至出生点 + + // 取消剩余的复活任务 + val iterator = hunterRespawnTasks.iterator() + while (iterator.hasNext()) { + iterator.next().value.cancel() + iterator.remove() + } + // 所有人传送至出生点,设为生存模式 + Bukkit.getOnlinePlayers().forEach { + it.gameMode = GameMode.SURVIVAL + it.teleport(overworld.spawnLocation) + } + stage = GameStage.OVER + } + /** * 判断物品是否为猎人指南针 */ @@ -321,16 +342,37 @@ class Console { */ fun trackNextPlayer(playerName: String) { if (stage != GameStage.PROCESSING) return - var i = trackRunnerMap[playerName] ?: return + val i = trackRunnerMap[playerName] ?: return + if (speedrunnerList.isEmpty()) return + + var j = i while (true) { - i++ - i %= speedrunnerList.size + j++ + j %= speedrunnerList.size val speedrunner = speedrunnerList[i] - if (speedrunner.gameMode == GameMode.SURVIVAL) { - continue + if (speedrunner.gameMode == GameMode.SURVIVAL && speedrunner.isOnline || i == j) { + trackRunnerMap[playerName] = j + break } } - trackRunnerMap[playerName] = i % speedrunnerList.size + } + + /** + * 处理玩家死亡 + */ + fun handlePlayerDeath(player: Player) { + if (isHunter(player)) { + // 猎人置为旁观者模式 + player.gameMode = GameMode.SPECTATOR + } else if (isSpeedrunner(player)) { + // 猎人置为旁观者模式 + player.gameMode = GameMode.SPECTATOR + val task = Bukkit.getScheduler().runTaskLater(Minehunt.instance(), Runnable { + player.gameMode = GameMode.SURVIVAL + hunterRespawnTasks.remove(player) + }, 20) + hunterRespawnTasks[player] = task + } } /** diff --git a/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt b/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt index 68b11f9..37a70e4 100644 --- a/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt +++ b/src/main/kotlin/xyz/fortern/minehunt/listener/PlayerListener.kt @@ -54,16 +54,14 @@ class PlayerListener( } /** - * 玩家丢弃物品时,阻止玩家丢弃猎人指南针 + * 玩家丢弃物品时,阻止玩家丢弃猎人指南针,并将追踪目标切换到下一个 */ @EventHandler fun onDropItem(event: PlayerDropItemEvent) { val itemStack = event.itemDrop.itemStack - if (!console.isHunterCompass(itemStack)) { - return - } - val player = event.player -// console.trackRunnerMap[player.name] = 0 + if (!console.isHunterCompass(itemStack)) return + + console.trackNextPlayer(event.player.name) } /** @@ -73,18 +71,20 @@ class PlayerListener( fun onPlayerMove(event: PlayerMoveEvent) { // 暂且通过取消事件的方法阻止玩家移动 if (console.stage != GameStage.PROCESSING) return + val player = event.player // 猎人等待出生时,或等待复活时,阻止其移动 if (console.isHunter(player) && (console.hunterSpawnCD != null || player.gameMode == GameMode.SPECTATOR)) event.isCancelled = true } + /** + * 处理玩家死亡事件 + */ + @EventHandler fun onPlayerDeath(event: PlayerDeathEvent) { val player = event.entity - if (console.isHunter(player)) { - // 猎人置为旁观者模式 - player.gameMode = GameMode.SPECTATOR - } + console.handlePlayerDeath(player) } }