diff options
-rw-r--r-- | doc/lua_api.txt | 12 | ||||
-rw-r--r-- | src/mapgen/cavegen.cpp | 53 | ||||
-rw-r--r-- | src/mapgen/cavegen.h | 2 | ||||
-rw-r--r-- | src/mapgen/mg_biome.cpp | 3 | ||||
-rw-r--r-- | src/mapgen/mg_biome.h | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_mapgen.cpp | 11 |
6 files changed, 52 insertions, 31 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f72b87625..f29b7d439 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6510,10 +6510,14 @@ Used by `minetest.register_biome`. depth_riverbed = 2, -- Node placed under river water and thickness of this layer - node_cave_liquid = "default:water_source", - -- 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_cave_liquid = "default:lava_source", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + -- Nodes placed inside 50% of the medium size caves. + -- Multiple nodes can be specified, each cave will use a randomly + -- chosen node from the list. + -- If this field is left out or 'nil', cave liquids fall back to + -- classic behaviour of lava and water distributed using 3D noise. + -- For no cave liquid, specify "air". node_dungeon = "default:cobble", -- Node used for primary dungeon structure. diff --git a/src/mapgen/cavegen.cpp b/src/mapgen/cavegen.cpp index e54d76e08..4fa3e009d 100644 --- a/src/mapgen/cavegen.cpp +++ b/src/mapgen/cavegen.cpp @@ -321,9 +321,26 @@ void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, this->ystride = nmax.X - nmin.X + 1; + flooded = ps->range(1, 2) == 2; + + // If flooded: + // Get biome at mapchunk midpoint. If cave liquid defined for biome, use it. + // If defined liquid is "air", disable 'flooded' to avoid placing "air". + use_biome_liquid = false; + if (flooded && bmgn) { + v3s16 midp = node_min + (node_max - node_min) / v3s16(2, 2, 2); + Biome *biome = (Biome *)bmgn->getBiomeAtPoint(midp); + if (biome->c_cave_liquid[0] != CONTENT_IGNORE) { + use_biome_liquid = true; + c_biome_liquid = + biome->c_cave_liquid[ps->range(0, biome->c_cave_liquid.size() - 1)]; + if (c_biome_liquid == CONTENT_AIR) + flooded = false; + } + } + // Set initial parameters from randomness int dswitchint = ps->range(1, 14); - flooded = ps->range(1, 2) == 2; if (large_cave) { part_max_length_rs = ps->range(2, 4); @@ -502,31 +519,19 @@ void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) fp.Z += 0.1f * ps->range(-10, 10); v3s16 cp(fp.X, fp.Y, fp.Z); - // Get biome at 'cp + of', the absolute centre point of this route - v3s16 cpabs = cp + of; + // Choose cave liquid MapNode liquidnode = CONTENT_IGNORE; - if (bmgn) { - Biome *biome = nullptr; - if (cpabs.X < node_min.X || cpabs.X > node_max.X || - cpabs.Z < node_min.Z || cpabs.Z > node_max.Z) - // Point is outside heat and humidity noise maps so use point noise - // calculations. - biome = (Biome *)bmgn->calcBiomeAtPoint(cpabs); - else - // Point is inside heat and humidity noise maps so use them - biome = (Biome *)bmgn->getBiomeAtPoint(cpabs); - - if (biome->c_cave_liquid != CONTENT_IGNORE) - liquidnode = biome->c_cave_liquid; - } - - if (liquidnode == CONTENT_IGNORE) { - // Fallback to classic behaviour using point 'startp' - float nval = NoisePerlin3D(np_caveliquids, startp.X, - startp.Y, startp.Z, seed); - liquidnode = (nval < 0.40f && node_max.Y < lava_depth) ? - lavanode : waternode; + if (flooded) { + if (use_biome_liquid) { + liquidnode = c_biome_liquid; + } else { + // If cave liquid not defined by biome, fallback to old hardcoded behaviour + float nval = NoisePerlin3D(np_caveliquids, startp.X, + startp.Y, startp.Z, seed); + liquidnode = (nval < 0.40f && node_max.Y < lava_depth) ? + lavanode : waternode; + } } s16 d0 = -rs / 2; diff --git a/src/mapgen/cavegen.h b/src/mapgen/cavegen.h index 7b7be6219..f5234a671 100644 --- a/src/mapgen/cavegen.h +++ b/src/mapgen/cavegen.h @@ -133,6 +133,7 @@ public: bool large_cave; bool large_cave_is_flat; bool flooded; + bool use_biome_liquid; v3s16 node_min; v3s16 node_max; @@ -150,6 +151,7 @@ public: content_t c_water_source; content_t c_lava_source; + content_t c_biome_liquid; // ndef is a mandatory parameter. // If gennotify is NULL, generation events are not logged. diff --git a/src/mapgen/mg_biome.cpp b/src/mapgen/mg_biome.cpp index 7f717011c..345bc8c6a 100644 --- a/src/mapgen/mg_biome.cpp +++ b/src/mapgen/mg_biome.cpp @@ -63,6 +63,7 @@ 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_nnlistsizes.push_back(1); b->m_nodenames.emplace_back("ignore"); b->m_nodenames.emplace_back("ignore"); b->m_nodenames.emplace_back("ignore"); @@ -330,7 +331,7 @@ void Biome::resolveNodeNames() getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR, false); getIdFromNrBacklog(&c_riverbed, "mapgen_stone", CONTENT_AIR, false); getIdFromNrBacklog(&c_dust, "ignore", CONTENT_IGNORE, false); - getIdFromNrBacklog(&c_cave_liquid, "ignore", CONTENT_IGNORE, false); + getIdsFromNrBacklog(&c_cave_liquid); getIdFromNrBacklog(&c_dungeon, "ignore", CONTENT_IGNORE, false); getIdFromNrBacklog(&c_dungeon_alt, "ignore", CONTENT_IGNORE, false); getIdFromNrBacklog(&c_dungeon_stair, "ignore", CONTENT_IGNORE, false); diff --git a/src/mapgen/mg_biome.h b/src/mapgen/mg_biome.h index 1f60f7bac..ee148adbc 100644 --- a/src/mapgen/mg_biome.h +++ b/src/mapgen/mg_biome.h @@ -52,7 +52,7 @@ public: content_t c_river_water; content_t c_riverbed; content_t c_dust; - content_t c_cave_liquid; + std::vector<content_t> c_cave_liquid; content_t c_dungeon; content_t c_dungeon_alt; content_t c_dungeon_stair; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 92ed4377e..cb1dc1fff 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -405,7 +405,16 @@ Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef) 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", "")); + + size_t nnames = getstringlistfield(L, index, "node_cave_liquid", &nn); + // If no cave liquids defined, set list to "ignore" to trigger old hardcoded + // cave liquid behaviour. + if (nnames == 0) { + nn.push_back("ignore"); + nnames = 1; + } + b->m_nnlistsizes.push_back(nnames); + 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", "")); |