只有一个条件的谓词没有包装层,这是实打实的结构变化
一个条件时对象本身就是谓词。两个或更多条件会被包进 all_of 或 any_of。另外还有八种条件类型,以及为什么取反是一种包装而不是一个标志位,构建器涉及的条件类型一共有八种,取反是包进一层包装,而不是一个开关标志。
数据包谓词(predicate)是一个描述条件的 JSON 文件,它的结构会随条件数量的不同而变化。这正是那些照抄示例再自行扩展的人容易栽跟头的地方。
一个条件不等于只含一项的列表
| 条件数量 | 输出结构 |
|---|---|
| 0 | {} |
| 1 | 条件对象本身 |
| 2+ | { "condition": "minecraft:all_of", "terms": [ … ] } |
单个条件外面没有包装层。一旦加上第二个条件,整个文件的结构就会改变——原来的条件变成新根节点下 terms 数组的第一个元素。任何读取或生成这类文件的东西都必须同时处理这两种形式,而一个只用一个条件搭出来的示例,并不会告诉你再加一个条件时需要用到的结构。
any_of 是另一种组合方式:所有项都必须通过,或者其中任意一项通过即可。
取反也是一种包装,而不是一个标志位
并不存在 "invert": true 字段。取反的条件是这样包装的:
{ "condition": "minecraft:inverted", "term": { …the original condition… } }
注意这里是单数形式的 term——inverted 只接受一个条件,而 all_of 和 any_of 接受的是 terms 数组。两个看起来相似的键,结构却不同;而且取反是按条件逐个生效的,所以一个谓词可以在同一个 all_of 里自由混用取反项和普通项。
构建器提供的八种条件类型
entity_properties random_chance
int_value_check random_chance_with_enchanted_bonus
weather_check time_check
location_check match_tool
游戏共有二十种条件类型;这八种是构建器的选择器所覆盖的。其中两种改过名字,而构建器仍然写出旧的 id——random_chance_with_looting 和 value_check——当前版本会拒绝它们,所以要在输出里把这两个改掉。
random_chance_with_enchanted_bonus 是值得停下来想一想的一个:它同时接受一个不带该魔咒时的概率以及一个随魔咒等级缩放的 enchanted_chance(原版自己的表里用的是抢夺),所以概率取决于击杀者手里拿着什么。这让它只在上下文中存在击杀者时才有意义——它是掉落率条件,不是通用的随机闸门。其他地方该用的都是普通的 random_chance。
int_value_check(以及 float_value_check)用来检测某个数值是否落在某个区间内。构建器的数值检查提供两种来源:魔咒等级,或者一段自定义表达式——后者需要你在复制之后手动编辑进 JSON。
选择器里的内容就是原版的那几套
在核对某个生物群系或结构 id 是否真实存在时,这一点值得知道:构建器的下拉菜单并不是精挑细选的样本。
- 66 个生物群系——截至 26.2 的全部生物群系;26.3 的
dappled_forest不在其中,需要手动输入 - 34 个结构——同样截至 26.2;26.3 新增的 18 个
abandoned_camp_*结构没有列出 - 18 个方块标签和 15 个物品,这些确实是可用的子集
这是对照游戏自身的注册表数据核实过的,而不是想当然,所以如果某个 id 不在生物群系或结构列表里,且不属于 26.3 的新增内容,那这个 id 就是不存在。方块标签和物品则相反:不在列表里只说明选择器没有列出它,自己手动输入 id 完全没问题。