『KubeJS新手教程?』用工作臺(tái)來附魔吧,把鐵砧放一邊 | 我的世界 Minecraft 魔改
在寫工作臺(tái)配方時(shí),你是否想過要實(shí)現(xiàn)些特殊的效果呢

Transform Ingredients
在有序/無序配方中,我們可以用一些函數(shù)來實(shí)現(xiàn)“材料”的轉(zhuǎn)換,以達(dá)到我們的需求:
.damageIngredient(IngredientFilter filter, int damage?) // 在你合成時(shí),損耗/增加物品的耐久度
.replaceIngredient(IngredientFilter filter, ItemStackJS item) // 將物品替換為其他的物品 (例如水桶合成后變?yōu)橥?
.keepIngredient(IngredientFilter filter) // 將物品保留在合成格中
.customIngredientAction(IngredientFilter filter, String customId) // 運(yùn)行你的自定義腳本,記得先注冊哦
IngredientFilter 材料過濾器可以是
- 物品 ItemStackJS ('minecraft:dirt', Item.of('minecraft:diamond_sword').ignoreNBT(), 等)
- 物品在合成格的位置/索引?(0, 1, 等)
- 物品和/或索引?( {item: 'something', index: 0}, 等)?
不同的函數(shù)對應(yīng)不同的使用場景
而我們這次需要用到的,就是 `customIngredientAction`?自定義的材料變化函數(shù)

Register Custom Ingredient Action
使用 `Ingredinet` 下的方法 `registerCustomIngredientAction` 來注冊我們的自定義函數(shù)
Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {})
其中 `itemstack` 代表指定的物品,`index` 代表合成格的索引,`inventory` 代表合成格包含的所有物品
我們可以通過 `NBT` 來修改物品的附魔,這里有兩種方案
一種方案:簡單的添加 `NBT` 會(huì)覆蓋掉物品原有的附魔,因此只適合沒有附魔的物品使用
Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {
// 通過 inventory 來獲取 附魔書的NBT
? ?let enchantments = inventory.get(inventory.find(Item.of('minecraft:enchanted_book').ignoreNBT())).nbt
// 將 附魔書的NBT 中關(guān)于附魔的部分添加到 物品
? ?itemstack.nbt.merge({Enchantments: enchantments.get('StoredEnchantments')})
// 返回 添加了附魔的物品
? ?return itemstack
})
另一種方案:完全實(shí)現(xiàn)了鐵砧的功能,除了消耗經(jīng)驗(yàn)和發(fā)出音效
Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {
// 復(fù)制物品 和 獲取附魔書
let itemstack1 = itemstack.copy()
let itemstack2 = inventory.get(inventory.find(Item.of('minecraft:enchanted_book').ignoreNBT()))
? ?// 分別獲取 物品 和 附魔書 的所有附魔
let map = EnchantmentHelper.getEnchantments(itemstack1)
let map1 = EnchantmentHelper.getEnchantments(itemstack2)
? ?
? ?//對 附魔書的附魔 進(jìn)行遍歷
let var22 = map1.keySet().iterator()
label172: while(true) {
let enchantment1
do {
// 當(dāng)沒有下一個(gè)附魔時(shí)跳出循環(huán)
? ? ? ? ? if(!var22.hasNext()) break label172
// 獲取下一個(gè)附魔
? ? ? ? ? enchantment1 = var22.next()
} while(enchantment1 == null)
// 獲取該附魔在 物品 和 附魔書 上的等級
? ? ? ?let i2 = map.getOrDefault(enchantment1, 0)
let j2 = map1.get(enchantment1)
? ? ? ?// 當(dāng)附魔等級一致時(shí)增加一級,否則取最大值
j2 = i2 == j2 ? j2 + 1 : Math.max(j2, i2)
// 標(biāo)記:該附魔能否附加在 物品 上
let flag1 = enchantment1.canEnchant(itemstack)
? ? ? ?
? ? ? ?// 對 物品的附魔 進(jìn)行遍歷
let var17 = map.keySet().iterator()
while(var17.hasNext()) {
let enchantment = var17.next()
// 物品不擁有該附魔 且 該附魔無法附加到物品上時(shí),標(biāo)記為否
? ? ? ? ? ?if(enchantment != enchantment1 && !enchantment1.isCompatibleWith(enchantment)) {
flag1 = false
}
}
if(flag1) {
// 確保 附魔等級 不超過上限
? ? ? ? ? if(j2 > enchantment1.getMaxLevel()) {
j2 = enchantment1.getMaxLevel()
}
// 將 物品的附魔 與 附魔書的附魔 合并,但并不是附加到物品上
? ? ? ? ? map.put(enchantment1, j2)
}
}
let listtag = [] // 緩存附魔標(biāo)簽
? ?// 對 合并后的Map 進(jìn)行遍歷
let var3 = map.entrySet().iterator()
while(var3.hasNext()) {
let entry = var3.next()
// 獲取 經(jīng)過篩選的附魔
? ? ? ?let enchantment = entry.getKey()
? ? ? ?if(enchantment != null) {
let i = entry.getValue()
// 當(dāng) 附魔 不為空時(shí),添加到 listtag 中
? ? ? ? ? ?listtag.push(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), i))
}
}
if(!listtag) {
// 當(dāng) listtag 為空時(shí),移除物品的附魔標(biāo)簽
? ? ? itemstack1.getItemStack().removeTagKey('Enchantments')
} else {
// 當(dāng) listtag 不為空時(shí),為物品添加附魔標(biāo)簽
? ? ? itemstack1.getItemStack().addTagElement('Enchantments', listtag)
}
// 返回 附魔后的物品
? return itemstack1
})
這里用到了原版的附魔幫手 `EnchantmentHelper`,所有要先導(dǎo)入
let EnchantmentHelper = java('net.minecraft.world.item.enchantment.EnchantmentHelper')
因此,該腳本在 1.16.5 與 1.18.2+ 的寫法并不相同

配方
最后只需要在寫配方時(shí)調(diào)用我們的自定義函數(shù)就可以了
onEvent('recipes', event => {
event.shapeless('minecraft:book', ['#kaka:tools', Item.of('minecraft:enchanted_book').ignoreNBT()])
.customIngredientAction('#kaka:tools', 'apply_enchantment')
})
// 我用了自定義的 物品標(biāo)簽 'kaka:tools', 所以需要另外注冊
onEvent('tags.items', event => {
event.add('kaka:tools', 'minecraft:netherite_pickaxe')
event.add('kaka:tools', ['minecraft:diamond_pickaxe'])
})
就是這樣,非常有趣的配方函數(shù),希望你能寫出自己想要的效果
謝謝你的閱讀,請不要忘了動(dòng)動(dòng)手指給我一個(gè)免費(fèi)點(diǎn)贊哦

最后是總覽:并沒有注釋哦,你還記得它們的作用嗎
let EnchantmentHelper = java('net.minecraft.world.item.enchantment.EnchantmentHelper')
onEvent('recipes', event => {
Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {
// let enchantments = inventory.get(inventory.find(Item.of('minecraft:enchanted_book').ignoreNBT())).nbt
// itemstack.nbt.merge({Enchantments: enchantments.get('StoredEnchantments')})
// return itemstack
let itemstack1 = itemstack.copy()
let itemstack2 = inventory.get(inventory.find(Item.of('minecraft:enchanted_book').ignoreNBT()))
let map = EnchantmentHelper.getEnchantments(itemstack1)
let map1 = EnchantmentHelper.getEnchantments(itemstack2)
let var22 = map1.keySet().iterator()
label172: while(true) {
let enchantment1
do {
if(!var22.hasNext()) break label172
enchantment1 = var22.next()
} while(enchantment1 == null)
let i2 = map.getOrDefault(enchantment1, 0)
let j2 = map1.get(enchantment1)
j2 = i2 == j2 ? j2 + 1 : Math.max(j2, i2)
let flag1 = enchantment1.canEnchant(itemstack)
let var17 = map.keySet().iterator()
while(var17.hasNext()) {
let enchantment = var17.next()
if(enchantment != enchantment1 && !enchantment1.isCompatibleWith(enchantment)) {
flag1 = false
}
}
if(flag1) {
if(j2 > enchantment1.getMaxLevel()) {
j2 = enchantment1.getMaxLevel()
}
map.put(enchantment1, j2)
}
}
let listtag = []
let var3 = map.entrySet().iterator()
while(var3.hasNext()) {
let entry = var3.next()
let enchantment = entry.getKey()
if(enchantment != null) {
let i = entry.getValue()
listtag.push(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), i))
}
}
if(!listtag) {
itemstack1.getItemStack().removeTagKey('Enchantments')
} else {
itemstack1.getItemStack().addTagElement('Enchantments', listtag)
}
return itemstack1
})
event.shapeless('minecraft:book', ['#kaka:tools', Item.of('minecraft:enchanted_book').ignoreNBT()])
.customIngredientAction('#kaka:tools', 'apply_enchantment')
})
onEvent('tags.items', event => {
event.add('kaka:tools', 'minecraft:netherite_pickaxe')
event.add('kaka:tools', ['minecraft:diamond_pickaxe'])
})
其實(shí)還有改輸出的函數(shù) `modifyResult` 哦,想想該怎么寫吧
