diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 620828824..0c7d44adf 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -5676,6 +5676,17 @@ Definition tables -- ^ Nodes placed as a blob of liquid in 50% of large caves. -- ^ If absent, cave liquids fall back to classic behaviour of lava or -- ^ water distributed according to a hardcoded 3D noise. + node_dungeon = "default:cobble", + -- ^ Node used for primary dungeon structure. + -- ^ If absent, dungeon materials fall back to classic behaviour. + -- ^ If present, the following two nodes are also used. + node_dungeon_alt = "default:mossycobble", + -- ^ Node used for randomly-distributed alternative structure nodes. + -- ^ If alternative structure nodes are not wanted leave this absent for + -- ^ performance reasons. + node_dungeon_stair = "stairs:stair_cobble", + -- ^ Node used for dungeon stairs. + -- ^ If absent, stairs fall back to 'node_dungeon'. y_max = 31000, y_min = 1, -- ^ Upper and lower limits for biome. diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 67dbee3f5..9562482c8 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -640,8 +640,7 @@ MapgenBasic::~MapgenBasic() } -void MapgenBasic::generateBiomes(MgStoneType *mgstone_type, - content_t *biome_stone) +void MapgenBasic::generateBiomes() { // can't generate biomes without a biome generator! assert(biomegen); @@ -649,8 +648,6 @@ void MapgenBasic::generateBiomes(MgStoneType *mgstone_type, const v3s16 &em = vm->m_area.getExtent(); u32 index = 0; - MgStoneType stone_type = MGSTONE_OTHER; - content_t c_biome_stone = c_stone; noise_filler_depth->perlinMap2D(node_min.X, node_min.Z); @@ -705,17 +702,6 @@ void MapgenBasic::generateBiomes(MgStoneType *mgstone_type, depth_water_top = biome->depth_water_top; depth_riverbed = biome->depth_riverbed; biome_y_min = biome->min_pos.Y; - - // Detect stone type for dungeons during every biome calculation. - // If none detected the last selected biome stone is chosen. - if (biome->c_stone == c_stone) - stone_type = MGSTONE_STONE; - else if (biome->c_stone == c_desert_stone) - stone_type = MGSTONE_DESERT_STONE; - else if (biome->c_stone == c_sandstone) - stone_type = MGSTONE_SANDSTONE; - - c_biome_stone = biome->c_stone; } if (c == c_stone) { @@ -776,9 +762,6 @@ void MapgenBasic::generateBiomes(MgStoneType *mgstone_type, VoxelArea::add_y(em, vi, -1); } } - - *mgstone_type = stone_type; - *biome_stone = c_biome_stone; } @@ -878,16 +861,18 @@ bool MapgenBasic::generateCaverns(s16 max_stone_y) } -void MapgenBasic::generateDungeons(s16 max_stone_y, - MgStoneType stone_type, content_t biome_stone) +void MapgenBasic::generateDungeons(s16 max_stone_y) { if (max_stone_y < node_min.Y) return; + // Get biome at mapchunk midpoint + v3s16 chunk_mid = node_min + (node_max - node_min) / v3s16(2, 2, 2); + Biome *biome = (Biome *)biomegen->calcBiomeAtPoint(chunk_mid); + DungeonParams dp; dp.seed = seed; - dp.only_in_ground = true; dp.corridor_len_min = 1; dp.corridor_len_max = 13; @@ -899,9 +884,27 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, dp.np_density = nparams_dungeon_density; dp.np_alt_wall = nparams_dungeon_alt_wall; - switch (stone_type) { - default: - case MGSTONE_STONE: + // Biome-defined dungeon nodes + if (biome->c_dungeon != CONTENT_IGNORE) { + dp.c_wall = biome->c_dungeon; + // If 'node_dungeon_alt' is not defined by biome, it and dp.c_alt_wall + // become CONTENT_IGNORE which skips the alt wall node placement loop in + // dungeongen.cpp. + dp.c_alt_wall = biome->c_dungeon_alt; + // Stairs fall back to 'c_dungeon' if not defined by biome + dp.c_stair = (biome->c_dungeon_stair != CONTENT_IGNORE) ? + biome->c_dungeon_stair : biome->c_dungeon; + + 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; + + // Otherwise classic behaviour + } else if (biome->c_stone == c_stone) { dp.c_wall = c_cobble; dp.c_alt_wall = c_mossycobble; dp.c_stair = c_stair_cobble; @@ -913,8 +916,8 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, 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: + + } else if (biome->c_stone == c_desert_stone) { dp.c_wall = c_desert_stone; dp.c_alt_wall = CONTENT_IGNORE; dp.c_stair = c_stair_desert_stone; @@ -926,8 +929,8 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, 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: + + } else if (biome->c_stone == c_sandstone) { dp.c_wall = c_sandstonebrick; dp.c_alt_wall = CONTENT_IGNORE; dp.c_stair = c_stair_sandstone_block; @@ -939,20 +942,20 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, dp.room_size_large_min = v3s16(10, 8, 10); dp.room_size_large_max = v3s16(18, 16, 18); dp.notifytype = GENNOTIFY_DUNGEON; - break; - case MGSTONE_OTHER: - dp.c_wall = biome_stone; - dp.c_alt_wall = biome_stone; - dp.c_stair = biome_stone; + + // Fallback to using biome 'node_stone' + } else { + dp.c_wall = biome->c_stone; + dp.c_alt_wall = CONTENT_IGNORE; + dp.c_stair = biome->c_stone; 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.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; } DungeonGen dgen(ndef, &gennotify, &dp); diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index 2ebba68ea..51d23cd28 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -77,13 +77,6 @@ enum GenNotifyType { NUM_GENNOTIFY_TYPES }; -enum MgStoneType { - MGSTONE_STONE, - MGSTONE_DESERT_STONE, - MGSTONE_SANDSTONE, - MGSTONE_OTHER, -}; - struct GenNotifyEvent { GenNotifyType type; v3s16 pos; @@ -247,10 +240,8 @@ public: virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth); virtual bool generateCaverns(s16 max_stone_y); - virtual void generateDungeons(s16 max_stone_y, - MgStoneType stone_type, content_t biome_stone); - virtual void generateBiomes(MgStoneType *mgstone_type, - content_t *biome_stone); + virtual void generateDungeons(s16 max_stone_y); + virtual void generateBiomes(); virtual void dustTopNodes(); protected: diff --git a/src/mapgen/mapgen_carpathian.cpp b/src/mapgen/mapgen_carpathian.cpp index 24f570b64..37c769693 100644 --- a/src/mapgen/mapgen_carpathian.cpp +++ b/src/mapgen/mapgen_carpathian.cpp @@ -248,10 +248,7 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - - MgStoneType mgstone_type; - content_t biome_stone; - generateBiomes(&mgstone_type, &biome_stone); + generateBiomes(); // Generate caverns, tunnels and classic caves if (flags & MG_CAVES) { @@ -272,7 +269,7 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data) // Generate dungeons if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) - generateDungeons(stone_surface_max_y, mgstone_type, biome_stone); + generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen/mapgen_flat.cpp b/src/mapgen/mapgen_flat.cpp index 57d358e86..60b30137b 100644 --- a/src/mapgen/mapgen_flat.cpp +++ b/src/mapgen/mapgen_flat.cpp @@ -196,17 +196,14 @@ void MapgenFlat::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - - MgStoneType mgstone_type; - content_t biome_stone; - generateBiomes(&mgstone_type, &biome_stone); + generateBiomes(); if (flags & MG_CAVES) generateCaves(stone_surface_max_y, large_cave_depth); if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) - generateDungeons(stone_surface_max_y, mgstone_type, biome_stone); + generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen/mapgen_fractal.cpp b/src/mapgen/mapgen_fractal.cpp index 45526b138..10397f7b8 100644 --- a/src/mapgen/mapgen_fractal.cpp +++ b/src/mapgen/mapgen_fractal.cpp @@ -207,17 +207,14 @@ void MapgenFractal::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - - MgStoneType mgstone_type; - content_t biome_stone; - generateBiomes(&mgstone_type, &biome_stone); + generateBiomes(); if (flags & MG_CAVES) generateCaves(stone_surface_max_y, large_cave_depth); if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) - generateDungeons(stone_surface_max_y, mgstone_type, biome_stone); + generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen/mapgen_v5.cpp b/src/mapgen/mapgen_v5.cpp index 2e788e8f1..aabc86c4d 100644 --- a/src/mapgen/mapgen_v5.cpp +++ b/src/mapgen/mapgen_v5.cpp @@ -207,10 +207,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - - MgStoneType mgstone_type; - content_t biome_stone; - generateBiomes(&mgstone_type, &biome_stone); + generateBiomes(); // Generate caverns, tunnels and classic caves if (flags & MG_CAVES) { @@ -231,7 +228,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) // Generate dungeons and desert temples if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) - generateDungeons(stone_surface_max_y, mgstone_type, biome_stone); + generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen/mapgen_v7.cpp b/src/mapgen/mapgen_v7.cpp index a99a50f29..c83a5105d 100644 --- a/src/mapgen/mapgen_v7.cpp +++ b/src/mapgen/mapgen_v7.cpp @@ -311,10 +311,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - - MgStoneType mgstone_type; - content_t biome_stone; - generateBiomes(&mgstone_type, &biome_stone); + generateBiomes(); // Generate caverns, tunnels and classic caves if (flags & MG_CAVES) { @@ -335,7 +332,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) // Generate dungeons if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) - generateDungeons(stone_surface_max_y, mgstone_type, biome_stone); + generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen/mapgen_valleys.cpp b/src/mapgen/mapgen_valleys.cpp index f4c3c7b79..af8845615 100644 --- a/src/mapgen/mapgen_valleys.cpp +++ b/src/mapgen/mapgen_valleys.cpp @@ -242,9 +242,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) updateHeightmap(node_min, node_max); // Place biome-specific nodes and build biomemap - MgStoneType mgstone_type; - content_t biome_stone; - generateBiomes(&mgstone_type, &biome_stone); + generateBiomes(); // Cave creation. if (flags & MG_CAVES) @@ -253,7 +251,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) // Dungeon creation if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) - generateDungeons(stone_surface_max_y, mgstone_type, biome_stone); + generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen/mg_biome.cpp b/src/mapgen/mg_biome.cpp index 584dea9c4..16e276b53 100644 --- a/src/mapgen/mg_biome.cpp +++ b/src/mapgen/mg_biome.cpp @@ -63,6 +63,9 @@ BiomeManager::BiomeManager(Server *server) : b->m_nodenames.emplace_back("mapgen_stone"); b->m_nodenames.emplace_back("ignore"); b->m_nodenames.emplace_back("ignore"); + b->m_nodenames.emplace_back("ignore"); + b->m_nodenames.emplace_back("ignore"); + b->m_nodenames.emplace_back("ignore"); m_ndef->pendNodeResolve(b); add(b); @@ -314,13 +317,16 @@ Biome *BiomeGenOriginal::calcBiomeFromNoise(float heat, float humidity, v3s16 po void Biome::resolveNodeNames() { - getIdFromNrBacklog(&c_top, "mapgen_stone", CONTENT_AIR); - getIdFromNrBacklog(&c_filler, "mapgen_stone", CONTENT_AIR); - getIdFromNrBacklog(&c_stone, "mapgen_stone", CONTENT_AIR); - getIdFromNrBacklog(&c_water_top, "mapgen_water_source", CONTENT_AIR); - getIdFromNrBacklog(&c_water, "mapgen_water_source", CONTENT_AIR); - getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR); - getIdFromNrBacklog(&c_riverbed, "mapgen_stone", CONTENT_AIR); - getIdFromNrBacklog(&c_dust, "ignore", CONTENT_IGNORE); - getIdFromNrBacklog(&c_cave_liquid, "ignore", CONTENT_IGNORE); + getIdFromNrBacklog(&c_top, "mapgen_stone", CONTENT_AIR); + getIdFromNrBacklog(&c_filler, "mapgen_stone", CONTENT_AIR); + getIdFromNrBacklog(&c_stone, "mapgen_stone", CONTENT_AIR); + getIdFromNrBacklog(&c_water_top, "mapgen_water_source", CONTENT_AIR); + getIdFromNrBacklog(&c_water, "mapgen_water_source", CONTENT_AIR); + getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR); + getIdFromNrBacklog(&c_riverbed, "mapgen_stone", CONTENT_AIR); + getIdFromNrBacklog(&c_dust, "ignore", CONTENT_IGNORE); + getIdFromNrBacklog(&c_cave_liquid, "ignore", CONTENT_IGNORE); + getIdFromNrBacklog(&c_dungeon, "ignore", CONTENT_IGNORE); + getIdFromNrBacklog(&c_dungeon_alt, "ignore", CONTENT_IGNORE); + getIdFromNrBacklog(&c_dungeon_stair, "ignore", CONTENT_IGNORE); } diff --git a/src/mapgen/mg_biome.h b/src/mapgen/mg_biome.h index 27b6ebf95..1f60f7bac 100644 --- a/src/mapgen/mg_biome.h +++ b/src/mapgen/mg_biome.h @@ -53,6 +53,9 @@ public: content_t c_riverbed; content_t c_dust; content_t c_cave_liquid; + content_t c_dungeon; + content_t c_dungeon_alt; + content_t c_dungeon_stair; s16 depth_top; s16 depth_filler; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 03a2b3eea..6fe0d322e 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -397,15 +397,18 @@ Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef) getintfield(L, index, "y_max", b->max_pos.Y); std::vector &nn = b->m_nodenames; - nn.push_back(getstringfield_default(L, index, "node_top", "")); - nn.push_back(getstringfield_default(L, index, "node_filler", "")); - nn.push_back(getstringfield_default(L, index, "node_stone", "")); - nn.push_back(getstringfield_default(L, index, "node_water_top", "")); - nn.push_back(getstringfield_default(L, index, "node_water", "")); - nn.push_back(getstringfield_default(L, index, "node_river_water", "")); - nn.push_back(getstringfield_default(L, index, "node_riverbed", "")); - nn.push_back(getstringfield_default(L, index, "node_dust", "")); - nn.push_back(getstringfield_default(L, index, "node_cave_liquid", "")); + nn.push_back(getstringfield_default(L, index, "node_top", "")); + nn.push_back(getstringfield_default(L, index, "node_filler", "")); + nn.push_back(getstringfield_default(L, index, "node_stone", "")); + nn.push_back(getstringfield_default(L, index, "node_water_top", "")); + nn.push_back(getstringfield_default(L, index, "node_water", "")); + nn.push_back(getstringfield_default(L, index, "node_river_water", "")); + nn.push_back(getstringfield_default(L, index, "node_riverbed", "")); + nn.push_back(getstringfield_default(L, index, "node_dust", "")); + nn.push_back(getstringfield_default(L, index, "node_cave_liquid", "")); + nn.push_back(getstringfield_default(L, index, "node_dungeon", "")); + nn.push_back(getstringfield_default(L, index, "node_dungeon_alt", "")); + nn.push_back(getstringfield_default(L, index, "node_dungeon_stair", "")); ndef->pendNodeResolve(b); return b;