s16 MapgenFractal::generateTerrain() { MapNode n_air(CONTENT_AIR); MapNode n_stone(c_stone); MapNode n_water(c_water_source); s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 index2d = 0; for (s16 z = node_min.Z; z <= node_max.Z; z++) { for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { u32 vi = vm->m_area.index(node_min.X, y, z); for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index2d++) { if (vm->m_data[vi].getContent() == CONTENT_IGNORE) { s16 seabed_height = noise_seabed->result[index2d]; if (y <= seabed_height || getFractalAtPoint(x, y, z)) { vm->m_data[vi] = n_stone; if (y > stone_surface_max_y) stone_surface_max_y = y; } else if (y <= water_level) { vm->m_data[vi] = n_water; } else { vm->m_data[vi] = n_air; } } } index2d -= ystride; } index2d += ystride; } return stone_surface_max_y; }
int MapgenFractal::getGroundLevelAtPoint(v2s16 p) { s16 search_start = 128; s16 search_end = -128; for (s16 y = search_start; y >= search_end; y--) { if (getFractalAtPoint(p.X, y, p.Y)) return y; } return -MAX_MAP_GENERATION_LIMIT; }
int MapgenFractal::getSpawnLevelAtPoint(v2s16 p) { bool solid_below = false; // Dry solid node is present below to spawn on u8 air_count = 0; // Consecutive air nodes above the dry solid node s16 seabed_level = NoisePerlin2D(&noise_seabed->np, p.X, p.Y, seed); // Seabed can rise above water_level or might be raised to create dry land s16 search_start = MYMAX(seabed_level, water_level + 1); if (seabed_level > water_level) solid_below = true; for (s16 y = search_start; y <= search_start + 128; y++) { if (getFractalAtPoint(p.X, y, p.Y)) { // Fractal node solid_below = true; air_count = 0; } else if (solid_below) { // Air above solid node air_count++; if (air_count == 2) return y - 2; } } return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point }