物品注册 (Item Registry)

预计阅读时间: 8 分钟

向游戏添加新物品

自定义物品在启动脚本中创建。它们不能在不重新启动游戏的情况下重新加载。事件不可取消。

// 监听物品注册事件
StartupEvents.registry('item', event => {
  // 此物品的纹理必须放在 kubejs/assets/kubejs/textures/item/test_item.png
  // 如果您想要自定义物品模型,可以在 Blockbench 中创建一个并将其放在 kubejs/assets/kubejs/models/item/test_item.json
  event.create('test_item')

  // 如果您想指定不同的纹理位置,也可以这样做,如下所示:
  event.create('test_item_1').texture('mobbo:item/lava') // 此纹理位于 kubejs/assets/mobbo/textures/item/lava.png

  // 您可以尽可能多地链式调用构建器方法
  event.create('test_item_2').maxStackSize(16).glow(true)

  // 您可以在 create() 中将物品类型指定为第二个参数,某些类型有不同的可用方法
  event.create('custom_sword', 'sword').tier('diamond').attackDamageBaseline(10)
})

有效的物品类型:

  • basic(这是默认值)

  • sword

  • pickaxe

  • axe

  • shovel

  • shears

  • hoe

  • helmet

  • chestplate

  • leggings

  • boots

物品构建器支持的其他方法(您可以在 create() 之后链式调用这些方法):

  • maxStackSize(size)

  • unstackable()maxStackSize(1) 相同

  • maxDamage(damage)

  • burnTime(ticks)

  • fireResistant(true/false)

  • rarity(rarity)

  • glow(true/false)

  • tooltip(text...)

  • color(index, colorHex)

  • color((itemstack, tintIndex) => ...)

  • displayName(name)

  • name(itemstack => ...)

  • translationKey(key)

  • textureJson(json)

  • modelJson(json)

  • parentModel(customParentModelLocation)

  • texture(customTextureLocation)

  • texture(key, customTextureLocation)

  • barColor(itemstack => ...)

  • barWidth(itemstack => ...)

  • useAnimation(animation)

  • useDuration(itemstack => ...)

  • use((level, player, hand) => ...)

  • finishUsing((itemstack, level, entity) => ...)

  • releaseUsing((itemstack, level, entity, tick) => ...)

  • tag(resourceLocation)

  • modifyAttribute(attribute, identifier, d, operation)

  • group(groupId)

  • containerItem(itemId)

  • subtypes(itemstack => ...)

  • food(foodBuilder => ...) 完整语法见下方

已删除的旧方法:

  • type(type) - 1.16 和 1.18

  • tool(type, level) - 1.16

如果您使用工具类型(swordpickaxeaxeshovelhoe),可用方法:

  • tier(toolTier)

  • modifyTier(tier => ...) 语法与自定义工具等级相同,见 自定义等级

  • attackDamageBaseline(damage) 只有在创建自定义武器(如长矛、战斧等)时才需要修改此值

  • attackDamageBonus(damage)

  • speedBaseline(speed) 与 attackDamageBaseline 相同,仅用于自定义武器类型

  • speed(speed)

默认可用的工具等级:

  • wood

  • stone

  • iron

  • gold

  • diamond

  • netherite

如果您使用护甲类型('helmet''chestplate''leggings''boots'),可用方法:

  • tier(armorTier)

  • modifyTier(tier => ...) 语法与自定义护甲等级相同,见 自定义等级

默认可用的护甲等级:

  • leather

  • chainmail

  • iron

  • gold

  • diamond

  • turtle

  • netherite

原版物品组/创造模式标签ID:

  • search

  • buildingBlocks

  • decorations

  • redstone

  • transportation

  • misc

  • food

  • tools

  • combat

  • brewing

示例 (Examples)

自定义食物 (Custom Foods)

1.21.1 1.20 - 1.19

StartupEvents.registry('item', event => {
  event.create('magic_steak').food(food => {
    food
      .nutrition(6)
      .saturation(6) // 此值不直接转换为获得的饱和度点数
      // 实际值可以假定为:
      // min(hunger * saturation * 2 + saturation, foodAmountAfterEating)
      .effect('minecraft:speed', 600, 0, 1)
      .removeEffect('minecraft:poison')
      .alwaysEdible() // 像金苹果一样
      .fastToEat() // 像干海带一样
      .meat() // 狗愿意吃它
      .eaten(ctx => {
        // 食用时运行代码
        ctx.player.tell(Text.gold('Yummy Yummy!'))
        // 如果您想修改此代码,则需要重新启动游戏。
        // 但是,如果您让此代码调用全局启动函数
        // 并将函数放在事件处理程序*外部*
        // 那么您可以使用命令:
        // /kubejs reload startup_scripts
        // 立即重新加载函数。
        // 见下方示例
      })
  })

  event.create('magicer_steak')
    .unstackable()
    .food(food =>
      food
        .nutrition(7)
        .saturation(7)
        // 这引用下面的函数而不是直接包含代码,因此它是可重新加载的!
        .eaten(ctx => global.myAwesomeReloadableFunction(ctx))
    )
})

global.myAwesomeReloadableFunction = ctx => {
  ctx.player.tell('Hello there!')
  ctx.player.tell(Text.of('Change me then reload with ').append(Text.red('/kubejs reload startup_scripts')).append(' to see your changes!'))
}
StartupEvents.registry('item', event => {
  event.create('magic_steak').food(food => {
    food
      .hunger(6)
      .saturation(6) // 此值不直接转换为获得的饱和度点数
      // 实际值可以假定为:
      // min(hunger * saturation * 2 + saturation, foodAmountAfterEating)
      .effect('minecraft:speed', 600, 0, 1)
      .removeEffect('minecraft:poison')
      .alwaysEdible() // 像金苹果一样
      .fastToEat() // 像干海带一样
      .meat() // 狗愿意吃它
      .eaten(ctx => {
        // 食用时运行代码
        ctx.player.tell(Text.gold('Yummy Yummy!'))
        // 如果您想修改此代码,则需要重新启动游戏。
        // 但是,如果您让此代码调用全局启动函数
        // 并将函数放在事件处理程序*外部*
        // 那么您可以使用命令:
        // /kubejs reload startup_scripts
        // 立即重新加载函数。
        // 见下方示例
      })
  })

  event.create('magicer_steak')
    .unstackable()
    .food(food =>
      food
        .hunger(7)
        .saturation(7)
        // 这引用下面的函数而不是直接包含代码,因此它是可重新加载的!
        .eaten(ctx => global.myAwesomeReloadableFunction(ctx))
    )
})

global.myAwesomeReloadableFunction = ctx => {
  ctx.player.tell('Hello there!')
  ctx.player.tell(Text.of('Change me then reload with ').append(Text.red('/kubejs reload startup_scripts')).append(' to see your changes!'))
}

自定义用途 (Custom Uses)

StartupEvents.registry('item', event => {
  event.create('nuke_soda', 'basic')
    .tooltip('§5Taste of Explosion!')
    .tooltip('§c...Inappropriate intake may cause disastrous result.')
    /**
     * 物品的使用动画,可以是 "spear"(三叉戟)、
     * "crossbow"、"eat"(食物)、"spyglass"、"block"、"none"、"bow"、"drink"
     * 使用某些动画时,会播放相应的声音。
     */
    .useAnimation('drink')
    /**
     * 物品完成使用前的持续时间,
     * 如果您需要像按住蓄力时间(如弓),
     * 考虑将此设置为 72000(1小时)或更多。
     * 返回值为 0 或更低将使物品不可用。
     */
    .useDuration(itemstack => 64)
    /**
     * 物品即将被使用时。
     * 如果为 true,如果持续时间 > 0,物品将开始其使用动画。
     */
    .use((level, player, hand) => true)
    // 物品使用持续时间到期时。
    .finishUsing((itemstack, level, entity) => {
      const effects = entity.potionEffects
      effects.add('minecraft:haste', 120 * 20)
      itemstack.shrink(1)
      if (entity.player) {
        entity.minecraftPlayer.addItem(Item.of('minecraft:glass_bottle').itemStack)
      }
      return itemstack
    })
    /**
     * 当持续时间尚未到期,但
     * 玩家释放右键时。
     * Tick 是玩家完成使用物品剩余的刻数。
     */
    .releaseUsing((itemstack, level, entity, tick) => {
      itemstack.shrink(1)
      level.createExplosion(entity.x, entity.y, entity.z).explode()
    })
})

进度条 (Bar)

StartupEvents.registry('item', event => {
  event.create('hammer')
    /**
     * 确定进度条的长度,应该是 0(空)到 13(满)之间的整数
     * 如果值低于 0,将被视为 0。
     * 值上限为 13,超过 13 的任何值将被视为"满",因此不显示
     */
    .barWidth(itemstack => itemstack.nbt.contains('hit_count') ? itemstack.nbt.getInt('hit_count') / 13 : 0)
    // 确定进度条的颜色。
    .barColor(itemstack => Color.AQUA)
})

动态染色和模型相关 (Dynamic Tinting and Model Stuff)

StartupEvents.registry('item', event => {
  // 旧样式,仅按索引设置颜色仍然有效!
  event.create('old_color_by_index')
    .textureJson({
      layer0: 'minecraft:item/paper',
      layer1: 'minecraft:item/ghast_tear'
    })
    .color(0, '#70F00F')
    .color(1, '#00FFF0')

  event.create('cooler_sword', 'sword')
    .displayName('Test Cooler Sword')
    .texture('minecraft:item/iron_sword')
    /**
     * 通过将颜色存储在物品栈的 nbt 中的示例
     * 您必须返回 -1 以不应用染色。
     *
     * 您可以通过以下方式测试:/give @p kubejs:cooler_sword{color:"#ff0000"}
     */
    .color(itemstack => itemstack.nbt && itemstack.nbt.color ? itemstack.nbt.color : -1)

  event.create('test_item')
    .displayName('Test Item')
    .textureJson({
      layer0: 'minecraft:item/beef',
      layer1: 'minecraft:item/ghast_tear'
    })
    /**
     * 如果您想将颜色应用于特定层,可以使用 tintIndex
     * tintIndex 是模型中的纹理层索引:layer0 -> 0, layer1 -> 1 等
     * 您可以使用 `Color` 包装器获取一些默认颜色
     *
     * 此示例将颜色应用于恶魂之泪纹理。
     */
    .color((itemstack, tintIndex) => tintIndex == 1 ? Color.BLUE : -1)

  // 为特定层设置纹理
  event.create('test_sword', 'sword')
    .displayName('Test Sword')
    .texture('layer0', 'minecraft:item/bell')

  // 直接设置您的自定义模型 json
  event.create('test_something')
    .displayName('Test something')
    .modelJson({
      parent: 'minecraft:block/anvil'
    })
})

脚本文件夹:startup_scripts/