电力网络

概述

GT5-Unofficial 的电力传输采用有向图(Directed Graph)作为底层网络结构。每个电缆方块是图中的一个节点(Node),相邻电缆或机器之间通过**路径(Path)**连接。这种设计使得能量可以沿着多条路径从多个电源流向多个消费者,同时自动处理电压等级匹配、电压损失累积和过载检测。

核心组件

节点(Node)

每个电缆方块在网络中对应一个 Node 对象:

字段 类型 含义
mNodeValue int 该节点的电压等级值(用于路由排序)
mHighestNodeValue int 整个网络中最高的节点等级
mNeighbourNodes[6] Node[] 6 个方向的相邻节点(null 表示未连接)
mNodePaths[6] NodePath[] 6 个方向的路径对象(包含损耗、载流量等)
mSelfPath NodePath 该节点自身的路径属性
mConsumers List<ConsumerNode> 连接在该节点的消费者列表
locks[6] Lock[] 6 个方向的锁定状态
mCreationTime long 创建时的 tick 数(防止每 tick 重复生成)

PowerNode 在 Node 基础上增加了 mHadVoltage 字段,标记该节点是否曾经接收过电压(影响消费者供电行为)。

路径(Path / PowerNodePath)

路径代表两个节点之间的电缆段属性:

字段 类型 含义
mLoss long 路径上所有电缆的损耗总和
mMaxAmps long 路径中最弱电缆的载流量
mMaxVoltage long 路径中最弱电缆的额定电压
mAmps long 当前累积电流(用于过载检测)
mVoltage long 当前电压值(用于过压检测)
mPipes List<MetaPipeEntity> 路径上的所有电缆方块

消费者(ConsumerNode)

消费者是电力网络的目的地,包括:

  • NodeEnergyConnected:GT 机器(实现 IEnergyConnected 接口)
  • NodeEnergyReceiver:RF/CoFH 机器(通过 EU→RF 转换接入)

路由算法

节点值层级

电压等级越高 → mNodeValue 越大 → 越靠近电源端
电压等级越低 → mNodeValue 越小 → 越靠近消费端

能量流动方向:高 mNodeValue → 低 mNodeValue(类似于水往低处流)

powerNode() 遍历流程

1. 从电源节点开始
2. 找到需要供电的消费者节点
3. 比较消费者与当前的 mNodeValue:
   - 如果消费者等级更低:向下遍历(向低等级节点方向)
   - 如果消费者等级更高:向上遍历(向高等级节点方向,但不超过网络最高值)
4. 沿着路径逐段传递能量,每段扣除电压损失
5. 当到达等级匹配的节点时,注入能量到消费者
6. 循环直到所有消费者都被处理或电流耗尽

电压损失累积

long tVoltLoss = 0;
if (tSelfPath != null) {
    tVoltLoss += tSelfPath.getLoss();           // 自身电缆损耗
    tSelfPath.applyVoltage(aVoltage, false);
}
tPath.applyVoltage(aVoltage - tVoltLoss, true); // 下一段施加剩余电压
tVoltLoss += tPath.getLoss();                    // 累加下一段损耗
// 继续向下一节点传递,电压逐渐降低

循环保护

路由算法有最大 20 次迭代的循环保护:

// 如果 20 次迭代仍未找到目标节点,抛出异常
if (iterations > 20) {
    throw new NullPointerException("infinite loop in powering nodes");
}

网络生命周期

网络形成

当电缆被放置并连接到机器或另一根电缆时:

  1. checkConnections() 被调用(每 20 tick 检查一次,或连接变化时立即检查)
  2. 电缆调用 joinEnet() 加入网络
  3. 创建 Node 和 NodePath 对象
  4. 相邻节点相互注册为邻居

网络断开

当电缆被破坏时:

  1. 该电缆的 Node 从网络中移除
  2. 相邻节点的邻居引用被清除
  3. 路径(Path)对象被销毁
  4. 如果路径上有 Lock,锁定状态仍然保留(永久锁定)

锁定状态

当路径发生过载(燃烧)时:

lock.addTileEntity(null);  // null 被添加到锁定列表
// isLocked() 永远返回 true(除非重载世界)

被锁定的路径在后续所有遍历中被直接跳过:

if (aCurrentNode.locks[ordinalSide].isLocked()) {
    return 0;  // 跳过该方向
}

与 IC2 / RF 的兼容性

IC2 兼容

GT5 可以与 IndustrialCraft² 互操作:

// Util.emitEnergyToNetwork 中处理
for (IC2EnergySink sink : adjacentIC2Sinks) {
    sink.acceptEnergyFrom(emitter);
    sink.injectEnergy(...);
}

RF/CoFH 兼容

RF 机器通过 NodeEnergyReceiver 接入:

// EU → RF 转换
rfOut = (voltage * GregTechAPI.mEUtoRF) / 100;
mTileEntity.receiveEnergy(side, rfOut, false);

// 可选:RF 爆炸保护
if (GregTechAPI.mRFExplosions && machineCapacity < rfOut * 600) {
    explode();  // 容量不足的 RF 机器会爆炸
}

玩家可观测的网络状态

扫描仪读取

使用扫描仪或 Waila bmod 可以查看:

  • 当前电缆电压和电流
  • 电缆最大载流量
  • 能量吞吐量(EU/t)
  • 路径状态(正常/锁定)
  • 平均电压/电流(1 秒滚动平均)

玩家行为对网络的影响

玩家操作 网络效果
放置电缆 创建新节点,加入网络
破坏电缆 节点从网络移除,路径断开
安装 Cover 阻止该方向的能量流向(类似断路)
移除 Cover 恢复该方向的能量流动
更换电缆类型 节点属性更新,可能改变载流量/损耗
破坏并替换电缆 重置该路径的 Lock 状态

网络设计建议

拓扑原则

  1. 同等级连接:同一电压等级的设备之间使用同等级电缆
  2. 树形结构优于网状:简单清晰的供电拓扑更容易排查问题
  3. 避免环路:虽然算法有循环保护,但环路会增加不必要的遍历
  4. 分压供电:不同电压等级使用独立的电缆网络,通过变压器连接

变压器中继

长距离输电时,每隔一定距离设置变压器进行电压补偿:

发电机 (HV) → 50 格铜缆 → 变压器降压 → 分送到 MV 设备

变压器可以恢复电压水平,确保下游设备获得足够电压。

相关条目