Appearance
红石触发器
文档版本:基于 2026-06-01 代码分析
概述
红石触发器系统允许管理员在游戏地图中设置"倒计时阈值触发器"。当游戏剩余时间达到预设阈值时,触发器方块输出红石信号,可用于自动化控制地图中的红石装置(如开门、亮灯、激活机关等)。
系统支持两种触发模式:MOMENT(跨越阈值瞬间输出脉冲)和 SUSTAINED(低于阈值时持续输出)。
核心概念
两种触发模式
| 模式 | id | 行为 | 暂停时 | 典型应用 |
|---|---|---|---|---|
| MOMENT | "moment" | 剩余时间跨越阈值的瞬间,输出 10 tick(0.5秒)脉冲 | 不触发 | 一次性机关(开门) |
| SUSTAINED | "sustained" | 剩余时间 <= 阈值时,持续输出红石信号 15 | 继续工作 | 持续性装置(警报灯) |
脉冲机制
MOMENT 模式触发后:
pulseTicks从 10 递减到 0(0.5 秒)- 递减期间输出红石信号 15
- 递减到 0 时自动关闭信号
架构设计
tick 调度逻辑
mermaid
flowchart TD
A[tick 每5tick] --> B{游戏状态?}
B -->|RUNNING| C[计算 remainingMillis]
B -->|PAUSED| D{触发器模式?}
B -->|其他| E[resetAllOutputs<br/>全部断电]
C --> F{模式?}
F -->|MOMENT| G{跨越阈值?<br/>last > threshold >= current?}
G -->|是| H[triggerNow<br/>输出10tick脉冲]
G -->|否| I[无操作]
F -->|SUSTAINED| J{remaining <= threshold?}
J -->|是| K[setSustainedPowered true]
J -->|否| L[setSustainedPowered false]
D -->|SUSTAINED| J
D -->|MOMENT| M[无操作<br/>暂停时不触发]
K --> N[setPowered true]
L --> O[setPowered false]红石信号输出
mermaid
flowchart LR
BE["RedstoneTriggerBlockEntity<br/>powered / pulseTicks"] -->|getSignal| Block["RedstoneTriggerBlock<br/>isSignalSource=true"]
Block -->|信号强度15| Neighbor["相邻方块"]触发器方块覆盖 isSignalSource() 返回 true,是红石信号源。信号通过 getSignal() 和 getDirectSignal() 输出强度 15。
关键文件
| 文件 | 说明 |
|---|---|
com/chenxi/chenxi_rfm/common/block/RedstoneTriggerBlock.java | 触发器方块类 |
com/chenxi/chenxi_rfm/common/block/RedstoneTriggerBlockEntity.java | 方块实体(信号控制+存储) |
com/chenxi/chenxi_rfm/server/rfm/RfmRedstoneTriggerManager.java | 触发器管理核心 |
com/chenxi/chenxi_rfm/common/rfm/trigger/RfmTriggerMode.java | 触发模式枚举 |
com/chenxi/chenxi_rfm/server/config/rfm/PersistentRfmTriggerSavedData.java | 持久化存储 |
com/chenxi/chenxi_rfm/server/event/ServerRfmGameEvents.java | tick 调度入口 |
关键流程
触发器注册
RedstoneTriggerBlockEntity.serverTick() 每秒调用 RfmRedstoneTriggerManager.registerIfAbsent(),从存储加载配置(名称、阈值、模式)应用到 BE。如果数据不存在则使用默认值。
方块右键
右键触发器方块 → 向客户端发送 OpenRfmManagerPanelPayload(initialTab=3) → 打开中控面板的触发器管理页,可进行配置和操作。
五种操作
| 操作 | 说明 |
|---|---|
| 保存 | 更新触发器名称、阈值、模式 |
| 立即触发 | 强制输出 10 tick 脉冲 |
| 重置 | 恢复默认配置(名称"红石触发器",阈值60秒,MOMENT模式) |
| 传送到 | 将管理员传送到触发器位置 |
| 清理无效 | 检查所有 TriggerRecord 对应的方块是否存在,不存在则移除 |
暂停时的特殊行为
- MOMENT:暂停期间不触发(阈值跨越仅在 RUNNING 时检测)
- SUSTAINED:暂停期间继续工作(持续信号根据剩余时间保持)
方块移除
RedstoneTriggerBlock.onRemove() → RfmRedstoneTriggerManager.removeByPos(level, pos, false) → 从存储中移除记录。
数据持久化
PersistentRfmTriggerSavedData
文件:<world>/data/nfa_rfm/rfm_trigger.dat
json
{
"Triggers": [
{
"Dimension": "minecraft:overworld",
"BlockX": 100, "BlockY": 64, "BlockZ": 200,
"Name": "阶段一触发",
"TargetRemainingSeconds": 300,
"Mode": "moment"
}
]
}| 字段 | 类型 | 说明 |
|---|---|---|
dimension | String | 维度 ID |
blockX/Y/Z | int | 方块坐标 |
name | String | 触发器名称(最长32字符) |
targetRemainingSeconds | int | 阈值(0-86400秒) |
mode | RfmTriggerMode | MOMENT 或 SUSTAINED |
注意事项 / 限制
- 脉冲长度硬编码:
MOMENTARY_PULSE_TICKS = 10(0.5秒),不可配置。 - 同位置幂等注册:按维度+坐标匹配,重复放置不会创建重复记录。
- 红石信号不穿透:信号仅影响直接相邻的方块和红石线。
- MOMENT仅跨越一次:阈值跨越瞬间触发一次脉冲。如果游戏时间被修改(如倒计时冻结后恢复),再次跨越可能触发第二次。
- SUSTAINED在游戏结束时断电:
resetAllOutputs()在游戏结束和executeGameEnd时调用。 - PAUSED≠STOP:SUSTAINED 模式在暂停时继续工作,这是设计使然。