Exemple #1
0
void MapgenV6::addMud()
{
	// 15ms @cs=8
	//TimeTaker timer1("add mud");
	MapNode n_dirt(c_dirt), n_gravel(c_gravel);
	MapNode n_sand(c_sand), n_desert_sand(c_desert_sand);
	MapNode addnode;

	u32 index = 0;
	for (s16 z = node_min.Z; z <= node_max.Z; z++)
	for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
		// Randomize mud amount
		s16 mud_add_amount = getMudAmount(index) / 2.0 + 0.5;

		// Find ground level
		s16 surface_y = find_stone_level(v2s16(x, z)); /////////////////optimize this!

		// Handle area not found
		if (surface_y == vm->m_area.MinEdge.Y - 1)
			continue;

		BiomeV6Type bt = getBiome(v3POS(x, surface_y, z));
		addnode = (bt == BT_DESERT) ? n_desert_sand : n_dirt;

		if (bt == BT_DESERT && surface_y + mud_add_amount <= water_level + 1) {
			addnode = n_sand;
		} else if (mud_add_amount <= 0) {
			mud_add_amount = 1 - mud_add_amount;
			addnode = n_gravel;
		} else if (bt != BT_DESERT && getHaveBeach(index) &&
				surface_y + mud_add_amount <= water_level + 2) {
			addnode = n_sand;
		}

		if ((bt == BT_DESERT || bt == BT_TUNDRA) && surface_y > 20)
			mud_add_amount = MYMAX(0, mud_add_amount - (surface_y - 20) / 5);

		/* If topmost node is grass, change it to mud.  It might be if it was
		// flown to there from a neighboring chunk and then converted.
		u32 i = vm->m_area.index(x, surface_y, z);
		if (vm->m_data[i].getContent() == c_dirt_with_grass)
			vm->m_data[i] = n_dirt;*/

		// Add mud on ground
		s16 mudcount = 0;
		v3s16 em = vm->m_area.getExtent();
		s16 y_start = surface_y + 1;
		u32 i = vm->m_area.index(x, y_start, z);
		for (s16 y = y_start; y <= node_max.Y; y++) {
			if (mudcount >= mud_add_amount)
				break;

			vm->m_data[i] = addnode;
			mudcount++;

			vm->m_area.add_y(em, i, 1);
		}
	}
}
int MapgenIndev::generateGround() {
    //TimeTaker timer1("Generating ground level");
    MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
    MapNode n_stone(c_stone), n_desert_stone(c_desert_stone);
    MapNode n_ice(c_ice), n_dirt(c_dirt),n_sand(c_sand), n_gravel(c_gravel), n_lava_source(c_lava_source);
    int stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
    u32 index = 0;

    for (s16 z = node_min.Z; z <= node_max.Z; z++)
        for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
            // Surface height
            s16 surface_y = (s16)baseTerrainLevelFromMap(index);

            // Log it
            if (surface_y > stone_surface_max_y)
                stone_surface_max_y = surface_y;

            auto bt = getBiome(index, v3POS(x, surface_y, z));

            s16 heat = m_emerge->env->m_use_weather ? m_emerge->env->getServerMap().updateBlockHeat(m_emerge->env, v3POS(x,node_max.Y,z), nullptr, &heat_cache) : 0;

            // Fill ground with stone
            v3POS em = vm->m_area.getExtent();
            u32 i = vm->m_area.index(x, node_min.Y, z);

            for (s16 y = node_min.Y; y <= node_max.Y; y++) {
                if (!vm->m_data[i]) {

                    if (y <= surface_y) {
                        int index3 = (z - node_min.Z) * zstride + (y - node_min.Y) * ystride + (x - node_min.X) * xstride;
                        if (cave_noise_threshold && noise_cave_indev->result[index3] > cave_noise_threshold) {
                            vm->m_data[i] = n_air;
                        } else {
                            auto n = (y > water_level - surface_y && bt == BT_DESERT) ? n_desert_stone : layers_get(index3);
                            bool protect = n.getContent() != CONTENT_AIR;
                            if (cave_noise_threshold && noise_cave_indev->result[index3] > cave_noise_threshold - 50) {
                                vm->m_data[i] = protect ? n_stone : n; //cave shell without layers
                                protect = true;
                            } else {
                                vm->m_data[i] = n;
                            }
                            if (protect)
                                vm->m_flags[i] |= VOXELFLAG_CHECKED2; // no cave liquid
                        }
                    } else if (y <= water_level) {
                        vm->m_data[i] = (heat < 0 && y > heat/3) ? n_ice : n_water_source;
                        if (liquid_pressure && y <= 0)
                            vm->m_data[i].addLevel(m_emerge->ndef, water_level - y, 1);
                    } else {
                        vm->m_data[i] = n_air;
                    }
                }
                vm->m_area.add_y(em, i, 1);
            }
        }

    return stone_surface_max_y;
}
Exemple #3
0
void MapgenV6::growGrass() // Add surface nodes
{
	MapNode n_dirt_with_grass(c_dirt_with_grass);
	MapNode n_dirt_with_snow(c_dirt_with_snow);
	MapNode n_snowblock(c_snowblock);
	MapNode n_snow(c_snow);
	MapNode n_dirt(c_dirt);
	v3s16 em = vm->m_area.getExtent();

	u32 index = 0;
	for (s16 z = full_node_min.Z; z <= full_node_max.Z; z++)
	for (s16 x = full_node_min.X; x <= full_node_max.X; x++, index++) {
		// Find the lowest surface to which enough light ends up to make
		// grass grow.  Basically just wait until not air and not leaves.
		s16 surface_y = 0;
		{
			u32 i = vm->m_area.index(x, node_max.Y, z);
			s16 y;
			// Go to ground level
			for (y = node_max.Y; y >= full_node_min.Y; y--) {
				MapNode &n = vm->m_data[i];
				if (ndef->get(n).param_type != CPT_LIGHT ||
						ndef->get(n).liquid_type != LIQUID_NONE ||
						n.getContent() == c_ice)
					break;
				vm->m_area.add_y(em, i, -1);
			}
			surface_y = (y >= full_node_min.Y) ? y : full_node_min.Y;
		}

		BiomeV6Type bt = getBiome(index, v3POS(x, surface_y, z));
		u32 i = vm->m_area.index(x, surface_y, z);
		content_t c = vm->m_data[i].getContent();
		if (m_emerge->env->m_use_weather && c == c_dirt) {
			int heat = m_emerge->env->getServerMap().updateBlockHeat(m_emerge->env, v3POS(x, surface_y, z), nullptr, &heat_cache);
			vm->m_data[i] = (heat < -10 ? n_dirt_with_snow : (heat < -5 || heat > 50) ? n_dirt : n_dirt_with_grass);
		} else
		if (surface_y >= water_level - 20) {
			if (bt == BT_TAIGA && c == c_dirt) {
				vm->m_data[i] = n_snowblock;
				vm->m_area.add_y(em, i, -1);
				vm->m_data[i] = n_dirt_with_snow;
			} else if (bt == BT_TUNDRA) {
				if (c == c_dirt) {
					vm->m_data[i] = n_dirt_with_snow;
				} else if (c == c_stone && surface_y < node_max.Y) {
					vm->m_area.add_y(em, i, 1);
					vm->m_data[i] = n_snow;
				}
			} else if (c == c_dirt) {
				vm->m_data[i] = n_dirt_with_grass;
			}
		}
	}
}
void MapgenValleys::generateSimpleCaves(s16 max_stone_y)
{
	PseudoRandom ps(blockseed + 72202);

	MapNode n_air(CONTENT_AIR);
	MapNode n_dirt(c_dirt);
	MapNode n_lava(c_lava_source);
	MapNode n_water(c_river_water_source);

	v3s16 em = vm->m_area.getExtent();

	s16 base_water_chance = 0;
	if (water_features < 11)
		base_water_chance = ceil(MAX_MAP_GENERATION_LIMIT / (water_features * 1000));

	if (max_stone_y >= node_min.Y) {
		u32 index_2d = 0;
		u32 index_3d = 0;
		for (s16 z = node_min.Z; z <= node_max.Z; z++)
		for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
			bool air_above = false;
			//bool underground = false;
			u32 index_data = vm->m_area.index(x, node_max.Y + 1, z);

			index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X);

			// Dig caves on down loop to check for air above.
			for (s16 y = node_max.Y + 1;
					y >= node_min.Y - 1;
					y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) {
				float terrain = noise_terrain_height->result[index_2d];

				// Saves some time and prevents removing above ground nodes.
				if (y > terrain + 1) {
					air_above = true;
					continue;
				}

				content_t c = vm->m_data[index_data].getContent();
				bool n1 = (fabs(noise_simple_caves_1->result[index_3d]) < 0.07f);
				bool n2 = (fabs(noise_simple_caves_2->result[index_3d]) < 0.07f);

				// River water is (foolishly) not set as ground content
				// in the default game. This can produce strange results
				// when a cave undercuts a river. However, that's not for
				// the mapgen to correct. Fix it in lua.

				if (c == CONTENT_AIR) {
					air_above = true;
				} else if (n1 && n2 && ndef->get(c).is_ground_content) {
					// When both n's are true, we're in a cave.
					vm->m_data[index_data] = n_air;
					air_above = true;
				} else if (air_above
						&& (c == c_stone || c == c_sandstone || c == c_desert_stone)) {
					// At the cave floor
					s16 sr = ps.next() & 1023;
					u32 j = index_data;
					vm->m_area.add_y(em, j, 1);

					if (sr > (terrain - y) * 25) {
						// Put dirt in caves near the surface.
						Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
						vm->m_data[index_data] = MapNode(biome->c_filler);
					} else {
						s16 lava_chance = 0;

						if (y <= lava_max_height && c == c_stone) {
							// Lava spawns increase with depth.
							lava_chance = ceil((lava_max_height - y + 1) / 10000);

							if (sr < lava_chance)
								vm->m_data[j] = n_lava;
						}

						if (base_water_chance > 0 && y <= cave_water_max_height) {
							s16 water_chance = base_water_chance
								- (abs(y - water_level) / (water_features * 1000));

							// Waterfalls may get out of control above ground.
							sr -= lava_chance;
							// If sr < 0 then we should have already placed lava --
							// don't immediately dump water on it.
							if (sr >= 0 && sr < water_chance)
								vm->m_data[j] = n_water;
						}
					}

					air_above = false;
				}

				// If we're not in a cave, there's no open space.
				if (!(n1 && n2))
					air_above = false;
			}
		}
	}
}