This commit is contained in:
2025-01-27 23:12:12 +08:00
parent e27f4ddb5c
commit e9ea1b2ecf
4 changed files with 107 additions and 11 deletions

View File

@@ -20,7 +20,7 @@ dependencies {
// Paper API // Paper API
compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT") compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT")
// Adventure API // 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 // Kotlin Stdlib https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
} }

View File

@@ -5,9 +5,13 @@ import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.title.Title import net.kyori.adventure.title.Title
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.Difficulty import org.bukkit.Difficulty
import org.bukkit.GameMode
import org.bukkit.GameRule import org.bukkit.GameRule
import org.bukkit.Location
import org.bukkit.entity.Player
import org.bukkit.scheduler.BukkitTask import org.bukkit.scheduler.BukkitTask
import org.bukkit.scoreboard.Team import org.bukkit.scoreboard.Team
import xyz.fortern.minehunt.rule.RuleItem
/** /**
* 游戏控制台 * 游戏控制台
@@ -31,17 +35,28 @@ class Console {
*/ */
private val spectatorTeam: Team private val spectatorTeam: Team
/**
* 用于遍历的速通者列表
*/
val speedrunnerList: MutableList<Player> = ArrayList()
/**
* 插件维护的猎人玩家集合
*/
val hunterSet: MutableSet<Player> = HashSet()
/**
* 插件维护的旁观者玩家集合
*/
val spectatorSet: MutableSet<Player> = HashSet()
/** /**
* 猎人持有的指南针指向的速通者在speedrunnerList中的index * 猎人持有的指南针指向的速通者在speedrunnerList中的index
*/ */
val trackRunnerMap: Map<String, Int> = HashMap() val trackRunnerMap: Map<String, Int> = HashMap()
/** var countdownTask: BukkitTask? = null
* 用于遍历的速通者列表 private set
*/
val speedrunnerList: MutableList<String> = ArrayList()
private var countdownTask: BukkitTask? = null
companion object { companion object {
@JvmStatic @JvmStatic
@@ -79,15 +94,17 @@ class Console {
fun tryStart(): Boolean { fun tryStart(): Boolean {
if (speedrunnerTeam.size == 0) return false if (speedrunnerTeam.size == 0) return false
if (Bukkit.getOnlinePlayers().count { it.isDead } > 0) return false if (Bukkit.getOnlinePlayers().count { it.isDead } > 0) return false
countdownToStart()
return true return true
} }
fun countdownToStart() { fun countdownToStart() {
// 进行开始前的倒计时
countdownTask = Bukkit.getScheduler().runTaskTimerAsynchronously(Minehunt.instance(), object : Runnable { countdownTask = Bukkit.getScheduler().runTaskTimerAsynchronously(Minehunt.instance(), object : Runnable {
private var countdown = 6 private var countdown = 6
override fun run() { override fun run() {
if (--countdown > 0) { if (--countdown > 0) {
// 倒计时期间,每秒显示一次标题
Bukkit.getOnlinePlayers().forEach { Bukkit.getOnlinePlayers().forEach {
val title = Title.title( val title = Title.title(
Component.text(countdown.toString(), NamedTextColor.DARK_PURPLE), Component.text(countdown.toString(), NamedTextColor.DARK_PURPLE),
@@ -96,6 +113,7 @@ class Console {
it.showTitle(title) it.showTitle(title)
} }
} else { } else {
// 倒计时结束后开始游戏
countdownTask = null countdownTask = null
start() start()
} }
@@ -103,7 +121,48 @@ class Console {
}, 0, 20) }, 0, 20)
} }
/**
* 开始游戏
*/
fun start() { 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)
} }

View File

@@ -20,8 +20,13 @@ class PlayerListener(
val stage = console.stage val stage = console.stage
if (stage == Console.GameStage.PREPARING) { if (stage == Console.GameStage.PREPARING) {
player.gameMode = GameMode.ADVENTURE 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)) { } 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) { if (stage == Console.GameStage.PREPARING) {
player.scoreboard.teams.forEach { it.removeEntry(player.name) } player.scoreboard.teams.forEach { it.removeEntry(player.name) }
} else if (stage == Console.GameStage.PROCESSING && console.speedrunnerTeam.hasEntry(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() player.spigot().respawn()

View File

@@ -0,0 +1,32 @@
package xyz.fortern.minehunt.rule
/**
* 描述一个规则项的类
*/
class RuleItem<T>(
/**
* 这项规则的名称
*/
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)
}
}