本帖最后由 CR_019 于 2022-3-26 21:53 编辑
复制代码
复制代码
前言
一年过后,我把这个包提取出来,对一些上一版存在的缺陷进行了修复和改进,并且发布。
在CNC发布之际,有必要把新增与修改的功能讲解一遍。
适合有一定命令和数据包开发基础的玩家阅读。
与上一版重复的部分不作提示。
正文
加载时运行函数:
cnc/functions/machine/crafting_table/load:
加载数据包用到的计分板。
每刻运行函数:
cnc/functions/machine/crafting_table/tick:
#开头基础处理 #放置与破坏处理
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入处理模块的计分板重置#放置与破坏处理:第1条:检测放置合成台(配合进度),第2条:检测破坏合成台第3条:防止盔甲架变黑
第4条:防止位于0槽位的gui被移动
#功能见子页面
#配方处理:cnc/functions/machine/crafting_table/recipe:
#获取已占槽位:
为配方的判定做准备,判定有多少个合成槽位有物品,以防止多放物品的情况无法被检测到;
使用计分板处理。
cnc/functions/machine/crafting_table/recipes/count:
#清除合成区物品:
检测输出物品被拿取时,将合成区物品数量-1;
检测的方式是这样的:
在输出栏(槽位16)空置时,占位物品有两个标签:"CNC_bg:1b"和"Output:1b"
输出栏有输出物品时,该物品有一个标签:"Output:1b"
而当玩家拿出输出栏物品后,有一个短暂的“真空期”,即在输出栏没有物品。
这里根据这三种状态的不同来判定玩家是否拿出输出栏物品。但是这种方法不能检测出右键拿取物品的行为。
cnc/functions/machine/crafting_table/recipes/clear:
这是一个穷举模块,在清除合成栏物品的同时,对药水、蜂蜜瓶等物品进行特殊处理。展示其中一个函数,其余类推,下同;
cnc/functions/machine/crafting_table/recipes/clear/1:
#右键侦测:
当一个配方的产物数量大于1时,玩家在输出栏点击右键,会拿取其中的一半物品,此时不能检测到输出栏物品被拿取,合成栏物品不会被清除,而在下一刻配方处理模块会将输出栏物品的数量复位,导致可以无限刷物品,这也是上一个版本中较为严重的一个问题。
这里设计这个模块来防止。
#开头的右键侦测前置:
分两部分,第一部分为前三条命令,判定手上拿着输出物品(含有"Output:1b"标签,该标签在玩家物品栏中会被清除)的玩家;
第二部分为后两条命令,与结尾的右键侦测前置一起,原来规避一种重大问题,在讲结尾前置的时候一并提及。
#右键侦测主命令:
合成台侦测周围有手上拿着输出物品的玩家,且自己的输出栏内仍有输出物品,则判定为玩家使用右键拿取了物品,触发右键操作函数
cnc/functions/machine/crafting_table/rightclick:
该操作先清除手中拿取的物品,然后重新载入配方,使输出栏物品数量恢复,然后使用rua影盒技术(误)将输出栏物品放到玩家物品栏中,最后清除合成区物品。
#结尾的右键侦测前置: 这么处理还有一个严重的问题,就是当用左键拿出物品后,在下一刻,合成台执行了配方模块函数,把配方复位后,就能够满足“右键侦测”条件,从而把物品复制到玩家物品栏中。表现上为左键和右键行为一样。 因此,在这一刻的结尾(经配方模块复位)执行获取输出栏的物品数量,在下一刻的开头(玩家操作后)再执行一次,并比较两者是否相同。若相同,则表示玩家未使用右键,不触发右键操作,反之亦然。
在清除合成区物品和右键侦测模块中还有这么一行:这是误放入处理的特殊处理,适用于在槽位16有输出物品的时候的处理,到误放入处理时讲解。
#配方检测
检测自定义的配方,见自定义配方的操作方法。
#shift处理相关:见Shift处理。
#输出标签处理:
cnc/functions/machine/crafting_table/inventory:
cnc/functions/machine/crafting_table/inventory/0:
使用穷举的方法,结合rua影盒技术,除去在玩家物品栏的输出物品的输出标签"Output"
注意用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。
#误放入处理cnc/functions/machine/crafting_table/check:cnc/functions/machine/crafting_table/replace/0:
cnc/functions/machine/crafting_table/replace/16_spe:
使用穷举,判定误放入合成台背景或输出栏的物品,并返还给玩家。
输出栏有物品的情况由配方检测处的那一条命令处理。
#shift键处理:
重头戏。首先检测背包里有标签"Output:1b"物品的玩家,给这个玩家加上CAM_shiftcheck的tag,然后检测是否有此tag的玩家,如有则以第16槽位为“真空”的合成台为执行者执行命令通过这两个(红字)条件,可判定玩家是否使用了shift,具体原因见SPGoding在该问题中的解答:
shift检测:cnc/functions/machine/crafting_table/shiftcheck:
里面所谓的计分板数据转移是因为命令的执行者不同:玩家或合成台(即在合成台位置的盔甲架)而计算时把数据放在一起会省事一点。
#检测玩家剩余槽位数:
第一版有一个重大的问题,就是当物品给予数量超过玩家物品栏可容下的最大数量时,仍会尝试将合成台里的原料消耗完,而物品却并没有多给,这是我们不想要的。因此在这里使用穷举方法,通过CNC_player_count计分板数据来获取玩家剩余槽位,以限制模拟合成的执行次数。cnc/functions/machine/crafting_table/shift_player:
#检测当前物品最大可堆叠数量:cnc/functions/machine/crafting_table/shift_data_get:首先侦测输出物品是否为不可堆叠物品,如果是,将计分板数据设置为1,接下来检测是否为以16个为一组的物品,如都不是,则默认为以64个为一组的物品。便于下面的计算。
#模拟合成:cncfunctions/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:
cnc/functions/machine/crafting_table/sub_shiftdealt:
译: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)
#有序合成:
#无序合成:
#同种多物品无序合成:
这里一开始我准备使用计分板计算的方法,后来@VCS-Official提醒我可以用execute if 简便地解决,在此致谢
#tag合成:
这里运用了穷举的办法获取物品是否符合断言,使得自定义该种配方的操作较为繁琐。由于需要动态的断言名称,暂时想不到很好的内建的方案。
来源于@晴路卡在该问题中的解答,进行了一定的修改。在此致谢。
其中引用的断言文件:replaceitem指令也可以用loot replace取代。
楼下会不会看到某位(来了呢
前言 经过近一个月的开发,我把上一版的部分内容,特别是shift处理的部分进行了优化。虽然照例是有一个视频的,但是我没空剪。就这样吧。 为了让这个帖子凉的更快一点,我决定只放干货。毕竟水的比热容大一点。。。 由于基于我的数据包,因此内部的计分板和tag均带有本数据包标志“CAM”,见谅。 开始。 data/cam/functions/machine/crafting_table/tick:#开头基础处理 #放置与破坏处理 没有变化。下面是复制的内容。
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入背景物品返还模块玩家确定的计分板重置
#放置与破坏处理:第1条:检测放置工作台(配合进度(就是视频里的advancement,用于调试的)),
第2条:检测破坏合成台
3:防止盔甲架变黑
#功能同第一版一样由于运用到recipes,shift放到后面讲。#配方处理 data/cam/functions/machine/crafting_table/recipe:变化不大。
#获取已占槽位:为配方的判定做准备,判定有多少个合成槽位有物品
data/cam/functions/machine/crafting_table/recipes/count:
#清除合成区物品:检测输出物品被拿取时,将合成区物品数量-1,
cam/functions/machine/crafting_table/recipes/clear:
这是一个穷举索引,下面展示其中一个:cam/functions/machine/crafting_table/recipes/clear/1:红字为主要实现的指令,其余为药水和蜂蜜瓶的特殊处理。由于我懒得翻译了,自己看吧。反正我针对的对象也不是完全不会命令的复制一下检测清除的翻译: 原理:从第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:(其中一个配方)
有序合成:指定Slot和物品属性,用CAM_table_count计分板确定已占槽位数,以达到多占槽位即判定不通过的目的;
无序合成:基本同上,不指定Slot
#误放入处理 #结尾基础处理
没有变化。复制一下第一版内容:
#误放入处理:
data/cam/functions/machine/crafting_table/check: 同样是一个穷举索引 data/cam/functions/machine/crafting_table/replace/0:
原理:若在箱子里检测到没有CAM_bg标签(因为在tick里高频清除了玩家和地面的该种物品,所以可以由此判断玩家放入了其他物品),则将其复制到潜影盒里,返还给玩家(本来想精确到特定slot,但因难度太大放弃了)。具体实现方法见[技巧] 修改玩家背包物品信息(免穷举 #结尾基础处理:清除玩家物品栏内的带CAM_bg:1b的物品,重置有关shift处理计分板。
以下为大改内容:#shift键处理:
翻译:首先检测背包里有标签CAM_output:1b物品的玩家,给这个玩家加上CAM_shiftcheck的tag,然后检测是否有此tag的玩家,如有则以第16槽位为“真空”的合成台为执行者执行命令通过这两个(红字)条件,可判定玩家是否使用了shift,具体原因见SPGoding在该问题中的解答 shift检测:data/cam/functions/machine/crafting_table/shiftcheck:
其中有一些条件已经不需要了,但是因为我懒,所以没有删除里面所谓的计分板数据转移是因为命令的执行者不同:玩家或合成台(即在合成台位置的盔甲架)而计算时把数据放在一起会省事一点。#检测玩家剩余槽位数:上个版本有一个重大的问题,就是当物品给予数量超过玩家物品栏可容下的最大数量时,仍会尝试将合成台里的原料消耗完,这是我们不想要的。因此在这里通过CAM_player_count计分板数据来获取玩家剩余槽位,以限制模拟合成的执行次数。data/cam/functions/machine/crafting_table/shift_player:没什么好看的,就是穷举。#检测当前物品最大可堆叠数量:没什么好解释的吧#模拟合成:
data/cam/functions/machine/crafting_table/shifttest:
该模拟合成有两个限制:原料和玩家物品栏。原料限制可以由配方函数控制,而玩家物品栏限制则为计算(括号内为对应计分板名):首先将玩家所剩槽位数(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:data/cam/functions/machine/crafting_table/sub_shiftdealt:翻译:1、-放置rua影盒2、-复制玩家合成出的物品数据 -如果要合成的物品数量大于64,将盒中物品数量设为64 -如果数量介于0与64之间,将盒中物品数量设为要合成的物品数量3、-将盒中物品给予玩家4、-将数量减去64 -若变量小于0,则停止 -若变量大于0,则继续从第二步执行5、清除rua影盒至此,有关shift的处理讲解结束。
#输出标签处理:极其辛酸的部分,因为这个东西我卡了十来天。
先讲解吧,事故现场后面放。事故现场丢了
data/cam/functions/machine/crafting_table/inventory:
穷举玩家含有CAM_output:1b的物品槽位并通过rua影盒处理之:
data/cam/functions/machine/crafting_table/inventory/0:
data/cam/functions/machine/crafting_table/inventory/9:
注意用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:
我在教程里发现了这么一段:

然而,数据包里好像并没有应用到。。。 于是我就设计了这个check函数: data/cam/functions/machine/crafting_table/check:
data/cam/functions/machine/crafting_table/replace/0:
check函数里的18条命令其实是一条命令,这里运用了穷举。
原理:若在箱子里检测到没有CAM_bg标签(因为在tick里高频清除了玩家和地面的该种物品,所以可以由此判断玩家放入了其他物品),则将其复制到潜影盒里,返还给玩家(本来想精确到特定slot,但因难度太大放弃了)。具体实现方法见[技巧] 修改玩家背包物品信息(免穷举
至此,解决。
问题2
这个就简单了。
如果通过战利品表来实现,还是有难度的,但是我们可以用Bugjang特性来解决
既然创造模式打掉方块不掉方块本体,而生存模式会掉,那我们为什么不利用这一特性呢?
这就是这里的思路了。
data/cam/functions/machine/crafting_table/clear:
总体梳理 注意:本部分包含了大量代码,不想看的同志们可以离开了。可以回到第二页观看短视频。
我只是想把我的合成台做得更人性化一点,也更像原版一点,于是把它优化了 亿 点 点
现在开始梳理
首先,再次展示一下tick:
data/cam/functions/machine/crafting_table/tick:
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入背景物品返还模块玩家确定的计分板重置
#放置与破坏处理:第1条:检测放置工作台(配合进度(就是视频里的advancement,用于调试的)),
第2条:检测破坏合成台
3:防止盔甲架变黑
#功能:
#Shift键处理:本人最自豪的部分之一,由于涉及到下方函数,原理先放一下。
#配方处理:
先亮代码:
data/cam/functions/machine/crafting_table/recipe:
(这里的CAM_shiftdealt计分板就是有关shift处理的)
data/cam/functions/machine/crafting_table/recipes/count:
data/cam/functions/machine/crafting_table/recipes/bamboo_sword:(其中一个配方)
data/cam/functions/machine/crafting_table/recipes/clear:(清除合成栏物品)
原理:从第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:
data/cam/functions/machine/crafting_table/shifttest:
data/cam/functions/machine/crafting_table/shiftdealt: data/cam/functions/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合成问题的解答
第四版前言
最近对1.3版本进行了一些不小的改进,同时该原理简介已经过于老旧(还停留在1.16版本),因此更新一下此贴,使其适用于最新版本的MC和CNC数据包。
正文
载入计分板:
cnc/functions/machine/crafting_table/load:
- <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>
- <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>
- <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>
- <div align="left">scoreboard objectives add CNC_pd dummy</div>
- <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:
- <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>
- <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>
- <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>
- <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:
代码:
- scoreboard objectives add CNC_crafterror dummy
- scoreboard objectives add CNC_table_count dummy
- scoreboard objectives add CNC_output dummy
- scoreboard objectives add CNC_clear dummy
- scoreboard objectives add CNC_shiftdealt dummy
- scoreboard objectives add CNC_shiftcount dummy
- scoreboard objectives add CNC_player_count dummy
- scoreboard objectives add CNC_bottlecount dummy
- scoreboard objectives add CNC_item_trigger dummy
- scoreboard objectives add CNC_shift_muti dummy
- scoreboard objectives add CNC_shapeless dummy
- scoreboard objectives add CNC_SLtemp dummy
- scoreboard objectives add CNC_SLout dummy
- scoreboard objectives add CNC_craftag dummy
- scoreboard objectives add CNC_rclick dummy
- scoreboard objectives add CNC_rclick_sub dummy
- scoreboard objectives add CNC_rclick_suc dummy
- scoreboard objectives add CNC_rclick_sub2 dummy
- scoreboard objectives add CNC_rclick_sub3 dummy
加载数据包用到的计分板。
每刻运行函数:
cnc/functions/machine/crafting_table/tick:
代码:
- #开头基础处理:物品处理 初始化变量
- kill @e[nbt={Item:{tag:{CNC_bg:1b}}}]
- execute store result score @a CNC_crafterror run clear @a minecraft:firework_star{CNC_bg:1b} 0
- execute as @a store result score @s CNC_bottlecount run clear @a #nbt_crafting:cam_recipes 0
- #放置与破坏处理
- 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
- 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
- execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] run data modify entity @s Fire set value 32767s
- execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/gui
- #功能
- #Shift键处理
- execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] run tag @s add CNC_shiftcheck
- 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
- #配方处理
- execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/recipe
- #输出标签处理
- execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] at @s run function cnc:machine/crafting_table/inventory
- #误放入处理
- execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/check
- #Shift键处理 初始化tag
- tag @a remove CNC_shiftcheck
- #结尾基础处理:物品处理 初始化变量
- clear @a firework_star{CNC_bg:1b}
- scoreboard players reset $temp CNC_rclick_suc
- scoreboard players reset @a CNC_rclick
#开头基础处理 #放置与破坏处理
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入处理模块的计分板重置#放置与破坏处理:第1条:检测放置合成台(配合进度),第2条:检测破坏合成台第3条:防止盔甲架变黑
第4条:防止位于0槽位的gui被移动
#功能见子页面
#配方处理:
代码:
- #配方处理
- execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/recipe
代码:
- #获取已占槽位
- function cnc:machine/crafting_table/recipes/count
- #右键侦测前置
- execute as @a store result score @s CNC_rclick run clear @s #uin:tech/all{Output:1b} 0
- execute as @a store result score @s CNC_rclick_sub run clear @s #uin:tech/all{Output:1b,CNC_bg:1b} 0
- execute as @a run scoreboard players operation @s CNC_rclick -= @s CNC_rclick_sub
- 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
- execute as @s run scoreboard players operation @s CNC_rclick_sub2 -= @s CNC_rclick_sub3
- scoreboard players operation @s 6 = @s CNC_rclick_sub2
- #清除合成区物品
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CNC_not_to_clear] run function cnc:machine/crafting_table/recipes/clear
- tag @s remove CNC_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CNC_bg:1b}}]} run tag @s add CNC_not_to_clear
- 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
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
- 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
- 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}
- #配方检测
- function #cnc:recipes
- #右键侦测前置
- 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
- #初始化变量
- scoreboard players reset @s CNC_table_count
- #shift处理相关
- 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:
代码:
- execute if data block ~ ~ ~ Items[{Slot:1b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:2b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:3b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:10b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:11b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:12b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:19b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:20b}] run scoreboard players add @s CNC_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:21b}] run scoreboard players add @s CNC_table_count 1
#清除合成区物品:
检测输出物品被拿取时,将合成区物品数量-1;
检测的方式是这样的:
在输出栏(槽位16)空置时,占位物品有两个标签:"CNC_bg:1b"和"Output:1b"
输出栏有输出物品时,该物品有一个标签:"Output:1b"
而当玩家拿出输出栏物品后,有一个短暂的“真空期”,即在输出栏没有物品。
这里根据这三种状态的不同来判定玩家是否拿出输出栏物品。但是这种方法不能检测出右键拿取物品的行为。
代码:
- #清除合成区物品(截取模块)
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CNC_not_to_clear] run function cnc:machine/crafting_table/recipes/clear
- tag @s remove CNC_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CNC_bg:1b}}]} run tag @s add CNC_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
代码:
- function cnc:machine/crafting_table/recipes/clear/1
- function cnc:machine/crafting_table/recipes/clear/2
- function cnc:machine/crafting_table/recipes/clear/3
- function cnc:machine/crafting_table/recipes/clear/10
- function cnc:machine/crafting_table/recipes/clear/11
- function cnc:machine/crafting_table/recipes/clear/12
- function cnc:machine/crafting_table/recipes/clear/19
- function cnc:machine/crafting_table/recipes/clear/20
- function cnc:machine/crafting_table/recipes/clear/21
这是一个穷举模块,在清除合成栏物品的同时,对药水、蜂蜜瓶等物品进行特殊处理。展示其中一个函数,其余类推,下同;
cnc/functions/machine/crafting_table/recipes/clear/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
- execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} run replaceitem block ~ ~ ~ container.1 minecraft:glass_bottle 2
- 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
#右键侦测:
代码:
- #右键侦测(截取模块)
- #右键侦测前置
- execute as @a store result score @s CNC_rclick run clear @s #uin:tech/all{Output:1b} 0
- execute as @a store result score @s CNC_rclick_sub run clear @s #uin:tech/all{Output:1b,CNC_bg:1b} 0
- execute as @a run scoreboard players operation @s CNC_rclick -= @s CNC_rclick_sub
- 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
- execute as @s run scoreboard players operation @s CNC_rclick_sub2 -= @s CNC_rclick_sub3
- scoreboard players operation @s 6 = @s CNC_rclick_sub2
- #清除合成区物品
- 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
- 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}
- #右键侦测前置
- 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时,玩家在输出栏点击右键,会拿取其中的一半物品,此时不能检测到输出栏物品被拿取,合成栏物品不会被清除,而在下一刻配方处理模块会将输出栏物品的数量复位,导致可以无限刷物品,这也是上一个版本中较为严重的一个问题。
这里设计这个模块来防止。
#开头的右键侦测前置:
分两部分,第一部分为前三条命令,判定手上拿着输出物品(含有"Output:1b"标签,该标签在玩家物品栏中会被清除)的玩家;
第二部分为后两条命令,与结尾的右键侦测前置一起,原来规避一种重大问题,在讲结尾前置的时候一并提及。
#右键侦测主命令:
合成台侦测周围有手上拿着输出物品的玩家,且自己的输出栏内仍有输出物品,则判定为玩家使用右键拿取了物品,触发右键操作函数
cnc/functions/machine/crafting_table/rightclick:
代码:
- #清除手里的物品
- clear @a[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] #uin:tech/all{Output:1b}
- #重载配方
- replaceitem block ~ ~ ~ container.16 air
- function #cnc:recipes
- #物品给予
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- execute if data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[{Slot:16b}]
- execute unless data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set value {Slot:0b,id:"minecraft:air",Count:1b}
- 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}
- setblock ~ 255 ~ air
- #清除合成区物品
- execute if score $temp CNC_rclick_suc matches 1.. run function cnc:machine/crafting_table/recipes/clear
该操作先清除手中拿取的物品,然后重新载入配方,使输出栏物品数量恢复,然后使用rua影盒技术(误)将输出栏物品放到玩家物品栏中,最后清除合成区物品。
#结尾的右键侦测前置: 这么处理还有一个严重的问题,就是当用左键拿出物品后,在下一刻,合成台执行了配方模块函数,把配方复位后,就能够满足“右键侦测”条件,从而把物品复制到玩家物品栏中。表现上为左键和右键行为一样。 因此,在这一刻的结尾(经配方模块复位)执行获取输出栏的物品数量,在下一刻的开头(玩家操作后)再执行一次,并比较两者是否相同。若相同,则表示玩家未使用右键,不触发右键操作,反之亦然。
在清除合成区物品和右键侦测模块中还有这么一行:
代码:
- 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
#配方检测
检测自定义的配方,见自定义配方的操作方法。
#shift处理相关:见Shift处理。
#输出标签处理:
代码:
- #输出标签处理
- execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] at @s run function cnc:machine/crafting_table/inventory
cnc/functions/machine/crafting_table/inventory:
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- execute if data entity @s {Inventory:[{Slot:0b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/0
- execute if data entity @s {Inventory:[{Slot:1b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/1
- execute if data entity @s {Inventory:[{Slot:2b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/2
- execute if data entity @s {Inventory:[{Slot:3b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/3
- execute if data entity @s {Inventory:[{Slot:4b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/4
- execute if data entity @s {Inventory:[{Slot:5b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/5
- execute if data entity @s {Inventory:[{Slot:6b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/6
- execute if data entity @s {Inventory:[{Slot:7b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/7
- execute if data entity @s {Inventory:[{Slot:8b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/8
- execute if data entity @s {Inventory:[{Slot:9b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/9
- execute if data entity @s {Inventory:[{Slot:10b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/10
- execute if data entity @s {Inventory:[{Slot:11b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/11
- execute if data entity @s {Inventory:[{Slot:12b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/12
- execute if data entity @s {Inventory:[{Slot:13b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/13
- execute if data entity @s {Inventory:[{Slot:14b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/14
- execute if data entity @s {Inventory:[{Slot:15b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/15
- execute if data entity @s {Inventory:[{Slot:16b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/16
- execute if data entity @s {Inventory:[{Slot:17b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/17
- execute if data entity @s {Inventory:[{Slot:18b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/18
- execute if data entity @s {Inventory:[{Slot:19b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/19
- execute if data entity @s {Inventory:[{Slot:20b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/20
- execute if data entity @s {Inventory:[{Slot:21b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/21
- execute if data entity @s {Inventory:[{Slot:22b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/22
- execute if data entity @s {Inventory:[{Slot:23b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/23
- execute if data entity @s {Inventory:[{Slot:24b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/24
- execute if data entity @s {Inventory:[{Slot:25b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/25
- execute if data entity @s {Inventory:[{Slot:26b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/26
- execute if data entity @s {Inventory:[{Slot:27b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/27
- execute if data entity @s {Inventory:[{Slot:28b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/28
- execute if data entity @s {Inventory:[{Slot:29b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/29
- execute if data entity @s {Inventory:[{Slot:30b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/30
- execute if data entity @s {Inventory:[{Slot:31b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/31
- execute if data entity @s {Inventory:[{Slot:32b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/32
- execute if data entity @s {Inventory:[{Slot:33b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/33
- execute if data entity @s {Inventory:[{Slot:34b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/34
- execute if data entity @s {Inventory:[{Slot:35b,tag:{Output:1b}}]} run function cnc:machine/crafting_table/inventory/35
- setblock ~ 255 ~ air
cnc/functions/machine/crafting_table/inventory/0:
代码:
- data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{Slot:0b}].id
- data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{Slot:0b}].Count
- data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{Slot:0b}].tag
- data remove block ~ 255 ~ Items[0].tag.Output
- loot replace entity @s hotbar.0 1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
使用穷举的方法,结合rua影盒技术,除去在玩家物品栏的输出物品的输出标签"Output"
注意用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。
#误放入处理
代码:
- #误放入处理
- execute as @e[type=minecraft:armor_stand,tag=cnc_crafting,tag=CNC_craft_enable] at @s run function cnc:machine/crafting_table/check
代码:
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:0b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/0
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{Output:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/16
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:4b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:6b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:8b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:13b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/13
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:14b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/14
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:15b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/15
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:17b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/17
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:18b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/18
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:22b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/22
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:23b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/23
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:24b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/24
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:25b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/25
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:26b,tag:{CNC_bg:1b}}]} positioned ~ ~ ~ run function cnc:machine/crafting_table/replace/26
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[0]
- 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}}
- execute as @e[sort=nearest,limit=1,scores={CNC_crafterror=1..}] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- execute at @s run setblock ~ 255 ~ air
cnc/functions/machine/crafting_table/replace/16_spe:
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- execute if data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[{Slot:16b}]
- execute unless data block ~ ~ ~ Items[{Slot:16b}] run data modify block ~ 255 ~ Items[0] set value {Slot:0b,id:"minecraft:air",Count:1b}
- execute as @e[sort=nearest,limit=1,scores={CNC_rclick=1..},distance=..5] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- setblock ~ 255 ~ air
使用穷举,判定误放入合成台背景或输出栏的物品,并返还给玩家。
输出栏有物品的情况由配方检测处的那一条命令处理。
#shift键处理:
重头戏。
代码:
- #Shift键处理
- execute as @a[nbt={Inventory:[{tag:{Output:1b}}]}] run tag @s add CNC_shiftcheck
- 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
单纯左键:该物品立刻消失,直到玩家再次左键放下前,检测不到该物品。Shift + 左键:该物品立刻消失并立刻出现在玩家物品栏内。
shift检测:cnc/functions/machine/crafting_table/shiftcheck:
代码:
- #初始化变量和tag
- scoreboard players set @s CNC_shiftdealt 2
- scoreboard players set @a CNC_player_count 37
- scoreboard players reset @a CNC_item_trigger
- #检测玩家剩余槽位数和当前物品最大可堆叠数量,以及计分板数据转移
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CNC_shiftcheck] at @s run function cnc:machine/crafting_table/shift_player
- scoreboard players operation @s CNC_player_count = @e[tag=CNC_shiftcheck] CNC_player_count
- function cnc:machine/crafting_table/shift_data_get
- scoreboard players operation @s CNC_player_count *= @s CNC_item_trigger
- execute store result score @s CNC_shift_muti run clear @a[tag=CNC_shiftcheck] #uin:tech/all{Output:1b} 0
- scoreboard players operation @s CNC_shiftdealt *= @s CNC_shift_muti
- #模拟执行合成操作,以确定可执行的最大合成次数
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @e[tag=CNC_shiftcheck] run function cnc:machine/crafting_table/shifttest
- execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless score @s CNC_shiftdealt < @s CNC_player_count run function cnc:machine/crafting_table/recipes/clear
- scoreboard players operation @s CNC_shiftdealt /= @s CNC_shift_muti
- #补偿机制相关
- execute as @e[tag=CNC_comp] run scoreboard players remove @s CNC_shiftdealt 1
- #清除输出栏
- replaceitem block ~ ~ ~ container.16 minecraft:air
- #(辅助)给予次数运算
- scoreboard players remove @s CNC_shiftdealt 2
- #计分板数据转移
- scoreboard players operation @e[tag=CNC_shiftcheck] CNC_shiftdealt = @s CNC_shiftdealt
- #给予玩家物品
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CNC_shiftcheck] at @s run function cnc:machine/crafting_table/shiftdealt
- #输出栏处理
- 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}
- #初始化
- tag @s remove CNC_comp
里面所谓的计分板数据转移是因为命令的执行者不同:玩家或合成台(即在合成台位置的盔甲架)而计算时把数据放在一起会省事一点。
#检测玩家剩余槽位数:
第一版有一个重大的问题,就是当物品给予数量超过玩家物品栏可容下的最大数量时,仍会尝试将合成台里的原料消耗完,而物品却并没有多给,这是我们不想要的。因此在这里使用穷举方法,通过CNC_player_count计分板数据来获取玩家剩余槽位,以限制模拟合成的执行次数。cnc/functions/machine/crafting_table/shift_player:
代码:
- execute if data entity @s Inventory[{Slot:0b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:1b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:2b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:3b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:4b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:5b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:6b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:7b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:8b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:9b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:10b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:11b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:12b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:13b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:14b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:15b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:16b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:17b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:18b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:19b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:20b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:21b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:22b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:23b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:24b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:25b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:26b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:27b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:28b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:29b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:30b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:31b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:32b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:33b}] run scoreboard players remove @s CNC_player_count 1
- execute if data entity @s Inventory[{Slot:34b}] run scoreboard players remove @s CNC_player_count 1
- 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:
代码:
- execute as @e[tag=CNC_shiftcheck,limit=1,sort=nearest] run scoreboard players set @s CAM_item_trigger 0
- 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
- 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
- execute as @e[tag=CNC_shiftcheck,limit=1] store result score @s CNC_item_trigger run clear @s #cnc:16x{Output:1b} 0
- 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
- 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
#模拟合成:cncfunctions/machine/crafting_table/shifttest:
代码:
- scoreboard players operation @s CNC_shiftdealt /= @s CNC_shift_muti
- replaceitem block ~ ~ ~ container.16 minecraft:air
- function cnc:machine/crafting_table/recipe
- scoreboard players operation @s CNC_shiftdealt *= @s CNC_shift_muti
- 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
- 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:
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{tag:{Output:1b}}].id
- data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{tag:{Output:1b}}].Count
- data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{tag:{Output:1b}}].tag
- execute as @s store result score @s CNC_shiftcount run data get block ~ 255 ~ Items[0].Count
- scoreboard players operation @s CNC_shiftcount *= @s CNC_shiftdealt
- function cnc:machine/crafting_table/sub_shiftdealt
- setblock ~ 255 ~ air
cnc/functions/machine/crafting_table/sub_shiftdealt:
代码:
- execute if score @s CNC_shiftcount matches 64.. run data modify block ~ 255 ~ Items[0].Count set value 64
- 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
- execute as @s if score @s CNC_shiftcount matches 1.. run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- scoreboard players remove @s CNC_shiftcount 64
- execute if score @s CNC_shiftcount matches 1.. run function cnc:machine/crafting_table/sub_shiftdealt
- 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)
#有序合成:
代码:
- #有序合成:在检测方块时注明Slot(合成区Slot:由上到下,由左到右依次为:1b,2b,3b;10b,11b,12b;19b,20b,21b)
- #镜像合成穷举一遍
- #示例:铁斧
- 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
- 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
#无序合成:
代码:
- #无重复的物品的无序合成:不注明Slot即可
- #无序合成与有序合成可以混用(如一部分材料限定位置,另一部分不限定)
- #示例:末影之眼
- 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
#同种多物品无序合成:
代码:
- #有重复物品的无序合成:先用exe if辅助判断一下需要的重复物品的个数,列入检测即可
- #示例:书的合成
- #无序合成模块
- 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 replaceitem block ~ ~ ~ container.16 book
这里一开始我准备使用计分板计算的方法,后来@VCS-Official提醒我可以用execute if 简便地解决,在此致谢
#tag合成:
这里运用了穷举的办法获取物品是否符合断言,使得自定义该种配方的操作较为繁琐。由于需要动态的断言名称,暂时想不到很好的内建的方案。
来源于@晴路卡在该问题中的解答,进行了一定的修改。在此致谢。
代码:
- #含有tag的配方比较复杂,要先设置一个断言,并在这里引用,穷举每一个合成区的物品,检测其是否符合该断言。在下方该tag处,不要键入id。建议直接复制这里的代码
- #断言路径:cnc:crafting_table/planks
- #示例:碗的合成
- #初始化
- scoreboard players reset @s CAM_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 CAM_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 CAM_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 CAM_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 CAM_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 CAM_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 CAM_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 CAM_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 CAM_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 CAM_craftag 1
- #主命令
- 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
- 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
其中引用的断言文件:
代码:
- {
- "condition": "minecraft:entity_properties",
- "entity": "this",
- "predicate": {
- "equipment": {
- "chest": {
- "tag": "minecraft:planks"
- }
- }
- }
- }
前言 经过近一个月的开发,我把上一版的部分内容,特别是shift处理的部分进行了优化。虽然照例是有一个视频的,但是我没空剪。就这样吧。 为了让这个帖子凉的更快一点,我决定只放干货。毕竟水的比热容大一点。。。 由于基于我的数据包,因此内部的计分板和tag均带有本数据包标志“CAM”,见谅。 开始。 data/cam/functions/machine/crafting_table/tick:
代码:
- #开头基础处理:物品处理 初始化变量
- kill @e[nbt={Item:{tag:{CAM_bg:1b}}}]
- execute store result score @a CAM_crafterror run clear @a minecraft:firework_star{CAM_bg:1b} 0
- execute as @a store result score @s CAM_bottlecount run clear @a #cam:cam_recipes 0
- #放置与破坏处理
- 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
- 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
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] run data modify entity @s Fire set value 32767s
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/gui
- #功能
- #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
- #配方处理
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/recipe
- #输出标签处理
- execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] at @s run function cam:machine/crafting_table/inventory
- #误放入处理
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/check
- #Shift键处理 初始化tag
- tag @a remove CAM_shiftcheck
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入背景物品返还模块玩家确定的计分板重置
#放置与破坏处理:第1条:检测放置工作台(配合进度(就是视频里的advancement,用于调试的)),
第2条:检测破坏合成台
3:防止盔甲架变黑
#功能同第一版一样由于运用到recipes,shift放到后面讲。#配方处理 data/cam/functions/machine/crafting_table/recipe:
代码:
- #获取已占槽位
- function cam:machine/crafting_table/recipes/count
- #清除合成区物品
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CAM_not_to_clear] run function cam:machine/crafting_table/recipes/clear
- tag @s remove CAM_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_bg:1b}}]} run tag @s add CAM_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
- #配方检测
- function cam:machine/crafting_table/recipes/bamboo_sword
- function cam:machine/crafting_table/recipes/red_string
- function cam:machine/crafting_table/recipes/weedstew
- function cam:machine/crafting_table/recipes/honey_apple
- function cam:machine/crafting_table/recipes/erosion_arrow
- #初始化变量
- scoreboard players reset @s CAM_table_count
- #shift处理相关
- 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:
代码:
- execute if data block ~ ~ ~ Items[{Slot:1b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:2b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:3b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:10b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:11b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:12b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:19b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:20b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:21b}] run scoreboard players add @s CAM_table_count 1
#清除合成区物品:检测输出物品被拿取时,将合成区物品数量-1,
代码:
- #清除合成区物品
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CAM_not_to_clear] run function cam:machine/crafting_table/recipes/clear
- tag @s remove CAM_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_bg:1b}}]} run tag @s add CAM_not_to_clear
- 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:
代码:
- function cam:machine/crafting_table/recipes/clear/1
- function cam:machine/crafting_table/recipes/clear/2
- function cam:machine/crafting_table/recipes/clear/3
- function cam:machine/crafting_table/recipes/clear/10
- function cam:machine/crafting_table/recipes/clear/11
- function cam:machine/crafting_table/recipes/clear/12
- function cam:machine/crafting_table/recipes/clear/19
- function cam:machine/crafting_table/recipes/clear/20
- function cam:machine/crafting_table/recipes/clear/21
这是一个穷举索引,下面展示其中一个:cam/functions/machine/crafting_table/recipes/clear/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
- execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:honey_bottle",Count:1b}]} run replaceitem block ~ ~ ~ container.1 minecraft:glass_bottle 2
- 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>
- execute if data block ~ ~ ~ {Items:[{Slot:1b,id:"minecraft:potion",Count:1b}]} run replaceitem block ~ ~ ~ container.1 minecraft:glass_bottle
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:(其中一个配方)
代码:
- 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}
- 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
#误放入处理 #结尾基础处理
没有变化。复制一下第一版内容:
#误放入处理:
data/cam/functions/machine/crafting_table/check:
代码:
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:0b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/0
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/16
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:4b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:6b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:8b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:13b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/13
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:14b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/14
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:15b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/15
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:17b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/17
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:18b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/18
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:22b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/22
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:23b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/23
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:24b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/24
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:25b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/25
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:26b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/26
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[0]
- 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}}
- execute as @e[sort=nearest,limit=1,scores={CAM_crafterror=1..}] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- execute at @s run setblock ~ 255 ~ air
原理:若在箱子里检测到没有CAM_bg标签(因为在tick里高频清除了玩家和地面的该种物品,所以可以由此判断玩家放入了其他物品),则将其复制到潜影盒里,返还给玩家
以下为大改内容:#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
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:
代码:
- #初始化变量和tag
- scoreboard players set @s CAM_shiftdealt 2
- scoreboard players set @a CAM_player_count 37
- scoreboard players reset @a CAM_item_trigger
- #检测玩家剩余槽位数和当前物品最大可堆叠数量,以及版权(划掉)计分板数据转移
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CAM_shiftcheck] at @s run function cam:machine/crafting_table/shift_player
- scoreboard players operation @s CAM_player_count = @e[tag=CAM_shiftcheck] CAM_player_count
- function cam:machine/crafting_table/shift_data_get
- scoreboard players operation @s CAM_player_count *= @s CAM_item_trigger
- execute store result score @s CAM_shift_muti run clear @a[tag=CAM_shiftcheck] #cam:cam_recipes{CAM_output:1b} 0
- scoreboard players operation @s CAM_shiftdealt *= @s CAM_shift_muti
- #模拟执行合成操作,以确定可执行的最大合成次数
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @e[tag=CAM_shiftcheck] run function cam:machine/crafting_table/shifttest
- execute if data block ~ ~ ~ {Items:[{Slot:16b}]} unless score @s CAM_shiftdealt < @s CAM_player_count run function cam:machine/crafting_table/recipes/clear
- scoreboard players operation @s CAM_shiftdealt /= @s CAM_shift_muti
- #补偿机制相关
- execute as @e[tag=CAM_comp] run scoreboard players remove @s CAM_shiftdealt 1
- #清除输出栏
- replaceitem block ~ ~ ~ container.16 minecraft:air
- #(辅助)给予次数运算
- scoreboard players remove @s CAM_shiftdealt 2
- #计分板数据转移
- scoreboard players operation @e[tag=CAM_shiftcheck] CAM_shiftdealt = @s CAM_shiftdealt
- #给予玩家物品
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CAM_shiftcheck] at @s run function cam:machine/crafting_table/shiftdealt
- #输出栏处理
- 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}
- #初始化
- tag @s remove CAM_comp
其中有一些条件已经不需要了,但是因为我懒,所以没有删除里面所谓的计分板数据转移是因为命令的执行者不同:玩家或合成台(即在合成台位置的盔甲架)而计算时把数据放在一起会省事一点。#检测玩家剩余槽位数:上个版本有一个重大的问题,就是当物品给予数量超过玩家物品栏可容下的最大数量时,仍会尝试将合成台里的原料消耗完,这是我们不想要的。因此在这里通过CAM_player_count计分板数据来获取玩家剩余槽位,以限制模拟合成的执行次数。data/cam/functions/machine/crafting_table/shift_player:
代码:
- execute if data entity @s Inventory[{Slot:0b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:1b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:2b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:3b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:4b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:5b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:6b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:7b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:8b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:9b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:10b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:11b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:12b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:13b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:14b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:15b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:16b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:17b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:18b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:19b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:20b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:21b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:22b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:23b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:24b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:25b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:26b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:27b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:28b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:29b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:30b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:31b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:32b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:33b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:34b}] run scoreboard players remove @s CAM_player_count 1
- execute if data entity @s Inventory[{Slot:35b}] run scoreboard players remove @s CAM_player_count 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
- execute if score @e[tag=CAM_shiftcheck,limit=1] CAM_item_trigger matches 1.. run scoreboard players set @s CAM_item_trigger 64
- execute as @e[tag=CAM_shiftcheck,limit=1] store result score @s CAM_item_trigger run clear @s #cam:16x{CAM_output:1b} 0
- execute if score @e[tag=CAM_shiftcheck,limit=1] CAM_item_trigger matches 1.. run scoreboard players set @s CAM_item_trigger 16
- execute as @e[tag=CAM_shiftcheck,limit=1] store result score @s CAM_item_trigger run clear @s #cam:1x{CAM_output:1b} 0
- 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:
代码:
- scoreboard players operation @s CAM_shiftdealt /= @s CAM_shift_muti
- replaceitem block ~ ~ ~ container.16 minecraft:air
- function cam:machine/crafting_table/recipe
- scoreboard players operation @s CAM_shiftdealt *= @s CAM_shift_muti
#物品给予模块data/cam/functions/machine/crafting_table/shiftdealt:
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{tag:{CAM_output:1b}}].id
- data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{tag:{CAM_output:1b}}].Count
- data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{tag:{CAM_output:1b}}].tag
- execute as @s store result score @s CAM_shiftcount run data get block ~ 255 ~ Items[0].Count
- scoreboard players operation @s CAM_shiftcount *= @s CAM_shiftdealt
- function cam:machine/crafting_table/sub_shiftdealt
- setblock ~ 255 ~ air
代码:
- execute if score @s CAM_shiftcount matches 64.. run data modify block ~ 255 ~ Items[0].Count set value 64
- 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
- execute as @s if score @s CAM_shiftcount matches 1.. run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- scoreboard players remove @s CAM_shiftcount 64
- execute if score @s CAM_shiftcount matches 1.. run function cam:machine/crafting_table/sub_shiftdealt
- execute if score @s CAM_shiftcount matches ..0 run data remove block ~ 255 ~ Items[0]
#输出标签处理:极其辛酸的部分,因为这个东西我卡了十来天。
先讲解吧,
data/cam/functions/machine/crafting_table/inventory:
代码:
- etblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- execute if data entity @s {Inventory:[{Slot:0b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/0
- execute if data entity @s {Inventory:[{Slot:1b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/1
- execute if data entity @s {Inventory:[{Slot:2b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/2
- execute if data entity @s {Inventory:[{Slot:3b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/3
- execute if data entity @s {Inventory:[{Slot:4b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/4
- execute if data entity @s {Inventory:[{Slot:5b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/5
- execute if data entity @s {Inventory:[{Slot:6b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/6
- execute if data entity @s {Inventory:[{Slot:7b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/7
- execute if data entity @s {Inventory:[{Slot:8b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/8
- execute if data entity @s {Inventory:[{Slot:9b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/9
- execute if data entity @s {Inventory:[{Slot:10b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/10
- execute if data entity @s {Inventory:[{Slot:11b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/11
- execute if data entity @s {Inventory:[{Slot:12b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/12
- execute if data entity @s {Inventory:[{Slot:13b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/13
- execute if data entity @s {Inventory:[{Slot:14b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/14
- execute if data entity @s {Inventory:[{Slot:15b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/15
- execute if data entity @s {Inventory:[{Slot:16b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/16
- execute if data entity @s {Inventory:[{Slot:17b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/17
- execute if data entity @s {Inventory:[{Slot:18b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/18
- execute if data entity @s {Inventory:[{Slot:19b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/19
- execute if data entity @s {Inventory:[{Slot:20b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/20
- execute if data entity @s {Inventory:[{Slot:21b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/21
- execute if data entity @s {Inventory:[{Slot:22b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/22
- execute if data entity @s {Inventory:[{Slot:23b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/23
- execute if data entity @s {Inventory:[{Slot:24b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/24
- execute if data entity @s {Inventory:[{Slot:25b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/25
- execute if data entity @s {Inventory:[{Slot:26b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/26
- execute if data entity @s {Inventory:[{Slot:27b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/27
- execute if data entity @s {Inventory:[{Slot:28b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/28
- execute if data entity @s {Inventory:[{Slot:29b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/29
- execute if data entity @s {Inventory:[{Slot:30b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/30
- execute if data entity @s {Inventory:[{Slot:31b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/31
- execute if data entity @s {Inventory:[{Slot:32b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/32
- execute if data entity @s {Inventory:[{Slot:33b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/33
- execute if data entity @s {Inventory:[{Slot:34b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/34
- execute if data entity @s {Inventory:[{Slot:35b,tag:{CAM_output:1b}}]} run function cam:machine/crafting_table/inventory/35
- setblock ~ 255 ~ air
data/cam/functions/machine/crafting_table/inventory/0:
代码:
- data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{Slot:0b}].id
- data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{Slot:0b}].Count
- data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{Slot:0b}].tag
- data remove block ~ 255 ~ Items[0].tag.CAM_output
- loot replace entity @s hotbar.0 1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
代码:
- data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{Slot:9b}].id
- data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{Slot:9b}].Count
- data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{Slot:9b}].tag
- data remove block ~ 255 ~ Items[0].tag.CAM_output
- loot replace entity @s inventory.0 1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
至此,讲解完全完成。
以下为第一版 事情是这样的,在开发我的原版模组时,想做一个合成NBT物品的合成台,于是我就去教程学习了一下有关内容,同时下载了更多的合成数据包
以拆解学习,但是我没能成功的把合成器拆出来,而且发现了几个小问题(有些是真的让人蛋疼。。。) 问题1、秘技:gui消失术!





于是,我决定自己写。 /2000 years later.jpg 经过4天的艰苦卓绝的开发,我成功把这个玩意搞出来了! 下面是展示视频 https://www.bilibili.com/video/av85551813/
问题1 由于该模块较为复杂,我先在这里展示一下tick函数结构: data/cam/functions/machine/crafting_table/tick:
代码:
- #开头基础处理:物品处理 初始化变量
- kill @e[nbt={Item:{tag:{CAM_bg:1b}}}]
- execute store result score @a CAM_crafterror run clear @a minecraft:firework_star{CAM_bg:1b} 0
- #放置与破坏处理
- 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
- 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
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] run data modify entity @s Fire set value 32767s
- #功能
- #Shift键处理
- execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] run tag @s add CAM_shiftcheck
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/shiftcheck
- #配方处理
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/recipe
- #输出标签处理
- execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] at @s run function cam:machine/crafting_table/inventory
- #误放入处理
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/check
- #Shift键处理 初始化tag
- tag @a remove CAM_shiftcheck
- #结尾基础处理:物品处理 初始化变量
- clear @a firework_star{CAM_bg:1b}
- scoreboard players reset @e CAM_shiftdealt
我在教程里发现了这么一段:

然而,数据包里好像并没有应用到。。。 于是我就设计了这个check函数: data/cam/functions/machine/crafting_table/check:
代码:
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:0b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/0
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/16
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:4b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:6b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:8b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/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
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:13b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/13
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:14b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/14
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:15b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/15
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:17b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/17
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:18b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/18
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:22b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/22
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:23b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/23
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:24b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/24
- execute as @s at @s unless data block ~ ~ ~ {Items:[{Slot:25b,tag:{CAM_bg:1b}}]} positioned ~ ~ ~ run function cam:machine/crafting_table/replace/25
- 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:
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- data modify block ~ 255 ~ Items[0] set from block ~ ~ ~ Items[0]
- 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}}
- execute as @e[sort=nearest,limit=1,scores={CAM_crafterror=1..}] run loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- execute at @s run setblock ~ 255 ~ air
原理:若在箱子里检测到没有CAM_bg标签(因为在tick里高频清除了玩家和地面的该种物品,所以可以由此判断玩家放入了其他物品),则将其复制到潜影盒里,返还给玩家
至此,解决。
问题2
这个就简单了。
如果通过战利品表来实现,还是有难度的,但是我们可以用
既然创造模式打掉方块不掉方块本体,而生存模式会掉,那我们为什么不利用这一特性呢?
这就是这里的思路了。
data/cam/functions/machine/crafting_table/clear:
代码:
- <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:
代码:
- #开头基础处理:物品处理 初始化变量
- kill @e[nbt={Item:{tag:{CAM_bg:1b}}}]
- execute store result score @a CAM_crafterror run clear @a minecraft:firework_star{CAM_bg:1b} 0
- #放置与破坏处理
- 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
- 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
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] run data modify entity @s Fire set value 32767s
- #功能
- #Shift键处理
- execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] run tag @s add CAM_shiftcheck
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/shiftcheck
- #配方处理
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/recipe
- #输出标签处理
- execute as @a[nbt={Inventory:[{tag:{CAM_output:1b}}]}] at @s run function cam:machine/crafting_table/inventory
- #误放入处理
- execute as @e[type=minecraft:armor_stand,tag=cam_crafting,tag=CAM_craft_enable] at @s run function cam:machine/crafting_table/check
- #Shift键处理 初始化tag
- tag @a remove CAM_shiftcheck
- #结尾基础处理:物品处理 初始化变量
- clear @a firework_star{CAM_bg:1b}
- scoreboard players reset @e CAM_shiftdealt
#开头基础处理:物品处理 初始化变量:清除带有CAM_bg标签的物品,将有关误放入背景物品返还模块玩家确定的计分板重置
#放置与破坏处理:第1条:检测放置工作台(配合进度(就是视频里的advancement,用于调试的)),
第2条:检测破坏合成台
3:防止盔甲架变黑
#功能:
#Shift键处理:本人最自豪的部分之一,由于涉及到下方函数,原理先放一下。
#配方处理:
先亮代码:
data/cam/functions/machine/crafting_table/recipe:
代码:
- function cam:machine/crafting_table/recipes/count
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @s[tag=!CAM_not_to_clear] run function cam:machine/crafting_table/recipes/clear
- tag @s remove CAM_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_bg:1b}}]} run tag @s add CAM_not_to_clear
- execute if data block ~ ~ ~ {Items:[{Slot:16b,tag:{CAM_output:1b}}]} run replaceitem block ~ ~ ~ container.16 minecraft:air
- function cam:machine/crafting_table/recipes/bamboo_sword
- function cam:machine/crafting_table/recipes/red_string
- scoreboard players reset @s CAM_table_count
- 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:
代码:
- execute if data block ~ ~ ~ Items[{Slot:1b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:2b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:3b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:10b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:11b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:12b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:19b}] run scoreboard players add @s CAM_table_count 1
- execute if data block ~ ~ ~ Items[{Slot:20b}] run scoreboard players add @s CAM_table_count 1
- 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:(其中一个配方)
代码:
- 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}
- 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}
代码:
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:1b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:1b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:2b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:2b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:3b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:3b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:10b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:10b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:11b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:11b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:12b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:12b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:19b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:19b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:20b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:20b}].Count byte 1 run scoreboard players get @s CAM_clear
- execute as @s store result score @s CAM_clear run data get block ~ ~ ~ Items[{Slot:21b}].Count
- scoreboard players remove @s CAM_clear 1
- execute store result block ~ ~ ~ Items[{Slot:21b}].Count byte 1 run scoreboard players get @s CAM_clear
- #(命令重复9遍)
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:
代码:
- scoreboard players set @s CAM_shiftdealt 1
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} if entity @e[tag=CAM_shiftcheck] run function cam:machine/crafting_table/shifttest
- scoreboard players operation @e[tag=CAM_shiftcheck] CAM_shiftdealt = @s CAM_shiftdealt
- execute unless data block ~ ~ ~ {Items:[{Slot:16b}]} as @e[tag=CAM_shiftcheck] at @s run function cam:machine/crafting_table/shiftdealt
代码:
- replaceitem block ~ ~ ~ container.16 minecraft:air
- function cam:machine/crafting_table/recipe
- execute if data block ~ ~ ~ {Items:[{Slot:16b}]} run function cam:machine/crafting_table/shifttest
代码:
- setblock ~ 255 ~ shulker_box{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}]}
- data modify block ~ 255 ~ Items[0].id set from entity @s Inventory[{tag:{CAM_output:1b}}].id
- data modify block ~ 255 ~ Items[0].Count set from entity @s Inventory[{tag:{CAM_output:1b}}].Count
- data modify block ~ 255 ~ Items[0].tag set from entity @s Inventory[{tag:{CAM_output:1b}}].tag
- data remove block ~ 255 ~ Items[0].tag.CAM_output
- execute as @s store result score @s CAM_shiftcount run data get block ~ 255 ~ Items[0].Count
- scoreboard players operation @s CAM_shiftcount *= @s CAM_shiftdealt
- execute if score @s CAM_shiftcount matches 65.. run function cam:machine/crafting_table/sub_shiftdealt
- execute as @s store result block ~ 255 ~ Items[0].Count byte 1 run scoreboard players get @s CAM_shiftcount
- loot give @s mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- setblock ~ 255 ~ air
代码:
- loot replace block ~ 255 ~ container.1 mine ~ 255 ~ minecraft:diamond_pickaxe{isShulkerMarker:1b}
- data modify block ~ 255 ~ Items[-1].Count set value 64
- scoreboard players remove @s CAM_shiftcount 64
- execute if score @s CAM_shiftcount matches 65.. run function cam:machine/crafting_table/sub_shiftdealt
版主大大@SPGoding 是这么回复的:

原理:首先,对物品栏内有带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合成问题的解答
本帖最后由 chaoren019 于 2020-2-25 17:20 编辑
有疑问或改进建议可在评论区提出
有疑问或改进建议可在评论区提出
本帖最后由 chaoren019 于 2020-1-31 20:38 编辑
这个东西的已知缺点:
1、右键侦测没做。。。现在会出现错误
2、因为使用了输出标签,所以一开始合成出来的东西不可堆叠,所以背包内至少要留一个空位(那我可以删除回复吗)
这个东西的已知缺点:
1、右键侦测没做。。。现在会出现错误
2、因为使用了输出标签,所以一开始合成出来的东西不可堆叠,所以背包内至少要留一个空位
gui的处理我在1.10版本已经做了,不过还没发布,检测gui发生改变我是用断言来检测的,教程里可能漏写了。
本帖最后由 chaoren019 于 2020-2-25 17:21 编辑
话说1.10什么时候发布?期待一下(又可以抄代码了(误))
(为什么我这边断言就不管用呢。。。)
ruhuasiyu 发表于 2020-1-30 10:06
gui的处理我在1.10版本已经做了,不过还没发布,检测gui发生改变我是用断言来检测的,教程里可能漏写了。 ...
话说1.10什么时候发布?期待一下
(为什么我这边断言就不管用呢。。。)
楼主自己造轮子ing……
6666666666666666666666666
啊!!我想要单品.能给我一份吗