Пример #1
0
        public static void GenerateRuin(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            // Todo: Support ruins deep underground - empty out their interiors.

            LoadRuinTemplates();

            var noiseVector = Chunk.Origin.ToVector3() * Settings.CaveNoiseScale;
            var ruinsNoise  = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z);

            if (Math.Abs(ruinsNoise) > GameSettings.Current.GenerationRuinsRate)
            {
                return;
            }


            var avgHeight = GetAverageHeight(Chunk.Origin.X, Chunk.Origin.Z, 16, 16, Settings);

            var ruinWallType  = Library.GetVoxelType("Cobble"); // Todo: Should make this data so this doesn't break if tile names change?
            var ruinFloorType = Library.GetVoxelType("Blue Tile");

            if (Settings.Overworld.Map.GetBiomeAt(Chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
            {
                ruinWallType  = Library.GetVoxelType(biome.RuinWallType);
                ruinFloorType = Library.GetVoxelType(biome.RuinFloorType);
            }

            if (!ruinWallType.HasValue() || !ruinFloorType.HasValue())
            {
                return;
            }

            int wallHeight = MathFunctions.RandInt(2, 6);
            var template   = RuinTemplates[MathFunctions.RandInt(0, RuinTemplates.Count)];

            var rotations = MathFunctions.RandInt(0, 3);

            for (var i = 0; i < rotations; ++i)
            {
                template = TextureTool.RotatedCopy(template);
            }

            for (int dx = 0; dx < 16; dx++)
            {
                for (int dz = 0; dz < 16; dz++)
                {
                    var worldPos = new Vector3(Chunk.Origin.X + dx, avgHeight, Chunk.Origin.Z + dz);

                    var baseVoxel  = Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos));
                    var underVoxel = VoxelHelpers.FindFirstVoxelBelow(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));
                    var decay      = Settings.NoiseGenerator.Generate(worldPos.X * 0.05f, worldPos.Y * 0.05f, worldPos.Z * 0.05f);

                    if (decay > 0.7f)
                    {
                        continue;
                    }
                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }
                    if (baseVoxel.Coordinate.Y == (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1)
                    {
                        continue;
                    }
                    if (!underVoxel.IsValid)
                    {
                        continue;
                    }


                    var templateColor = template.Data[template.Index(dx, dz)];

                    if (templateColor == new Color(0, 0, 255, 255)) // Border
                    {
                        continue;
                    }
                    else if (templateColor == new Color(0, 0, 0, 255)) // Space
                    {
                        continue;
                    }
                    else if (templateColor == new Color(255, 0, 0, 255)) // Wall
                    {
                        baseVoxel.RawSetType(ruinWallType);
                        FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel);
                        FillRuinColumn(Settings, ruinWallType, 1, wallHeight, baseVoxel, decay);
                    }
                    else if (templateColor == new Color(128, 128, 0, 255)) // Door
                    {
                        baseVoxel.RawSetType(ruinWallType);
                        FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel);
                        FillRuinColumn(Settings, ruinWallType, 3, wallHeight, baseVoxel, decay);
                    }
                    else if (templateColor == new Color(128, 0, 0, 255)) // Floor
                    {
                        FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel);
                        baseVoxel.RawSetType(ruinFloorType);
                    }
                }
            }
        }