Свое измерение. Свои биомы. Свой мир.

5,018
47
783
В общем, сидел я такой гудел, пытался сделать мир. В итоге вроде что то получилось, но вот беда - почему то ни в какую не хочет мой WorldProvider подгружать мой биом. При заходе в мой мир биом\биомы остается\остаются теми же, которые были в ванилле на тот момент когда я покидал мир. Я перепробовал уже все, поудалял все-все что только можно, но выяснить в чем ошибка, даже теперь не могу. Спустя двое суток еб... беготни, я решил все таки написать на форум с этой проблемой.
Я прилагаю полный код всего что наделал, если кто шарит в мирах, взгляните пожалуйста, может быть вы скажете, что не так.
Java:
public class RealismChunkGenerator implements IChunkGenerator
{
    protected static final IBlockState STONE = BlocksList.MAGMATIC_STONE.getDefaultState();
    private final Random rand;
    private NoiseGeneratorOctaves minLimitPerlinNoise;
    private NoiseGeneratorOctaves maxLimitPerlinNoise;
    private NoiseGeneratorOctaves mainPerlinNoise;
    private NoiseGeneratorPerlin surfaceNoise;
    public NoiseGeneratorOctaves scaleNoise;
    public NoiseGeneratorOctaves depthNoise;
    public NoiseGeneratorOctaves forestNoise;
    private final World world;
    private final boolean mapFeaturesEnabled;
    private final WorldType terrainType;
    private final double[] heightMap;
    private final float[] biomeWeights;
    private ChunkGeneratorSettings settings;
    private IBlockState oceanBlock = Blocks.WATER.getDefaultState();
    private double[] depthBuffer = new double[256];
    private Biome[] biomesForGeneration;
    double[] mainNoiseRegion;
    double[] minLimitRegion;
    double[] maxLimitRegion;
    double[] depthRegion;

    public RealismChunkGenerator(World worldIn, long seed, boolean mapFeaturesEnabledIn, String generatorOptions)
    {

        this.world = worldIn;
        this.mapFeaturesEnabled = mapFeaturesEnabledIn;
        this.terrainType = worldIn.getWorldInfo().getTerrainType();
        this.rand = new Random(seed);
        this.minLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16);
        this.maxLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16);
        this.mainPerlinNoise = new NoiseGeneratorOctaves(this.rand, 8);
        this.surfaceNoise = new NoiseGeneratorPerlin(this.rand, 4);
        this.scaleNoise = new NoiseGeneratorOctaves(this.rand, 10);
        this.depthNoise = new NoiseGeneratorOctaves(this.rand, 16);
        this.forestNoise = new NoiseGeneratorOctaves(this.rand, 8);
        this.heightMap = new double[825];
        this.biomeWeights = new float[25];

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

        if (generatorOptions != null)
        {
            this.settings = ChunkGeneratorSettings.Factory.jsonToFactory(generatorOptions).build();
            this.oceanBlock = this.settings.useLavaOceans ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState();
            worldIn.setSeaLevel(this.settings.seaLevel);
        }

        net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld ctx =
                new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld(minLimitPerlinNoise, maxLimitPerlinNoise, mainPerlinNoise, surfaceNoise, scaleNoise, depthNoise, forestNoise);
        ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx);
        this.minLimitPerlinNoise = ctx.getLPerlin1();
        this.maxLimitPerlinNoise = ctx.getLPerlin2();
        this.mainPerlinNoise = ctx.getPerlin();
        this.surfaceNoise = ctx.getHeight();
        this.scaleNoise = ctx.getScale();
        this.depthNoise = ctx.getDepth();
        this.forestNoise = ctx.getForest();
    }

    public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
    {
        this.biomesForGeneration = this.world.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10);
     
        this.generateHeightmap(x * 4, 0, z * 4);

        for (int i = 0; i < 4; ++i)
        {
            int j = i * 5;
            int k = (i + 1) * 5;

            for (int l = 0; l < 4; ++l)
            {
                int i1 = (j + l) * 33;
                int j1 = (j + l + 1) * 33;
                int k1 = (k + l) * 33;
                int l1 = (k + l + 1) * 33;

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

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

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

                            for (int l2 = 0; l2 < 4; ++l2)
                            {
                                if ((lvt_45_1_ += d16) > 0.0D)
                                {
                                    primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, STONE);
                                }
                                else if (i2 * 8 + j2 < this.settings.seaLevel)
                                {
                                    primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, this.oceanBlock);
                                }
                            }

                            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(this, x, z, primer, this.world)) 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.world, this.rand, primer, x * 16 + i, z * 16 + j, this.depthBuffer[j + i * 16]);
            }
        }
    }

    public Chunk generateChunk(int x, int z)
    {
        this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
        ChunkPrimer chunkprimer = new ChunkPrimer();
        this.setBlocksInChunk(x, z, chunkprimer);
       this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16);
       
        this.replaceBiomeBlocks(x, z, chunkprimer, this.biomesForGeneration);

        Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
        byte[] abyte = chunk.getBiomeArray();

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

        chunk.generateSkylightMap();
        return chunk;
    }

    private void generateHeightmap(int p_185978_1_, int p_185978_2_, int p_185978_3_)
    {
        this.depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion, p_185978_1_, p_185978_3_, 5, 5, (double)this.settings.depthNoiseScaleX, (double)this.settings.depthNoiseScaleZ, (double)this.settings.depthNoiseScaleExponent);
        float f = this.settings.coordinateScale;
        float f1 = this.settings.heightScale;
        this.mainNoiseRegion = this.mainPerlinNoise.generateNoiseOctaves(this.mainNoiseRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)(f / this.settings.mainNoiseScaleX), (double)(f1 / this.settings.mainNoiseScaleY), (double)(f / this.settings.mainNoiseScaleZ));
        this.minLimitRegion = this.minLimitPerlinNoise.generateNoiseOctaves(this.minLimitRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)f, (double)f1, (double)f);
        this.maxLimitRegion = this.maxLimitPerlinNoise.generateNoiseOctaves(this.maxLimitRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)f, (double)f1, (double)f);
        int i = 0;
        int j = 0;

        for (int k = 0; k < 5; ++k)
        {
            for (int l = 0; l < 5; ++l)
            {
                float f2 = 0.0F;
                float f3 = 0.0F;
                float f4 = 0.0F;
                int i1 = 2;
                Biome biome = this.biomesForGeneration[k + 2 + (l + 2) * 10];

                for (int j1 = -2; j1 <= 2; ++j1)
                {
                    for (int k1 = -2; k1 <= 2; ++k1)
                    {
                        Biome biome1 = this.biomesForGeneration[k + j1 + 2 + (l + k1 + 2) * 10];
                        float f5 = this.settings.biomeDepthOffSet + biome1.getBaseHeight() * this.settings.biomeDepthWeight;
                        float f6 = this.settings.biomeScaleOffset + biome1.getHeightVariation() * this.settings.biomeScaleWeight;

                        if (this.terrainType == WorldType.AMPLIFIED && f5 > 0.0F)
                        {
                            f5 = 1.0F + f5 * 2.0F;
                            f6 = 1.0F + f6 * 4.0F;
                        }

                        float f7 = this.biomeWeights[j1 + 2 + (k1 + 2) * 5] / (f5 + 2.0F);

                        if (biome1.getBaseHeight() > biome.getBaseHeight())
                        {
                            f7 /= 2.0F;
                        }

                        f2 += f6 * f7;
                        f3 += f5 * f7;
                        f4 += f7;
                    }
                }

                f2 = f2 / f4;
                f3 = f3 / f4;
                f2 = f2 * 0.9F + 0.1F;
                f3 = (f3 * 4.0F - 1.0F) / 8.0F;
                double d7 = this.depthRegion[j] / 8000.0D;

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

                d7 = d7 * 3.0D - 2.0D;

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

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

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

                    d7 = d7 / 8.0D;
                }

                ++j;
                double d8 = (double)f3;
                double d9 = (double)f2;
                d8 = d8 + d7 * 0.2D;
                d8 = d8 * (double)this.settings.baseSize / 8.0D;
                double d0 = (double)this.settings.baseSize + d8 * 4.0D;

                for (int l1 = 0; l1 < 33; ++l1)
                {
                    double d1 = ((double)l1 - d0) * (double)this.settings.stretchY * 128.0D / 256.0D / d9;

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

                    double d2 = this.minLimitRegion[i] / (double)this.settings.lowerLimitScale;
                    double d3 = this.maxLimitRegion[i] / (double)this.settings.upperLimitScale;
                    double d4 = (this.mainNoiseRegion[i] / 10.0D + 1.0D) / 2.0D;
                    double d5 = MathHelper.clampedLerp(d2, d3, d4) - d1;

                    if (l1 > 29)
                    {
                        double d6 = (double)((float)(l1 - 29) / 3.0F);
                        d5 = d5 * (1.0D - d6) + -10.0D * d6;
                    }

                    this.heightMap[i] = d5;
                    ++i;
                }
            }
        }
    }

    @Override
    public void populate(int x, int z) {
        // TODO Auto-generated method stub
       
    }

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

    @Override
    public List<SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position,
            boolean findUnexplored) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void recreateStructures(Chunk chunkIn, int x, int z) {
        // TODO Auto-generated method stub
       
    }

    @Override
    public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos) {
        // TODO Auto-generated method stub
        return false;
    }

 
}
Java:
public class RegBiomes {

    public static final Biome MAGMATIC_BIOME = new MagmaticBiome();
//    public static final Biome SEDIMENTARY_BIOME = new SedimentaryBiome();
//    public static final Biome METAMORPHIC_BIOME = new MetamorhicBiome();
   
   
    public static void registerBiomes() {
        register(MAGMATIC_BIOME, "magmatic_biome", BiomeType.WARM, Type.HILLS);
   
    }
   
    public static Biome register(Biome b, String name, BiomeType bt, Type... types) {
        b.setRegistryName(name);
        ForgeRegistries.BIOMES.register(b);
   
        BiomeDictionary.addTypes(b, types);
        BiomeManager.addBiome(bt, new BiomeEntry(b, 10));
        BiomeManager.addSpawnBiome(b);
        return b;
    }
}
public class RealismWorld extends WorldProviderSurface {

public RealismWorld() {
super();
this.biomeProvider = new RealismBiomeProvider();

}

@Override
public DimensionType getDimensionType() {
return RegWorlds.REALISM_WORLD;
}

@Override
public IChunkGenerator createChunkGenerator() {
return new RealismChunkGenerator(world, world.rand.nextLong(), false, "magmatic_biome");
}

@Override
public boolean canRespawnHere() {
return true;
}


@Override
public boolean isSurfaceWorld() {
return true;
}
}
Ну и биомпровайдер еще есть, но не считая того что ванильные биомы там заменены на один мой пока, он ничем от ванильного не отличается.
Java:
public class RealismBiomeProvider extends BiomeProvider
{
    private ChunkGeneratorSettings settings;
    private GenLayer genBiomes;
    /** A GenLayer containing the indices into BiomeGenBase.biomeList[] */
    private GenLayer biomeIndexLayer;
    /** The biome list. */
    private final BiomeCache biomeCache;
    /** A list of biomes that the player can spawn in. */
    private final List<Biome> biomesToSpawnIn;
    public static List<Biome> allowedBiomes = Lists.newArrayList(RegBiomes.MAGMATIC_BIOME);

    public RealismBiomeProvider()
    {
        this.biomeCache = new BiomeCache(this);
        this.biomesToSpawnIn = Lists.newArrayList(allowedBiomes);
    }

    private RealismBiomeProvider(long seed, WorldType worldType, ChunkGeneratorSettings options) {
        this();
        GenLayer[] agenlayer = GenLayer.initializeAllBiomeGenerators(seed, worldType, options);
        //agenlayer = getModdedBiomeGenerators(worldTypeIn, seed, agenlayer);
        this.genBiomes = agenlayer[0];
        this.biomeIndexLayer = agenlayer[1];
    }

    public RealismBiomeProvider(WorldInfo info)
    {
        this();
    }

    /**
     * Gets the list of valid biomes for the player to spawn in.
     */
    public List<Biome> getBiomesToSpawnIn()
    {
        return this.biomesToSpawnIn;
    }

    /**
     * Returns the biome generator
     */
    public Biome getBiome(BlockPos pos)
    {
        return this.getBiome(pos, (Biome)null);
    }

    public Biome getBiome(BlockPos pos, Biome defaultBiome)
    {
        return this.biomeCache.getBiome(pos.getX(), pos.getZ(), defaultBiome);
    }

    /**
     * Return an adjusted version of a given temperature based on the y height
     */
    public float getTemperatureAtHeight(float p_76939_1_, int p_76939_2_)
    {
        return p_76939_1_;
    }

    /**
     * Returns an array of biomes for the location input.
     */
    public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height)
    {
        IntCache.resetIntCache();

        if (biomes == null || biomes.length < width * height)
        {
            biomes = new Biome[width * height];
        }

        int[] aint = this.genBiomes.getInts(x, z, width, height);

        try
        {
            for (int i = 0; i < width * height; ++i)
            {
                biomes[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
            }

            return biomes;
        }
        catch (Throwable throwable)
        {
            CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
            CrashReportCategory crashreportcategory = crashreport.makeCategory("RawBiomeBlock");
            crashreportcategory.addCrashSection("biomes[] size", Integer.valueOf(biomes.length));
            crashreportcategory.addCrashSection("x", Integer.valueOf(x));
            crashreportcategory.addCrashSection("z", Integer.valueOf(z));
            crashreportcategory.addCrashSection("w", Integer.valueOf(width));
            crashreportcategory.addCrashSection("h", Integer.valueOf(height));
            throw new ReportedException(crashreport);
        }
    }

    /**
     * Gets biomes to use for the blocks and loads the other data like temperature and humidity onto the
     * WorldChunkManager.
     */
    public Biome[] getBiomes(@Nullable Biome[] oldBiomeList, int x, int z, int width, int depth)
    {
        return this.getBiomes(oldBiomeList, x, z, width, depth, true);
    }

    /**
     * Gets a list of biomes for the specified blocks.
     */
    public Biome[] getBiomes(@Nullable Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag)
    {
        IntCache.resetIntCache();

        if (listToReuse == null || listToReuse.length < width * length)
        {
            listToReuse = new Biome[width * length];
        }

        if (cacheFlag && width == 16 && length == 16 && (x & 15) == 0 && (z & 15) == 0)
        {
            Biome[] abiome = this.biomeCache.getCachedBiomes(x, z);
            System.arraycopy(abiome, 0, listToReuse, 0, width * length);
            return listToReuse;
        }
        else
        {
            int[] aint = this.biomeIndexLayer.getInts(x, z, width, length);

            for (int i = 0; i < width * length; ++i)
            {
                listToReuse[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
            }

            return listToReuse;
        }
    }

    /**
     * checks given Chunk's Biomes against List of allowed ones
     */
    public boolean areBiomesViable(int x, int z, int radius, List<Biome> allowed)
    {
        IntCache.resetIntCache();
        int i = x - radius >> 2;
        int j = z - radius >> 2;
        int k = x + radius >> 2;
        int l = z + radius >> 2;
        int i1 = k - i + 1;
        int j1 = l - j + 1;
        int[] aint = this.genBiomes.getInts(i, j, i1, j1);

        try
        {
            for (int k1 = 0; k1 < i1 * j1; ++k1)
            {
                Biome biome = Biome.getBiome(aint[k1]);

                if (!allowed.contains(biome))
                {
                    return false;
                }
            }

            return true;
        }
        catch (Throwable throwable)
        {
            CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
            CrashReportCategory crashreportcategory = crashreport.makeCategory("Layer");
            crashreportcategory.addCrashSection("Layer", this.genBiomes.toString());
            crashreportcategory.addCrashSection("x", Integer.valueOf(x));
            crashreportcategory.addCrashSection("z", Integer.valueOf(z));
            crashreportcategory.addCrashSection("radius", Integer.valueOf(radius));
            crashreportcategory.addCrashSection("allowed", allowed);
            throw new ReportedException(crashreport);
        }
    }

    @Nullable
    public BlockPos findBiomePosition(int x, int z, int range, List<Biome> biomes, Random random)
    {
        IntCache.resetIntCache();
        int i = x - range >> 2;
        int j = z - range >> 2;
        int k = x + range >> 2;
        int l = z + range >> 2;
        int i1 = k - i + 1;
        int j1 = l - j + 1;
        int[] aint = this.genBiomes.getInts(i, j, i1, j1);
        BlockPos blockpos = null;
        int k1 = 0;

        for (int l1 = 0; l1 < i1 * j1; ++l1)
        {
            int i2 = i + l1 % i1 << 2;
            int j2 = j + l1 / i1 << 2;
            Biome biome = Biome.getBiome(aint[l1]);

            if (biomes.contains(biome) && (blockpos == null || random.nextInt(k1 + 1) == 0))
            {
                blockpos = new BlockPos(i2, 0, j2);
                ++k1;
            }
        }

        return blockpos;
    }

    /**
     * Calls the WorldChunkManager's biomeCache.cleanupCache()
     */
    public void cleanupCache()
    {
        this.biomeCache.cleanupCache();
    }

    public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {
        net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens event = new net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens(worldType, seed, original);
        net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event);
        return event.getNewBiomeGens();
    }

    public boolean isFixedBiome()
    {
        return this.settings != null && this.settings.fixedBiome >= 0;
    }

    public Biome getFixedBiome()
    {
        return this.settings != null && this.settings.fixedBiome >= 0 ? Biome.getBiomeForId(this.settings.fixedBiome) : null;
    }
}
 
Последнее редактирование:
5,018
47
783
Итак, спустя еще полтора часа мучений я дошел до нового левела, где крашится уже по другой причине. Ввиду того, что чанкгенератор упорно берет ванильные биомы вместо моих я принял твердое решение насильно подсовывать ему нормальные биомы.

Java:
 public Chunk generateChunk(int x, int z)
    {
        this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
        ChunkPrimer chunkprimer = new ChunkPrimer();
        this.setBlocksInChunk(x, z, chunkprimer);
       RealismBiomeProvider rbp = (RealismBiomeProvider)this.world.getBiomeProvider();
        
        this.biomesForGeneration = rbp.getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16);
        
        this.replaceBiomeBlocks(x, z, chunkprimer, this.biomesForGeneration);


      
       Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
       byte[] abyte = chunk.getBiomeArray();

       for (int i = 0; i < abyte.length; ++i)
       {
           abyte[i] = (byte)Biome.getIdForBiome(this.biomesForGeneration[i]);
       }
       chunk.generateSkylightMap();
    
        return chunk;
    }

Крашится с ошибкой, указывая что мой BiomeProvider якобы нулл
P.S биомов теперь три, и они все указаны в слоях и в провайдере.
Вот слои:
Java:
public class RealismGenLayer {

    public static GenLayer[] initializeAllBiomeGenerators(long seed, WorldType worldType, String options)
    {
        int deltaX = (int)(seed >> 8 & 0xF);
        int deltaZ = (int)(seed >> 16 & 0xF);
        GenLayer biomes = new GenLayerBiomes(1L, deltaX, deltaZ);
        biomes = new GenLayerZoom(1000L, biomes);

        GenLayer genlayervoronoizoom = new GenLayerVoronoiZoom(10L, biomes);

        biomes.initWorldGenSeed(seed);
        genlayervoronoizoom.initWorldGenSeed(seed);
        return new GenLayer[] { biomes, genlayervoronoizoom };
    }
    public RealismGenLayer(long seed)
    {

    }

}

Java:
public class GenLayerBiomes extends GenLayer {
    
    
      private final int deltaX;
      private final int deltaZ;
      int idMagmatic =  Biome.getIdForBiome(RegBiomes.MAGMATIC_BIOME);
      int idSedimentary =  Biome.getIdForBiome(RegBiomes.SEDIMENTARY_BIOME);
      int idMetamorphic =  Biome.getIdForBiome(RegBiomes.METAMORPHIC_BIOME);
      
      private final int[] all_biomes = {idMagmatic, idSedimentary,idMetamorphic};
      
    
      
      public GenLayerBiomes(long seed, int deltaX, int deltaZ)
      {
        super(seed);
        this.deltaX = deltaX;
        this.deltaZ = deltaZ;
      }
      
      public int[] getInts(int x, int z, int width, int height)
      {
        int[] dest = IntCache.getIntCache(width * height);
        for (int dz = 0; dz < height; dz++) {
          for (int dx = 0; dx < width; dx++)
          {
            initChunkSeed(dx + x, dz + z);
      
              dest[(dx + dz * width)] = this.all_biomes[nextInt(this.all_biomes.length)];
            }
          }
        
        return dest;
      }
    }


Java:
Caused by: java.lang.NullPointerException
    at com.legendgamer.realism.world.RealismWorld.<init>(RealismWorld.java:15) ~[RealismWorld.class:?]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_191]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_191]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_191]
    at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.8.0_191]
    at net.minecraft.world.DimensionType.createDimension(DimensionType.java:47) ~[DimensionType.class:?]
 
3,005
192
592
5,018
47
783
И можно с указанием "вот тут 15 строка" ?
Там просто сетается биомпровайдер. Логично что дело в биом провайдере, если что, вот он:

Java:
public class RealismBiomeProvider extends BiomeProvider
{
     public static List<Biome> allowedBiomes = Lists.newArrayList(new Biome[] { RegBiomes.SEDIMENTARY_BIOME,RegBiomes.METAMORPHIC_BIOME,RegBiomes.MAGMATIC_BIOME });
    
     public GenLayer genBiomes;
     public GenLayer biomeIndexLayer;
     public  BiomeCache biomeCache;
     public  List<Biome> biomesToSpawnIn;


    public RealismBiomeProvider()
    {
        this.biomeCache = new BiomeCache(this);
        this.biomesToSpawnIn = Lists.newArrayList(allowedBiomes);
    }
    public RealismBiomeProvider(long seed, WorldType worldType, String options)
    {
        this();
        GenLayer[] agenlayer = RealismGenLayer.initializeAllBiomeGenerators(seed, worldType, options);

        this.genBiomes = agenlayer[0];
        this.biomeIndexLayer = agenlayer[1];
    }
    public RealismBiomeProvider(long seed, WorldInfo info)
    {
        this(seed, info.getTerrainType(), info.getGeneratorOptions());
    }

    public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height)
    {

        if ((biomes == null) || (biomes.length < width * height)) {
            biomes = new Biome[width * height];
        }
        int[] aint = this.genBiomes.getInts(x, z, width, height);
        try
        {
            for (int i = 0; i < width * height; i++) {
                biomes[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
            }
            return biomes;
        }
        catch (Throwable throwable)
        {
            CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
            CrashReportCategory crashreportcategory = crashreport.makeCategory("RawBiomeBlock");
            crashreportcategory.addCrashSection("biomes[] size", Integer.valueOf(biomes.length));
            crashreportcategory.addCrashSection("x", Integer.valueOf(x));
            crashreportcategory.addCrashSection("z", Integer.valueOf(z));
            crashreportcategory.addCrashSection("w", Integer.valueOf(width));
            crashreportcategory.addCrashSection("h", Integer.valueOf(height));
            throw new ReportedException(crashreport);
        }
    }

}
 
3,005
192
592
5,018
47
783
Java:
package com.legendgamer.realism.world;

import com.legendgamer.realism.reg.RegWorlds;
import com.legendgamer.realism.world.biomes.provider.RealismBiomeProvider;
import com.legendgamer.realism.world.chunks.RealismChunkGenerator;

import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.gen.IChunkGenerator;

public class RealismWorld extends WorldProvider {

    public RealismWorld() {
        super();
    /*15*/    this.biomeProvider = new RealismBiomeProvider(world.rand.nextLong(), this.world.getWorldInfo());
        
    }
 
3,005
192
592
3,005
192
592
И как у тебя рандомный long относится к seed'у ?
~~~
И зачем ты передаешь deltaX deltaZ в GenLayerBiomes, если ты их не юзаешь?
~~~
Ты передаешь аргументы, но ты их НЕ ЮЗАЕШЬ, ЗАЧЕЕЕЕЕЕЕЕМММ.........
 
5,018
47
783
У тебя туда еще отдается 2 переменные, ты не подумал, что ошибка может быть в них?
Одна же вроде...
я все конструкторы попробовал добавлять.

И как у тебя рандомный long относится к seed'у ?
Я думал тут сид сетается...
 
3,005
192
592
Убери весь юзлесс код и попробуй заново.
У тебя передаются переменные, которые ты даже не юзаешь, зачем их нужно было вообще добавлять ..
 
5,018
47
783
У тебя передаются переменные, которые ты даже не юзаешь, зачем их нужно было вообще добавлять ..
Удалил.
Но есть они или нет, ничего не меняется... :(
В принципе не регается дименшен, вылетает
Java:
java.lang.Error: Could not create new dimension
    at net.minecraft.world.DimensionType.createDimension(DimensionType.java:55)
    at net.minecraftforge.common.DimensionManager.createProviderFor(DimensionManager.java:287)
    at net.minecraft.world.WorldServer.<init>(WorldServer.java:116)
    at net.minecraft.world.WorldServerMulti.<init>(WorldServerMulti.java:18)
    at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(IntegratedServer.java:127)
    at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:160)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:550)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at net.minecraft.world.DimensionType.createDimension(DimensionType.java:47)
    ... 7 more
Caused by: java.lang.NullPointerException
    at com.legendgamer.realism.world.RealismWorld.<init>(RealismWorld.java:15)
    ... 12 more
 
3,005
192
592
5,018
47
783
Покажи 15 строку...
Все та же :/
Что так не работает
this.biomeProvider = new RealismBiomeProvider(world.getSeed(), this.world.getWorldInfo(),true);
Что так
this.biomeProvider = new RealismBiomeProvider(world.getSeed(), this.world.getWorldInfo());
что так
this.biomeProvider = new RealismBiomeProvider();Мож потому что все в разных конструкторах... засунука в один


Сделал такой биомпровайдер теперь

Java:
public class RealismBiomeProvider extends BiomeProvider
{
     public static List<Biome> allowedBiomes = Lists.newArrayList(new Biome[] { RegBiomes.SEDIMENTARY_BIOME,RegBiomes.METAMORPHIC_BIOME,RegBiomes.MAGMATIC_BIOME });
   
     public GenLayer genBiomes;
     public GenLayer biomeIndexLayer;
     public  BiomeCache biomeCache;
     public  List<Biome> biomesToSpawnIn;

    public RealismBiomeProvider(long seed, WorldType worldType)
    {
        GenLayer[] agenlayer = RealismGenLayer.initializeAllBiomeGenerators(seed, worldType);

        this.genBiomes = agenlayer[0];
        this.biomeIndexLayer = agenlayer[1];
        this.biomeCache = new BiomeCache(this);
        this.biomesToSpawnIn = Lists.newArrayList(allowedBiomes);
       
    }
   


    public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height)
    {

        if ((biomes == null) || (biomes.length < width * height)) {
            biomes = new Biome[width * height];
        }
        int[] aint = this.genBiomes.getInts(x, z, width, height);
        try
        {
            for (int i = 0; i < width * height; i++) {
                biomes[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
            }
            return biomes;
        }
        catch (Throwable throwable)
        {
            CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
            CrashReportCategory crashreportcategory = crashreport.makeCategory("RawBiomeBlock");
            crashreportcategory.addCrashSection("biomes[] size", Integer.valueOf(biomes.length));
            crashreportcategory.addCrashSection("x", Integer.valueOf(x));
            crashreportcategory.addCrashSection("z", Integer.valueOf(z));
            crashreportcategory.addCrashSection("w", Integer.valueOf(width));
            crashreportcategory.addCrashSection("h", Integer.valueOf(height));
            throw new ReportedException(crashreport);
        }
    }

}

Не происходит вызова биомпровайдера... или я не умею пользоваться брекпоинтами. Но если проследить этот путь, то тут биомпровайдером и не пахнет1548716329279.png
 
Последнее редактирование:
5,018
47
783
P.S Только что чекнул брекпоинтами... конструктор биомпровайдера не вызывается в принципе. Это как вообще?)
 
5,018
47
783
Итак, взяв и вручную переопределив метод init() из WorldProvider(жизнь заставила:D), я обнаружил что проблема в том, что в биомпровайдере не хватает метода getBiomes[]
Собственно создав его я ... тут же наткнулся на следующую ошибку.
Метод generateHighMap
Скопипащен из ваниллы целиком. Методом научного тыка стало ясно что эклипсу плевать на что ругаться в этом методе, и он просто самую первую строчку в нем всегда обзывает нуллом.

Java:
  public void generateHeightmap(int x, int y, int z)
    {
        this.depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion, x, z, 5, 5, (double)this.settings.depthNoiseScaleX, (double)this.settings.depthNoiseScaleZ, (double)this.settings.depthNoiseScaleExponent);
        float f = this.settings.coordinateScale;
        float f1 = this.settings.heightScale;
        this.mainNoiseRegion = this.mainPerlinNoise.generateNoiseOctaves(this.mainNoiseRegion, x, y, z, 5, 33, 5, (double)(f / this.settings.mainNoiseScaleX), (double)(f1 / this.settings.mainNoiseScaleY), (double)(f / this.settings.mainNoiseScaleZ));
        this.minLimitRegion = this.minLimitPerlinNoise.generateNoiseOctaves(this.minLimitRegion, x, y, z, 5, 33, 5, (double)f, (double)f1, (double)f);
        this.maxLimitRegion = this.maxLimitPerlinNoise.generateNoiseOctaves(this.maxLimitRegion, x, y, z, 5, 33, 5, (double)f, (double)f1, (double)f);
        int i = 0;
        int j = 0;

        for (int k = 0; k < 5; ++k)
        {
            for (int l = 0; l < 5; ++l)
            {
                float f2 = 0.0F;
                float f3 = 0.0F;
                float f4 = 0.0F;
                int i1 = 2;
                Biome biome = this.biomesForGeneration[k + 2 + (l + 2) * 10];

                for (int j1 = -2; j1 <= 2; ++j1)
                {
                    for (int k1 = -2; k1 <= 2; ++k1)
                    {
                        Biome biome1 = this.biomesForGeneration[k + j1 + 2 + (l + k1 + 2) * 10];
                        float f5 = this.settings.biomeDepthOffSet + biome1.getBaseHeight() * this.settings.biomeDepthWeight;
                        float f6 = this.settings.biomeScaleOffset + biome1.getHeightVariation() * this.settings.biomeScaleWeight;

                        if (this.terrainType == WorldType.AMPLIFIED && f5 > 0.0F)
                        {
                            f5 = 1.0F + f5 * 2.0F;
                            f6 = 1.0F + f6 * 4.0F;
                        }

                        float f7 = this.biomeWeights[j1 + 2 + (k1 + 2) * 5] / (f5 + 2.0F);

                        if (biome1.getBaseHeight() > biome.getBaseHeight())
                        {
                            f7 /= 2.0F;
                        }

                        f2 += f6 * f7;
                        f3 += f5 * f7;
                        f4 += f7;
                    }
                }

                f2 = f2 / f4;
                f3 = f3 / f4;
                f2 = f2 * 0.9F + 0.1F;
                f3 = (f3 * 4.0F - 1.0F) / 8.0F;
                double d7 = this.depthRegion[j] / 8000.0D;

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

                d7 = d7 * 3.0D - 2.0D;

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

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

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

                    d7 = d7 / 8.0D;
                }

                ++j;
                double d8 = (double)f3;
                double d9 = (double)f2;
                d8 = d8 + d7 * 0.2D;
                d8 = d8 * (double)this.settings.baseSize / 8.0D;
                double d0 = (double)this.settings.baseSize + d8 * 4.0D;

                for (int l1 = 0; l1 < 33; ++l1)
                {
                    double d1 = ((double)l1 - d0) * (double)this.settings.stretchY * 128.0D / 256.0D / d9;

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

                    double d2 = this.minLimitRegion[i] / (double)this.settings.lowerLimitScale;
                    double d3 = this.maxLimitRegion[i] / (double)this.settings.upperLimitScale;
                    double d4 = (this.mainNoiseRegion[i] / 10.0D + 1.0D) / 2.0D;
                    double d5 = MathHelper.clampedLerp(d2, d3, d4) - d1;

                    if (l1 > 29)
                    {
                        double d6 = (double)((float)(l1 - 29) / 3.0F);
                        d5 = d5 * (1.0D - d6) + -10.0D * d6;
                    }

                    this.heightMap[i] = d5;
                    ++i;
                }
            }
        }
    }

Краш таков ныне:

Java:
java.lang.NullPointerException: Exception generating new chunk
    at com.legendgamer.realism.world.chunks.RealismChunkGenerator.generateHeightmap(RealismChunkGenerator.java:207)
    at com.legendgamer.realism.world.chunks.RealismChunkGenerator.setBlocksInChunk(RealismChunkGenerator.java:98)
    at com.legendgamer.realism.world.chunks.RealismChunkGenerator.generateChunk(RealismChunkGenerator.java:184)
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155)
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:361)
    at net.minecraft.world.World.spawnEntity(World.java:1314)
    at net.minecraft.world.WorldServer.spawnEntity(WorldServer.java:1121)
    at net.minecraft.server.management.PlayerList.playerLoggedIn(PlayerList.java:398)
    at net.minecraft.server.management.PlayerList.initializeConnectionToPlayer(PlayerList.java:175)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.completeServerSideConnection(NetworkDispatcher.java:259)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.access$100(NetworkDispatcher.java:72)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:208)
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307)
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197)
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:863)
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741)
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590)
    at java.lang.Thread.run(Unknown Source)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Client thread
Stacktrace:
    at com.legendgamer.realism.world.chunks.RealismChunkGenerator.generateHeightmap(RealismChunkGenerator.java:207)
    at com.legendgamer.realism.world.chunks.RealismChunkGenerator.setBlocksInChunk(RealismChunkGenerator.java:98)
    at com.legendgamer.realism.world.chunks.RealismChunkGenerator.generateChunk(RealismChunkGenerator.java:184)

-- Chunk to be generated --
Details:
    Location: 54,-74
    Position hash: -317827579850
    Generator: com.legendgamer.realism.world.chunks.RealismChunkGenerator@34041e07
Stacktrace:
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155)
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:361)
    at net.minecraft.world.World.spawnEntity(World.java:1314)
    at net.minecraft.world.WorldServer.spawnEntity(WorldServer.java:1121)
    at net.minecraft.server.management.PlayerList.playerLoggedIn(PlayerList.java:398)
    at net.minecraft.server.management.PlayerList.initializeConnectionToPlayer(PlayerList.java:175)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.completeServerSideConnection(NetworkDispatcher.java:259)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.access$100(NetworkDispatcher.java:72)
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:208)
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307)
 
5,018
47
783
Я все таки нашел проблему. Проблема была в том что некоторые переменные брались не из моего класса, а из ChunkGeneratorSettings, где они имели модификатор final, вследствие чего у меня уже не юзались. Но после сиюминутной радости я обнаружил что в моем мире нету света :\
Буду думать
P.s превращу ка эту тему в микроблог о том как я мир создавал. Кому нибудь потом полезно будет.

Проблему со светом решил hasSkyLight = true;

Теперь дело за биомами, которые есть, но которые не работают.
 
Последнее редактирование:
5,018
47
783
Итак, новые вопросы:
- Почему нету земли и травы? В каком слое и где это заменяется? Как это вообще делается?
- Почему у меня на каждый блок новый биом?
2019-01-29_03.40.24.png
Java:
public class GenLayerBiomes extends GenLayer {
    
    

      int idMagmatic =  Biome.getIdForBiome(RegBiomes.MAGMATIC_BIOME);
      int idSedimentary =  Biome.getIdForBiome(RegBiomes.SEDIMENTARY_BIOME);
      int idMetamorphic =  Biome.getIdForBiome(RegBiomes.METAMORPHIC_BIOME);
      
      public final int[] all_biomes = {idMagmatic, idSedimentary,idMetamorphic};
      
    
      
      public GenLayerBiomes(long seed)
      {
        super(seed);
    
      }
      @Override
      public int[] getInts(int x, int z, int width, int height)
      {
        int[] dest = IntCache.getIntCache(width * height);
        for (int dz = 0; dz < height; dz++) {
          for (int dx = 0; dx < width; dx++)
          {
            initChunkSeed(dx + x, dz + z);
      
              dest[(dx + dz * width)] = this.all_biomes[nextInt(this.all_biomes.length)];
            }
          }
        
        return dest;
      }
    }
Java:
public class RealismGenLayer {

    public static GenLayer[] initializeAllBiomeGenerators(long seed, WorldType worldType)
    {
        int deltaX = (int)(seed >> 8 & 0xF);
        int deltaZ = (int)(seed >> 16 & 0xF);
        GenLayer biomes = new GenLayerBiomes(1L);
        GenLayer zoom1 = new GenLayerZoom(1001L, biomes);
        GenLayer fuzzyzoom1 = new GenLayerFuzzyZoom(2000L, biomes);
        
        
        
        GenLayer genlayervoronoizoom = new GenLayerVoronoiZoom(10L, biomes);

        biomes.initWorldGenSeed(seed);
        genlayervoronoizoom.initWorldGenSeed(seed);
        return new GenLayer[] { biomes, genlayervoronoizoom };
    }
    
}
 
5,018
47
783
Добрый вечер всем! Возвращаясь к теме мира. В общем то, сделал я свои биомы, поправил ошибку с размерами - зума не хватало. Но осталась другая проблема - почему то нету ни topBlock, ни fillerBlock.

Весьма удивителен и тот факт что аналогичные земля и трава в дефолтном мире тоже исчезли... Не заменяются. Кто в курсе с чем это связано?
 
102
3
77
Хотел ответить тебе после того, как доделаю вторую часть руководства, но как обычно на это уйдет больше времени, чем предполагалось:f_facepalm:, поэтому опишу вкратце.
Посмотрел что вы тут коллективным разумом усердно лепили и это зашквар, прям максимальный (n) Сказывается отсутствие нормальных руководств по всему этому направлению в целом. Ну ничего, скоро исправим.
Единственное, что я проверил из работоспособности твоего кода - это алгоритм генерации биомов. С ним все нормально. Проблема появления нового биома у каждого блока либо в другом месте, либо ты ожидал биомы других размеров (у тебя они очень маленькие, но не в 1 блок). Вставил твою генерацию биомов - все получилось:
2019-01-30_21.48.35.png
Собрал тебе супер-минимальную версию (из будущего руководства, да-да, но не второго) для того, чтобы в новом измерении генерировалась поверхность, аналогичная Обычному миру, но со своим алгоритмом генерации биомов. Учитывай, что ChunkProviderTest тут по сути ванильный (ну раз тебе нужен был аналогичный - вот аналогичный). Телепортироваться между мирами - ПКМ с предметом.

А вообще, почитай-ка Генерацию биомов, чтобы со слоями больше конфузов не было.

UPD. Обновил мод
 

Вложения

  • Test_Dimension.rar
    9.2 KB · Просмотры: 5
Последнее редактирование:
5,018
47
783
С размерами я разобрался там зум просто надо было накинуть..
У меня что то сломалось в реплейсе. Настолько сломалось что даже в ванилле перестало работать:)
 
Сверху