Ejemplo n.º 1
0
        internal static void Generate(Chunk chunk, List <Position> takenPositions)
        {
            int clutterCount = Settings.Random.Next(MIN_CLUTTER_PER_CHUNK, MAX_CLUTTER_PER_CHUNK + 1);

            for (int i = 0; i < clutterCount; i++)
            {
                //returns number avoiding upper chunk boundaries ensuring cross chunk placements dont touch each other
                int xProposedInChunk = Settings.Random.Next(0, Chunk.CHUNK_SIZE - 1);
                int zProposedInChunk = Settings.Random.Next(0, Chunk.CHUNK_SIZE - 1);
                int yProposed        = chunk.HeightMap[xProposedInChunk, zProposedInChunk];

                var block = chunk.Blocks[xProposedInChunk, yProposed, zProposedInChunk];
                if (block.Type != Block.BlockType.Grass && block.Type != Block.BlockType.Snow)
                {
                    continue;
                }
                int xProposedInWorld = chunk.Coords.WorldCoordsX + xProposedInChunk;
                int zProposedInWorld = chunk.Coords.WorldCoordsZ + zProposedInChunk;

                //ensure clutter is not placed too close to another taken coord, otherwise skip it
                if (TreeGenerator.IsPositionTaken(takenPositions, xProposedInWorld, zProposedInWorld, DISTANCE_TOLERANCE))
                {
                    continue;
                }

                //place the clutter
                var clutterType = (ClutterType)Settings.Random.Next(0, 7);                                                   //0-6
                takenPositions.Add(new Position(xProposedInWorld, yProposed, zProposedInWorld));
                chunk.Clutters.Add(new Clutter(new Coords(xProposedInWorld, yProposed + 1, zProposedInWorld), clutterType)); //add new clutter to the chunk collection
            }
        }
Ejemplo n.º 2
0
        public static void Generate()
        {
            Debug.WriteLine("Generating new world: " + Settings.WorldFilePath);
            Debug.WriteLine("World type: {0}, Size {1}x{2}", WorldData.WorldType, WorldData.SizeInChunksX, WorldData.SizeInChunksZ);

            Settings.Random = string.IsNullOrEmpty(WorldData.RawSeed) ? new Random() : new Random(GetNumericSeed());

            WorldData.Chunks = new Chunks(WorldData.SizeInChunksX, WorldData.SizeInChunksZ);

            const int MIN_SURFACE_HEIGHT = Chunk.CHUNK_HEIGHT / 2 - 40;            //max amount below half
            const int MAX_SURFACE_HEIGHT = Chunk.CHUNK_HEIGHT / 2 + 8;             //max amount above half
            var       heightMap          = PerlinNoise.GetIntMap(MIN_SURFACE_HEIGHT, MAX_SURFACE_HEIGHT, 8);
            var       mineralMap         = PerlinNoise.GetFloatMap(1, MAX_SURFACE_HEIGHT - 5, 2);

            var chunkCount = 1;

            foreach (Chunk chunk in WorldData.Chunks)
            {
                Settings.Launcher.UpdateProgressInvokable(string.Format("Generating Chunks {0} / {1}", chunkCount, WorldData.SizeInChunksX * WorldData.SizeInChunksZ), chunkCount, WorldData.SizeInChunksX * WorldData.SizeInChunksZ);

                //bm: we can't run this in parallel or the results will not be deterministic based on our seed.
                GenerateChunk(WorldData.Chunks[chunk.Coords.X, chunk.Coords.Z], heightMap, mineralMap);

                chunkCount++;
            }

            //loop through chunks again for actions that require the neighboring chunks to be built
            Debug.WriteLine("Completing growth in chunks and building heightmaps...");
            Settings.Launcher.UpdateProgressInvokable("Completing growth in chunks...", 0, 0);
            foreach (Chunk chunk in WorldData.Chunks)
            {
                //build heightmap here only so we know where to place trees/clutter (it will get built again on world load anyway)
                chunk.BuildHeightMap();

                var takenPositions = new List <Position>();                //positions taken by tree or clutter, ensures neither spawn on top of or directly touching another

                //generate trees
                if (WorldData.GenerateWithTrees)
                {
                    TreeGenerator.Generate(chunk, takenPositions);
                }

                //generate clutter
                ClutterGenerator.Generate(chunk, takenPositions);
            }

            Settings.Random = new Random();             //reset the random object to ensure the seed is not used for any more random numbers as this could make gameplay predictable
            Debug.WriteLine("World generation complete.");

            //default sun to directly overhead in new worlds
            SkyHost.SunAngleRadians  = OpenTK.MathHelper.PiOver2;
            SkyHost.SunLightStrength = SkyHost.BRIGHTEST_SKYLIGHT_STRENGTH;

            Debug.WriteLine("New world saving...");
            Settings.Launcher.UpdateProgressInvokable("New world saving...", 0, 0);
            WorldData.SaveToDisk();
            Debug.WriteLine("New world save complete.");
        }