动作系统概览
动作系统是 QI 物品的「主动效果 / 技能」引擎:玩家做某事(触发器)→ 执行一串效果(处理器)。本页讲整体结构与 YAML 写法,细节拆到子页。
1. 一个动作长什么样
yaml
my_item:
actions:
triggers:
left_click: # 触发器名(自定义)
trigger:
atom: left_click # 触发原子,见 触发器
cooldown: 3s # 冷却,见 冷却/消耗/条件
consume: # 资源消耗
- "item:minecraft-redstone:1"
conditions: # 触发条件(全过才执行)
- "player_level:>=10"
refs: # 按顺序执行的处理器引用
- handler: qi:title
payload: "<gold>火花</gold>||<gray>剑刃震鸣</gray>||3||30||10"
- handler: qi:sound
payload: "minecraft:entity.player.attack.crit;1;1.2"结构层级:
actions:
triggers:
<触发器名>:
trigger: { atom: ... } 或 trigger: { sequence: [...] , window: ms }
cooldown: <时长> (可选)
consume: [ <消耗>, ... ] (可选)
conditions: [ <条件>, ... ] (可选)
refs:
- handler: <处理器ID>
payload: <载荷>
- ...2. 执行流程
玩家动作(如左键)
→ 触发原子 left_click 命中
→ 评估所有 conditions(必须全部为真)
→ 检查冷却(在冷却中则停止)
→ 触发前事件 QinhActionTriggerEvent(可被插件取消)
→ 检查 consume(资源不足则停止)
→ 按顺序执行每个 ref 的 handler(传 payload)
每个 handler 返回 HANDLED / NOT_HANDLED / HANDLER_UNAVAILABLE
派发后事件 QinhActionDispatchedEvent(供监听)
→ 若任一 handler 返回 HANDLED:
扣除 consume、记录冷却事件细节见 事件。
3. 关键设计:YAML 里不能写逻辑
QI 刻意禁止在动作 YAML 里写流程控制:if / else / when / unless / switch / filter / rules / flow 等都是被禁字段(ActionRoutingPolicy)。一个触发器底下就是「按顺序跑一串处理器」,处理器之间不互相依赖结果。
需要复杂逻辑怎么办? 由开发者实现一个 动作处理器,把 if/switch/状态判断写进 Kotlin/Java,YAML 只负责引用它并传 payload。
这条边界让配置保持简单、可被 GUI 完整编辑。config.yml 里 action-routing.strict: true 时违规报错,false 时仅警告。
4. 动作从哪加载
| 来源 | 说明 |
|---|---|
| 内嵌(推荐) | 直接写在物品 YAML 的 actions.triggers 段 |
| 独立文件 | actions_file 字段指向单独文件(已弃用,建议内嵌) |
⚠️ 动作只在 /qi reload 时载入。改了 YAML 一定要重载,否则不生效。重载会重置所有冷却与连招状态。
5. 触发器与处理器速览
- 触发器(Trigger):100+ 原子。点击类(left/right/shift)、潜行(单击 / 双击 / 序列)、移动(冲刺 / 滑翔 / 跳)、战斗(命中 / 受击 / 击杀 / 暴击)、容器 / 合成、实体交互、环境、服务器事件、
tick周期。完整清单见 触发器。 - 处理器(Handler):内置 10 个(
qi:message/qi:action_bar/qi:title/qi:subtitle/qi:sound/qi:bossbar/qi:command/qi:console_command/qi:give_item/qi:close_inventory)+ 生态(qinhskills:cast/combat:swing)。每个的 payload 格式见 处理器。
6. 一个完整的多动作物品
yaml
legendary_sword:
type: weapon
material: diamond_sword
display_name: "<gold>传奇剑刃</gold>"
actions:
triggers:
# 单原子 + 条件
left_click:
trigger:
atom: left_click
cooldown: 1s
conditions:
- "player_level:>=15"
refs:
- handler: qi:action_bar
payload: "<gold>▶ 斩击</gold>"
- handler: combat:swing
payload: "light"
# 序列连招(潜行→左键→左键)
whirlwind:
trigger:
sequence:
- sneak_down
- left_click
- left_click
window: 400 # 步间窗口(毫秒)
cooldown: 5s
consume:
- "level:2"
refs:
- handler: qi:message
payload: "<gold>旋风斩!</gold>"
- handler: qinhskills:cast
payload: '{"skill":"whirlwind_slash","level":1}'
# 受击触发
on_hit:
trigger:
atom: on_hit
cooldown: 3s
consume:
- "item:redstone:1"
conditions:
- "player_sneaking:true"
refs:
- handler: qi:title
payload: "<red>反击!</red>||<dark_red>+10 防御</dark_red>||5||20||5"
- handler: combat:swing
payload: "heavy"🖼️ [图片占位] 动作触发瞬间的游戏画面(标题 + 音效 + 粒子) · 建议
assets/action-trigger.png
7. 诊断动作
| 命令 | 用途 |
|---|---|
/qi trigger report | 显示 ActionTable 触发配置报告 |
/qi trigger test [itemId] [player] | 手动执行某物品的第一个触发绑定 |
/qi status / /qi diagnose | 查看动作表加载情况与问题 |
见 命令。
子页导航
- 触发器原子大全 —— 100+ 触发原子逐个列出
- 动作处理器大全 —— 每个 handler 的 payload 格式
- 冷却 / 消耗 / 条件 / 连招 —— 语法细节
- 开发自定义处理器 → 动作处理器开发