Dungeons: Make multiple large rooms possible (#8678)
authorParamat <paramat@users.noreply.github.com>
Tue, 16 Jul 2019 19:39:58 +0000 (20:39 +0100)
committerGitHub <noreply@github.com>
Tue, 16 Jul 2019 19:39:58 +0000 (20:39 +0100)
Re-add the random size range for large rooms.
Remove 'first_room_large' bool.
Add 'large_room_chance' parameter that can disable large rooms,
specify 1 large room, or specify a chance for large rooms.
If 1 or a chance is specified, the first generated room is large,
to take advantage of the intersection checks that are done for the
1st room only.

src/mapgen/dungeongen.cpp
src/mapgen/dungeongen.h
src/mapgen/mapgen.cpp
src/mapgen/mapgen_v6.cpp

index 497fe0368e1fc34b614e5146528cb8f175c62091..efc3acc515e700271a9912c99adc354011492cd8 100644 (file)
@@ -64,9 +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     = v3s16(16, 16, 16);
-               dp.first_room_large    = true;
-               dp.num_rooms           = 16;
+               dp.room_size_large_min = v3s16(8, 8, 8);
+               dp.room_size_large_max = v3s16(16, 16, 16);
+               dp.large_room_chance   = 1;
+               dp.num_rooms           = 8;
                dp.num_dungeons        = 1;
                dp.notifytype          = GENNOTIFY_DUNGEON;
 
@@ -152,11 +153,10 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
        */
        bool fits = false;
        for (u32 i = 0; i < 100 && !fits; i++) {
-               // 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;
+               if (dp.large_room_chance >= 1) {
+                       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);
                } 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);
@@ -250,9 +250,16 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
                makeCorridor(doorplace, doordir, corridor_end, corridor_end_dir);
 
                // Find a place for a random sized room
-               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);
-               roomsize.X = random.range(dp.room_size_min.X, dp.room_size_max.X);
+               if (dp.large_room_chance > 1 && random.range(1, dp.large_room_chance) == 1) {
+                       // 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);
+               } 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);
+                       roomsize.X = random.range(dp.room_size_min.X, dp.room_size_max.X);
+               }
 
                m_pos = corridor_end;
                m_dir = corridor_end_dir;
@@ -265,7 +272,6 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
                else
                        // Don't actually make a door
                        roomplace -= doordir;
-
        }
 }
 
index dd5245fa946952f92df60f5a53ba0f67ed582b98..d2e733f717bbc26430c9a59e201888c4b49c97d1 100644 (file)
@@ -58,10 +58,14 @@ struct DungeonParams {
        // 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;
+       // Large room size random range. Includes walls / floor / ceilng
+       v3s16 room_size_large_min;
+       v3s16 room_size_large_max;
+       // Value 0 disables large rooms.
+       // Value 1 results in 1 large room, the first generated room.
+       // Value > 1 makes the first generated room large, all other rooms have a
+       // '1 in value' chance of being large.
+       u16 large_room_chance;
        // Dimensions of 3D 'brush' that creates corridors.
        // Dimensions are of the empty space, not including walls / floor / ceilng.
        v3s16 holesize;
index 3d1549b7ad5a16b126ef75d1a3dc0687cf51485d..67e9d644d094d700be852f96cb9c8a6255de7012 100644 (file)
@@ -877,20 +877,20 @@ void MapgenBasic::generateDungeons(s16 max_stone_y)
        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;
+       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_min = v3s16(10, 8, 10);
+       dp.room_size_large_max = v3s16(18, 16, 18);
+       dp.large_room_chance   = (ps.range(1, 4) == 1) ? 1 : 0;
+       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);
index 23de9bae534a7e4c7f0fdb93c23f624cde40aee9..ae87b094dd4fc299c2d568fea3b26199b44d643c 100644 (file)
@@ -572,13 +572,13 @@ void MapgenV6::makeChunk(BlockMakeData *data)
 
                        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.num_rooms        = ps.range(2, 16);
-                       dp.first_room_large = ps.range(1, 4) == 1;
+                       dp.seed              = seed;
+                       dp.num_dungeons      = num_dungeons;
+                       dp.only_in_ground    = true;
+                       dp.corridor_len_min  = 1;
+                       dp.corridor_len_max  = 13;
+                       dp.num_rooms         = ps.range(2, 16);
+                       dp.large_room_chance = (ps.range(1, 4) == 1) ? 1 : 0;
 
                        dp.np_alt_wall
                                = NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0);
@@ -592,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     = v3s16(
-                                       ps.range(10, 18), ps.range(13, 21), ps.range(10, 18));
+                               dp.room_size_large_min = v3s16(10, 13, 10);
+                               dp.room_size_large_max = v3s16(18, 21, 18);
                                dp.notifytype          = GENNOTIFY_TEMPLE;
                        } else {
                                dp.c_wall              = c_cobble;
@@ -604,8 +604,8 @@ 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     = v3s16(
-                                       ps.range(8, 16), ps.range(8, 16), ps.range(8, 16));
+                               dp.room_size_large_min = v3s16(8, 8, 8);
+                               dp.room_size_large_max = v3s16(16, 16, 16);
                                dp.notifytype          = GENNOTIFY_DUNGEON;
                        }