简体中文
多方块结构
多方块结构就是玩家用方块搭出来的一个「机关」. 你先把形状和坐标写进配置文件; 玩家把方块摆成这个形状并与之交互 (最常见的做法是对着方块按右键) 后, 插件会逐个核对方块是否对得上, 对得上就执行你配置好的动作 (发消息, 给经验等)
每个结构对应一个文件, 放在 plugins/EmakiStructure/multiblocks/<id>.yml. 文件名就是结构 id, 两者不一致时插件会拒绝加载
定义格式
yaml
version: 1 # 当前只支持 1 (填别的会被拒绝加载)
id: "teleporter" # 必须与文件名一致, 否则拒载 (id_mismatch)
shape:
allow_rotation: true # 默认 true: 玩家把整个结构转 90 度摆放也算通过
core_block: [4, 1, 4] # 可选: 核心方块坐标. 玩家右键它就能触发 (不写则右键任意成员方块都算)
blocks: # 结构由哪些方块组成
- pos: [4, 1, 4] # 相对坐标, 以结构最小角为原点 (0,0,0), 不能为负
block: "minecraft:obsidian"
- pos: [4, 2, 4]
block: "minecraft:ender_eye" # 要指定方块状态就写 minecraft:...[state=value]
- pos: [5, 1, 4]
block: "craftengine-myns:console" # 自定义方块写成 来源-原始id, 不能带状态段
- pos: [6, 1, 4]
furniture: "itemsadder:myplugin:chair" # 家具成员; 与 block 只能二选一
trigger:
targets: "any" # any = 任意成员触发; specific = 只有 positions 里的方块能触发; all = 全部成员都要被点到
positions: # targets 填 specific 时必填
- [4, 1, 4]
actions: | # 触发后执行的动作, 一行一条 (CoreLib 动作管道语法)
send_message "&a传送门已激活!"
action giveexp amount=10
cooldown: # 可选: 冷却, 防止玩家连点
global: "0" # 所有玩家共享的冷却; 0 = 无冷却, 支持 30s / 5m 写法
per_player: "0" # 每个玩家各自计的冷却
condition: "permission=teleport.use" # 可选: 触发条件, 不满足就不触发 (CoreLib 条件语法)坐标一律是相对坐标: 以结构自身的最小角为原点 (0,0,0), 不是世界坐标. 想知道某个方块该填什么, 可以用 /ems multiblock export <id> 按选区自动生成, 直接参照生成结果填写
加载时的检查
插件在读取每个文件时会逐条检查, 任何一条不通过就拒绝整个文件或跳过该成员, 并在控制台写明是哪个文件, 哪一行出了问题:
- 每个成员必须只写
block或furniture中的一个, 不能两个都写或都不写 - 坐标必须非负, 落在结构尺寸内, 且不能重复
furniture只认itemsadder:/oraxen:/nexo:/craftengine:这四种开头block写minecraft:开头时能带方块状态; 写其他来源 (自定义方块) 时不能带状态段targets填了any/specific/all以外的值, 或者specific没写positions, 或者一个有效成员都没有 (blocks_empty), 都会拒绝整个文件id与文件名不一致,version不是 1, 文件读取失败, 同样拒绝加载- 同一个 id 出现两次时, 后一个不加载 (
duplicate_id)
命令
/ems multiblock export <id> [force]: 按当前选区导出结构定义; 该 id 已存在时需加force才会覆盖 (already_exists)/ems multiblock place <id> [朝向]: 手动把结构摆放到你站的位置 (原版方块 / 自定义方块 / 家具三类成员都会放), 放完自动开始形状检测; 最多回报 5 条失败项/ems multiblock list: 列出所有已加载的定义, 以及数量统计/ems multiblock validate <id>: 对现场再检查一次形状, 不通过时该实例会被标记为未完成 (verification_failed)
触发流程
玩家交互后, 插件按下面的顺序逐步处理:
- 命中结构: 玩家右键的方块属于某个结构区域 (或点中了候选位置)
- 判断是否摆齐: 只检查发生过变化的方块, 不做全图扫描. 短时间内的重复变更会被合并处理 (
detection.debounce), 需要推断结构位置时受detection.max_cold_checks的数量上限约束 - 条件与冷却: 先看
condition是否满足 (整个条件组都满足才算通过), 再看冷却. 冷却优先取定义文件里的cooldown节, 没写就回退到config.yml的cooldown.global/cooldown.per_player - 发事件: 触发
MultiblockTriggerEvent(不能取消), 在正在处理这次交互的线程上发出; Folia 上就是被点方块所在区域的那个线程 - 执行动作: 逐行执行
trigger.actions
retrigger_on_reform 默认是 false: 结构被破坏后又重新摆好时, 它只恢复为活动状态, 不会再次触发, 这样玩家就没法反复拆了重摆刷奖励
增量检测配置要点
下面这些键都在配置详解的 detection 节:
sweep_interval: 定期扫描的间隔, 用来补查可能漏掉的情况.0表示关闭; 开启时不能小于 30s. 它只扫描"进行中"的结构, 不做全图遍历instance_limit: 每个定义, 每个玩家最多同时保留多少个"进行中"记录, 超了就淘汰最旧的instance_ttl: 一个"进行中"记录多久没有任何变化就被清理sample_recheck: 要不要对活动中的结构做低频抽样复检, 默认关闭