Jump to content

[1.10.2] [RESOLVED] Dimension onReplaceBiomeBlocks Issue


CommanderNeville

Recommended Posts

I'm an idiot. Forget you ever saw this. Turns out in my biome code I was using my reference blocks instead of my ModBlocks. Whoops.

I've been having some trouble with onReplaceBiomeBlocks and replaceBiomeBlocks and have been unable to detect exactly what is going wrong. The code being used is recycled from a mod I created (but never posted) which worked in 1.9. Did anything drastic change in that time period?

 

I decided to check the vanilla code for replaceBiomeBlocks but I simply ran into another issue.

 

Against my expectations the mod is having trouble loading the initial chunks.

 

Loading the dimension will work up until it begins loading the actual chunks. One of the errors had to deal with this:

Spoiler

if (j == 0 && iblockstate1.getBlock() == Blocks.SAND && k > 1)

 {
          j = rand.nextInt(4) + Math.max(0, j1 - 63);
          iblockstate1 = iblockstate1.getValue(BlockSand.VARIANT) == BlockSand.EnumType.RED_SAND ? RED_SANDSTONE : SANDSTONE;

 }

 

I do apologize for the messiness of the code; I am relatively new to modding, and any help would be appreciated.

 

The ParadiseChunkGenerator

Spoiler

package com.commander.mgln.world;

import java.awt.List;
import java.util.Random;

import javax.annotation.Nullable;

import com.google.common.collect.ImmutableList;
import com.commander.mgln.init.ModBiomes;

import net.minecraft.entity.EnumCreatureType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldEntitySpawner;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biome.SpawnListEntry;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraft.world.gen.MapGenBase;
import net.minecraft.world.gen.MapGenCaves;
import net.minecraftforge.event.terraingen.TerrainGen;

class ParadiseChunkGenerator implements IChunkGenerator 
{

    private final World worldObj;
    private Random random;
    private Biome[] biomesForGeneration;

    private MapGenBase caveGenerator = new MapGenCaves();
    private ParadiseTerrainGenerator terraingen = new ParadiseTerrainGenerator();

    public ParadiseChunkGenerator(World worldObj) 
    {
        this.worldObj = worldObj;
        long seed = worldObj.getSeed();
        this.random = new Random((seed + 516) * 314);
        terraingen.setup(worldObj, random);
    }

    @Override
    public Chunk provideChunk(int x, int z) 
    {
        ChunkPrimer chunkprimer = new ChunkPrimer();

        // Setup biomes for terraingen
        this.biomesForGeneration = this.worldObj.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10);
        terraingen.setBiomesForGeneration(biomesForGeneration);
        terraingen.generate(x, z, chunkprimer);

        // Setup biomes again for actual biome decoration
        this.biomesForGeneration = this.worldObj.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 16, z * 16, 16, 16);
        // This will replace stone with the biome specific stones
        terraingen.replaceBiomeBlocks(x, z, chunkprimer, biomesForGeneration);
        Chunk chunk = new Chunk(this.worldObj, chunkprimer, x, z);

        byte[] biomeArray = chunk.getBiomeArray();
        for (int i = 0; i < biomeArray.length; ++i) 
        {
            biomeArray = (byte)Biome.getIdForBiome(biomesForGeneration);
        }

        chunk.generateSkylightMap();
        return chunk;
    }

    @Override
    public void populate(int x, int z) 
    {
        int i = x * 16;
        int j = z * 16;
        BlockPos blockpos = new BlockPos(i, 0, j);
        Biome biome = ModBiomes.paradise;

        // Make sure animals appropriate to the biome spawn here when the chunk is generated
        WorldEntitySpawner.performWorldGenSpawning(this.worldObj, biome, i + 8, j + 8, 16, 16, this.random);
    }

    @Override
    public boolean generateStructures(Chunk chunkIn, int x, int z) 
    {
        return false;
    }

    @Override
    public java.util.List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) 
    {
        return null;
    }

    @Nullable
    @Override
    public BlockPos getStrongholdGen(World worldIn, String structureName, BlockPos position) {
        return null;
    }

    @Override
    public void recreateStructures(Chunk chunkIn, int x, int z) {

    }
}

The ParadiseTerrainGenerator

Spoiler

package com.commander.mgln.world;

import java.util.List;
import java.util.Random;

import net.minecraft.block.BlockSand;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
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.biome.Biome;
import net.minecraft.world.biome.Biome.SpawnListEntry;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.gen.NoiseGeneratorOctaves;
import net.minecraft.world.gen.NoiseGeneratorPerlin;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

public class ParadiseTerrainGenerator
{
    private World world;
    private Random random;

    private final double[] heightMap;
    private double[] mainNoiseRegion;
    private double[] minLimitRegion;
    private double[] maxLimitRegion;
    private double[] depthRegion;

    private NoiseGeneratorOctaves minLimitPerlinNoise;
    private NoiseGeneratorOctaves maxLimitPerlinNoise;
    private NoiseGeneratorOctaves mainPerlinNoise;
    private NoiseGeneratorPerlin surfaceNoise;

    // A NoiseGeneratorOctaves used in generating terrain
    private NoiseGeneratorOctaves depthNoise;

    private final float[] biomeWeights;
    private double[] depthBuffer = new double[256];

    private Biome[] biomesForGeneration;
    private World worldObj;

    public ParadiseTerrainGenerator() 
    {
        this.heightMap = new double[825];

        this.biomeWeights = new float[25];
        for (int j = -2; j <= 2; ++j)
        {
            for (int k = -2; k <= 2; ++k) 
            {
                float f = 10.0F / MathHelper.sqrt_float((j * j + k * k) + 0.2F);
                this.biomeWeights[j + 2 + (k + 2) * 5] = f;
            }
        }
    }

    public void setBiomesForGeneration(Biome[] biomesForGeneration) 
    {
        this.biomesForGeneration = biomesForGeneration;
    }

    public void setup(World world, Random rand) 
    {
        this.world = world;
        this.random = rand;

        this.minLimitPerlinNoise = new NoiseGeneratorOctaves(rand, 16);
        this.maxLimitPerlinNoise = new NoiseGeneratorOctaves(rand, 16);
        this.mainPerlinNoise = new NoiseGeneratorOctaves(rand, 8);
        this.surfaceNoise = new NoiseGeneratorPerlin(rand, 4);
        NoiseGeneratorOctaves noiseGen5 = new NoiseGeneratorOctaves(rand, 10);
        this.depthNoise = new NoiseGeneratorOctaves(rand, 16);
        NoiseGeneratorOctaves mobSpawnerNoise = new NoiseGeneratorOctaves(rand, 8);

        net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld ctx =
                new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld(minLimitPerlinNoise,
                    maxLimitPerlinNoise, mainPerlinNoise, surfaceNoise, noiseGen5, depthNoise, mobSpawnerNoise);
        ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(world, rand, ctx);
        this.minLimitPerlinNoise = ctx.getLPerlin1();
        this.maxLimitPerlinNoise = ctx.getLPerlin2();
        this.mainPerlinNoise = ctx.getPerlin();
        this.surfaceNoise = ctx.getHeight();
        this.depthNoise = ctx.getDepth();
    }
    private void generateHeightmap(int chunkX4, int chunkY4, int chunkZ4) 
    {
        this.depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion, chunkX4, chunkZ4, 5, 5, 200.0D, 200.0D, 0.5D);
        this.mainNoiseRegion = this.mainPerlinNoise.generateNoiseOctaves(this.mainNoiseRegion, chunkX4, chunkY4, chunkZ4, 5, 33, 5, 8.55515D, 4.277575D, 8.55515D);
        this.minLimitRegion = this.minLimitPerlinNoise.generateNoiseOctaves(this.minLimitRegion, chunkX4, chunkY4, chunkZ4, 5, 33, 5, 684.412D, 684.412D, 684.412D);
        this.maxLimitRegion = this.maxLimitPerlinNoise.generateNoiseOctaves(this.maxLimitRegion, chunkX4, chunkY4, chunkZ4, 5, 33, 5, 684.412D, 684.412D, 684.412D);
        int l = 0;
        int i1 = 0;

        for (int j1 = 0; j1 < 5; ++j1) 
        {
            for (int k1 = 0; k1 < 5; ++k1) 
            {
                float f = 0.0F;
                float f1 = 0.0F;
                float f2 = 0.0F;
                byte b0 = 2;

                for (int l1 = -b0; l1 <= b0; ++l1) 
                {
                    for (int i2 = -b0; i2 <= b0; ++i2) 
                    {
                        Biome biome = this.biomesForGeneration[j1 + 2 + (k1 + 2) * 10];
                        float baseHeight = biome.getBaseHeight();
                        float variation = biome.getHeightVariation();

                        float f5 = biomeWeights[l1 + 2 + (i2 + 2) * 5] / (baseHeight + 2.0F);
                        f += variation * f5;
                        f1 += baseHeight * f5;
                        f2 += f5;
                    }
                }

                f /= f2;
                f1 /= f2;
                f = f * 0.9F + 0.1F;
                f1 = (f1 * 4.0F - 1.0F) / 8.0F;
                double d12 = this.depthRegion[i1] / 8000.0D;

                if (d12 < 0.0D) 
                {
                    d12 = -d12 * 0.3D;
                }

                d12 = d12 * 3.0D - 2.0D;

                if (d12 < 0.0D) 
                {
                    d12 /= 2.0D;

                    if (d12 < -1.0D) 
                    {
                        d12 = -1.0D;
                    }

                    d12 /= 1.4D;
                    d12 /= 2.0D;
                } 
                else 
                {
                    if (d12 > 1.0D) 
                    {
                        d12 = 1.0D;
                    }

                    d12 /= 8.0D;
                }

                ++i1;
                double d13 = f1;
                double d14 = f;
                d13 += d12 * 0.2D;
                d13 = d13 * 8.5D / 8.0D;
                double d5 = 8.5D + d13 * 4.0D;

                for (int j2 = 0; j2 < 33; ++j2) 
                {
                    double d6 = (j2 - d5) * 12.0D * 128.0D / 256.0D / d14;

                    if (d6 < 0.0D) {
                        d6 *= 4.0D;
                    }

                    double d7 = this.minLimitRegion[l] / 512.0D;
                    double d8 = this.maxLimitRegion[l] / 512.0D;
                    double d9 = (this.mainNoiseRegion[l] / 10.0D + 1.0D) / 2.0D;
                    double d10 = MathHelper.denormalizeClamp(d7, d8, d9) - d6;

                    if (j2 > 29) {
                        double d11 = ((j2 - 29) / 3.0F);
                        d10 = d10 * (1.0D - d11) + -10.0D * d11;
                    }

                    this.heightMap[l] = d10;
                    ++l;
                }
            }
        }
    }
    public void generate(int chunkX, int chunkZ, ChunkPrimer primer) 
    {
        generateHeightmap(chunkX * 4, 0, chunkZ * 4);

        byte waterLevel = 1;
        for (int x4 = 0; x4 < 4; ++x4) 
        {
            int l = x4 * 5;
            int i1 = (x4 + 1) * 5;

            for (int z4 = 0; z4 < 4; ++z4) 
            {
                int k1 = (l + z4) * 33;
                int l1 = (l + z4 + 1) * 33;
                int i2 = (i1 + z4) * 33;
                int j2 = (i1 + z4 + 1) * 33;

                for (int height32 = 0; height32 < 32; ++height32) 
                {
                    double d0 = 0.125D;
                    double d1 = heightMap[k1 + height32];
                    double d2 = heightMap[l1 + height32];
                    double d3 = heightMap[i2 + height32];
                    double d4 = heightMap[j2 + height32];
                    double d5 = (heightMap[k1 + height32 + 1] - d1) * d0;
                    double d6 = (heightMap[l1 + height32 + 1] - d2) * d0;
                    double d7 = (heightMap[i2 + height32 + 1] - d3) * d0;
                    double d8 = (heightMap[j2 + height32 + 1] - d4) * d0;

                    for (int h = 0; h < 8; ++h) 
                    {
                        double d9 = 0.25D;
                        double d10 = d1;
                        double d11 = d2;
                        double d12 = (d3 - d1) * d9;
                        double d13 = (d4 - d2) * d9;
                        int height = (height32 * 8) + h;

                        for (int x = 0; x < 4; ++x) 
                        {
                            double d14 = 0.25D;
                            double d16 = (d11 - d10) * d14;
                            double d15 = d10 - d16;

                            for (int z = 0; z < 4; ++z) 
                            {
                                if (height < 2) 
                                {
                                    primer.setBlockState(x4 * 4 + x, height32 * 8 + h, z4 * 4 + z, Blocks.BEDROCK.getDefaultState());
                                } 
                                else if ((d15 += d16) > 0.0D) 
                                {
                                    primer.setBlockState(x4 * 4 + x, height32 * 8 + h, z4 * 4 + z, Blocks.STONE.getDefaultState());
                                }
                            }

                            d10 += d12;
                            d11 += d13;
                        }

                        d1 += d5;
                        d2 += d6;
                        d3 += d7;
                        d4 += d8;
                    }
                }
            }
        }
    }
    public void replaceBiomeBlocks(int x, int z, ChunkPrimer primer, Biome[] biomesIn)
    {
        if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks((IChunkGenerator) this, x, z, primer, this.worldObj)) return;
        double d0 = 0.03125D;
        this.depthBuffer = this.surfaceNoise.getRegion(this.depthBuffer, (double)(x * 16), (double)(z * 16), 16, 16, 0.0625D, 0.0625D, 1.0D);

        for (int i = 0; i < 16; ++i)
        {
            for (int j = 0; j < 16; ++j)
            {
                Biome biome = biomesIn[j + i * 16];
                biome.genTerrainBlocks(this.worldObj, this.random, primer, x * 16 + i, z * 16 + j, this.depthBuffer[j + i * 16]);
            }
        }
    }
}

Thank you for reading. I hope the issue can be resolved without distress.

Edited by CommanderNeville
Added extra details
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Sonic77 adalah pilihan tepat bagi Anda yang menginginkan pengalaman bermain slot yang unggul dengan akun pro Swiss terbaik. Berikut adalah beberapa alasan mengapa Anda harus memilih Sonic77: Slot Gacor Terbaik Kami menyajikan koleksi slot gacor terbaik dari provider terkemuka. Dengan fitur-fitur unggulan dan peluang kemenangan yang tinggi, Anda akan merasakan pengalaman bermain yang tak terlupakan. Akun Pro Swiss Berkualitas Kami menawarkan akun pro Swiss yang berkualitas dan terpercaya. Dengan akun ini, Anda dapat menikmati berbagai keuntungan eksklusif dan fasilitas premium yang tidak tersedia untuk akun reguler.
    • SV388 SITUS RESMI SABUNG AYAM 2024   Temukan situs resmi untuk sabung ayam terpercaya di tahun 2024 dengan SV388! Dengan layanan terbaik dan pengalaman bertaruh yang tak tertandingi, SV388 adalah tempat terbaik untuk pecinta sabung ayam. Daftar sekarang untuk mengakses arena sabung ayam yang menarik dan nikmati kesempatan besar untuk meraih kemenangan. Jelajahi sensasi taruhan yang tak terlupakan di tahun ini dengan SV388! [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]] [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]]   JURAGANSLOT88 SITUS JUDI SLOT ONLINE TERPERCAYA 2024 Jelajahi pengalaman judi slot online terpercaya di tahun 2024 dengan JuraganSlot88! Sebagai salah satu situs terkemuka, JuraganSlot88 menawarkan berbagai pilihan permainan slot yang menarik dengan layanan terbaik dan keamanan yang terjamin. Daftar sekarang untuk mengakses sensasi taruhan yang tak terlupakan dan raih kesempatan besar untuk meraih kemenangan di tahun ini dengan JuraganSlot88 [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]] [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]]
    • Slot Bank MEGA atau Daftar slot Bank MEGA bisa anda lakukan pada situs WINNING303 kapanpun dan dimanapun, Bermodalkan Hp saja anda bisa mengakses chat ke agen kami selama 24 jam full. keuntungan bergabung bersama kami di WINNING303 adalah anda akan mendapatkan bonus 100% khusus member baru yang bergabung dan deposit. Tidak perlu banyak, 5 ribu rupiah saja anda sudah bisa bermain bersama kami di WINNING303 . Tunggu apa lagi ? Segera Klik DAFTAR dan anda akan jadi Jutawan dalam semalam.
    • ladangtoto situs resmi ladangtoto situs terpercaya 2024   Temukan situs resmi dan terpercaya untuk tahun 2024 di LadangToto! Dengan layanan terbaik dan keamanan yang terjamin, LadangToto adalah pilihan utama untuk penggemar judi online. Daftar sekarang untuk mengakses berbagai jenis permainan taruhan, termasuk togel, kasino, dan banyak lagi. Jelajahi sensasi taruhan yang tak terlupakan dan raih kesempatan besar untuk meraih kemenangan di tahun ini dengan LadangToto!" [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]] [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]]
    • WINNING303 DAFTAR SITUS JUDI SLOT RESMI TERPERCAYA 2024 Temukan situs judi slot resmi dan terpercaya untuk tahun 2024 di Winning303! Daftar sekarang untuk mengakses pengalaman berjudi slot yang aman dan terjamin. Dengan layanan terbaik dan reputasi yang kokoh, Winning303 adalah pilihan terbaik bagi para penggemar judi slot. Jelajahi berbagai pilihan permainan dan raih kesempatan besar untuk meraih kemenangan di tahun ini dengan Winning303 [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]] [[jumpuri:❱❱❱❱❱ DAFTAR DI SINI ❰❰❰❰❰ > https://w303.pink/orochimaru]]
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.