末地维度覆盖

基本信息

属性 值
覆盖的维度 维度 ID 1(原版末地) —— 本模组不新增维度,而是完全替换末地
维度提供者 WorldProviderHardcoreEnd extends WorldProviderEnd
区块提供者 ChunkProviderHardcoreEnd extends ChunkProviderEnd
生物群系 BiomeGenHardcoreEnd(9) extends BiomeGenEnd,替换 BiomeGenBase.sky
注册点 HardcoreEnderExpansion.java:126(preInit)、:187(postInit)
数据源 world/DimensionOverride.java、world/WorldProviderHardcoreEnd.java、world/ChunkProviderHardcoreEnd.java、world/biome/

功能

本模组把末地当作可重置的挑战区:击杀末影龙的次数会持久化到存档,并反向影响末影龙血量与末地种子。

维度提供者(world/WorldProviderHardcoreEnd.java)

@Override
public IChunkProvider createChunkGenerator() {
    return new ChunkProviderHardcoreEnd(worldObj, worldObj.getSeed());
}

@Override
public long getSeed() {
    return super.getSeed() + WorldDataHandler.<DragonSavefile>get(DragonSavefile.class).getDragonDeathAmount();
}

getSeed() 在原版种子基础上加上末影龙死亡次数(:17-19)。每多杀一次龙,末地地形种子整体改变一次 —— 这是「重置末地」的实现方式。

维度注册(world/DimensionOverride.java)

setup() 在 preInit 调用(:27-44):

  1. 把 BiomeGenBase.getBiomeGenArray()[9] 置 null(:28)
  2. 反射替换 BiomeGenBase.sky 字段为 new BiomeGenHardcoreEnd(9).setColor(8421631).setBiomeName("Sky").setDisableRain()(:29-32)
  3. 恢复数组项 9(:33)
  4. 注册结构 IO:StructureTower / ComponentTower(hardcoreenderdragon_EndTower / ..._EndTowerC)、StructureIsland / ComponentIsland(hardcoreenderdragon_EndIsland / ..._EndIslandC)(:35-39)
  5. 若 BiomeGenHardcoreEnd.overrideWorldGen 为真,注册 DimensionOverride 自身为 WorldEvent.Load 监听者(:43)

postInit() 在 postInit 调用(:46-54):

  1. 完整性校验:若 BiomeGenBase.sky 不是 BiomeGenHardcoreEnd 实例,抛 RuntimeException 拒绝继续(:47-49)
  2. 调用 overrideMobLists()(:50)
  3. DimensionManager.unregisterProviderType(1) 后 registerProviderType(1, WorldProviderHardcoreEnd.class, false)(:52-53)

verifyIntegrity()(:56-68)反射读取 DimensionManager.providers 静态 Hashtable,校验 ID 1 的类是否正确 —— 捕获 NullPointerException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException 后包装为 RuntimeException("End world provider check failed!", e)。该方法确实被调用:HardcoreEnderExpansion.java:199。

onWorldLoad(WorldEvent.Load)(:72-81)在 overrideWorldGen 开启时,把 WorldServer 的 chunkProvider 字段反射替换为 ChunkProviderServerOverride。内嵌类 ChunkProviderServerOverride extends ChunkProviderServer 重写 populate,先调 provideChunk 再调 super.populate(:92-104)。

区块生成(world/ChunkProviderHardcoreEnd.java)

重写方法 行为 位置
replaceBiomeBlocks 未开 overrideWorldGen 时广播 ChunkProviderEvent.ReplaceBiomeBlocks(Result.DENY 即返回);把全部 32768 个方块槽中的 Blocks.stone 换成 Blocks.end_stone;维度 ID 为 1 时运行 islandGen 与 towerGen :40-63
populate 置 BlockFalling.fallInstantly = true;未开 overrideWorldGen 时广播 PopulateChunkEvent.Pre;维度 ID 为 1 时 generateStructuresInChunk 两个生成器;调用 ((BiomeGenHardcoreEnd) BiomeGenBase.sky).decorate(...);最后广播 PopulateChunkEvent.Post 并复位 fallInstantly :65-85
recreateStructures 维度 ID 为 1 时以 blocks = null 重建两个生成器 :87-93
func_147416_a 恒返回 null(禁用原版末影传送门的地图定位) :95-98

populate 捕获 ConcurrentModificationException 后只 e.printStackTrace(),源码注释为 // I have no fucking clue(:75-77)。这属于作者显式标注的已知情况,有 intent evidence(源码注释本身),故不是缺陷。

数值

数值名 值 位置
末影龙死亡次数对种子的加成 + getDragonDeathAmount() WorldProviderHardcoreEnd.java:18
末影龙死亡次数对血量的加成 min(90, 次数 × 15) EntityBossDragon.java:158-159
末地生物群系 ID 9 DimensionOverride.java:32
末地群系颜色 8421631(0x8080AF) DimensionOverride.java:32
末地群系名 "Sky" DimensionOverride.java:32
方块替换扫描量 32768 个槽位 ChunkProviderHardcoreEnd.java:55

交互

触发 行为
玩家进入末地 WorldEvent.Load → 若 overrideWorldGen 则替换区块提供者
区块生成 两个 MapGen(岛 + 塔)在维度 1 中运行
末影龙死亡 死亡次数写入 DragonSavefile,影响下次 getSeed() 与龙血量
维度加载顺序 若别的模组先替换了 BiomeGenBase.sky,本模组 postInit 直接抛异常终止

未注册内容

world/structure/sanctuary/(MapGenSanctuary / StructureSanctuary / ComponentSanctuary / 2 个 data 生成器,5 个文件)完全未接入:DimensionOverride.java:40-41 的两行 MapGenStructureIO 注册被 // TODO SANCTUARY 注释。grep -rn MapGenSanctuary src/main/java 显示除自身文件外零引用。仓库有 // TODO SANCTUARY 注释作为 intent evidence,属未完成功能。

相关条目

  • 生态岛 - 3 种生态岛
  • 结构 - 龙巢神殿、塔、废墟
  • 世界生成 - 6 个 WorldGen 特性
  • 怪物 - 刷怪列表替换
  • 配置 - overrideWorldGen / overrideBiomeMobs / overworldEndermanMultiplier