简体中文
EmakiItem
先看四件事: EmakiItem 能做什么, 每个功能对应哪一页, 主配置 config.yml 有哪些设置, 以及它和其他模块怎么配合
EmakiItem 是轻量自定义物品模块, 提供稳定物品 ID (配置里给每件物品的唯一编号), 基础属性, 套装, 触发动作, 自动更新与 PlaceholderAPI 支持. 你可以把它当作装备成长线的起点: 先生成一件有稳定 ID 的装备, 再交给 Forge, Strengthen, Gem, Attribute 和 Skills 继续扩展
基本信息
| 项目 | 值 |
|---|---|
| 模块版本 | 2.8.16 |
| 主命令 | /emakiitem |
| 别名 | /ei |
| 硬依赖 | EmakiCoreLib |
| 软依赖 | EmakiAttribute, EmakiSkills, MythicMobs, PlaceholderAPI |
| 权限节点 | emakiitem.use, emakiitem.give, emakiitem.browse, emakiitem.inspect, emakiitem.update, emakiitem.reload, emakiitem.debug, emakiitem.admin |
硬依赖 (缺了它模块就无法运行的插件) 必须装上, 否则模块跑不起来; 软依赖不装也能启动, 只是对应的功能不会启用
功能页面
| 页面 | 内容 |
|---|---|
| 命令与权限 | 列出物品和发放物品, 检查手持物与物品组件, 刷新物品与套装, 重载配置与调试 |
| 物品定义与套装 | items/*.yml 与 sets/*.yml 的字段, 以及物品 ID 到游戏内物品 (ItemStack) 的生成规则 |
| 物品浏览 GUI | /ei browse 的两级浏览界面, pack.yml 物品包元数据与槽位类型 |
| 触发器 | 在交互, 攻击, 投射物, 方块, 丢弃等事件中执行动作 |
| 物品更新策略 | 物品定义改动后, 把玩家手里的旧物品更新到新版本 |
| 物品修复系统 | 耐久归零后的禁用状态, 以及材料/货币修复流程 |
| 跨模块集成 | 被 Attribute, Forge, Strengthen, Gem, Skills, Cooking 引用时, 物品来源怎么写 |
| MythicMobs 集成 | 在 MythicMobs 的 Drops 中掉落 EmakiItem 物品 |
| 占位符 | PlaceholderAPI 能取到哪些占位符 |
| CoreLib 动作 | 主手物品的更新, 重绘, 修复, 耐久操作, 以及原版 Data Component 动作 |
| API | 通过 EmakiItemApi 创建, 识别与查询物品, 并扩展自定义 effect 类型 |
| 事件 API | 物品流程中的 Bukkit 事件与可以拦截的位置 |
核心能力
| 能力 | 说明 |
|---|---|
| 稳定物品 ID | 用配置里写的 ID 标识物品, 不靠显示名区分 |
| 物品组件 | 配置材质, 名称, Lore, 模型, 附魔, flags, 耐久等 |
| 属性写入 | 可以向 Attribute 提供属性数据 |
| 技能绑定 | 可以让物品提供技能, 或带上技能解锁信息 |
| 套装系统 | 按已装备的件数触发属性, 技能或 Lore |
| 触发器 | 在交互, 攻击, 投射物, 方块, 丢弃等事件中执行动作 |
| 自动更新 | 玩家登录, 切换手持, 点击背包, 拾取等场景刷新物品 |
| 修复系统 | 耐久归零后进入禁用状态, 可以用材料或货币修复 |
| 浏览界面 | 两级 GUI 按物品包浏览全部物品, 可以直接取出 |
| ID alias 与迁移 | 支持物品 ID 改名映射, 也可以批量迁移配置与玩家背包 |
默认配置目录
text
plugins/EmakiItem/
├── config.yml
├── id_aliases.yml
├── items/
├── sets/
├── gui/
└── lang/你把物品写进 items/, 把套装写进 sets/; gui/ 存放修复界面与两级浏览界面模板 (repair_gui.yml, pack_browser_gui.yml, item_browser_gui.yml), id_aliases.yml 保存物品 ID 改名映射
items/ 下每个子目录都是一个物品包, 你可以在里面放一份 pack.yml, 定义它在浏览界面里的图标, 详见物品浏览 GUI
主配置
config.yml 只放全局设置, 每件物品自己的行为写在各自的定义文件里. 看下表前先记住两点: 「必填」一列问的是插件缺了某个键时会不会自己顶上默认值, 下面这些键都有默认值, 所以全部标「否」; 「取值范围」写的是插件实际的限制, 插件不校验的写「—」
顶层设置
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
version | string | 否 | "2.8.16" | — | 配置文件结构的标记, 由项目的资源同步流程维护, 不是功能开关. 缺失时回退到 2.6.7 |
language | string | 否 | zh_CN | — | 语言文件名, 对应 lang/<language>.yml. 缺失时回退到 zh_CN |
release_default_data | boolean | 否 | true | true / false | 启动时是否释放 items/, sets/ 等内置默认数据; 关掉后只加载已有数据, 不再自动生成缺失的默认示例. 这一项管不到 config.yml 和语言文件 |
yaml
# 发货默认值
version: "2.8.16"
language: "zh_CN"
release_default_data: true使用示例: 切换到英文并停止释放默认示例数据
yaml
language: "en_US"
release_default_data: falsedata_directories
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
data_directories | object | 否 | — | — | 数据目录的扫描设置, 作用于 items/ 与 sets/ |
data_directories.max_depth | int | 否 | 2 | >= 1 (源码按 max(1, 值) 处理) | 子目录可以递归到多深, 算上数据目录本身: 1 只读目录根部那一层的 .yml, 2 再多允许一层子目录, 3 再多允许两层. 超过深度的目录会被跳过, 并记一条警告 |
yaml
# 发货默认值
data_directories:
max_depth: 2使用示例: 允许读取两层子目录 (例如 items/<物品包>/<子目录>/*.yml)
yaml
data_directories:
max_depth: 3set_bonus
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
set_bonus | object | 否 | — | — | 套装加成设置. 套装定义放在 sets/*.yml, 每件物品在自己的定义里声明属于哪个套装, 是哪个部位 |
set_bonus.enabled | boolean | 否 | true | true / false | 是否启用套装加成系统. 关掉后不再计算, 也不再应用任何套装加成 |
set_bonus.refresh_triggers | object | 否 | — | — | 决定什么时候重新计算套装. 玩家装备变化, 背包变化或执行命令时重新数一遍当前已穿戴/持有的套装件数并刷新加成; 没写出来的项按 true 处理 |
set_bonus.refresh_triggers.join | boolean | 否 | true | true / false | 玩家进服时刷新套装状态 |
set_bonus.refresh_triggers.held_change | boolean | 否 | true | true / false | 玩家切换手持物品时刷新 |
set_bonus.refresh_triggers.inventory_click | boolean | 否 | true | true / false | 玩家点击背包时刷新 |
set_bonus.refresh_triggers.inventory_drag | boolean | 否 | true | true / false | 玩家拖拽物品时刷新 |
set_bonus.refresh_triggers.pickup | boolean | 否 | true | true / false | 玩家拾取物品时刷新 |
set_bonus.refresh_triggers.interact | boolean | 否 | true | true / false | 玩家交互时刷新 |
set_bonus.refresh_triggers.command | boolean | 否 | true | true / false | 执行 EmakiItem 相关命令时允许触发套装刷新 |
yaml
# 发货默认值
set_bonus:
enabled: true
refresh_triggers:
join: true
held_change: true
inventory_click: true
inventory_drag: true
pickup: true
interact: true
command: true使用示例: 关掉高频的背包点击与拖拽刷新, 只保留低频触发
yaml
set_bonus:
refresh_triggers:
inventory_click: false
inventory_drag: falseitem_state
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_state | object | 否 | — | — | 物品自定义状态的设置, 数据写在 emaki:item_state 这块 PDC (PDC 是物品自带的附加数据存储) 里, 由 item_state_* 动作段和 API 读写. 这一整段是增量配置: 一个键都不写时, 行为与旧版本一致 |
item_state.clamp | boolean | 否 | true | true / false | 写入值是否按 fields 里声明的 min/max 做钳制. 关掉后只保留溢出保护, 不再按配置钳制 |
item_state.fill_defaults | boolean | 否 | true | true / false | add 操作遇到字段还不存在时, 是否拿 fields 里的 default 当起始值. 关掉后字段缺失就直接拒绝 (reason=missing_state) |
item_state.fields | map | 否 | {} | — | 字段声明, 这里的键名就是状态键名 (写入时统一转成小写). 没在这里声明的字段, 不受钳制, 默认值和阈值的影响 |
item_state.migrations | map | 否 | {} | — | 按 schema (字段结构的版本号) 做的迁移步骤; 空映射表示不迁移 |
item_state.preservation | object | 否 | — | — | 状态保全策略 |
item_state.derivation | object | 否 | — | — | 由状态变化触发的派生刷新 |
item_state.fields
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_state.fields.<key> | object | 否 | — | — | 单个字段声明, <key> 就是状态键名 |
item_state.fields.<key>.type | string | 否 | double | INTEGER / LONG / DOUBLE / BOOLEAN / STRING (大小写不敏感) | 字段类型. 留空或写了不认识的值, 会让这个字段整体被跳过; min/max/thresholds 只对数值类型 (INTEGER, LONG, DOUBLE) 生效 |
item_state.fields.<key>.default | 标量 | 否 | 无 | 需能被 type 强转 | 字段不存在, 且 fill_defaults 开着时, 拿它当 add 的起始值. 值没法转成 type 指定的类型时, 就等于没有默认值 |
item_state.fields.<key>.min | number | 否 | 无 | 数值 | 钳制下界, 只在 clamp 开启且字段是数值类型时生效 |
item_state.fields.<key>.max | number | 否 | 无 | 数值 | 钳制上界 |
item_state.fields.<key>.thresholds | map | 否 | {} | — | 阈值集合, 键是阈值 ID. 每个字段最多保留按 value 从小到大排最靠前的 64 个, 跟书写顺序无关; 阈值集合一变, 这个字段的 once 记录就会被重新武装 |
item_state.fields.<key>.thresholds.<id>.value | number | 是 | 无 | 数值 | 触发阈值. 缺了这一项的阈值条目会被丢弃 |
item_state.fields.<key>.thresholds.<id>.once | boolean | 否 | false | true / false | 是否只奖励一次, 直到被重新武装 |
item_state.fields.<key>.thresholds.<id>.reward_on_fall | boolean | 否 | false | true / false | 数值向下跨过阈值时是否也触发 |
item_state.fields.<key>.thresholds.<id>.actions | list | 否 | 空 | — | 跨过阈值时执行的动作列表 |
item_state.fields.<key>.thresholds.<id>.message_key | string | 否 | "" | — | 阈值提示使用的语言键 |
item_state.fields.<key>.thresholds.<id>.sound | string | 否 | "" | — | 跨过阈值时播放的音效 |
item_state.fields.<key>.thresholds.<id>.sound_volume | double | 否 | 1.0 | — | 音效音量 |
item_state.fields.<key>.thresholds.<id>.sound_pitch | double | 否 | 1.0 | — | 音效音高 |
item_state.fields.<key>.thresholds.<id>.refresh_derived | boolean | 否 | true | true / false | 该阈值触发后是否执行派生刷新 |
item_state.migrations
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_state.migrations.<key> | object | 否 | — | — | 单个迁移步骤, <key> 只作标识 |
item_state.migrations.<key>.from | int | 是 | 无 | — | 起始 schema 版本. 缺失, 或 to <= from 时该步被跳过 |
item_state.migrations.<key>.to | int | 是 | 无 | > from | 目标 schema 版本 |
item_state.migrations.<key>.rename | map | 否 | 空 | — | 字段重命名, 写法 旧字段名: 新字段名; 源名与目标名相同的条目会被忽略 |
item_state.migrations.<key>.retype | map | 否 | 空 | 目标类型同 type | 字段改类型, 写法 字段名: 类型 |
item_state.migrations.<key>.drop | list | 否 | 空 | — | 要丢弃的字段名列表 |
item_state.preservation
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_state.preservation.verify_rebuild | boolean | 否 | true | true / false | 物品 rebuild (重建) 之后再检查一次状态还在不在, 丢了的话用重建前的快照补回去; 只有确实丢了才写入, 正常路径什么都不做 |
item_state.preservation.repair_on_pickup | boolean | 否 | false | true / false | 拾取时修复损坏的状态元数据 |
item_state.preservation.repair_on_drop | boolean | 否 | false | true / false | 丢弃时修复损坏的状态元数据 |
item_state.preservation.repair_on_trade | boolean | 否 | false | true / false | 交易时修复损坏的状态元数据 |
item_state.preservation.repair_on_container_transfer | boolean | 否 | false | true / false | 容器转移时修复损坏的状态元数据 |
item_state.preservation.repair_on_join | boolean | 否 | false | true / false | 玩家进服时修复损坏的状态元数据 |
item_state.derivation
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_state.derivation.enabled | boolean | 否 | false | true / false | 派生刷新的总开关. 默认关闭, 免得给已经在跑的服务器增加额外的刷新负担 |
item_state.derivation.refresh_lore | boolean | 否 | true | true / false | 派生刷新时刷新套装 Lore |
item_state.derivation.refresh_attributes | boolean | 否 | true | true / false | 派生刷新时同步属性 |
item_state.derivation.scan_holder | boolean | 否 | true | true / false | 缺少持有者信息时, 允许扫描在线玩家来定位物品 |
item_state.derivation.max_depth | int | 否 | 2 | 1 ~ 8 (源码按 clamp(值, 1, 8) 处理) | 派生刷新与阈值奖励的最大递归层数, 用来挡住自己触发自己的循环 |
yaml
# 发货默认值
item_state:
clamp: true
fill_defaults: true
preservation:
verify_rebuild: true
repair_on_pickup: false
repair_on_drop: false
repair_on_trade: false
repair_on_container_transfer: false
repair_on_join: false
derivation:
enabled: false
refresh_lore: true
refresh_attributes: true
scan_holder: true
max_depth: 2使用示例: 声明一个带阈值的击杀计数, 并按 schema 版本迁移旧字段
yaml
item_state:
fields:
kills:
type: INTEGER
default: 0
min: 0
max: 9999
thresholds:
novice:
value: 10
once: true
message_key: "state.kills.novice"
sound: "minecraft:entity.player.levelup"
sound_volume: 1.0
sound_pitch: 1.2
veteran:
value: 100
actions:
- 'send_message text="<gold>连杀达标</gold>"'
migrations:
"1":
from: 0
to: 1
rename:
kill_count: kills
retype:
kills: LONG
drop:
- legacy_tagproficiency_guard
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
proficiency_guard | object | 否 | — | — | 熟练度派发的防刷设置, 作用于 damage_dealt / kill_entity / kill_player 的槽位派发. 除 dedupe_per_event 外, 其他项默认都是关闭或无限, 不会改变服务器原本的熟练度获取速度 |
proficiency_guard.dedupe_per_event | boolean | 否 | true | true / false | 同一种物品定义在一次事件里只派发一次, 修掉「同一定义同时装在多个槽位时, 每个槽各触发一次」的问题 |
proficiency_guard.max_dispatches_per_event | int | 否 | 0 | >= 0 (源码按 max(0, 值) 处理); 0 表示不限制 | 单次事件最多派发多少次 |
proficiency_guard.same_target_cooldown_seconds | number | 否 | 0 | >= 0 (内部换算为毫秒); 0 表示无冷却 | 对同一目标的冷却秒数 |
proficiency_guard.daily_soft_cap | int | 否 | 0 | >= 0 (源码按 max(0, 值) 处理); 0 表示无上限 | 每日软上限. 计数只放在内存里, 按服务器本地日期跨天重置, 重启后不会保留 |
proficiency_guard.decay_factor | double | 否 | 1.0 | (0, 1]; 越界或非有限值回退 1.0 | 超过软上限后的递减系数. 1.0 表示不递减 (超限直接拒绝) |
proficiency_guard.decay_minimum_ratio | double | 否 | 0.0 | [0, 1] (源码按 clamp 处理) | 递减之后最低的通过概率下限 |
proficiency_guard.guarded_triggers | list | 否 | damage_dealt, kill_entity, kill_player | — | 受这一段约束的触发器名单; 留空时回退到默认那三项 |
yaml
# 发货默认值
proficiency_guard:
dedupe_per_event: true
max_dispatches_per_event: 0
same_target_cooldown_seconds: 0
daily_soft_cap: 0
decay_factor: 1.0
decay_minimum_ratio: 0.0
guarded_triggers:
- "damage_dealt"
- "kill_entity"
- "kill_player"使用示例: 限制单次事件派发次数, 并对同一目标加 1 秒冷却
yaml
proficiency_guard:
max_dispatches_per_event: 3
same_target_cooldown_seconds: 1mythicmobs
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
mythicmobs | object | 否 | — | — | MythicMobs 集成设置. 没装 MythicMobs 时会自动跳过, 不影响其他功能 |
mythicmobs.enabled | boolean | 否 | true | true / false | MythicMobs 集成的总开关. 关掉后不注册任何 Drop |
mythicmobs.drops | object | 否 | — | — | 自定义 Drop 设置 |
mythicmobs.drops.enabled | boolean | 否 | true | true / false | 是否注册 MythicMobs 自定义 Drop |
mythicmobs.drops.names | list | 否 | emakiitem, ei_item | — | 能识别的 Drop 名称; 留空时回退到默认值 |
yaml
# 发货默认值
mythicmobs:
enabled: true
drops:
enabled: true
names:
- "emakiitem"
- "ei_item"使用示例: 只用自定义的 Drop 名称
yaml
mythicmobs:
drops:
names:
- "emakiitem"相互作用
先记住分工: set_bonus.refresh_triggers 管的是套装状态的刷新; 物品的自动更新由物品定义里的 update.triggers 单独控制, 两者互不覆盖
item_state.* 作用于 emaki:item_state 这块 PDC (插件自定义数据, 即物品身上由插件写入的隐藏字段), 由 item_state_* 动作段和 API 读写, 全部是增量配置: 你一个键都不写时, 行为与旧版本一致. proficiency_guard.* 作用于 damage_dealt, kill_entity, kill_player 的槽位派发, 除 dedupe_per_event 外其他项默认都是关闭或无限
典型物品生命周期
- 你在
items/里定义物品 ID, 材质, 名称, Lore 和组件 - 需要的话, 再写入 Attribute 属性, Skills 技能或 set 信息
- 用命令把物品发放给玩家
- 玩家穿上或使用这件装备
- 到了触发时机, Item 自动更新这件物品的状态
- 之后 Forge / Strengthen / Gem 还可以继续在这件物品上写入自己那层数据
- 最后由 CoreLib 统一重建展示效果
与其他模块的关系
| 模块 | 协作方式 |
|---|---|
| EmakiAttribute | Item 写入基础属性或套装属性 |
| EmakiSkills | Item 写入装备技能 ID 与装备强制触发器; PDC 键由独立的协议模块统一持有, 不依赖 EmakiSkills 是否启用 |
| EmakiForge | Forge 可以改造 EmakiItem 生成的装备 |
| EmakiStrengthen | Strengthen 可以强化 EmakiItem 装备 |
| EmakiGem | Gem 可以给 EmakiItem 装备开孔和镶嵌 |
| MythicMobs | MythicMobs 怪物可以通过 Drops 掉落 EmakiItem 物品 |