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

@@ -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<Player> = ArrayList()
/**
* 插件维护的猎人玩家集合
*/
val hunterSet: MutableSet<Player> = HashSet()
/**
* 插件维护的旁观者玩家集合
*/
val spectatorSet: MutableSet<Player> = HashSet()
/**
* 猎人持有的指南针指向的速通者在speedrunnerList中的index
*/
val trackRunnerMap: Map<String, Int> = HashMap()
/**
* 用于遍历的速通者列表
*/
val speedrunnerList: MutableList<String> = 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)
}

View File

@@ -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()

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)
}
}