ruhuasiyu
本帖最后由 ruhuasiyu 于 2020-3-16 11:06 编辑

之前,我们可以通过添加相应配方,然后检测物品将要烧炼完毕时来替换产物并清理待烧炼物。这种做法的局限性一是若要求待烧炼物含指定NBT,则必须添加该物品的的烧炼配方,这就导致即使没有相应的NBT也会烧炼,个人建议为原物品也添加合理的烧炼配方,或者烧炼配方的产物和待烧炼物相同,同时不奖励经验值;二是即使产物应当可堆叠也无法正常堆叠,这时需配合漏斗等设备传输方可持续烧炼。
情形添加配方注意事项
原版物品A->NBT物品BA->B在烧炼即将完成时生成产物。
NBT物品A->原版物品BA->B同上一条。对于原版物品A,还需要清理产物或添加其它合适的烧炼效果。
A->C同上一条。产物无法堆叠,需配合漏斗等设备传输方可持续烧炼。
NBT物品A->NBT物品BA->B同上上条。若有其它烧炼配方可以得到原版物品B,则进行相应配方烧炼时的产物会直接变为NBT物品B,因此要排除这种情形。
A->C同前两条。

然后 @chaoren019 提醒我应该可以通过“检测待烧炼槽位为指定nbt时,用计分板储存烧炼刻数和燃料剩余时间,模拟烧炼过程,而跳过添加配方”,我便试着做了一下。

检测燃料的燃烧值需要生成一个放置有铁矿石的熔炉,然后等待1tick获取其BurnTime。我们将熔炉原有物品信息记录在盔甲架主手上,只是在计算时会导致熔炉内物品闪烁一下。此外该方法在更换不同燃烧值物品时,燃烧火焰条会有所变化,这和通常烧炼配方有差异。

首先在放置熔炉时为标记的盔甲架添加手持物来记录燃料的变化。
cpp:tick
execute as @e[type=armor_stand,tag=cpp_furnace] at @s run function cpp:furnace/check

cpp:furnace/tick
execute unless block ~ ~ ~ furnace run kill @s
execute as @s[tag=cpp_check_fuel] run function cpp:furnace/fuel_get
execute unless predicate cpp:furnace/outfull if predicate cpp:furnace/furnace run function cpp:furnace/type

cpp:furnace/type
# 燃料改变
execute as @s[tag=cpp_check_fuel] run function cpp:furnace/fuel_get
execute if data block ~ ~ ~ Items[{Slot:1b}] run function cpp:furnace/fuel_change_check
# 消耗燃料
execute as @s[tag=!cpp_check_fuel] if block ~ ~ ~ furnace{BurnTime:0s,Items:[{Slot:1b}]} run function cpp:furnace/fuel_use
# 进度 高炉、烟熏炉每次加2
execute unless block ~ ~ ~ furnace{BurnTime:0s} store result block ~ ~ ~ CookTime short 1 run scoreboard players add @s cppTick 1
execute if score @s cppTick matches 200.. run function cpp:furnace/done
# 停止
execute if block ~ ~ ~ furnace{BurnTime:0s} run scoreboard players reset @s cppTick
# 发光
execute as @e[type=armor_stand,tag=cpp_furnace] at @s if block ~ ~ ~ furnace[lit=false] unless block ~ ~ ~ furnace{BurnTime:0s} run function cpp:furnace/lit_true
execute as @e[type=armor_stand,tag=cpp_furnace] at @s if block ~ ~ ~ furnace[lit=true]{BurnTime:0s} run function cpp:furnace/lit_false

当检测到燃料改变时,重新计算燃烧值。
cpp:furnace/fuel_get
tag @s remove cpp_check_fuel
execute store result score @s cppValue run data get block ~ ~ ~ BurnTime
replaceitem block ~ ~ ~ container.0 air
data modify block ~ ~ ~ {} merge from entity @s HandItems[0].tag.storage

cpp:furnace/fuel_change_check
execute store result score #change cppValue run data modify entity @s HandItems[0].tag.id set from block ~ ~ ~ Items[{Slot:1b}].id
execute if score #change cppValue matches 1 run function cpp:furnace/fuel_change

cpp:furnace/fuel_change
data modify entity @s HandItems[0].tag.storage set from block ~ ~ ~
replaceitem block ~ ~ ~ container.0 iron_ore
replaceitem block ~ ~ ~ container.2 air
tag @s add cpp_check_fuel

cpp:furnace/fuel_use
execute store result block ~ ~ ~ BurnTime short 1 run scoreboard players get @s cppValue
execute store result block ~ ~ ~ Items[{Slot:1b}].Count byte 1 run data get block ~ ~ ~ Items[{Slot:1b}].Count 0.9999

烧炼完毕时,通过战利品表生成产物,注意不能直接 loot replace 进熔炉的输出槽。烧炼完成时添加获取经验的配方记录,这里我们统一设定为每次0.15点,可以根据需要实现不同配方不同经验值。
cpp:furnace/done
execute if data block ~ ~ ~ Items[{Slot:2b}] store result block ~ ~ ~ Items[{Slot:2b}].Count byte -1 run data get block ~ ~ ~ Items[{Slot:2b}].Count -1.0001
execute unless data block ~ ~ ~ Items[{Slot:2b}] run function cpp:furnace/done_loot
execute store result block ~ ~ ~ Items[{Slot:0b}].Count byte 1 run data get block ~ ~ ~ Items[{Slot:0b}].Count 0.9999
scoreboard players reset @s cppTick
data modify block ~ ~ ~ CookTime set value 0s
execute store result score #t cppValue run data get block ~ ~ ~ RecipesUsed."minecraft:charcoal"
execute store result block ~ ~ ~ RecipesUsed."minecraft:charcoal" int 1 run scoreboard players add #t cppValue 1

cpp:furnace/done_loot
clone ~ ~ ~ ~ ~ ~ ~ 255 ~
loot replace block ~ 255 ~ container.0 loot cpp:furnace/furnace
data modify block ~ 255 ~ Items[{Slot:0b}].Slot set value 2b
data modify block ~ ~ ~ Items append from block ~ 255 ~ Items[{Slot:2b}]
setblock ~ 255 ~ air

修改熔炉的火焰外观。
cpp:furnace/lit_true
data modify storage cpp:furnace {} merge from block ~ ~ ~ {}
execute if block ~ ~ ~ furnace[facing=east] run setblock ~ ~ ~ furnace[lit=true,facing=east]
execute if block ~ ~ ~ furnace[facing=west] run setblock ~ ~ ~ furnace[lit=true,facing=west]
execute if block ~ ~ ~ furnace[facing=south] run setblock ~ ~ ~ furnace[lit=true,facing=south]
execute if block ~ ~ ~ furnace[facing=north] run setblock ~ ~ ~ furnace[lit=true,facing=north]
data modify block ~ ~ ~ {} merge from storage cpp:furnace {}

cpp:furnace/lit_false
data modify storage cpp:furnace {} merge from block ~ ~ ~ {}
execute if block ~ ~ ~ furnace[facing=east] run setblock ~ 255 ~ furnace[lit=false,facing=east]
execute if block ~ ~ ~ furnace[facing=west] run setblock ~ 255 ~ furnace[lit=false,facing=west]
execute if block ~ ~ ~ furnace[facing=south] run setblock ~ 255 ~ furnace[lit=false,facing=south]
execute if block ~ ~ ~ furnace[facing=north] run setblock ~ 255 ~ furnace[lit=false,facing=north]
data modify block ~ ~ ~ {} merge from storage cpp:furnace {}

使用断言和战利品表来记录配方。这里断言需要分输出栏空和输出栏为相应产物两种情形。
cpp/loot_tables/furnace/outfull.json
{
        "condition": "minecraft:location_check",
        "predicate": {
                "block": {
                        "nbt": "{Items:[{Slot:2b,Count:64b}]}"
                }
        }

cpp/loot_tables/furnace/furnace.json
{
        "pools": [
                {
                        "rolls": 1,
                        "entries": [
                                {
                                        "type": "minecraft:alternatives",
                                        "children": [
                                                {
                                                        "conditions": [
                                                                {
                                                                        "condition": "minecraft:location_check",
                                                                        "predicate": {
                                                                                "block": {
                                                                                        "nbt": "{Items:[{Slot:0b,tag:{id:'cpp:bear_meat'}}]}"
                                                                                 }
                                                                         }
                                                                 }
                                                         ],
                                                         "type": "minecraft:loot_table",
                                                         "name": "cpp:cooked_bear_meat"
                                                }
                                        ]
                                }
                        ]
                }
        ]
}

cpp/predicates/furnace/furnace1.json
{
        "condition": "minecraft:alternative",
        "terms": [
                {
                        "condition": "minecraft:location_check",
                        "predicate": {
                                "block": {
                                        "nbt": "{Items:[{Slot:0b,tag:{id:'cpp:bear_meat'}}]}"
                                }
                        }
                }
        ]
}

cpp/predicates/furnace/furnace.json
{
        "condition": "minecraft:alternative",
        "terms": [
                {
                        "condition": "minecraft:inverted",
                        "term": {
                                "condition": "minecraft:alternative",
                                "terms": [
                                        {
                                                "condition": "minecraft:inverted",
                                                "term": {
                                                        "condition": "minecraft:reference",
                                                        "name": "cpp:furnace/furnace1"
                                                }
                                        },
                                        {
                                                "condition": "minecraft:location_check",
                                                "predicate": {
                                                        "block": {
                                                                "nbt": "{Items:[{Slot:2b}]}"
                                                        }
                                                }
                                        }
                                ]
                        }
                },
                {
                        "condition": "minecraft:location_check",
                        "predicate": {
                                "block": {
                                        "nbt": "{Items:[{Slot:0b,tag:{id:'cpp:bear_meat'}},{Slot:2b,tag:{id:'cpp:cooked_bear_meat'}}]}"
                                }
                        }
                }
        ]
}



来自群组: The Command's Power
2021.12 数据,可能有更多内容之前,我们可以通过添加相应配方,然后检测物品将要烧炼完毕时来替换产物并清理待烧炼物。这种做法的局限性一是若要求待烧炼物含指定NBT,则必须添加该物品的的烧炼配方,这就导致即使没有相应的NBT也会烧炼,个人建议为原物品也添加合理的烧炼配方,或者烧炼配方的产物和待烧炼物相同,同时不奖励经验值;二是即使产物应当可堆叠也无法正常堆叠,这时需配合漏斗等设备传输方可持续烧炼。
情形
添加配方
注意事项
原版物品A->NBT物品B
A->B
在烧炼即将完成时生成产物。
NBT物品A->原版物品B
A->B
同上一条。对于原版物品A,还需要清理产物或添加其它合适的烧炼效果。
A->C
同上一条。产物无法堆叠,需配合漏斗等设备传输方可持续烧炼。
NBT物品A->NBT物品B
A->B
同上上条。若有其它烧炼配方可以得到原版物品B,则进行相应配方烧炼时的产物会直接变为NBT物品B,因此要排除这种情形。
A->C
同前两条。

然后 @chaoren019 提醒我应该可以通过“检测待烧炼槽位为指定nbt时,用计分板储存烧炼刻数和燃料剩余时间,模拟烧炼过程,而跳过添加配方”,我便试着做了一下。


检测燃料的燃烧值需要生成一个放置有铁矿石的熔炉,然后等待1tick获取其BurnTime。我们将熔炉原有物品信息记录在盔甲架主手上,只是在计算时会导致熔炉内物品闪烁一下。此外该方法在更换不同燃烧值物品时,燃烧火焰条会有所变化,这和通常烧炼配方有差异。


首先在放置熔炉时为标记的盔甲架添加手持物来记录燃料的变化。
cpp:tick
execute as @e[type=armor_stand,tag=cpp_furnace] at @s run function cpp:furnace/check

cpp:furnace/tick
execute unless block ~ ~ ~ furnace run kill @s
execute as @s[tag=cpp_check_fuel] run function cpp:furnace/fuel_get
execute unless predicate cpp:furnace/outfull if predicate cpp:furnace/furnace run function cpp:furnace/type

cpp:furnace/type
# 燃料改变
execute as @s[tag=cpp_check_fuel] run function cpp:furnace/fuel_get
execute if data block ~ ~ ~ Items[{Slot:1b}] run function cpp:furnace/fuel_change_check
# 消耗燃料
execute as @s[tag=!cpp_check_fuel] if block ~ ~ ~ furnace{BurnTime:0s,Items:[{Slot:1b}]} run function cpp:furnace/fuel_use
# 进度 高炉、烟熏炉每次加2
execute unless block ~ ~ ~ furnace{BurnTime:0s} store result block ~ ~ ~ CookTime short 1 run scoreboard players add @s cppTick 1
execute if score @s cppTick matches 200.. run function cpp:furnace/done
# 停止
execute if block ~ ~ ~ furnace{BurnTime:0s} run scoreboard players reset @s cppTick
# 发光
execute as @e[type=armor_stand,tag=cpp_furnace] at @s if block ~ ~ ~ furnace[lit=false] unless block ~ ~ ~ furnace{BurnTime:0s} run function cpp:furnace/lit_true
execute as @e[type=armor_stand,tag=cpp_furnace] at @s if block ~ ~ ~ furnace[lit=true]{BurnTime:0s} run function cpp:furnace/lit_false

当检测到燃料改变时,重新计算燃烧值。
cpp:furnace/fuel_get
tag @s remove cpp_check_fuel
execute store result score @s cppValue run data get block ~ ~ ~ BurnTime
replaceitem block ~ ~ ~ container.0 air
data modify block ~ ~ ~ {} merge from entity @s HandItems[0].tag.storage

cpp:furnace/fuel_change_check
execute store result score #change cppValue run data modify entity @s HandItems[0].tag.id set from block ~ ~ ~ Items[{Slot:1b}].id
execute if score #change cppValue matches 1 run function cpp:furnace/fuel_change

cpp:furnace/fuel_change
data modify entity @s HandItems[0].tag.storage set from block ~ ~ ~
replaceitem block ~ ~ ~ container.0 iron_ore
replaceitem block ~ ~ ~ container.2 air
tag @s add cpp_check_fuel

cpp:furnace/fuel_use
execute store result block ~ ~ ~ BurnTime short 1 run scoreboard players get @s cppValue
execute store result block ~ ~ ~ Items[{Slot:1b}].Count byte 1 run data get block ~ ~ ~ Items[{Slot:1b}].Count 0.9999

烧炼完毕时,通过战利品表生成产物,注意不能直接 loot replace 进熔炉的输出槽。烧炼完成时添加获取经验的配方记录,这里我们统一设定为每次0.15点,可以根据需要实现不同配方不同经验值。
cpp:furnace/done
execute if data block ~ ~ ~ Items[{Slot:2b}] store result block ~ ~ ~ Items[{Slot:2b}].Count byte -1 run data get block ~ ~ ~ Items[{Slot:2b}].Count -1.0001
execute unless data block ~ ~ ~ Items[{Slot:2b}] run function cpp:furnace/done_loot
execute store result block ~ ~ ~ Items[{Slot:0b}].Count byte 1 run data get block ~ ~ ~ Items[{Slot:0b}].Count 0.9999
scoreboard players reset @s cppTick
data modify block ~ ~ ~ CookTime set value 0s
execute store result score #t cppValue run data get block ~ ~ ~ RecipesUsed."minecraft:charcoal"
execute store result block ~ ~ ~ RecipesUsed."minecraft:charcoal" int 1 run scoreboard players add #t cppValue 1

cpp:furnace/done_loot
clone ~ ~ ~ ~ ~ ~ ~ 255 ~
loot replace block ~ 255 ~ container.0 loot cpp:furnace/furnace
data modify block ~ 255 ~ Items[{Slot:0b}].Slot set value 2b
data modify block ~ ~ ~ Items append from block ~ 255 ~ Items[{Slot:2b}]
setblock ~ 255 ~ air

修改熔炉的火焰外观。
cpp:furnace/lit_true
data modify storage cpp:furnace {} merge from block ~ ~ ~ {}
execute if block ~ ~ ~ furnace[facing=east] run setblock ~ ~ ~ furnace[lit=true,facing=east]
execute if block ~ ~ ~ furnace[facing=west] run setblock ~ ~ ~ furnace[lit=true,facing=west]
execute if block ~ ~ ~ furnace[facing=south] run setblock ~ ~ ~ furnace[lit=true,facing=south]
execute if block ~ ~ ~ furnace[facing=north] run setblock ~ ~ ~ furnace[lit=true,facing=north]
data modify block ~ ~ ~ {} merge from storage cpp:furnace {}

cpp:furnace/lit_false
data modify storage cpp:furnace {} merge from block ~ ~ ~ {}
execute if block ~ ~ ~ furnace[facing=east] run setblock ~ 255 ~ furnace[lit=false,facing=east]
execute if block ~ ~ ~ furnace[facing=west] run setblock ~ 255 ~ furnace[lit=false,facing=west]
execute if block ~ ~ ~ furnace[facing=south] run setblock ~ 255 ~ furnace[lit=false,facing=south]
execute if block ~ ~ ~ furnace[facing=north] run setblock ~ 255 ~ furnace[lit=false,facing=north]
data modify block ~ ~ ~ {} merge from storage cpp:furnace {}

使用断言和战利品表来记录配方。这里断言需要分输出栏空和输出栏为相应产物两种情形。
cpp/loot_tables/furnace/outfull.json
{
  "condition": "minecraft:location_check",
  "predicate": {
    "block": {
   "nbt": "{Items:[{Slot:2b,Count:64b}]}"
    }
  }

cpp/loot_tables/furnace/furnace.json
{
  "pools": [
    {
   "rolls": 1,
   "entries": [
  {
    "type": "minecraft:alternatives",
    "children": [
   {
  "conditions": [
    {
   "condition": "minecraft:location_check",
   "predicate": {
  "block": {
    "nbt": "{Items:[{Slot:0b,tag:{id:'cpp:bear_meat'}}]}"
   }
    }
  }
   ],
   "type": "minecraft:loot_table",
   "name": "cpp:cooked_bear_meat"
   }
    ]
  }
   ]
    }
  ]
}

cpp/predicates/furnace/furnace1.json
{
  "condition": "minecraft:alternative",
  "terms": [
    {
   "condition": "minecraft:location_check",
   "predicate": {
  "block": {
    "nbt": "{Items:[{Slot:0b,tag:{id:'cpp:bear_meat'}}]}"
  }
   }
    }
  ]
}

cpp/predicates/furnace/furnace.json
{
  "condition": "minecraft:alternative",
  "terms": [
    {
   "condition": "minecraft:inverted",
   "term": {
  "condition": "minecraft:alternative",
  "terms": [
    {
   "condition": "minecraft:inverted",
   "term": {
  "condition": "minecraft:reference",
  "name": "cpp:furnace/furnace1"
   }
    },
    {
   "condition": "minecraft:location_check",
   "predicate": {
  "block": {
    "nbt": "{Items:[{Slot:2b}]}"
  }
   }
    }
  ]
   }
    },
    {
   "condition": "minecraft:location_check",
   "predicate": {
  "block": {
    "nbt": "{Items:[{Slot:0b,tag:{id:'cpp:bear_meat'}},{Slot:2b,tag:{id:'cpp:cooked_bear_meat'}}]}"
  }
   }
    }
  ]
}





Jokey_钥匙
对不起 不想动脑子了
但是输出槽满64会出错吗?

Ph-苯
(小白发言)
放置方块很卡?是指在255放置方块会导致亮度变化吗?放基岩层如何?
我通常在远处强加载一个区块用来放方块,所有我开发的模组都使用同一个区块。

聖夢韜
厉害厉害啊

ruhuasiyu
七刀月复 发表于 2020-3-6 22:56
(小白发言)
放置方块很卡?是指在255放置方块会导致亮度变化吗?放基岩层如何?
我通常在远处强加载一个 ...

放置的时候会卡一下

CR_019
由于没有实测,只能在这里理论推理一下(顺便占个楼):
1、类比于潜影盒戏法,为什么放置熔炉会卡,放潜影盒不卡?
2、如果不在高处放置熔炉,直接将熔炉输入、输出、烧炼进度用数据暂存起来,直接在原熔炉上搞个铁矿石(为避免视觉上有差错,可设置空白材质),然后将上述数据存回去,是否可以避免问题?

ruhuasiyu
chaoren019 发表于 2020-3-7 18:56
由于没有实测,只能在这里理论推理一下(顺便占个楼):
1、类比于潜影盒戏法,为什么放置熔炉会卡,放潜影 ...

1 因为潜影盒是即用即毁,而熔炉会存在1tick

2 我试试吧

ruhuasiyu
七刀月复 发表于 2020-3-6 22:56
(小白发言)
放置方块很卡?是指在255放置方块会导致亮度变化吗?放基岩层如何?
我通常在远处强加载一个 ...

放置方块就是会卡,除非方块在1tick内就处理完了销毁了

沈念6
dddddddddddddddddddddddddd

Ph-苯
ruhuasiyu 发表于 2020-3-8 09:59
放置方块就是会卡,除非方块在1tick内就处理完了销毁了

那可以专门使用一个特殊位置的方块吗?不需要每次检测都放置,只要在模组加载时放置就行。

非酋longes
虽然看不懂但是666666就完事了

dv123321
感觉用处不是恒大  主要是卡服就是最大的弊病 如果整改搭配其他插件 应该能有更大的发挥作用

ruhuasiyu
dv123321 发表于 2020-3-8 17:59
感觉用处不是恒大  主要是卡服就是最大的弊病 如果整改搭配其他插件 应该能有更大的发挥作用 ...

命令并不多,并不卡

ZYXZH
6666666666

基哥Grumm
也就是说
能够自定义熔炉的烧炼配方以及产物吗
例如把腐肉丢进去烧成泥土也可以实现吗

ruhuasiyu
隐退 发表于 2020-3-17 11:25
u1s1,我觉得之前的方法挺好的,连接口都不用
我觉得这个问题应该可以修,直接用 scoreboard 和 e ...

你说的我都考虑过,熔炉有一个特性,如果a烧成b,那么无论输出栏的b有什么nbt都会烧a然后输出栏数量直接+1

zzl2010
谢谢            

qiuyang0191
我只能说666来表示对大佬的敬佩之情

知雨晓雨
喜欢喜欢we全文