コード例 #1
0
        public RealisticMapGenParameters( [NotNull] XElement root )
            : this() {
            if( root == null ) throw new ArgumentNullException( "root" );

            XAttribute versionTag = root.Attribute( "version" );
            int version = 0;
            if( versionTag != null && !String.IsNullOrEmpty(versionTag.Value) ) {
                version = Int32.Parse( versionTag.Value );
            }

            XElement el = root.Element( "theme" );
            if( el != null ) {
                string themeVal = el.Value;
                MapGenTheme theme;
                if( EnumUtil.TryParse( themeVal, out theme, true ) ) {
                    // for old versions of MapGen templates, use enum
                    Theme = new RealisticMapGenBlockTheme( theme );
                } else {
                    // for newer versions, use the whole custom thing
                    Theme = new RealisticMapGenBlockTheme( el );
                }
            }

            Seed = Int32.Parse( root.Element( "seed" ).Value );
            MapWidth = Int32.Parse( root.Element( "dimX" ).Value );
            MapLength = Int32.Parse( root.Element( "dimY" ).Value );
            MapHeight = Int32.Parse( root.Element( "dimH" ).Value );
            MaxHeight = Int32.Parse( root.Element( "maxHeight" ).Value );
            MaxDepth = Int32.Parse( root.Element( "maxDepth" ).Value );

            AddWater = Boolean.Parse( root.Element( "addWater" ).Value );
            if( root.Element( "customWaterLevel" ) != null ) CustomWaterLevel = Boolean.Parse( root.Element( "customWaterLevel" ).Value );
            MatchWaterCoverage = Boolean.Parse( root.Element( "matchWaterCoverage" ).Value );
            WaterLevel = Int32.Parse( root.Element( "waterLevel" ).Value );
            WaterCoverage = float.Parse( root.Element( "waterCoverage" ).Value );

            UseBias = Boolean.Parse( root.Element( "useBias" ).Value );
            if( root.Element( "delayBias" ) != null ) DelayBias = Boolean.Parse( root.Element( "delayBias" ).Value );
            Bias = float.Parse( root.Element( "bias" ).Value );
            RaisedCorners = Int32.Parse( root.Element( "raisedCorners" ).Value );
            LoweredCorners = Int32.Parse( root.Element( "loweredCorners" ).Value );
            MidPoint = Int32.Parse( root.Element( "midPoint" ).Value );

            if( version == 0 ) {
                DetailScale = Int32.Parse( root.Element( "minDetailSize" ).Value );
                FeatureScale = Int32.Parse( root.Element( "maxDetailSize" ).Value );
            } else {
                DetailScale = Int32.Parse( root.Element( "detailScale" ).Value );
                FeatureScale = Int32.Parse( root.Element( "featureScale" ).Value );
            }
            Roughness = float.Parse( root.Element( "roughness" ).Value );
            LayeredHeightmap = Boolean.Parse( root.Element( "layeredHeightmap" ).Value );
            MarbledHeightmap = Boolean.Parse( root.Element( "marbledHeightmap" ).Value );
            InvertHeightmap = Boolean.Parse( root.Element( "invertHeightmap" ).Value );
            if( root.Element( "aboveFuncExponent" ) != null ) AboveFuncExponent = float.Parse( root.Element( "aboveFuncExponent" ).Value );
            if( root.Element( "belowFuncExponent" ) != null ) BelowFuncExponent = float.Parse( root.Element( "belowFuncExponent" ).Value );

            AddTrees = Boolean.Parse( root.Element( "addTrees" ).Value );
            TreeSpacingMin = Int32.Parse( root.Element( "treeSpacingMin" ).Value );
            TreeSpacingMax = Int32.Parse( root.Element( "treeSpacingMax" ).Value );
            TreeHeightMin = Int32.Parse( root.Element( "treeHeightMin" ).Value );
            TreeHeightMax = Int32.Parse( root.Element( "treeHeightMax" ).Value );

            if( root.Element( "addCaves" ) != null ) {
                AddCaves = Boolean.Parse( root.Element( "addCaves" ).Value );
                AddCaveLava = Boolean.Parse( root.Element( "addCaveLava" ).Value );
                AddCaveWater = Boolean.Parse( root.Element( "addCaveWater" ).Value );
                AddOre = Boolean.Parse( root.Element( "addOre" ).Value );
                CaveDensity = float.Parse( root.Element( "caveDensity" ).Value );
                CaveSize = float.Parse( root.Element( "caveSize" ).Value );
            }

            if( root.Element( "addSnow" ) != null ) AddSnow = Boolean.Parse( root.Element( "addSnow" ).Value );
            if( root.Element( "snowAltitude" ) != null ) SnowAltitude = Int32.Parse( root.Element( "snowAltitude" ).Value );
            if( root.Element( "snowTransition" ) != null ) SnowTransition = Int32.Parse( root.Element( "snowTransition" ).Value );

            if( root.Element( "addCliffs" ) != null ) AddCliffs = Boolean.Parse( root.Element( "addCliffs" ).Value );
            if( root.Element( "cliffSmoothing" ) != null ) CliffSmoothing = Boolean.Parse( root.Element( "cliffSmoothing" ).Value );
            if( root.Element( "cliffThreshold" ) != null ) CliffThreshold = float.Parse( root.Element( "cliffThreshold" ).Value );

            if( root.Element( "addBeaches" ) != null ) AddBeaches = Boolean.Parse( root.Element( "addBeaches" ).Value );
            if( root.Element( "beachExtent" ) != null ) BeachExtent = Int32.Parse( root.Element( "beachExtent" ).Value );
            if( root.Element( "beachHeight" ) != null ) BeachHeight = Int32.Parse( root.Element( "beachHeight" ).Value );

            if( root.Element( "maxHeightVariation" ) != null ) MaxHeightVariation = Int32.Parse( root.Element( "maxHeightVariation" ).Value );
            if( root.Element( "maxDepthVariation" ) != null ) MaxDepthVariation = Int32.Parse( root.Element( "maxDepthVariation" ).Value );

            if( root.Element( "addGiantTrees" ) != null ) AddGiantTrees = Boolean.Parse( root.Element( "addGiantTrees" ).Value );

            Validate();
        }
コード例 #2
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;
        }
コード例 #3
0
        public void ApplyDefaults() {
            Theme = new RealisticMapGenBlockTheme( MapGenTheme.Forest );
            Seed = (new Random()).Next();

            // default map dimensions
            MapWidth = 256;
            MapLength = 256;
            MapHeight = 96;

            // default terrain elevation / depth
            MaxHeight = 20;
            MaxDepth = 12;
            MaxHeightVariation = 4;
            MaxDepthVariation = 0;

            // water defaults: 50% water level, approx 50% coverage
            AddWater = true;
            CustomWaterLevel = false;
            MatchWaterCoverage = false;
            WaterLevel = 48;
            WaterCoverage = .5f;

            // bias defaults (no bias at all)
            UseBias = false;
            DelayBias = false;
            Bias = 0;
            RaisedCorners = 0;
            LoweredCorners = 0;
            MidPoint = 0;

            // default heightmap filtering options
            DetailScale = 7;
            FeatureScale = 1;
            Roughness = .5f;
            LayeredHeightmap = false;
            MarbledHeightmap = false;
            InvertHeightmap = false;
            AboveFuncExponent = 1;
            BelowFuncExponent = 1;

            // default tree params (small tress only)
            AddTrees = true;
            AddGiantTrees = false;
            TreeSpacingMin = 7;
            TreeSpacingMax = 11;
            TreeHeightMin = 5;
            TreeHeightMax = 7;

            // default cave/ore params (all off)
            AddCaves = false;
            AddOre = false;
            AddCaveWater = false;
            AddCaveLava = false;
            CaveDensity = 2;
            CaveSize = 1;

            // default snow params (off)
            AddSnow = false;
            SnowAltitude = 70;
            SnowTransition = 7;

            // default cliff params (on)
            AddCliffs = true;
            CliffSmoothing = true;
            CliffThreshold = 1;
            CliffsideBlockThreshold = 0.01f;

            // default beach params (off)
            AddBeaches = false;
            BeachExtent = 6;
            BeachHeight = 2;
        }