Search in sources :

Example 1 with Biome

use of cn.nukkit.level.generator.biome.Biome in project Nukkit by Nukkit.

the class Nether method generateChunk.

@Override
public void generateChunk(int chunkX, int chunkZ) {
    this.nukkitRandom.setSeed(chunkX * localSeed1 ^ chunkZ * localSeed2 ^ this.level.getSeed());
    double[][][] noise = Generator.getFastNoise3D(this.noiseBase, 16, 128, 16, 4, 8, 4, chunkX * 16, 0, chunkZ * 16);
    FullChunk chunk = this.level.getChunk(chunkX, chunkZ);
    for (int x = 0; x < 16; ++x) {
        for (int z = 0; z < 16; ++z) {
            Biome biome = Biome.getBiome(Biome.HELL);
            chunk.setBiomeId(x, z, Biome.HELL);
            int biomecolor = biome.getColor();
            chunk.setBiomeColor(x, z, (biomecolor >> 16), (biomecolor >> 8) & 0xff, (biomecolor & 0xff));
            chunk.setBlockId(x, 0, z, Block.BEDROCK);
            chunk.setBlockId(x, 127, z, Block.BEDROCK);
            for (int y = 1; y <= bedrockDepth; y++) {
                if (nukkitRandom.nextRange(1, 5) == 1) {
                    chunk.setBlockId(x, y, z, Block.BEDROCK);
                    chunk.setBlockId(x, 127 - y, z, Block.BEDROCK);
                }
            }
            for (int y = 1; y < 127; ++y) {
                double noiseValue = (Math.abs(this.emptyHeight - y) / this.emptyHeight) * this.emptyAmplitude - noise[x][z][y];
                noiseValue -= 1 - this.density;
                if (noiseValue > 0) {
                    chunk.setBlockId(x, y, z, Block.NETHERRACK);
                } else if (y <= this.waterHeight) {
                    chunk.setBlockId(x, y, z, Block.STILL_LAVA);
                    chunk.setBlockLight(x, y + 1, z, 15);
                }
            }
        }
    }
    for (Populator populator : this.generationPopulators) {
        populator.populate(this.level, chunkX, chunkZ, this.nukkitRandom);
    }
}
Also used : FullChunk(cn.nukkit.level.format.FullChunk) Biome(cn.nukkit.level.generator.biome.Biome)

Example 2 with Biome

use of cn.nukkit.level.generator.biome.Biome in project Nukkit by Nukkit.

the class Normal method generateChunk.

@Override
public void generateChunk(int chunkX, int chunkZ) {
    this.nukkitRandom.setSeed(chunkX * localSeed1 ^ chunkZ * localSeed2 ^ this.level.getSeed());
    double[][] seaFloorNoise = Generator.getFastNoise2D(this.noiseSeaFloor, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] landNoise = Generator.getFastNoise2D(this.noiseLand, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] mountainNoise = Generator.getFastNoise2D(this.noiseMountains, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] baseNoise = Generator.getFastNoise2D(this.noiseBaseGround, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] riverNoise = Generator.getFastNoise2D(this.noiseRiver, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    FullChunk chunk = this.level.getChunk(chunkX, chunkZ);
    for (int genx = 0; genx < 16; genx++) {
        for (int genz = 0; genz < 16; genz++) {
            Biome biome;
            boolean canBaseGround = false;
            boolean canRiver = true;
            // using a quadratic function which smooth the world
            // y = (2.956x)^2 - 0.6,  (0 <= x <= 2)
            double landHeightNoise = landNoise[genx][genz] + 1F;
            landHeightNoise *= 2.956;
            landHeightNoise = landHeightNoise * landHeightNoise;
            landHeightNoise = landHeightNoise - 0.6F;
            landHeightNoise = landHeightNoise > 0 ? landHeightNoise : 0;
            // generate mountains
            double mountainHeightGenerate = mountainNoise[genx][genz] - 0.2F;
            mountainHeightGenerate = mountainHeightGenerate > 0 ? mountainHeightGenerate : 0;
            int mountainGenerate = (int) (mountainHeight * mountainHeightGenerate);
            int landHeightGenerate = (int) (landHeightRange * landHeightNoise);
            if (landHeightGenerate > landHeightRange) {
                if (landHeightGenerate > landHeightRange) {
                    canBaseGround = true;
                }
                landHeightGenerate = landHeightRange;
            }
            int genyHeight = seaFloorHeight + landHeightGenerate;
            genyHeight += mountainGenerate;
            // prepare for generate ocean, desert, and land
            if (genyHeight < beathStartHeight) {
                if (genyHeight < beathStartHeight - 5) {
                    genyHeight += (int) (seaFloorGenerateRange * seaFloorNoise[genx][genz]);
                }
                biome = Biome.getBiome(Biome.OCEAN);
                if (genyHeight < seaFloorHeight - seaFloorGenerateRange) {
                    genyHeight = seaFloorHeight;
                }
                canRiver = false;
            } else if (genyHeight <= beathStopHeight && genyHeight >= beathStartHeight) {
                biome = Biome.getBiome(Biome.BEACH);
            } else {
                biome = this.pickBiome(chunkX * 16 + genx, chunkZ * 16 + genz);
                if (canBaseGround) {
                    int baseGroundHeight = (int) (landHeightRange * landHeightNoise) - landHeightRange;
                    int baseGroundHeight2 = (int) (basegroundHeight * (baseNoise[genx][genz] + 1F));
                    if (baseGroundHeight2 > baseGroundHeight)
                        baseGroundHeight2 = baseGroundHeight;
                    if (baseGroundHeight2 > mountainGenerate)
                        baseGroundHeight2 = baseGroundHeight2 - mountainGenerate;
                    else
                        baseGroundHeight2 = 0;
                    genyHeight += baseGroundHeight2;
                }
            }
            if (canRiver && genyHeight <= seaHeight - 5) {
                canRiver = false;
            }
            // generate river
            if (canRiver) {
                double riverGenerate = riverNoise[genx][genz];
                if (riverGenerate > -0.25F && riverGenerate < 0.25F) {
                    riverGenerate = riverGenerate > 0 ? riverGenerate : -riverGenerate;
                    riverGenerate = 0.25F - riverGenerate;
                    // y=x^2 * 4 - 0.0000001
                    riverGenerate = riverGenerate * riverGenerate * 4F;
                    // smooth again
                    riverGenerate = riverGenerate - 0.0000001F;
                    riverGenerate = riverGenerate > 0 ? riverGenerate : 0;
                    genyHeight -= riverGenerate * 64;
                    if (genyHeight < seaHeight) {
                        biome = Biome.getBiome(Biome.RIVER);
                        // to generate river floor
                        if (genyHeight <= seaHeight - 8) {
                            int genyHeight1 = seaHeight - 9 + (int) (basegroundHeight * (baseNoise[genx][genz] + 1F));
                            int genyHeight2 = genyHeight < seaHeight - 7 ? seaHeight - 7 : genyHeight;
                            genyHeight = genyHeight1 > genyHeight2 ? genyHeight1 : genyHeight2;
                        }
                    }
                }
            }
            chunk.setBiomeId(genx, genz, biome.getId());
            // biome color
            // todo: smooth chunk color
            int biomecolor = biome.getColor();
            chunk.setBiomeColor(genx, genz, (biomecolor >> 16), (biomecolor >> 8) & 0xff, (biomecolor & 0xff));
            // generating
            int generateHeight = genyHeight > seaHeight ? genyHeight : seaHeight;
            for (int geny = 0; geny <= generateHeight; geny++) {
                if (geny <= bedrockDepth && (geny == 0 || nukkitRandom.nextRange(1, 5) == 1)) {
                    chunk.setBlock(genx, geny, genz, Block.BEDROCK);
                } else if (geny > genyHeight) {
                    if ((biome.getId() == Biome.ICE_PLAINS || biome.getId() == Biome.TAIGA) && geny == seaHeight) {
                        chunk.setBlock(genx, geny, genz, Block.ICE);
                    } else {
                        chunk.setBlock(genx, geny, genz, Block.STILL_WATER);
                    }
                } else {
                    chunk.setBlock(genx, geny, genz, Block.STONE);
                }
            }
        }
    }
    // populator chunk
    for (Populator populator : this.generationPopulators) {
        populator.populate(this.level, chunkX, chunkZ, this.nukkitRandom);
    }
}
Also used : FullChunk(cn.nukkit.level.format.FullChunk) Biome(cn.nukkit.level.generator.biome.Biome)

Example 3 with Biome

use of cn.nukkit.level.generator.biome.Biome in project Nukkit by Nukkit.

the class PopulatorCaves method generateCaveNode.

protected void generateCaveNode(long seed, FullChunk chunk, double x, double y, double z, float radius, float angelOffset, float angel, int angle, int maxAngle, double scale) {
    int chunkX = chunk.getX();
    int chunkZ = chunk.getZ();
    double realX = chunkX * 16 + 8;
    double realZ = chunkZ * 16 + 8;
    float f1 = 0.0F;
    float f2 = 0.0F;
    Random localRandom = new Random(seed);
    if (maxAngle <= 0) {
        int checkAreaSize = this.checkAreaSize * 16 - 16;
        maxAngle = checkAreaSize - localRandom.nextInt(checkAreaSize / 4);
    }
    boolean isLargeCave = false;
    if (angle == -1) {
        angle = maxAngle / 2;
        isLargeCave = true;
    }
    int randomAngel = localRandom.nextInt(maxAngle / 2) + maxAngle / 4;
    boolean bigAngel = localRandom.nextInt(6) == 0;
    for (; angle < maxAngle; angle++) {
        double offsetXZ = 1.5D + MathHelper.sin(angle * 3.141593F / maxAngle) * radius * 1.0F;
        double offsetY = offsetXZ * scale;
        float cos = MathHelper.cos(angel);
        float sin = MathHelper.sin(angel);
        x += MathHelper.cos(angelOffset) * cos;
        y += sin;
        z += MathHelper.sin(angelOffset) * cos;
        if (bigAngel)
            angel *= 0.92F;
        else {
            angel *= 0.7F;
        }
        angel += f2 * 0.1F;
        angelOffset += f1 * 0.1F;
        f2 *= 0.9F;
        f1 *= 0.75F;
        f2 += (localRandom.nextFloat() - localRandom.nextFloat()) * localRandom.nextFloat() * 2.0F;
        f1 += (localRandom.nextFloat() - localRandom.nextFloat()) * localRandom.nextFloat() * 4.0F;
        if ((!isLargeCave) && (angle == randomAngel) && (radius > 1.0F) && (maxAngle > 0)) {
            generateCaveNode(localRandom.nextLong(), chunk, x, y, z, localRandom.nextFloat() * 0.5F + 0.5F, angelOffset - 1.570796F, angel / 3.0F, angle, maxAngle, 1.0D);
            generateCaveNode(localRandom.nextLong(), chunk, x, y, z, localRandom.nextFloat() * 0.5F + 0.5F, angelOffset + 1.570796F, angel / 3.0F, angle, maxAngle, 1.0D);
            return;
        }
        if ((!isLargeCave) && (localRandom.nextInt(4) == 0)) {
            continue;
        }
        // Check if distance to working point (x and z) too larger than working radius (maybe ??)
        double distanceX = x - realX;
        double distanceZ = z - realZ;
        double angelDiff = maxAngle - angle;
        double newRadius = radius + 2.0F + 16.0F;
        if (distanceX * distanceX + distanceZ * distanceZ - angelDiff * angelDiff > newRadius * newRadius) {
            return;
        }
        // Boundaries check.
        if ((x < realX - 16.0D - offsetXZ * 2.0D) || (z < realZ - 16.0D - offsetXZ * 2.0D) || (x > realX + 16.0D + offsetXZ * 2.0D) || (z > realZ + 16.0D + offsetXZ * 2.0D))
            continue;
        int xFrom = MathHelper.floor(x - offsetXZ) - chunkX * 16 - 1;
        int xTo = MathHelper.floor(x + offsetXZ) - chunkX * 16 + 1;
        int yFrom = MathHelper.floor(y - offsetY) - 1;
        int yTo = MathHelper.floor(y + offsetY) + 1;
        int zFrom = MathHelper.floor(z - offsetXZ) - chunkZ * 16 - 1;
        int zTo = MathHelper.floor(z + offsetXZ) - chunkZ * 16 + 1;
        if (xFrom < 0)
            xFrom = 0;
        if (xTo > 16)
            xTo = 16;
        if (yFrom < 1)
            yFrom = 1;
        if (yTo > this.worldHeightCap - 8) {
            yTo = this.worldHeightCap - 8;
        }
        if (zFrom < 0)
            zFrom = 0;
        if (zTo > 16)
            zTo = 16;
        // Search for water
        boolean waterFound = false;
        for (int xx = xFrom; (!waterFound) && (xx < xTo); xx++) {
            for (int zz = zFrom; (!waterFound) && (zz < zTo); zz++) {
                for (int yy = yTo + 1; (!waterFound) && (yy >= yFrom - 1); yy--) {
                    if (yy >= 0 && yy < this.worldHeightCap) {
                        int block = chunk.getBlockId(xx, yy, zz);
                        if (block == Block.WATER || block == Block.STILL_WATER) {
                            waterFound = true;
                        }
                        if ((yy != yFrom - 1) && (xx != xFrom) && (xx != xTo - 1) && (zz != zFrom) && (zz != zTo - 1))
                            yy = yFrom;
                    }
                }
            }
        }
        if (waterFound) {
            continue;
        }
        // Generate cave
        for (int xx = xFrom; xx < xTo; xx++) {
            double modX = (xx + chunkX * 16 + 0.5D - x) / offsetXZ;
            for (int zz = zFrom; zz < zTo; zz++) {
                double modZ = (zz + chunkZ * 16 + 0.5D - z) / offsetXZ;
                boolean grassFound = false;
                if (modX * modX + modZ * modZ < 1.0D) {
                    for (int yy = yTo; yy > yFrom; yy--) {
                        double modY = ((yy - 1) + 0.5D - y) / offsetY;
                        if ((modY > -0.7D) && (modX * modX + modY * modY + modZ * modZ < 1.0D)) {
                            Biome biome = Biome.getBiome(chunk.getBiomeId(xx, zz));
                            if (!(biome instanceof CaveBiome)) {
                                continue;
                            }
                            int material = chunk.getBlockId(xx, yy, zz);
                            int materialAbove = chunk.getBlockId(xx, yy + 1, zz);
                            if (material == Block.GRASS || material == Block.MYCELIUM) {
                                grassFound = true;
                            }
                            // TODO: check this
                            // if (this.isSuitableBlock(material, materialAbove, biome))
                            {
                                if (yy - 1 < 10) {
                                    chunk.setBlock(xx, yy, zz, Block.LAVA);
                                } else {
                                    chunk.setBlock(xx, yy, zz, Block.AIR);
                                    // move it down
                                    if (grassFound && (chunk.getBlockId(xx, yy - 1, zz) == Block.DIRT)) {
                                        chunk.setBlock(xx, yy - 1, zz, ((CaveBiome) biome).getSurfaceBlock());
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if (isLargeCave) {
            break;
        }
    }
}
Also used : Biome(cn.nukkit.level.generator.biome.Biome) CaveBiome(cn.nukkit.level.generator.biome.CaveBiome) NukkitRandom(cn.nukkit.math.NukkitRandom) Random(java.util.Random) CaveBiome(cn.nukkit.level.generator.biome.CaveBiome)

Example 4 with Biome

use of cn.nukkit.level.generator.biome.Biome in project Nukkit by Nukkit.

the class PopulatorGroundCover method populate.

@Override
public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom random) {
    FullChunk chunk = level.getChunk(chunkX, chunkZ);
    for (int x = 0; x < 16; ++x) {
        for (int z = 0; z < 16; ++z) {
            Biome biome = Biome.getBiome(chunk.getBiomeId(x, z));
            Block[] cover = biome.getGroundCover();
            if (cover != null && cover.length > 0) {
                int diffY = 0;
                if (!cover[0].isSolid()) {
                    diffY = 1;
                }
                int height = chunk.getHeightMap(x, z);
                if (height == 0 || height == 255)
                    height = 126;
                int y;
                for (y = height + 1; y > 0; --y) {
                    int fullId = chunk.getFullBlock(x, y, z);
                    if (fullId != 0 && !Block.get(fullId >> 4).isTransparent()) {
                        break;
                    }
                }
                int startY = Math.min(127, y + diffY);
                int endY = startY - cover.length;
                for (y = startY; y > endY && y >= 0; --y) {
                    Block b = cover[startY - y];
                    int blockId = chunk.getBlockId(x, y, z);
                    if (blockId == 0 && b.isSolid()) {
                        break;
                    }
                    if (b.getDamage() == 0) {
                        chunk.setBlockId(x, y, z, b.getId());
                    } else {
                        chunk.setBlock(x, y, z, b.getId(), b.getDamage());
                    }
                }
            }
        }
    }
}
Also used : FullChunk(cn.nukkit.level.format.FullChunk) Biome(cn.nukkit.level.generator.biome.Biome) Block(cn.nukkit.block.Block)

Example 5 with Biome

use of cn.nukkit.level.generator.biome.Biome in project Nukkit by Nukkit.

the class BaseFullChunk method checkOldBiomes.

protected void checkOldBiomes(byte[] data) {
    if (data.length != 256) {
        return;
    }
    for (int x = 0; x < 16; ++x) {
        for (int z = 0; z < 16; ++z) {
            Biome biome = Biome.getBiome(data[(z << 4) | x] & 0xff);
            this.setBiomeId(x, z, biome.getId());
            int c = biome.getColor();
            this.setBiomeColor(x, z, c >> 16, (c >> 8) & 0xff, c & 0xff);
        }
    }
}
Also used : Biome(cn.nukkit.level.generator.biome.Biome)

Aggregations

Biome (cn.nukkit.level.generator.biome.Biome)7 FullChunk (cn.nukkit.level.format.FullChunk)5 Block (cn.nukkit.block.Block)1 CaveBiome (cn.nukkit.level.generator.biome.CaveBiome)1 NukkitRandom (cn.nukkit.math.NukkitRandom)1 Random (java.util.Random)1