画布 / 玻璃画布 / 投影仪 / 绘图桌 / 调色器 / 颜料罐

基本信息

这六个方块构成 OpenBlocks 的「投影建造」系统:用画布记录蓝图,投影仪把蓝图以半透明实体方块的形式投射出来。

注册名 类 材质 声明位置
OpenBlocks:canvas BlockCanvas implements IPaintableBlock Material.sponge OpenBlocks.java:368
OpenBlocks:canvasglass BlockCanvasGlass extends BlockCanvas Material.glass OpenBlocks.java:378
OpenBlocks:projector BlockProjector Material.iron OpenBlocks.java:381
OpenBlocks:drawingtable BlockDrawingTable Material.wood OpenBlocks.java:384
OpenBlocks:paintmixer BlockPaintMixer Material.rock OpenBlocks.java:365
OpenBlocks:paintcan BlockPaintCan Material.rock OpenBlocks.java:371

注意 canvas 与 canvasglass 共用同一个 TileEntity 类型 TileEntityCanvas(OpenBlocks.java:368、:378)。

功能

画布(BlockCanvas)

一块可以「涂色」的方块,同时也是一个 3D 贴图容器。

关键常量(BlockCanvas.java:25-29):

常量 值 含义
RENDER_ALL_SIDES -1 渲染全部 6 面
BASE_LAYER -1 底图层(承载原方块贴图)
NO_LAYER -2 不渲染任何层

BlockCanvas 用两个可变字段 layer / renderSide 驱动渲染(:31-32),由 TESR 在渲染前设置:

  • setLayerForRender / setSideForRender(:53-59)

  • shouldSideBeRendered 只在 renderSide 匹配或为 RENDER_ALL_SIDES 时渲染(:61-65)

  • colorMultiplier 与 getUnrotatedTexture 都从 TE 取该层该面的颜色/贴图,取不到时返回 0xFFFFFFFF 与基类贴图(:67-86)

  • 渲染状态是共享的可变字段:layer、renderSide、renderPass 在方块单例上,不是线程/方块级的;BlockPaintCan 也有同样的 renderPass(BlockPaintCan.java:16)。这是 GTNH 上多线程渲染下的常见坑,仓库内无相关注释

  • replaceBlock(:88-99)根据原方块材质选择换成 canvasGlass 还是 canvas,并把原方块存进 TE(paintedBlock / paintedBlockMeta,TileEntityCanvas.java:39-40)

  • IPaintableBlock.recolourBlockRGB 委派给 tile.applyPaint(color, side)(:102-105),recolourBlock 先把原版方块色转成 ColorMeta 再走 RGB 路径(:108-111)

玻璃画布(BlockCanvasGlass)

extends BlockCanvas,只有三点差异(BlockCanvasGlass.java:12-41):Material.glass + setStepSound(soundTypeGlass)(:14-17)、非实心且非普通渲染(:19-27)、相邻同类或原版玻璃时隐藏面(:29-36)。getSubBlocks 被置空(:38-40)——它只能通过画布系统获得,不会出现在创造模式物品栏。

投影仪(BlockProjector)

半高(SLAB_HEIGHT = 0.5)的方块,把画布记录的蓝图投射成半透明实体方块。

  • META_BIT_ACTIVE = 0:激活状态存在方块 meta 的第 0 位(BlockProjector.java:16),ByteUtils.set(...) 写入(TileEntityProjector.java:73)
  • 发光:getLightValue(world,...) 在激活时返回 clamp(Config.projectorLightLevelValue, 0, 15)(BlockProjector.java:36-42);无世界重载返回 1(:44-47)
  • 光锥贴图 CONE_ICON 在类加载时按 Config.renderHoloGrid 决定用 projector_cone_grid 还是 projector_cone(:22)——配置在运行时改动不会换贴图
  • 侧/顶面直接复用原版石台阶贴图 stone_slab_side / stone_slab_top(:67-68),所以它看起来就是台阶
  • 固定在渲染通道 1:canRenderInPass 恒 true、getRenderBlockPass 返回 1(:77-85)

绘图桌(BlockDrawingTable)

FOUR_DIRECTIONS 木材方块,但不是工作台——它是一张模板制作台。

  • 只有 1 个槽位,且只接受 MetasGeneric.unpreparedStencil(未加工的模板坯)(TileEntityDrawingTable.java:23-31)
  • 实现 IStencilCrafter,通过 RPC 让玩家在槽中设计模板形状(TileEntityDrawingTable.java:21、:60 起)
  • 有独立 GUI GuiDrawingTable / ContainerDrawingTable(:35-43),canUpdate() 返回 false(:50-53)
  • 贴图 openblocks:drawingtable_top / _front,其余面走基类(BlockDrawingTable.java:26-36)

调色器(BlockPaintMixer)

TESR_ONLY,边界 0.125~0.875 的柱体(BlockPaintMixer.java:11-16)。负责把不同颜色混合成新颜色。

颜料罐(BlockPaintCan)

装一种颜色的液体罐,双渲染通道:pass 0 画罐体、pass 1 画液面(shouldSideBeRendered 按 renderPass 与 side == 1 分流,BlockPaintCan.java:56-64)。colorMultiplier 在 pass 1 返回 tile.getColor(),pass 0 恒白(:71-81)。suppressPickBlock 返回 true(:83-86),即中键取方块拿不到它。

数值

数值名 来源 值
画布 RENDER_ALL_SIDES 常量 -1(BlockCanvas.java:25)
画布 BASE_LAYER 常量 -1(BlockCanvas.java:27)
画布 NO_LAYER 常量 -2(BlockCanvas.java:29)
画布 ALL_SIDES TileEntityCanvas.ALL_SIDES {0,1,2,3,4,5}(TileEntityCanvas.java:36)
投影仪高度 SLAB_HEIGHT 0.5(BlockProjector.java:18)
投影仪激活位 META_BIT_ACTIVE 0(BlockProjector.java:16)
投影仪发光范围 硬编码 0 ~ 15(BlockProjector.java:20-21)
调色器边界 硬编码 0.125 ~ 0.875(BlockPaintMixer.java:14)
颜料罐边界 硬编码 0.25/0.25/0.25 ~ 0.7/0.6875/0.75(BlockPaintCan.java:33)

交互

触发 行为
画布被染色 recolourBlockRGB → tile.applyPaint(color, side)(BlockCanvas.java:102-105)
画布被模板覆盖 useStencil 在最后一层时替换顶层模板,旧的模板以物品形式返还(TileEntityCanvas.java:181-190)
画布方块被挖 TE 恢复原方块与其 meta(TileEntityCanvas.java:173-176)
投影仪激活 meta bit 0 置位,渲染出蓝图实体方块,并按配置发光
玻璃画布 创造模式物品栏中不出现(getSubBlocks 置空,BlockCanvasGlass.java:38-40),且无合成配方
绘图桌放入未加工模板坯 进入模板设计模式,产出定制的 stencil 物品(TileEntityDrawingTable.java:23-31)
调色器 把颜料刷与颜料罐中的颜色混合,产出新的颜料罐(TileEntityPaintMixer.java:40、:98)

合成配方

画布(Config.java:992-1003,产出 9 个):

ppp
pfp
ppp
字符 物品
p Items.paper 纸
f Blocks.fence 栅栏

调色器(Config.java:979-990):

ooo
i i
iii
字符 物品
o Blocks.obsidian 黑曜石
i ingotIron 铁锭

投影仪(Config.java:1005-1038,共 2 个配方,仅第 2 行左右对调):

grl
iri
srs
字符 物品
g dustGlowstone 荧石粉
r dustRedstone 红石粉
l gemLapis 青金石
i ingotIron 铁锭
s Blocks.stone_slab 石台阶

绘图桌(Config.java:1073-1088):

sks
pcp
ppp
字符 物品
s MetasGeneric.unpreparedStencil 未加工模板坯
k MetasGeneric.sketchingPencil 素描铅笔
c craftingTableWood 工作台
p plankWood 木板

配方直接消耗两个 MetasGeneric 子物品,说明它确实是模板制作台而非普通工作台。

玻璃画布与颜料罐在 Config.registerCraftingRecipes 中没有任何合成配方(对全文件 grep canvasGlass / paintCan 只命中方块/物品/TE 定义与 NEIOpenBlocksConfig,无 recipeList.add)。它们的来源是:

  • canvasglass —— BlockCanvas.replaceBlock 在原方块材质为 Material.glass 时就地替换(BlockCanvas.java:92-93);NEI 中被显式隐藏(NEIOpenBlocksConfig.java:24-25)
  • paintcan —— 调色器 TileEntityPaintMixer 的产物(TileEntityPaintMixer.java:40),调色器本身是 6 格仓库(TileEntityPaintMixer.java:98)

相关条目