Package com.khorn.terraincontrol.generator.terrain

Source Code of com.khorn.terraincontrol.generator.terrain.CavesGen

package com.khorn.terraincontrol.generator.terrain;

import com.khorn.terraincontrol.LocalBiome;
import com.khorn.terraincontrol.LocalMaterialData;
import com.khorn.terraincontrol.LocalWorld;
import com.khorn.terraincontrol.configuration.BiomeConfig;
import com.khorn.terraincontrol.configuration.WorldConfig;
import com.khorn.terraincontrol.generator.ChunkBuffer;
import com.khorn.terraincontrol.util.ChunkCoordinate;
import com.khorn.terraincontrol.util.helpers.MathHelper;
import com.khorn.terraincontrol.util.minecraftTypes.DefaultMaterial;

import java.util.Random;

public class CavesGen extends TerrainGenBase
{
    private WorldConfig worldSettings;

    public CavesGen(WorldConfig wrk, LocalWorld world)
    {
        super(world);
        this.worldSettings = wrk;
    }

    protected void generateLargeCaveNode(long seed, ChunkBuffer generatingChunkBuffer, double x, double y, double z)
    {
        generateCaveNode(seed, generatingChunkBuffer, x, y, z, 1.0F + this.random.nextFloat() * 6.0F, 0.0F, 0.0F, -1, -1, 0.5D);
    }

    protected void generateCaveNode(long seed, ChunkBuffer generatingChunkBuffer, double x, double y, double z, float paramFloat1,
            float paramFloat2, float paramFloat3, int angle, int maxAngle, double paramDouble4)
    {
        ChunkCoordinate generatingChunk = generatingChunkBuffer.getChunkCoordinate();
        double real_x = generatingChunk.getBlockXCenter();
        double real_z = generatingChunk.getBlockZCenter();

        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 j = localRandom.nextInt(maxAngle / 2) + maxAngle / 4;
        int k = localRandom.nextInt(6) == 0 ? 1 : 0;

        for (; angle < maxAngle; angle++)
        {
            double d3 = 1.5D + MathHelper.sin(angle * 3.141593F / maxAngle) * paramFloat1 * 1.0F;
            double d4 = d3 * paramDouble4;

            float f3 = MathHelper.cos(paramFloat3);
            float f4 = MathHelper.sin(paramFloat3);
            x += MathHelper.cos(paramFloat2) * f3;
            y += f4;
            z += MathHelper.sin(paramFloat2) * f3;

            if (k != 0)
                paramFloat3 *= 0.92F;
            else
            {
                paramFloat3 *= 0.7F;
            }
            paramFloat3 += f2 * 0.1F;
            paramFloat2 += 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 == j) && (paramFloat1 > 1.0F) && (maxAngle > 0))
            {
                generateCaveNode(localRandom.nextLong(), generatingChunkBuffer, x, y, z, localRandom.nextFloat() * 0.5F + 0.5F,
                        paramFloat2 - 1.570796F, paramFloat3 / 3.0F, angle, maxAngle, 1.0D);
                generateCaveNode(localRandom.nextLong(), generatingChunkBuffer, x, y, z, localRandom.nextFloat() * 0.5F + 0.5F,
                        paramFloat2 + 1.570796F, paramFloat3 / 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 d5 = x - real_x;
            double d6 = z - real_z;
            double d7 = maxAngle - angle;
            double d8 = paramFloat1 + 2.0F + 16.0F;
            if (d5 * d5 + d6 * d6 - d7 * d7 > d8 * d8)
            {
                return;
            }

            //Boundaries check.
            if ((x < real_x - 16.0D - d3 * 2.0D) || (z < real_z - 16.0D - d3 * 2.0D) || (x > real_x + 16.0D + d3 * 2.0D) || (z > real_z + 16.0D + d3 * 2.0D))
                continue;


            int m = MathHelper.floor(x - d3) - generatingChunk.getBlockX() - 1;
            int n = MathHelper.floor(x + d3) - generatingChunk.getBlockX() + 1;

            int i1 = MathHelper.floor(y - d4) - 1;
            int i2 = MathHelper.floor(y + d4) + 1;

            int i3 = MathHelper.floor(z - d3) - generatingChunk.getBlockZ() - 1;
            int i4 = MathHelper.floor(z + d3) - generatingChunk.getBlockZ() + 1;

            if (m < 0)
                m = 0;
            if (n > 16)
                n = 16;

            if (i1 < 1)
                i1 = 1;
            if (i2 > this.worldSettings.worldHeightCap - 8)
            {
                i2 = this.worldSettings.worldHeightCap - 8;
            }
            if (i3 < 0)
                i3 = 0;
            if (i4 > 16)
                i4 = 16;

            // Search for water
            boolean waterFound = false;
            for (int local_x = m; (!waterFound) && (local_x < n); local_x++)
            {
                for (int local_z = i3; (!waterFound) && (local_z < i4); local_z++)
                {
                    for (int local_y = i2 + 1; (!waterFound) && (local_y >= i1 - 1); local_y--)
                    {
                        if (local_y >= 0 && local_y < this.worldSettings.worldHeightCap)
                        {
                            LocalMaterialData material = generatingChunkBuffer.getBlock(local_x, local_y, local_z);
                            if (material.isMaterial(DefaultMaterial.WATER)
                                    || material.isMaterial(DefaultMaterial.STATIONARY_WATER))
                            {
                                waterFound = true;
                            }
                            if ((local_y != i1 - 1) && (local_x != m) && (local_x != n - 1) && (local_z != i3) && (local_z != i4 - 1))
                                local_y = i1;
                        }
                    }
                }
            }
            if (waterFound)
                continue;

            // Generate cave
            for (int local_x = m; local_x < n; local_x++)
            {
                double d9 = (local_x + generatingChunk.getBlockX() + 0.5D - x) / d3;
                for (int local_z = i3; local_z < i4; local_z++)
                {
                    LocalBiome biome = this.world.getBiome(local_x + generatingChunk.getBlockX(), local_z + generatingChunk.getBlockZ());
                    double d10 = (local_z + generatingChunk.getBlockZ() + 0.5D - z) / d3;

                    boolean grassFound = false;
                    if (d9 * d9 + d10 * d10 < 1.0D)
                    {
                        for (int local_y = i2; local_y > i1; local_y--)
                        {
                            double d11 = ((local_y - 1) + 0.5D - y) / d4;
                            if ((d11 > -0.7D) && (d9 * d9 + d11 * d11 + d10 * d10 < 1.0D))
                            {
                                LocalMaterialData material = generatingChunkBuffer.getBlock(local_x, local_y, local_z);
                                LocalMaterialData materialAbove = generatingChunkBuffer.getBlock(local_x, local_y + 1, local_z);
                                if (material.isMaterial(DefaultMaterial.GRASS) || material.isMaterial(DefaultMaterial.MYCEL))
                                    grassFound = true;
                                if (this.isSuitableBlock(material, materialAbove, biome))
                                {
                                    if (local_y - 1 < 10)
                                    {
                                        generatingChunkBuffer.setBlock(local_x, local_y, local_z, lava);
                                    } else
                                    {
                                        generatingChunkBuffer.setBlock(local_x, local_y, local_z, air);

                                        // Replace supporting sand with
                                        // sandstone. TODO: support red
                                        // sand(stone) in Minecraft 1.8
                                        if (materialAbove.isMaterial(DefaultMaterial.SAND) && materialAbove.getBlockData() == 0)
                                        {
                                            generatingChunkBuffer.setBlock(local_x, local_y + 1, local_z, sandstone);
                                        }

                                        // If grass was just deleted, try to
                                        // move it down
                                        if (grassFound
                                                && (generatingChunkBuffer.getBlock(local_x, local_y - 1, local_z)
                                                        .isMaterial(DefaultMaterial.DIRT)))
                                        {
                                            generatingChunkBuffer.setBlock(local_x, local_y - 1, local_z,
                                                    biome.getBiomeConfig().surfaceBlock);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (isLargeCave)
                break;
        }
    }

    protected boolean isSuitableBlock(LocalMaterialData material, LocalMaterialData materialAbove, LocalBiome biome)
    {
        BiomeConfig biomeConfig = biome.getBiomeConfig();
        if (material.equals(biomeConfig.stoneBlock))
        {
            return true;
        }
        if (material.canFall())
        {
            return !materialAbove.isLiquid();
        }
        if (material.equals(biomeConfig.groundBlock))
        {
            return true;
        }
        if (material.equals(biomeConfig.surfaceBlock))
        {
            return true;
        }

        // Few hardcoded cases
        if (material.isMaterial(DefaultMaterial.HARD_CLAY))
        {
            return true;
        }
        if (material.isMaterial(DefaultMaterial.SANDSTONE))
        {
            return true;
        }
        // TODO: add red sandstone case in Minecraft 1.8
        if (material.isMaterial(DefaultMaterial.SNOW))
        {
            return true;
        }

        return false;
    }

    @Override
    protected void generateChunk(ChunkCoordinate chunkCoord, ChunkBuffer generatingChunkBuffer)
    {
        int i = this.random.nextInt(this.random.nextInt(this.random.nextInt(this.worldSettings.caveFrequency) + 1) + 1);
        if (this.worldSettings.evenCaveDistribution)
            i = this.worldSettings.caveFrequency;
        if (this.random.nextInt(100) >= this.worldSettings.caveRarity)
            i = 0;

        for (int j = 0; j < i; j++)
        {
            double x = chunkCoord.getBlockX() + this.random.nextInt(ChunkCoordinate.CHUNK_X_SIZE);

            double y;

            if (this.worldSettings.evenCaveDistribution)
                y = this.random.nextInt(this.worldSettings.caveMaxAltitude - this.worldSettings.caveMinAltitude) + this.worldSettings.caveMinAltitude;
            else
                y = this.random.nextInt(this.random.nextInt(this.worldSettings.caveMaxAltitude - this.worldSettings.caveMinAltitude) + 1) + this.worldSettings.caveMinAltitude;

            double z = chunkCoord.getBlockZ() + this.random.nextInt(ChunkCoordinate.CHUNK_Z_SIZE);

            int count = this.worldSettings.caveSystemFrequency;
            boolean largeCaveSpawned = false;
            if (this.random.nextInt(100) <= this.worldSettings.individualCaveRarity)
            {
                generateLargeCaveNode(this.random.nextLong(), generatingChunkBuffer, x, y, z);
                largeCaveSpawned = true;
            }

            if ((largeCaveSpawned) || (this.random.nextInt(100) <= this.worldSettings.caveSystemPocketChance - 1))
            {
                count += this.random.nextInt(this.worldSettings.caveSystemPocketMaxSize - this.worldSettings.caveSystemPocketMinSize) + this.worldSettings.caveSystemPocketMinSize;
            }
            while (count > 0)
            {
                count--;
                float f1 = this.random.nextFloat() * 3.141593F * 2.0F;
                float f2 = (this.random.nextFloat() - 0.5F) * 2.0F / 8.0F;
                float f3 = this.random.nextFloat() * 2.0F + this.random.nextFloat();

                generateCaveNode(this.random.nextLong(), generatingChunkBuffer, x, y, z, f3, f1, f2, 0, 0, 1.0D);
            }
        }
    }

}
TOP

Related Classes of com.khorn.terraincontrol.generator.terrain.CavesGen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.