跳转至

物品、方块与配方

InnerCore的物品、方块与配方系统使用JavaScript或TypeScript脚本注册内容,并由资源目录提供纹理。这里的能力属于旧第三方客户端模组生态,不是国际版附加包原生格式。

不要混淆开发体系

本文出现的IDRegistryItemBlockRecipes等接口来自InnerCore/CoreEngine资料。它们不能直接用于官方附加包、国际版脚本API或服务端插件。

物品资源

物品纹理通常放在资源目录的items-opaque子目录中,文件名采用纹理名_数据值.png纹理名_数据值.tga形式。资料以oxidized_stick_0.png为例;脚本中只引用不带扩展名和目录的纹理名,并用数据值选择变种。

assets/resources/items-opaque/oxidized_stick_0.png

build.config中必须有资源目录描述,否则资源不会按模组资源加载:

build.config
{
  "resources": [
    {
      "path": "assets/resources/",
      "resourceType": "resource"
    }
  ]
}

注册物品

第一个物品先注册翻译,再生成数值ID,最后创建物品。

dev/oxidized_stick.js
Translation.addTranslation("item.oxidized_stick.name", {
  en: "Oxidized Stick"
});

IDRegistry.genItemID("oxidized_stick");
Item.createItem("oxidized_stick", "item.oxidized_stick.name", {
  name: "oxidized_stick",
  data: 0
}, {
  stack: 64
});

IDRegistry.genItemID会为字符串标识符生成旧引擎内部使用的数值标识符。ItemID.oxidized_stick则提供该数值ID。资料说明,生成后的物品可能在游戏界面中表现为类似minecraft:item_oxidized_stick的形式。

默认物品会进入创造模式物品栏。若物品仅用于技术逻辑,可在附加参数中设置isTech: true

物品行为

物品使用逻辑可通过专用函数绑定,也可直接监听回调。资料更推荐在能满足需求时使用专用函数,因为它已经处理了部分方块界面与方块实体交互判断。

Item.registerUseFunction("oxidized_stick", function(coords, item, block, playerUid) {
  Entity.addVelocity(playerUid, 0, 0.5 * Math.random(), 0);
});

等价的直接回调需要自行判断物品ID

Callback.addCallback("ItemUse", function(coords, item, block, isExternal, playerUid) {
  if (item.id == ItemID.oxidized_stick) {
    Entity.addVelocity(playerUid, 0, 0.5 * Math.random(), 0);
  }
});

资料还介绍了投掷物、食物和盔甲:投掷物使用Item.createThrowableItemItem.registerThrowableFunction,食物使用Item.createFoodItemFoodEaten回调,盔甲使用Item.createArmorItem并提供部位、护甲值、耐久、击退抗性和穿戴纹理路径。

物品额外数据

InnerCore资料把物品上的额外数据称为ItemExtraData。它可保存字符串、整数、浮点数、布尔值、对象和长整数等数据,并通过ItemInstanceextra字段随物品传递。

const extraData = new ItemExtraData();
extraData.putString("rune", "fire");

Entity.setCarriedItem(player, item.id, item.count, item.data, extraData);

读取时可提供默认值:

const rune = item.extra ? item.extra.getString("rune", "unknown") : "unknown";

这种机制适合旧InnerCore物品的附加状态,例如随机符文、特殊耐久或自定义数据。新附加包项目不应照搬该接口。

配方

资料把配方分为无序配方、有序配方和烧炼配方。无序配方只要求输入物品集合;有序配方使用图案和掩码;烧炼配方使用熔炉输入、输出和可选燃料。

Recipes.addShapeless({
  id: VanillaItemID.diamond,
  count: 1,
  data: 0
}, [
  { id: VanillaItemID.iron_ingot, data: 0 },
  { id: VanillaItemID.gold_ingot, data: -1 },
  { id: VanillaItemID.flint }
]);
Recipes.addShaped2(VanillaItemID.sapling, 1, 0, [" l ", "lll", " o "], [
  "o", VanillaBlockID.log, 0,
  "l", VanillaBlockID.leaves, 0
]);
Recipes.addFurnace(VanillaItemID.rotten_flesh, 0, VanillaItemID.leather, 0);
Recipes.addFurnaceFuel(VanillaBlockID.magma, 0, 400);

配方回调可修改结果、消耗输入或取消合成。资料特别提醒,配方和工作台事件会影响所有相关配方,处理时应先做简单判断。

方块资源

方块纹理通常放在terrain-atlas子目录。文件名仍使用纹理名_数据值.png形式;脚本中引用["纹理名",数据值]

assets/resources/terrain-atlas/log_oxidized_top_0.png
assets/resources/terrain-atlas/log_oxidized_side_0.png

方块的6个面按底面、顶面、背面、正面、左面、右面描述。资料指出,列表不足6项时,最后一项会重复用于剩余面。

[
  ["crafting_table_bottom", 0],
  ["crafting_table_top", 0],
  ["crafting_table_front", 0],
  ["crafting_table_front", 0],
  ["crafting_table_side", 0]
]

注册方块

注册方块时同样先生成ID,再调用Block.createBlock。一个方块ID可包含多个变种,以节省旧版数值ID空间。

IDRegistry.genBlockID("oxidized_log");
Block.createBlock("oxidized_log", [{
  name: "Oxidized Log",
  texture: [
    ["oxidized_log_top", 0],
    ["oxidized_log_top", 0],
    ["oxidized_log_side", 0]
  ],
  inCreative: true
}], "opaque");

第三个参数可为特殊类型名,也可为属性对象。资料列出的属性包括basematerialsoundsolidrenderlayerlightlevellightopacityexplosionresfrictiondestroytime等。多个方块共用的属性可通过Block.createSpecialType注册。

液体与模型

液体由静止方块、流动方块和桶物品组合而成。资料使用Block.createLiquidBlock注册完整液体,并指出液体会设置自己的渲染层和渲染类型。

Block.createLiquidBlock("ink", {
  name: "Ink",
  tickDelay: 30,
  still: {
    texture: ["ink", 0]
  },
  flowing: {
    texture: ["ink", 0]
  },
  bucket: {
    texture: { name: "bucket_ink", meta: 0 }
  },
  uiTextures: ["liquid_ink"]
});

复杂方块形状使用BlockRendererICRender。模型由盒体组成,可设置静态渲染、碰撞箱、击中轮廓,也可在坐标上进行客户端映射。资料特别提醒:映射是客户端侧的,不应把它当作稳定的方块状态系统;简单旋转和状态变化优先使用方块变种。