Skip to content

流程控制

IM 脚本支持 if / elseswitch / caseforchance / failwithrequiretry / catchreturn / 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

工作原理

  1. 把指定槽位的物品设为当前目标。
  2. 块内所有动作自动作用于该物品,不用重复指定槽位。
  3. 块结束时,修改后的物品自动同步回槽位
  4. 恢复之前的目标物品上下文。

自动写回的前提

只有 with @槽位ID 会自动写回。对普通变量使用 with 不会自动写回:

yaml
# ✓ with @槽位 → 自动写回
with @input {
  装备.lore.attr("攻击力", "+10")
}

# ❌ with 普通变量 → 不自动写回
装备 = item(@input)
with 装备 {
  装备.lore.attr("攻击力", "+10")
}
slot.set("input", 装备)   # 必须手动写回

支持的动作

with 块内所有以下动作可省略"目标物品"参数:

分类动作
Lorelore.replace / .append / .insert / .delete / .clear / .setLine / .attr / .setAttr / .setCounter / .setValue / .insertAfter / .random_replace / .sort / .copy / .move
Namename.set / .prefix / .suffix
NBTnbt.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

下一步:学习 内置函数内置动作

TQ Minecraft Server Plugin Docs