前言
解压怀旧一下mc,打造一个全自动化世界。期间,做了很多自动化逻辑流程设计、查修一些bug反馈到github修正,手工开发一些function补充功能,自编译mod提前修已知问题等,基本没有娱乐,主要在研究和创造,过程不亚于工作中的开发。
结果很不错,这里分享一些难点解决。
一、问题背景
mc 全自动化实现,电孤炉不能更换石墨电极,批量生产更换频率不低,有待解决。
环境:mc1.16.3,forge,沉浸工程 植物魔法 精致存储等
解决之后,积压的数万矿石不到1天就消化了,效率不错。
二、方案
最简单的办法是基于别人的mod开发一个mod,新版开发环境还得构造,没时间,网也q了。这里分享一个基于官方机制,添加一个数据包(datapack)来解决。
三、datapack使用介绍
略,见https://minecraft-zh.gamepedia.com/%E6%95%B0%E6%8D%AE%E5%8C%85,假设你已经了解如何添加1个数据包并生效一个函数。
四、先上效果
使用布局如图,另一张是供物料特写
五、实现原理
- 核心:在电孤炉电极外观上放置一个命令方块执行新增加的函数ie_auto_electrode。代码写死了下向5格就是电孤炉的中心。
- 外围:放置一个定时器定时触发红石信号驱动。这里用了植物魔法的沙漏,也可以用原版红石中继器实现。
- 外围:附件放置一个自动放置石墨电极物品的装置,基本原理很简单,抛下一个物品,触发压力板,再反向控制不再放置物品。这里上面用于了植物魔法花格箱以解决准度,原版投掷器也可以。
核心逻辑:
1、创建2个积分板用于存储中间数据和状态。
2、环境检测,确保下方是电孤炉,附件有满耐久的石墨电极。
3、检测电弧炉23-25号slot nbt数据,检测是否有电极缺失或损坏值大于95550(96000最大)。
4、如有,进行更换或恢复耐久,清除1个满耐久电极。
5、执行1次替换就设置了结束状态。全部替换需要反复执行完成。
六、代码
细节暂不解释,有用直接复制走即可,有兴趣可以交流。
ie_auto_electrode.mcfunction
# init
scoreboard objectives add cmd_result dummy
scoreboard objectives add cmd_succ dummy
execute if block ~ ~1 ~ minecraft:air run kill @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}}]
execute if block ~ ~1 ~ minecraft:air run summon minecraft:item ~ ~1 ~ {Item:{id:"minecraft:torch",Count:1}}
execute if block ~ ~1 ~ minecraft:air run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ 0
# check
execute unless block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0}} run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ 2
execute unless entity @e[type=item,distance=..3,nbt={Item:{id:"immersiveengineering:graphite_electrode",Count:1b}}] run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ 2
execute as @e[type=item,distance=..3,nbt={Item:{id:"immersiveengineering:graphite_electrode",Count:1b}},limit=1] if data entity @s Item.tag.graphDmg unless data entity @s Item.tag{graphDmg:0} run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ 2
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 run data modify entity @e[type=item,distance=..3,nbt={Item:{id:"immersiveengineering:graphite_electrode",Count:1b}},limit=1] Age set value 0
#execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 run say init
#execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 2 run say uninit
# add 23
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 unless block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:23b}]} store success score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ run data modify block ~ ~-4 ~ inventory append value {Slot:23b,id:"immersiveengineering:graphite_electrode",Count:1b,Count:1b,tag:{graphDmg:0,Damage:0}}
# add 24
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 unless block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:24b}]} store success score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ run data modify block ~ ~-4 ~ inventory append value {Slot:24b,id:"immersiveengineering:graphite_electrode",Count:1b,Count:1b,tag:{graphDmg:0,Damage:0}}
# add 25
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 unless block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:25b}]} store success score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ run data modify block ~ ~-4 ~ inventory append value {Slot:25b,id:"immersiveengineering:graphite_electrode",Count:1b,Count:1b,tag:{graphDmg:0,Damage:0}}
# fix 23
# init dmg
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result 0
# get current dmg
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 if block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:23b}]} store result score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result run data get block ~ ~-4 ~ inventory[{Slot:23b}].tag.graphDmg
# modify
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 if block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:23b}]} if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result matches 95550.. store success score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ run data modify block ~ ~-4 ~ inventory[{Slot:23b}].tag.graphDmg set value 0
# end
# fix 24
# init dmg
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result 0
# get current dmg
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 if block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:24b}]} store result score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result run data get block ~ ~-4 ~ inventory[{Slot:24b}].tag.graphDmg
# modify
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 if block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:24b}]} if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result matches 95550.. store success score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ run data modify block ~ ~-4 ~ inventory[{Slot:24b}].tag.graphDmg set value 0
# end
# fix 25
# init dmg
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 run scoreboard players set @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result 0
# get current dmg
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 if block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:25b}]} store result score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result run data get block ~ ~-4 ~ inventory[{Slot:25b}].tag.graphDmg
# modify
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 if block ~ ~-4 ~ immersiveengineering:arc_furnace{offset:{X:0,Y:0,Z:0},inventory:[{Slot:25b}]} if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_result matches 95550.. store success score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ run data modify block ~ ~-4 ~ inventory[{Slot:25b}].tag.graphDmg set value 0
# end
# use one
execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 1 run kill @e[type=item,distance=..3,nbt={Item:{id:"immersiveengineering:graphite_electrode",Count:1b}},limit=1]
# clear
#execute if score @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}},limit=1] cmd_succ matches 0 run say "undo"
execute if block ~ ~1 ~ minecraft:air run kill @e[type=item,distance=..1,nbt={Item:{id:"minecraft:torch",Count:1b}}]