CR_019
本帖最后由 CR_019 于 2022-3-26 21:53 编辑

第四版前言
最近对1.3版本进行了一些不小的改进,同时该原理简介已经过于老旧(还停留在1.16版本),因此更新一下此贴,使其适用于最新版本的MC和CNC数据包。

正文
载入计分板
cnc/functions/machine/crafting_table/load:
  1. <div align="left">scoreboard objectives add CNC_crafterror dummy</div><div align="left">scoreboard objectives add CNC_table_count dummy</div><div align="left">scoreboard objectives add CNC_output dummy</div><div align="left">scoreboard objectives add CNC_clear dummy</div><div align="left">scoreboard objectives add CNC_shiftdealt dummy</div><div align="left">scoreboard objectives add CNC_shiftcount dummy</div><div align="left">scoreboard objectives add CNC_player_count dummy</div><div align="left">scoreboard objectives add CNC_bottlecount dummy</div><div align="left">scoreboard objectives add CNC_item_trigger dummy</div><div align="left">scoreboard objectives add CNC_shift_muti dummy</div><div align="left">scoreboard objectives add CNC_shapeless dummy</div><div align="left">scoreboard objectives add CNC_SLtemp dummy</div><div align="left">scoreboard objectives add CNC_SLout dummy</div><div align="left">scoreboard objectives add CNC_SLout2 dummy</div><div align="left">scoreboard objectives add CNC_SLout3 dummy</div><div align="left">scoreboard objectives add CNC_SLout4 dummy</div><div align="left">scoreboard objectives add CNC_craftag dummy</div><div align="left">scoreboard objectives add CNC_rclick dummy</div><div align="left">scoreboard objectives add CNC_rclick_sub dummy</div><div align="left">scoreboard objectives add CNC_rclick_suc dummy</div><div align="left">scoreboard objectives add CNC_rclick_sub2 dummy</div><div align="left">scoreboard objectives add CNC_rclick_sub3 dummy</div><div align="left">scoreboard objectives add CNC_replace_err dummy</div><div align="left">scoreboard objectives add CNC_tag_id dummy</div><div align="left">scoreboard objectives add CNC_tag_slot dummy</div><div align="left">scoreboard objectives add CNC_tag_count dummy</div>
  2. <div align="left">scoreboard objectives add CNC_tag_out dummy</div><div align="left">scoreboard objectives add CNC_tag_out2 dummy</div><div align="left">scoreboard objectives add CNC_tag_out3 dummy</div><div align="left">scoreboard objectives add CNC_tag_out4 dummy</div><div align="left">scoreboard objectives add CNC_tag_out5 dummy</div><div align="left">scoreboard objectives add CNC_tag_out6 dummy</div><div align="left">scoreboard objectives add CNC_tag_out7 dummy</div><div align="left">scoreboard objectives add CNC_tag_out8 dummy</div><div align="left">scoreboard objectives add CNC_tag_out9 dummy</div>
  3. <div align="left">scoreboard objectives add CNC_replace dummy</div><div align="left">scoreboard objectives add CNC_replace_1 dummy</div><div align="left">scoreboard objectives add CNC_replace_2 dummy</div><div align="left">scoreboard objectives add CNC_replace_3 dummy</div><div align="left">scoreboard objectives add CNC_replace_4 dummy</div><div align="left">scoreboard objectives add CNC_replace_5 dummy</div><div align="left">scoreboard objectives add CNC_replace_6 dummy</div><div align="left">scoreboard objectives add CNC_replace_7 dummy</div><div align="left">scoreboard objectives add CNC_replace_8 dummy</div><div align="left">scoreboard objectives add CNC_replace_9 dummy</div>
  4. <div align="left">scoreboard objectives add CNC_pd dummy</div>
  5. <div align="left">scoreboard objectives add CNC_constant dummy</div><div align="left">scoreboard players set C_2 CNC_constant 2</div>
复制代码
每刻运行函数:

cnc/functions/machine/crafting_table/tick:
  1. <div align="left">   #开头基础处理:物品处理 初始化变量</div><div align="left">kill @e[predicate=cnc:crafting_table/bg]</div><div align="left">execute store result score @a CNC_crafterror run clear @a minecraft:firework_star{CNC_bg:1b} 0</div><div align="left">execute as @a store success score @s CNC_pd run clear @s #uin:tech/all{Output:1b} 0</div>
  2. <div align="left">#放置与破坏处理</div><div align="left">execute as @e[type=minecraft:armor_stand,tag=cnc_crafting] at @s run function cnc:machine/crafting_table/tick_</div><div align="left">#功能</div>
  3. <div align="left">#Shift键处理</div><div align="left">execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] run tag @s add CNC_shiftcheck</div><div align="left">execute if entity @a[tag=CNC_shiftcheck] as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s unless data block ~ ~ ~ {Items:[{Slot:16b}]} run function cnc:machine/crafting_table/shiftcheck</div><div align="left">#配方处理</div><div align="left">execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s if entity @a[distance=..8] run function cnc:machine/crafting_table/recipe</div><div align="left">#输出标签处理</div><div align="left">execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] at @s run function cnc:machine/crafting_table/inventory</div><div align="left">#误放入处理</div><div align="left">execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s if entity @a[distance=..8] run function cnc:machine/crafting_table/check</div><div align="left">#Shift键处理 初始化tag</div><div align="left">tag @a remove CNC_shiftcheck</div>
  4. <div align="left">#结尾基础处理:物品处理 初始化变量</div><div align="left">clear @a firework_star{CNC_bg:1b}</div><div align="left">kill @e[type=item,nbt={Item:{tag:{CNC_bg:1b}}}]</div><div align="left">scoreboard players reset @a CNC_replace_err</div><div align="left">scoreboard players reset $temp CNC_rclick_suc</div><div align="left">scoreboard players reset @a CNC_rclick</div>
复制代码

在子页面中,将逐条介绍各个功能,其中shift处理由于与下面的配方处理有关,故放在后面讲。

2021.12 数据,可能有更多内容


前言
一年过后,我把这个包提取出来,对一些上一版存在的缺陷进行了修复和改进,并且发布。
    在CNC发布之际,有必要把新增与修改的功能讲解一遍。
    适合有一定命令和数据包开发基础的玩家阅读。
    与上一版重复的部分不作提示。
正文
加载时运行函数:
cnc/functions/machine/crafting_table/load:

代码:

  1. scoreboard objectives add CNC_crafterror dummy
  2. scoreboard objectives add CNC_table_count dummy
  3. scoreboard objectives add CNC_output dummy
  4. scoreboard objectives add CNC_clear dummy
  5. scoreboard objectives add CNC_shiftdealt dummy
  6. scoreboard objectives add CNC_shiftcount dummy
  7. scoreboard objectives add CNC_player_count dummy
  8. scoreboard objectives add CNC_bottlecount dummy
  9. scoreboard objectives add CNC_item_trigger dummy
  10. scoreboard objectives add CNC_shift_muti dummy
  11. scoreboard objectives add CNC_shapeless dummy
  12. scoreboard objectives add CNC_SLtemp dummy
  13. scoreboard objectives add CNC_SLout dummy
  14. scoreboard objectives add CNC_craftag dummy
  15. scoreboard objectives add CNC_rclick dummy
  16. scoreboard objectives add CNC_rclick_sub dummy
  17. scoreboard objectives add CNC_rclick_suc dummy
  18. scoreboard objectives add CNC_rclick_sub2 dummy
  19. scoreboard objectives add CNC_rclick_sub3 dummy

加载数据包用到的计分板。
每刻运行函数:
cnc/functions/machine/crafting_table/tick:

代码:

  1. #开头基础处理:物品处理 初始化变量
  2. kill @e[nbt={Item:{tag:{CNC_bg:1b}}}]
  3. execute store result score @a CNC_crafterror run clear @a minecraft:firework_star{CNC_bg:1b} 0
  4. execute as @a store result score @s CNC_bottlecount run clear @a #nbt_crafting:cam_recipes 0

  5. #放置与破坏处理
  6. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting] at @s align xyz if block ~ ~ ~ minecraft:crafting_table run function cnc:machine/crafting_table/replace
  7. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s unless block ~ ~ ~ minecraft:barrel run function cnc:machine/crafting_table/clear
  8. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] run data modify entity @s Fire set value 32767s
  9. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/gui

  10. #功能

  11. #Shift键处理
  12. execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] run tag @s add CNC_shiftcheck
  13. execute if entity @a[tag=CNC_shiftcheck] as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s unless data block ~ ~ ~ {Items:[{Slot:16b}]} run function cnc:machine/crafting_table/shiftcheck
  14. #配方处理
  15. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/recipe
  16. #输出标签处理
  17. execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] at @s run function cnc:machine/crafting_table/inventory
  18. #误放入处理
  19. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/check
  20. #Shift键处理 初始化tag
  21. tag @a remove CNC_shiftcheck


  22. #结尾基础处理:物品处理 初始化变量
  23. clear @a firework_star{CNC_bg:1b}
  24. scoreboard players reset $temp CNC_rclick_suc
  25. scoreboard players reset @a CNC_rclick

#开头基础处理 #放置与破坏处理


#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入处理模块的计分板重置#放置与破坏处理:第1条:检测放置合成台(配合进度),第2条:检测破坏合成台第3条:防止盔甲架变黑
第4条:防止位于0槽位的gui被移动


#功能见子页面
#配方处理:

代码:

  1. #配方处理
  2. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/recipe
cnc/functions/machine/crafting_table/recipe:

代码:

  1. #获取已占槽位
  2. function cnc:machine/crafting_table/recipes/count
  3. #右键侦测前置
  4. execute as @a store result score @s CNC_rclick run clear @s #uin:tech/all{Output:1b} 0
  5. execute as @a store result score @s CNC_rclick_sub run clear @s #uin:tech/all{Output:1b,CNC_bg:1b} 0
  6. execute as @a run scoreboard players operation @s CNC_rclick -= @s CNC_rclick_sub
  7. execute at @s if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b,CNC_bg:1b}}]} store result score @s CNC_rclick_sub3 run data get block ~ ~ ~ Items[{Slot:16b}].Count
  8. execute as @s run scoreboard players operation @s CNC_rclick_sub2 -= @s CNC_rclick_sub3
  9. scoreboard players operation @s 6 = @s CNC_rclick_sub2
  10. #清除合成区物品
  11. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CNC_not_to_clear] run function cnc:machine/crafting_table/recipes/clear
  12. tag @s remove CNC_not_to_clear
  13. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CNC_bg:1b}}]} run tag @s add CNC_not_to_clear
  14. execute at @s if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b,CNC_bg:1b}}]} unless score @s CNC_rclick_sub2 matches 0 if entity @a[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] run function cnc:machine/crafting_table/rightclick
  15. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
  16. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} at @s run function cnc:machine/crafting_table/replace/16_spe
  17. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} at @s run clear @a[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] #uin:tech/all{Output:1b}
  18. #配方检测
  19. function #cnc:recipes
  20. #右键侦测前置
  21. execute at @s if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b,CNC_bg:1b}}]} store result score @s CNC_rclick_sub2 run data get block ~ ~ ~ Items[{Slot:16b}].Count
  22. #初始化变量
  23. scoreboard players reset @s CNC_table_count
  24. #shift处理相关
  25. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} run scoreboard players add @s CNC_shiftdealt 1

#获取已占槽位:
为配方的判定做准备,判定有多少个合成槽位有物品,以防止多放物品的情况无法被检测到;
使用计分板处理。
cnc/functions/machine/crafting_table/recipes/count:

代码:

  1. execute if data block ~ ~ ~ Items[{Slot:1b}] run scoreboard players add @s CNC_table_count 1
  2. execute if data block ~ ~ ~ Items[{Slot:2b}] run scoreboard players add @s CNC_table_count 1
  3. execute if data block ~ ~ ~ Items[{Slot:3b}] run scoreboard players add @s CNC_table_count 1
  4. execute if data block ~ ~ ~ Items[{Slot:10b}] run scoreboard players add @s CNC_table_count 1
  5. execute if data block ~ ~ ~ Items[{Slot:11b}] run scoreboard players add @s CNC_table_count 1
  6. execute if data block ~ ~ ~ Items[{Slot:12b}] run scoreboard players add @s CNC_table_count 1
  7. execute if data block ~ ~ ~ Items[{Slot:19b}] run scoreboard players add @s CNC_table_count 1
  8. execute if data block ~ ~ ~ Items[{Slot:20b}] run scoreboard players add @s CNC_table_count 1
  9. execute if data block ~ ~ ~ Items[{Slot:21b}] run scoreboard players add @s CNC_table_count 1

#清除合成区物品:
检测输出物品被拿取时,将合成区物品数量-1;
检测的方式是这样的:
在输出栏(槽位16)空置时,占位物品有两个标签:&quot;CNC_bg:1b&quot;和&quot;Output:1b&quot;
输出栏有输出物品时,该物品有一个标签:&quot;Output:1b&quot;
而当玩家拿出输出栏物品后,有一个短暂的“真空期”,即在输出栏没有物品。
这里根据这三种状态的不同来判定玩家是否拿出输出栏物品。但是这种方法不能检测出右键拿取物品的行为。

代码:

  1. #清除合成区物品(截取模块)
  2. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CNC_not_to_clear] run function cnc:machine/crafting_table/recipes/clear
  3. tag @s remove CNC_not_to_clear
  4. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CNC_bg:1b}}]} run tag @s add CNC_not_to_clear
  5. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
cnc/functions/machine/crafting_table/recipes/clear:

代码:

  1. function cnc:machine/crafting_table/recipes/clear/1
  2. function cnc:machine/crafting_table/recipes/clear/2
  3. function cnc:machine/crafting_table/recipes/clear/3
  4. function cnc:machine/crafting_table/recipes/clear/10
  5. function cnc:machine/crafting_table/recipes/clear/11
  6. function cnc:machine/crafting_table/recipes/clear/12
  7. function cnc:machine/crafting_table/recipes/clear/19
  8. function cnc:machine/crafting_table/recipes/clear/20
  9. function cnc:machine/crafting_table/recipes/clear/21



这是一个穷举模块,在清除合成栏物品的同时,对药水、蜂蜜瓶等物品进行特殊处理。展示其中一个函数,其余类推,下同;
cnc/functions/machine/crafting_table/recipes/clear/1:

代码:

  1. execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle"}]} unless data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} run give @a[scores={CNC_bottlecount=1..},limit=1,sort=nearest] glass_bottle 1
  2. execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} run replaceitem block ~ ~ ~ container.1 minecraft:glass_bottle 2
  3. execute as @s unless data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:potion"}]} unless data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} store result block ~ ~ ~ Items[{Slot:1b}].Count byte 0.99 run data get block ~ ~ ~ Items[{Slot:1b}].Count

#右键侦测:

代码:

  1. #右键侦测(截取模块)
  2. #右键侦测前置
  3. execute as @a store result score @s CNC_rclick run clear @s #uin:tech/all{Output:1b} 0
  4. execute as @a store result score @s CNC_rclick_sub run clear @s #uin:tech/all{Output:1b,CNC_bg:1b} 0
  5. execute as @a run scoreboard players operation @s CNC_rclick -= @s CNC_rclick_sub
  6. execute at @s if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b,CNC_bg:1b}}]} store result score @s CNC_rclick_sub3 run data get block ~ ~ ~ Items[{Slot:16b}].Count
  7. execute as @s run scoreboard players operation @s CNC_rclick_sub2 -= @s CNC_rclick_sub3
  8. scoreboard players operation @s 6 = @s CNC_rclick_sub2
  9. #清除合成区物品
  10. execute at @s if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b,CNC_bg:1b}}]} unless score @s CNC_rclick_sub2 matches 0 if entity @a[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] run function cnc:machine/crafting_table/rightclick
  11. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} at @s run clear @a[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] #uin:tech/all{Output:1b}
  12. #右键侦测前置
  13. execute at @s if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b,CNC_bg:1b}}]} store result score @s CNC_rclick_sub2 run data get block ~ ~ ~ Items[{Slot:16b}].Count

当一个配方的产物数量大于1时,玩家在输出栏点击右键,会拿取其中的一半物品,此时不能检测到输出栏物品被拿取,合成栏物品不会被清除,而在下一刻配方处理模块会将输出栏物品的数量复位,导致可以无限刷物品,这也是上一个版本中较为严重的一个问题。
这里设计这个模块来防止。


#开头的右键侦测前置:
分两部分,第一部分为前三条命令,判定手上拿着输出物品(含有&quot;Output:1b&quot;标签,该标签在玩家物品栏中会被清除)的玩家;
第二部分为后两条命令,与结尾的右键侦测前置一起,原来规避一种重大问题,在讲结尾前置的时候一并提及。
#右键侦测主命令:
合成台侦测周围有手上拿着输出物品的玩家,且自己的输出栏内仍有输出物品,则判定为玩家使用右键拿取了物品,触发右键操作函数
cnc/functions/machine/crafting_table/rightclick:

代码:

  1. #清除手里的物品
  2. clear @a[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] #uin:tech/all{Output:1b}
  3. #重载配方
  4. replaceitem block ~ ~ ~ container.16 air
  5. function #cnc:recipes
  6. #物品给予
  7. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  8. execute if data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[{Slot:16b}]
  9. execute unless data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set value {Slot:0b,id:"minecraft:air",Count:1b}
  10. execute as @e[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] store result score $temp CNC_rclick_suc run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  11. setblock ~ 255 ~ air
  12. #清除合成区物品
  13. execute if score $temp CNC_rclick_suc matches 1.. run function cnc:machine/crafting_table/recipes/clear

    该操作先清除手中拿取的物品,然后重新载入配方,使输出栏物品数量恢复,然后使用rua影盒技术(误)将输出栏物品放到玩家物品栏中,最后清除合成区物品。
#结尾的右键侦测前置:  这么处理还有一个严重的问题,就是当用左键拿出物品后,在下一刻,合成台执行了配方模块函数,把配方复位后,就能够满足“右键侦测”条件,从而把物品复制到玩家物品栏中。表现上为左键和右键行为一样。  因此,在这一刻的结尾(经配方模块复位)执行获取输出栏的物品数量,在下一刻的开头(玩家操作后)再执行一次,并比较两者是否相同。若相同,则表示玩家未使用右键,不触发右键操作,反之亦然。
    在清除合成区物品和右键侦测模块中还有这么一行:

代码:

  1. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} at @s run function cnc:machine/crafting_table/replace/16_spe
这是误放入处理的特殊处理,适用于在槽位16有输出物品的时候的处理,到误放入处理时讲解。
#配方检测
检测自定义的配方,见自定义配方的操作方法。
#shift处理相关:见Shift处理。



#输出标签处理:

代码:

  1. #输出标签处理
  2. execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] at @s run function cnc:machine/crafting_table/inventory

cnc/functions/machine/crafting_table/inventory:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}

  2. execute if data entity @s {Inventory:[{Slot:0b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/0
  3. execute if data entity @s {Inventory:[{Slot:1b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/1
  4. execute if data entity @s {Inventory:[{Slot:2b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/2
  5. execute if data entity @s {Inventory:[{Slot:3b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/3
  6. execute if data entity @s {Inventory:[{Slot:4b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/4
  7. execute if data entity @s {Inventory:[{Slot:5b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/5
  8. execute if data entity @s {Inventory:[{Slot:6b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/6
  9. execute if data entity @s {Inventory:[{Slot:7b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/7
  10. execute if data entity @s {Inventory:[{Slot:8b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/8
  11. execute if data entity @s {Inventory:[{Slot:9b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/9
  12. execute if data entity @s {Inventory:[{Slot:10b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/10
  13. execute if data entity @s {Inventory:[{Slot:11b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/11
  14. execute if data entity @s {Inventory:[{Slot:12b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/12
  15. execute if data entity @s {Inventory:[{Slot:13b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/13
  16. execute if data entity @s {Inventory:[{Slot:14b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/14
  17. execute if data entity @s {Inventory:[{Slot:15b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/15
  18. execute if data entity @s {Inventory:[{Slot:16b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/16
  19. execute if data entity @s {Inventory:[{Slot:17b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/17
  20. execute if data entity @s {Inventory:[{Slot:18b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/18
  21. execute if data entity @s {Inventory:[{Slot:19b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/19
  22. execute if data entity @s {Inventory:[{Slot:20b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/20
  23. execute if data entity @s {Inventory:[{Slot:21b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/21
  24. execute if data entity @s {Inventory:[{Slot:22b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/22
  25. execute if data entity @s {Inventory:[{Slot:23b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/23
  26. execute if data entity @s {Inventory:[{Slot:24b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/24
  27. execute if data entity @s {Inventory:[{Slot:25b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/25
  28. execute if data entity @s {Inventory:[{Slot:26b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/26
  29. execute if data entity @s {Inventory:[{Slot:27b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/27
  30. execute if data entity @s {Inventory:[{Slot:28b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/28
  31. execute if data entity @s {Inventory:[{Slot:29b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/29
  32. execute if data entity @s {Inventory:[{Slot:30b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/30
  33. execute if data entity @s {Inventory:[{Slot:31b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/31
  34. execute if data entity @s {Inventory:[{Slot:32b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/32
  35. execute if data entity @s {Inventory:[{Slot:33b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/33
  36. execute if data entity @s {Inventory:[{Slot:34b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/34
  37. execute if data entity @s {Inventory:[{Slot:35b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/35



  38. setblock ~ 255 ~ air

cnc/functions/machine/crafting_table/inventory/0:

代码:

  1. data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{Slot:0b}].id
  2. data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{Slot:0b}].Count
  3. data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{Slot:0b}].tag
  4. data remove block ~ 255 ~ Items[0].tag.Output
  5. loot replace entity @s hotbar.0 1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}

使用穷举的方法,结合rua影盒技术,除去在玩家物品栏的输出物品的输出标签&quot;Output&quot;
注意用loot replace 和replaceitem 时注意快捷栏是hotbar0~8对应Inventory中Slot的0~8,inventory的0~26对应Inventory中的9~35。注意用loot replace 和replaceitem 时注意快捷栏是hotbar0~8对应Inventory中Slot的0~8,loot命令中inventory的0~26对应Inventory中的9~35。
#误放入处理

代码:

  1. #误放入处理
  2. execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/check
cnc/functions/machine/crafting_table/check:

代码:

  1. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:0b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/0
  2. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/16
  3. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:4b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/4
  4. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:5b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/5
  5. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:6b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/6
  6. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:7b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/7
  7. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:8b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/8
  8. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:9b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/9
  9. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:13b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/13
  10. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:14b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/14
  11. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:15b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/15
  12. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:17b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/17
  13. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:18b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/18
  14. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:22b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/22
  15. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:23b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/23
  16. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:24b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/24
  17. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:25b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/25
  18. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:26b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/26
cnc/functions/machine/crafting_table/replace/0:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[0]
  3. data modify block ~ ~ ~ Items[0] set value {id:"minecraft:firework_star",Count:1b,Slot:0b,tag:{CustomModelData:9102024,display:{Name:"{"translate":"item.cnc.crafting_table"}"},CNC_bg:1b}}
  4. execute as @e[sort=nearest,limit=1,scores={CNC_crafterror=1..}] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  5. execute at @s run setblock ~ 255 ~ air

cnc/functions/machine/crafting_table/replace/16_spe:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. execute if data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[{Slot:16b}]
  3. execute unless data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set value {Slot:0b,id:"minecraft:air",Count:1b}
  4. execute as @e[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  5. setblock ~ 255 ~ air

使用穷举,判定误放入合成台背景或输出栏的物品,并返还给玩家。
输出栏有物品的情况由配方检测处的那一条命令处理。



#shift键处理:
重头戏。

代码:

  1. #Shift键处理
  2. execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] run tag @s add CNC_shiftcheck
  3. execute if entity @a[tag=CNC_shiftcheck] as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s unless data block ~ ~ ~ {Items:[{Slot:16b}]} run function cnc:machine/crafting_table/shiftcheck
首先检测背包里有标签&quot;Output:1b&quot;物品的玩家,给这个玩家加上CAM_shiftcheck的tag,然后检测是否有此tag的玩家,如有则以第16槽位为“真空”的合成台为执行者执行命令通过这两个(红字)条件,可判定玩家是否使用了shift,具体原因见SPGoding该问题中的解答:
单纯左键:该物品立刻消失,直到玩家再次左键放下前,检测不到该物品。Shift + 左键:该物品立刻消失并立刻出现在玩家物品栏内。



shift检测:cnc/functions/machine/crafting_table/shiftcheck:

代码:

  1. #初始化变量和tag
  2. scoreboard players set @s CNC_shiftdealt 2
  3. scoreboard players set @a CNC_player_count 37
  4. scoreboard players reset @a CNC_item_trigger
  5. #检测玩家剩余槽位数和当前物品最大可堆叠数量,以及计分板数据转移
  6. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CNC_shiftcheck] at @s run function cnc:machine/crafting_table/shift_player
  7. scoreboard players operation @s CNC_player_count = @e[tag=CNC_shiftcheck] CNC_player_count
  8. function cnc:machine/crafting_table/shift_data_get
  9. scoreboard players operation @s CNC_player_count *= @s CNC_item_trigger
  10. execute store result score @s CNC_shift_muti run clear @a[tag=CNC_shiftcheck] #uin:tech/all{Output:1b} 0
  11. scoreboard players operation @s CNC_shiftdealt *= @s CNC_shift_muti
  12. #模拟执行合成操作,以确定可执行的最大合成次数
  13. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @e[tag=CNC_shiftcheck] run function cnc:machine/crafting_table/shifttest
  14. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless score @s CNC_shiftdealt < @s CNC_player_count run function cnc:machine/crafting_table/recipes/clear
  15. scoreboard players operation @s CNC_shiftdealt /= @s CNC_shift_muti
  16. #补偿机制相关
  17. execute as @e[tag=CNC_comp] run scoreboard players remove @s CNC_shiftdealt 1
  18. #清除输出栏
  19. replaceitem block ~ ~ ~ container.16 minecraft:air
  20. #(辅助)给予次数运算
  21. scoreboard players remove @s CNC_shiftdealt 2
  22. #计分板数据转移
  23. scoreboard players operation @e[tag=CNC_shiftcheck] CNC_shiftdealt = @s CNC_shiftdealt
  24. #给予玩家物品
  25. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CNC_shiftcheck] at @s run function cnc:machine/crafting_table/shiftdealt
  26. #输出栏处理
  27. execute if entity @e[tag=CNC_shiftcheck] run replaceitem block ~ ~ ~ container.16 minecraft:firework_star{CustomModelData:9102025,display:{Name:"{"translate":"item.cnc.crafting_table_output"}"},CNC_bg:1b,Output:1b}
  28. #初始化
  29. tag @s remove CNC_comp

里面所谓的计分板数据转移是因为命令的执行者不同:玩家或合成台(即在合成台位置的盔甲架)而计算时把数据放在一起会省事一点。


#检测玩家剩余槽位数:
第一版有一个重大的问题,就是当物品给予数量超过玩家物品栏可容下的最大数量时,仍会尝试将合成台里的原料消耗完,而物品却并没有多给,这是我们不想要的。因此在这里使用穷举方法,通过CNC_player_count计分板数据来获取玩家剩余槽位,以限制模拟合成的执行次数。cnc/functions/machine/crafting_table/shift_player:

代码:

  1. execute if data entity @s Inventory[{Slot:0b}] run scoreboard players remove @s CNC_player_count 1
  2. execute if data entity @s Inventory[{Slot:1b}] run scoreboard players remove @s CNC_player_count 1
  3. execute if data entity @s Inventory[{Slot:2b}] run scoreboard players remove @s CNC_player_count 1
  4. execute if data entity @s Inventory[{Slot:3b}] run scoreboard players remove @s CNC_player_count 1
  5. execute if data entity @s Inventory[{Slot:4b}] run scoreboard players remove @s CNC_player_count 1
  6. execute if data entity @s Inventory[{Slot:5b}] run scoreboard players remove @s CNC_player_count 1
  7. execute if data entity @s Inventory[{Slot:6b}] run scoreboard players remove @s CNC_player_count 1
  8. execute if data entity @s Inventory[{Slot:7b}] run scoreboard players remove @s CNC_player_count 1
  9. execute if data entity @s Inventory[{Slot:8b}] run scoreboard players remove @s CNC_player_count 1
  10. execute if data entity @s Inventory[{Slot:9b}] run scoreboard players remove @s CNC_player_count 1
  11. execute if data entity @s Inventory[{Slot:10b}] run scoreboard players remove @s CNC_player_count 1
  12. execute if data entity @s Inventory[{Slot:11b}] run scoreboard players remove @s CNC_player_count 1
  13. execute if data entity @s Inventory[{Slot:12b}] run scoreboard players remove @s CNC_player_count 1
  14. execute if data entity @s Inventory[{Slot:13b}] run scoreboard players remove @s CNC_player_count 1
  15. execute if data entity @s Inventory[{Slot:14b}] run scoreboard players remove @s CNC_player_count 1
  16. execute if data entity @s Inventory[{Slot:15b}] run scoreboard players remove @s CNC_player_count 1
  17. execute if data entity @s Inventory[{Slot:16b}] run scoreboard players remove @s CNC_player_count 1
  18. execute if data entity @s Inventory[{Slot:17b}] run scoreboard players remove @s CNC_player_count 1
  19. execute if data entity @s Inventory[{Slot:18b}] run scoreboard players remove @s CNC_player_count 1
  20. execute if data entity @s Inventory[{Slot:19b}] run scoreboard players remove @s CNC_player_count 1
  21. execute if data entity @s Inventory[{Slot:20b}] run scoreboard players remove @s CNC_player_count 1
  22. execute if data entity @s Inventory[{Slot:21b}] run scoreboard players remove @s CNC_player_count 1
  23. execute if data entity @s Inventory[{Slot:22b}] run scoreboard players remove @s CNC_player_count 1
  24. execute if data entity @s Inventory[{Slot:23b}] run scoreboard players remove @s CNC_player_count 1
  25. execute if data entity @s Inventory[{Slot:24b}] run scoreboard players remove @s CNC_player_count 1
  26. execute if data entity @s Inventory[{Slot:25b}] run scoreboard players remove @s CNC_player_count 1
  27. execute if data entity @s Inventory[{Slot:26b}] run scoreboard players remove @s CNC_player_count 1
  28. execute if data entity @s Inventory[{Slot:27b}] run scoreboard players remove @s CNC_player_count 1
  29. execute if data entity @s Inventory[{Slot:28b}] run scoreboard players remove @s CNC_player_count 1
  30. execute if data entity @s Inventory[{Slot:29b}] run scoreboard players remove @s CNC_player_count 1
  31. execute if data entity @s Inventory[{Slot:30b}] run scoreboard players remove @s CNC_player_count 1
  32. execute if data entity @s Inventory[{Slot:31b}] run scoreboard players remove @s CNC_player_count 1
  33. execute if data entity @s Inventory[{Slot:32b}] run scoreboard players remove @s CNC_player_count 1
  34. execute if data entity @s Inventory[{Slot:33b}] run scoreboard players remove @s CNC_player_count 1
  35. execute if data entity @s Inventory[{Slot:34b}] run scoreboard players remove @s CNC_player_count 1
  36. execute if data entity @s Inventory[{Slot:35b}] run scoreboard players remove @s CNC_player_count 1

#检测当前物品最大可堆叠数量:cnc/functions/machine/crafting_table/shift_data_get:

代码:

  1. execute as @e[tag=CNC_shiftcheck,limit=1,sort=nearest] run scoreboard players set @s CAM_item_trigger 0
  2. execute as @e[tag=CNC_shiftcheck,limit=1,sort=nearest] store result score @s CNC_item_trigger run clear @s #cnc:1x{Output:1b} 0
  3. execute if score @e[tag=CNC_shiftcheck,limit=1,sort=nearest] CNC_item_trigger matches 1.. run scoreboard players set @s CNC_item_trigger 1
  4. execute as @e[tag=CNC_shiftcheck,limit=1] store result score @s CNC_item_trigger run clear @s #cnc:16x{Output:1b} 0
  5. execute if score @e[tag=CNC_shiftcheck,limit=1,sort=nearest] CNC_item_trigger matches 1.. run scoreboard players set @s CNC_item_trigger 16
  6. execute if score @e[tag=CNC_shiftcheck,limit=1,sort=nearest] CNC_item_trigger matches ..0 run scoreboard players set @s CNC_item_trigger 64
首先侦测输出物品是否为不可堆叠物品,如果是,将计分板数据设置为1,接下来检测是否为以16个为一组的物品,如都不是,则默认为以64个为一组的物品。便于下面的计算。
#模拟合成:cncfunctions/machine/crafting_table/shifttest:

代码:

  1. scoreboard players operation @s CNC_shiftdealt /= @s CNC_shift_muti
  2. replaceitem block ~ ~ ~ container.16 minecraft:air
  3. function cnc:machine/crafting_table/recipe
  4. scoreboard players operation @s CNC_shiftdealt *= @s CNC_shift_muti
  5. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} if score @s CNC_shiftdealt > @s CNC_player_count run tag @a[tag=CNC_shiftcheck] add CNC_comp
  6. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} if score @s CNC_shiftdealt < @s CNC_player_count run function cnc:machine/crafting_table/shifttest



模拟合成有两个限制:原料和玩家物品栏。原料限制可以由配方函数控制,而玩家物品栏限制则为计算(括号内为对应计分板名):首先将玩家所剩槽位数(CNC_player_count)乘以其最大可堆叠数(CNC_item_trigger),即为玩家最多可获得的物品数,记为a;然后将单次可合成数(CNC_shift_muti)乘以已模拟执行合成次数(CNC_shiftdealt),即为已经“合成”出的物品数量,记为b;将两数对比,若b大于a,则证明模拟合成次数达到了上限,停止模拟合成操作。为了少用几个计分板,这里面还有一些琐碎的小计算,这里不再赘述,都在代码里面。


但是我们要注意一种常见的情形:在某次执行中,b小于a,可再递归执行一次,但是执行完以后b却大于了a,导致过量合成。因此我们要将开始的shiftdealt变量调高一个,到后面减去即可。这样操作很方便,但有一个问题,就是如果合成的量正好为整组,如此操作会使实际合成的物品量少一个配方的输出物品数量。


#物品给予模块cnc/functions/machine/crafting_table/shiftdealt:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{tag:{Output:1b}}].id
  3. data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{tag:{Output:1b}}].Count
  4. data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{tag:{Output:1b}}].tag
  5. execute as @s store result score @s CNC_shiftcount run data get block ~ 255 ~ Items[0].Count
  6. scoreboard players operation @s CNC_shiftcount *= @s CNC_shiftdealt
  7. function cnc:machine/crafting_table/sub_shiftdealt
  8. setblock ~ 255 ~ air

cnc/functions/machine/crafting_table/sub_shiftdealt:

代码:

  1. execute if score @s CNC_shiftcount matches 64.. run data modify block ~ 255 ~ Items[0].Count set value 64
  2. execute as @s if score @s CNC_shiftcount matches 1..64 store result block ~ 255 ~ Items[0].Count byte 1 run scoreboard players get @s CNC_shiftcount
  3. execute as @s if score @s CNC_shiftcount matches 1.. run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  4. scoreboard players remove @s CNC_shiftcount 64
  5. execute if score @s CNC_shiftcount matches 1.. run function cnc:machine/crafting_table/sub_shiftdealt
  6. execute if score @s CNC_shiftcount matches ..0 run data remove block ~ 255 ~ Items[0]

译:1、-放置rua影盒2、-复制玩家合成出的物品数据    -如果要合成的物品数量大于64,将盒中物品数量设为64    -如果数量介于0与64之间,将盒中物品数量设为要合成的物品数量3、-将盒中物品给予玩家4、-将数量减去64    -若变量小于0,则停止    -若变量大于0,则继续从第二步执行5、清除rua影盒注:这里直接使用64个的原因是容器中,物品的数量不受该物品堆叠最大数量限制,最高可达127;而在rua影盒技术中使用的loot命令会把内含的物品正确堆叠。用64而不用127的原因是为了兼顾性能和稳定性。



自定义配方的操作方法(在cnc/functions/machine/crafting_table/recipes/sample中):
自定义配方使用execute命令,分为两部分,检测部分(if)和输出部分(run replaceitem)
#有序合成:

代码:

  1. #有序合成:在检测方块时注明Slot(合成区Slot:由上到下,由左到右依次为:1b,2b,3b;10b,11b,12b;19b,20b,21b)
  2. #镜像合成穷举一遍
  3. #示例:铁斧
  4. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:20b,id:"minecraft:stick"},{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}] unless data block ~ ~ ~ {Items:[{id:"minecraft:iron_sword",tag:{id:"cam:chain_blade"}}]} run replaceitem block ~ ~ ~ container.16 minecraft:iron_axe
  5. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:20b,id:"minecraft:stick"},{Slot:11b,id:"minecraft:stick"},{Slot:3b,id:"minecraft:iron_ingot"},{Slot:2b,id:"minecraft:iron_ingot"},{Slot:12b,id:"minecraft:iron_ingot"}]} if entity @s[scores={CNC_table_count=5}] unless data block ~ ~ ~ {Items:[{id:"minecraft:iron_sword",tag:{id:"cam:chain_blade"}}]} run replaceitem block ~ ~ ~ container.16 minecraft:iron_axe

#无序合成:

代码:

  1. #无重复的物品的无序合成:不注明Slot即可
  2. #无序合成与有序合成可以混用(如一部分材料限定位置,另一部分不限定)
  3. #示例:末影之眼
  4. execute if block ~ ~ ~ minecraft:barrel{Items:[{id:"minecraft:blaze_powder"},{id:"minecraft:ender_pearl"}]} if entity @s[scores={CNC_table_count=2}] run replaceitem block ~ ~ ~ container.16 ender_eye

#同种多物品无序合成:

代码:

  1. #有重复物品的无序合成:先用exe if辅助判断一下需要的重复物品的个数,列入检测即可
  2. #示例:书的合成

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

这里一开始我准备使用计分板计算的方法,后来@VCS-Official提醒我可以用execute if 简便地解决,在此致谢
#tag合成:
这里运用了穷举的办法获取物品是否符合断言,使得自定义该种配方的操作较为繁琐。由于需要动态的断言名称,暂时想不到很好的内建的方案。
来源于@晴路卡该问题中的解答,进行了一定的修改。在此致谢。

代码:

  1. #含有tag的配方比较复杂,要先设置一个断言,并在这里引用,穷举每一个合成区的物品,检测其是否符合该断言。在下方该tag处,不要键入id。建议直接复制这里的代码
  2. #断言路径:cnc:crafting_table/planks
  3. #示例:碗的合成

  4. #初始化
  5. scoreboard players reset @s CAM_craftag
  6. #检测tag
  7. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  8. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:1b}].id
  9. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  10. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  11. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:2b}].id
  12. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  13. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  14. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:3b}].id
  15. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  16. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  17. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:10b}].id
  18. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  19. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  20. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:11b}].id
  21. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  22. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  23. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:12b}].id
  24. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  25. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  26. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:19b}].id
  27. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  28. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  29. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:20b}].id
  30. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  31. data modify entity @s ArmorItems[2] set value {id:"minecraft:stone",Count:1b}
  32. data modify entity @s ArmorItems[2].id set from block ~ ~ ~ Items[{Slot:21b}].id
  33. execute if entity @s[predicate=cnc:crafting_table/planks] run scoreboard players add @s CAM_craftag 1
  34. #主命令
  35. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:1b},{Slot:11b},{Slot:3b}]} if entity @s[scores={CNC_table_count=3,CAM_craftag=3}] run replaceitem block ~ ~ ~ container.16 bowl
  36. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:10b},{Slot:20b},{Slot:12b}]} if entity @s[scores={CNC_table_count=3,CAM_craftag=3}] run replaceitem block ~ ~ ~ container.16 bowl

其中引用的断言文件:

代码:

  1.     {
  2.    "condition": "minecraft:entity_properties",
  3.    "entity": "this",
  4.    "predicate": {
  5.   "equipment": {
  6.     "chest": {
  7.    "tag": "minecraft:planks"
  8.     }
  9.   }
  10.    }
  11.     }
replaceitem指令也可以用loot replace取代。

楼下会不会看到某位(来了呢
前言   经过近一个月的开发,我把上一版的部分内容,特别是shift处理的部分进行了优化。虽然照例是有一个视频的,但是我没空剪。就这样吧。    为了让这个帖子凉的更快一点,我决定只放干货。毕竟水的比热容大一点。。。    由于基于我的数据包,因此内部的计分板和tag均带有本数据包标志“CAM”,见谅。    开始。    data/cam/functions/machine/crafting_table/tick:

代码:

  1. #开头基础处理:物品处理 初始化变量
  2. kill @e[nbt={Item:{tag:{CAM_bg:1b}}}]
  3. execute store result score @a CAM_crafterror run clear @a minecraft:firework_star{CAM_bg:1b} 0
  4. execute as @a store result score @s CAM_bottlecount run clear @a #cam:cam_recipes 0

  5. #放置与破坏处理
  6. execute as @e[type=minecraft:armor_stand,tag=cam_crafting] at @s align xyz if block ~ ~ ~ minecraft:petrified_oak_slab run function cam:machine/crafting_table/replace
  7. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s unless block ~ ~ ~ minecraft:barrel run function cam:machine/crafting_table/clear
  8. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] run data modify entity @s Fire set value 32767s
  9. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/gui

  10. #功能
  11. #Shift键处理
  12. execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] run tag @s add CAM_shiftcheck
  13. execute if entity @a[tag=CAM_shiftcheck] as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s unless data block ~ ~ ~ {Items:[{Slot:16b}]} run function cam:machine/crafting_table/shiftcheck
  14. #配方处理
  15. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/recipe
  16. #输出标签处理
  17. execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] at @s run function cam:machine/crafting_table/inventory
  18. #误放入处理
  19. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/check
  20. #Shift键处理 初始化tag
  21. tag @a remove CAM_shiftcheck
#开头基础处理 #放置与破坏处理    没有变化。下面是复制的内容。
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入背景物品返还模块玩家确定的计分板重置
#放置与破坏处理:第1条:检测放置工作台(配合进度(就是视频里的advancement,用于调试的)),
第2条:检测破坏合成台
3:防止盔甲架变黑
#功能同第一版一样由于运用到recipes,shift放到后面讲。#配方处理 data/cam/functions/machine/crafting_table/recipe:

代码:

  1. #获取已占槽位
  2. function cam:machine/crafting_table/recipes/count
  3. #清除合成区物品
  4. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CAM_not_to_clear] run function cam:machine/crafting_table/recipes/clear
  5. tag @s remove CAM_not_to_clear
  6. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_bg:1b}}]} run tag @s add CAM_not_to_clear
  7. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
  8. #配方检测
  9. function cam:machine/crafting_table/recipes/bamboo_sword
  10. function cam:machine/crafting_table/recipes/red_string
  11. function cam:machine/crafting_table/recipes/weedstew
  12. function cam:machine/crafting_table/recipes/honey_apple
  13. function cam:machine/crafting_table/recipes/erosion_arrow
  14. #初始化变量
  15. scoreboard players reset @s CAM_table_count
  16. #shift处理相关
  17. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run scoreboard players add @s CAM_shiftdealt 1
变化不大。
#获取已占槽位:为配方的判定做准备,判定有多少个合成槽位有物品
data/cam/functions/machine/crafting_table/recipes/count:

代码:

  1. execute if data block ~ ~ ~ Items[{Slot:1b}] run scoreboard players add @s CAM_table_count 1
  2. execute if data block ~ ~ ~ Items[{Slot:2b}] run scoreboard players add @s CAM_table_count 1
  3. execute if data block ~ ~ ~ Items[{Slot:3b}] run scoreboard players add @s CAM_table_count 1
  4. execute if data block ~ ~ ~ Items[{Slot:10b}] run scoreboard players add @s CAM_table_count 1
  5. execute if data block ~ ~ ~ Items[{Slot:11b}] run scoreboard players add @s CAM_table_count 1
  6. execute if data block ~ ~ ~ Items[{Slot:12b}] run scoreboard players add @s CAM_table_count 1
  7. execute if data block ~ ~ ~ Items[{Slot:19b}] run scoreboard players add @s CAM_table_count 1
  8. execute if data block ~ ~ ~ Items[{Slot:20b}] run scoreboard players add @s CAM_table_count 1
  9. execute if data block ~ ~ ~ Items[{Slot:21b}] run scoreboard players add @s CAM_table_count 1



    #清除合成区物品:检测输出物品被拿取时,将合成区物品数量-1,

代码:

  1. #清除合成区物品
  2. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CAM_not_to_clear] run function cam:machine/crafting_table/recipes/clear
  3. tag @s remove CAM_not_to_clear
  4. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_bg:1b}}]} run tag @s add CAM_not_to_clear
  5. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air

cam/functions/machine/crafting_table/recipes/clear:

代码:

  1. function cam:machine/crafting_table/recipes/clear/1
  2. function cam:machine/crafting_table/recipes/clear/2
  3. function cam:machine/crafting_table/recipes/clear/3
  4. function cam:machine/crafting_table/recipes/clear/10
  5. function cam:machine/crafting_table/recipes/clear/11
  6. function cam:machine/crafting_table/recipes/clear/12
  7. function cam:machine/crafting_table/recipes/clear/19
  8. function cam:machine/crafting_table/recipes/clear/20
  9. function cam:machine/crafting_table/recipes/clear/21

这是一个穷举索引,下面展示其中一个:cam/functions/machine/crafting_table/recipes/clear/1:

代码:

  1. execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle"}]} unless data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} run give @a[scores={CAM_bottlecount=1..},limit=1,sort=nearest] glass_bottle 1
  2. execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} run replaceitem block ~ ~ ~ container.1 minecraft:glass_bottle 2
  3. execute as @s unless data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:potion"}]} unless data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} store result block ~ ~ ~ Items[{Slot:1b}].Count byte 0.99 run data get block ~ ~ ~ Items[{Slot:1b}].Count</font>
  4. execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:potion",Count:1b}]} run replaceitem block ~ ~ ~ container.1 minecraft:glass_bottle
红字为主要实现的指令,其余为药水和蜂蜜瓶的特殊处理。由于我懒得翻译了,自己看吧。反正我针对的对象也不是完全不会命令的复制一下检测清除的翻译:  原理:从第4行开始(前一刻)
  1、如果输出栏(Slot:16)是“空的”(透明材质的占位符),将所在位置盔甲架加上tag;
  2、清除16号位物品(使合成栏变动时消除输出物品,拒绝白嫖)
  3、运行配方检测(若满足则在16号位放上物品)
  4、 运行到check指令时,如16号位真空,将空的16号位加上占位符
    否则无变化
    (后一刻)
  5、如果16号位真空,即check未填补(被配方占据),而此时输出物被拿走,检测tag(即玩家是否误点了占位符),若否,则将输入    栏物品数量-1
  6、移除tag,进行下一刻检测  这样就达到了输入、输出两边同时存在,但只能取一边的目的。
#配方检测:展示其中一个配方:  data/cam/functions/machine/crafting_table/recipes/bamboo_sword:(其中一个配方)

代码:

  1. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:19b,tag:{id:"cam:red_string"}},{Slot:11b,id:"minecraft:bamboo"},{Slot:3b,id:"minecraft:bamboo"}]} if entity @s[scores={CAM_table_count=3}] run replaceitem block ~ ~ ~ container.16 wooden_sword{display:{Name:"{"translate":"item.cam.bamboo_sword","italic":"false"}"},CustomModelData:9102019,CAM_output:1b}
  2. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:21b,tag:{id:"cam:red_string"}},{Slot:11b,id:"minecraft:bamboo"},{Slot:1b,id:"minecraft:bamboo"}]} if entity @s[scores={CAM_table_count=3}] run replaceitem block ~ ~ ~ container.16 wooden_sword{display:{Name:"{"translate":"item.cam.bamboo_sword","italic":"false"}"},CustomModelData:9102019,CAM_output:1b}
有序合成:指定Slot和物品属性,用CAM_table_count计分板确定已占槽位数,以达到多占槽位即判定不通过的目的;
无序合成:基本同上,不指定Slot
#误放入处理 #结尾基础处理
没有变化。复制一下第一版内容:
#误放入处理:   
data/cam/functions/machine/crafting_table/check:

代码:

  1. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:0b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/0
  2. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/16
  3. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:4b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/4
  4. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:5b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/5
  5. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:6b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/6
  6. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:7b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/7
  7. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:8b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/8
  8. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:9b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/9
  9. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:13b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/13
  10. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:14b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/14
  11. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:15b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/15
  12. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:17b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/17
  13. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:18b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/18
  14. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:22b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/22
  15. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:23b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/23
  16. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:24b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/24
  17. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:25b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/25
  18. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:26b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/26
  同样是一个穷举索引   data/cam/functions/machine/crafting_table/replace/0:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[0]
  3. data modify block ~ ~ ~ Items[0] set value {id:"minecraft:firework_star",Count:1b,Slot:0b,tag:{CustomModelData:9102024,display:{Name:"{"translate":"item.cam.crafting_table"}"},CAM_bg:1b}}
  4. execute as @e[sort=nearest,limit=1,scores={CAM_crafterror=1..}] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  5. execute at @s run setblock ~ 255 ~ air

   原理:若在箱子里检测到没有CAM_bg标签(因为在tick里高频清除了玩家和地面的该种物品,所以可以由此判断玩家放入了其他物品),则将其复制到潜影盒里,返还给玩家(本来想精确到特定slot,但因难度太大放弃了)。具体实现方法见[技巧] 修改玩家背包物品信息(免穷举 #结尾基础处理:清除玩家物品栏内的带CAM_bg:1b的物品,重置有关shift处理计分板。
以下为大改内容:#shift键处理:
#Shift键处理
execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] run tag @s add CAM_shiftcheck
execute if entity @a[tag=CAM_shiftcheck] as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s unless data block ~ ~ ~ {Items:[{Slot:16b}]} run function cam:machine/crafting_table/shiftcheck

翻译:首先检测背包里有标签CAM_output:1b物品的玩家,给这个玩家加上CAM_shiftcheck的tag,然后检测是否有此tag的玩家,如有则以第16槽位为“真空”的合成台为执行者执行命令通过这两个(红字)条件,可判定玩家是否使用了shift,具体原因见SPGoding该问题中的解答 shift检测:data/cam/functions/machine/crafting_table/shiftcheck:

代码:

  1. #初始化变量和tag
  2. scoreboard players set @s CAM_shiftdealt 2
  3. scoreboard players set @a CAM_player_count 37
  4. scoreboard players reset @a CAM_item_trigger
  5. #检测玩家剩余槽位数和当前物品最大可堆叠数量,以及版权(划掉)计分板数据转移
  6. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CAM_shiftcheck] at @s run function cam:machine/crafting_table/shift_player
  7. scoreboard players operation @s CAM_player_count = @e[tag=CAM_shiftcheck] CAM_player_count
  8. function cam:machine/crafting_table/shift_data_get
  9. scoreboard players operation @s CAM_player_count *= @s CAM_item_trigger
  10. execute store result score @s CAM_shift_muti run clear @a[tag=CAM_shiftcheck] #cam:cam_recipes{CAM_output:1b} 0
  11. scoreboard players operation @s CAM_shiftdealt *= @s CAM_shift_muti
  12. #模拟执行合成操作,以确定可执行的最大合成次数
  13. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @e[tag=CAM_shiftcheck] run function cam:machine/crafting_table/shifttest
  14. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless score @s CAM_shiftdealt < @s CAM_player_count run function cam:machine/crafting_table/recipes/clear
  15. scoreboard players operation @s CAM_shiftdealt /= @s CAM_shift_muti
  16. #补偿机制相关
  17. execute as @e[tag=CAM_comp] run scoreboard players remove @s CAM_shiftdealt 1
  18. #清除输出栏
  19. replaceitem block ~ ~ ~ container.16 minecraft:air
  20. #(辅助)给予次数运算
  21. scoreboard players remove @s CAM_shiftdealt 2
  22. #计分板数据转移
  23. scoreboard players operation @e[tag=CAM_shiftcheck] CAM_shiftdealt = @s CAM_shiftdealt
  24. #给予玩家物品
  25. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CAM_shiftcheck] at @s run function cam:machine/crafting_table/shiftdealt
  26. #输出栏处理
  27. execute if entity @e[tag=CAM_shiftcheck] run replaceitem block ~ ~ ~ container.16 minecraft:firework_star{CustomModelData:9102025,display:{Name:"{"translate":"item.cam.crafting_table_output"}"},CAM_bg:1b,CAM_output:1b}
  28. #初始化
  29. tag @s remove CAM_comp

其中有一些条件已经不需要了,但是因为我懒,所以没有删除里面所谓的计分板数据转移是因为命令的执行者不同:玩家或合成台(即在合成台位置的盔甲架)而计算时把数据放在一起会省事一点。#检测玩家剩余槽位数:上个版本有一个重大的问题,就是当物品给予数量超过玩家物品栏可容下的最大数量时,仍会尝试将合成台里的原料消耗完,这是我们不想要的。因此在这里通过CAM_player_count计分板数据来获取玩家剩余槽位,以限制模拟合成的执行次数。data/cam/functions/machine/crafting_table/shift_player:

代码:

  1. execute if data entity @s Inventory[{Slot:0b}] run scoreboard players remove @s CAM_player_count 1
  2. execute if data entity @s Inventory[{Slot:1b}] run scoreboard players remove @s CAM_player_count 1
  3. execute if data entity @s Inventory[{Slot:2b}] run scoreboard players remove @s CAM_player_count 1
  4. execute if data entity @s Inventory[{Slot:3b}] run scoreboard players remove @s CAM_player_count 1
  5. execute if data entity @s Inventory[{Slot:4b}] run scoreboard players remove @s CAM_player_count 1
  6. execute if data entity @s Inventory[{Slot:5b}] run scoreboard players remove @s CAM_player_count 1
  7. execute if data entity @s Inventory[{Slot:6b}] run scoreboard players remove @s CAM_player_count 1
  8. execute if data entity @s Inventory[{Slot:7b}] run scoreboard players remove @s CAM_player_count 1
  9. execute if data entity @s Inventory[{Slot:8b}] run scoreboard players remove @s CAM_player_count 1
  10. execute if data entity @s Inventory[{Slot:9b}] run scoreboard players remove @s CAM_player_count 1
  11. execute if data entity @s Inventory[{Slot:10b}] run scoreboard players remove @s CAM_player_count 1
  12. execute if data entity @s Inventory[{Slot:11b}] run scoreboard players remove @s CAM_player_count 1
  13. execute if data entity @s Inventory[{Slot:12b}] run scoreboard players remove @s CAM_player_count 1
  14. execute if data entity @s Inventory[{Slot:13b}] run scoreboard players remove @s CAM_player_count 1
  15. execute if data entity @s Inventory[{Slot:14b}] run scoreboard players remove @s CAM_player_count 1
  16. execute if data entity @s Inventory[{Slot:15b}] run scoreboard players remove @s CAM_player_count 1
  17. execute if data entity @s Inventory[{Slot:16b}] run scoreboard players remove @s CAM_player_count 1
  18. execute if data entity @s Inventory[{Slot:17b}] run scoreboard players remove @s CAM_player_count 1
  19. execute if data entity @s Inventory[{Slot:18b}] run scoreboard players remove @s CAM_player_count 1
  20. execute if data entity @s Inventory[{Slot:19b}] run scoreboard players remove @s CAM_player_count 1
  21. execute if data entity @s Inventory[{Slot:20b}] run scoreboard players remove @s CAM_player_count 1
  22. execute if data entity @s Inventory[{Slot:21b}] run scoreboard players remove @s CAM_player_count 1
  23. execute if data entity @s Inventory[{Slot:22b}] run scoreboard players remove @s CAM_player_count 1
  24. execute if data entity @s Inventory[{Slot:23b}] run scoreboard players remove @s CAM_player_count 1
  25. execute if data entity @s Inventory[{Slot:24b}] run scoreboard players remove @s CAM_player_count 1
  26. execute if data entity @s Inventory[{Slot:25b}] run scoreboard players remove @s CAM_player_count 1
  27. execute if data entity @s Inventory[{Slot:26b}] run scoreboard players remove @s CAM_player_count 1
  28. execute if data entity @s Inventory[{Slot:27b}] run scoreboard players remove @s CAM_player_count 1
  29. execute if data entity @s Inventory[{Slot:28b}] run scoreboard players remove @s CAM_player_count 1
  30. execute if data entity @s Inventory[{Slot:29b}] run scoreboard players remove @s CAM_player_count 1
  31. execute if data entity @s Inventory[{Slot:30b}] run scoreboard players remove @s CAM_player_count 1
  32. execute if data entity @s Inventory[{Slot:31b}] run scoreboard players remove @s CAM_player_count 1
  33. execute if data entity @s Inventory[{Slot:32b}] run scoreboard players remove @s CAM_player_count 1
  34. execute if data entity @s Inventory[{Slot:33b}] run scoreboard players remove @s CAM_player_count 1
  35. execute if data entity @s Inventory[{Slot:34b}] run scoreboard players remove @s CAM_player_count 1
  36. execute if data entity @s Inventory[{Slot:35b}] run scoreboard players remove @s CAM_player_count 1
没什么好看的,就是穷举。#检测当前物品最大可堆叠数量:没什么好解释的吧

代码:

  1. execute as @e[tag=CAM_shiftcheck,limit=1] store result score @s CAM_item_trigger run clear @s #cam:64x{CAM_output:1b} 0
  2. execute if score @e[tag=CAM_shiftcheck,limit=1] CAM_item_trigger matches 1.. run scoreboard players set @s CAM_item_trigger 64
  3. execute as @e[tag=CAM_shiftcheck,limit=1] store result score @s CAM_item_trigger run clear @s #cam:16x{CAM_output:1b} 0
  4. execute if score @e[tag=CAM_shiftcheck,limit=1] CAM_item_trigger matches 1.. run scoreboard players set @s CAM_item_trigger 16
  5. execute as @e[tag=CAM_shiftcheck,limit=1] store result score @s CAM_item_trigger run clear @s #cam:1x{CAM_output:1b} 0
  6. execute if score @e[tag=CAM_shiftcheck,limit=1] CAM_item_trigger matches 1.. run scoreboard players set @s CAM_item_trigger 1
#模拟合成:
data/cam/functions/machine/crafting_table/shifttest:

代码:

  1. scoreboard players operation @s CAM_shiftdealt /= @s CAM_shift_muti
  2. replaceitem block ~ ~ ~ container.16 minecraft:air
  3. function cam:machine/crafting_table/recipe
  4. scoreboard players operation @s CAM_shiftdealt *= @s CAM_shift_muti
该模拟合成有两个限制:原料和玩家物品栏。原料限制可以由配方函数控制,而玩家物品栏限制则为计算(括号内为对应计分板名):首先将玩家所剩槽位数(CAM_player_count)乘以其最大可堆叠数(CAM_item_trigger),即为玩家最多可获得的物品数,记为a;然后将单次可合成数(CAM_shift_muti)乘以已模拟执行合成次数(CAM_shiftdealt),即为已经“合成”出的物品数量,记为b;将两数对比,若b大于a,则证明模拟合成次数达到了上限,停止模拟合成操作。为了少用几个计分板,这里面还有一些琐碎的小计算,这里不再赘述,都在代码里面。
但是我们要注意一种常见的情形:在某次执行中,b小于a,可再递归执行一次,但是执行完以后b却大于了a,导致过量合成。因此需要使用补偿模块,以防止此类事件的发生。我是写了一个补偿模块,但是写这篇帖子的时候突然发现完全不需要,只要将开始的shiftdealt变量调高一个,到后面减去即可。以上段落足以证明我是一个sb
#物品给予模块data/cam/functions/machine/crafting_table/shiftdealt:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{tag:{CAM_output:1b}}].id
  3. data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{tag:{CAM_output:1b}}].Count
  4. data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{tag:{CAM_output:1b}}].tag
  5. execute as @s store result score @s CAM_shiftcount run data get block ~ 255 ~ Items[0].Count
  6. scoreboard players operation @s CAM_shiftcount *= @s CAM_shiftdealt
  7. function cam:machine/crafting_table/sub_shiftdealt
  8. setblock ~ 255 ~ air
data/cam/functions/machine/crafting_table/sub_shiftdealt:

代码:

  1. execute if score @s CAM_shiftcount matches 64.. run data modify block ~ 255 ~ Items[0].Count set value 64
  2. execute as @s if score @s CAM_shiftcount matches 1..64 store result block ~ 255 ~ Items[0].Count byte 1 run scoreboard players get @s CAM_shiftcount
  3. execute as @s if score @s CAM_shiftcount matches 1.. run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  4. scoreboard players remove @s CAM_shiftcount 64
  5. execute if score @s CAM_shiftcount matches 1.. run function cam:machine/crafting_table/sub_shiftdealt
  6. execute if score @s CAM_shiftcount matches ..0 run data remove block ~ 255 ~ Items[0]
翻译:1、-放置rua影盒2、-复制玩家合成出的物品数据    -如果要合成的物品数量大于64,将盒中物品数量设为64    -如果数量介于0与64之间,将盒中物品数量设为要合成的物品数量3、-将盒中物品给予玩家4、-将数量减去64    -若变量小于0,则停止    -若变量大于0,则继续从第二步执行5、清除rua影盒至此,有关shift的处理讲解结束。
#输出标签处理:极其辛酸的部分,因为这个东西我卡了十来天。


先讲解吧,事故现场后面放。事故现场丢了
data/cam/functions/machine/crafting_table/inventory:

代码:

  1. etblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}

  2. execute if data entity @s {Inventory:[{Slot:0b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/0
  3. execute if data entity @s {Inventory:[{Slot:1b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/1
  4. execute if data entity @s {Inventory:[{Slot:2b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/2
  5. execute if data entity @s {Inventory:[{Slot:3b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/3
  6. execute if data entity @s {Inventory:[{Slot:4b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/4
  7. execute if data entity @s {Inventory:[{Slot:5b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/5
  8. execute if data entity @s {Inventory:[{Slot:6b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/6
  9. execute if data entity @s {Inventory:[{Slot:7b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/7
  10. execute if data entity @s {Inventory:[{Slot:8b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/8
  11. execute if data entity @s {Inventory:[{Slot:9b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/9
  12. execute if data entity @s {Inventory:[{Slot:10b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/10
  13. execute if data entity @s {Inventory:[{Slot:11b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/11
  14. execute if data entity @s {Inventory:[{Slot:12b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/12
  15. execute if data entity @s {Inventory:[{Slot:13b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/13
  16. execute if data entity @s {Inventory:[{Slot:14b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/14
  17. execute if data entity @s {Inventory:[{Slot:15b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/15
  18. execute if data entity @s {Inventory:[{Slot:16b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/16
  19. execute if data entity @s {Inventory:[{Slot:17b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/17
  20. execute if data entity @s {Inventory:[{Slot:18b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/18
  21. execute if data entity @s {Inventory:[{Slot:19b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/19
  22. execute if data entity @s {Inventory:[{Slot:20b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/20
  23. execute if data entity @s {Inventory:[{Slot:21b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/21
  24. execute if data entity @s {Inventory:[{Slot:22b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/22
  25. execute if data entity @s {Inventory:[{Slot:23b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/23
  26. execute if data entity @s {Inventory:[{Slot:24b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/24
  27. execute if data entity @s {Inventory:[{Slot:25b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/25
  28. execute if data entity @s {Inventory:[{Slot:26b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/26
  29. execute if data entity @s {Inventory:[{Slot:27b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/27
  30. execute if data entity @s {Inventory:[{Slot:28b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/28
  31. execute if data entity @s {Inventory:[{Slot:29b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/29
  32. execute if data entity @s {Inventory:[{Slot:30b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/30
  33. execute if data entity @s {Inventory:[{Slot:31b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/31
  34. execute if data entity @s {Inventory:[{Slot:32b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/32
  35. execute if data entity @s {Inventory:[{Slot:33b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/33
  36. execute if data entity @s {Inventory:[{Slot:34b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/34
  37. execute if data entity @s {Inventory:[{Slot:35b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/35



  38. setblock ~ 255 ~ air
穷举玩家含有CAM_output:1b的物品槽位并通过rua影盒处理之:
data/cam/functions/machine/crafting_table/inventory/0:

代码:

  1. data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{Slot:0b}].id
  2. data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{Slot:0b}].Count
  3. data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{Slot:0b}].tag
  4. data remove block ~ 255 ~ Items[0].tag.CAM_output
  5. loot replace entity @s hotbar.0 1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
data/cam/functions/machine/crafting_table/inventory/9:

代码:

  1. data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{Slot:9b}].id
  2. data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{Slot:9b}].Count
  3. data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{Slot:9b}].tag
  4. data remove block ~ 255 ~ Items[0].tag.CAM_output
  5. loot replace entity @s inventory.0 1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
注意用loot replace 和replaceitem 时注意快捷栏是hotbar0~8对应Inventory中Slot的0~8,inventory的0~26对应Inventory中的9~35。


至此,讲解完全完成。


以下为第一版  事情是这样的,在开发我的原版模组时,想做一个合成NBT物品的合成台,于是我就去教程学习了一下有关内容,同时下载了更多的合成数据包
以拆解学习,但是我没能成功的把合成器拆出来,而且发现了几个小问题(有些是真的让人蛋疼。。。)    问题1、秘技:gui消失术!   
   只要在第一个槽位放入一个物品即可。很让人无语的一个问题。   问题2:创造模式下,破坏机器仍然会掉落。   
  3(其实这个应该算个特性):发现符合条件的配方立即转化,手残党的噩梦。。。


 

    于是,我决定自己写。    /2000 years later.jpg  经过4天的艰苦卓绝的开发,我成功把这个玩意搞出来了!  下面是展示视频    https://www.bilibili.com/video/av85551813/


  问题1  由于该模块较为复杂,我先在这里展示一下tick函数结构:   data/cam/functions/machine/crafting_table/tick:

代码:


  1. #开头基础处理:物品处理 初始化变量
  2. kill @e[nbt={Item:{tag:{CAM_bg:1b}}}]
  3. execute store result score @a CAM_crafterror run clear @a minecraft:firework_star{CAM_bg:1b} 0

  4. #放置与破坏处理
  5. execute as @e[type=minecraft:armor_stand,tag=cam_crafting] at @s align xyz if block ~ ~ ~ minecraft:petrified_oak_slab run function cam:machine/crafting_table/replace
  6. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s unless block ~ ~ ~ minecraft:barrel run function cam:machine/crafting_table/clear
  7. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] run data modify entity @s Fire set value 32767s

  8. #功能
  9. #Shift键处理
  10. execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] run tag @s add CAM_shiftcheck
  11. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/shiftcheck
  12. #配方处理
  13. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/recipe
  14. #输出标签处理
  15. execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] at @s run function cam:machine/crafting_table/inventory
  16. #误放入处理
  17. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/check
  18. #Shift键处理 初始化tag
  19. tag @a remove CAM_shiftcheck

  20. #结尾基础处理:物品处理 初始化变量
  21. clear @a firework_star{CAM_bg:1b}
  22. scoreboard players reset @e CAM_shiftdealt



   我在教程里发现了这么一段:



  然而,数据包里好像并没有应用到。。。  于是我就设计了这个check函数:  data/cam/functions/machine/crafting_table/check:

代码:

  1. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:0b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/0
  2. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/16
  3. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:4b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/4
  4. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:5b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/5
  5. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:6b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/6
  6. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:7b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/7
  7. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:8b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/8
  8. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:9b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/9
  9. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:13b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/13
  10. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:14b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/14
  11. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:15b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/15
  12. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:17b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/17
  13. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:18b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/18
  14. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:22b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/22
  15. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:23b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/23
  16. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:24b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/24
  17. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:25b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/25
  18. execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:26b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/26

   data/cam/functions/machine/crafting_table/replace/0:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[0]
  3. data modify block ~ ~ ~ Items[0] set value {id:"minecraft:firework_star",Count:1b,Slot:0b,tag:{CustomModelData:9102024,display:{Name:"{"translate":"item.cam.crafting_table"}"},CAM_bg:1b}}
  4. execute as @e[sort=nearest,limit=1,scores={CAM_crafterror=1..}] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  5. execute at @s run setblock ~ 255 ~ air
  check函数里的18条命令其实是一条命令,这里运用了穷举。
   原理:若在箱子里检测到没有CAM_bg标签(因为在tick里高频清除了玩家和地面的该种物品,所以可以由此判断玩家放入了其他物品),则将其复制到潜影盒里,返还给玩家(本来想精确到特定slot,但因难度太大放弃了)。具体实现方法见[技巧] 修改玩家背包物品信息(免穷举
   至此,解决。


   问题2
   这个就简单了。
   如果通过战利品表来实现,还是有难度的,但是我们可以用Bugjang特性来解决
   既然创造模式打掉方块不掉方块本体,而生存模式会掉,那我们为什么不利用这一特性呢?
   这就是这里的思路了。


data/cam/functions/machine/crafting_table/clear:

代码:

  1. <blockquote>execute at @s if entity @e[type=item,nbt={Item:{id:"minecraft:barrel"}},distance=..2] run loot spawn ~ ~ ~ loot minecraft:blocks/cam_crafting_table
 


  总体梳理  注意:本部分包含了大量代码,不想看的同志们可以离开了。可以回到第二页观看短视频。
  我只是想把我的合成台做得更人性化一点,也更像原版一点,于是把它优化了   亿   点    点
   现在开始梳理
   首先,再次展示一下tick:
  data/cam/functions/machine/crafting_table/tick:

代码:


  1. #开头基础处理:物品处理 初始化变量
  2. kill @e[nbt={Item:{tag:{CAM_bg:1b}}}]
  3. execute store result score @a CAM_crafterror run clear @a minecraft:firework_star{CAM_bg:1b} 0

  4. #放置与破坏处理
  5. execute as @e[type=minecraft:armor_stand,tag=cam_crafting] at @s align xyz if block ~ ~ ~ minecraft:petrified_oak_slab run function cam:machine/crafting_table/replace
  6. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s unless block ~ ~ ~ minecraft:barrel run function cam:machine/crafting_table/clear
  7. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] run data modify entity @s Fire set value 32767s

  8. #功能
  9. #Shift键处理
  10. execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] run tag @s add CAM_shiftcheck
  11. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/shiftcheck
  12. #配方处理
  13. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/recipe
  14. #输出标签处理
  15. execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] at @s run function cam:machine/crafting_table/inventory
  16. #误放入处理
  17. execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/check
  18. #Shift键处理 初始化tag
  19. tag @a remove CAM_shiftcheck

  20. #结尾基础处理:物品处理 初始化变量
  21. clear @a firework_star{CAM_bg:1b}
  22. scoreboard players reset @e CAM_shiftdealt



   #开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入背景物品返还模块玩家确定的计分板重置
   #放置与破坏处理:第1条:检测放置工作台(配合进度(就是视频里的advancement,用于调试的)),
  第2条:检测破坏合成台
  3:防止盔甲架变黑


   #功能:
    #Shift键处理:本人最自豪的部分之一,由于涉及到下方函数,原理先放一下。
    #配方处理:
    先亮代码:
    data/cam/functions/machine/crafting_table/recipe:

代码:

  1. function cam:machine/crafting_table/recipes/count
  2. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CAM_not_to_clear] run function cam:machine/crafting_table/recipes/clear
  3. tag @s remove CAM_not_to_clear
  4. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_bg:1b}}]} run tag @s add CAM_not_to_clear
  5. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
  6. function cam:machine/crafting_table/recipes/bamboo_sword
  7. function cam:machine/crafting_table/recipes/red_string
  8. scoreboard players reset @s CAM_table_count
  9. execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run scoreboard players add @s CAM_shiftdealt 1
  (这里的CAM_shiftdealt计分板就是有关shift处理的)
  data/cam/functions/machine/crafting_table/recipes/count:

代码:

  1. execute if data block ~ ~ ~ Items[{Slot:1b}] run scoreboard players add @s CAM_table_count 1
  2. execute if data block ~ ~ ~ Items[{Slot:2b}] run scoreboard players add @s CAM_table_count 1
  3. execute if data block ~ ~ ~ Items[{Slot:3b}] run scoreboard players add @s CAM_table_count 1
  4. execute if data block ~ ~ ~ Items[{Slot:10b}] run scoreboard players add @s CAM_table_count 1
  5. execute if data block ~ ~ ~ Items[{Slot:11b}] run scoreboard players add @s CAM_table_count 1
  6. execute if data block ~ ~ ~ Items[{Slot:12b}] run scoreboard players add @s CAM_table_count 1
  7. execute if data block ~ ~ ~ Items[{Slot:19b}] run scoreboard players add @s CAM_table_count 1
  8. execute if data block ~ ~ ~ Items[{Slot:20b}] run scoreboard players add @s CAM_table_count 1
  9. execute if data block ~ ~ ~ Items[{Slot:21b}] run scoreboard players add @s CAM_table_count 1



  data/cam/functions/machine/crafting_table/recipes/bamboo_sword:(其中一个配方)

代码:

  1. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:19b,tag:{id:"cam:red_string"}},{Slot:11b,id:"minecraft:bamboo"},{Slot:3b,id:"minecraft:bamboo"}]} if entity @s[scores={CAM_table_count=3}] run replaceitem block ~ ~ ~ container.16 wooden_sword{display:{Name:"{"translate":"item.cam.bamboo_sword","italic":"false"}"},CustomModelData:9102019,CAM_output:1b}
  2. execute if block ~ ~ ~ minecraft:barrel{Items:[{Slot:21b,tag:{id:"cam:red_string"}},{Slot:11b,id:"minecraft:bamboo"},{Slot:1b,id:"minecraft:bamboo"}]} if entity @s[scores={CAM_table_count=3}] run replaceitem block ~ ~ ~ container.16 wooden_sword{display:{Name:"{"translate":"item.cam.bamboo_sword","italic":"false"}"},CustomModelData:9102019,CAM_output:1b}
  data/cam/functions/machine/crafting_table/recipes/clear:(清除合成栏物品)

代码:

  1. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:1b}].Count
  2. scoreboard players remove @s CAM_clear 1
  3. execute store result block ~ ~ ~ Items[{Slot:1b}].Count byte 1 run scoreboard players get @s CAM_clear

  4. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:2b}].Count
  5. scoreboard players remove @s CAM_clear 1
  6. execute store result block ~ ~ ~ Items[{Slot:2b}].Count byte 1 run scoreboard players get @s CAM_clear

  7. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:3b}].Count
  8. scoreboard players remove @s CAM_clear 1
  9. execute store result block ~ ~ ~ Items[{Slot:3b}].Count byte 1 run scoreboard players get @s CAM_clear

  10. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:10b}].Count
  11. scoreboard players remove @s CAM_clear 1
  12. execute store result block ~ ~ ~ Items[{Slot:10b}].Count byte 1 run scoreboard players get @s CAM_clear

  13. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:11b}].Count
  14. scoreboard players remove @s CAM_clear 1
  15. execute store result block ~ ~ ~ Items[{Slot:11b}].Count byte 1 run scoreboard players get @s CAM_clear

  16. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:12b}].Count
  17. scoreboard players remove @s CAM_clear 1
  18. execute store result block ~ ~ ~ Items[{Slot:12b}].Count byte 1 run scoreboard players get @s CAM_clear

  19. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:19b}].Count
  20. scoreboard players remove @s CAM_clear 1
  21. execute store result block ~ ~ ~ Items[{Slot:19b}].Count byte 1 run scoreboard players get @s CAM_clear

  22. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:20b}].Count
  23. scoreboard players remove @s CAM_clear 1
  24. execute store result block ~ ~ ~ Items[{Slot:20b}].Count byte 1 run scoreboard players get @s CAM_clear

  25. execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:21b}].Count
  26. scoreboard players remove @s CAM_clear 1
  27. execute store result block ~ ~ ~ Items[{Slot:21b}].Count byte 1 run scoreboard players get @s CAM_clear
  28. #(命令重复9遍)
    原理:从第4行开始(前一刻)
  1、如果输出栏(Slot:16)是“空的”(透明材质的占位符),将所在位置盔甲架加上tag;
  2、清除16号位物品(使合成栏变动时消除输出物品,拒绝白嫖)
  3、运行配方检测(若满足则在16号位放上物品)
  4、 运行到check指令时,如16号位真空,将空的16号位加上占位符
    否则无变化
    (后一刻)
  5、如果16号位真空,即check未填补(被配方占据),而此时输出物被拿走,检测tag(即玩家是否误点了占位符),若否,则将输入    栏物品数量-1
  6、移除tag,进行下一刻检测  这样就达到了输入、输出两边同时存在,但只能取一边的目的。
  配方:    有序合成:指定Slot和物品属性,用CAM_table_count计分板确定已占槽位数,以达到多占槽位清除的目的;
  无序合成:基本同上,不指定Slot


  #输出标签处理:由于输出栏物品都带有CAM_output的标签,以侦测玩家是否误放入输出栏物品及防止做出配方,将配方保存在台子里,然后通过破坏方块的方式来非法达到“我全都要”的目的(见解决问题2时函数的最后一行),因此设计了这一函数。


  原理就是通过潜影盒改变玩家物品,用穷举确定玩家物品栏Slot,代码较多,又长又臭,就不拿出来恶心大家了。  #误放入处理:就是上面解决问题1时用到的check函数,不再赘述;
  #结尾基础处理:清除玩家物品栏内的带CAM_bg:1b的物品,重置有关shift处理计分板。
  Shift处理原理
  最好的当然要放在最后。
   我们知道,mc原版工作台在你按下shift时,会把可合成的最大数量物品一次性合成出来。可惜,容器做不到这一点。
   因此我就搞了这么一手。
   上代码!
  data/cam/functions/machine/crafting_table/shiftcheck:

代码:

  1. scoreboard players set @s CAM_shiftdealt 1
  2. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @e[tag=CAM_shiftcheck] run function cam:machine/crafting_table/shifttest
  3. scoreboard players operation @e[tag=CAM_shiftcheck] CAM_shiftdealt = @s CAM_shiftdealt
  4. execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CAM_shiftcheck] at @s run function cam:machine/crafting_table/shiftdealt
    data/cam/functions/machine/crafting_table/shifttest:


代码:

  1. replaceitem block ~ ~ ~ container.16 minecraft:air
  2. function cam:machine/crafting_table/recipe
  3. execute if data block ~ ~ ~ {Items:[{Slot:16b}]} run function cam:machine/crafting_table/shifttest
   data/cam/functions/machine/crafting_table/shiftdealt:

代码:

  1. setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
  2. data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{tag:{CAM_output:1b}}].id
  3. data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{tag:{CAM_output:1b}}].Count
  4. data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{tag:{CAM_output:1b}}].tag
  5. data remove block ~ 255 ~ Items[0].tag.CAM_output
  6. execute as @s store result score @s CAM_shiftcount run data get block ~ 255 ~ Items[0].Count
  7. scoreboard players operation @s CAM_shiftcount *= @s CAM_shiftdealt
  8. execute if score @s CAM_shiftcount matches 65.. run function cam:machine/crafting_table/sub_shiftdealt
  9. execute as @s store result block ~ 255 ~ Items[0].Count byte 1 run scoreboard players get @s CAM_shiftcount
  10. loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  11. setblock ~ 255 ~ air
  data/cam/functions/machine/crafting_table/sub_shiftdealt:

代码:

  1. loot replace block ~ 255 ~ container.1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
  2. data modify block ~ 255 ~ Items[-1].Count set value 64
  3. scoreboard players remove @s CAM_shiftcount 64
  4. execute if score @s CAM_shiftcount matches 65.. run function cam:machine/crafting_table/sub_shiftdealt
  首先,这么区分Shift+左键和单纯左键?
   版主大大@SPGoding 是这么回复的:
   
。  OK,可以开始搞事了!
  原理:首先,对物品栏内有带CAM_output:1b的物品的玩家(先于输出物品处理)加上CAM_shiftcheck的标签进行检测;
   然后,检测此时有没有输出栏内为真空的合成台(此时recipe暂未执行,所有合成台内均为输出品或占位符),如有则说明玩家使用了shift(我想至少现在没有能在1/20秒内完成左键选中+移动+左键放置的玩家吧),执行shift测试指令。
  shift测试指令:通过循环执行配方指令+清除输出栏物品来达到对配方还能使用次数的计数,看到配方函数最后一行的计分板命令了吗?就是为这里准备的。
  由于此时执行对象还是盔甲架,因此我们要把盔甲架上的分数转移到玩家上。
  然后选定玩家为执行者,进行处理(因为shiftcheck函数每刻执行,所以条件决不能省(我就因为这个调试了大半个小时)(视频里还有这个bug))
  shift处理函数:将玩家物品栏内物品数据复制到潜影盒上,把该数据复制到计分板CAM_shiftcount,把这个数据乘以CAM_shiftdealt上的数(即执行配方的次数),复制回潜影盒,再掉包给玩家,这回不用确定槽位了,因为shift和loot give指令一样,是自动整理的。
  但有时会出现乘完后数目大于64的情况,我不知道是否要处理,但我还是设计了以上shift辅助处理函数(sub_shiftdealt):
  将潜影盒内物品数量向后复制一位(比如原来0槽位的复制到1号位,1号到2号,但0号位不变,这样潜影盒物品所占槽位数量就多了一个),再把最后的一个物品项数量改为64,然后计分板减去64,若其还多,循环执行。
  (亲测有效)



后记
这是我在开发自己的综合类原版模组时的一点心得,也是可能算是创新的一点优化。看起来还真凉了。。。。。报应啊目前问题
1、右键侦测暂无,建议我目前没有合成多个物品的配方,暂不考虑制作,因为可能要重写系统,如果这样我肯定不会更
2、因为使用了输出标签,所以一开始合成出来的东西不可堆叠,所以背包内至少要留一个空位3、同样因为使用了输出标签,导致按下shift前若背包内有合成的物品,也不可堆叠,,视为已被占满的槽位
下载
该数据包已经被提取出来,命名为CNC,现已发布
【LAY Studio|原版模组|CNC】NBT合成台


鸣谢:
ruhuasiyu:原版模组教程
ruhuasiyu:原版模组《更多的合成》
SPGoding该问题中的解答
@Medi*******(应本人要求匿名)对物品给予方面的优化建议
@不笑君对清除合成区物品清除方面优化的建议
@VCS-Official 对多个重复物品合成的建议
@晴路卡 对tag合成问题的解答



CR_019
本帖最后由 chaoren019 于 2020-2-25 17:20 编辑

有疑问或改进建议可在评论区提出

CR_019
本帖最后由 chaoren019 于 2020-1-31 20:38 编辑

这个东西的已知缺点:
1、右键侦测没做。。。现在会出现错误
2、因为使用了输出标签,所以一开始合成出来的东西不可堆叠,所以背包内至少要留一个空位(那我可以删除回复吗)


ruhuasiyu
gui的处理我在1.10版本已经做了,不过还没发布,检测gui发生改变我是用断言来检测的,教程里可能漏写了。

CR_019
本帖最后由 chaoren019 于 2020-2-25 17:21 编辑
ruhuasiyu 发表于 2020-1-30 10:06
gui的处理我在1.10版本已经做了,不过还没发布,检测gui发生改变我是用断言来检测的,教程里可能漏写了。 ...

话说1.10什么时候发布?期待一下(又可以抄代码了(误))

(为什么我这边断言就不管用呢。。。)



wshycaa
楼主自己造轮子ing……

Summer621
6666666666666666666666666

不笑君
啊!!我想要单品.能给我一份吗

凌空的猫
我也做过这东西(自己造轮子),和你的差不多,但真的没想到怎么检测Shift,果然是大佬QUQ

CR_019
本帖最后由 chaoren019 于 2020-2-26 09:05 编辑
不笑君 发表于 2020-1-31 18:41
啊!!我想要单品.能给我一份吗

可以给一个没处理过的粗糙版本,只要你可以忍受我数据包自带的“CAM_”前缀。。。尽量自己改改吧。。。(提示:没改全会出现bug)
已将单品链接上线,见第3页

woaibaihu
额鹅鹅鹅鹅鹅鹅饿鹅鹅鹅鹅鹅鹅饿

12tianxun
所以说,这么多都是帮rua修bug?(rua,出来找打)@ruhuasiyu

worid.
新人好祝新人2021年快乐

神奇的BL
你这个是检测箱子类内部的物品吗
发射器之类的也可以吧~

CR_019
本帖最后由 CR_019 于 2021-2-13 18:14 编辑
Biondo 发表于 2021-1-28 09:39
你这个是检测箱子类内部的物品吗
发射器之类的也可以吧~

发射器也可以,但是发射器只有9个槽位,不够这里需要的功能
利用发射器做合成台的看这里https://www.mcbbs.net/forum.php? ... ortid%26sortid%3D38


xiaoqiqi0923
所以我们是来帮你修bug的?? 帮你体验bug awa

xiaoqiqi0923
你的数据包自带 bug XP系统用不了啊 awa

神乐丢丢
可以啊,学到了

神乐丢丢

哈哈哈
被发现了

神乐丢丢
牛逼啊,学到了

xhl123
有点拿到弄  我后面去试试

第一页 上一页 下一页 最后一页