FMP 模块(appeng.integration.modules.FMP)

基本信息

属性 值
源码 appeng/integration/modules/FMP.java
类声明 48,public class
实现接口 IIntegrationModule + IFMP(integration/abstraction/IFMP.java:20)+ IPartFactory + IPartConverter(均为 codechicken.multipart.MultiPartRegistry 的嵌套接口)
静态单例 public static FMP instance
modID McMultipart(IntegrationType.java:38)
side BOTH
本 wiki 收录情况 Forge MultiPart 未被本 wiki 收录 —— 写全名 Forge MultiPart

本模块接口最多的一个

FMP 是 25 个模块里唯一同时实现 4 个接口的: IIntegrationModule + IFMP + IPartFactory + IPartConverter。

后两个来自 Forge MultiPart: codechicken.multipart.MultiPartRegistry.IPartFactory 与 codechicken.multipart.MultiPartRegistry.IPartConverter(FMP.java:41 / :42 import)。

生命周期

阶段 行号 动作
init() 93 注册 7 个 multipart 方块 + converter + part 名表 + AEMultiTile 透传(:96-114)
postInit() 124 MinecraftForge.EVENT_BUS.register(new FMPEvent())(:125)

注入内容 1:7 个 AE2 方块的 multipart 变体

FMP.java:96-102,全部经 createAndRegister(IBlockDefinition, int)(:70):

AE2 方块 damage 行号
blocks.quartz() 0 96
blocks.quartzPillar() 0 97
blocks.quartzChiseled() 0 98
blocks.skyStone() 0 99
blocks.skyStone() 1 100
blocks.skyStone() 2 101
blocks.skyStone() 3 102

⚠️ 这些是 AE2 自己的方块(ApiBlocks 定义), 不是 Forge MultiPart 的方块。见 方块石英、 方块天空石 等条目。

「不可定向方块」的处理在 createAndRegister(:70)与 convertTile(:129)里 —— 源码注释 use for FMP (parts/CableBusContainer.java:468-470)表明这套调用是 FMP 专用的。

注入内容 2:converter + part 名表

// FMP.java:104-114
final PartRegistry[] reg = PartRegistry.values();
final String[] data = new String[reg.length];
for (int x = 0; x < data.length; x++) { data[x] = reg[x].getName(); }
MultiPartRegistry.registerConverter(this);
MultiPartRegistry.registerParts(this, data);
MultipartGenerator.registerPassThroughInterface("appeng.helpers.AEMultiTile");
调用 位置 作用
MultiPartRegistry.registerConverter(this) 111 注册方块 ↔ multipart 的转换器
MultiPartRegistry.registerParts(this, data) 112 注册 part 名表(来自 PartRegistry 枚举)
MultipartGenerator.registerPassThroughInterface("appeng.helpers.AEMultiTile") 114 让 AEMultiTile 作为透传接口

⚠️ PartRegistry 在本模块里没有 import(FMP.java:38-45 只 import 了 codechicken.lib.vec.BlockCoord、codechicken.microblock.BlockMicroMaterial、 codechicken.multipart.MultiPartRegistry.{IPartConverter,IPartFactory})。 PartRegistry 来自 appeng.items.parts(AE2 自己的枚举,不在本分片)。 即「AE2 的 part 名」被塞进 FMP 的 part 表。

注入内容 3:Forge 事件

postInit()(:124-126)注册 FMPEvent(FMP.java:116)。 FMPEvent 产出 FMPPacketEvent(FMP.java:170), 后者在 integration/modules/helpers/FMPPacketEvent.java(见 helpers 总览)。

IFMP 的 4 个方法

integration/abstraction/IFMP.java:20,4 个:

方法 行号 语义
IPartHost getOrCreateHost(TileEntity tile) 22 造 / 取 AE2 的 part 宿主
CableBusContainer getCableContainer(TileEntity te) 24 取方块对应的线缆总线容器
void registerPassThrough(Class<?> layerInterface) 26 登记透传接口
Event newFMPPacketEvent(EntityPlayerMP sender) 28 造 FMP 发包事件

⚠️ IFMP 的返回类型大量是接口 / 事件类型而非基本类型 (IPartHost / CableBusContainer / Event), 用「基本类型白名单」统计会只数到 registerPassThrough 一个。 正确方法数是 4。

3 个 AE2 类型的引入

IFMP.java import 了 appeng.api.parts.IPartHost、 appeng.parts.CableBusContainer(AE2 内部类,非 api/) 与 cpw.mods.fml.common.eventhandler.Event。 即 abstraction/ 层并非完全不碰 AE2 内部类 —— CableBusContainer(parts/)被直接暴露在抽象接口里。

4 个方法的实现

IFMP 方法 FMP.java 行号
getOrCreateHost(TileEntity) 见 ImmibisMicroblocks.java:77 同名方法(不同类)
getCableContainer(TileEntity) —
registerPassThrough(Class) 157-164
newFMPPacketEvent(EntityPlayerMP) 178-180

newFMPPacketEvent(:178-180)返回 new FMPPacketEvent(sender)。 其消费者在 appeng/fmp/FMPEvent.java:45 的 ServerFMPEvent(FMPPacketEvent),与 core/sync/packets/PacketMultiPart.java:44 的 MinecraftForge.EVENT_BUS.post(fmp.newFMPPacketEvent(sender)) (两处均不在本分片)。

位置相关方法

方法 行号 说明
createAndRegister(IBlockDefinition, int) 70
convertTile(...) 122
getPlacementHelper(...) 134 → new FMPPlacementHelper(mp)
isTileMultipart(TileEntity) 144 te instanceof TileMultipart
registerPassThrough(Class) 157

mod 没装时是否安全跳过

是。codechicken.* 的 import 只在 FMP.class 被加载时解析, McMultipart 未装 → Loader.isModLoaded 为 false → FAILED。

⚠️ 但 FMPPacketEvent(integration/modules/helpers/FMPPacketEvent.java) 可能仍被 AE2 其它地方发包。它是否也走 isEnabled(FMP) 门控, 需读该文件(见 helpers 总览)。

与 Waila 的联动

Waila.java:35-37 在 FMP 启用时额外注册 multipart 的 Waila provider:

if (IntegrationRegistry.INSTANCE.isEnabled(IntegrationType.FMP)) {
    registerPartProvider(registrar, partHost, Class.forName("codechicken.multipart.TileMultipart"));
}

相关条目