Set
Belongs to: Server Owner Guide · Related: Attributes & Values · Action System
A Set lets multiple items, when worn together, activate extra bonuses (attributes / potion effects / active skills), triggered in tiers by piece count worn. Config file: plugins/QinhItems/sets/*.yml.
1. Data Model
data class SetDefinition(
val id: String,
val displayName: String, // MiniMessage
val icon: String, // material name (editor icon)
val belongingPieces: List<String>, // member item ID / prefix
val lore: List<String>, // set description
val bonuses: List<SetBonus>, // bonuses tiered by piece count
val loreFormat: SetLoreFormat? = null, // custom Lore template
)
data class SetBonus(
val pieces: Int, // piece count required to activate
val name: String,
val lore: List<String>, // shown when activated
val effects: Map<String,Int>, // potion effect name→level (0=I)
val attributes: Map<String,Double>, // attribute bonus (accumulated)
val abilities: List<SetAbility>, // active / event skills
)
data class SetAbility(
val trigger: String, // right_click / on_damage / on_kill …
val refs: List<ActionRef>, // action handler references
val cooldownMs: Long = 0L,
)2. Full YAML Example
warrior_bloodlust: # set ID
display_name: "<red>Bloodlust</red>"
icon: NETHERITE_SWORD
belonging_pieces: # members: exact ID or prefix
- "warrior_helmet"
- "warrior_chestplate"
- "warrior_leggings"
- "warrior_boots"
- "warrior_sword"
- "warrior" # prefix: any warrior_xxx counts
lore:
- "<gray>The legendary warrior set</gray>"
- "<gray>Complete the set to activate special effects</gray>"
bonuses:
- pieces: 2 # activates at 2 pieces
name: "Warrior's Heart"
lore:
- "<blue>+5 Physical Damage</blue>"
attributes:
物理伤害: 5
- pieces: 4 # activates at 4 pieces (stacks with 2-piece)
name: "Power of Frenzy"
lore:
- "<blue>Cumulative +15 Physical Damage</blue>"
- "<green>+100 Health</green>"
attributes:
物理伤害: 10 # 4 pieces total 5+10=15
生命: 100
effects:
SPEED: 1 # Haste II (0=I)
STRENGTH: 0
abilities:
- trigger: right_click # right-click while holding ≥4 pieces
cooldown: 5s
actions:
- handler: "qinhskills:cast"
payload: "set burst skill name"
- trigger: on_damage # triggers on dealing damage
cooldown: 3s
actions:
- handler: "qinhskills:cast"
payload: "on-hit counter skill name"3. How Bonuses Stack
- Attributes accumulate: wearing 4 pieces → you enjoy both the 2-piece and 4-piece attributes.
物理伤害= 5 + 10 = 15, applied as aqi:set:<id>source. - Potion effects take the highest: 2-piece
SPEED:1+ 3-pieceSPEED:0→SPEED:1. - Set attributes go through an independent source of the Attribute System; set perm effects go through
PermEffectSync.
4. Set Skill Triggers
| Trigger | When it fires | Note |
|---|---|---|
right_click / left_click | Click while holding ≥ piece count | Manual |
shift_right_click / shift_left_click | Sneak + click | Manual |
shift_toggle | Toggle sneaking | Manual |
on_damage | Deal damage to an entity | Automatic |
on_hit | Take damage | Automatic |
on_kill | Kill an entity | Automatic |
The handler + payload in a skill's refs are dispatched by QI (e.g. qinhskills:cast is handed to QinhSkills). The cooldown supports 5s / 200ms / 3t (ticks).
5. Member Matching Rules
Each entry in belongingPieces can be:
- Exact ID: the item ID equals it exactly.
- Prefix: the item ID starts with
it_(e.g.warriormatcheswarrior_helmet).
SetRegistry.findForItem("warrior_helmet") // → warrior_bloodlust
SetRegistry.isPieceOf("warrior_helmet", "warrior_bloodlust") // true6. Set Lore Display
SetLoreRenderer renders the set section, showing the activated / not-activated state of each tier's bonus:
Default format (when wearing 2/4 pieces):
Bloodlust
◆ [2] Warrior's Heart [Activated]
+5 Physical Damage
◇ [3] Bloodlust [1 more needed]
◇ [4] Power of Frenzy [2 more needed]
─ Set Description ─
The legendary warrior set
Complete the set to activate special effectsYou can customize the template with lore_format. Variables: {name} / {pieces} / {need} / {lore} / {desc}:
lore_format:
header: "<dark_gray>─── <white>{name}</white> ───</dark_gray>"
inactive_line: "◇ <gray>[{pieces}] {name} [{need} more needed]</gray>"
active_line: "◆ <yellow>[{pieces}] {name} [Activated]</yellow>"
lore_line: " <dark_gray>{lore}</dark_gray>"
lore_divider: "<dark_gray>─ Set Description ─</dark_gray>"
desc_line: " <dark_gray>{desc}</dark_gray>"Real-time piece-count display relies on
SetLoreContextHolder: when equipment changes,EquipmentWatcherfills in each player's piece count, and rendering reads the current observer's piece count.
🖼️ [Image placeholder] Hovering over a set item, showing the difference in style between 2/4 activated and 3/4 not activated · suggested
assets/set-lore.png
7. Files & Reloading
- Sets live in
sets/<set ID>.yml(one file per set recommended). /qi reload(or a set config change) triggersSetRegistry.load()to reload.- When the same ID appears in multiple files, the one whose filename =
<id>.ymltakes priority; otherwise the last one is used.
8. Developer API
SetRegistry.get(id): SetDefinition?
SetRegistry.all(): List<SetDefinition>
SetRegistry.findForItem(itemId): SetDefinition?
SetRegistry.isPieceOf(itemId, setId): Boolean
setDef.activeBonus(matchedCount): SetBonus? // highest-tier bonus at current piece count
setDef.nextBonus(matchedCount): SetBonus? // next-tier bonusFor editing sets via GUI, see Set Editor.
Next Steps
- Action System: handlers used by set skills
- Attributes & Values: how set attributes are applied
- Set Editor: orchestrate sets via GUI