Skip to content

套装(Set)

所属:服主指南 · 相关:属性与数值 · 动作系统

套装让多件物品组合穿戴后激活额外加成(属性 / 药水效果 / 主动技能),按穿戴件数分级触发。配置文件:plugins/QinhItems/sets/*.yml


1. 数据模型

kotlin
data class SetDefinition(
    val id: String,
    val displayName: String,                 // MiniMessage
    val icon: String,                        // 材质名(编辑器图标)
    val belongingPieces: List<String>,       // 成员物品 ID / 前缀
    val lore: List<String>,                  // 套装描述
    val bonuses: List<SetBonus>,             // 按件数分级的加成
    val loreFormat: SetLoreFormat? = null,   // 自定义 Lore 模板
)

data class SetBonus(
    val pieces: Int,                         // 激活所需件数
    val name: String,
    val lore: List<String>,                  // 激活时显示
    val effects: Map<String,Int>,            // 药水效果 名→等级(0=I)
    val attributes: Map<String,Double>,      // 属性加成(累加)
    val abilities: List<SetAbility>,         // 主动 / 事件技能
)

data class SetAbility(
    val trigger: String,                     // right_click / on_damage / on_kill …
    val refs: List<ActionRef>,               // 动作处理器引用
    val cooldownMs: Long = 0L,
)

2. YAML 完整示例

yaml
warrior_bloodlust:                          # 套装 ID
  display_name: "<red>血色狂暴</red>"
  icon: NETHERITE_SWORD
  belonging_pieces:                          # 成员:精确 ID 或前缀
    - "warrior_helmet"
    - "warrior_chestplate"
    - "warrior_leggings"
    - "warrior_boots"
    - "warrior_sword"
    - "warrior"                              # 前缀:warrior_xxx 都算
  lore:
    - "<gray>传说中的战士套装</gray>"
    - "<gray>集齐套装可激活特殊效果</gray>"
  bonuses:
    - pieces: 2                              # 2 件激活
      name: "战士之心"
      lore:
        - "<blue>+5 物理伤害</blue>"
      attributes:
        物理伤害: 5
    - pieces: 4                              # 4 件激活(与 2 件累加)
      name: "狂暴之力"
      lore:
        - "<blue>累计 +15 物理伤害</blue>"
        - "<green>+100 生命</green>"
      attributes:
        物理伤害: 10                         # 4 件总计 5+10=15
        生命: 100
      effects:
        SPEED: 1                             # 急迫 II(0=I)
        STRENGTH: 0
      abilities:
        - trigger: right_click               # 手持≥4件右键触发
          cooldown: 5s
          actions:
            - handler: "qinhskills:cast"
              payload: "套装爆发技能名"
        - trigger: on_damage                 # 造成伤害时触发
          cooldown: 3s
          actions:
            - handler: "qinhskills:cast"
              payload: "命中反击技能名"

3. 加成如何叠加

  • 属性累加:穿 4 件 → 同时享受 2 件 + 4 件的属性。物理伤害 = 5 + 10 = 15,作为 qi:set:<id> 源应用。
  • 药水效果取最高:2 件 SPEED:1 + 3 件 SPEED:0SPEED:1
  • 套装属性走 属性系统 的独立源;套装 perm 效果走 PermEffectSync

4. 套装技能触发器

触发器何时触发备注
right_click / left_click手持 ≥ 件数时点击手动
shift_right_click / shift_left_click潜行 + 点击手动
shift_toggle切换潜行手动
on_damage对实体造成伤害自动
on_hit受到伤害自动
on_kill击杀实体自动

技能 refs 里的 handler + payload 由 QI 派发(如 qinhskills:cast 交给 QinhSkills)。冷却 cooldown 支持 5s / 200ms / 3t(tick)。


5. 成员匹配规则

belongingPieces 里每一项可以是:

  • 精确 ID:物品 ID 完全等于它。
  • 前缀:物品 ID 以 它_ 开头(如 warrior 匹配 warrior_helmet)。
kotlin
SetRegistry.findForItem("warrior_helmet")  // → warrior_bloodlust
SetRegistry.isPieceOf("warrior_helmet", "warrior_bloodlust")  // true

6. 套装 Lore 显示

SetLoreRenderer 渲染套装段,显示每级加成的激活 / 未激活状态:

默认格式(穿 2/4 件时):

血色狂暴
◆ [2] 战士之心 [已激活]
  +5 物理伤害
◇ [3] 血色狂暴 [还需1]
◇ [4] 狂暴之力 [还需2]
─ 套装描述 ─
  传说中的战士套装
  集齐套装可激活特殊效果

可用 lore_format 自定义模板,变量:{name} / {pieces} / {need} / {lore} / {desc}

yaml
  lore_format:
    header: "<dark_gray>─── <white>{name}</white> ───</dark_gray>"
    inactive_line: "◇ <gray>[{pieces}] {name} [还需{need}]</gray>"
    active_line: "◆ <yellow>[{pieces}] {name} [已激活]</yellow>"
    lore_line: "  <dark_gray>{lore}</dark_gray>"
    lore_divider: "<dark_gray>─ 套装描述 ─</dark_gray>"
    desc_line: "  <dark_gray>{desc}</dark_gray>"

套装件数实时显示靠 SetLoreContextHolder:装备变化时由 EquipmentWatcher 填入每个玩家的件数,渲染时取当前观察者的件数。

🖼️ [图片占位] 套装物品 hover,展示 2/4 已激活、3/4 未激活的差异样式 · 建议 assets/set-lore.png


7. 文件与重载

  • 套装存在 sets/<套装ID>.yml(推荐每套一文件)。
  • /qi reload(或套装配置变更)触发 SetRegistry.load() 重新加载。
  • 同 ID 多文件时,优先取文件名 = <id>.yml 的,否则取最后一个。

8. 开发者 API

kotlin
SetRegistry.get(id): SetDefinition?
SetRegistry.all(): List<SetDefinition>
SetRegistry.findForItem(itemId): SetDefinition?
SetRegistry.isPieceOf(itemId, setId): Boolean

setDef.activeBonus(matchedCount): SetBonus?   // 当前件数下最高档加成
setDef.nextBonus(matchedCount): SetBonus?     // 下一档加成

GUI 编辑套装见 套装编辑器


下一步