跳到正文
烈焰甘蔗Wiki

通道系统(Channel)

基本信息

属性 值
存取类 com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor
描述注册 com.gtnewhorizon.structurelib.ChannelDescription
GUI com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels
承载物品 Constructable Trigger

通道用来告诉多方块"这次要用哪个变体"。主通道由物品堆叠数承载(堆几个就是几号档位),子通道则是 NBT 里的额外键值对,用来选择同一档位下的不同分支。

NBT 字段

所有子通道数据存放在物品 NBT 根下的一个复合标签中:

字段 类型 说明
channels 复合标签(TAG_COMPOUND) 键为通道标识(全小写),值为正整数

键的约束由源码强制:必须非空且全小写。在 debug 模式下违反会直接抛 IllegalArgumentException(Channel name can be lower case ONLY),正常模式下不校验大小写。

unsetChannelData 在移除后会自动做逐层清理:若 channels 复合标签变空则移除它,若整个根标签变空则把 stackTagCompound 置为 null。因此一个完全没有通道的触发器不会残留任何 NBT。

wipeChannelData 同样会做这层清理。

主通道与子通道的关系

getChannelData(stack, channel) 的行为是取不到就回落到主通道:

  • 若 channels 中存在该键 → 返回其整数值
  • 否则 → 返回 stackSize(物品堆叠数)

因此子通道是"覆盖默认值"而非"附加维度"。withChannel(stack, channel) 则返回一个把子通道值提升为主通道的临时物品栈,若该子通道不存在则原样返回。

存取 API

方法 作用
setChannelData 写入子通道,值必须 > 0,否则抛异常
getChannelData 读取,不存在时回落到堆叠数
hasSubChannel() 是否存在任何子通道
hasSubChannel(channel) 是否存在指定子通道
unsetChannelData 移除指定子通道
wipeChannelData 清除全部子通道
countChannelData 子通道数量(不含主通道)
iterateChannelData 返回 Stream<键值对>(不含主通道)
withChannel 将指定子通道提升为主通道

iterateChannelData 返回的流不支持修改,底层数据在迭代中被改动仍可能抛出 ConcurrentModificationException。

mod 间注册通道描述

其他 mod 可以通过 IMC(mod 间通信)向 StructureLib 注册通道描述,指令侧也能据此在 GUI 中提供自动补全和 tooltip。StructureLib 处理两个 IMC 键:

IMC 键 载荷 处理
register_channel Channels 标签列表,每项含 Channel 与 Description 调用 StructureLibAPI.registerChannelDescription
register_channel_item Items 标签列表 把物品登记为某个通道值的指示物

被登记的物品在 GUI 中会以"Indicates value X for sub channel Y"的 tooltip 呈现,并可直接拖放到 GUI 中来设置对应子通道值。

通道配置 GUI

玩家对空气右键(服务端、不潜行)触发器可打开通道配置界面。

元素 语言键 说明
标题 item.structurelib.constructableTrigger.gui.title Sub Channels
键输入框 ...gui.key Key:
值输入框 ...gui.value Value:
Add 按钮 ...gui.add 新增子通道
Update 按钮 ...gui.set 更新已有子通道
Remove 按钮 ...gui.unset 移除子通道
Clear 按钮 ...gui.wipe 清除全部(红色,需二次确认)
来源标注 ...gui.channels.from 显示通道由哪个 mod 注册

GUI 实现了 NEI 集成接口(INEIGuiHandler),可从 NEI 物品面板拖放物品进来直接赋值。

清空操作有 3 秒超时的二次确认:WIPE_CONFIRM_TIMEOUT_MS = 3000,期间按钮变为 Sure?,超时后恢复。

拾取通道

客户端支持中键拾取与重置通道,涉及两处实现:

  • MixinGuiContainer_PickChannel(客户端 mixin,注入 GuiContainer.mouseClicked)——在物品栏/容器界面中用中键拾取通道
  • ChannelPickHandler——在世界中用中键对位置拾取通道

拾取到 ItemConstructableTrigger 时中键点击会被直接吞掉(cancel),避免把物品丢出。ChannelWipeConfirmation 负责清除确认。

中键拾取所依赖的 GUI 补丁

ChannelPickHandler 需要访问原版 GuiSlot 的 overlayBackground 方法,仓库内附带 AT 文件 structurelib_at.cfg:

public net.minecraft.client.gui.GuiSlot func_148136_c(IIII)V # overlayBackground

但需要注意的是,gradle.properties 中 accessTransformersFile = 留空,且 StructureLibCore.getAccessTransformerClass() 返回 null。AT 文件虽然被打进 jar 根目录,但并未通过 IFMLLoadingPlugin 声明挂载。

相关条目:/sl_channel、Constructable Trigger、多方块构造机制、提示渲染系统。

浏览全部模组