Beispiel #1
0
        public static void GenerateWater(VoxelChunk chunk, ChunkGeneratorSettings Settings)
        {
            var iceID = Library.GetVoxelType("Ice");

            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x, 0, z) + chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
                    {
                        for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
                        {
                            var globalY = y + chunk.Origin.Y;
                            if (globalY > Settings.NormalizedSeaLevel)
                            {
                                break;
                            }

                            var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                            if (voxel.IsEmpty && voxel.Sunlight)
                            {
                                if (globalY == Settings.NormalizedSeaLevel && biome.WaterSurfaceIce)
                                {
                                    voxel.RawSetType(iceID);
                                }
                                else
                                {
                                    voxel.QuickSetLiquid(biome.WaterIsLava ? LiquidType.Lava : LiquidType.Water, WaterManager.maxWaterLevel);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #2
0
 private static void GenerateSliceGeometry(
     RawPrimitive Into,
     VoxelChunk Chunk,
     int LocalY,
     TerrainTileSheet TileSheet,
     WorldManager World,
     SliceCache Cache)
 {
     for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
     {
         for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
         {
             GenerateVoxelGeometry(Into, VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, LocalY, z)), TileSheet, World, Cache);
         }
     }
 }
        private static void PrecomputeVoxelSlopesSlice(ChunkManager Chunks, VoxelChunk Chunk, int LocalY)
        {
            for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
            {
                for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                {
                    PrecomputeVoxelSlopes(Chunks, VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, LocalY, z)));
                }
            }

            var startChunkCorner = new GlobalVoxelCoordinate(Chunk.ID, new LocalVoxelCoordinate(0, 0, 0)) + new GlobalVoxelOffset(-1, 0, -1);
            var endChunkCorner   = new GlobalVoxelCoordinate(Chunk.ID, new LocalVoxelCoordinate(0, 0, 0)) + new GlobalVoxelOffset(VoxelConstants.ChunkSizeX, 0, VoxelConstants.ChunkSizeZ);

            for (int x = startChunkCorner.X; x <= endChunkCorner.X; ++x)
            {
                var v1 = new VoxelHandle(Chunk.Manager, new GlobalVoxelCoordinate(x, Chunk.Origin.Y + LocalY, startChunkCorner.Z));
                if (v1.IsValid)
                {
                    PrecomputeVoxelSlopes(Chunks, v1);
                }

                var v2 = new VoxelHandle(Chunk.Manager, new GlobalVoxelCoordinate(x, Chunk.Origin.Y + LocalY, endChunkCorner.Z));
                if (v2.IsValid)
                {
                    PrecomputeVoxelSlopes(Chunks, v2);
                }
            }

            for (int z = startChunkCorner.Z + 1; z < endChunkCorner.Z; ++z)
            {
                var v1 = new VoxelHandle(Chunk.Manager, new GlobalVoxelCoordinate(startChunkCorner.X, Chunk.Origin.Y + LocalY, z));
                if (v1.IsValid)
                {
                    PrecomputeVoxelSlopes(Chunks, v1);
                }

                var v2 = new VoxelHandle(Chunk.Manager, new GlobalVoxelCoordinate(endChunkCorner.X, Chunk.Origin.Y + LocalY, z));
                if (v2.IsValid)
                {
                    PrecomputeVoxelSlopes(Chunks, v2);
                }
            }
        }
Beispiel #4
0
        public static void GenerateLava(VoxelChunk chunk, ChunkGeneratorSettings Settings)
        {
            if (chunk.Origin.Y >= Settings.LavaLevel)
            {
                return;
            }

            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    for (var y = 0; y < Settings.LavaLevel - chunk.Origin.Y; ++y)
                    {
                        var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                        if (voxel.IsEmpty && voxel.LiquidLevel == 0)
                        {
                            voxel.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel);
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public static void GenerateCaves(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            if (Library.GetBiome("Cave").HasValue(out BiomeData caveBiome) && Library.GetBiome("Hell").HasValue(out BiomeData hellBiome))
            {
                for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
                {
                    for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                    {
                        for (int i = 0; i < Settings.CaveLevels.Count; i++)
                        {
                            // Does layer intersect this voxel?
                            int y = Settings.CaveLevels[i];
                            if (y + Settings.MaxCaveHeight < Chunk.Origin.Y)
                            {
                                continue;
                            }
                            if (y >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY)
                            {
                                continue;
                            }

                            var coordinate = new GlobalVoxelCoordinate(Chunk.Origin.X + x, y, Chunk.Origin.Z + z);

                            var data = GetCaveGenerationData(coordinate, i, Settings);

                            var biome = (y <= Settings.HellLevel) ? hellBiome : caveBiome;

                            if (!data.CaveHere)
                            {
                                continue;
                            }

                            for (int dy = 0; dy < data.Height; dy++)
                            {
                                var globalY = y + dy;

                                // Prevent caves punching holes in bedrock.
                                if (globalY <= 0)
                                {
                                    continue;
                                }

                                // Check if voxel is inside chunk.
                                if (globalY <= 0 || globalY < Chunk.Origin.Y || globalY >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY)
                                {
                                    continue;
                                }

                                var voxel = VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, globalY - Chunk.Origin.Y, z));

                                // Prevent caves from breaking surface.
                                bool caveBreaksSurface = false;

                                foreach (var neighborCoordinate in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate))
                                {
                                    var v = Chunk.Manager.CreateVoxelHandle(neighborCoordinate);
                                    if (!v.IsValid || (v.Sunlight))
                                    {
                                        caveBreaksSurface = true;
                                        break;
                                    }
                                }

                                if (caveBreaksSurface)
                                {
                                    break;
                                }

                                voxel.RawSetType(Library.EmptyVoxelType);

                                if (dy == 0)
                                {
                                    // Place soil voxel and grass below cave.
                                    var below = VoxelHelpers.GetVoxelBelow(voxel);
                                    if (below.IsValid)
                                    {
                                        below.RawSetType(Library.GetVoxelType(biome.SoilLayer.VoxelType));
                                        var grassType = Library.GetGrassType(biome.GrassDecal);
                                        if (grassType != null)
                                        {
                                            below.RawSetGrass(grassType.ID);
                                        }
                                    }

                                    // Spawn flora and fauna.
                                    if (data.Noise > Settings.CaveSize * 1.8f && globalY > Settings.LavaLevel)
                                    {
                                        GenerateCaveFlora(below, biome, Settings);
                                        GenerateCaveFauna(below, biome, Settings);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #6
0
        public static VoxelChunk GenerateChunk(GlobalChunkCoordinate ID, ChunkGeneratorSettings Settings)
        {
            var origin      = new GlobalVoxelCoordinate(ID, new LocalVoxelCoordinate(0, 0, 0));
            var worldDepth  = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY;
            var waterHeight = NormalizeHeight(Settings.Overworld.GenerationSettings.SeaLevel + 1.0f / worldDepth);

            var c = new VoxelChunk(Settings.World.ChunkManager, ID);

            if (GameSettings.Current.NoStone)
            {
                return(c);
            }

            for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
            {
                for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                {
                    var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), Settings.Overworld.InstanceSettings.Origin);

                    if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x + origin.X, 0, z + origin.Z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biomeData))
                    {
                        var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height));
                        var height           = MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2);
                        var stoneHeight      = (int)MathFunctions.Clamp((int)(height - (biomeData.SoilLayer.Depth + (Math.Sin(overworldPosition.X) + Math.Cos(overworldPosition.Y)))), 1, height);

                        for (int y = 0; y < VoxelConstants.ChunkSizeY; y++)
                        {
                            var globalY = origin.Y + y;
                            var voxel   = VoxelHandle.UnsafeCreateLocalHandle(c, new LocalVoxelCoordinate(x, y, z));

                            if (globalY == 0)
                            {
                                voxel.RawSetType(Library.GetVoxelType("Bedrock"));
                                continue;
                            }

                            // Below the stone line, use subsurface layers.
                            if (globalY <= stoneHeight && stoneHeight > 1)
                            {
                                var depth           = stoneHeight - globalY - biomeData.SubsurfaceLayers[0].Depth + 1;
                                var subsurfaceLayer = 0;
                                while (depth > 0 && subsurfaceLayer < biomeData.SubsurfaceLayers.Count - 1)
                                {
                                    depth           -= biomeData.SubsurfaceLayers[subsurfaceLayer].Depth;
                                    subsurfaceLayer += 1;
                                }

                                voxel.RawSetType(Library.GetVoxelType(biomeData.SubsurfaceLayers[subsurfaceLayer].VoxelType));
                            }
                            // Otherwise, on the surface.
                            else if ((globalY == (int)height || globalY == stoneHeight) && normalizedHeight > waterHeight)
                            {
                                voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType));

                                if (!String.IsNullOrEmpty(biomeData.GrassDecal))
                                {
                                    if (!biomeData.ClumpGrass || (biomeData.ClumpGrass &&
                                                                  Settings.NoiseGenerator.Noise(overworldPosition.X / biomeData.ClumpSize, 0, overworldPosition.Y / biomeData.ClumpSize) > biomeData.ClumpTreshold))
                                    {
                                        voxel.RawSetGrass(Library.GetGrassType(biomeData.GrassDecal).ID);
                                    }
                                }
                            }
                            else if (globalY > height && globalY > 0)
                            {
                                voxel.RawSetType(Library.EmptyVoxelType);
                            }
                            else if (normalizedHeight <= waterHeight)
                            {
                                voxel.RawSetType(Library.GetVoxelType(biomeData.ShoreVoxel));
                            }
                            else
                            {
                                voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType));
                            }
                        }
                    }
                }
            }

            return(c);
        }