float *NoiseIndev::perlinMap2DFar(float x, float y) { float f = 1.0, g = 1.0; int i, j, index, oct; x /= np->spread.X; y /= np->spread.Y; memset(result, 0, sizeof(float) * sx * sy); for (oct = 0; oct < np->octaves; oct++) { gradientMap2D(x * f, y * f, f / np->spread.X, f / np->spread.Y, seed + np->seed + oct); index = 0; for (j = 0; j != sy; j++) { for (i = 0; i != sx; i++) { result[index] += g * buf[index]; index++; } } f *= 2.0; g *= np->persist * farscale(npindev->farpersist, x, y); // only difference from not far version } return result; }
void NoiseIndev::transformNoiseMapFarScale(float xx, float yy, float zz) { int i = 0; for (int z = 0; z != sz; z++) { for (int y = 0; y != sy; y++) { for (int x = 0; x != sx; x++) { result[i] = result[i] * npindev->scale * farscale(npindev->farscale, xx, yy, zz) + npindev->offset; i++; } } } }
int Mapgen_features::float_islands_generate(const v3POS & node_min, const v3POS & node_max, int min_y, MMVManip *vm) { int generated = 0; if (node_min.Y < min_y) return generated; // originally from http://forum.minetest.net/viewtopic.php?id=4776 float RAR = 0.8 * farscale(0.4, node_min.Y); // 0.4; // Island rarity in chunk layer. -0.4 = thick layer with holes, 0 = 50%, 0.4 = desert rarity, 0.7 = very rare. float AMPY = 24; // 24; // Amplitude of island centre y variation. float TGRAD = 24; // 24; // Noise gradient to create top surface. Tallness of island top. float BGRAD = 24; // 24; // Noise gradient to create bottom surface. Tallness of island bottom. v3POS p0(node_min.X, node_min.Y, node_min.Z); float xl = node_max.X - node_min.X; float yl = node_max.Y - node_min.Y; float zl = node_max.Z - node_min.Z; u32 zstride = xl + y_offset; float midy = node_min.Y + yl * 0.5; u32 index = 0; for (int z1 = 0; z1 <= zl; ++z1) for (int y1 = 0; y1 <= yl; ++y1) for (int x1 = 0; x1 <= xl; ++x1, ++index) { int y = y1 + node_min.Y; u32 index2d = z1 * zstride + x1; float noise3 = noise_float_islands3->result[index2d]; float pmidy = midy + noise3 / 1.5 * AMPY; float noise1 = noise_float_islands1->result[index]; float offset = y > pmidy ? (y - pmidy) / TGRAD : (pmidy - y) / BGRAD; float noise1off = noise1 - offset - RAR; if (noise1off > 0 && noise1off < 0.7) { float noise2 = noise_float_islands2->result[index]; if (noise2 - noise1off > -0.7) { v3POS p = p0 + v3POS(x1, y1, z1); u32 i = vm->m_area.index(p); if (!vm->m_area.contains(i)) continue; // Cancel if not air if (vm->m_data[i].getContent() != CONTENT_AIR) continue; vm->m_data[i] = layers_get(index); ++generated; } } } return generated; }
CaveIndev::CaveIndev(MapgenIndev *mg, PseudoRandom *ps, PseudoRandom *ps2, v3s16 node_min, bool is_large_cave) { this->mg = mg; this->vm = mg->vm; this->ndef = mg->ndef; this->water_level = mg->water_level; this->large_cave = is_large_cave; this->ps = ps; this->ps2 = ps2; this->c_water_source = mg->c_water_source; this->c_lava_source = mg->c_lava_source; this->c_ice = mg->c_ice; min_tunnel_diameter = 2; max_tunnel_diameter = ps->range(2,6); dswitchint = ps->range(1,14); flooded = large_cave && ps->range(0,4); if (large_cave) { part_max_length_rs = ps->range(2,4); float scale = farscale(0.4, node_min.X, node_min.Y, node_min.Z); if (node_min.Y < -100 && !ps->range(0, scale * 14)) { //huge flooded = !ps->range(0, 10); tunnel_routepoints = ps->range(10, 50); min_tunnel_diameter = 30; max_tunnel_diameter = ps->range(40, ps->range(50, 80)); } else { tunnel_routepoints = ps->range(5, ps->range(15,30)); min_tunnel_diameter = 5; max_tunnel_diameter = ps->range(7, ps->range(8,24)); } flooded_water = !ps->range(0, 2); } else { part_max_length_rs = ps->range(2,9); tunnel_routepoints = ps->range(10, ps->range(15,30)); } large_cave_is_flat = (ps->range(0,1) == 0); }
void DungeonGen::makeDungeon(v3s16 start_padding) { v3s16 areasize = vm->m_area.getExtent(); v3s16 roomsize; v3s16 roomplace; float far_multi = farscale(5, vm->m_area.MinEdge.X, vm->m_area.MinEdge.Y, vm->m_area.MinEdge.Z); /* Find place for first room */ bool fits = false; for (u32 i = 0; i < 100 && !fits; i++) { bool is_large_room = ((random.next() & 3) == 1); roomsize = is_large_room ? v3s16(random.range(8, 16 * far_multi), random.range(8, 16 * far_multi), random.range(8, 16 * far_multi)) : v3s16(random.range(4, 8 * far_multi), random.range(4, 6 * far_multi), random.range(4, 8 * far_multi)); roomsize += dp.roomsize; // start_padding is used to disallow starting the generation of // a dungeon in a neighboring generation chunk roomplace = vm->m_area.MinEdge + start_padding + v3s16( random.range(0, areasize.X - roomsize.X - start_padding.X), random.range(0, areasize.Y - roomsize.Y - start_padding.Y), random.range(0, areasize.Z - roomsize.Z - start_padding.Z)); /* Check that we're not putting the room to an unknown place, otherwise it might end up floating in the air */ fits = true; for (s16 z = 0; z < roomsize.Z; z++) for (s16 y = 0; y < roomsize.Y; y++) for (s16 x = 0; x < roomsize.X; x++) { v3s16 p = roomplace + v3s16(x, y, z); u32 vi = vm->m_area.index(p); if ((vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) || vm->m_data[vi].getContent() == CONTENT_IGNORE) { fits = false; break; } } } // No place found if (fits == false) return; /* Stores the center position of the last room made, so that a new corridor can be started from the last room instead of the new room, if chosen so. */ v3s16 last_room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); u32 room_count = random.range(2, random.range(8, 16 * far_multi)); for (u32 i = 0; i < room_count; i++) { // Make a room to the determined place makeRoom(roomsize, roomplace); v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); mg->gennotify.addEvent(dp.notifytype, room_center); #ifdef DGEN_USE_TORCHES // Place torch at room center (for testing) vm->m_data[vm->m_area.index(room_center)] = MapNode(c_torch); #endif // Quit if last room if (i == room_count - 1) break; // Determine walker start position bool start_in_last_room = (random.range(0, 2) != 0); v3s16 walker_start_place; if (start_in_last_room) { walker_start_place = last_room_center; } else { walker_start_place = room_center; // Store center of current room as the last one last_room_center = room_center; } // Create walker and find a place for a door v3s16 doorplace; v3s16 doordir; m_pos = walker_start_place; if (!findPlaceForDoor(doorplace, doordir)) return; if (random.range(0, 1) == 0) // Make the door makeDoor(doorplace, doordir); else // Don't actually make a door doorplace -= doordir; // Make a random corridor starting from the door v3s16 corridor_end; v3s16 corridor_end_dir; makeCorridor(doorplace, doordir, corridor_end, corridor_end_dir); // Find a place for a random sized room roomsize = v3s16(random.range(4, 8 * far_multi), random.range(4, 6 * far_multi), random.range(4, 8 * far_multi)); roomsize += dp.roomsize; m_pos = corridor_end; m_dir = corridor_end_dir; if (!findPlaceForRoomDoor(roomsize, doorplace, doordir, roomplace)) return; if (random.range(0, 1) == 0) // Make the door makeDoor(doorplace, doordir); else // Don't actually make a door roomplace -= doordir; } }
void MapgenIndev::calculateNoise() { int x = node_min.X; int y = node_min.Y; int z = node_min.Z; // Need to adjust for the original implementation's +.5 offset... if (!(flags & MG_FLAT)) { noiseindev_terrain_base->perlinMap2DFar( x + 0.5 * noiseindev_terrain_base->npindev->spread.X * farscale(noiseindev_terrain_base->npindev->farspread, x, z), z + 0.5 * noiseindev_terrain_base->npindev->spread.Z * farscale(noiseindev_terrain_base->npindev->farspread, x, z)); noiseindev_terrain_base->transformNoiseMapFarScale(x, y, z); noiseindev_terrain_higher->perlinMap2DFar( x + 0.5 * noiseindev_terrain_higher->npindev->spread.X * farscale(noiseindev_terrain_higher->npindev->farspread, x, z), z + 0.5 * noiseindev_terrain_higher->npindev->spread.Z * farscale(noiseindev_terrain_higher->npindev->farspread, x, z)); noiseindev_terrain_higher->transformNoiseMapFarScale(x, y, z); noiseindev_steepness->perlinMap2DFar( x + 0.5 * noiseindev_steepness->npindev->spread.X * farscale(noiseindev_steepness->npindev->farspread, x, z), z + 0.5 * noiseindev_steepness->npindev->spread.Z * farscale(noiseindev_steepness->npindev->farspread, x, z)); noiseindev_steepness->transformNoiseMapFarScale(x, y, z); noiseindev_height_select->perlinMap2DFar( x + 0.5 * noiseindev_height_select->npindev->spread.X * farscale(noiseindev_height_select->npindev->farspread, x, z), z + 0.5 * noiseindev_height_select->npindev->spread.Z * farscale(noiseindev_height_select->npindev->farspread, x, z)); noiseindev_float_islands1->perlinMap3D( x + 0.33 * noiseindev_float_islands1->npindev->spread.X * farscale(noiseindev_float_islands1->npindev->farspread, x, y, z), y + 0.33 * noiseindev_float_islands1->npindev->spread.Y * farscale(noiseindev_float_islands1->npindev->farspread, x, y, z), z + 0.33 * noiseindev_float_islands1->npindev->spread.Z * farscale(noiseindev_float_islands1->npindev->farspread, x, y, z) ); noiseindev_float_islands1->transformNoiseMapFarScale(x, y, z); noiseindev_float_islands2->perlinMap3D( x + 0.33 * noiseindev_float_islands2->npindev->spread.X * farscale(noiseindev_float_islands2->npindev->farspread, x, y, z), y + 0.33 * noiseindev_float_islands2->npindev->spread.Y * farscale(noiseindev_float_islands2->npindev->farspread, x, y, z), z + 0.33 * noiseindev_float_islands2->npindev->spread.Z * farscale(noiseindev_float_islands2->npindev->farspread, x, y, z) ); noiseindev_float_islands2->transformNoiseMapFarScale(x, y, z); noiseindev_float_islands3->perlinMap2DFar( x + 0.5 * noiseindev_float_islands3->npindev->spread.X * farscale(noiseindev_float_islands3->npindev->farspread, x, z), z + 0.5 * noiseindev_float_islands3->npindev->spread.Z * farscale(noiseindev_float_islands3->npindev->farspread, x, z)); noiseindev_float_islands3->transformNoiseMapFarScale(x, y, z); noiseindev_mud->perlinMap2DFar( x + 0.5 * noiseindev_mud->npindev->spread.X * farscale(noiseindev_mud->npindev->farspread, x, y, z), z + 0.5 * noiseindev_mud->npindev->spread.Z * farscale(noiseindev_mud->npindev->farspread, x, y, z)); noiseindev_mud->transformNoiseMapFarScale(x, y, z); } noiseindev_beach->perlinMap2DFar( x + 0.2 * noiseindev_beach->npindev->spread.X * farscale(noiseindev_beach->npindev->farspread, x, z), z + 0.7 * noiseindev_beach->npindev->spread.Z * farscale(noiseindev_beach->npindev->farspread, x, z)); noiseindev_biome->perlinMap2DFar( x + 0.6 * noiseindev_biome->npindev->spread.X * farscale(noiseindev_biome->npindev->farspread, x, z), z + 0.2 * noiseindev_biome->npindev->spread.Z * farscale(noiseindev_biome->npindev->farspread, x, z)); }