Skip to content

JavaScript 脚本

EmakiItem 通过 CoreLib 的脚本系统注册脚本模块,模块 ID 为 itemitems 是等价别名)。脚本中通过 emaki.module("item") 获取模块门面,用于查询/创建物品、注册运行时物品定义和物品工厂。

本页只介绍 EmakiItem 专属的脚本方法、注册字段、上下文和示例。通用脚本机制请阅读 CoreLib JavaScript 脚本系统

注意:CoreLib 注入对象里的 emaki.item 是上下文 ItemStack 工具,不是 EmakiItem 插件 API;EmakiItem 插件 API 通过 emaki.module("item") 获取。

调用任何业务方法前,先用 available() 守卫。EmakiItem 是 CoreLib 的 softdepend。

获取模块

js
function main(ctx) {
  const item = emaki.module("item");
  if (!item.available()) {
    return { skipped: true, message: "EmakiItem 不可用" };
  }
  // ...
  return true;
}

基础探针方法

方法返回说明
available()boolean模块是否可用。

EmakiItem 模块门面只提供 available() 探针。

查询与创建

方法返回说明
exists(id)boolean物品定义是否存在。
create(id, amount)map创建物品并返回物品摘要。amount>0 时钳制到 [1,64];省略或 ≤0 时使用定义的默认数量(amount 字段,默认 1)。
identify(itemKey)string根据上下文 attribute key 取 ItemStack 并识别其物品 id;无则返回空串。
definitionIds()list返回所有物品定义 id(YAML + 运行时)的排序副本。
displayName(id)string物品显示名。

物品摘要 Map 保留旧字段 typeamountdisplayName、可选 lorecustomModelData,并新增 schemaVersion、规范化 item 和完整 components snapshot。空气或无物品时返回空 Map。

这些查询方法读取的是模块实例化时捕获的快照,同一次脚本调用内不会反映后续注册结果。

运行时物品定义

运行时 definition Map 与 YAML definition 交给同一个 EmakiItemDefinitionParser,因此支持相同的 item、components、set、condition、repair、update、actions 等字段;override 仍只是脚本注册控制字段。

方法返回说明
registerDefinition(definition)boolean注册一个运行时物品定义。
registerDefinition(id, definition)boolean重载:把 id 合并进 definition 后注册。
unregisterDefinition(id)void按 id 注销定义。
registeredDefinitions()list返回运行时注册的定义 id 列表。

定义 definition 字段

字段类型必填默认说明
idstring物品 id,会被规范化;为空注册失败。
overridebooleanfalse是否覆盖同名 YAML definition;只控制注册,不进入运行时物品模型。
itemmap/string与 YAML 相同的共享基础物品 definition。推荐 map 中写 sourceamountcomponents
name_actions / lore_actions结构名称和 Lore 业务动作链。
effectslist与 YAML 相同的 variables / ea_attribute / es_skill 效果。
set / condition / repair / updatemap与 YAML definition 相同的业务配置。
actionsmap触发动作,如 giveinteract
js
item.registerDefinition({
  id: "js_event_sword",
  override: false,
  item: {
    source: "minecraft-diamond_sword",
    amount: 1,
    components: {
      "minecraft:custom_name": "<red>JS 活动之剑</red>",
      "minecraft:lore": ["<gray>由 JavaScript 运行时注册</gray>"],
      "minecraft:enchantment_glint_override": true
    }
  },
  effects: [
    { type: "ea_attribute", ea_attributes: { attack_damage: 10 } }
  ]
});

注册时会验证 item.source resolver 与组件值。来源不可用、未知组件 ID 或当前版本支持但值非法时注册失败;已知高版本组件会跳过并记录警告。注册成功后会清理物品工厂缓存。

物品工厂

工厂在创建物品时按优先级依次尝试,由 JS 函数动态返回物品定义片段。

方法返回说明
registerFactory(definition)boolean注册一个物品工厂。
registerFactory(id, definition)boolean重载:把 id 合并进 definition 后注册。
unregisterFactory(id)void按 id 注销工厂。
registeredFactories()list返回已注册工厂 id 列表。
createFactory(id, amount)map保留方法,当前始终返回空 Map;工厂产物请通过物品 ID 正常创建流程获取。

工厂 definition 字段

字段类型必填默认说明
idstring工厂 id,会被规范化;为空注册失败。
priorityint0优先级,数值小者先尝试;相同按 id 排序。
functionstringcreate工厂函数名,也可用 execute
timeoutMillislong引擎默认超时单次脚本超时。

工厂函数的 arguments 字段

字段类型说明
idstring请求的物品 id(规范化)。
factoryIdstring工厂 id。
amountint请求数量(至少 1)。
scriptstring脚本路径。
playerUuidstring有在线玩家时注入(取第一个在线玩家,不代表请求者)。
playerNamestring有在线玩家时注入。

工厂函数须返回一个物品定义片段 Map,否则视为不匹配返回 null。返回的 Map 会补全 id 后走定义解析并生成 ItemStack。多个工厂按优先级依次尝试,首个返回非 null 的胜出。

触发脚本上下文

物品触发动作调用脚本时,可通过 emaki.context 读取以下占位符与 attribute:

读取方式说明
emaki.context.placeholder("item_id")item_id物品 id。
emaki.context.placeholder("item_trigger")item_trigger触发器名。
emaki.context.placeholder("item_name")item_name物品名。
emaki.context.attribute("item_id")item_id物品 id(attribute 形式)。

触发示例

EmakiItem 自带触发型示例脚本 scripts/examples/item_right_click.js

js
function main(ctx) {
  const item = emaki.module("item");
  const itemId = emaki.context.placeholder("item_id");
  const trigger = emaki.context.placeholder("item_trigger");
  if (emaki.player.exists()) {
    emaki.player.sendMessage("[EmakiJS] 物品触发脚本: " + itemId + " trigger=" + trigger + " item=" + item.available());
  }
  return {
    success: true,
    output: {
      item_id: String(itemId || ""),
      trigger: String(trigger || ""),
      item_available: item.available()
    }
  };
}

注册示例

EmakiItem 自带扩展型示例脚本 scripts/examples/item_runtime_definition.js

js
function register() {
  const item = emaki.module("item");

  item.registerDefinition({
    id: "js_event_sword",
    item: {
      source: "minecraft-diamond_sword",
      components: {
        "minecraft:custom_name": "<red>JS 活动之剑</red>",
        "minecraft:lore": [
          "<gray>由 JavaScript 运行时注册</gray>",
          "<yellow>攻击 +10</yellow>"
        ]
      }
    },
    effects: [{
      type: "ea_attribute",
      ea_attributes: { attack_damage: 10 }
    }],
    actions: {
      give: ["message text=<gold>你获得了 JS 活动之剑!</gold>"]
    }
  });

  item.registerFactory({
    id: "js_random_relic",
    priority: 10,
    function: "createRelic"
  });
}

function createRelic(ctx) {
  if (ctx.id !== "js_random_relic") {
    return null;
  }
  const roll = emaki.random.integer(0, 99);
  return {
    item: {
      source: "minecraft-nether_star",
      components: {
        "minecraft:custom_name": roll >= 50 ? "<light_purple>闪耀随机遗物</light_purple>" : "<aqua>随机遗物</aqua>",
        "minecraft:lore": [
          "<gray>由 JavaScript Factory 动态生成</gray>",
          "<dark_gray>roll=" + roll + "</dark_gray>"
        ]
      }
    },
    effects: [{ type: "variables", variables: { roll: roll } }]
  };
}

启用扩展脚本

把脚本放到 CoreLib 的全局扩展目录后重载:

text
plugins/EmakiCoreLib/scripts/extensions/global/item_runtime_definition.js
text
/corelib script reload

示例文件默认释放到 plugins/EmakiCoreLib/scripts/examples/,不会自动启用。

注意事项

  • 所有注册方法都要求 CoreLib 脚本系统已启用,否则注册返回 false 或静默跳过。
  • CoreLib 缺失时模块自动降级,查询返回空、注册返回 false。
  • 工厂按优先级升序执行(数值小者先尝试)。
  • 注册或注销定义成功后会清理物品工厂缓存。