This commit is contained in:
2025-02-21 03:51:35 +08:00
parent b8d5e5aa70
commit 989bbf85e3
7 changed files with 150 additions and 44 deletions

2
.gitignore vendored
View File

@@ -7,7 +7,7 @@
# IntelliJ # IntelliJ
out/ out/
.kotlin/
# Compiled class file # Compiled class file
*.class *.class

View File

@@ -11,11 +11,12 @@ import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.CompassMeta import org.bukkit.inventory.meta.CompassMeta
import org.bukkit.scheduler.BukkitRunnable import org.bukkit.scheduler.BukkitRunnable
import org.bukkit.scheduler.BukkitTask import org.bukkit.scheduler.BukkitTask
import org.bukkit.scoreboard.Criteria
import org.bukkit.scoreboard.DisplaySlot
import org.bukkit.scoreboard.Team import org.bukkit.scoreboard.Team
import xyz.fortern.minehunt.rule.GameRules import xyz.fortern.minehunt.rule.GameRules
import xyz.fortern.minehunt.rule.RuleKey import xyz.fortern.minehunt.rule.RuleKey
@@ -32,11 +33,20 @@ class Console {
*/ */
val gameRules = GameRules() val gameRules = GameRules()
val ruleBook = Bukkit.createInventory(null, InventoryType.HOPPER, Component.text("Game Rules")) /**
* 游戏阶段
*/
var stage: GameStage = GameStage.PREPARING var stage: GameStage = GameStage.PREPARING
private set private set
/**
* 计分板
*/
private val scoreboard = Bukkit.getScoreboardManager().mainScoreboard
/**
* 主世界
*/
private var overworld = Bukkit.getWorld("world")!! private var overworld = Bukkit.getWorld("world")!!
/** /**
@@ -164,7 +174,8 @@ class Console {
init { init {
instance = this instance = this
// 初始化游戏规则 setRuleScoreboard()
// 初始化 Minecraft 游戏规则
overworld.worldBorder.size = 32.0 overworld.worldBorder.size = 32.0
overworld.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false) overworld.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false)
overworld.setGameRule(GameRule.DO_WEATHER_CYCLE, false) overworld.setGameRule(GameRule.DO_WEATHER_CYCLE, false)
@@ -475,6 +486,43 @@ class Console {
} }
} }
private fun setRuleScoreboard() {
//清除旧的计分板信息
scoreboard.teams.forEach { it.unregister() }
val objective = scoreboard.getObjective("rule-list")
objective?.unregister()
//设置新的计分板信息
val ruleListObjective = scoreboard.registerNewObjective(
"rule-list",
Criteria.DUMMY,
Component.text("游戏规则", NamedTextColor.DARK_AQUA)
)
val rules = gameRules.getAllRules()
rules.onEachIndexed { i, entry ->
val entryId = entry.key.name
val score = ruleListObjective.getScore(entryId)
.apply { customName(Component.text(entry.key.info, NamedTextColor.GOLD)) }
score.score = rules.size - i
val teamForOneRule = scoreboard.registerNewTeam(entryId)
teamForOneRule.addEntry(entryId)
teamForOneRule.suffix(
Component.text(": ").append(Component.text(entry.value.toString(), NamedTextColor.GREEN))
)
}
ruleListObjective.displaySlot = DisplaySlot.SIDEBAR
}
fun refreshEntry(ruleKey: RuleKey<*>) {
val teamForOneRule = scoreboard.getTeam(ruleKey.name) ?: return
teamForOneRule.suffix(
Component.text(": ").append(
Component.text(gameRules.getRuleValue(ruleKey).toString(), NamedTextColor.GREEN)
)
)
}
/** /**
* 游戏阶段 * 游戏阶段
*/ */

View File

@@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender
import org.bukkit.command.TabExecutor import org.bukkit.command.TabExecutor
import org.bukkit.entity.Player import org.bukkit.entity.Player
import xyz.fortern.minehunt.Console import xyz.fortern.minehunt.Console
import xyz.fortern.minehunt.Minehunt
import xyz.fortern.minehunt.rule.RuleKey import xyz.fortern.minehunt.rule.RuleKey
/** /**
@@ -16,12 +17,31 @@ class MinehuntCommand(
private val console: Console private val console: Console
) : TabExecutor { ) : TabExecutor {
private val subCommand: List<String> = listOf("help", "join", "leave", "rule", "stat", "stop") private val subCommands: List<String> = listOf("help", "join", "leave", "rule", "stat", "stop")
private val teams: List<String> = listOf("hunter", "speedrunner", "spectator") private val teams: List<String> = listOf("hunter", "speedrunner", "spectator")
private val rules: List<String> = listOf("hunter_respawn_cd", "hunter_ready_cd", "friendly_fire") private val rules: List<String> = listOf("hunter_respawn_cd", "hunter_ready_cd", "friendly_fire")
private val ruleHelp: Component = Component.text("/minehunt rule <ruleItem>\n查看一项规则的详情\n") private val helpMessages = listOf(
.append(Component.text("/minehunt rule <ruleItem> <value>\n为一项规则设置新的值")) Component.text("Minehunt v${Minehunt.instance().pluginMeta.version}", NamedTextColor.GREEN),
Component.text("/minehunt help ", NamedTextColor.GOLD)
.append(Component.text("帮助信息", NamedTextColor.WHITE)),
Component.text("/minehunt join (hunter|speedrunner|spectator) ", NamedTextColor.GOLD)
.append(Component.text("加入一个阵营", NamedTextColor.WHITE)),
Component.text("/minehunt leave ", NamedTextColor.GOLD)
.append(Component.text("加入观察者阵营", NamedTextColor.WHITE)),
Component.text("/minehunt rule ", NamedTextColor.GOLD)
.append(Component.text("查看或修改游戏规则", NamedTextColor.WHITE)),
Component.text("/minehunt start ", NamedTextColor.GOLD)
.append(Component.text("开始游戏", NamedTextColor.WHITE)),
Component.text("/minehunt stop ", NamedTextColor.GOLD)
.append(Component.text("进行中止游戏的投票", NamedTextColor.WHITE))
)
private val ruleHelpMessages = listOf(
Component.text("/minehunt rule <ruleItem> ", NamedTextColor.GREEN)
.append(Component.text("查看一项规则的详情", NamedTextColor.WHITE)),
Component.text("/minehunt rule <ruleItem> <value> ", NamedTextColor.GREEN)
.append(Component.text("为一项规则设置新的值", NamedTextColor.WHITE))
)
/** /**
* 执行命令 * 执行命令
@@ -60,9 +80,18 @@ class MinehuntCommand(
*/ */
private fun handlerCommand(sender: CommandSender, args: List<String>, flag: Boolean): List<String>? { private fun handlerCommand(sender: CommandSender, args: List<String>, flag: Boolean): List<String>? {
if (args.isEmpty() || args[0] == "" || args[0] == "help" || args[0] == "?") if (args.isEmpty() || args[0] == "" || args[0] == "help" || args[0] == "?")
return if (flag) sendHelp(sender) else subCommand return if (flag) {
sendHelp(sender)
null
} else {
subCommands
}
return when (args[0]) { return when (args[0]) {
"help" -> {
onHelp(sender, flag)
}
"join" -> { "join" -> {
onJoin(sender, args, flag) onJoin(sender, args, flag)
} }
@@ -88,12 +117,17 @@ class MinehuntCommand(
sender.sendMessage(Component.text("错误的子命令")) sender.sendMessage(Component.text("错误的子命令"))
null null
} else { } else {
if (args.size == 1) subCommand.filter { it.startsWith(args[0]) } else null if (args.size == 1) subCommands.filter { it.startsWith(args[0]) } else null
} }
} }
} }
} }
private fun onHelp(sender: CommandSender, flag: Boolean): List<String>? {
if (flag) sendHelp(sender)
return null
}
/** /**
* 玩家加入队伍 * 玩家加入队伍
*/ */
@@ -130,7 +164,7 @@ class MinehuntCommand(
return null return null
} else { } else {
if (args.size == 2) { if (args.size == 2) {
return teams.filter { it.startsWith(args[0]) } return teams.filter { it.startsWith(teamName) }
} }
} }
@@ -158,13 +192,12 @@ class MinehuntCommand(
// args[0] == rule // args[0] == rule
if (args.size == 1) { if (args.size == 1) {
if (flag) { if (flag) {
sender.sendMessage(ruleHelp) sendHelpRule(sender)
} }
return null return null
} }
val rule = args[1] return when (val rule = args[1]) {
return when (rule) {
"hunter_respawn_cd" -> { "hunter_respawn_cd" -> {
getOrChangeRule(args, flag, sender, RuleKey.HUNTER_RESPAWN_CD) getOrChangeRule(args, flag, sender, RuleKey.HUNTER_RESPAWN_CD)
} }
@@ -182,7 +215,7 @@ class MinehuntCommand(
sender.sendMessage(Component.text("不存在的规则项")) sender.sendMessage(Component.text("不存在的规则项"))
null null
} else { } else {
if (args.size == 2) rules.filter { it.startsWith(args[0]) } else null if (args.size == 2) rules.filter { it.startsWith(rule) } else null
} }
} }
} }
@@ -207,7 +240,14 @@ class MinehuntCommand(
// 给规则赋值 // 给规则赋值
if (flag) { if (flag) {
if (console.gameRules.setGameRuleValueSafe(ruleKey, args[2])) { if (console.gameRules.setGameRuleValueSafe(ruleKey, args[2])) {
sender.sendMessage(Component.text("规则修改成功", NamedTextColor.GREEN)) sender.sendMessage(
Component.text(sender.name, NamedTextColor.YELLOW)
.append(Component.text("修改规则项", NamedTextColor.WHITE))
.append(Component.text(ruleKey.name, NamedTextColor.GOLD))
.append(Component.text("值为", NamedTextColor.WHITE))
.append(Component.text(args[2], NamedTextColor.GREEN))
)
console.refreshEntry(ruleKey)
} else { } else {
sender.sendMessage(Component.text("不合适的值", NamedTextColor.RED)) sender.sendMessage(Component.text("不合适的值", NamedTextColor.RED))
} }
@@ -229,7 +269,6 @@ class MinehuntCommand(
*/ */
private fun onStart(sender: CommandSender, flag: Boolean): List<String>? { private fun onStart(sender: CommandSender, flag: Boolean): List<String>? {
if (flag) { if (flag) {
// TODO 正在编辑规则时,也不能开始
if (console.stage == Console.GameStage.PREPARING) { if (console.stage == Console.GameStage.PREPARING) {
console.tryStart() console.tryStart()
} else { } else {
@@ -266,12 +305,14 @@ class MinehuntCommand(
/** /**
* 发送帮助信息 * 发送帮助信息
*/ */
private fun sendHelp(sender: CommandSender): List<String>? { private fun sendHelp(sender: CommandSender) {
sender.sendMessage("§aMinehunt v1.0.0") helpMessages.forEach { sender.sendMessage(it) }
sender.sendMessage("§a/minehunt help") }
sender.sendMessage("§a/minehunt start")
sender.sendMessage("§a/minehunt stop") /**
sender.sendMessage("§a/minehunt set <time>") * 发送rule子命令的帮助信息
return null */
private fun sendHelpRule(sender: CommandSender) {
ruleHelpMessages.forEach { sender.sendMessage(it) }
} }
} }

View File

@@ -15,6 +15,8 @@ import org.bukkit.inventory.ItemStack
*/ */
class TestCommand : CommandExecutor { class TestCommand : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean { override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
if (args.isEmpty()) return false
when (args[0]) { when (args[0]) {
// 发送消息 // 发送消息
"sendTo" -> { "sendTo" -> {

View File

@@ -86,4 +86,6 @@ class PlayerListener(
} }
} }
// TODO 改变维度时,记录最后的位置
} }

View File

@@ -8,7 +8,7 @@ import xyz.fortern.minehunt.rule.RuleKey.Companion.HUNTER_RESPAWN_CD
* 描述所有游戏规则的类 * 描述所有游戏规则的类
*/ */
class GameRules internal constructor() { class GameRules internal constructor() {
private val map: MutableMap<RuleKey<*>, Any> = HashMap() private val map: MutableMap<RuleKey<*>, Any> = LinkedHashMap()
init { init {
setRuleValue(HUNTER_RESPAWN_CD, 30) setRuleValue(HUNTER_RESPAWN_CD, 30)
@@ -16,6 +16,9 @@ class GameRules internal constructor() {
setRuleValue(FRIENDLY_FIRE, true) setRuleValue(FRIENDLY_FIRE, true)
} }
/**
* 设置一项游戏规则
*/
fun <T> setGameRuleValueSafe(rule: RuleKey<T>, value: String): Boolean { fun <T> setGameRuleValueSafe(rule: RuleKey<T>, value: String): Boolean {
val okValue: T = rule.validate(value) ?: return false val okValue: T = rule.validate(value) ?: return false
setRuleValue(rule, okValue) setRuleValue(rule, okValue)
@@ -26,8 +29,18 @@ class GameRules internal constructor() {
map[rule] = value!! map[rule] = value!!
} }
/**
* 根据key获取一项游戏规则
*/
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <T> getRuleValue(rule: RuleKey<T>): T { fun <T> getRuleValue(rule: RuleKey<T>): T {
return map[rule] as T return map[rule] as T
} }
/**
* 获取所有游戏规则
*/
fun getAllRules(): Map<RuleKey<*>, Any> {
return map
}
} }

View File

@@ -9,25 +9,6 @@ import xyz.fortern.minehunt.util.Util
// TODO 使用物品栏修改游戏规则 // TODO 使用物品栏修改游戏规则
class RuleBook { class RuleBook {
val rootInventory = Bukkit.createInventory(null, 9, Component.text("点击任意一个规则项进行设置")).also {
Util.fillItem(it, filler)
val rule1 = ItemStack(Material.CLOCK)
val itemMeta1 = rule1.itemMeta
itemMeta1.customName(Component.text(RuleKey.HUNTER_READY_CD.info))
itemMeta1.lore(listOf(Component.text(RuleKey.HUNTER_READY_CD.name)))
it.setItem(1, rule1)
val rule2 = ItemStack(Material.CLOCK)
val itemMeta2 = rule2.itemMeta
itemMeta2.customName(Component.text(RuleKey.HUNTER_RESPAWN_CD.info))
itemMeta2.lore(listOf(Component.text(RuleKey.HUNTER_RESPAWN_CD.name)))
it.setItem(5, rule2)
val rule3 = ItemStack(Material.CLOCK)
val itemMeta3 = rule3.itemMeta
itemMeta3.customName(Component.text(RuleKey.FRIENDLY_FIRE.info))
itemMeta3.lore(listOf(Component.text(RuleKey.FRIENDLY_FIRE.name)))
it.setItem(9, rule3)
}
private val filler = ItemStack(Material.BLACK_STAINED_GLASS_PANE).also { private val filler = ItemStack(Material.BLACK_STAINED_GLASS_PANE).also {
it.addItemFlags( it.addItemFlags(
ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ATTRIBUTES,
@@ -37,4 +18,23 @@ class RuleBook {
ItemFlag.HIDE_UNBREAKABLE ItemFlag.HIDE_UNBREAKABLE
) )
} }
val rootInventory = Bukkit.createInventory(null, 9, Component.text("点击任意一个规则项进行设置")).also {
Util.fillItem(it, filler)
val rule1 = ItemStack(Material.CLOCK)
val itemMeta1 = rule1.itemMeta
itemMeta1.customName(Component.text(RuleKey.HUNTER_READY_CD.info))
itemMeta1.lore(listOf(Component.text(RuleKey.HUNTER_READY_CD.name)))
it.setItem(0, rule1)
val rule2 = ItemStack(Material.CLOCK)
val itemMeta2 = rule2.itemMeta
itemMeta2.customName(Component.text(RuleKey.HUNTER_RESPAWN_CD.info))
itemMeta2.lore(listOf(Component.text(RuleKey.HUNTER_RESPAWN_CD.name)))
it.setItem(4, rule2)
val rule3 = ItemStack(Material.CLOCK)
val itemMeta3 = rule3.itemMeta
itemMeta3.customName(Component.text(RuleKey.FRIENDLY_FIRE.info))
itemMeta3.lore(listOf(Component.text(RuleKey.FRIENDLY_FIRE.name)))
it.setItem(8, rule3)
}
} }