From 264ee49212817a2d7ae85e36ddcde3538531fbd2 Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 6 Oct 2025 18:38:01 +1100 Subject: [PATCH] replace sellafield craters (already had the crater code so why not) --- src/main/java/com/hbm/lib/HbmWorld.java | 21 +++++ src/main/java/com/hbm/lib/HbmWorldGen.java | 18 ---- .../com/hbm/world/feature/Sellafield.java | 71 --------------- .../com/hbm/world/gen/MapGenChainloader.java | 75 ++++++++++++++++ .../java/com/hbm/world/gen/MapGenCrater.java | 90 +++++++++++++++++++ 5 files changed, 186 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/com/hbm/world/feature/Sellafield.java create mode 100644 src/main/java/com/hbm/world/gen/MapGenChainloader.java create mode 100644 src/main/java/com/hbm/world/gen/MapGenCrater.java diff --git a/src/main/java/com/hbm/lib/HbmWorld.java b/src/main/java/com/hbm/lib/HbmWorld.java index 537309fb7..ca4732b70 100644 --- a/src/main/java/com/hbm/lib/HbmWorld.java +++ b/src/main/java/com/hbm/lib/HbmWorld.java @@ -1,5 +1,11 @@ package com.hbm.lib; +import com.hbm.world.gen.MapGenChainloader.MapGenEventHandler; +import com.hbm.world.gen.MapGenCrater; +import com.hbm.blocks.ModBlocks; +import com.hbm.config.GeneralConfig; +import com.hbm.config.WorldConfig; +import com.hbm.world.gen.MapGenChainloader; import com.hbm.world.gen.MapGenNTMFeatures; import com.hbm.world.gen.NTMWorldGenerator; import com.hbm.world.gen.component.*; @@ -8,6 +14,7 @@ import com.hbm.world.gen.nbt.NBTStructure; import cpw.mods.fml.common.IWorldGenerator; import cpw.mods.fml.common.registry.GameRegistry; +import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.gen.structure.MapGenStructureIO; import net.minecraftforge.common.MinecraftForge; @@ -31,6 +38,9 @@ public class HbmWorld { MinecraftForge.EVENT_BUS.register(worldGenerator); NBTStructure.register(); + + MinecraftForge.TERRAIN_GEN_BUS.register(new MapGenEventHandler()); + registerNTMTerrain(); } private static void registerWorldGen(IWorldGenerator nukerWorldGen, int weightedProbability) { @@ -45,4 +55,15 @@ public class HbmWorld { BunkerComponents.registerComponents(); MapGenStructureIO.func_143031_a(SiloComponent.class, "NTMSiloComponent"); } + + /** Register multi-chunk spanning terrain features using chainloader */ + private static void registerNTMTerrain() { + if(GeneralConfig.enableRad && WorldConfig.radfreq > 0) { + MapGenCrater sellafieldCrater = new MapGenCrater(WorldConfig.radfreq); + sellafieldCrater.regolith = sellafieldCrater.rock = ModBlocks.sellafield_slaked; + sellafieldCrater.targetBiome = BiomeGenBase.desert; + MapGenChainloader.addOverworldGenerator(sellafieldCrater); + } + } + } diff --git a/src/main/java/com/hbm/lib/HbmWorldGen.java b/src/main/java/com/hbm/lib/HbmWorldGen.java index dd7af4b60..6d004cbf9 100644 --- a/src/main/java/com/hbm/lib/HbmWorldGen.java +++ b/src/main/java/com/hbm/lib/HbmWorldGen.java @@ -386,24 +386,6 @@ public class HbmWorldGen implements IWorldGenerator { } } - if(WorldConfig.radfreq > 0 && GeneralConfig.enableRad && rand.nextInt(WorldConfig.radfreq) == 0 && biome == BiomeGenBase.desert) { - - for (int a = 0; a < 1; a++) { - int x = i + rand.nextInt(16); - int z = j + rand.nextInt(16); - - double r = rand.nextInt(15) + 10; - - if(rand.nextInt(50) == 0) - r = 50; - - new Sellafield().generate(world, x, z, r, r * 0.35D); - - if(GeneralConfig.enableDebugMode) - MainRegistry.logger.info("[Debug] Successfully spawned raditation hotspot at " + x + " " + z); - } - } - if (WorldConfig.geyserChlorine > 0 && biome == BiomeGenBase.plains && rand.nextInt(WorldConfig.geyserWater) == 0) { int x = i + rand.nextInt(16); int z = j + rand.nextInt(16); diff --git a/src/main/java/com/hbm/world/feature/Sellafield.java b/src/main/java/com/hbm/world/feature/Sellafield.java deleted file mode 100644 index 98a6d615d..000000000 --- a/src/main/java/com/hbm/world/feature/Sellafield.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.hbm.world.feature; - -import java.util.Random; - -import com.hbm.blocks.ModBlocks; - -import net.minecraft.block.Block; -import net.minecraft.world.World; - -public class Sellafield { - - private double depthFunc(double x, double rad, double depth) { - - return -Math.pow(x, 2) / Math.pow(rad, 2) * depth + depth; - } - - public void generate(World world, int x, int z, double radius, double depth) { - - if(world.isRemote) - return; - - Random rand = new Random(); - - int iRad = (int)Math.round(radius); - - for(int a = -iRad - 5; a <= iRad + 5; a++) { - - for(int b = -iRad - 5; b <= iRad + 5; b++) { - - double r = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); - - if(r - rand.nextInt(3) <= radius) { - - int dep = (int)depthFunc(r, radius, depth); - dig(world, x + a, z + b, dep); - - if(r + rand.nextInt(3) <= radius / 3D) { - place(world, x + a, z + b, 3, ModBlocks.sellafield, 1); - } else if(r - rand.nextInt(3) <= radius / 3D * 2D) { - place(world, x + a, z + b, 3, ModBlocks.sellafield); - } else { - place(world, x + a, z + b, 3, ModBlocks.sellafield_slaked); - } - } - } - } - } - - private void dig(World world, int x, int z, int depth) { - - int y = world.getHeightValue(x, z) - 1; - - if(y < depth * 2) - return; - - for(int i = 0; i < depth; i++) - world.setBlockToAir(x, y - i, z); - } - - private void place(World world, int x, int z, int depth, Block block) { place(world, x, z, depth, block, 0); } - - private void place(World world, int x, int z, int depth, Block block, int meta) { - - int y = world.getHeightValue(x, z) - 1; - - for(int i = 0; i < depth; i++) - world.setBlock(x, y - i, z, block, meta, 2); - } - - //private void placeCore(World world, int x, int z, double rad) { } -} diff --git a/src/main/java/com/hbm/world/gen/MapGenChainloader.java b/src/main/java/com/hbm/world/gen/MapGenChainloader.java new file mode 100644 index 000000000..3f9c96018 --- /dev/null +++ b/src/main/java/com/hbm/world/gen/MapGenChainloader.java @@ -0,0 +1,75 @@ +package com.hbm.world.gen; + +import java.util.ArrayList; +import java.util.List; + +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.block.Block; +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.gen.MapGenBase; +import net.minecraftforge.event.terraingen.InitMapGenEvent; +import net.minecraftforge.event.terraingen.InitMapGenEvent.EventType; + +public class MapGenChainloader extends MapGenBase { + + /** + * There is no way - with existing forge hooks - to add entirely new `MapGenBase` generators to existing dimensions (overworld, nether). + * So, in order to fix that (while not breaking mods like Greg's Caves), we chainload our own MapGenBase into the existing cave generator + */ + + private MapGenBase parent; + + private List generators = new ArrayList<>(); + + // These may be added to before OR after mapgen registration safely + private static List overworldGenerators = new ArrayList<>(); + private static List netherGenerators = new ArrayList<>(); + + // Executes our chainloaded parent, and all our child generators + @Override + public void func_151539_a(IChunkProvider chunk, World world, int chunkX, int chunkZ, Block[] blocks) { + parent.func_151539_a(chunk, world, chunkX, chunkZ, blocks); + + // Some mods may use vanilla gen events for added dimensions, so we guard against that here + if(world.provider.dimensionId != 0 && world.provider.dimensionId != -1) return; + + for(MapGenBase generator : generators) { + generator.func_151539_a(chunk, world, chunkX, chunkZ, blocks); + } + } + + public static void addOverworldGenerator(MapGenBase generator) { + if(overworldGenerators.contains(generator)) return; + overworldGenerators.add(generator); + } + + public static void addNetherGenerator(MapGenBase generator) { + if(netherGenerators.contains(generator)) return; + netherGenerators.add(generator); + } + + public static class MapGenEventHandler { + + // Register as late as possible to pick up any modded cave generators + @SubscribeEvent(priority = EventPriority.LOWEST) + public void addMapGenChainloader(InitMapGenEvent event) { + if(!(event.newGen instanceof MapGenChainloader)) { + if(event.type == EventType.CAVE) { + MapGenChainloader loader = new MapGenChainloader(); + loader.parent = event.newGen; + loader.generators = overworldGenerators; + event.newGen = loader; + } else if(event.type == EventType.NETHER_CAVE) { + MapGenChainloader loader = new MapGenChainloader(); + loader.parent = event.newGen; + loader.generators = netherGenerators; + event.newGen = loader; + } + } + } + + } + +} diff --git a/src/main/java/com/hbm/world/gen/MapGenCrater.java b/src/main/java/com/hbm/world/gen/MapGenCrater.java new file mode 100644 index 000000000..7afc58735 --- /dev/null +++ b/src/main/java/com/hbm/world/gen/MapGenCrater.java @@ -0,0 +1,90 @@ +package com.hbm.world.gen; + +import net.minecraft.block.Block; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.MapGenBase; + +public class MapGenCrater extends MapGenBase { + + private int frequency = 100; + private int minSize = 8; + private int maxSize = 64; + + public Block regolith; + public Block rock; + + public BiomeGenBase targetBiome; + + public MapGenCrater(int frequency) { + this.frequency = frequency; + } + + public void setSize(int minSize, int maxSize) { + this.minSize = minSize; + this.maxSize = maxSize; + + this.range = (maxSize / 8) + 1; + } + + private double depthFunc(double x, double rad, double depth) { + return -Math.pow(x, 2) / Math.pow(rad, 2) * depth + depth; + } + + // This function is looped over from -this.range to +this.range on both XZ axes. + @Override + protected void func_151538_a(World world, int offsetX, int offsetZ, int chunkX, int chunkZ, Block[] blocks) { + if(rand.nextInt(frequency) == 0 && (targetBiome == null || targetBiome == world.getBiomeGenForCoords(offsetX * 16, offsetZ * 16))) { + int xCoord = -offsetX + chunkX; + int zCoord = -offsetZ + chunkZ; + + double radius = rand.nextInt(maxSize - minSize) + minSize; + double depth = radius * 0.35D; + + for(int bx = 15; bx >= 0; bx--) { // bx, bz is the coordinate of the block we're modifying, relative to the generating chunk origin + for(int bz = 15; bz >= 0; bz--) { + for(int y = 254; y >= 0; y--) { + int index = (bx * 16 + bz) * 256 + y; + + if(blocks[index] != null && (blocks[index].isOpaqueCube() || blocks[index].getMaterial().isLiquid())) { + // x, z are the coordinates relative to the target virtual chunk origin + int x = xCoord * 16 + bx; + int z = zCoord * 16 + bz; + + // y is at the current height now + double r = Math.sqrt(x * x + z * z); + + if(r - rand.nextInt(3) <= radius) { + // Carve out to intended depth + int dep = (int)MathHelper.clamp_double(depthFunc(r, radius, depth), 0, y - 1); + for(int i = 0; i < dep; i++) { + blocks[index - i] = null; + } + + index -= dep; + y -= dep; + + dep = Math.min(3, y - 1); + + // Fill back in + if(r + rand.nextInt(3) <= radius / 3D) { + for(int i = 0; i < dep; i++) { + blocks[index - i] = regolith; + } + } else { + for(int i = 0; i < dep; i++) { + blocks[index - i] = rock; + } + } + } + + break; + } + } + } + } + } + } + +}