欢迎光临散文网 会员登陆 & 注册

『KubeJS新手教程?』用工作台来附魔吧,把铁砧放一边 | 我的世界 Minecraft 魔改

2022-09-05 18:24 作者:吕不才  | 我要投稿

在写工作台配方时,你是否想过要实现些特殊的效果呢

Transform Ingredients

在有序/无序配方中,我们可以用一些函数来实现“材料”的转换,以达到我们的需求:

.damageIngredient(IngredientFilter filter, int damage?) // 在你合成时,损耗/增加物品的耐久度
.replaceIngredient(IngredientFilter filter, ItemStackJS item) // 将物品替换为其他的物品 (例如水桶合成后变为桶)
.keepIngredient(IngredientFilter filter) // 将物品保留在合成格中
.customIngredientAction(IngredientFilter filter, String customId) // 运行你的自定义脚本,记得先注册哦

IngredientFilter 材料过滤器可以是

- 物品 ItemStackJS ('minecraft:dirt', Item.of('minecraft:diamond_sword').ignoreNBT(), 等)

- 物品在合成格的位置/索引 (0, 1, 等)

- 物品和/或索引 ( {item: 'something', index: 0}, 等) 

不同的函数对应不同的使用场景

而我们这次需要用到的,就是 `customIngredientAction` 自定义的材料变化函数

Register Custom Ingredient Action

使用 `Ingredinet` 下的方法 `registerCustomIngredientAction` 来注册我们的自定义函数

Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {})

其中 `itemstack` 代表指定的物品,`index` 代表合成格的索引,`inventory` 代表合成格包含的所有物品

我们可以通过 `NBT` 来修改物品的附魔,这里有两种方案

一种方案:简单的添加 `NBT` 会覆盖掉物品原有的附魔,因此只适合没有附魔的物品使用

Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {
	// 通过 inventory 来获取 附魔书的NBT
    let enchantments = inventory.get(inventory.find(Item.of('minecraft:enchanted_book').ignoreNBT())).nbt

	// 将 附魔书的NBT 中关于附魔的部分添加到 物品
    itemstack.nbt.merge({Enchantments: enchantments.get('StoredEnchantments')})

	// 返回 添加了附魔的物品
    return itemstack
})

另一种方案:完全实现了铁砧的功能,除了消耗经验和发出音效

Ingredient.registerCustomIngredientAction('apply_enchantment', (itemstack, index, inventory) => {
	// 复制物品 和 获取附魔书
 	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 = [] // 缓存附魔标签
    // 对 合并后的Map 进行遍历
	let var3 = map.entrySet().iterator()

	while(var3.hasNext()) {
		let entry = var3.next()
		// 获取 经过筛选的附魔
        let enchantment = entry.getKey()

        if(enchantment != null) {
			let i = entry.getValue()

			// 当 附魔 不为空时,添加到 listtag 中
            listtag.push(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), i))
		}
	}

	if(!listtag) {
		// 当 listtag 为空时,移除物品的附魔标签
      	itemstack1.getItemStack().removeTagKey('Enchantments')
	} else {
		// 当 listtag 不为空时,为物品添加附魔标签
      	itemstack1.getItemStack().addTagElement('Enchantments', listtag)
	}

	// 返回 附魔后的物品
  	return itemstack1
})

这里用到了原版的附魔帮手 `EnchantmentHelper`,所有要先导入

let EnchantmentHelper = java('net.minecraft.world.item.enchantment.EnchantmentHelper')

因此,该脚本在 1.16.5 与 1.18.2+ 的写法并不相同

配方

最后只需要在写配方时调用我们的自定义函数就可以了

onEvent('recipes', event => {
	event.shapeless('minecraft:book', ['#kaka:tools', Item.of('minecraft:enchanted_book').ignoreNBT()])
		.customIngredientAction('#kaka:tools', 'apply_enchantment')
})

// 我用了自定义的 物品标签 'kaka:tools', 所以需要另外注册
onEvent('tags.items', event => {
	event.add('kaka:tools', 'minecraft:netherite_pickaxe')
	event.add('kaka:tools', ['minecraft:diamond_pickaxe'])
})

就是这样,非常有趣的配方函数,希望你能写出自己想要的效果

谢谢你的阅读,请不要忘了动动手指给我一个免费点赞哦

最后是总览:并没有注释哦,你还记得它们的作用吗

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'])
})

其实还有改输出的函数 `modifyResult` 哦,想想该怎么写吧


『KubeJS新手教程?』用工作台来附魔吧,把铁砧放一边 | 我的世界 Minecraft 魔改的评论 (共 条)

分享到微博请遵守国家法律