Search in sources :

Example 1 with CaveBiome

use of cn.nukkit.level.generator.biome.CaveBiome 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)

Aggregations

Biome (cn.nukkit.level.generator.biome.Biome)1 CaveBiome (cn.nukkit.level.generator.biome.CaveBiome)1 NukkitRandom (cn.nukkit.math.NukkitRandom)1 Random (java.util.Random)1