Skip to content

GUI 与动作

GTCore 的 GUI 和动作系统可以给插件、脚本、玩法配置共用。
常见用途是管理菜单、兑换菜单、礼包菜单、确认弹窗、输入流程和按钮动作。

动作写法

动作一般写成:

text
[动作名] 参数

例子:

text
[message] &a领取成功
[console] eco give {player} 100
[player] spawn
[op] mythicmobs mobs spawn SkeletonKing 1
[item] DIAMOND*3
[sound] ENTITY_PLAYER_LEVELUP 1 1.2

{player} 会替换成玩家名。

常用动作表

动作示例说明
message[message] &a成功给玩家发消息
broadcast[broadcast] &e{player} 完成兑换全服广播
console[console] say hello后台执行命令
player[player] spawn玩家身份执行命令
op[op] cmi fly临时 OP 身份执行命令,执行完恢复
item[item] ni:starter_sword*1发放物品
takeitem[takeitem] DIAMOND*3扣除物品
hasitem[hasitem] mm:BossKey*1检查物品,不满足会中断后续控制动作
money[money] give 100加钱
money[money] take 100扣钱
hasmoney[hasmoney] 1000检查余额
permission[permission] gt.vip检查权限
condition[condition] %player_level% >= 30条件表达式
chance[chance] 30%概率判断
delay[delay] 20延迟执行后续动作
title`[title] &a成功&7奖励已发放
actionbar[actionbar] &e正在处理ActionBar
teleport[teleport] world 0 80 0传送
xp[xp] give 50加经验
health[health] set 20设置血量
food[food] set 20设置饥饿值
effect[effect] SPEED 200 1药水效果
close[close]关闭 GUI
refresh[refresh]刷新 GUI
script[script] groovy/example.groovy执行脚本
clientgui[clientgui] pai open main调用客户端 GUI 适配

物品 ID

GUI 图标、动作发物品、条件扣物品都使用统一物品 ID。

写法说明
DIAMOND原版物品
minecraft:diamond原版物品
ni:starter_swordNeigeItems
mm:BossKeyMythicMobs 物品
ia:namespace:itemItemsAdder
oraxen:my_itemOraxen
sx:my_itemSX-Item
mi:SWORD:MY_SWORDMMOItems
ce:namespace:itemCraftEngine

原版物品不需要写 vanilla:,直接写材料 ID 即可。

Groovy 创建简单 GUI

文件位置:

text
plugins/GTCore/scripts/groovy/reward_menu.groovy

内容:

groovy
import com.rusbrook.gtcore.sdk.CommandExecutorHandler
import com.rusbrook.gtcore.sdk.GTGui
import com.rusbrook.gtcore.sdk.GTAction
import org.bukkit.entity.Player

ctx.registerCommand("reward", [] as List, "", "打开奖励菜单", "/reward", { sender, label, args ->
    if (!(sender instanceof Player)) {
        sender.sendMessage("§c只有玩家可以使用。")
        return true
    }

    def player = sender as Player
    def menu = GTGui.menu("&6奖励菜单")
        .rows(3)
        .locked(true)
        .border(GTGui.material("GRAY_STAINED_GLASS_PANE", " "))
        .button(13, GTGui.button(
            GTGui.material("DIAMOND", "&b领取钻石", ["&7点击领取 3 个钻石"])
        ).actions([
            GTAction.item("DIAMOND", 3),
            GTAction.message("&a领取成功。"),
            GTAction.sound("ENTITY_PLAYER_LEVELUP", 1, 1.2),
            GTAction.close()
        ]).build())
        .build()

    ctx.openMenu(player, menu)
    return true
} as CommandExecutorHandler, null)

重载:

text
/gtcore reloadscripts

输入:

text
/reward

效果:打开一个 3 行菜单,点击中间钻石按钮后发放 3 个钻石并关闭界面。

用物品库做图标和奖励

NeigeItems 图标:

groovy
def icon = GTGui.item("ni:starter_sword", player, 1)

MythicMobs 图标:

groovy
def key = GTGui.item("mm:BossKey", player, 1)

按钮动作:

groovy
GTGui.button(icon)
    .actions([
        "[hasitem] mm:BossKey*1",
        "[takeitem] mm:BossKey*1",
        "[item] ni:starter_sword*1",
        "[message] &a兑换成功。"
    ])
    .build()

效果:玩家需要 1 个 MM 钥匙,点击后扣掉钥匙并发放 NI 武器。

分页菜单

大量物品不要一次塞满 GUI,使用分页:

groovy
import com.rusbrook.gtcore.sdk.CommandExecutorHandler
import com.rusbrook.gtcore.sdk.GTGui
import org.bukkit.entity.Player

def ids = [
    "DIAMOND", "GOLD_INGOT", "IRON_INGOT",
    "ni:starter_sword", "mm:BossKey"
]

ctx.registerCommand("repo", [] as List, "", "打开仓库示例", "/repo", { sender, label, args ->
    if (!(sender instanceof Player)) return true
    def player = sender as Player
    def items = ids.collect { GTGui.item(it, player, 1) }.findAll { it != null }

    def menu = GTGui.repository("&8物品预览", items, 6, 2, 5, 45, 53).build()
    ctx.openMenu(player, menu)
    return true
} as CommandExecutorHandler, null)

效果:物品显示在中间区域,底部箭头翻页。

确认弹窗

适合删除、购买、解绑、重置这类危险操作。

groovy
def dialog = GTGui.dialog("&c确认购买")
    .message([
        "&7本次购买将扣除 &e1000 &7金币。",
        "&7确认后无法撤销。"
    ])
    .confirmItem(GTGui.material("LIME_WOOL", "&a确认"))
    .cancelItem(GTGui.material("RED_WOOL", "&c取消"))
    .confirmActions([
        "[hasmoney] 1000",
        "[money] take 1000",
        "[item] ni:vip_box*1",
        "[message] &a购买成功。"
    ])
    .cancelActions([
        "[message] &7已取消。"
    ])
    .build()

ctx.openDialog(player, dialog)

高版本会优先使用可用的 Dialog 能力;低版本会自动走兼容输入或 GUI 方案。

输入流程

需要输入名称、数量、价格时使用 ctx.input

groovy
import com.rusbrook.gtcore.sdk.GuiInputHandler

ctx.input(player, "输入价格", ["&7请输入新的价格,30 秒内有效。"], 30, { input ->
    if (input.cancelled || input.timeout) {
        input.player.sendMessage("§c输入已取消。")
        return
    }
    def price = input.text as String
    input.player.sendMessage("§a新的价格: §e" + price)
} as GuiInputHandler)

适合管理菜单里编辑数字、文本、条件和动作。

Map 配置创建 GUI

脚本里也可以直接用 Map 生成菜单,结构更像配置文件:

groovy
def spec = [
    title: "&8礼包菜单",
    rows: 3,
    locked: true,
    border: "GRAY_STAINED_GLASS_PANE",
    buttons: [
        13: [
            material: "CHEST",
            name: "&a新手礼包",
            lore: ["&7点击领取奖励"],
            actions: [
                "[permission] gt.reward.starter",
                "[item] DIAMOND*3",
                "[money] give 100",
                "[message] &a领取成功。"
            ],
            close: true
        ]
    ]
]

ctx.openMenu(player, GTGui.menu(spec, player))

这种写法适合把 GUI 内容放进 YAML,再由脚本或插件读取后打开。

动作执行顺序

动作从上到下执行。检查类动作失败时会中断后续动作:

yaml
actions:
  - "[permission] gt.vip"
  - "[hasmoney] 1000"
  - "[money] take 1000"
  - "[item] ni:vip_box*1"
  - "[message] &a购买成功"

如果没有 gt.vip 权限或余额不足,后面的扣钱、发物品不会继续执行。

性能建议

  • 高频 GUI 不要每次点击都重读磁盘。
  • 大列表用分页。
  • 物品库图标可以缓存 ID,打开 GUI 时再创建 ItemStack。
  • 点击按钮后执行数据库或网络操作时,先提示处理中,完成后再刷新。
  • 需要防重复点击时使用事务或锁,不要只靠关闭 GUI。