Example #1
0
void MapgenV6::placeTreesAndJungleGrass()
{
	//TimeTaker t("placeTrees");

	PseudoRandom grassrandom(blockseed + 53);

	content_t c_sand            = ndef->getId("mapgen_sand");

	content_t c_junglegrass = ndef->getId("mapgen_junglegrass");
	// if we don't have junglegrass, don't place cignore... that's bad
	if (c_junglegrass == CONTENT_IGNORE)
		c_junglegrass = CONTENT_AIR;
	MapNode n_junglegrass(c_junglegrass);
	v3s16 em = vm->m_area.getExtent();

	// Divide area into parts
	s16 div = 8;
	s16 sidelen = central_area_size.X / div;
	double area = sidelen * sidelen;

	// N.B.  We must add jungle grass first, since tree leaves will
	// obstruct the ground, giving us a false ground level
	for (s16 z0 = 0; z0 < div; z0++)
	for (s16 x0 = 0; x0 < div; x0++) {
		// Center position of part of division
		v2s16 p2d_center(
			node_min.X + sidelen / 2 + sidelen * x0,
			node_min.Z + sidelen / 2 + sidelen * z0
		);
		// Minimum edge of part of division
		v2s16 p2d_min(
			node_min.X + sidelen * x0,
			node_min.Z + sidelen * z0
		);
		// Maximum edge of part of division
		v2s16 p2d_max(
			node_min.X + sidelen + sidelen * x0 - 1,
			node_min.Z + sidelen + sidelen * z0 - 1
		);

		// Get biome at center position of part of division
		BiomeV6Type bt = getBiome(v3POS(p2d_center.X, node_min.Y, p2d_center.Y));

		// Amount of trees
		float humidity = getHumidity(v3POS(p2d_center.X, node_max.Y, p2d_center.Y));
		s32 tree_count;
		if (bt == BT_JUNGLE || bt == BT_TAIGA || bt == BT_NORMAL) {
			tree_count = area * getTreeAmount(p2d_center) * ((humidity + 1)/2.0);
			if (bt == BT_JUNGLE)
				tree_count *= 4;
		} else {
			tree_count = 0;
		}

		if (node_max.Y < water_level)
			tree_count /= 2;

		// Add jungle grass
		if (bt == BT_JUNGLE) {
			u32 grass_count = 5 * humidity * tree_count;
			for (u32 i = 0; i < grass_count; i++) {
				s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
				s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
/* wtf
				int mapindex = central_area_size.X * (z - node_min.Z)
								+ (x - node_min.X);
				s16 y = heightmap[mapindex];
*/
				s16 y = findGroundLevelFull(v2s16(x, z));
				if (y < water_level)
					continue;

				u32 vi = vm->m_area.index(x, y, z);
				// place on dirt_with_grass, since we know it is exposed to sunlight
				if (vm->m_data[vi].getContent() == c_dirt_with_grass) {
					vm->m_area.add_y(em, vi, 1);
					vm->m_data[vi] = n_junglegrass;
				}
			}
		}

		// Put trees in random places on part of division
		for (s32 i = 0; i < tree_count; i++) {
			s16 x = myrand_range(p2d_min.X, p2d_max.X);
			s16 z = myrand_range(p2d_min.Y, p2d_max.Y);
/* wtf
			int mapindex = central_area_size.X * (z - node_min.Z)
							+ (x - node_min.X);
			s16 y = heightmap[mapindex];
*/
			s16 y = findGroundLevelFull(v2s16(x, z));

			// Don't make a tree under water level
			// Don't make a tree so high that it doesn't fit
			if (y > node_max.Y - 6)
				continue;

			v3s16 p(x, y, z);
			// Trees grow only on mud and grass and snowblock
			{
				u32 i = vm->m_area.index(p);
				content_t c = vm->m_data[i].getContent();
				if (c != c_dirt &&
						c != c_dirt_with_grass &&
						c != c_dirt_with_snow &&
						c != c_snowblock &&
						(y >= water_level || c != c_sand))
					continue;
			}
			p.Y++;

			// Make a tree
			if (y < water_level) {
				if (y < water_level - 20) // do not spawn trees in lakes
					treegen::make_cavetree(*vm, p, bt == BT_JUNGLE, ndef, myrand());
			} else if (bt == BT_JUNGLE) {
				treegen::make_jungletree(*vm, p, ndef, myrand());
			} else if (bt == BT_TAIGA) {
				treegen::make_pine_tree(*vm, p - v3s16(0, 1, 0), ndef, myrand());
			} else if (bt == BT_NORMAL) {
				bool is_apple_tree = (myrand_range(0, 3) == 0) &&
							getHaveAppleTree(v2s16(x, z));
				treegen::make_tree(*vm, p, is_apple_tree, ndef, myrand());
			}
		}
	}
	//printf("placeTreesAndJungleGrass: %dms\n", t.stop());
}
Example #2
0
void MapgenV6::placeTreesAndJungleGrass() {
	//TimeTaker t("placeTrees");
	
	PseudoRandom grassrandom(blockseed + 53);

	content_t c_sand            = ndef->getId("mapgen_sand");

	content_t c_junglegrass = ndef->getId("mapgen_junglegrass");
	// if we don't have junglegrass, don't place cignore... that's bad
	if (c_junglegrass == CONTENT_IGNORE)
		c_junglegrass = CONTENT_AIR;
	MapNode n_junglegrass(c_junglegrass);
	v3s16 em = vm->m_area.getExtent();
	
	// Divide area into parts
	s16 div = 8;
	s16 sidelen = central_area_size.X / div;
	double area = sidelen * sidelen;
	
	// N.B.  We must add jungle grass first, since tree leaves will
	// obstruct the ground, giving us a false ground level
	for (s16 z0 = 0; z0 < div; z0++)
	for (s16 x0 = 0; x0 < div; x0++) {
		// Center position of part of division
		v2s16 p2d_center(
			node_min.X + sidelen / 2 + sidelen * x0,
			node_min.Z + sidelen / 2 + sidelen * z0
		);
		// Minimum edge of part of division
		v2s16 p2d_min(
			node_min.X + sidelen * x0,
			node_min.Z + sidelen * z0
		);
		// Maximum edge of part of division
		v2s16 p2d_max(
			node_min.X + sidelen + sidelen * x0 - 1,
			node_min.Z + sidelen + sidelen * z0 - 1
		);
		
		// Amount of trees, jungle area
		u32 tree_count = area * getTreeAmount(p2d_center);
		
		float humidity = 0;
		bool is_jungle = false;
		if (flags & MGV6_JUNGLES) {
			humidity = getHumidity(p2d_center);
			if (humidity > 0.75) {
				is_jungle = true;
				tree_count *= 4;
			}
		}

		if (node_max.Y < water_level)
			tree_count /= 2;

		// Add jungle grass
		if (is_jungle) {			
			u32 grass_count = 5 * humidity * tree_count;
			for (u32 i = 0; i < grass_count; i++) {
				s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
				s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
				
				s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////optimize this!
				if (y < water_level || y < node_min.Y || y > node_max.Y)
					continue;
				
				u32 vi = vm->m_area.index(x, y, z);
				// place on dirt_with_grass, since we know it is exposed to sunlight
				if (vm->m_data[vi].getContent() == c_dirt_with_grass) {
					vm->m_area.add_y(em, vi, 1);
					vm->m_data[vi] = n_junglegrass;
				}
			}
		}
		
		// Put trees in random places on part of division
		for (u32 i = 0; i < tree_count; i++) {
			s16 x = myrand_range(p2d_min.X, p2d_max.X);
			s16 z = myrand_range(p2d_min.Y, p2d_max.Y);
			s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////////optimize this!
			// Don't make a tree under water level
			// Don't make a tree so high that it doesn't fit
			if(y > node_max.Y - 6)
				continue;
			
			v3s16 p(x,y,z);
			// Trees grow only on mud and grass
			{
				u32 i = vm->m_area.index(p);
				MapNode *n = &vm->m_data[i];
				if (n->getContent() != c_dirt &&
					n->getContent() != c_dirt_with_grass &&
					(y >= water_level || n->getContent() != c_sand))
					continue;
			}
			p.Y++;
			
			// Make a tree
			if (y < water_level) {
				if (y < water_level - 20) // do not spawn trees in lakes
					treegen::make_cavetree(*vm, p, is_jungle, ndef, myrand());
			}
			else if (is_jungle) {
				treegen::make_jungletree(*vm, p, ndef, myrand());
			} else {
				bool is_apple_tree = (myrand_range(0, 3) == 0) &&
										getHaveAppleTree(v2s16(x, z));
				treegen::make_tree(*vm, p, is_apple_tree, ndef, myrand());
			}
		}
	}
	//printf("placeTreesAndJungleGrass: %dms\n", t.stop());
}