简体中文
公开 API
编译依赖
xml
<repositories><repository><id>jiuwu-releases</id><url>https://repo.crypticlib.com/repository/maven-public/</url></repository></repositories>
<dependency><groupId>emaki.jiuwu.craft</groupId><artifactId>emaki-skills-api</artifactId><version>2.8.7</version><scope>provided</scope></dependency>kotlin
repositories { maven("https://repo.crypticlib.com/repository/maven-public/") }
dependencies { compileOnly("emaki.jiuwu.craft:emaki-skills-api:2.8.7") }仅编译依赖
runtime 已内嵌未 relocate 的 facade, 模型和事件类. 不要安装, bundle, shade 或 relocate API Jar; PDC codec 可独立调用也不改变此规则
门面与分层
可用性检查以 EmakiSkillsApi.status().usable() 为准. catalog(), operations(), extensions() 永不为 null: 桥缺失时返回稳定的不可用实现; install, uninstall, Bridge 为 runtime 内部接口约定. 访问器开销很低且桥会随重载替换, 因此应在使用点解析分层, 不得缓存到字段
catalog
catalog() 返回技能定义, 玩家技能视图, 等级, 已学习状态, cast mode 与最大等级判断:
| 方法 | 线程 | 说明 |
|---|---|---|
skills() | 任意线程 | 全部已加载技能定义快照 (含已禁用定义), 按规范 id 排序 |
skill(String skillId) | 任意线程 | 查询单个定义; id 为空或未找到时返回空 Optional |
playerSkills(Player) | 玩家 owner thread | 读取槽位绑定与 cast mode 快照; 档案未加载时返回 NOT_FOUND |
level(Player, String) | 玩家 owner thread | 读取等级, 夹取到 [1, maxLevel] |
upgradePreview(Player, String) | 玩家 owner thread | 报价下一次升级: 目标等级, 成功率, 货币与材料消耗. 只是报价, 不扣费也不锁定 |
hasLearned(Player, String) | 玩家 owner thread | 仅判断"手动解锁来源"是否包含该技能, 不代表玩家能否使用 |
castModeEnabled(Player) | 玩家 owner thread | 读取 cast mode 开关 |
atMaxLevel(Player, String) | 玩家 owner thread | 是否已达最大等级. 未开启升级的技能最大等级为 1 |
线程约束: 在非 owner thread 调用玩家查询, 返回 WRONG_THREAD
Operations
异步施法方法为 cast(Player,String) 与 castByTrigger(Player,String), 均返回 CompletableFuture<EmakiResult<SkillCastOutcome>>. 两者可从任意线程提交; runtime 负责切换到玩家 owner thread 执行 Bukkit, pre/post event, 资源和冷却阶段. future callback 不保证仍在 owner thread, 后续操作玩家必须自行切回
learn, forget, forgetAll, equip, unequip, bindTrigger, upgrade, setLevel, addLevel, setCastMode 均为同步方法, 必须在玩家 owner thread 调用. 升级摇点失败是成功完成的流程, 由 SkillUpgradeOutcome.successfulRoll()==false 表示, 而非外层 Failure. setLevel 低于 1 返回 INVALID_INPUT, 超过上限按上限夹取
Extensions
extensions() 注册两类扩展点: 外部技能来源与外部技能定义:
registerSkillSource(Plugin owner, SkillSourceProvider provider)返回SkillSourceRegistration; 同 owner 同 provider id 的新注册替换旧注册, 关闭陈旧 handle 不删除替代项, owner disable 时自动清理.owner为空或已禁用,id()为空, 返回的都是不生效的空 handleSkillSourceProvider.id()在 owner 内唯一,priority()数值小者优先 (默认100),collect(Player)在玩家 owner thread 同步调用, 实现必须足够快且不得访问其他实体或区域的状态
外部技能定义
registerSkillDefinition(Plugin owner, ExternalSkillDefinition definition) 返回 SkillDefinitionRegistration; unregisterSkillDefinitions(Plugin owner) 移除该插件注册的全部外部定义
ExternalSkillDefinition 为接口, 仅 id() 是抽象方法, 其余访问器均带默认实现:
| 方法 | 默认 | 说明 |
|---|---|---|
id() | 必填 | 规范技能 id; 归一化同 YAML 技能 id (trim, 按 Locale.ROOT 小写, 空格转下划线). 空白 id 使注册不生效 |
displayName() | 回退 id() | UI 显示名 |
description() | 空列表 | 技能 UI 中的说明行 |
iconMaterial() | "" | 作为技能图标的材质名 |
activationType() | "ACTIVE" | ACTIVE / PASSIVE, 大小写不敏感; 无法识别时按 ACTIVE 处理 |
passiveTriggers() | 空列表 | 被动技能响应的触发器 id; 主动技能忽略 |
cooldownTicks() | 0 | 施法冷却 (tick); 小于 0 夹取为 0 |
globalCooldownTicks() | 0 | 该技能施加的共享冷却 (tick); 小于 0 夹取为 0 |
scriptLines() | 空 map | 各脚本阶段的 CoreLib 动作行, key 为阶段名; 识别的阶段为 cast, hit, miss, fail (大小写不敏感), 其他 key 忽略; 写法与 YAML 技能的 script.actions 一致. 空 map 关闭原生管道 |
scriptConditions() | 空 map | 各阶段的前置条件, key 与语法同 scriptLines(); 条件通过该阶段才执行 |
tags() | 空列表 | 用于筛选与装备限制的标签 |
loreAliases() | 空列表 | 从物品 Lore 解锁该技能的别名 |
pdcSkillId() | "" | 用于装备匹配的持久化技能 id; 空则使用 id() |
uiCategory() | "default" | 技能所属 UI 分类; 空白回退 default |
sortOrder() | 0 | 分类内显示顺序, 数值小者靠前 |
showInSlots() | true | 是否出现在技能槽 UI |
enabled() | true | 是否启用; 禁用的定义仍保持注册, 但不计为已解锁且无法施放 |
mythicSkill() | "" | 要施放的 MythicMobs 技能名; 仅在 scriptLines() 为空时使用 |
行为边界 (注册前后均须核对):
- 注册的定义与
skills/里的 YAML 技能同等参与施法, 槽位绑定, 等级与升级查询, 技能来源收集以及SkillCatalog的返回; 同一 id 下注册定义覆盖 YAML 技能 - 同一 owner 同一 id 重复注册是替换; owner 禁用时其全部注册被清理, 关闭 handle 可提前注销
- 注册或移除定义会丢弃已编译的技能管道, 替换在下次施法即生效, 无需
/eskills reload; 只要 owner 保持启用, 定义在配置重载后仍然存活 - 访问器会被 runtime 反复读取 (包括在玩家 owner thread 上), 并把映射结果保留到注册变化为止, 因此必须返回稳定, 无副作用的值: 定义只构建一次, 每次调用返回同样的值
- 该接口不暴露升级表, cron, 参数声明, 资源消耗与条件 DSL, 因此代码定义的技能没有升级路径, 也没有声明式消耗或条件模型, 需要时用自定义阶段实现; 其脚本也不在配置预检的覆盖范围内
scriptLines()为空且mythicSkill()指定了技能名时, 改为经 MythicMobs 施放owner为空或已禁用,definition为 null,id()空白或抛异常, 或定义无法映射时, 返回不生效的空 handle; EmakiSkills 不可用时同样返回空 handle
脚本动作注册表已移除
技能脚本即 CoreLib 管道, 因此第三方不能再向 EmakiSkills 注册脚本动作段. 新增动作段必须改用 CoreLib 的 stage 注册表注册 (EmakiCoreLibApi.registerActionStage), 注册后所有模块都能使用. EmakiSkills 自己注册的十二个段见 CoreLib 动作
EquipmentSkillPdcCodec 提供底层 payload read/write/copy/clear; 实时装备读写仍受 owner-thread 约束
结果说明
无负载成功使用 EmakiResult<Unit>; 可选负载通过 optionalValue() 读取. 结果工厂为 success, partial, failure. FailureKind 精确取值为 UNAVAILABLE, NOT_FOUND, INVALID_INPUT, REJECTED, CANCELLED, TARGET_OFFLINE, WRONG_THREAD, INTERNAL_ERROR. 可用性必须通过 status() 或 FailureKind 判断, 禁止以捕获 NullPointerException 作为判断手段