污染系统
基本信息
gregtech/common/pollution/ 下 10 个类构成的逐区块污染模拟系统。
本条目补齐物品效果 · Pollution里只有概念描述、
没有具体数值的部分。
| 类 | 行 | 作用 |
|---|---|---|
Pollution |
618 | 主类:每维度一个实例 |
PollutionConfig |
— | @Config 全部污染参数 |
PollutionHelper |
17 | 炉灶按秒排放的便利方法 |
FurnacePollution |
枚举 | 8 种炉子的污染倍率 |
BlockMatcher |
— | 客户端植物染色匹配器 |
ColorOverrideType |
枚举 | 染色类型 |
EntityFXPollution |
— | 污染粒子实体 |
PollutionRenderer |
— | 区块污染着色渲染 |
PollutionTooltip |
— | 悬停提示 |
GTClientPollutionMap |
— | 客户端已知污染值缓存 |
主循环
| 常量 | 值 | 位置 |
|---|---|---|
cycleLen |
1200 tick(60 s) | Pollution.java:81 |
POLLUTIONPACKET_MINVALUE |
1000 | Pollution.java:86 |
| 衰减系数 | tPollution = (int)(0.9945f * tPollution) |
:153 |
| 扩散阈值 | tPollution > 400000 |
:154 |
| 每 tick 处理区块数 | max(1, pollutionList.size() / cycleLen) |
:141 |
onWorldTick 只在 Phase.END 生效(START 直接 return),
并按 world.provider.dimensionId 从
GTMod.proxy.dimensionWisePollution 取该维度的实例 ——
null(未启用污染的维度)直接返回。
每 tick 末尾 setChunkPollution(actualPos, tPollution) 无条件写回,
即使值没变。
扩散算法
只向 4 个正交邻居(+X / −X / +Z / −Z)扩散,无对角。触发条件
neighborPollution * 6 < tPollution * 5(即邻居低于本区块的 5/6),
转移量 tDiff = (tPollution - neighborPollution) / 20,
本区块同步减去同一份 tDiff(守恒)。
四级效果阈值
全部读 GTMod.proxy 的配置,且逐级嵌套 —— 只有超过上一级才检查下一级:
| 级别 | 阈值字段 | 效果 |
|---|---|---|
| 1 | mPollutionSmogLimit |
随机三选一:虚弱 / 缓慢 / 挖掘缓慢(nextInt(3)) |
| 2 | mPollutionPoisonLimit |
随机四选一:反胃 / 中毒 / 失明 / 饥饿(nextInt(4)) |
| 3 | mPollutionVegetationLimit |
破坏植物,for (f = 20; f < tPollution/25000; f++) |
| 4 | mPollutionSourRainLimit |
作为 damageBlock 的 sourRain 入参 |
效果持续/强度:
| 效果 | 时长 | 等级 |
|---|---|---|
| 虚弱 / 缓慢 / 挖掘缓慢 | min(tPollution / 1000, 1000) |
tPollution / 400000 |
| 反胃 / 失明 | min(tPollution / 2000, 1000) |
1(写死) |
| 中毒 | min(tPollution / 4000, 1000) |
tPollution / 500000 |
| 饥饿 | tPollution / 500000(无 min 夹取) |
0 |
豁免:两类效果都跳过
EntityPlayerMP 且 capabilities.isCreativeMode 的玩家,
以及 HazardProtection.isWearingFullGasHazmat(tEnt) 为真的实体
(即穿全套防化服免疫)。植物破坏不受此豁免。
switch 用的是 fall-through(无 break),
所以 nextInt(3) 命中 case 1 时会同时进入 case 2 和 default;
nextInt(4) 同理。这是刻意的概率叠加而非 bug。
植物破坏坐标
int x = (chunkX << 4) + nextInt(16);
int y = 60 + (-f + nextInt(f * 2 + 1));
int z = (chunkZ << 4) + nextInt(16);
Y 基准恒为 60(不是地形高度),并按 f 在 [60-f, 60+f] 内展开 ——
即 f 越大被扫描的高度带越宽。
8 种炉子的污染倍率
FurnacePollution 枚举,实际污染量 =
Math.round(PollutionConfig.furnacePollutionAmount × 倍率),
furnacePollutionAmount 默认 20、注释要求 min 1!:
| 炉子 | 倍率 | 默认每 tick |
|---|---|---|
BLAST_FURNACE |
2.0 | 40 |
SMOKER |
2.0 | 40 |
IRON_FURNACE |
1.2 | 24 |
FURNACE |
1.0 | 20 |
ALCHEMICAL_FURNACE |
1.0 | 20 |
ADVANCED_ALCHEMICAL_FURNACE |
1.0 | 20 |
SLAB_FURNACE |
1.0 | 20 |
NETHER_FURNACE |
0.5 | 10 |
PollutionHelper.furnaceAddPollutionOnUpdate 只在
world.getTotalWorldTime() % 20 == 0 时排放(即每秒一次),
且 world.isRemote 时直接返回。
机器排放默认值(PollutionConfig)
| 配置项 | 默认 | 备注 |
|---|---|---|
pollutionHighPressureLavaBoilerPerSecond |
20 | 线圈锅炉 |
pollutionHighPressureCoalBoilerPerSecond |
30 | 高压线圈锅炉 |
pollutionBaseDieselGeneratorPerSecond |
40 | 基础柴油发电机 |
pollutionBaseGasTurbinePerSecond |
40 | 基础燃气轮机 |
pollutionDieselGeneratorReleasedByTier[] |
{0.1, 1.0, 0.9, 0.8, 0.7, 0.6} |
6 档,index 0 是 LV |
pollutionGasTurbineReleasedByTier[] |
同上 | 6 档 |
explosionPollutionAmount |
333.34 | 爆炸(float) |
furnacesPollute |
true |
|
furnacePollutionAmount |
20 | |
rocketPollutionAmount |
10000 | Galacticraft 火箭 |
rocketsPollute |
true |
pollutionHighPressureCoalBoilerPerSecond默认 30,高于 同类的…LavaBoilerPerSecond(20)—— 煤锅炉比熔岩锅炉排放更多, 读配置时容易记反。
各 tier 数组的注释明确:第 0 项有意义,因为数组下标即机器 tier
(LV is 1 指的是机器 tier 1,对应数组 index 0)。
5 个 BlockMatcher
onPostInitClient 在 PollutionConfig.pollution 为真时创建并注册到
Forge 事件总线:
| 字段 | 配置来源 |
|---|---|
standardBlocks |
renderStandardBlock |
liquidBlocks |
renderBlockLiquid |
doublePlants |
renderBlockDoublePlant |
crossedSquares |
renderCrossedSquares |
blockVine |
renderblockVine |
最后一个配置键
renderblockVine的小写 b 与前四个的renderBlock…驼峰不一致。五个字段全是public static且只在客户端初始化 —— 服务器端访问会 NPE。
BlockMatcher 三个数据成员:whiteList
(Map<Class<?>, ColorOverrideType>)、blackList(Set<Class<?>>)、
blockIDs(Map<Integer, ColorOverrideType>)。
数据存储与同步
| 机制 | 实现 |
|---|---|
| 存储 | Storage extends GTChunkAssociatedData<ChunkData>,private static final |
| 迁移 | migrate(ChunkDataEvent.Load) + GT_PollutionEventHandler 监听 ChunkWatchEvent |
| 同步 | tPollution > 1000 时用 GTValues.NW.sendToAllAround(new GTPacketPollution(...), TargetPoint),锚点 (chunkX<<4, 64, chunkZ<<4)、范围 256 |
addPollution 有 4 个重载(IGregTechTileEntity / TileEntity /
Chunk / World+坐标),后三者都先判
!GTMod.proxy.mPollution || aPollution == 0 || isRemote 返回。
相关条目
- 物品效果 · Pollution — 本系统的概念版条目
- Hazmat 附魔 — 防化服是污染豁免的关键
- GT Commands
源码
src/main/java/gregtech/common/pollution/(10 个.java)src/main/java/gregtech/api/GregTechAPI.java(GT_PollutionEventHandler注册)- 复算:
ls src/main/java/gregtech/common/pollution/ | wc -l→ 10