流程控制
IM 脚本支持 if / else、switch / case、for、chance / fail、with、require、try / catch、return / break / continue。
最重要的限制:所有流程控制块必须换行,单行写法不被支持。
if / else
yaml
execute: |
if 成功率 >= 50 {
effect.message("&a成功率较高")
} else if 成功率 >= 20 {
effect.message("&e成功率一般")
} else {
effect.message("&c成功率较低")
}嵌套:
yaml
execute: |
if 等级 >= 5 {
if 有VIP {
成功率 += 10
}
}必须多行
yaml
# ❌ 错误:单行 if 会导致块内代码不执行,变量赋值静默失败
if 条件 { x = 10 }
# ✓ 正确
if 条件 {
x = 10
}else if / else 同样必须多行。
switch / case
yaml
execute: |
switch 品质 {
case "普通": # 冒号可选
颜色 = "&f"
case "稀有" # 不带冒号也可以
颜色 = "&9"
case "传说":
颜色 = "&6"
default:
颜色 = "&7"
}特点:
- 匹配到 case 后自动退出,无穿透,不需要
break。 - case 后的冒号
:是可选的。 - 每个 case 只能匹配一个值,不支持多值 case。要匹配多个值请改用
if / else if。 - switch 表达式可以是变量、属性访问或任意表达式:
yaml
switch @input.type {
case "DIAMOND_SWORD":
品质 = "传说"
case "IRON_SWORD":
品质 = "普通"
default:
品质 = "未知"
}for 循环
仅支持数值范围
for 循环不支持列表遍历、不支持 while。要遍历列表,用 for i in 0..size-1 { list_get(列表, i) }。
yaml
execute: |
# 范围循环
for i in 1..10 {
effect.message("第 {i} 次")
}
# 变量作为边界
for i in 1..最大等级 {
effect.message("等级 {i}")
}
# 遍历列表 / Lore
for i in 0..list_size(@input.lore)-1 {
当前行 = list_get(@input.lore, i)
log("Lore:", 当前行)
}
# 方法链作为边界
for i in 1..材料列表.size() {
item = list_get(材料列表, i-1) # i 从 1 开始,索引从 0 开始
}循环中修改列表物品
list_get() 返回深拷贝,修改副本不会影响原列表。三种正确模式:
yaml
# 模式 1:直接用修改后的副本 slot.set
for i in 1..物品列表.size() {
副本 = list_get(物品列表, i-1)
副本.lore.append("&7编号: {i}")
slot.set("s" + i, 副本) # ✓ 用修改后的副本
}
# 模式 2:用 list_set 写回列表
for i in 0..list_size(物品列表)-1 {
副本 = list_get(物品列表, i)
副本.lore.append("...")
物品列表 = list_set(物品列表, i, 副本) # ✓ 写回
}
# 模式 3:不用列表,直接操作原始变量
材料1.lore.append("&7需要: 10")
slot.set("s1", 材料1)错误模式:
yaml
# ❌ 改了副本,但 slot.set 用的是原变量
for i in 0..list_size(物品列表)-1 {
副本 = list_get(物品列表, i)
副本.lore.append("...")
}
slot.set("s1", 材料1) # ❌ 材料1 没被修改详见 列表与统计函数。
chance / fail 概率执行
yaml
execute: |
chance 成功率 {
effect.message("&a强化成功!")
装备.lore.attr("等级", "+1")
} fail {
effect.message("&c强化失败")
if rand(100) < 30 {
effect.message("&4装备损坏!")
item.clear(@input)
}
}
# 纯概率(没有 fail 块也可以)
chance 50 {
effect.message("50% 概率触发")
}chance 后面可以是数字(百分比)也可以是变量。fail 块可选。
with 目标物品操作
with @槽位 { ... } 把指定槽位的物品设为当前操作目标,块内所有动作自动作用于它,结束时自动写回槽位。
yaml
execute: |
with @input {
装备.name.prefix("&6[强化] ")
装备.lore.attr("攻击力", "+10")
装备.lore.setCounter("强化等级", 新等级, 10)
}
# 块执行完毕,@input 槽位已自动更新,不需要 slot.set工作原理
- 把指定槽位的物品设为当前目标。
- 块内所有动作自动作用于该物品,不用重复指定槽位。
- 块结束时,修改后的物品自动同步回槽位。
- 恢复之前的目标物品上下文。
自动写回的前提
只有 with @槽位ID 会自动写回。对普通变量使用 with 不会自动写回:
yaml
# ✓ with @槽位 → 自动写回
with @input {
装备.lore.attr("攻击力", "+10")
}
# ❌ with 普通变量 → 不自动写回
装备 = item(@input)
with 装备 {
装备.lore.attr("攻击力", "+10")
}
slot.set("input", 装备) # 必须手动写回支持的动作
with 块内所有以下动作可省略"目标物品"参数:
| 分类 | 动作 |
|---|---|
| Lore | lore.replace / .append / .insert / .delete / .clear / .setLine / .attr / .setAttr / .setCounter / .setValue / .insertAfter / .random_replace / .sort / .copy / .move |
| Name | name.set / .prefix / .suffix |
| NBT | nbt.set / .add / .remove |
| 附魔 | enchant.add / .remove |
| 耐久 | durability.set / .repair |
| 物品 | item.setType / amount.set |
限制
- 不支持槽位组(multiple=true)。槽位组请用
for循环配合list_get/slot.set。 - 经济(
money.take等)和效果(effect.message等)虽可写在 with 块内,但它们与目标物品无关,行为和在外部一样。 - with 块内支持
return,会跳出整个脚本。
require 条件检查
条件不满足时显示消息并立即中止脚本。
yaml
execute: |
require @input.filled : "&c请放入装备"
require @material.filled : "&c请放入材料"
require 等级 < 10 : "&c已达到最大等级"
require money >= 消耗金币 : "&c金币不足,需要{消耗金币}"
require lshop_has("绑定金币", 1000) : "&c绑定金币不足"
# 所有条件满足后才会执行到这里
effect.message("&a开始强化...")require 条件 : "消息" 等价于 if !条件 { effect.message("消息"); return },更简洁。
常用于 execute 开头或 conditions 字段。
return / break / continue
yaml
execute: |
# return:结束整个脚本
if !@input.filled {
effect.message("&c没有物品")
return
}
# break:跳出最近一层循环
for i in 1..100 {
if i > 10 {
break
}
}
# continue:跳过本次循环
for i in 1..10 {
if i == 5 {
continue
}
effect.message("第 {i} 次")
}break/continue只在数值范围for里有效(IM 没有 while)。return可以出现在任何地方,直接跳出当前脚本块。
try / catch / throw
捕获运行时错误,避免脚本中断。
yaml
execute: |
try {
item = list_get(items, 100) # 越界会抛错
} catch {
effect.message("&c发生错误: {error}") # {error} 是错误消息
}
# 手动抛错
try {
if @input.empty {
throw("请放入物品!")
}
if 数量 < 0 {
throw("数量不能为负数")
}
} catch {
effect.message("&c{error}")
}
# 嵌套
try {
try {
throw("内层错误")
} catch {
throw("处理后的错误: " + {error})
}
} catch {
effect.message("&c最终错误: {error}")
}适用场景:
- 列表越界访问
- 外部集成(MM / NI)可能失败的调用
- 用户输入验证
- 需要优雅兜底的场景
注释
支持三种形式:
yaml
execute: |
// 单行(推荐)
# 单行(井号)
装备.name.set("新名称") // 行尾注释
/*
* 多行注释
* 可以写多行说明
*/// 和 # 是单行注释,/* */ 是多行注释。脚本里的 # 不会被 YAML 当作注释,因为整个 execute 块是 YAML 多行字符串。
流程控制速查
| 语句 | 用途 | 关键限制 |
|---|---|---|
if / else if / else | 条件分支 | 必须多行;无单行形式 |
switch / case / default | 多值分支 | 单值 case,不支持多值;无穿透 |
for i in A..B | 数值循环 | 不支持列表遍历、不支持 while |
chance N { } fail { } | 概率分支 | N 可为百分数或变量;fail 可选 |
with @槽位 | 批量修改某槽位物品 | 不支持槽位组;自动写回 |
require 条件 : 消息 | 前置检查 | 不满足时发消息并 return |
try / catch | 错误捕获 | {error} 为错误消息 |
return / break / continue | 提前退出 | break/continue 仅限 for |