条件表达式
基本信息
| 属性 | 值 |
|---|---|
| 基类 | net.bdew.lib.recipes.Condition(recipes/ast-conditions.scala:17) |
| 子类数 | 6 |
| 命名约定 | 全部以 Cnd 前缀 |
| 求值入口 | RecipeLoader.resolveCondition(recipes/RecipeLoader.scala:327) |
| 原语条件 | 3(mod / API / 矿物字典) |
功能
条件表达式是 BD lib 配置与配方 DSL 的分支机制,让同一条配方或调校参数只在特定模组组合存在时才生效。这在依赖可选附属的环境里是刚需 —— 同一个 .cfg 可以同时服务于装了和没装某个附属的整合包。
三种存在性原语
| 条件 | 判定对象 | 典型用途 |
|---|---|---|
HaveMod {string} |
FML 中是否加载了指定 modid 的模组 | 配方中引用某个附属的物品 |
HaveAPI {string} |
是否注册了指定的 API(ModAPIManager,非普通模组) |
判断某个库接口是否可用 |
HaveOD {string} |
矿物字典(OreDictionary)中是否存在该条目 | 配方引用 ingotIron 这类跨模组统一名 |
HaveAPI 与 HaveMod 的区别在于前者查的是 FML 的 API 注册表而非模组列表 —— BD lib 自身就通过 ModAPIManager.INSTANCE.injectAPIModContainers 参与这一机制(ApiReporter.scala:22-23)。
布尔运算
CndNOT(! {condition})、CndAND(({c} && {c}))、CndOR(({c} || {c}))三者可任意嵌套组合,构造出任意布尔表达式。CndAND 与 CndOR 的构造函数各接收两个 Condition 参数(c1、c2),嵌套由解析器在读取时递归构建。
两个作用域中的条件
同一套 Condition AST 被两个作用域复用,语法不同:
| 作用域 | 语法 | AST 类型 |
|---|---|---|
| 配置作用域 | if {cond} << {statements} >> [else << {statements} >>] |
CsConditionalConfig |
| 配方作用域 | if {cond} recipes { {statements} } [else { {statements} }] |
RsConditional |
源码注释指出,解析器在 RecipeParser.conditionBridge 中把 RsConditional 桥接到配置作用域,以便延迟执行。
数值
| 数值名 | 值 |
|---|---|
Condition 子类总数 |
6 |
| 其中存在性原语 | 3(CndHaveMod / CndHaveAPI / CndHaveOD) |
| 其中布尔运算符 | 3(CndNOT / CndAND / CndOR) |
| 支持条件的作用域数 | 2(配置 / 配方) |
支持 else 分支 |
是(两者均可选) |
交互
条件本身不可由玩家触发,它在配置加载时一次性求值:
| 触发 | 行为 |
|---|---|
加载 .cfg 时遇到 if 块 |
求值条件;为真则执行 thn 语句列表,否则执行 els(可为空) |
| 条件引用了未安装的 mod | HaveMod 为假,对应配方/参数整块跳过,游戏正常启动 |
| 条件引用了不存在的矿物字典条目 | HaveOD 为假,对应分支跳过 |
嵌套 && / || / ! |
递归求值,无短路副作用(结果为纯布尔) |