Ejemplo n.º 1
0
    public virtual void GenerateTerrain(Chunk chunk, int seed)
    {
        System.Random rng           = new System.Random(unchecked (seed + chunk.Position.GetHashCode()));
        Vector3Int    worldPosition = chunk.Position * Chunk.CHUNK_SIZE;

        var biomeLocker = chunk.GetBiomeLock();

        biomeLocker.EnterReadLock();

        var locker = chunk.GetLock();

        locker.EnterWriteLock();
        for (int x = 0; x < Chunk.CHUNK_SIZE; x++)
        {
            for (int z = 0; z < Chunk.CHUNK_SIZE; z++)
            {
                int globalX = x + worldPosition.x;
                int globalZ = z + worldPosition.z;

                (double temperature, double humidity) = GetBiomeValues(globalX, globalZ);

                Biome primaryBiome  = GetPrimaryAndHeight(chunk, x, z, globalX, globalZ, out double height);
                int   terrainHeight = (int)height;

                Block lastBlock = null;
                for (int y = 0; y < Chunk.CHUNK_SIZE; y++)
                {
                    int   globalY  = y + worldPosition.y;
                    int   index    = x + y * Chunk.CHUNK_SIZE + z * Chunk.CHUNK_SIZE_SQR;
                    Block newBlock = Air;

                    if (globalY > terrainHeight)
                    {
                        if (globalY <= WATER_LEVEL)
                        {
                            newBlock = Water;
                        }
                        else if (globalY - 1 == terrainHeight)
                        {
                            if (lastBlock != null && GetFloral(lastBlock, temperature, humidity, globalY, rng, out Block floral))
                            {
                                newBlock = floral;
                            }
                        }
                    }
                    else if (globalY <= terrainHeight)
                    {
                        newBlock = primaryBiome.GetBlock(terrainHeight, globalY, rng);
                    }

                    lastBlock = newBlock;

                    chunk.SetBlock(newBlock, index, true, false);
                }
            }
        }

        biomeLocker.ExitReadLock();

        locker.ExitWriteLock();
    }