Hello !
So I have a problem about generating a new type of "Ravine" (called Maw of the Void that litterally pierce trough the Bedrock) but the problem is y can't see if it works because when I try to generate a new world Minecraft freeze at the beginning...
I don't know what I did wrong, I even try with a normal ravin code but Minecraft freeze again, maybe a problem with the InitMapGenEvent ? I don't know...
Here is my code :
Main Mod Class (CotVMod) :
package nk.cotv;
import net.minecraft.potion.Potion;
import net.minecraft.world.WorldType;
import net.minecraftforge.common.BiomeManager.BiomeType;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.registry.GameRegistry;
import nk.cotv.entities.EntitySpiritOfTheVoid;
import nk.cotv.events.MapGenEventHandler;
import nk.cotv.events.PotionEventHandler;
import nk.cotv.gui.GuiScreenOverlay;
import nk.cotv.potions.StressEffect;
@Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION)
public class CotVMod {
@SidedProxy(clientSide = Reference.CLIENTPROXY, serverSide = Reference.COMMONPROXY)
public static CommonProxy proxy;
@Instance(Reference.MODID)
public static CotVMod modInstance;
public static Potion stresseffect = new StressEffect(true, 0x1a0000).setIconIndex(0, 0).setPotionName("potion.stress");
public static MapGenBase mawOfTheVoidGenerator;
@EventHandler
public static void preInit(FMLPreInitializationEvent event) {
proxy.preInit(event);
EntitySpiritOfTheVoid.MainRegistry();
mawOfTheVoidGenerator = new MapGenMawOfTheVoid();
MinecraftForge.EVENT_BUS.register(new PotionEventHandler());
MinecraftForge.TERRAIN_GEN_BUS.register(new MapGenEventHandler());
}
@EventHandler
public static void init(FMLInitializationEvent event) {
proxy.init(event);
}
@EventHandler
public static void postInit(FMLPostInitializationEvent event) {
proxy.postInit(event);
}
}
My custom map gen class, basicaly it's like a ravine but with little changes so I can make the difference between them and normal ravin for testing purpose so it's not finished :
package nk.cotv.world.gen;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.MapGenBase;
public class MapGenMawOfTheVoid extends MapGenBase {
protected static final IBlockState AIR = Blocks.AIR.getDefaultState();
private final float[] rs = new float[1024];
protected void addTunnel(long seed, int chunkX, int chunkZ, ChunkPrimer primer, double blockX, double blockY, double blockZ, float scale, float leftRightRadian, float upDownRadian, int currentY, int targetY, double scaleHeight)
{
Random random = new Random(seed);
double centerX = (double)(chunkX * 16 + 8);
double centerZ = (double)(chunkZ * 16 + 8);
float leftRightChange = 0.0F;
float upDownChange = 0.0F;
if (targetY <= 0)
{
int blockRangeY = this.range * 16 - 16;
targetY = blockRangeY - random.nextInt(blockRangeY / 4);
}
boolean createFinalRoom = false;
if (currentY == -1)
{
currentY = targetY / 2;
createFinalRoom = true;
}
float nextInterHeight = 1.0F;
for (int j = 0; j < 256; ++j)
{
if (j == 0 || random.nextInt(3) == 0)
{
nextInterHeight = 1.0F + random.nextFloat() * random.nextFloat();
}
this.rs[j] = nextInterHeight * nextInterHeight;
}
for (; currentY < targetY; ++currentY)
{
double roomWidth = 2.5D + (double)(MathHelper.sin((float)currentY * (float)Math.PI / (float)targetY) * scale);
double roomHeight = roomWidth * scaleHeight;
roomWidth = roomWidth * ((double)random.nextFloat() * 0.25 + 0.75D);
roomHeight = roomHeight * ((double)random.nextFloat() * 0.25 + 0.75D);
float moveHorizontal = MathHelper.cos(upDownRadian);
float moveVertical = MathHelper.sin(upDownRadian);
blockX += (double)(MathHelper.cos(leftRightRadian) * moveHorizontal);
blockY += (double)moveVertical;
blockZ += (double)(MathHelper.sin(leftRightRadian) * moveHorizontal);
upDownRadian = upDownRadian * 0.7F;
upDownRadian = upDownRadian + upDownChange * 0.05F;
leftRightRadian += leftRightChange * 0.05F;
upDownChange = upDownChange * 0.8F;
leftRightRadian = leftRightRadian * 0.5F;
upDownChange = upDownChange + (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F;
leftRightRadian = leftRightRadian + (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0F;
if (createFinalRoom || random.nextInt(4) != 0)
{
double distanceX = blockX - centerX;
double distanceZ = blockZ - centerZ;
double distanceY = (double)(targetY - currentY);
double maxDistance = (double)(scale + 2.0F + 16.0F);
if (distanceX * distanceX + distanceZ * distanceZ - distanceY * distanceY > maxDistance * maxDistance)
{
return;
}
if (blockX >= centerX - 16.0D - roomWidth * 2.0D && blockZ >= centerZ - 16.0D - roomWidth * 2.0D && blockX <= centerX + 16.0D + roomWidth * 2.0D && blockZ <= centerZ + 16.0D + roomWidth * 2.0D)
{
int xLow = MathHelper.floor(blockX - roomWidth) - chunkX * 16 - 1;
int xHigh = MathHelper.floor(blockX + roomWidth) - chunkX * 16 + 1;
int yLow = MathHelper.floor(blockY - roomHeight) - 1;
int yHigh = MathHelper.floor(blockY + roomHeight) + 1;
int zLow = MathHelper.floor(blockZ - roomWidth) - chunkZ * 16 - 1;
int zHigh = MathHelper.floor(blockZ + roomWidth) - chunkZ * 16 + 1;
for (int x = xLow; x < xHigh; ++x)
{
double xScale = (chunkX * 16 + x + 0.5D - blockX) / roomWidth;
for (int z = zLow; z < zHigh; ++z)
{
double zScale = (chunkZ * 16 + z + 0.5D - blockZ) / roomWidth;
if (xScale * xScale + zScale * zScale < 1.0D)
{
for (int y = yHigh - 1; y >= yLow; --y)
{
double yScale = (y + 0.5D - blockY) / roomHeight;
if ((xScale * xScale + zScale * zScale) * rs[y] + yScale * yScale / 6.0D < 1.0D)
{
digBlock(primer, x, y, z, chunkX, chunkZ, false);
}
}
}
}
}
if (createFinalRoom) {
break;
}
}
}
}
}
/**
* Recursively called by generate()
*/
@Override
protected void recursiveGenerate(World worldIn, int chunkX, int chunkZ, int originalX, int originalZ, ChunkPrimer chunkPrimerIn)
{
if (this.rand.nextInt(15) == 0)
{
int worldHeight = world.getActualHeight();
double blockX = chunkX * 16 + rand.nextInt(16);
double blockY = rand.nextInt(rand.nextInt(worldHeight / 2) + world.provider.getAverageGroundLevel() + 10);
double blockZ = chunkZ * 16 + rand.nextInt(16);
float leftRightRadian = rand.nextFloat() * (float)Math.PI * 2.0F;
float upDownRadian = (rand.nextFloat() - 0.5F) * 2.0F / 8.0F;
float scale = (rand.nextFloat() * 6.0F + rand.nextFloat()) * 6.0F;
if (blockY > worldHeight - 40)
{
blockY = world.provider.getAverageGroundLevel() + rand.nextInt(10);
}
addTunnel(rand.nextLong(), originalX, originalZ, chunkPrimerIn, blockX, blockY, blockZ, scale, leftRightRadian, upDownRadian, 0, 0, 3.0D);
}
}
//Exception biomes to make sure we generate like vanilla
private boolean isExceptionBiome(net.minecraft.world.biome.Biome biome)
{
if (biome == net.minecraft.init.Biomes.BEACH) return true;
if (biome == net.minecraft.init.Biomes.OCEAN) return true;
if (biome == net.minecraft.init.Biomes.DEEP_OCEAN) return true;
if (biome == net.minecraft.init.Biomes.RIVER) return true;
if (biome == net.minecraft.init.Biomes.MUSHROOM_ISLAND) return true;
if (biome == net.minecraft.init.Biomes.MUSHROOM_ISLAND_SHORE) return true;
if (biome == net.minecraft.init.Biomes.FROZEN_OCEAN) return true;
if (biome == net.minecraft.init.Biomes.FROZEN_RIVER) return true;
if (biome == net.minecraft.init.Biomes.MUTATED_SWAMPLAND) return true;
if (biome == net.minecraft.init.Biomes.STONE_BEACH) return true;
return false;
}
/**
* Digs out the current block, default implementation removes stone, filler, and top block
* Sets the block to lava if y is less then 10, and air other wise.
* If setting to air, it also checks to see if we've broken the surface and if so
* tries to make the floor the biome's top block
*
* @param data Block data array
* @param index Pre-calculated index into block data
* @param x local X position
* @param y local Y position
* @param z local Z position
* @param chunkX Chunk X position
* @param chunkZ Chunk Y position
* @param foundTop True if we've encountered the biome's top block. Ideally if we've broken the surface.
*/
protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop)
{
net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16));
IBlockState state = data.getBlockState(x, y, z);
IBlockState top = isExceptionBiome(biome) ? Blocks.GRASS.getDefaultState() : biome.topBlock;
IBlockState filler = isExceptionBiome(biome) ? Blocks.DIRT.getDefaultState() : biome.fillerBlock;
if (state.getBlock() == Blocks.STONE || state.getBlock() == top.getBlock() || state.getBlock() == filler.getBlock() || state.getBlock() == Blocks.FLOWING_WATER || state.getBlock() == Blocks.WATER || state.getBlock() == Blocks.FLOWING_LAVA || state.getBlock() == Blocks.LAVA || state.getBlock() == Blocks.BEDROCK)
{
data.setBlockState(x, y, z, AIR);
if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == filler.getBlock())
{
data.setBlockState(x, y - 1, z, top.getBlock().getDefaultState());
}
}
}
}
The event handler class that is supposed to generate my custom ravine in the world :
package nk.cotv.events;
import net.minecraftforge.event.terraingen.InitMapGenEvent;
import net.minecraftforge.event.terraingen.InitMapGenEvent.EventType;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import nk.cotv.CotVMod;
public class MapGenEventHandler {
@SubscribeEvent(priority = EventPriority.LOWEST)
public void caveControl(InitMapGenEvent event) {
if(event.getType() == EventType.CUSTOM) {
event.setNewGen(CotVMod.mawOfTheVoidGenerator);
}
}
}
If someone can help me please, I am using Forge 1.12.1-14.22.0.2463