Skip to content

技能定义 ​

技能定义文件这样写: 每一项字段是什么意思, 默认值是多少, 能填哪些值

一个技能一个文件, 放在 plugins/EmakiSkills/skills/*.yml. 你只需要在技能文件里写「技能本身是什么」这类管理信息 (名字, 冷却, 消耗, 升级等), 真正的技能效果交给原生脚本系统或 MythicMobs 执行. 本地资源定义放在 plugins/EmakiSkills/resources/*.yml

加载规则 ​

  • 一份文件只加载一个技能; 文件里的 id 写成空值时, 整份文件会被跳过, 并计入加载问题
  • 想临时停用某个技能, 把它设为 enabled: false 就行, 不会进注册表, 等于这个技能不存在
  • 技能 id 会统一转成小写; 列表字段里的 id 也一样处理, 并把 - 换成 _
  • 列表字段支持别名键 (见下表), 两个位置都写时会按顺序合并并去重

顶层字段 ​

yaml
id: "fireball"
enabled: true
display_name: "<red>火球术"
description:
  - "<gray>向前方释放一枚火球。"
icon_material: "fire_charge"
mythic_skill: "EmakiFireball"
trigger_type: "active"
cooldown_ticks: 100
global_cooldown_ticks: 20
字段类型必填默认值取值范围说明
idstring是—非空; 转小写技能的唯一 ID. 写成空值会让整份文件被跳过
enabledboolean否truetrue / false是否启用. 填 false 时技能不加载, 等于不存在
display_namestring否id任意 MiniMessage 文本显示名, 用在 GUI, ActionBar 和反馈文案的 %skill% 里
descriptionlist<\string>否[]—技能描述, 分行写在 GUI 里显示
icon_materialstring否""Bukkit Material 名 (转小写)GUI 图标的材质. 留空时用槽位配置里的材质, 都没有就用内置的备用材质
mythic_skillstring否""MythicMobs 技能 idmythic / hybrid 模式下要执行的 MythicMobs 技能, 非玩家施法者那条路径也用它
trigger_typestring否"active"active / passive (其他值一律按 active)主动技能还是被动技能
passive_triggerslist<\string>否[]已注册的被动触发器 id被动技能的事件来源. 没注册的 id 在派发时会被直接丢掉, 不会报错
cron_expressionstring否""Quartz cron 表达式填了非空值时, 会自动注册一个 cron_<id> 被动触发器并加进 passive_triggers; 格式见 CoreLib 表达式 - Cron 表达式
cron_max_executionsinteger否0≥ 0, 负数按 0cron 触发器总共能触发几次; 0 表示不限
variablesmap否{}键名不以 emaki_ 开头运行时变量块, 写法见 变量类型
scriptmap否禁用—原生脚本块, 写法见 原生脚本系统
upgrademap否禁用—升级规则, 见下文
cooldown_ticksinteger否0≥ 0, 负数按 0技能自己的冷却, 单位是 tick (20 tick = 1 秒)
global_cooldown_ticksinteger否0≥ 0, 负数按 0全局冷却, 单位 tick; 释放后所有技能共用这个冷却
resource_costslist<\map>否[]—资源消耗或资源检查, 条目字段见下文
lore_aliaseslist<\string>否[]—从装备的 Lore 里认出这个技能时要匹配的别名
pdc_skill_idstring否id—从装备的 PDC 里认出这个技能时用的 ID
tagslist<\string>否[]命中 skill_tags.equip_limits 时受数量限制技能标签, 用来做装备数量限制和分类筛选
tab_tagslist<\string>否[]别名 tabTagsGUI 页签标签
required_skillslist<\string>否[]别名 dependencies装备这个技能前必须先装备好的技能 ID
conflicting_skillslist<\string>否[]别名 conflicts不能和这个技能同时装备的技能 ID
ui_categorystring否"default"—GUI 分类
sort_orderinteger否0越小越靠前GUI 排序, 数值越小越靠前
show_in_slotsboolean否truetrue / false是否允许它出现在玩家的主动技能槽选择列表里. 强制触发器的技能常设为 false
conditionmap否无—技能释放 (和升级) 的条件块, 见下文

condition 条件块 ​

技能释放和升级共用同一套条件块. 条件表达式在计算前会先交给 PlaceholderAPI 渲染

yaml
condition:
  type: "all_of"
  entries:
    - "%player_level% >= 5"
    - "%emakiskills_level_fireball% >= 2"
字段类型必填默认值取值范围说明
conditionmap否无—条件块. 必须写成映射节点; 缺了 entries 就当成没有条件
condition.typestring否all_ofall_of, any_of, none_of, at_least, exactly多个条件怎么组合
condition.entrieslist<\string>否[]表达式字符串条件表达式列表; 不写这个键, 整块条件就是空的
condition.required_countinteger否0≥ 0at_least / exactly 这两种组合方式下, 需要命中的条件数量
condition.invalid_as_failureboolean否truetrue / false由通用条件解析器读取; EmakiSkills 的释放和升级路径固定按「表达式不合法就算不通过」处理
condition.on_pass.actions / condition.on_fail.actionslist<\string>否[]—由通用条件解析器读取; EmakiSkills 的技能不用这些字段
condition.on_fail.block_output / condition.on_fail.messageboolean / string否false / ""—同上, EmakiSkills 的技能不用

条件没解析出来就当不通过: 技能不会释放, 升级也会被拒绝. 释放失败的反馈键是 cast.condition_not_met, 升级失败的反馈键是 upgrade.condition_not_met

条件文本会先交给 PlaceholderAPI 渲染, 所以条件里写的 %...% 必须能被当前装的 PlaceholderAPI 扩展认出来 (例如 %emakiskills_level_fireball%); 认不出的占位符会原样进入表达式计算, 按上一条规则判为不通过

变量与脚本 ​

  • variables: 运行时变量, 写法和类型见 变量类型. 写脚本行, 条件和文本时用 %var.<变量名>% 引用它
  • script: 原生脚本块, 键位和阶段见 原生脚本系统
yaml
variables:
  fire_damage:
    type: expression
    value: "10 + %level% * 5"
  battle_cry:
    type: random_text
    lines:
      - "<red>燃烧吧!"
      - "<red>烈焰之力!"

script:
  mode: native          # native / mythic / hybrid
  stop_on_failure: true
  actions:
    cast:
      - 'trigger | damage amount=%var.fire_damage%'
    hit:
      - 'trigger | ignite duration=3s'

resource_costs 资源消耗 ​

yaml
resource_costs:
  - type: "ea-resource"
    target_id: "mana"
    amount: 20
    operation: "consume"
    failure_message: "<red>法力不足。"
字段类型必填默认值取值范围说明
typestring是—ea-resource, attribute-check (别名 ea-attribute-check), local-resource, auraskills-mana (别名 aura-skills-mana, aura-mana), mythiclib-mana (别名 mmocore-mana, mythic-mana)资源类型. 认不出的取值会让整条被丢掉
target_idstring否""资源 / 属性 ID对应的本地资源, Attribute 资源或属性 ID
amountdouble否0≥ 0, 负数按 0要检查或扣除的数量
operationstring否consumeconsume (扣除), require (只检查)其他取值按 consume 处理
failure_messagestring否""MiniMessage, 经 PlaceholderAPI 渲染不够时的提示; 留空时回退成 target_id 这段文字

要注意插件不在时的行为: auraskills-mana 要求装了 AuraSkills, mythiclib-mana 要求装了 MythicLib 或 MMOCore; 对应插件不在时这一条就当成不可用, 检查直接放行, 扣除会被跳过. ea-resource 和 attribute-check 在 EmakiAttribute 不可用时同样直接放行. attribute-check 永远不扣除

本地资源文件 ​

resources/*.yml 用来定义 local-resource 用的资源. 资源 ID 取文件里写的 id, 和文件名无关

yaml
id: "mana"
display_name: "<gradient:#4DA6FF:#00BFFF>魔力</gradient>"
max: 100.0
default_current: 100.0
regen_amount: 2.0
regen_interval_ticks: 20
clamp_min: 0.0
clamp_max: 100.0
字段类型必填默认值取值范围说明
idstring是—非空; 转小写资源唯一 ID; 空值会让整份文件被跳过
display_namestring否idMiniMessage显示名
maxdouble否100.0≥ 0, 负数按 0这个资源能到达的最大值
default_currentdouble否100.0≥ 0, 负数按 0玩家第一次加载时的当前值
regen_amountdouble否0.0≥ 0, 负数按 0每次自然回复增加多少
regen_interval_ticksinteger否0≥ 0, 负数按 0回复间隔, 单位 tick; 0 表示不回复
clamp_mindouble否0.0≥ 0, 负数按 0当前值的下限
clamp_maxdouble否0.0<= 0 时回退 max, 否则 ≥ clamp_min当前值的上限

本地资源与其他资源系统

本地资源只存在技能自己的数据里, 不会自动和 EmakiAttribute 互通. 如果你已经在用 EA 维护同名资源, 技能费用就改用 ea-resource, 免得两套数值并存

升级配置 ​

yaml
upgrade:
  enabled: true
  max_level: 5
  gui_template: "upgrade_gui"
  failure_penalty: "none"
  economy:
    enabled: true
    currencies:
      - provider: "vault"
        currency_id: ""
        base_cost: 1200
        cost_formula: "%base_cost% * %target_level%"
        display_name: "<gold>金币</gold>"
  success_rates:
    2: 100.0
    3: 90.0
  levels:
    2:
      materials:
        - item_sources:
            - "minecraft-blaze_powder"
          amount: 2
      actions:
        success:
          - 'send_message text="<yellow>火球术更强了。</yellow>"'
字段类型必填默认值取值范围说明
upgrade.enabledboolean否falsetrue / false是否启用升级. 关掉时最大等级就是 1
upgrade.max_levelinteger否1≥ 1, 小于 1 被抬升为 1最大等级, 也是 level 命令和 API 能取到的上限
upgrade.gui_templatestring否upgrade_guigui/ 下的模板名升级 GUI 用的模板. 留空, 等于 upgrade_gui, 或指向不存在的模板时, 都会回退到 upgrade_gui (模板不存在会记一条警告)
upgrade.failure_penaltystring否nonenone / downgrade升级失败的惩罚. 只有 downgrade 会真的降一级 (最低降到 1 级). 写 reset 只会影响 GUI 文案, 不会重置等级
upgrade.economy.enabledboolean否falsetrue / false是否启用经济消耗
upgrade.economy.currencieslist<\map>否[]—货币列表, 字段见下
upgrade.success_ratesmap<int,double>否100.0键为 > 0 的整数, 值夹取到 0~100按目标等级配置的成功率; 没配的等级按 100 算. 键是非正数或非整数时会被跳过
upgrade.levelsmap<int,map>否{}键为 > 1 的整数映射节点按目标等级覆盖材料, 经济, 成功率和升级动作

upgrade.economy.currencies 每项:

字段类型必填默认值取值范围说明
providerstring否auto (转小写)经济提供者名经济来源; 留空按 auto 交给 CoreLib 去选
currency_idstring否""—货币 ID
base_costdouble否0≥ 0, 负数按 0cost_formula 里 %base_cost% 的取值
cost_formulastring否%base_cost%表达式实际消耗的表达式. 可以按 %base_cost%, %level% (当前等级), %target_level%, %max_level% 来算; 结果 ≤ 0 的条目不参与消耗
display_namestring否""MiniMessage显示名; 留空回退成 currency_id, 再留空回退成 provider

upgrade.levels.<n> 每项 (<n> 为目标等级, 必须 > 1):

字段类型必填默认值取值范围说明
levels.<n>.materialslist<\map>否[]—这一级需要的物品材料, 字段见下
levels.<n>.economy.enabledboolean否truetrue / false这一级是否把经济配置覆盖成「启用」
levels.<n>.economy.currencieslist<\map>否[]同 upgrade.economy.currencies这一级的货币覆盖列表; enabled: false 时这一级不收费
levels.<n>.success_ratedouble否取 upgrade.success_rates夹取到 0~100这一级的成功率覆盖, 优先于 upgrade.success_rates
levels.<n>.actions.successlist<\string>否[]动作管道行升级成功后执行的动作
levels.<n>.actions.failurelist<\string>否[]动作管道行升级失败后执行的动作 (包括摇点失败和降级)

levels.<n>.materials 每项:

字段类型必填默认值取值范围说明
item_sourceslist<\string>否""物品源写法, 见 物品匹配器允许的物品源; 只取列表里第一项作为物品标识. 与同级的 matcher 取 AND
matchermap否无组件 / PDC / Lore 条件非物品源条件. matcher 里不能再写物品源
amountinteger否1≥ 1, 0 按 1需要几个
optionalboolean否falsetrue / false会被解析, 但当前升级判定和扣除流程不读这个字段
protectionboolean否falsetrue / false会被解析, 但当前升级判定和扣除流程不读这个字段

item_sources 和 matcher 都省略时, 这个材料永远匹配不上, 也就等于不需要它. 同类的 item_sources 条目在扣除时会合并累加; 带 matcher 的条目各自独立

升级流程与 GUI ​

  • 先算目标等级 (当前等级加 1), 再被 max_level 卡住上限; 技能必须已经解锁, 且 upgrade.enabled: true
  • 流程顺序是: 检查条件 → 触发 SkillPreUpgradeEvent (可取消, 也能改成功率) → 检查消耗 → 扣除消耗 → 摇点 → 应用等级或失败惩罚
  • 消耗在摇点之前就扣掉了: 摇点失败也不会退还已经扣掉的货币和材料 (只有提交阶段出异常时才会尝试补偿回滚)
  • 玩家看到的反馈来自 lang/<language>.yml 的 upgrade.* 文案键 (例如 upgrade.success, upgrade.failed, upgrade.insufficient_funds)

升级 GUI 由 upgrade.gui_template 指定的模板渲染, 你在槽位里写的 type 决定它显示什么:

槽位 type显示内容
skill_display技能图标和名称, 可替换的变量有等级, 成功率, 失败惩罚文案
cost_currency货币消耗清单; 没有消耗时显示 gui.upgrade_cost_free. 变量有 %currencies%, %currency_count%
cost_material材料消耗清单, 逐项显示「已有/需要」并按是否满足上色; 变量有 %materials%, %material_count%, %missing_count%
success_rate成功率标题, 变量有 %success_rate%
confirm确认按钮; 按未开启升级 / 已满级 / 材料不足 / 可升级切换图标和状态文案. 点击后调用的和命令是同一套升级服务

不用担心报价和实际扣费对不上: GUI 和升级流程用的是同一个报价函数 (算这次升级要花多少东西的函数, preview). GUI 渲染时按当前状态展示消耗, 点升级时重新报一次价并按结果实际扣除, 所以玩家状态没变的时候两边数值一样; 如果在点击之前状态已经变了 (例如材料被用掉), 就以点击时重新报的价和实际扣除为准, 不够的话整笔失败, 也不会扣费

config.yml 中的来源与标签 ​

下面这两项要写在 plugins/EmakiSkills/config.yml, 它们决定技能怎么被认出来, 以及玩家最多能装备几个

装备技能来源开关 ​

yaml
skill_sources:
  read_lore_skills: true
  read_pdc_skills: true
  require_lore_pdc_match: false
字段类型必填默认值取值范围说明
skill_sources.read_lore_skillsboolean否truetrue / false是否从装备的 Lore 里读技能
skill_sources.read_pdc_skillsboolean否truetrue / false是否从装备的 PDC 里读技能
skill_sources.require_lore_pdc_matchboolean否falsetrue / false严格模式. 开启后只保留同一物品, 同一槽位下 Lore 和 PDC 的交集, 两边对不上的技能不生效

记住: 两侧都关闭, 或开启严格模式却只开启了一侧时, 配置预检会给出警告

标签装备数量限制 ​

当技能定义里的 tags 命中了这里的标签, 玩家最多就只能同时装备对应的数量:

yaml
skill_tags:
  equip_limits:
    ultimate: 1
    mobility: 2
字段类型必填默认值取值范围说明
skill_tags.equip_limits.<tag>integer否无 (不限)> 0, <= 0 或非整数时忽略该键这个标签最多能同时装备几个. 标签名会被规范化, 并把 - 换成 _
tag_limitsmap否无同上旧键名. skill_tags.equip_limits 为空时回退读这个键

照上面的配置, 带 ultimate 标签的技能最多装备 1 个, 带 mobility 的最多装备 2 个. 没列出来的标签不受限制

最小示例 ​

yaml
id: fireball
enabled: true
display_name: '<red>火球术'
description:
  - '<gray>向前方释放一枚火球。'
icon_material: FIRE_CHARGE
mythic_skill: EmakiFireball
trigger_type: active
cooldown_ticks: 100
global_cooldown_ticks: 20
resource_costs:
  - type: ea-resource
    target_id: mana
    amount: 20
    operation: consume
    failure_message: '<red>法力不足。'