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
out/
.kotlin/
# Compiled class file
*.class

View File

@@ -11,11 +11,12 @@ import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.CompassMeta
import org.bukkit.scheduler.BukkitRunnable
import org.bukkit.scheduler.BukkitTask
import org.bukkit.scoreboard.Criteria
import org.bukkit.scoreboard.DisplaySlot
import org.bukkit.scoreboard.Team
import xyz.fortern.minehunt.rule.GameRules
import xyz.fortern.minehunt.rule.RuleKey
@@ -32,11 +33,20 @@ class Console {
*/
val gameRules = GameRules()
val ruleBook = Bukkit.createInventory(null, InventoryType.HOPPER, Component.text("Game Rules"))
/**
* 游戏阶段
*/
var stage: GameStage = GameStage.PREPARING
private set
/**
* 计分板
*/
private val scoreboard = Bukkit.getScoreboardManager().mainScoreboard
/**
* 主世界
*/
private var overworld = Bukkit.getWorld("world")!!
/**
@@ -164,7 +174,8 @@ class Console {
init {
instance = this
// 初始化游戏规则
setRuleScoreboard()
// 初始化 Minecraft 游戏规则
overworld.worldBorder.size = 32.0
overworld.setGameRule(GameRule.DO_DAYLIGHT_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.entity.Player
import xyz.fortern.minehunt.Console
import xyz.fortern.minehunt.Minehunt
import xyz.fortern.minehunt.rule.RuleKey
/**
@@ -16,12 +17,31 @@ class MinehuntCommand(
private val console: Console
) : 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 rules: List<String> = listOf("hunter_respawn_cd", "hunter_ready_cd", "friendly_fire")
private val ruleHelp: Component = Component.text("/minehunt rule <ruleItem>\n查看一项规则的详情\n")
.append(Component.text("/minehunt rule <ruleItem> <value>\n为一项规则设置新的值"))
private val helpMessages = listOf(
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>? {
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]) {
"help" -> {
onHelp(sender, flag)
}
"join" -> {
onJoin(sender, args, flag)
}
@@ -88,12 +117,17 @@ class MinehuntCommand(
sender.sendMessage(Component.text("错误的子命令"))
null
} 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
} else {
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
if (args.size == 1) {
if (flag) {
sender.sendMessage(ruleHelp)
sendHelpRule(sender)
}
return null
}
val rule = args[1]
return when (rule) {
return when (val rule = args[1]) {
"hunter_respawn_cd" -> {
getOrChangeRule(args, flag, sender, RuleKey.HUNTER_RESPAWN_CD)
}
@@ -182,7 +215,7 @@ class MinehuntCommand(
sender.sendMessage(Component.text("不存在的规则项"))
null
} 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 (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 {
sender.sendMessage(Component.text("不合适的值", NamedTextColor.RED))
}
@@ -229,7 +269,6 @@ class MinehuntCommand(
*/
private fun onStart(sender: CommandSender, flag: Boolean): List<String>? {
if (flag) {
// TODO 正在编辑规则时,也不能开始
if (console.stage == Console.GameStage.PREPARING) {
console.tryStart()
} else {
@@ -266,12 +305,14 @@ class MinehuntCommand(
/**
* 发送帮助信息
*/
private fun sendHelp(sender: CommandSender): List<String>? {
sender.sendMessage("§aMinehunt v1.0.0")
sender.sendMessage("§a/minehunt help")
sender.sendMessage("§a/minehunt start")
sender.sendMessage("§a/minehunt stop")
sender.sendMessage("§a/minehunt set <time>")
return null
private fun sendHelp(sender: CommandSender) {
helpMessages.forEach { sender.sendMessage(it) }
}
/**
* 发送rule子命令的帮助信息
*/
private fun sendHelpRule(sender: CommandSender) {
ruleHelpMessages.forEach { sender.sendMessage(it) }
}
}

View File

@@ -15,6 +15,8 @@ import org.bukkit.inventory.ItemStack
*/
class TestCommand : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
if (args.isEmpty()) return false
when (args[0]) {
// 发送消息
"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() {
private val map: MutableMap<RuleKey<*>, Any> = HashMap()
private val map: MutableMap<RuleKey<*>, Any> = LinkedHashMap()
init {
setRuleValue(HUNTER_RESPAWN_CD, 30)
@@ -16,6 +16,9 @@ class GameRules internal constructor() {
setRuleValue(FRIENDLY_FIRE, true)
}
/**
* 设置一项游戏规则
*/
fun <T> setGameRuleValueSafe(rule: RuleKey<T>, value: String): Boolean {
val okValue: T = rule.validate(value) ?: return false
setRuleValue(rule, okValue)
@@ -26,8 +29,18 @@ class GameRules internal constructor() {
map[rule] = value!!
}
/**
* 根据key获取一项游戏规则
*/
@Suppress("UNCHECKED_CAST")
fun <T> getRuleValue(rule: RuleKey<T>): 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 使用物品栏修改游戏规则
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 {
it.addItemFlags(
ItemFlag.HIDE_ATTRIBUTES,
@@ -37,4 +18,23 @@ class RuleBook {
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)
}
}