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); } } } } } } } }
void AsyncLoad( object sender, DoWorkEventArgs e ) { stopwatch = Stopwatch.StartNew(); try { map = MapUtility.Load( fileToLoad ); map.CalculateShadows(); } catch( Exception ex ) { MessageBox.Show( String.Format( "Could not load specified map: {0}: {1}", ex.GetType().Name, ex.Message ) ); } }