过滤器是游戏对生物提出的一个是非问题。“攻击者是玩家吗?”“现在是白天吗?”“这个生物在水里吗?”如果答案是肯定的,过滤器就通过,它所把守的事情就被允许发生。
过滤器在生物的各个文件里随处可见:在事件中,在伤害感应、索敌之类的组件中,还有生成规则中。学会一次,到处都能用。
文件结构
过滤器没有自己单独的文件。它们写在其他文件里,位于名为 filters 的键下(在生成规则中则是 biome_filter)。
BP/
entities/
ruby_golem.json <- in events and many components
spawn_rules/
ruby_golem.json <- minecraft:biome_filter单个测试
最小的过滤器就是一个测试:
{ "test": "is_family", "subject": "other", "operator": "==", "value": "player" }把它读成一句话:“另一个实体的族群****等于 player 吗?”
| 字段 | 含义 | 如果不写 |
|---|---|---|
test | 要问哪个问题。见下面的表格。 | 必填 |
subject | 问的是谁 | self |
operator | 如何与 value 比较 | equals |
value | 要比较的对象 | 对于是非类测试:true |
domain | 少数测试需要的额外信息,比如装备栏位或属性名 | 取决于测试 |
得益于这些默认值,简短的过滤器很常见:
{ "test": "is_daytime" }
{ "test": "in_water", "value": false }
{ "test": "has_tag", "value": "wiki:tamed" }第一个问“现在是白天吗?”。第二个问“这个生物不在水里吗?”。
主体:测试的是谁
| 主体 | 是谁 |
|---|---|
self | 拥有这个过滤器的生物 |
other | 互动中的另一个实体:被瞄准、被触碰或被互动的那个 |
player | 参与互动的玩家 |
target | 生物当前的目标 |
damager | 在伤害感应中,造成伤害的一方 |
parent | 生物的亲代 |
block | 涉及的方块,用于 is_block 之类的方块测试 |
哪些主体有意义取决于过滤器所在的位置。在伤害感应中,other 和 damager 都是攻击者。在索敌行为中,other 是被考虑作为目标的那个生物。
运算符:如何比较
| 运算符 | 含义 |
|---|---|
==、=、equals | 等于(默认) |
!=、<>、not | 不等于 |
< | 小于 |
<= | 小于或等于 |
> | 大于 |
>= | 大于或等于 |
大于/小于运算符只对 actor_health 或 distance_to_nearest_player 这类数值测试有意义。
组合测试
用组把多个测试放在一起:
| 组 | 何时通过 |
|---|---|
all_of | 里面的每个测试都通过(与) |
any_of | 里面至少一个测试通过(或) |
none_of | 里面没有测试通过(非) |
组里还可以放其他组,所以你能搭建出任何需要的规则。下面这个过滤器在玩家没有潜行,并且是夜晚或雷雨天时通过:
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "is_sneaking", "subject": "other", "value": false },
{
"any_of": [
{ "test": "is_daytime", "value": false },
{ "test": "weather_at_position", "value": "thunderstorm" }
]
}
]
}单纯的列表等于 all_of
如果你只写了一个测试列表而没有写组名,那么每个测试都必须通过,效果和 all_of 一样。原版的生成规则经常这样写。
过滤器用在哪里
伤害感应:根据谁打了你做出反应
"minecraft:damage_sensor": {
"triggers": [
{
"on_damage": {
"filters": { "test": "is_family", "subject": "other", "value": "player" },
"event": "wiki:become_angry"
}
}
]
}只有玩家才会让傀儡生气。来自生物、摔落或火焰的伤害不会引起特殊反应。参见 minecraft:damage_sensor。
索敌:攻击谁
"minecraft:behavior.nearest_attackable_target": {
"priority": 2,
"entity_types": [
{
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "monster" },
{ "test": "is_family", "subject": "other", "operator": "not", "value": "creeper" }
]
},
"max_dist": 16
}
]
}傀儡会猎杀怪物,但不招惹苦力怕。参见 behavior.nearest_attackable_target。
环境感应:对世界做出反应
"minecraft:environment_sensor": {
"triggers": [
{
"filters": { "test": "in_water" },
"event": "wiki:start_rusting"
}
]
}环境感应会持续检查它的过滤器,并在过滤器通过期间触发事件。
事件和生成规则
在事件中,filters 决定某个条目是否执行(参见实体事件)。在生成规则中,minecraft:biome_filter 使用同样的测试来挑选生物群系(参见生成规则)。
最常用的测试
测试一共有一百多种。下面是你最常用到的那些,按检查的内容分组。
它是谁?
| 测试 | 值 | 主体满足以下条件时通过…… |
|---|---|---|
is_family | 族群名,比如 "player" | 在 minecraft:type_family 中有这个族群 |
has_component | 组件 ID,比如 "minecraft:is_baby" | 当前拥有这个组件 |
has_tag | 标签名 | 拥有通过 /tag 添加的这个标签 |
is_baby | true / false | 是幼崽 |
is_tamed | true / false | 已被驯服 |
is_owner | true / false | 是拥有该过滤器的生物的主人 |
has_nametag | true / false | 有自定义名称 |
is_variant | 数字 | minecraft:variant 中是这个数字 |
is_mark_variant | 数字 | minecraft:mark_variant 中是这个数字 |
is_color | 颜色名,比如 "red" | 是这种颜色 |
生命值和状态
| 测试 | 值 | 主体满足以下条件时通过…… |
|---|---|---|
actor_health | 数字 | 生命值与该值比较成立(使用 <、> 等) |
is_missing_health | true / false | 生命值不满 |
has_mob_effect | 效果 ID,比如 "poison" | 拥有这个效果。参见原版效果。 |
on_fire | true / false | 正在燃烧 |
on_ground | true / false | 站在地面上 |
is_sneaking | true / false | 正在潜行 |
is_sprinting | true / false | 正在疾跑 |
is_moving | true / false | 正在移动 |
is_riding | true / false | 正在骑乘另一个实体 |
rider_count | 数字 | 有这么多个骑乘者 |
has_target | true / false | 有可攻击的目标 |
has_damage | 伤害类型,比如 "fall" 或 "fire" | 正在受到这种伤害(用于伤害感应) |
物品
| 测试 | 值 | 主体满足以下条件时通过…… |
|---|---|---|
has_equipment | 物品 ID | 在 domain 指定的栏位(比如 "hand"、"head" 或 "any")中有这个物品 |
has_equipment_tag | 物品标签 | 在 domain 栏位中有带这个标签的物品 |
has_ranged_weapon | true / false | 手持弓或弩 |
它在哪里
| 测试 | 值 | 主体满足以下条件时通过…… |
|---|---|---|
in_water | true / false | 在水中 |
is_underwater | true / false | 完全在水下 |
in_water_or_rain | true / false | 在水中或雨中 |
in_lava | true / false | 在熔岩中 |
is_underground | true / false | 头顶上方有方块 |
in_nether / in_overworld | true / false | 在那个维度中 |
has_biome_tag | 生物群系标签,比如 "desert" | 位于带有该标签的生物群系中。参见原版生物群系。 |
is_biome | 生物群系类型,比如 "ocean" 或 "jungle" | 位于那一大类生物群系中 |
is_altitude | 数字 | 所在高度与该值比较成立 |
is_block | 方块 ID | (配合 "subject": "block")涉及的方块就是这个方块 |
is_in_village | true / false | 在村庄里 |
用 has_biome_tag 还是 is_biome?
优先使用 has_biome_tag。标签更精确,而且其他附加包中的自定义生物群系也可以带有相同的标签。
距离
| 测试 | 值 | 何时通过…… |
|---|---|---|
distance_to_nearest_player | 方块数 | 最近的玩家在这个距离上(使用 < 或 >) |
target_distance | 方块数 | 生物的目标在这个距离上 |
owner_distance | 方块数 | 生物的主人在这个距离上 |
home_distance | 方块数 | 生物的家在这个距离上 |
时间、天气和世界
| 测试 | 值 | 何时通过…… |
|---|---|---|
is_daytime | true / false | 现在是白天 |
hourly_clock_time | 0 到 24000 之间的数字 | 当天时间与该值比较成立 |
moon_phase | 0 到 7 之间的数字 | 月亮处于那个月相 |
weather_at_position | 天气,比如 "thunderstorm" | 主体所在位置的天气相符 |
is_difficulty | "peaceful"、"easy"、"normal" 或 "hard" | 游戏处于那个难度 |
is_game_rule | true / false | domain 中指定的游戏规则已开启 |
random_chance | 数字 | 随机掷骰命中:值为 10 时大约每 10 次通过 1 次 |
实体属性
这些测试读取生物 description 中声明的属性。属性名写在 domain 中:
| 测试 | 值 |
|---|---|
bool_property | true / false |
int_property | 整数 |
float_property | 小数 |
enum_property | values 中的某个词 |
has_property | 属性名(写在 value 中,不需要 domain) |
{ "test": "enum_property", "domain": "wiki:mood", "value": "angry" }出问题时
| 你看到的现象 | 最可能的原因 |
|---|---|
| 过滤器从不通过 | subject 写错了。在伤害感应或索敌中,你通常需要的是 other,而不是 self。 |
| 过滤器在不该通过时通过了 | 想表达“不”的是非类测试漏了 "value": false,或者某个键拼错了(比如 allof)。查看内容日志。 |
| 族群测试失败 | 目标的 minecraft:type_family 列表中没有这个族群 |
| 属性测试失败 | domain 中的属性名与 description.properties 中的不一致 |
| 数值测试表现奇怪 | 漏写了运算符,所以它检查的是完全相等 |
更多帮助请看故障排除。