JavaScript 脚本
EmakiItem 通过 CoreLib 的脚本系统注册脚本模块,模块 ID 为 item(items 是等价别名)。脚本中通过 emaki.module("item") 获取模块门面,用于查询/创建物品、注册运行时物品定义和物品工厂。
本页只介绍 EmakiItem 专属的脚本方法、注册字段、上下文和示例。通用脚本机制请阅读 CoreLib JavaScript 脚本系统。
注意:CoreLib 注入对象里的
emaki.item是上下文 ItemStack 工具,不是 EmakiItem 插件 API;EmakiItem 插件 API 通过emaki.module("item")获取。
调用任何业务方法前,先用
available()守卫。EmakiItem 是 CoreLib 的 softdepend。
获取模块
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 保留旧字段 type、amount、displayName、可选 lore 与 customModelData,并新增 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 字段
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
id | string | 是 | 无 | 物品 id,会被规范化;为空注册失败。 |
override | boolean | 否 | false | 是否覆盖同名 YAML definition;只控制注册,不进入运行时物品模型。 |
item | map/string | 是 | 无 | 与 YAML 相同的共享基础物品 definition。推荐 map 中写 source、amount、components。 |
name_actions / lore_actions | 结构 | 否 | — | 名称和 Lore 业务动作链。 |
effects | list | 否 | — | 与 YAML 相同的 variables / ea_attribute / es_skill 效果。 |
set / condition / repair / update | map | 否 | — | 与 YAML definition 相同的业务配置。 |
actions | map | 否 | — | 触发动作,如 give、interact。 |
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.sourceresolver 与组件值。来源不可用、未知组件 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 字段
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
id | string | 是 | 无 | 工厂 id,会被规范化;为空注册失败。 |
priority | int | 否 | 0 | 优先级,数值小者先尝试;相同按 id 排序。 |
function | string | 否 | create | 工厂函数名,也可用 execute。 |
timeoutMillis | long | 否 | 引擎默认超时 | 单次脚本超时。 |
工厂函数的 arguments 字段
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 请求的物品 id(规范化)。 |
factoryId | string | 工厂 id。 |
amount | int | 请求数量(至少 1)。 |
script | string | 脚本路径。 |
playerUuid | string | 有在线玩家时注入(取第一个在线玩家,不代表请求者)。 |
playerName | string | 有在线玩家时注入。 |
工厂函数须返回一个物品定义片段 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:
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:
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 的全局扩展目录后重载:
plugins/EmakiCoreLib/scripts/extensions/global/item_runtime_definition.js/corelib script reload示例文件默认释放到
plugins/EmakiCoreLib/scripts/examples/,不会自动启用。
注意事项
- 所有注册方法都要求 CoreLib 脚本系统已启用,否则注册返回
false或静默跳过。 - CoreLib 缺失时模块自动降级,查询返回空、注册返回 false。
- 工厂按优先级升序执行(数值小者先尝试)。
- 注册或注销定义成功后会清理物品工厂缓存。