API 与兼容

基本信息

属性 值
API 根包 com.github.lunatrius.schematica.api
API 声明 @API(owner = "Schematica", apiVersion = "1.1", provides = "SchematicaAPI")(api/package-info.java:1)
核心接口 api/ISchematic.java(16 个方法)
事件数 2(PreSchematicSaveEvent、PostSchematicCaptureEvent)
兼容探针数 4(LOTR、ForgeMultipart、GTNH/DreamCraft、打印机放置注册表)
编译期依赖 com.github.GTNewHorizons:LunatriusCore:1.2.1-GTNH(dependencies.gradle:4)
编译期可选依赖 curse.maven:lotr-423748:4091561(compileOnly,dependencies.gradle:5)
硬前置(运行时) required-after:LunatriusCore;(reference/Reference.java:11)

功能

对外 API:ISchematic

api/ISchematic.java 是蓝图的数据模型接口,16 个方法(按源码声明顺序):

方法 行 用途
Block getBlock(int x, int y, int z) :20 读方块;越界返回 Air(:13 javadoc)
boolean setBlock(int x, int y, int z, Block block) :33 写方块(无 meta 重载)
boolean setBlock(int x, int y, int z, Block block, int metadata) :46 写方块 + meta
TileEntity getTileEntity(int x, int y, int z) :56 读 TileEntity
List<TileEntity> getTileEntities() :63 取全部 TileEntity
void setTileEntity(int x, int y, int z, TileEntity tileEntity) :73 写 TileEntity
void removeTileEntity(int x, int y, int z) :82 删 TileEntity
int getBlockMetadata(int x, int y, int z) :92 读元数据
boolean setBlockMetadata(int x, int y, int z, int metadata) :104 写元数据
List<Entity> getEntities() :111 取全部实体
void addEntity(Entity entity) :118 加实体
void removeEntity(Entity entity) :125 删实体
ItemStack getIcon() :132 读图标
void setIcon(ItemStack icon) :139 设图标
int getWidth() / int getLength() / int getHeight() :146/:153/:160 三轴尺寸

事件

两个事件都继承 FML Event 并实现 Cancelable/HasResult 语义之外的最小形式,字段为 public final ISchematic schematic:

事件 文件 触发点
PostSchematicCaptureEvent api/event/PostSchematicCaptureEvent.java:12 写文件前,SchematicFormat.writeToFile 投递(world/schematic/SchematicFormat.java:77-78)
PreSchematicSaveEvent api/event/PreSchematicSaveEvent.java:15 写 NBT 前,SchematicAlpha.writeToNBT 两处投递(world/schematic/SchematicAlpha.java:273、:385)

PreSchematicSaveEvent 额外暴露 public final NBTTagCompound extendedMetadata(:27)与 boolean replaceMapping(String oldName, String newName) throws DuplicateMappingException(:53),供其他 mod 在保存前改写方块 ID 映射。

⚠️ PostSchematicCaptureEvent 的 getResult() 未被检查——writeToFile 只是无条件 MinecraftForge.EVENT_BUS.post(event) 后继续写盘(world/schematic/SchematicFormat.java:77-89),监听方无法通过 event 阻止写入。

配套异常 api/event/DuplicateMappingException.java:3 继承 Exception,由 replaceMapping 在映射冲突时抛出。

打印机放置注册表(PlacementRegistry)

client/printer/registry/PlacementRegistry.java 是单例(INSTANCE,:25),静态块中调 populatePlacementMaps() 填充三张表(:175-177)。查询优先级为 item → block → block 类(getPlacementData,:155-173)。

表 字段 填充方式
类表 classPlacementMap addPlacementMapping(Class<? extends Block>, PlacementData)(:131)
方块表 blockPlacementMap addPlacementMapping(Block, PlacementData)(:139)
物品表 itemPlacementMap addPlacementMapping(Item, PlacementData)(:147)

populatePlacementMaps()(:31-129)预置 11 个类级 + 24 个方块级 + 4 个物品级映射,类级为 BlockButton/BlockChest/BlockDispenser/BlockEnderChest/BlockFurnace/BlockHopper/BlockPistonBase/BlockPumpkin/BlockRotatedPillar/BlockStairs/BlockTorch(:38-71),物品级为 Items.wooden_door/iron_door/repeater/comparator(:117-128)。

PlacementData(client/printer/registry/PlacementData.java:11)含 PlacementType 枚举(:13)、maskOffset(默认 0x0)、maskMeta(默认 0xF)、offsetLowY/offsetHighY(默认 0.0f/1.0f)与 Map<ForgeDirection, Integer> mapping(:21-27)。setOffset / setMaskMeta / setExtraClick 均为链式 setter(:39、:46、:85)。

IExtraClick(client/printer/registry/IExtraClick.java:4-6)是函数式接口 int getExtraClicks(Block, int metadata),用于按方块属性决定额外点击次数。预置两处使用:双层石/木台阶各自挂 block.isOpaqueCube() ? 1 : 0(:36、:81、:110)。

数值

跨 mod 兼容探针

目标 mod 探针 来源
lotr(Lord of the Rings Mod) Loader.isModLoaded("lotr") → 反射实例化 Reference.LOTR_PROXY proxy/ClientProxy.java:383-388
ForgeMultipart Loader.isModLoaded("ForgeMultipart") nbt/ForgeMultipart.java:39
dreamcraft(GTNH) Loader.isModLoaded("dreamcraft") → CommonProxy.GTNH proxy/CommonProxy.java:48

LOTR 兼容:ILOTRPresent(compat/ILOTRPresent.java:10)只定义 Boolean isBlackListed(Block, ItemStack)(:17)。LOTRProxy 实现把 LOTRMod.chisel 与 LOTRMod.chiselIthildin 拉黑(compat/LOTRProxy.java:16),因为凿子有多个变体方块。加载失败或未装 LOTR 时回退 NoLOTRProxy,其 isBlackListed 恒返回 false(compat/NoLOTRProxy.java:9-11)。

⚠️ ILOTRPresent 的 proxy 创建是反射而非直接 new(proxy/ClientProxy.java:385-388),且整个块包在 try/catch 中,异常时打 warn "Failed to create lotr proxy in the normal way" 并回退(:392-395)。ILOTRPresent 的 javadoc 注明这是基于 Forge 论坛 diesieben07 的帖子的标准做法(compat/ILOTRPresent.java:7-8),并留有 // TODO:fix printer functionality with weapon racks/ armour stands/ plates etc.(:18)。

ForgeMultipart 兼容:nbt/ForgeMultipart.java 在 postInit 调 init()(proxy/CommonProxy.java:65)。init() 用 ReflectionHelper 反射取 codechicken 的 Scala 单例与方法(:48-93),客户端与服务端走不同路径(:105-115):客户端手工遍历 parts 复合标签重建(:124-160),服务端直接 methodCreateFromNBT.invoke(:162-170)。反射失败则打 error "Something went wrong, disabling FMP integration." 并自我禁用 enabled = false(:95-96)。

客户端路径在 parts 数量不匹配时打 info 并返回 null(:142-145),parts 为空同样返回 null(:147-149)。

GTNH 探针:CommonProxy.GTNH = Loader.isModLoaded("dreamcraft")(proxy/CommonProxy.java:48)——用 modid 猜整合包,若整合包改名即失效。

Litematica 格式翻译层

compat/ 包的 4 张映射表服务于 .litematic 读取(见 蓝图格式),均为本仓库自建,不依赖 Litematica mod:

表 条目数 来源
DirectBlockMappings 258 ^ m( 计数(compat/DirectBlockMappings.java)
VanillaBlockRenames 302 put( 计数(compat/VanillaBlockRenames.java)
VanillaPropertyMeta 234 ^ p( 计数(compat/VanillaPropertyMeta.java)
BlockStateTranslator.KEEP_PROPERTIES 20 KEEP_PROPERTIES.put 计数(compat/BlockStateTranslator.java)

DirectBlockMappings 刻意绕过字符串查注册表、直接引用 Blocks.xxx 静态字段,因为某些方块注册名与预期不符(如 minecraft:stone_bricks → Blocks.stonebrick,compat/DirectBlockMappings.java:14-16 注释)。

VanillaBlockMappings 暴露 getBlockName_1_7_10(String modernName) 与 getMetadata(String blockName, String properties)(compat/VanillaBlockMappings.java:27-37),后者在查不到时返回 -1(:33、:36)。颜色系列方块通过 registerColorMeta 按白=0、橙=1、品红=2……展开(:44-50)。

交互

其他 mod 使用本 API 的推荐路径:

  1. 监听 PreSchematicSaveEvent,调 replaceMapping 把不能被打印机放置的方块映射到替代方块——例:compat/LOTRProxy 用黑名单方式处理,见上。
  2. 调 PlacementRegistry.INSTANCE.addPlacementMapping(...) 为自家方块补放置朝向规则(client/printer/registry/PlacementRegistry.java:131-153)。
  3. 直接构造 world/storage/Schematic(ISchematic 实现)读写蓝图数据模型。

跨 mod 内容隔离说明

以下内容不属于本仓库,本条目不收录其行为:

  • Litematica mod(1.21):本仓库只自行解析 .litematic 文件格式,不依赖、不集成 Litematica mod。
  • schematica 分类(wiki 中已存在的另一个条目):对应 mirror/Schematica 仓库的上游版本,modid 同为 Schematica,但源码树、commit 与注册内容均不同。本条目全部内容来自 /Users/evlos/a/mirror/Schematica-Plus/。
  • LunatriusCore(硬前置):com.github.lunatrius.core.util.vector.Vector3i 等工具类来自外部仓库,本仓库只消费其 API。

相关条目