引用与插值
脚本里随时要引用槽位物品、玩家信息、变量。本页把三种引用机制(@槽位、内置变量、{} 插值)集中列出来。
@槽位ID 引用
定义好的槽位在脚本里用 @槽位ID 引用。注意:@xxx 里的 xxx 是槽位定义时的 id,不是布局字符,也不是槽位类型名。
yaml
slots:
I: input(id=主装备, ...) # 槽位 ID 是 "主装备"
M: material(id=材料, ...) # 槽位 ID 是 "材料"
execute: |
装备 = @主装备 # ✓ 用 id
数量 = @材料.amount基本属性
| 表达式 | 类型 | 说明 |
|---|---|---|
@input | ItemStack | 物品对象(可继续链式调用) |
@input.filled | Boolean | 是否有物品 |
@input.empty | Boolean | 是否为空(等同 !filled) |
@input.amount | Number | 数量 |
@input.type | String | 材质名(如 DIAMOND_SWORD) |
@input.name | String | 显示名 |
@input.hasName | Boolean | 是否有自定义显示名 |
@input.durability | Number | 当前耐久 |
@input.maxDurability | Number | 最大耐久 |
@input.damage | Number | 已损耗值 |
@input.durabilityPercent | Number | 耐久百分比(0–100) |
简化方法
| 方法 | 说明 |
|---|---|
@input.attr("攻击力") | 从 Lore 提取属性值(找 属性名: +数值) |
@input.counter("次数") | 提取计数器当前值(找 次数: 3/10) |
@input.counterMax("次数") | 提取计数器最大值 |
@input.text("品质") | 提取文本字段(找 品质: 传说) |
@input.hasAttr("攻击力") | 是否存在该属性 |
@input.hasCounter("次数") | 是否存在该计数器 |
正则 / 模板提取
yaml
# 正则提取单个值
值 = @input.extract("攻击力: (\\d+)", 1)
# 模板提取(推荐,最灵活)
当前等级 = @input.t("强化等级: {#level}/{#max}", "level")模板语法:
| 占位符 | 说明 |
|---|---|
{#name} | 提取数字(整数或浮点,支持正负号) |
{name} | 提取任意文本 |
{*} | 跳过/匹配任意内容(不提取) |
yaml
# Lore: "§6吞噬次数: 3/10"
@input.t("吞噬次数: {#current}/{#max}", "current") # → 3
# Lore: "§a品质: 传说"
@input.t("{*}品质: {quality}", "quality") # → "传说"
# 多个值一起取:
result = @input.template("强化+{#level} 攻击力+{#atk}")
if result.isMatched() {
等级 = result.getInt("level")
攻击 = result.getInt("atk")
}TemplateResult 对象方法:
| 方法 | 说明 |
|---|---|
result.isMatched() | 是否匹配成功 |
result.get("name") | 获取值(Object) |
result.getInt("name") | 整数 |
result.getDouble("name") | 浮点 |
result.getString("name") | 字符串 |
NBT
yaml
值 = @input.nbt("CustomData.Level")
存在 = @input.hasNbt("CustomData")
nbt_json = @input.serialize()附魔
yaml
等级 = @input.enchant("SHARPNESS") # 英文
等级 = @input.enchant("锋利") # 中文也可以
有 = @input.hasEnchant("SHARPNESS")
数量 = @input.enchantCount()支持的中文附魔名:锋利、亡灵杀手、节肢杀手、击退、火焰附加、抢夺、效率、精准采集、耐久、时运、力量、冲击、火矢、无限、保护、火焰保护、摔落保护、爆炸保护、弹射物保护、水下呼吸、水下速掘、荆棘、深海探索者、冰霜行者、经验修补、消失诅咒、绑定诅咒。
Lore
yaml
lore_list = @input.lore # List<String>
有 = @input.hasLore # Boolean
行数 = @input.loreCount()
第 N 行 = @input.loreGet(0) # 支持负数索引,-1 = 最后一行
行号 = @input.loreFind("关键词") # -1 表示未找到Toggle 开关
yaml
if @lock1.on { # 开关开启
...
}
if !@lock1.state { # 同义
...
}槽位组(multiple=true)
@id 变成 List<ItemStack>:
| 表达式 | 类型 | 说明 |
|---|---|---|
@food | List<ItemStack> | 整个列表(空位为 null) |
@food.filled | Number | 有物品的数量 |
@food.size | Number | 槽位总数 |
@food.empty | Boolean | 是否全部为空 |
遍历槽位组:
yaml
for i in 0..list_size(@food)-1 {
物品 = list_get(@food, i)
if 物品 != null {
log("第", i, "格:", 物品)
}
}list_get 返回深拷贝
修改 list_get() 返回的物品不会影响列表本身。要持久化,list_set(列表, 索引, 副本) 写回,或直接用副本 slot.set 到具体槽位。
内置变量
无需 @ 前缀,直接使用。
玩家
| 变量 | 类型 | 说明 |
|---|---|---|
player.name | String | 玩家名 |
player.uuid | String | UUID |
player.displayName | String | 显示名(含称号等) |
player.level | Number | 经验等级 |
player.exp | Number | 当前等级经验百分比(0.0–1.0) |
player.totalExp | Number | 总经验值 |
player.health | Number | 当前血量 |
player.maxHealth | Number | 最大血量 |
player.food | Number | 饱食度(0–20) |
player.world | String | 所在世界名 |
player.x / .y / .z | Number | 坐标 |
player.isOp | Boolean | 是否 OP |
player.gamemode | String | SURVIVAL / CREATIVE / ADVENTURE / SPECTATOR |
player.isSneaking | Boolean | 是否潜行 |
player.isFlying | Boolean | 是否飞行 |
经济
| 变量 | 类型 | 说明 |
|---|---|---|
money / player.money | Number | 玩家金币(需 Vault) |
points | Number | 点券(需 PlayerPoints) |
预览
| 变量 | 类型 | 说明 |
|---|---|---|
isPreviewMode | Boolean | 是否为预览模式 |
previewSlotId | String | 当前预览的源槽位 ID |
装备 变量约定
装备 不是关键字,是一个约定俗成的变量名,用来引用当前操作的物品。它不会自动创建,必须显式赋值:
yaml
# ✅ 正确
execute: |
装备 = @input # ← 必须先赋值
装备.lore.append("新行")
装备.name.prefix("&6")
slot.set("input", 装备) # ← 必须写回
# ❌ 错误 — 未赋值的话,所有操作静默失败
target: input
execute: |
装备.lore.append("新行") # 装备是 null,什么也不会发生关于 target: input:只把目标物品设到 context.targetItem 内部字段,用于 loreFind 等需要"当前目标"的场合。它不会创建名为"装备"的变量。
等效写法对比:
yaml
# 直接操作 @槽位
@input.lore.append("新行")
@input.name.set("新名称")
# 用 "装备" 变量(更简洁,能复用)
装备 = @input
装备.lore.append("新行")
装备.name.set("新名称")
slot.set("input", 装备)
# 用 with(最简洁,自动写回)
with @input {
装备.lore.append("新行")
装备.name.set("新名称")
}字符串 / 列表方法链
字符串:
yaml
text = "Hello World"
text.length() # 11
text.contains("World") # true
text.replace("World", "Minecraft") # "Hello Minecraft"
text.lowercase() / text.uppercase()
text.substring(0, 5) # "Hello"
text.split(" ") # ["Hello", "World"]
text.split(" ", 0) # 只取第 0 段:"Hello"
text.trim() # 去首尾空格
text.color() # & → § 颜色码转换列表:
yaml
list = [1, 2, 3]
list.size() # 3
list.get(0) # 1
list.get(-1) # 3(负索引从末尾)
list.contains(2) # true
list.join(",") # "1,2,3"
list.isEmpty() # false变量插值 {}
在字符串里用 {变量} 插入变量值。
yaml
variables: |
等级 = 5
名称 = "传说之剑"
execute: |
effect.message("&a你的 {名称} 升到了 {等级} 级!")
装备.name.set("&6{名称} +{等级}")
装备.lore.replace("等级: {旧等级}", "等级: {新等级}")完整规则
| 语法 | 说明 | 示例 |
|---|---|---|
{变量} | 基础插值 | {等级} → 5 |
{变量.属性} | 属性访问 | {player.name} → Steve |
{变量.方法()} | 方法调用 | {text.length()} → 11 |
{表达式} | 表达式计算 | {等级 + 1} → 6 |
\{ / \} | 转义字面量 { / } |
适用位置
effect.message("...")/effect.title(...)/effect.subtitle(...)装备.name.set(...)/.prefix(...)/.suffix(...)装备.lore.append(...)/.insert(...)/.setLine(...)display/button槽位的name和lore参数- 所有接受字符串的动作参数
不适用位置
| 场景 | 错误 | 正确 |
|---|---|---|
| 变量赋值左侧 | {变量} = 10 | 变量 = 10 |
| 匹配表达式 | match: "{变量}" | match: 变量(直接引用) |
| 函数参数 | max({a}, {b}) | max(a, b)(直接写变量) |
字符串拼接 vs 插值
| 场景 | 推荐 | 示例 |
|---|---|---|
| 静态模板 | 插值 | "等级: {等级}" |
| 构建新变量 | 拼接 | 文本 = "&7等级: " + 等级 |
| 动态颜色码 | 拼接 | 颜色 + 数值 + "%" |
| 消息 / Lore 文本 | 插值 | effect.message("成功率: {成功率}%") |
yaml
# ✓ 拼接:颜色码在引号内
状态 = "&7" + 变量
# ❌ 不是拼接:& 不是运算符
状态 = &7 + 变量下一步:流程控制 学习 if / switch / for / chance / with / require / try/catch。