Dungeongen: Add and improve parameters
authorparamat <mat.gregory@virginmedia.com>
Tue, 21 Feb 2017 01:56:34 +0000 (01:56 +0000)
committerparamat <mat.gregory@virginmedia.com>
Sun, 26 Feb 2017 06:46:14 +0000 (06:46 +0000)
Add:
Bool for 'only_in_ground'.
Min and max corridor length.
Min and max room size with X, Y, Z components.
Min and max large room size with X, Y, Z components.

'only_in_ground = false' allows core mapgens to create structures
in air and water using dungeongen.
Corridor length parameters replace a fixed random range.
Room size parameters replace the former system where one parameter
'roomsize' was added to fixed random ranges.

All parameters are set for no change to current dungeon behaviour.

Remove some now-redundant and long-unused code.

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

index 7825e9e2ce53013639bdc44400b9e36e0a2d738f..6cef3f88dbd432c273ea2699db227ade13071ca4 100644 (file)
@@ -52,6 +52,7 @@ DungeonGen::DungeonGen(INodeDefManager *ndef,
        if (dparams) {
                memcpy(&dp, dparams, sizeof(dp));
        } else {
+               // Default dungeon parameters
                dp.seed = 0;
 
                dp.c_water       = ndef->getId("mapgen_water_source");
@@ -63,14 +64,20 @@ DungeonGen::DungeonGen(INodeDefManager *ndef,
                if (dp.c_river_water == CONTENT_IGNORE)
                        dp.c_river_water = ndef->getId("mapgen_water_source");
 
-               dp.diagonal_dirs = false;
-               dp.holesize      = v3s16(1, 2, 1);
-               dp.roomsize      = v3s16(0, 0, 0);
-               dp.rooms_min     = 2;
-               dp.rooms_max     = 16;
-               dp.y_min         = -MAX_MAP_GENERATION_LIMIT;
-               dp.y_max         = MAX_MAP_GENERATION_LIMIT;
-               dp.notifytype    = GENNOTIFY_DUNGEON;
+               dp.diagonal_dirs       = false;
+               dp.only_in_ground      = true;
+               dp.holesize            = v3s16(1, 2, 1);
+               dp.corridor_len_min    = 1;
+               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.y_min               = -MAX_MAP_GENERATION_LIMIT;
+               dp.y_max               = MAX_MAP_GENERATION_LIMIT;
+               dp.notifytype          = GENNOTIFY_DUNGEON;
 
                dp.np_density  = nparams_dungeon_density;
                dp.np_alt_wall = nparams_dungeon_alt_wall;
@@ -97,16 +104,19 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax)
        // Dungeon generator doesn't modify places which have this set
        vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
 
-       // Set all air and water to be untouchable
-       // to make dungeons open to caves and open air
-       for (s16 z = nmin.Z; z <= nmax.Z; z++) {
-               for (s16 y = nmin.Y; y <= nmax.Y; y++) {
-                       u32 i = vm->m_area.index(nmin.X, y, z);
-                       for (s16 x = nmin.X; x <= nmax.X; x++) {
-                               content_t c = vm->m_data[i].getContent();
-                               if (c == CONTENT_AIR || c == dp.c_water || c == dp.c_river_water)
-                                       vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
-                               i++;
+       if (dp.only_in_ground) {
+               // Set all air and water to be untouchable
+               // to make dungeons open to caves and open air
+               for (s16 z = nmin.Z; z <= nmax.Z; z++) {
+                       for (s16 y = nmin.Y; y <= nmax.Y; y++) {
+                               u32 i = vm->m_area.index(nmin.X, y, z);
+                               for (s16 x = nmin.X; x <= nmax.X; x++) {
+                                       content_t c = vm->m_data[i].getContent();
+                                       if (c == CONTENT_AIR || c == dp.c_water ||
+                                                       c == dp.c_river_water)
+                                               vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
+                                       i++;
+                               }
                        }
                }
        }
@@ -142,21 +152,25 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
        v3s16 roomplace;
 
        /*
-               Find place for first room
+               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(8, 16);
-                       roomsize.Y = random.range(8, 16);
-                       roomsize.X = random.range(8, 16);
+                       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(4, 8);
-                       roomsize.Y = random.range(4, 6);
-                       roomsize.X = random.range(4, 8);
+                       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);
                }
-               roomsize += dp.roomsize;
 
                // start_padding is used to disallow starting the generation of
                // a dungeon in a neighboring generation chunk
@@ -246,10 +260,9 @@ 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(4, 8);
-               roomsize.Y = random.range(4, 6);
-               roomsize.X = random.range(4, 8);
-               roomsize += dp.roomsize;
+               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;
@@ -397,13 +410,8 @@ void DungeonGen::makeCorridor(v3s16 doorplace, v3s16 doordir,
        makeHole(doorplace);
        v3s16 p0 = doorplace;
        v3s16 dir = doordir;
-       u32 length;
-       /*if (random.next() % 2)
-               length = random.range(1, 13);
-       else
-               length = random.range(1, 6);*/
-       length = random.range(1, 13);
-       u32 partlength = random.range(1, 13);
+       u32 length = random.range(dp.corridor_len_min, dp.corridor_len_max);
+       u32 partlength = random.range(dp.corridor_len_min, dp.corridor_len_max);
        u32 partcount = 0;
        s16 make_stairs = 0;
 
@@ -556,7 +564,6 @@ bool DungeonGen::findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
                        continue;
                v3s16 roomplace;
                // X east, Z north, Y up
-#if 1
                if (doordir == v3s16(1, 0, 0)) // X+
                        roomplace = doorplace +
                                v3s16(0, -1, random.range(-roomsize.Z + 2, -2));
@@ -569,17 +576,6 @@ bool DungeonGen::findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
                if (doordir == v3s16(0, 0, -1)) // Z-
                        roomplace = doorplace +
                                v3s16(random.range(-roomsize.X + 2, -2), -1, -roomsize.Z + 1);
-#endif
-#if 0
-               if (doordir == v3s16(1, 0, 0)) // X+
-                       roomplace = doorplace + v3s16(0, -1, -roomsize.Z / 2);
-               if (doordir == v3s16(-1, 0, 0)) // X-
-                       roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z / 2);
-               if (doordir == v3s16(0, 0, 1)) // Z+
-                       roomplace = doorplace + v3s16(-roomsize.X / 2, -1, 0);
-               if (doordir == v3s16(0, 0, -1)) // Z-
-                       roomplace = doorplace + v3s16(-roomsize.X / 2, -1, -roomsize.Z + 1);
-#endif
 
                // Check fit
                bool fits = true;
index 30786b9f3b0e2b2a60d2e0103addb66a92080af8..4bd208330714387e755328936aafeabc80ab7b5a 100644 (file)
@@ -48,8 +48,14 @@ struct DungeonParams {
        content_t c_stair;
 
        bool diagonal_dirs;
+       bool only_in_ground;
        v3s16 holesize;
-       v3s16 roomsize;
+       u16 corridor_len_min;
+       u16 corridor_len_max;
+       v3s16 room_size_min;
+       v3s16 room_size_max;
+       v3s16 room_size_large_min;
+       v3s16 room_size_large_max;
        u16 rooms_min;
        u16 rooms_max;
        s16 y_min;
index 00ae917a1006d96a1f852be8a6027555736d6abb..e1e3ccd25b171f680c89c74958986b20c47f6fa8 100644 (file)
@@ -845,47 +845,61 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, MgStoneType stone_type)
 
        DungeonParams dp;
 
-       dp.seed          = seed;
-       dp.c_water       = c_water_source;
-       dp.c_river_water = c_river_water_source;
-       dp.rooms_min     = 2;
-       dp.rooms_max     = 16;
-       dp.y_min         = -MAX_MAP_GENERATION_LIMIT;
-       dp.y_max         = MAX_MAP_GENERATION_LIMIT;
-       dp.np_density    = nparams_dungeon_density;
-       dp.np_alt_wall   = nparams_dungeon_alt_wall;
+       dp.seed             = seed;
+       dp.c_water          = c_water_source;
+       dp.c_river_water    = c_river_water_source;
+
+       dp.only_in_ground   = true;
+       dp.corridor_len_min = 1;
+       dp.corridor_len_max = 13;
+       dp.rooms_min        = 2;
+       dp.rooms_max        = 16;
+       dp.y_min            = -MAX_MAP_GENERATION_LIMIT;
+       dp.y_max            = MAX_MAP_GENERATION_LIMIT;
+
+       dp.np_density       = nparams_dungeon_density;
+       dp.np_alt_wall      = nparams_dungeon_alt_wall;
 
        switch (stone_type) {
        default:
        case MGSTONE_STONE:
-               dp.c_wall     = c_cobble;
-               dp.c_alt_wall = c_mossycobble;
-               dp.c_stair    = c_stair_cobble;
-
-               dp.diagonal_dirs = false;
-               dp.holesize      = v3s16(1, 2, 1);
-               dp.roomsize      = v3s16(0, 0, 0);
-               dp.notifytype    = GENNOTIFY_DUNGEON;
+               dp.c_wall              = c_cobble;
+               dp.c_alt_wall          = c_mossycobble;
+               dp.c_stair             = c_stair_cobble;
+
+               dp.diagonal_dirs       = false;
+               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.notifytype          = GENNOTIFY_DUNGEON;
                break;
        case MGSTONE_DESERT_STONE:
-               dp.c_wall     = c_desert_stone;
-               dp.c_alt_wall = CONTENT_IGNORE;
-               dp.c_stair    = c_stair_desert_stone;
-
-               dp.diagonal_dirs = true;
-               dp.holesize      = v3s16(2, 3, 2);
-               dp.roomsize      = v3s16(2, 5, 2);
-               dp.notifytype    = GENNOTIFY_TEMPLE;
+               dp.c_wall              = c_desert_stone;
+               dp.c_alt_wall          = CONTENT_IGNORE;
+               dp.c_stair             = c_stair_desert_stone;
+
+               dp.diagonal_dirs       = true;
+               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.notifytype          = GENNOTIFY_TEMPLE;
                break;
        case MGSTONE_SANDSTONE:
-               dp.c_wall     = c_sandstonebrick;
-               dp.c_alt_wall = CONTENT_IGNORE;
-               dp.c_stair    = c_stair_sandstonebrick;
-
-               dp.diagonal_dirs = false;
-               dp.holesize      = v3s16(2, 2, 2);
-               dp.roomsize      = v3s16(2, 0, 2);
-               dp.notifytype    = GENNOTIFY_DUNGEON;
+               dp.c_wall              = c_sandstonebrick;
+               dp.c_alt_wall          = CONTENT_IGNORE;
+               dp.c_stair             = c_stair_sandstonebrick;
+
+               dp.diagonal_dirs       = false;
+               dp.holesize            = v3s16(2, 2, 2);
+               dp.room_size_min       = v3s16(6, 4, 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;
                break;
        }
 
index 807bbe7517f675f1dc8fb095921f0a37b6421f66..f3e893f58757ea3f7b72a9359f5dc0d514d12ad2 100644 (file)
@@ -564,34 +564,47 @@ void MapgenV6::makeChunk(BlockMakeData *data)
        if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonParams dp;
 
-               dp.seed = seed;
-               dp.c_water       = c_water_source;
-               dp.c_river_water = c_water_source;
-               dp.rooms_min     = 2;
-               dp.rooms_max     = 16;
-               dp.y_min         = -MAX_MAP_GENERATION_LIMIT;
-               dp.y_max         = MAX_MAP_GENERATION_LIMIT;
-               dp.np_density    = NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0);
-               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.c_water          = c_water_source;
+               dp.c_river_water    = c_water_source;
+
+               dp.only_in_ground   = true;
+               dp.corridor_len_min = 1;
+               dp.corridor_len_max = 13;
+               dp.rooms_min        = 2;
+               dp.rooms_max        = 16;
+               dp.y_min            = -MAX_MAP_GENERATION_LIMIT;
+               dp.y_max            = MAX_MAP_GENERATION_LIMIT;
+
+               dp.np_density
+                       = NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0);
+               dp.np_alt_wall
+                       = NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0);
 
                if (getBiome(0, v2s16(node_min.X, node_min.Z)) == BT_DESERT) {
-                       dp.c_wall     = c_desert_stone;
-                       dp.c_alt_wall = CONTENT_IGNORE;
-                       dp.c_stair    = c_stair_desert_stone;
-
-                       dp.diagonal_dirs = true;
-                       dp.holesize      = v3s16(2, 3, 2);
-                       dp.roomsize      = v3s16(2, 5, 2);
-                       dp.notifytype    = GENNOTIFY_TEMPLE;
+                       dp.c_wall              = c_desert_stone;
+                       dp.c_alt_wall          = CONTENT_IGNORE;
+                       dp.c_stair             = c_stair_desert_stone;
+
+                       dp.diagonal_dirs       = true;
+                       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.notifytype          = GENNOTIFY_TEMPLE;
                } else {
-                       dp.c_wall     = c_cobble;
-                       dp.c_alt_wall = c_mossycobble;
-                       dp.c_stair    = c_stair_cobble;
-
-                       dp.diagonal_dirs = false;
-                       dp.holesize      = v3s16(1, 2, 1);
-                       dp.roomsize      = v3s16(0, 0, 0);
-                       dp.notifytype    = GENNOTIFY_DUNGEON;
+                       dp.c_wall              = c_cobble;
+                       dp.c_alt_wall          = c_mossycobble;
+                       dp.c_stair             = c_stair_cobble;
+
+                       dp.diagonal_dirs       = false;
+                       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.notifytype          = GENNOTIFY_DUNGEON;
                }
 
                DungeonGen dgen(ndef, &gennotify, &dp);