本篇教程由作者设定使用 CC BY-NC-SA 协议。

(CNC1.3.6及以前,数据包内示例函数有一些小错误,在CNC1.3.X fix1中修复,请注意)

有序合成

这是一个有序合成的示例函数:

execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:20b,id:"minecraft:stick",tag:{CNC_example:0b}},{Slot:11b,id:"minecraft:stick"},{Slot:1b,id:"minecraft:iron_ingot"},{Slot:2b,id:"minecraft:iron_ingot"},{Slot:10b,id:"minecraft:iron_ingot"}]} if entity @s[scores={CNC_table_count=5}] run item replace block ~ ~ ~ container.16 with minecraft:iron_axe{Output:1b,CNC_example:1b }

 

它表示在合成区如下放置物品:

 

铁锭铁锭    
铁锭木棍      

木棍*

 *带有{CNC_example:0b}标签的木棍


时,输出栏输出带有{CNC_example:1b}标签的铁斧。

操作注意事项:

1、 在if block字段下,barrel的NBT里填写合成区摆放的物品,Item列表下,每一个对象是一个物品。其中需写明物品id、NBT标签(即tag,如有)和槽位(即Slot。合成区槽位:由上到下,由左到右依次为:1b,2b,3b;10b,11b,12b;19b,20b,21b)

2、 在if entity字段下的CNC_table_count计分板填写放入合成区的物品一共占用了几个槽位(这一个条件是为了防止多放入物品而设置);

3、 在 item replace 字段下填写输出物品数据,和give命令的格式相同;

4、 但需要在输出物品下添加{Output:1b}的标签,否则不能正常工作。

5、 如果你的配方支持平移或镜像合成,你需要将平移或镜像后的配方按新的槽位位置再写一遍,即需要穷举所有可能情况。

无序合成

无重复物品的无序合成

无序合成的语法与有序合成相同,唯一的区别在于填写合成区物品时不写Slot标签;

因此,有序合成和无序合成可以混用,你可以指定部分物品按指定方式排列,而另一部分物品随意排列。

以下是末影之眼的完整示例:

execute if block ~ ~ ~ minecraft:barrel{Items:[{id:"minecraft:blaze_powder"},{id:"minecraft:ender_pearl"}]} if entity @s[scores={CNC_table_count=2}] run item replace block ~ ~ ~ container.16 with ender_eye

有重复物品的无序合成

因为在if里填入多个相同对象不会让数据包检测多个物品,只要有一个这样的物品就会通过这个条件,所以对于有重复物品的无序合成配方,需要用计分板方法辅助判定。

在主要命令前加入以下命令:

execute store result score @s CNC_SLout if data block ~ ~ ~ Items[{id:"minecraft:paper"}]

计分板CNC_SLout是预设的无序合成判定用的计分板,你可以换成自己的,只要上下一致,没有关系。

在下面的主函数中,在if entity字段后的条件中加入CNC_SLout的计分板,其分数为该物品的个数:

execute if block ~ ~ ~ minecraft:barrel{Items:[{id:"minecraft:paper"},{id:"minecraft:leather"}]} if entity @s[scores={CNC_table_count=4,CNC_SLout=3}] run item replace block ~ ~ ~ container.16 with book{Output:1b}

对于有多种重复物品的无序合成,使用多个计分板,如法炮制即可。

已预设的计分板有:CNC_SLout,CNC_SLout2,CNC_SLout3,CNC_SLout4

以下是书的合成的完整示例:

#无序合成模块
execute store result score @s CNC_SLout if data block ~ ~ ~ Items[{id:"minecraft:paper"}]
#主命令
execute if block ~ ~ ~ minecraft:barrel{Items:[{id:"minecraft:paper"},{id:"minecraft:leather"}]} if entity @s[scores={CNC_table_count=4,CNC_SLout=3}] run item replace block ~ ~ ~ container.16 with book{Output:1b}

替换合成栏物品(需要版本1.4及以上)

替换合成栏物品:有时合成物品后,合成栏内部分物品不需要清除,只需要将其替换为其他物品或不作改动。

此时可以用以下方法实现:主函数结束后检测输出栏物品,若为本配方的目标物品,则将对应合成栏位的计分板(CNC_replace_1~9,见下例)设置为指定值,该值需要在cnc/funcctions/machine/crafting_table/recipes/clear/replacements.mcfunction文件中建立对应,操作方法见对应函数中的示例。

已有的预设:0为不动(没有建立对应的值都是不动),1为替换成桶(适用于水桶、熔岩桶、牛奶桶),2为空瓶(处理较为特殊,适用于药水、蜂蜜瓶)

若该槽位物品数量大于1(如堆叠了多个蜂蜜瓶),则向玩家返还一个被替换的物品,同时合成栏槽位物品数量减1,;若数量等于1,则将该槽位物品替换为指定物品。

示例1:蛋糕的合成

#主命令
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:1b,id:"minecraft:milk_bucket"},{Slot:2b,id:"minecraft:milk_bucket"},{Slot:3b,id:"minecraft:milk_bucket"},{Slot:10b,id:"minecraft:sugar"},{Slot:12b,id:"minecraft:sugar"},{Slot:11b,id:"minecraft:egg"},{Slot:19b,id:"minecraft:wheat"},{Slot:20b,id:"minecraft:wheat"},{Slot:21b,id:"minecraft:wheat"}]} if entity @s[scores={CNC_table_count=9}] run item replace block ~ ~ ~ container.16 with minecraft:cake{Output:1b}
#检测替换
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:cake"}]} run scoreboard players set @s CNC_replace_1 1
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:cake"}]} run scoreboard players set @s CNC_replace_2 1
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:cake"}]} run scoreboard players set @s CNC_replace_3 1


如果要替换的物品没有确定的槽位,则需要穷举检测其槽位。

示例2:由蜂蜜合成糖

#主命令
execute if block ~ ~ ~ minecraft:barrel{Items:[{id:"minecraft:honey_bottle"}]} if entity @s[scores={CNC_table_count=1}] run item replace block ~ ~ ~ container.16 with minecraft:sugar{Output:1b} 3
#检测替换
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:1b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_1 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:2b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_2 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:3b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_3 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:10b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_4 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:11b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_5 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:12b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_6 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:19b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_7 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:20b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_8 2
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:16b,id:"minecraft:sugar"},{Slot:21b,id:"minecraft:honey_bottle"}]} run scoreboard players set @s CNC_replace_9 2

包含tag的配方(版本1.3.7及以上)

1.3.7版本及以上支持此方法。

在旧版的基础上稍微简化了操作,但是对性能消耗较大。

首先断言文件的写法稍有不同:

{
  "condition": "minecraft:inverted",
  "term": {
      "condition": "minecraft:alternative",
      "terms": [
        {
          "condition": "minecraft:inverted",
          "term": {
            "condition": "minecraft:entity_properties",
            "entity": "this",
            "predicate": {
              "equipment": {
                "chest": {
                  "tag": "minecraft:planks"
                }
              }
            }
          }
        },
        {
          "condition": "minecraft:inverted",
          "term": {
            "condition": "minecraft:entity_scores",
            "entity": "this",
            "scores": {
              "CNC_tag_id":-1
            }
          }
        }
      ]
  }
}

使用与门的写法写一个 同时满足分数和物品tag 的条件,建议复制示例断言,记得更改id数值(CNC_tag_id计分板)

然后将此断言引用到主断言中(路径为data/cnc/predicates/crafting_table/tag_main.mcfunction)

主断言中已有一些示例:

{
    "condition": "minecraft:alternative",
    "terms": [
        {
            "condition": "minecraft:reference",
            "name": "cnc:crafting_table/planks"
        },
        {
            "condition": "minecraft:reference",
            "name": "cnc:crafting_table/slabs"
        }
    ]
}

再在配方函数中引用。注意先将CNC_tag_id计分板设为你设置的id值

检测完成后将会将得到的结果记录在盔甲架的CNC_craftag计分板上,以便进一步处理

示例1:碗的合成

#初始化
scoreboard players reset @s CNC_tag_out
scoreboard players reset @s CNC_craftag
#设置id(该id应与你设置的断言文件指定的id一致)
scoreboard players set @s CNC_tag_id -1
#tag检测
#设置CNC_tag_slot为0,检测全部槽位
scoreboard players set @s CNC_tag_slot 0
function cnc:machine/crafting_table/tag
execute if score @s CNC_craftag matches 3 run scoreboard players set @s CNC_tag_out 1
#主命令
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:1b},{Slot:11b},{Slot:3b}]} if entity @s[scores={CNC_table_count=3,CNC_tag_out=1}] run item replace block ~ ~ ~ container.16 with bowl
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:10b},{Slot:20b},{Slot:12b}]} if entity @s[scores={CNC_table_count=3,CNC_tag_out=1}] run item replace block ~ ~ ~ container.16 with bowl{Output:1b}


对多个tag检测与只对部分槽位检测,使用旧版方法穷举是性能上最佳的方法,见tag_old函数;

如果觉得穷举法较为困难难以掌握,CNC支持一种操作上较为简便,但性能消耗较大的方法:


对多个槽位检测,先检测一个tag,将得到的分数转存在一个计分板上,(CNC提供9个计分板预设:CNC_tag_out计分板,及CNC_tag_out2~9 这8个计分板)然后检测另一个tag,将得到的分数转存在另一个计分板上,然后在主函数中调用这两个计分板的分数即可;(示例中使用一种“开关”的方法,即预先判断返回值是否符合预期,若是则将CNC_tag_out设置为1;当然直接储存返回值再在主函数中判定亦可);

注意检测每个tag前都需要初始化


只对部分槽位检测,需要设置CNC_tag_slot分数,按照二进制计算(第一个槽位为1,第二个为2,第三个为4,以此类推,最后加在一起)

#如果要检测全部槽位,建议将该值设为0而不是511。


示例2:木桶的合成

#tag检测
#检测木板(槽位:1+3+4+6+7+9,数值1+4+8+32+64+256=365)
scoreboard players reset @s CNC_craftag
scoreboard players reset @s CNC_tag_out
scoreboard players set @s CNC_tag_id -1
scoreboard players set @s CNC_tag_slot 365
function cnc:machine/crafting_table/tag
execute if score @s CNC_craftag matches 6 run scoreboard players set @s CNC_tag_out 1
#检测台阶(槽位:2+8,数值2+128=130)
scoreboard players reset @s CNC_craftag
scoreboard players reset @s CNC_tag_out2
scoreboard players set @s CNC_tag_id -2
scoreboard players set @s CNC_tag_slot 130
function cnc:machine/crafting_table/tag
execute if score @s CNC_craftag matches 2 run scoreboard players set @s CNC_tag_out2 1
#主命令
execute if entity @s[scores={CNC_table_count=8,CNC_tag_out=1,CNC_tag_out2=1}] run item replace block ~ ~ ~ container.16 with barrel{Output:1b}


旧版tag检测方式依然可用,见下方:

包含tag的配方_旧版(所有已发布CNC版本均可用)

操作方法较为复杂。

首先设置断言:

{
      "condition": "minecraft:entity_properties",
      "entity": "this",
      "predicate": {
        "equipment": {
          "chest": {
            "tag": "minecraft:planks"
          }
        }
      }
}

 

物品在此tag中,断言通过。

然后在函数中引用该断言。

建议先复制下面这段命令(CNC1.3.6及以前,数据包内示例函数中的这一段是有误的,计分板应该是CNC_craftag而不是CAM_craftag,在CNC1.3.X fix1中修复)

#初始化
scoreboard players reset @s CNC_craftag
#检测tag
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:1b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:2b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:3b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:10b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:11b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:12b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:19b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:20b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:21b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1

 

可以看到,在#检测tag下面,有9组命令,每组3行,这是对9个合成栏槽位进行穷举。

在每组的第三行引用了断言文件(if entity @s[predicate=cnc:crafting_table/planks]),将predicate后面的断言路径改成你自己的断言路径即可。

 

接下来在配方主函数中,如果是无序合成,则if block字段中不需填写tag物品的相关消息;如果是有序合成,则需要填写tag物品的槽位。注意不要写id。

然后在if entity字段中加入CNC_craftag计分板的分数,即tag物品的总数即可。以下是碗的合成的完整示例:

 

#初始化
scoreboard players reset @s CNC_craftag
#检测tag
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:1b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:2b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:3b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:10b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:11b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:12b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:19b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:20b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:21b}].id
execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CNC_craftag 1
#主命令
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:1b},{Slot:11b},{Slot:3b}]} if entity @s[scores={CNC_table_count=3,CNC_craftag=3}] run item replace block ~ ~ ~ container.16 with bowl{Output:1b}
execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:10b},{Slot:20b},{Slot:12b}]} if entity @s[scores={CNC_table_count=3,CNC_craftag=3}] run item replace block ~ ~ ~ container.16 with bowl{Output:1b}