replace sellafield craters (already had the crater code so why not)

This commit is contained in:
George Paton 2025-10-06 18:38:01 +11:00
parent 15d7edacb5
commit 264ee49212
5 changed files with 186 additions and 89 deletions

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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) { }
}

View File

@ -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<MapGenBase> generators = new ArrayList<>();
// These may be added to before OR after mapgen registration safely
private static List<MapGenBase> overworldGenerators = new ArrayList<>();
private static List<MapGenBase> 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;
}
}
}
}
}

View File

@ -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;
}
}
}
}
}
}
}