SetBlock() публичный Метод

Sets a block at given coordinates. Checks bounds.
public SetBlock ( Vector3I coords, Block type ) : void
coords Vector3I Coordinate vector (X,Y,Z).
type Block Block type to set.
Результат void
Пример #1
0
        internal static void GenerateFlatgrass(Map map, bool hollow)
        {
            for (int i = 0; i < map.widthX; i++)
            {
                for (int j = 0; j < map.widthY; j++)
                {
                    if (!hollow)
                    {
                        for (int k = 1; k < map.height / 2 - 1; k++)
                        {
                            if (k < map.height / 2 - 5)
                            {
                                map.SetBlock(i, j, k, Block.Stone);
                            }
                            else
                            {
                                map.SetBlock(i, j, k, Block.Dirt);
                            }
                        }
                    }
                    map.SetBlock(i, j, map.height / 2 - 1, Block.Grass);
                }
            }

            map.MakeFloodBarrier();
        }
Пример #2
0
        void ExpandGround()
        {
            Map newMap = new Map(null, map.Width, map.Length, map.Height, false)
            {
                Blocks = (byte[])map.Blocks.Clone()
            };

            for (int x = 2; x < genParams.MapWidth - 2; x++)
            {
                for (int y = 2; y < genParams.MapLength - 2; y++)
                {
                    for (int z = 2; z < genParams.MapHeight - 2; z++)
                    {
                        if (map.GetBlock(x, y, z) == Block.Air)
                        {
                            if (HasNeighbors(x, y, z))
                            {
                                newMap.SetBlock(x, y, z, Block.Dirt);
                            }
                        }
                        else
                        {
                            newMap.SetBlock(x, y, z, Block.Stone);
                        }
                    }
                }
                if (x % 4 == 0)
                {
                    int percent = x * 100 / map.Width;
                    ReportProgress(percent / 2 + 30, "Expanding (" + percent + "%)...");
                }
            }
            map = newMap;
        }
Пример #3
0
        void SmoothEdges()
        {
            Map newMap = new Map(null, map.Width, map.Length, map.Height, false)
            {
                Blocks = (byte[])map.Blocks.Clone()
            };

            for (int x = 1; x < genParams.MapWidth - 1; x++)
            {
                for (int y = 1; y < genParams.MapLength - 1; y++)
                {
                    for (int z = 1; z < genParams.MapHeight - 1; z++)
                    {
                        int sum = (map.GetBlock(x - 1, y, z) != Block.Air ? 1 : 0) +
                                  (map.GetBlock(x + 1, y, z) != Block.Air ? 1 : 0) +
                                  (map.GetBlock(x, y - 1, z) != Block.Air ? 1 : 0) +
                                  (map.GetBlock(x, y + 1, z) != Block.Air ? 1 : 0) +
                                  (map.GetBlock(x, y, z - 1) != Block.Air ? 1 : 0) +
                                  (map.GetBlock(x, y, z + 1) != Block.Air ? 1 : 0);
                        if (map.GetBlock(x, y, z) != Block.Air)
                        {
                            newMap.SetBlock(x, y, z, Block.White);
                        }
                        else if (sum > 1 && map.GetBlock(x, y, z - 1) != Block.Air)
                        {
                            newMap.SetBlock(x, y, z, Block.Blue);
                        }
                    }
                }
            }
            map = newMap;
        }
Пример #4
0
        /// <summary> Makes an admincrete barrier, 1 block thick, around the lower half of the map. </summary>
        public static void MakeFloodBarrier(Map map)
        {
            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Length; y++)
                {
                    map.SetBlock(x, y, 0, Block.Admincrete);
                }
            }

            for (int x = 0; x < map.Width; x++)
            {
                for (int z = 0; z < map.Height / 2; z++)
                {
                    map.SetBlock(x, 0, z, Block.Admincrete);
                    map.SetBlock(x, map.Length - 1, z, Block.Admincrete);
                }
            }

            for (int y = 0; y < map.Length; y++)
            {
                for (int z = 0; z < map.Height / 2; z++)
                {
                    map.SetBlock(0, y, z, Block.Admincrete);
                    map.SetBlock(map.Width - 1, y, z, Block.Admincrete);
                }
            }
        }
Пример #5
0
        private void AddBeaches([NotNull] Map map)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            int beachExtentSqr = (args.BeachExtent + 1) * (args.BeachExtent + 1);

            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Length; y++)
                {
                    for (int z = args.WaterLevel; z <= args.WaterLevel + args.BeachHeight; z++)
                    {
                        if (map.GetBlock(x, y, z) != bGroundSurface)
                        {
                            continue;
                        }
                        bool found = false;
                        for (int dx = -args.BeachExtent; !found && dx <= args.BeachExtent; dx++)
                        {
                            for (int dy = -args.BeachExtent; !found && dy <= args.BeachExtent; dy++)
                            {
                                for (int dz = -args.BeachHeight; dz <= 0; dz++)
                                {
                                    if (dx * dx + dy * dy + dz * dz > beachExtentSqr)
                                    {
                                        continue;
                                    }
                                    int xx = x + dx;
                                    int yy = y + dy;
                                    int zz = z + dz;
                                    if (xx < 0 || xx >= map.Width || yy < 0 || yy >= map.Length || zz < 0 ||
                                        zz >= map.Height)
                                    {
                                        continue;
                                    }
                                    Block block = map.GetBlock(xx, yy, zz);
                                    if (block == bWater || block == bWaterSurface)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (found)
                        {
                            map.SetBlock(x, y, z, bSeaFloor);
                            if (z > 0 && map.GetBlock(x, y, z - 1) == bGround)
                            {
                                map.SetBlock(x, y, z - 1, bSeaFloor);
                            }
                        }
                    }
                }
            }
        }
Пример #6
0
        void AddBeaches(Map map)
        {
            int beachExtentSqr = (args.BeachExtent + 1) * (args.BeachExtent + 1);

            for (int x = 0; x < map.WidthX; x++)
            {
                for (int y = 0; y < map.WidthY; y++)
                {
                    for (int h = args.WaterLevel; h <= args.WaterLevel + args.BeachHeight; h++)
                    {
                        if (map.GetBlock(x, y, h) != bGroundSurface)
                        {
                            continue;
                        }
                        bool found = false;
                        for (int dx = -args.BeachExtent; !found && dx <= args.BeachExtent; dx++)
                        {
                            for (int dy = -args.BeachExtent; !found && dy <= args.BeachExtent; dy++)
                            {
                                for (int dh = -args.BeachHeight; dh <= 0; dh++)
                                {
                                    if (dx * dx + dy * dy + dh * dh > beachExtentSqr)
                                    {
                                        continue;
                                    }
                                    int xx = x + dx;
                                    int yy = y + dy;
                                    int hh = h + dh;
                                    if (xx < 0 || xx >= map.WidthX || yy < 0 || yy >= map.WidthY || hh < 0 ||
                                        hh >= map.Height)
                                    {
                                        continue;
                                    }
                                    Block block = map.GetBlock(xx, yy, hh);
                                    if (block == bWater || block == bWaterSurface)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (found)
                        {
                            map.SetBlock(x, y, h, bSeaFloor);
                            if (h > 0 && map.GetBlock(x, y, h - 1) == bGround)
                            {
                                map.SetBlock(x, y, h - 1, bSeaFloor);
                            }
                        }
                    }
                }
            }
        }
Пример #7
0
 private static void SetUpRed()
 {
     for (int x = 0; x <= _map.Width; x++)
     {
         for (int y = 0; y <= 10; y++)
         {
             _map.SetBlock(x, y, _ground, Block.Red);
             _map.SetBlock(x, y, _ground - 1, Block.Black);
         }
     }
 }
Пример #8
0
 public static void GenerateFlatgrass(Map map)
 {
     for (int i = 0; i < map.WidthX; i++)
     {
         for (int j = 0; j < map.WidthY; j++)
         {
             for (int k = 0; k < map.Height / 2 - 1; k++)
             {
                 if (k < map.Height / 2 - 5)
                 {
                     map.SetBlock(i, j, k, Block.Stone);
                 }
                 else
                 {
                     map.SetBlock(i, j, k, Block.Dirt);
                 }
             }
             map.SetBlock(i, j, map.Height / 2 - 1, Block.Grass);
         }
     }
 }
Пример #9
0
 public void Generate()
 {
     double[,] heightmap = GenerateHeightmap(map.widthX, map.widthY);
     Feedback("Filling...");
     for (int x = 0; x < map.widthX; x++)
     {
         for (int y = 0; y < map.widthY; y++)
         {
             double level = heightmap[x, y];
             if (level > water)
             {
                 level = (level - water) * smoothingOver + water;
                 map.SetBlock(x, y, (int)(level * map.height), Block.Grass);
                 if (!hollow)
                 {
                     for (int i = (int)(level * map.height) - 1; i > 0; i--)
                     {
                         if ((int)(level * map.height) - i < 5)
                         {
                             map.SetBlock(x, y, i, Block.Dirt);
                         }
                         else
                         {
                             map.SetBlock(x, y, i, Block.Stone);
                         }
                     }
                 }
             }
             else
             {
                 level = (level - water) * smoothingUnder + water;
                 map.SetBlock(x, y, (int)(water * map.height), Block.Water);
                 if (!hollow)
                 {
                     for (int i = (int)(water * map.height) - 1; i >= (int)(level * map.height); i--)
                     {
                         map.SetBlock(x, y, i, Block.Water);
                     }
                 }
                 map.SetBlock(x, y, (int)(level * map.height), Block.Sand);
                 if (!hollow)
                 {
                     for (int i = (int)(level * map.height) - 1; i > 0; i--)
                     {
                         map.SetBlock(x, y, i, Block.Stone);
                     }
                 }
             }
         }
     }
     map.MakeFloodBarrier();
     map.Save(filename);
     Feedback("Done.");
 }
Пример #10
0
        void PlantGiantTrees()
        {
            if (genParams.GiantTreeDensity <= 0)
            {
                return;
            }
            Map outMap = new Map(null, map.Width, map.Length, map.Height, false)
            {
                Blocks = (byte[])map.Blocks.Clone()
            };
            int plantableBlocks = ComputeSurfaceCoverage(Block.Grass);
            var foresterArgs    = new ForesterArgs {
                Map       = map,
                Rand      = rand,
                TreeCount = (int)(plantableBlocks * genParams.GiantTreeDensity / BaseGiantTreeDensity),
                Operation = Forester.ForesterOperation.Add,
                PlantOn   = Block.Grass
            };

            foresterArgs.BlockPlacing += (sender, e) => outMap.SetBlock(e.Coordinate, e.Block);
            Forester.Generate(foresterArgs);
            map = outMap;
        }
Пример #11
0
        public void setIgloo(Map Map, int xIn, int yIn, int zIn)
        {
            int width  = rand.Next(15, 30);
            int height = rand.Next(15, 30);

            for (int x = -width; x <= width; x++)
            {
                for (int y = height; y >= -height; y--)
                {
                    for (int z = -width; z <= width; z++)
                    {
                        if (y == height || (Math.Abs(x) == width && Math.Abs(z) == width && y >= 0))
                        {
                            Map.SetBlock(x + xIn, y + yIn, z + zIn, Block.Stone);
                            Map.SetBlock(x + xIn, y + yIn + 1, z + zIn, Block.Admincrete);
                        }

                        if (y >= 1 && ((Math.Abs(x) == width) ^ (Math.Abs(z) == width)))
                        {
                            Map.SetBlock(x + xIn, y + yIn, z + zIn, Block.Gravel);
                        }

                        if (y > 0 && y < height && Math.Abs(z) < width && Math.Abs(x) < width)
                        {
                            Map.SetBlock(x + xIn, y + yIn, z + zIn, Block.Air);   //unsure
                        }
                        if (y == -1 || y == 0)
                        {
                            Map.SetBlock(x + xIn, y + yIn, z + zIn, Block.Gray);
                        }

                        if (y < -1)
                        {
                            if ((Math.Abs(x) == width || Math.Abs(z) == width))
                            {
                                Map.SetBlock(x + xIn, y + yIn, z + zIn, Block.Brick);
                            }
                        }
                    }
                }
            }
        }
Пример #12
0
        public Map GenerateMap()
        {
            Map map = new Map(null, args.MapWidth, args.MapLength, args.MapHeight, true);

            // Match water coverage
            float desiredWaterLevel = .5f;
            if (args.MatchWaterCoverage)
            {
                ReportProgress(2, "Heightmap Processing: Matching water coverage");
                desiredWaterLevel = Noise.FindThreshold(heightmap, args.WaterCoverage);
            }

            // Calculate above/below water multipliers
            float aboveWaterMultiplier = 0;
            if (desiredWaterLevel != 1)
            {
                aboveWaterMultiplier = (args.MaxHeight / (1 - desiredWaterLevel));
            }

            // Apply power functions to above/below water parts of the heightmap
            if (args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1)
            {
                ReportProgress(5, "Heightmap Processing: Adjusting slope");
                for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
                {
                    for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                    {
                        if (heightmap[x, y] < desiredWaterLevel)
                        {
                            float normalizedDepth = 1 - heightmap[x, y] / desiredWaterLevel;
                            heightmap[x, y] = desiredWaterLevel - (float)Math.Pow(normalizedDepth, args.BelowFuncExponent) * desiredWaterLevel;
                        }
                        else
                        {
                            float normalizedHeight = (heightmap[x, y] - desiredWaterLevel) / (1 - desiredWaterLevel);
                            heightmap[x, y] = desiredWaterLevel + (float)Math.Pow(normalizedHeight, args.AboveFuncExponent) * (1 - desiredWaterLevel);
                        }
                    }
                }
            }

            // Calculate the slope
            if (args.CliffSmoothing)
            {
                ReportProgress(2, "Heightmap Processing: Smoothing");
                slopemap = Noise.CalculateSlope(Noise.GaussianBlur5X5(heightmap));
            }
            else
            {
                slopemap = Noise.CalculateSlope(heightmap);
            }

            float[,] altmap = null;
            if (args.MaxHeightVariation != 0 || args.MaxDepthVariation != 0)
            {
                ReportProgress(5, "Heightmap Processing: Randomizing");
                altmap = new float[map.Width, map.Length];
                int blendmapDetailSize = (int)Math.Log(Math.Max(args.MapWidth, args.MapLength), 2) - 2;
                new Noise(rand.Next(), NoiseInterpolationMode.Cosine).PerlinNoise(altmap, 3, blendmapDetailSize, 0.5f, 0, 0);
                Noise.Normalize(altmap, -1, 1);
            }

            int snowStartThreshold = args.SnowAltitude - args.SnowTransition;
            int snowThreshold = args.SnowAltitude;

            ReportProgress(10, "Filling");
            for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
            {
                for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                {
                    int level;
                    float slope;
                    if (heightmap[x, y] < desiredWaterLevel)
                    {
                        float depth = args.MaxDepth;
                        if (altmap != null)
                        {
                            depth += altmap[x, y] * args.MaxDepthVariation;
                        }
                        slope = slopemap[x, y] * depth;
                        level = args.WaterLevel - (int)Math.Round(Math.Pow(1 - heightmap[x, y] / desiredWaterLevel, args.BelowFuncExponent) * depth);

                        if (args.AddWater)
                        {
                            if (args.WaterLevel - level > 3)
                            {
                                map.SetBlock(x, y, args.WaterLevel, bDeepWaterSurface);
                            }
                            else
                            {
                                map.SetBlock(x, y, args.WaterLevel, bWaterSurface);
                            }
                            for (int i = args.WaterLevel; i > level; i--)
                            {
                                map.SetBlock(x, y, i, bWater);
                            }
                            for (int i = level; i >= 0; i--)
                            {
                                if (level - i < SeaFloorThickness)
                                {
                                    map.SetBlock(x, y, i, bSeaFloor);
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, bBedrock);
                                }
                            }
                        }
                        else
                        {
                            if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                            {
                                map.SetBlock(x, y, level, bCliff);
                            }
                            else
                            {
                                if (slope < args.CliffThreshold)
                                {
                                    map.SetBlock(x, y, level, bGroundSurface);
                                }
                                else
                                {
                                    map.SetBlock(x, y, level, bCliff);
                                }
                            }

                            for (int i = level - 1; i >= 0; i--)
                            {
                                if (level - i < groundThickness)
                                {
                                    if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                    {
                                        map.SetBlock(x, y, i, bCliff);
                                    }
                                    else
                                    {
                                        if (slope < args.CliffThreshold)
                                        {
                                            map.SetBlock(x, y, i, bGround);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, bCliff);
                                        }
                                    }
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, bBedrock);
                                }
                            }
                        }

                    }
                    else
                    {
                        float height;
                        if (altmap != null)
                        {
                            height = args.MaxHeight + altmap[x, y] * args.MaxHeightVariation;
                        }
                        else
                        {
                            height = args.MaxHeight;
                        }
                        slope = slopemap[x, y] * height;
                        if (height != 0)
                        {
                            level = args.WaterLevel + (int)Math.Round(Math.Pow(heightmap[x, y] - desiredWaterLevel, args.AboveFuncExponent) * aboveWaterMultiplier / args.MaxHeight * height);
                        }
                        else
                        {
                            level = args.WaterLevel;
                        }

                        bool snow = args.AddSnow &&
                                    (level > snowThreshold ||
                                    (level > snowStartThreshold && rand.NextDouble() < (level - snowStartThreshold) / (double)(snowThreshold - snowStartThreshold)));

                        if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                        {
                            map.SetBlock(x, y, level, bCliff);
                        }
                        else
                        {
                            if (slope < args.CliffThreshold)
                            {
                                map.SetBlock(x, y, level, (snow ? Block.White : bGroundSurface));
                            }
                            else
                            {
                                map.SetBlock(x, y, level, bCliff);
                            }
                        }

                        for (int i = level - 1; i >= 0; i--)
                        {
                            if (level - i < groundThickness)
                            {
                                if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                {
                                    map.SetBlock(x, y, i, bCliff);
                                }
                                else
                                {
                                    if (slope < args.CliffThreshold)
                                    {
                                        if (snow)
                                        {
                                            map.SetBlock(x, y, i, Block.White);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, bGround);
                                        }
                                    }
                                    else
                                    {
                                        map.SetBlock(x, y, i, bCliff);
                                    }
                                }
                            }
                            else
                            {
                                map.SetBlock(x, y, i, bBedrock);
                            }
                        }
                    }
                }
            }

            if (args.AddCaves || args.AddOre)
            {
                AddCaves(map);
            }

            if (args.AddBeaches)
            {
                ReportProgress(5, "Processing: Adding beaches");
                AddBeaches(map);
            }

            if (args.AddTrees)
            {
                ReportProgress(5, "Processing: Planting trees");
                if (args.AddGiantTrees)
                {
                    Map outMap = new Map(null, map.Width, map.Length, map.Height, false) { Blocks = (byte[])map.Blocks.Clone() };
                    var foresterArgs = new ForesterArgs
                    {
                        Map = map,
                        Rand = rand,
                        TreeCount = (int)(map.Width * map.Length * 4 / (1024f * (args.TreeSpacingMax + args.TreeSpacingMin) / 2)),
                        Operation = Forester.ForesterOperation.Add,
                        PlantOn = bGroundSurface
                    };
                    foresterArgs.BlockPlacing += (sender, e) => outMap.SetBlock(e.Coordinate, e.Block);
                    Forester.Generate(foresterArgs);
                    map = outMap;
                }
                GenerateTrees(map);
            }

            ReportProgress(0, "Generation complete");

            map.Metadata["_Origin", "GeneratorName"] = "fCraft";
            map.Metadata["_Origin", "GeneratorVersion"] = Updater.LatestStable;
            map.Metadata["_Origin", "GeneratorParams"] = args.Serialize().ToString(SaveOptions.DisableFormatting);
            return map;
        }
Пример #13
0
 void PlantGiantTrees() {
     if( genParams.GiantTreeDensity <= 0 ) return;
     Map outMap = new Map( null, map.Width, map.Length, map.Height, false ) {
         Blocks = (byte[])map.Blocks.Clone()
     };
     int plantableBlocks = ComputeSurfaceCoverage( Block.Grass );
     var foresterArgs = new ForesterArgs {
         Map = map,
         Rand = rand,
         TreeCount = (int)(plantableBlocks*genParams.GiantTreeDensity/BaseGiantTreeDensity),
         Operation = Forester.ForesterOperation.Add,
         PlantOn = Block.Grass
     };
     foresterArgs.BlockPlacing += ( sender, e ) => outMap.SetBlock( e.Coordinate, e.Block );
     Forester.Generate( foresterArgs );
     map = outMap;
 }
Пример #14
0
 void ExpandGround() {
     Map newMap = new Map( null, map.Width, map.Length, map.Height, false ) {Blocks = (byte[])map.Blocks.Clone()};
     for( int x = 2; x < genParams.MapWidth - 2; x++ ) {
         for( int y = 2; y < genParams.MapLength - 2; y++ ) {
             for( int z = 2; z < genParams.MapHeight - 2; z++ ) {
                 if( map.GetBlock( x, y, z ) == Block.Air ) {
                     if( HasNeighbors( x, y, z ) ) {
                         newMap.SetBlock( x, y, z, Block.Dirt );
                     }
                 } else {
                     newMap.SetBlock( x, y, z, Block.Stone );
                 }
             }
         }
         if( x%4 == 0 ) {
             int percent = x*100/map.Width;
             ReportProgress( percent/2 + 30, "Expanding (" + percent + "%)..." );
         }
     }
     map = newMap;
 }
Пример #15
0
 void SmoothEdges() {
     Map newMap = new Map( null, map.Width, map.Length, map.Height, false ) {Blocks = (byte[])map.Blocks.Clone()};
     for( int x = 1; x < genParams.MapWidth - 1; x++ ) {
         for( int y = 1; y < genParams.MapLength - 1; y++ ) {
             for( int z = 1; z < genParams.MapHeight - 1; z++ ) {
                 int sum = (map.GetBlock( x - 1, y, z ) != Block.Air ? 1 : 0) +
                           (map.GetBlock( x + 1, y, z ) != Block.Air ? 1 : 0) +
                           (map.GetBlock( x, y - 1, z ) != Block.Air ? 1 : 0) +
                           (map.GetBlock( x, y + 1, z ) != Block.Air ? 1 : 0) +
                           (map.GetBlock( x, y, z - 1 ) != Block.Air ? 1 : 0) +
                           (map.GetBlock( x, y, z + 1 ) != Block.Air ? 1 : 0);
                 if( map.GetBlock( x, y, z ) != Block.Air ) {
                     newMap.SetBlock( x, y, z, Block.White );
                 } else if( sum > 1 && map.GetBlock( x, y, z - 1 ) != Block.Air ) {
                     newMap.SetBlock( x, y, z, Block.Blue );
                 }
             }
         }
     }
     map = newMap;
 }
Пример #16
0
        public override Map Generate() {
            if( Finished ) return Result;
            try {
                ReportProgress( 0, "Clumping spheres..." );
                rand = new Random( genParams.Seed );
                map = new Map( null, genParams.MapWidth, genParams.MapLength, genParams.MapHeight, true );

                int numIslands = Math.Max( 1, (int)(map.Volume * genParams.IslandDensity / (96 * 96 * 64)) );
                Random islandCoordRand = new Random( rand.Next() );

                List<Island> islands = new List<Island>();

                for( int i = 0; i < numIslands; i++ ) {
                    Vector3I offset = new Vector3I( islandCoordRand.Next( 16, genParams.MapWidth - 16 ),
                                                    islandCoordRand.Next( 16, genParams.MapLength - 16 ),
                                                    islandCoordRand.Next( 16, genParams.MapHeight - 16 ) );
                    islands.Add( CreateIsland( offset ) );
                }
                if( Canceled ) return null;
                
                ReportProgress( 10, "Smoothing (0%)..." );
                SmoothEdges();
                if( Canceled ) return null;
                
                ReportProgress( 15, "Smoothing (50%)..." );
                SmoothEdges();
                if( Canceled ) return null;
                
                ReportProgress( 20, "Expanding..." );
                ExpandGround();
                if( Canceled ) return null;

                ReportProgress( 70, "Adding stone..." );
                for( int i = 0; i < numIslands; i++ ) {
                    MakeIslandBase( islands[i] );
                }

                ReportProgress( 75, "Planting grass..." );
                PlantGrass();
                if( Canceled ) return null;
                
                ReportProgress( 80, "Watering..." );
                for( int x = 0; x < map.Width; x++ ) {
                    for( int y = 0; y < map.Length; y++ ) {
                        map.SetBlock( x, y, 0, Block.Admincrete );
                        map.SetBlock( x, y, 1, Block.Water );
                    }
                }
                MakeWater();
                if( Canceled ) return null;
                
                ReportProgress( 85, "Planting trees..." );
                PlantGiantTrees();
                PlantTrees();
                if( Canceled ) return null;

                ReportProgress( 88, "Planting flowers..." );
                PlantFlowers();
                if( Canceled ) return null;
                
                ReportProgress( 90, "Eroding (0%)..." );
                Erode();
                if( Canceled ) return null;
                ReportProgress( 95, "Eroding (50%)..." );
                Erode();
                if( Canceled ) return null;
                
                Result = map;
                return Result;
            } finally {
                Finished = true;
                Progress = 100;
                StatusString = (Canceled ? "Canceled" : "Finished");
            }
        }
Пример #17
0
        internal static void DoGenerate( Map map, Player player, string mode, string filename, Random rand, bool hollow )
        {
            switch( mode ) {
                case "flatgrass":
                    player.Message( "Generating flatgrass map..." );
                    GenerateFlatgrass( map, hollow );

                    if( map.Save( filename ) ) {
                        player.Message( "Map generation: Done." );
                    } else {
                        player.Message( Color.Red, "An error occured while generating the map." );
                    }
                    break;

                case "lag":
                    player.Message( "Generating laggy map..." );
                    for( int x = 0; x < map.widthX; x+=2 ) {
                        for( int y = 0; y < map.widthY; y+=2 ) {
                            for( int h = 0; h < map.widthY; h+=2 ) {
                                map.SetBlock( x, y, h, Block.Lava );
                            }
                        }
                    }

                    if( map.Save( filename ) ) {
                        player.Message( "Map generation: Done." );
                    } else {
                        player.Message( Color.Red, "An error occured while generating the map." );
                    }
                    break;

                case "empty":
                    player.Message( "Generating empty map..." );
                    map.MakeFloodBarrier();

                    if( map.Save( filename ) ) {
                        player.Message( "Map generation: Done." );
                    } else {
                        player.Message( Color.Red, "An error occured while generating the map." );
                    }

                    break;

                case "hills":
                    player.Message( "Generating terrain..." );
                    Tasks.Add( MapGenerator.GenerationTask, new MapGenerator( rand, map, player, filename,
                                                                              1, 1, 0.5, 0.5, 0, 0.5, hollow ), false );
                    break;

                case "mountains":
                    player.Message( "Generating terrain..." );
                    Tasks.Add( MapGenerator.GenerationTask, new MapGenerator( rand, map, player, filename,
                                                                              4, 1, 0.5, 0.5, 0.1, 0.5, hollow ), false );
                    break;

                case "lake":
                    player.Message( "Generating terrain..." );
                    Tasks.Add( MapGenerator.GenerationTask, new MapGenerator( rand, map, player, filename,
                                                                              1, 0.6, 0.9, 0.5, -0.35, 0.55, hollow ), false );
                    break;

                case "island":
                    player.Message( "Generating terrain..." );
                    Tasks.Add( MapGenerator.GenerationTask, new MapGenerator( rand, map, player, filename,
                                                                              1, 0.6, 1, 0.5, 0.3, 0.35, hollow ), false );
                    break;

                default:
                    player.Message( "Unknown map generation mode: " + mode );
                    break;
            }
        }
Пример #18
0
        internal static void GenerateFlatgrass( Map map, bool hollow )
        {
            for ( int i = 0; i < map.widthX; i++ ) {
                for ( int j = 0; j < map.widthY; j++ ) {
                    if ( !hollow ) {
                        for ( int k = 1; k < map.height / 2 - 1; k++ ) {
                            if ( k < map.height / 2 - 5 ) {
                                map.SetBlock( i, j, k, Block.Stone );
                            } else {
                                map.SetBlock( i, j, k, Block.Dirt );
                            }
                        }
                    }
                    map.SetBlock( i, j, map.height / 2 - 1, Block.Grass );
                }
            }

            map.MakeFloodBarrier();
        }
Пример #19
0
        // Plant a single tree - Based on Minecraft Classic's "com.mojang.minecraft.level.maybeGrowTree"
        void GrowTree(Random treeRand, int startX, int startY, int startZ)
        {
            int treeHeight = treeRand.Next(3) + 4;

            Block blockUnder = map.GetBlock(startX, startY, startZ - 1);

            if ((blockUnder != Block.Grass) || (startZ >= map.Height - treeHeight - 1))
            {
                return;
            }

            for (int z = startZ; z <= startZ + 1 + treeHeight; z++)
            {
                int extent = 1;
                if (z == startZ)
                {
                    extent = 0;
                }
                if (z >= startZ + 1 + treeHeight - 2)
                {
                    extent = 2;
                }
                for (int x = startX - extent; (x <= startX + extent); x++)
                {
                    for (int y = startY - extent; (y <= startY + extent); y++)
                    {
                        if ((x >= 0) && (z >= 0) && (y >= 0) && (x < map.Width) && (z < map.Height) && (y < map.Length))
                        {
                            if (map.GetBlock(x, y, z) != Block.Air)
                            {
                                return;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }
            }

            map.SetBlock(startX, startY, startZ - 1, Block.Dirt);

            for (int z = startZ - 3 + treeHeight; z <= startZ + treeHeight; z++)
            {
                int n             = z - (startZ + treeHeight);
                int foliageExtent = 1 - n / 2;
                for (int x = startX - foliageExtent; x <= startX + foliageExtent; x++)
                {
                    int j = x - startX;
                    for (int y = startY - foliageExtent; y <= startY + foliageExtent; y++)
                    {
                        int i3 = y - startY;
                        if ((Math.Abs(j) == foliageExtent) && (Math.Abs(i3) == foliageExtent) &&
                            ((treeRand.Next(2) == 0) || (n == 0)))
                        {
                            continue;
                        }
                        map.SetBlock(x, y, z, Block.Leaves);
                    }
                }
            }
            for (int z = 0; z < treeHeight; z++)
            {
                map.SetBlock(startX, startY, startZ + z, Block.Log);
            }
        }
Пример #20
0
        public Map GenerateMap()
        {
            Map map = new Map(null, args.WidthX, args.WidthY, args.Height, true);


            // Match water coverage
            float desiredWaterLevel = .5f;

            if (args.MatchWaterCoverage)
            {
                ReportProgress(2, "Heightmap Processing: Matching water coverage");
                desiredWaterLevel = MatchWaterCoverage(heightmap, args.WaterCoverage);
            }


            // Calculate above/below water multipliers
            float aboveWaterMultiplier = 0;

            if (desiredWaterLevel != 1)
            {
                aboveWaterMultiplier = (args.MaxHeight / (1 - desiredWaterLevel));
            }


            // Apply power functions to above/below water parts of the heightmap
            if (args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1)
            {
                ReportProgress(5, "Heightmap Processing: Adjusting slope");
                for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
                {
                    for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                    {
                        if (heightmap[x, y] < desiredWaterLevel)
                        {
                            float normalizedDepth = 1 - heightmap[x, y] / desiredWaterLevel;
                            heightmap[x, y] = desiredWaterLevel - (float)Math.Pow(normalizedDepth, args.BelowFuncExponent) * desiredWaterLevel;
                        }
                        else
                        {
                            float normalizedHeight = (heightmap[x, y] - desiredWaterLevel) / (1 - desiredWaterLevel);
                            heightmap[x, y] = desiredWaterLevel + (float)Math.Pow(normalizedHeight, args.AboveFuncExponent) * (1 - desiredWaterLevel);
                        }
                    }
                }
            }

            // Calculate the slope
            if (args.CliffSmoothing)
            {
                ReportProgress(2, "Heightmap Processing: Smoothing");
                slopemap = Noise.CalculateSlope(Noise.GaussianBlur5X5(heightmap));
            }
            else
            {
                slopemap = Noise.CalculateSlope(heightmap);
            }

            int   level;
            float slope;

            /* draw heightmap visually (DEBUG)
             *
             *
             * float underWaterMultiplier = 0;
             * if( desiredWaterLevel != 0 ) {
             *  underWaterMultiplier = (float)(args.maxDepth / desiredWaterLevel);
             * }
             *
             * for( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) {
             *  for( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) {
             *      if( heightmap[x, y] < desiredWaterLevel ) {
             *          slope = slopemap[x, y] * args.maxDepth;
             *          level = args.waterLevel - (int)Math.Round( (desiredWaterLevel - heightmap[x, y]) * underWaterMultiplier );
             *      } else {
             *          slope = slopemap[x, y] * args.maxHeight;
             *          level = args.waterLevel + (int)Math.Round( (heightmap[x, y] - desiredWaterLevel) * aboveWaterMultiplier );
             *      }
             *      Block block;
             *      if( slope < .12 ) {
             *          block = Block.Green;
             *      } else if( slope < .24 ) {
             *          block = Block.Lime;
             *      } else if( slope < .36 ) {
             *          block = Block.Yellow;
             *      } else if( slope < .48 ) {
             *          block = Block.Orange;
             *      } else if( slope < .6 ) {
             *          block = Block.Red;
             *      } else {
             *          block = Block.Black;
             *      }
             *      for( int i = level; i >= 0; i-- ) {
             *          map.SetBlock( x, y, i, block );
             *      }
             *  }
             * }*/


            float[,] altmap = null;
            if (args.MaxHeightVariation != 0 || args.MaxDepthVariation != 0)
            {
                ReportProgress(5, "Heightmap Processing: Randomizing");
                altmap = new float[map.WidthX, map.WidthY];
                int blendmapDetailSize = (int)Math.Log(Math.Max(args.WidthX, args.WidthY), 2) - 2;
                new Noise(rand.Next(), NoiseInterpolationMode.Cosine).PerlinNoise2D(altmap, 3, blendmapDetailSize, 0.5f, 0, 0);
                Noise.Normalize(altmap, -1, 1);
            }

            int snowStartThreshold = args.SnowAltitude - args.SnowTransition;
            int snowThreshold      = args.SnowAltitude;

            ReportProgress(10, "Filling");
            for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
            {
                for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                {
                    if (heightmap[x, y] < desiredWaterLevel)
                    {
                        float depth = args.MaxDepth;
                        if (altmap != null)
                        {
                            depth += altmap[x, y] * args.MaxDepthVariation;
                        }
                        slope = slopemap[x, y] * depth;
                        level = args.WaterLevel - (int)Math.Round(Math.Pow(1 - heightmap[x, y] / desiredWaterLevel, args.BelowFuncExponent) * depth);

                        if (args.AddWater)
                        {
                            if (args.WaterLevel - level > 3)
                            {
                                map.SetBlock(x, y, args.WaterLevel, bDeepWaterSurface);
                            }
                            else
                            {
                                map.SetBlock(x, y, args.WaterLevel, bWaterSurface);
                            }
                            for (int i = args.WaterLevel; i > level; i--)
                            {
                                map.SetBlock(x, y, i, bWater);
                            }
                            for (int i = level; i >= 0; i--)
                            {
                                if (level - i < SeaFloorThickness)
                                {
                                    map.SetBlock(x, y, i, bSeaFloor);
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, bBedrock);
                                }
                            }
                        }
                        else
                        {
                            if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                            {
                                map.SetBlock(x, y, level, bCliff);
                            }
                            else
                            {
                                if (slope < args.CliffThreshold)
                                {
                                    map.SetBlock(x, y, level, bGroundSurface);
                                }
                                else
                                {
                                    map.SetBlock(x, y, level, bCliff);
                                }
                            }

                            for (int i = level - 1; i >= 0; i--)
                            {
                                if (level - i < groundThickness)
                                {
                                    if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                    {
                                        map.SetBlock(x, y, i, bCliff);
                                    }
                                    else
                                    {
                                        if (slope < args.CliffThreshold)
                                        {
                                            map.SetBlock(x, y, i, bGround);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, bCliff);
                                        }
                                    }
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, bBedrock);
                                }
                            }
                        }
                    }
                    else
                    {
                        float height = (args.MaxHeightVariation != 0 ? (args.MaxHeight + altmap[x, y] * args.MaxHeightVariation) : args.MaxHeight);
                        slope = slopemap[x, y] * height;
                        if (height != 0)
                        {
                            level = args.WaterLevel + (int)Math.Round(Math.Pow(heightmap[x, y] - desiredWaterLevel, args.AboveFuncExponent) * aboveWaterMultiplier / args.MaxHeight * height);
                        }
                        else
                        {
                            level = args.WaterLevel;
                        }

                        bool snow = args.AddSnow &&
                                    (level > snowThreshold ||
                                     (level > snowStartThreshold && rand.NextDouble() < (level - snowStartThreshold) / (double)(snowThreshold - snowStartThreshold)));

                        if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                        {
                            map.SetBlock(x, y, level, bCliff);
                        }
                        else
                        {
                            if (slope < args.CliffThreshold)
                            {
                                map.SetBlock(x, y, level, (snow ? Block.White : bGroundSurface));
                            }
                            else
                            {
                                map.SetBlock(x, y, level, bCliff);
                            }
                        }

                        for (int i = level - 1; i >= 0; i--)
                        {
                            if (level - i < groundThickness)
                            {
                                if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                {
                                    map.SetBlock(x, y, i, bCliff);
                                }
                                else
                                {
                                    if (slope < args.CliffThreshold)
                                    {
                                        if (snow)
                                        {
                                            map.SetBlock(x, y, i, Block.White);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, bGround);
                                        }
                                    }
                                    else
                                    {
                                        map.SetBlock(x, y, i, bCliff);
                                    }
                                }
                            }
                            else
                            {
                                map.SetBlock(x, y, i, bBedrock);
                            }
                        }
                    }
                }
            }

            if (args.AddCaves || args.AddOre)
            {
                AddCaves(map);
            }

            if (args.AddBeaches)
            {
                ReportProgress(5, "Processing: Adding beaches");
                AddBeaches(map);
            }

            if (args.AddTrees)
            {
                ReportProgress(5, "Processing: Planting trees");
                Map outMap = new Map(null, map.WidthX, map.WidthY, map.Height, false)
                {
                    Blocks = (byte[])map.Blocks.Clone()
                };

                Forester treeGen = new Forester(new ForesterArgs {
                    InMap              = map,
                    OutMap             = outMap,
                    Rand               = rand,
                    TreeCount          = (int)(map.WidthX * map.WidthY * 4 / (1024f * (args.TreeSpacingMax + args.TreeSpacingMin) / 2)),
                    Operation          = Forester.ForesterOperation.Add,
                    GroundSurfaceBlock = bGroundSurface
                });
                treeGen.Generate();
                map = outMap;

                GenerateTrees(map);
            }

            ReportProgress(0, "Generation complete");
            map.ResetSpawn();

            map.SetMeta("_Origin", "GeneratorName", "fCraft");
            map.SetMeta("_Origin", "GeneratorVersion", Updater.CurrentRelease.VersionString);
            map.SetMeta("_Origin", "GeneratorParams", args.Serialize().ToString(SaveOptions.DisableFormatting));
            return(map);
        }
Пример #21
0
        void DoGenerate(Map map, Player player, string mode, string filename, Random rand, bool hollow)
        {
            switch (mode)
            {
            case "flatgrass":
                player.Message("Generating flatgrass map...");
                GenerateFlatgrass(map, hollow);

                if (map.Save(filename))
                {
                    player.Message("Map generation: Done.");
                }
                else
                {
                    player.Message(Color.Red, "An error occured while generating the map.");
                }
                break;

            case "lag":
                player.Message("Generating laggy map...");
                for (int x = 0; x < map.widthX; x += 2)
                {
                    for (int y = 0; y < map.widthY; y += 2)
                    {
                        for (int h = 0; h < map.widthY; h += 2)
                        {
                            map.SetBlock(x, y, h, Block.Lava);
                        }
                    }
                }

                if (map.Save(filename))
                {
                    player.Message("Map generation: Done.");
                }
                else
                {
                    player.Message(Color.Red, "An error occured while generating the map.");
                }
                break;

            case "empty":
                player.Message("Generating empty map...");
                map.MakeFloodBarrier();

                if (map.Save(filename))
                {
                    player.Message("Map generation: Done.");
                }
                else
                {
                    player.Message(Color.Red, "An error occured while generating the map.");
                }

                break;

            case "hills":
                player.Message("Generating terrain...");
                world.tasks.Add(MapGenerator.GenerationTask, new MapGenerator(rand, map, player, filename,
                                                                              1, 1, 0.5, 0.45, 0, 0.5, hollow), false);
                break;

            case "mountains":
                player.Message("Generating terrain...");
                world.tasks.Add(MapGenerator.GenerationTask, new MapGenerator(rand, map, player, filename,
                                                                              4, 1, 0.5, 0.45, 0.1, 0.5, hollow), false);
                break;

            case "lake":
                player.Message("Generating terrain...");
                world.tasks.Add(MapGenerator.GenerationTask, new MapGenerator(rand, map, player, filename,
                                                                              1, 0.6, 0.9, 0.45, -0.35, 0.55, hollow), false);
                break;

            case "island":
                player.Message("Generating terrain...");
                world.tasks.Add(MapGenerator.GenerationTask, new MapGenerator(rand, map, player, filename,
                                                                              1, 0.6, 1, 0.45, 0.3, 0.35, hollow), false);
                break;

            default:
                player.Message("Unknown map generation mode: " + mode);
                break;
            }
        }
Пример #22
0
        public override Map Generate()
        {
            if (Finished)
            {
                return(Result);
            }
            try {
                ReportProgress(0, "Clumping spheres...");
                rand = new Random(genParams.Seed);
                map  = new Map(null, genParams.MapWidth, genParams.MapLength, genParams.MapHeight, true);

                int    numIslands      = Math.Max(1, (int)(map.Volume * genParams.IslandDensity / (96 * 96 * 64)));
                Random islandCoordRand = new Random(rand.Next());

                List <Island> islands = new List <Island>();

                for (int i = 0; i < numIslands; i++)
                {
                    Vector3I offset = new Vector3I(islandCoordRand.Next(16, genParams.MapWidth - 16),
                                                   islandCoordRand.Next(16, genParams.MapLength - 16),
                                                   islandCoordRand.Next(16, genParams.MapHeight - 16));
                    islands.Add(CreateIsland(offset));
                }
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(10, "Smoothing (0%)...");
                SmoothEdges();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(15, "Smoothing (50%)...");
                SmoothEdges();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(20, "Expanding...");
                ExpandGround();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(70, "Adding stone...");
                for (int i = 0; i < numIslands; i++)
                {
                    MakeIslandBase(islands[i]);
                }

                ReportProgress(75, "Planting grass...");
                PlantGrass();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(80, "Watering...");
                for (int x = 0; x < map.Width; x++)
                {
                    for (int y = 0; y < map.Length; y++)
                    {
                        map.SetBlock(x, y, 0, Block.Admincrete);
                        map.SetBlock(x, y, 1, Block.Water);
                    }
                }
                MakeWater();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(85, "Planting trees...");
                PlantGiantTrees();
                PlantTrees();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(88, "Planting flowers...");
                PlantFlowers();
                if (Canceled)
                {
                    return(null);
                }

                ReportProgress(90, "Eroding (0%)...");
                Erode();
                if (Canceled)
                {
                    return(null);
                }
                ReportProgress(95, "Eroding (50%)...");
                Erode();
                if (Canceled)
                {
                    return(null);
                }

                Result = map;
                return(Result);
            } finally {
                Finished     = true;
                Progress     = 100;
                StatusString = (Canceled ? "Canceled" : "Finished");
            }
        }
Пример #23
0
        public Map GenerateMap()
        {
            Map map = new Map(null, args.MapWidth, args.MapLength, args.MapHeight, true);

            // Match water coverage
            float desiredWaterLevel = .5f;

            if (args.MatchWaterCoverage)
            {
                ReportProgress(2, "Heightmap Processing: Matching water coverage");
                desiredWaterLevel = Noise.FindThreshold(heightmap, args.WaterCoverage);
            }

            // Calculate above/below water multipliers
            float aboveWaterMultiplier = 0;

            if (desiredWaterLevel != 1)
            {
                aboveWaterMultiplier = (args.MaxHeight / (1 - desiredWaterLevel));
            }

            // Apply power functions to above/below water parts of the heightmap
            if (args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1)
            {
                ReportProgress(5, "Heightmap Processing: Adjusting slope");
                for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
                {
                    for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                    {
                        if (heightmap[x, y] < desiredWaterLevel)
                        {
                            float normalizedDepth = 1 - heightmap[x, y] / desiredWaterLevel;
                            heightmap[x, y] = desiredWaterLevel - ( float )Math.Pow(normalizedDepth, args.BelowFuncExponent) * desiredWaterLevel;
                        }
                        else
                        {
                            float normalizedHeight = (heightmap[x, y] - desiredWaterLevel) / (1 - desiredWaterLevel);
                            heightmap[x, y] = desiredWaterLevel + ( float )Math.Pow(normalizedHeight, args.AboveFuncExponent) * (1 - desiredWaterLevel);
                        }
                    }
                }
            }

            // Calculate the slope
            if (args.CliffSmoothing)
            {
                ReportProgress(2, "Heightmap Processing: Smoothing");
                slopemap = Noise.CalculateSlope(Noise.GaussianBlur5X5(heightmap));
            }
            else
            {
                slopemap = Noise.CalculateSlope(heightmap);
            }

            float[,] altmap = null;
            if (args.MaxHeightVariation != 0 || args.MaxDepthVariation != 0)
            {
                ReportProgress(5, "Heightmap Processing: Randomizing");
                altmap = new float[map.Width, map.Length];
                int blendmapDetailSize = ( int )Math.Log(Math.Max(args.MapWidth, args.MapLength), 2) - 2;
                new Noise(rand.Next(), NoiseInterpolationMode.Cosine).PerlinNoise(altmap, 3, blendmapDetailSize, 0.5f, 0, 0);
                Noise.Normalize(altmap, -1, 1);
            }

            int snowStartThreshold = args.SnowAltitude - args.SnowTransition;
            int snowThreshold      = args.SnowAltitude;

            ReportProgress(10, "Filling");
            for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
            {
                for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                {
                    int   level;
                    float slope;
                    if (heightmap[x, y] < desiredWaterLevel)
                    {
                        float depth = args.MaxDepth;
                        if (altmap != null)
                        {
                            depth += altmap[x, y] * args.MaxDepthVariation;
                        }
                        slope = slopemap[x, y] * depth;
                        level = args.WaterLevel - ( int )Math.Round(Math.Pow(1 - heightmap[x, y] / desiredWaterLevel, args.BelowFuncExponent) * depth);

                        if (args.AddWater)
                        {
                            if (args.WaterLevel - level > 3)
                            {
                                map.SetBlock(x, y, args.WaterLevel, bDeepWaterSurface);
                            }
                            else
                            {
                                map.SetBlock(x, y, args.WaterLevel, bWaterSurface);
                            }
                            for (int i = args.WaterLevel; i > level; i--)
                            {
                                map.SetBlock(x, y, i, bWater);
                            }
                            for (int i = level; i >= 0; i--)
                            {
                                if (level - i < SeaFloorThickness)
                                {
                                    map.SetBlock(x, y, i, bSeaFloor);
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, bBedrock);
                                }
                            }
                        }
                        else
                        {
                            if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                            {
                                map.SetBlock(x, y, level, bCliff);
                            }
                            else
                            {
                                if (slope < args.CliffThreshold)
                                {
                                    map.SetBlock(x, y, level, bGroundSurface);
                                }
                                else
                                {
                                    map.SetBlock(x, y, level, bCliff);
                                }
                            }

                            for (int i = level - 1; i >= 0; i--)
                            {
                                if (level - i < groundThickness)
                                {
                                    if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                    {
                                        map.SetBlock(x, y, i, bCliff);
                                    }
                                    else
                                    {
                                        if (slope < args.CliffThreshold)
                                        {
                                            map.SetBlock(x, y, i, bGround);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, bCliff);
                                        }
                                    }
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, bBedrock);
                                }
                            }
                        }
                    }
                    else
                    {
                        float height;
                        if (altmap != null)
                        {
                            height = args.MaxHeight + altmap[x, y] * args.MaxHeightVariation;
                        }
                        else
                        {
                            height = args.MaxHeight;
                        }
                        slope = slopemap[x, y] * height;
                        if (height != 0)
                        {
                            level = args.WaterLevel + ( int )Math.Round(Math.Pow(heightmap[x, y] - desiredWaterLevel, args.AboveFuncExponent) * aboveWaterMultiplier / args.MaxHeight * height);
                        }
                        else
                        {
                            level = args.WaterLevel;
                        }

                        bool snow = args.AddSnow &&
                                    (level > snowThreshold ||
                                     (level > snowStartThreshold && rand.NextDouble() < (level - snowStartThreshold) / ( double )(snowThreshold - snowStartThreshold)));

                        if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                        {
                            map.SetBlock(x, y, level, bCliff);
                        }
                        else
                        {
                            if (slope < args.CliffThreshold)
                            {
                                map.SetBlock(x, y, level, (snow ? Block.White : bGroundSurface));
                            }
                            else
                            {
                                map.SetBlock(x, y, level, bCliff);
                            }
                        }

                        for (int i = level - 1; i >= 0; i--)
                        {
                            if (level - i < groundThickness)
                            {
                                if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                {
                                    map.SetBlock(x, y, i, bCliff);
                                }
                                else
                                {
                                    if (slope < args.CliffThreshold)
                                    {
                                        if (snow)
                                        {
                                            map.SetBlock(x, y, i, Block.White);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, bGround);
                                        }
                                    }
                                    else
                                    {
                                        map.SetBlock(x, y, i, bCliff);
                                    }
                                }
                            }
                            else
                            {
                                map.SetBlock(x, y, i, bBedrock);
                            }
                        }
                    }
                }
            }

            if (args.AddCaves || args.AddOre)
            {
                AddCaves(map);
            }

            if (args.AddBeaches)
            {
                ReportProgress(5, "Processing: Adding beaches");
                AddBeaches(map);
            }

            if (args.AddIgloos)
            {
                //GenerateIgloos( map );
            }

            if (args.AddTrees)
            {
                ReportProgress(5, "Processing: Planting trees");
                if (args.AddGiantTrees)
                {
                    Map outMap = new Map(null, map.Width, map.Length, map.Height, false)
                    {
                        Blocks = ( byte[] )map.Blocks.Clone()
                    };
                    var foresterArgs = new ForesterArgs {
                        Map       = map,
                        Rand      = rand,
                        TreeCount = ( int )(map.Width * map.Length * 4 / (1024f * (args.TreeSpacingMax + args.TreeSpacingMin) / 2)),
                        Operation = Forester.ForesterOperation.Add,
                        PlantOn   = bGroundSurface
                    };
                    foresterArgs.BlockPlacing += (sender, e) => outMap.SetBlock(e.Coordinate, e.Block);
                    Forester.Generate(foresterArgs);
                    map = outMap;
                }
                GenerateTrees(map);
            }

            ReportProgress(0, "Generation complete");

            map.Metadata["_Origin", "GeneratorName"]    = "fCraft";
            map.Metadata["_Origin", "GeneratorVersion"] = Updater.CurrentRelease.VersionString;
            map.Metadata["_Origin", "GeneratorParams"]  = args.Serialize().ToString(SaveOptions.DisableFormatting);
            return(map);
        }
Пример #24
0
        /// <summary> Makes an admincrete barrier, 1 block thick, around the lower half of the map. </summary>
        public static void MakeFloodBarrier( Map map ) {
            for( int x = 0; x < map.Width; x++ ) {
                for( int y = 0; y < map.Length; y++ ) {
                    map.SetBlock( x, y, 0, Block.Admincrete );
                }
            }

            for( int x = 0; x < map.Width; x++ ) {
                for( int z = 0; z < map.Height / 2; z++ ) {
                    map.SetBlock( x, 0, z, Block.Admincrete );
                    map.SetBlock( x, map.Length - 1, z, Block.Admincrete );
                }
            }

            for( int y = 0; y < map.Length; y++ ) {
                for( int z = 0; z < map.Height / 2; z++ ) {
                    map.SetBlock( 0, y, z, Block.Admincrete );
                    map.SetBlock( map.Width - 1, y, z, Block.Admincrete );
                }
            }
        }
Пример #25
0
        private void GenerateTrees([NotNull] Map map)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            int          minHeight       = args.TreeHeightMin;
            int          maxHeight       = args.TreeHeightMax;
            int          minTrunkPadding = args.TreeSpacingMin;
            int          maxTrunkPadding = args.TreeSpacingMax;
            const int    topLayers       = 2;
            const double odds            = 0.618;

            Random rn = new Random();

            map.CalculateShadows();

            for (int x = 0; x < map.Width; x += rn.Next(minTrunkPadding, maxTrunkPadding + 1))
            {
                for (int y = 0; y < map.Length; y += rn.Next(minTrunkPadding, maxTrunkPadding + 1))
                {
                    int nx = x + rn.Next(-(minTrunkPadding / 2), (maxTrunkPadding / 2) + 1);
                    int ny = y + rn.Next(-(minTrunkPadding / 2), (maxTrunkPadding / 2) + 1);
                    if (nx < 0 || nx >= map.Width || ny < 0 || ny >= map.Length)
                    {
                        continue;
                    }
                    int nz = map.Shadows[nx, ny];

                    if ((map.GetBlock(nx, ny, nz) == bGroundSurface) && slopemap[nx, ny] < .5)
                    {
                        // Pick a random height for the tree between Min and Max,
                        // discarding this tree if it would breach the top of the map
                        int nh;
                        if ((nh = rn.Next(minHeight, maxHeight + 1)) + nz + nh / 2 > map.Height)
                        {
                            continue;
                        }

                        // Generate the trunk of the tree
                        for (int z = 1; z <= nh; z++)
                        {
                            map.SetBlock(nx, ny, nz + z, Block.Log);
                        }

                        for (int i = -1; i < nh / 2; i++)
                        {
                            // Should we draw thin (2x2) or thicker (4x4) foliage
                            int radius = (i >= (nh / 2) - topLayers) ? 1 : 2;
                            // Draw the foliage
                            for (int xoff = -radius; xoff < radius + 1; xoff++)
                            {
                                for (int yoff = -radius; yoff < radius + 1; yoff++)
                                {
                                    // Drop random leaves from the edges
                                    if (rn.NextDouble() > odds && Math.Abs(xoff) == Math.Abs(yoff) && Math.Abs(xoff) == radius)
                                    {
                                        continue;
                                    }
                                    // By default only replace an existing block if its air
                                    if (map.GetBlock(nx + xoff, ny + yoff, nz + nh + i) == Block.Air)
                                    {
                                        map.SetBlock(nx + xoff, ny + yoff, nz + nh + i, Block.Leaves);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #26
0
        public void setIgloo( Map Map, int xIn, int yIn, int zIn)
        {
            int width = rand.Next( 15, 30 );
            int height = rand.Next( 15, 30 );
            for ( int x = -width; x <= width; x++ )
                for ( int y = height; y >= -height; y-- )
                    for ( int z = -width; z <= width; z++ ) {
                        if ( y == height || ( Math.Abs( x ) == width && Math.Abs( z ) == width && y >= 0 ) ) {
                           Map.SetBlock( x + xIn, y + yIn, z + zIn, Block.Stone);
                           Map.SetBlock( x + xIn, y + yIn + 1, z + zIn, Block.Admincrete );
                        }

                        if ( y >= 1 && ( ( Math.Abs( x ) == width ) ^ ( Math.Abs( z ) == width ) ) )
                            Map.SetBlock( x + xIn, y + yIn, z + zIn, Block.Gravel );

                        if ( y > 0 && y < height && Math.Abs( z ) < width && Math.Abs( x ) < width )
                            Map.SetBlock( x + xIn, y + yIn, z + zIn, Block.Air ); //unsure

                        if ( y == -1 || y == 0 )
                           Map.SetBlock( x + xIn, y + yIn, z + zIn, Block.Gray );

                        if ( y < -1 ) {
                            if ( ( Math.Abs( x ) == width || Math.Abs( z ) == width ))
                                Map.SetBlock( x + xIn, y + yIn, z + zIn, Block.Brick );
                        }
                    }
        }
Пример #27
0
 protected void UpdateMap(BlockUpdate upd)
 {
     _map.SetBlock(upd.X, upd.Y, upd.Z, upd.BlockType);
     _map.QueueUpdate(upd);
 }
Пример #28
0
        Map GenerateMap()
        {
            Map map = new Map(null, genParams.MapWidth, genParams.MapLength, genParams.MapHeight, true);

            theme = genParams.Theme;

            // scale features vertically based on map height
            double verticalScale = (genParams.MapHeight / 96.0) / 2 + 0.5;

            maxHeightScaled    = (int)Math.Round(genParams.MaxHeight * verticalScale);
            maxDepthScaled     = (int)Math.Round(genParams.MaxDepth * verticalScale);
            snowAltitudeScaled = (int)Math.Round(genParams.SnowAltitude * verticalScale);

            // Match water coverage
            float desiredWaterLevel = .5f;

            if (genParams.MatchWaterCoverage)
            {
                ReportRelativeProgress(2, "Heightmap Processing: Matching water coverage");
                // find a number between 0 and 1 ("desiredWaterLevel") for the heightmap such that
                // the fraction of heightmap coordinates ("blocks") that are below this threshold ("underwater")
                // match the specified WaterCoverage
                desiredWaterLevel = Noise.FindThreshold(heightmap, genParams.WaterCoverage);
            }


            // Calculate above/below water multipliers
            float aboveWaterMultiplier = 0;

            if (desiredWaterLevel < 1)
            {
                aboveWaterMultiplier = (maxHeightScaled / (1 - desiredWaterLevel));
            }


            // Apply power functions to above/below water parts of the heightmap
            if (Math.Abs(genParams.BelowFuncExponent - 1) > float.Epsilon ||
                Math.Abs(genParams.AboveFuncExponent - 1) > float.Epsilon)
            {
                ReportRelativeProgress(5, "Heightmap Processing: Adjusting slope");
                for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
                {
                    for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                    {
                        if (heightmap[x, y] < desiredWaterLevel)
                        {
                            float normalizedDepth = 1 - heightmap[x, y] / desiredWaterLevel;
                            heightmap[x, y] = desiredWaterLevel -
                                              (float)Math.Pow(normalizedDepth, genParams.BelowFuncExponent) *
                                              desiredWaterLevel;
                        }
                        else
                        {
                            float normalizedHeight = (heightmap[x, y] - desiredWaterLevel) / (1 - desiredWaterLevel);
                            heightmap[x, y] = desiredWaterLevel +
                                              (float)Math.Pow(normalizedHeight, genParams.AboveFuncExponent) *
                                              (1 - desiredWaterLevel);
                        }
                    }
                }
            }

            // Calculate the slope
            if (genParams.CliffSmoothing)
            {
                ReportRelativeProgress(2, "Heightmap Processing: Smoothing");
                slopemap = Noise.CalculateSlope(Noise.GaussianBlur5X5(heightmap));
            }
            else
            {
                slopemap = Noise.CalculateSlope(heightmap);
            }

            // Randomize max height/depth
            float[,] altmap = null;
            if (genParams.MaxHeightVariation != 0 || genParams.MaxDepthVariation != 0)
            {
                ReportRelativeProgress(5, "Heightmap Processing: Randomizing");
                altmap = new float[map.Width, map.Length];
                int blendmapDetailSize = (int)Math.Log(Math.Max(genParams.MapWidth, genParams.MapLength), 2) - 2;
                new Noise(rand.Next(), NoiseInterpolationMode.Cosine)
                .PerlinNoise(altmap, Math.Min(blendmapDetailSize, 3), blendmapDetailSize,
                             0.5f, 0, 0);
                Noise.Normalize(altmap, -1, 1);
            }

            int snowStartThreshold = snowAltitudeScaled - genParams.SnowTransition;
            int snowThreshold      = snowAltitudeScaled;

            ReportRelativeProgress(10, "Filling");
            if (theme.AirBlock != Block.Air)
            {
                map.Blocks.MemSet((byte)theme.AirBlock);
            }
            for (int x = heightmap.GetLength(0) - 1; x >= 0; x--)
            {
                for (int y = heightmap.GetLength(1) - 1; y >= 0; y--)
                {
                    int   level;
                    float slope;
                    if (heightmap[x, y] < desiredWaterLevel)
                    {
                        // for blocks below "sea level"
                        float depth = maxDepthScaled;
                        if (altmap != null)
                        {
                            depth += altmap[x, y] * genParams.MaxDepthVariation;
                        }
                        slope = slopemap[x, y] * depth;
                        level = genParams.WaterLevel - (int)Math.Round(Math.Pow(1 - heightmap[x, y] / desiredWaterLevel, genParams.BelowFuncExponent) * depth);

                        if (genParams.AddWater)
                        {
                            if (genParams.WaterLevel - level > 3)
                            {
                                map.SetBlock(x, y, genParams.WaterLevel, theme.DeepWaterSurfaceBlock);
                            }
                            else
                            {
                                map.SetBlock(x, y, genParams.WaterLevel, theme.WaterSurfaceBlock);
                            }
                            for (int i = genParams.WaterLevel; i > level; i--)
                            {
                                map.SetBlock(x, y, i, theme.WaterBlock);
                            }
                            for (int i = level; i >= 0; i--)
                            {
                                if (level - i < theme.SeaFloorThickness)
                                {
                                    map.SetBlock(x, y, i, theme.SeaFloorBlock);
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, theme.BedrockBlock);
                                }
                            }
                        }
                        else
                        {
                            if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                            {
                                map.SetBlock(x, y, level, theme.CliffBlock);
                            }
                            else
                            {
                                if (slope < genParams.CliffThreshold)
                                {
                                    map.SetBlock(x, y, level, theme.GroundSurfaceBlock);
                                }
                                else
                                {
                                    map.SetBlock(x, y, level, theme.CliffBlock);
                                }
                            }

                            for (int i = level - 1; i >= 0; i--)
                            {
                                if (level - i < theme.GroundThickness)
                                {
                                    if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                    {
                                        map.SetBlock(x, y, i, theme.CliffBlock);
                                    }
                                    else
                                    {
                                        if (slope < genParams.CliffThreshold)
                                        {
                                            map.SetBlock(x, y, i, theme.GroundBlock);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, theme.CliffBlock);
                                        }
                                    }
                                }
                                else
                                {
                                    map.SetBlock(x, y, i, theme.BedrockBlock);
                                }
                            }
                        }
                    }
                    else
                    {
                        // for blocks above "sea level"
                        float height;
                        if (altmap != null)
                        {
                            height = maxHeightScaled + altmap[x, y] * genParams.MaxHeightVariation;
                        }
                        else
                        {
                            height = maxHeightScaled;
                        }
                        slope = slopemap[x, y] * height;
                        if (height != 0)
                        {
                            level = genParams.WaterLevel +
                                    (int)Math.Round(Math.Pow(heightmap[x, y] - desiredWaterLevel, genParams.AboveFuncExponent) *
                                                    aboveWaterMultiplier / maxHeightScaled * height);
                        }
                        else
                        {
                            level = genParams.WaterLevel;
                        }

                        bool snow = genParams.AddSnow &&
                                    (level > snowThreshold ||
                                     (level > snowStartThreshold && rand.NextDouble() < (level - snowStartThreshold) / (double)(snowThreshold - snowStartThreshold)));

                        if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75)
                        {
                            map.SetBlock(x, y, level, theme.CliffBlock);
                        }
                        else
                        {
                            if (slope < genParams.CliffThreshold)
                            {
                                map.SetBlock(x, y, level, (snow ? theme.SnowBlock : theme.GroundSurfaceBlock));
                            }
                            else
                            {
                                map.SetBlock(x, y, level, theme.CliffBlock);
                            }
                        }

                        for (int i = level - 1; i >= 0; i--)
                        {
                            if (level - i < theme.GroundThickness)
                            {
                                if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold))
                                {
                                    map.SetBlock(x, y, i, theme.CliffBlock);
                                }
                                else
                                {
                                    if (slope < genParams.CliffThreshold)
                                    {
                                        if (snow)
                                        {
                                            map.SetBlock(x, y, i, theme.SnowBlock);
                                        }
                                        else
                                        {
                                            map.SetBlock(x, y, i, theme.GroundBlock);
                                        }
                                    }
                                    else
                                    {
                                        map.SetBlock(x, y, i, theme.CliffBlock);
                                    }
                                }
                            }
                            else
                            {
                                map.SetBlock(x, y, i, theme.BedrockBlock);
                            }
                        }
                    }
                }
            }

            if (genParams.AddCaves || genParams.AddOre)
            {
                AddCaves(map);
            }

            if (genParams.AddBeaches)
            {
                ReportRelativeProgress(5, "Processing: Adding beaches");
                AddBeaches(map);
            }

            if (genParams.AddTrees)
            {
                ReportRelativeProgress(5, "Processing: Planting trees");
                if (genParams.AddGiantTrees)
                {
                    Map outMap = new Map(null, map.Width, map.Length, map.Height, false)
                    {
                        Blocks = (byte[])map.Blocks.Clone()
                    };
                    var foresterArgs = new ForesterArgs {
                        Map       = map,
                        Rand      = rand,
                        TreeCount = (int)(map.Width * map.Length * 4 / (1024f * (genParams.TreeSpacingMax + genParams.TreeSpacingMin) / 2)),
                        Operation = Forester.ForesterOperation.Add,
                        PlantOn   = theme.GroundSurfaceBlock
                    };
                    foresterArgs.BlockPlacing += (sender, e) => outMap.SetBlock(e.Coordinate, e.Block);
                    Forester.Generate(foresterArgs);
                    map = outMap;
                }
                GenerateTrees(map);
            }

            if (genParams.AddFloodBarrier)
            {
                MakeFloodBarrier(map);
            }
            return(map);
        }