diff --git a/src/mapgen/dungeongen.cpp b/src/mapgen/dungeongen.cpp index 1cb46f140..497fe0368 100644 --- a/src/mapgen/dungeongen.cpp +++ b/src/mapgen/dungeongen.cpp @@ -64,10 +64,10 @@ DungeonGen::DungeonGen(const NodeDefManager *ndef, dp.corridor_len_max = 13; dp.room_size_min = v3s16(4, 4, 4); dp.room_size_max = v3s16(8, 6, 8); - dp.room_size_large_min = v3s16(8, 8, 8); - dp.room_size_large_max = v3s16(16, 16, 16); - dp.rooms_min = 2; - dp.rooms_max = 16; + dp.room_size_large = v3s16(16, 16, 16); + dp.first_room_large = true; + dp.num_rooms = 16; + dp.num_dungeons = 1; dp.notifytype = GENNOTIFY_DUNGEON; dp.np_alt_wall = @@ -76,10 +76,9 @@ DungeonGen::DungeonGen(const NodeDefManager *ndef, } -void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax, - u16 num_dungeons) +void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax) { - if (num_dungeons == 0) + if (dp.num_dungeons == 0) return; assert(vm); @@ -119,7 +118,7 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax, } // Add them - for (u32 i = 0; i < num_dungeons; i++) + for (u32 i = 0; i < dp.num_dungeons; i++) makeDungeon(v3s16(1, 1, 1) * MAP_BLOCKSIZE); // Optionally convert some structure to alternative structure @@ -150,19 +149,14 @@ void DungeonGen::makeDungeon(v3s16 start_padding) /* Find place for first room. - There is a 1 in 4 chance of the first room being 'large', - all other rooms are not 'large'. */ bool fits = false; for (u32 i = 0; i < 100 && !fits; i++) { - bool is_large_room = ((random.next() & 3) == 1); - if (is_large_room) { - roomsize.Z = random.range( - dp.room_size_large_min.Z, dp.room_size_large_max.Z); - roomsize.Y = random.range( - dp.room_size_large_min.Y, dp.room_size_large_max.Y); - roomsize.X = random.range( - dp.room_size_large_min.X, dp.room_size_large_max.X); + // Only the first room can be 'large' + if (dp.first_room_large) { + roomsize.Z = dp.room_size_large.Z; + roomsize.Y = dp.room_size_large.Y; + roomsize.X = dp.room_size_large.X; } else { roomsize.Z = random.range(dp.room_size_min.Z, dp.room_size_max.Z); roomsize.Y = random.range(dp.room_size_min.Y, dp.room_size_max.Y); @@ -204,8 +198,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding) */ v3s16 last_room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); - u32 room_count = random.range(dp.rooms_min, dp.rooms_max); - for (u32 i = 0; i < room_count; i++) { + for (u32 i = 0; i < dp.num_rooms; i++) { // Make a room to the determined place makeRoom(roomsize, roomplace); @@ -219,7 +212,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding) #endif // Quit if last room - if (i == room_count - 1) + if (i + 1 == dp.num_rooms) break; // Determine walker start position diff --git a/src/mapgen/dungeongen.h b/src/mapgen/dungeongen.h index 7b476527b..dd5245fa9 100644 --- a/src/mapgen/dungeongen.h +++ b/src/mapgen/dungeongen.h @@ -46,32 +46,33 @@ struct DungeonParams { content_t c_alt_wall; content_t c_stair; - // Diagonal corridors are possible - bool diagonal_dirs; - // Dungeon only generates in ground + // 3D noise that determines which c_wall nodes are converted to c_alt_wall + NoiseParams np_alt_wall; + + // Number of dungeons generated in mapchunk + u16 num_dungeons; + // Dungeons only generate in ground bool only_in_ground; + // Number of rooms + u16 num_rooms; + // Room size random range. Includes walls / floor / ceilng + v3s16 room_size_min; + v3s16 room_size_max; + // Large room size + v3s16 room_size_large; + // First generated room is large + bool first_room_large; // Dimensions of 3D 'brush' that creates corridors. // Dimensions are of the empty space, not including walls / floor / ceilng. v3s16 holesize; - // Corridor length + // Corridor length random range u16 corridor_len_min; u16 corridor_len_max; - // Room size includes walls / floor / ceilng - v3s16 room_size_min; - v3s16 room_size_max; - // The 1st room generated has a 1 in 4 chance of being 'large', all other - // rooms are not 'large'. - v3s16 room_size_large_min; - v3s16 room_size_large_max; - // Number of rooms - u16 rooms_min; - u16 rooms_max; + // Diagonal corridors are possible + bool diagonal_dirs; // Usually 'GENNOTIFY_DUNGEON', but mapgen v6 uses 'GENNOTIFY_TEMPLE' for // desert dungeons. GenNotifyType notifytype; - - // 3D noise that determines which c_wall nodes are converted to c_alt_wall - NoiseParams np_alt_wall; }; class DungeonGen { @@ -94,8 +95,7 @@ public: DungeonGen(const NodeDefManager *ndef, GenerateNotifier *gennotify, DungeonParams *dparams); - void generate(MMVManip *vm, u32 bseed, - v3s16 full_node_min, v3s16 full_node_max, u16 num_dungeons); + void generate(MMVManip *vm, u32 bseed, v3s16 full_node_min, v3s16 full_node_max); void makeDungeon(v3s16 start_padding); void makeRoom(v3s16 roomsize, v3s16 roomplace); diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 838253a75..3d1549b7a 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -870,30 +870,32 @@ void MapgenBasic::generateDungeons(s16 max_stone_y) if (num_dungeons == 0) return; + PseudoRandom ps(blockseed + 70033); + + DungeonParams dp; + + dp.np_alt_wall = + NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); + + dp.seed = seed; + dp.num_dungeons = num_dungeons; + dp.only_in_ground = true; + dp.num_rooms = ps.range(2, 16); + dp.room_size_min = v3s16(6, 5, 6); + dp.room_size_max = v3s16(10, 6, 10); + dp.room_size_large = v3s16( + ps.range(10, 18), ps.range(8, 16), ps.range(10, 18)); + dp.first_room_large = ps.range(1, 4) == 1; + dp.holesize = v3s16(2, 3, 2); + dp.corridor_len_min = 1; + dp.corridor_len_max = 13; + dp.diagonal_dirs = ps.range(1, 12) == 1; + dp.notifytype = GENNOTIFY_DUNGEON; + // Get biome at mapchunk midpoint v3s16 chunk_mid = node_min + (node_max - node_min) / v3s16(2, 2, 2); Biome *biome = (Biome *)biomegen->getBiomeAtPoint(chunk_mid); - DungeonParams dp; - - dp.seed = seed; - dp.only_in_ground = true; - dp.corridor_len_min = 1; - dp.corridor_len_max = 13; - dp.rooms_min = 2; - dp.rooms_max = 16; - - dp.np_alt_wall = - NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); - - dp.diagonal_dirs = false; - dp.holesize = v3s16(2, 3, 2); - dp.room_size_min = v3s16(6, 5, 6); - dp.room_size_max = v3s16(10, 6, 10); - dp.room_size_large_min = v3s16(10, 8, 10); - dp.room_size_large_max = v3s16(18, 16, 18); - dp.notifytype = GENNOTIFY_DUNGEON; - // Use biome-defined dungeon nodes if defined if (biome->c_dungeon != CONTENT_IGNORE) { dp.c_wall = biome->c_dungeon; @@ -917,7 +919,7 @@ void MapgenBasic::generateDungeons(s16 max_stone_y) } DungeonGen dgen(ndef, &gennotify, &dp); - dgen.generate(vm, blockseed, full_node_min, full_node_max, num_dungeons); + dgen.generate(vm, blockseed, full_node_min, full_node_max); } diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp index 9cf4da892..23de9bae5 100644 --- a/src/mapgen/mapgen_v6.cpp +++ b/src/mapgen/mapgen_v6.cpp @@ -568,14 +568,17 @@ void MapgenV6::makeChunk(BlockMakeData *data) NoisePerlin3D(&np_dungeons, node_min.X, node_min.Y, node_min.Z, seed)), 0.0f); if (num_dungeons >= 1) { + PseudoRandom ps(blockseed + 4713); + DungeonParams dp; dp.seed = seed; + dp.num_dungeons = num_dungeons; dp.only_in_ground = true; dp.corridor_len_min = 1; dp.corridor_len_max = 13; - dp.rooms_min = 2; - dp.rooms_max = 16; + dp.num_rooms = ps.range(2, 16); + dp.first_room_large = ps.range(1, 4) == 1; dp.np_alt_wall = NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); @@ -589,8 +592,8 @@ void MapgenV6::makeChunk(BlockMakeData *data) dp.holesize = v3s16(2, 3, 2); dp.room_size_min = v3s16(6, 9, 6); dp.room_size_max = v3s16(10, 11, 10); - dp.room_size_large_min = v3s16(10, 13, 10); - dp.room_size_large_max = v3s16(18, 21, 18); + dp.room_size_large = v3s16( + ps.range(10, 18), ps.range(13, 21), ps.range(10, 18)); dp.notifytype = GENNOTIFY_TEMPLE; } else { dp.c_wall = c_cobble; @@ -601,13 +604,13 @@ void MapgenV6::makeChunk(BlockMakeData *data) dp.holesize = v3s16(1, 2, 1); dp.room_size_min = v3s16(4, 4, 4); dp.room_size_max = v3s16(8, 6, 8); - dp.room_size_large_min = v3s16(8, 8, 8); - dp.room_size_large_max = v3s16(16, 16, 16); + dp.room_size_large = v3s16( + ps.range(8, 16), ps.range(8, 16), ps.range(8, 16)); dp.notifytype = GENNOTIFY_DUNGEON; } DungeonGen dgen(ndef, &gennotify, &dp); - dgen.generate(vm, blockseed, full_node_min, full_node_max, num_dungeons); + dgen.generate(vm, blockseed, full_node_min, full_node_max); } }