aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt12
-rw-r--r--src/mapgen/cavegen.cpp53
-rw-r--r--src/mapgen/cavegen.h2
-rw-r--r--src/mapgen/mg_biome.cpp3
-rw-r--r--src/mapgen/mg_biome.h2
-rw-r--r--src/script/lua_api/l_mapgen.cpp11
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", ""));