diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f348f5103..30f4d87df 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3723,6 +3723,9 @@ Definition tables ### Biome definition (`register_biome`) +**Note** +The biome API is still in an experimental phase and subject to change. + { name = "tundra", node_dust = "default:snow", @@ -3742,6 +3745,9 @@ Definition tables -- ^ Node that replaces all seawater nodes not in the defined surface layer. node_river_water = "default:ice", -- ^ Node that replaces river water in mapgens that use default:river_water. + node_riverbed = "default:gravel", + depth_riverbed = 2, + -- ^ Node placed under river water and thickness of this layer. y_min = 1, y_max = 31000, -- ^ Lower and upper limits for biome. diff --git a/src/mapgen.cpp b/src/mapgen.cpp index b5c48a471..66892a574 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -536,13 +536,15 @@ MgStoneType MapgenBasic::generateBiomes() u16 depth_top = 0; u16 base_filler = 0; u16 depth_water_top = 0; + u16 depth_riverbed = 0; u32 vi = vm->m_area.index(x, node_max.Y, z); // Check node at base of mapchunk above, either a node of a previously // generated mapchunk or if not, a node of overgenerated base terrain. content_t c_above = vm->m_data[vi + em.X].getContent(); bool air_above = c_above == CONTENT_AIR; - bool water_above = (c_above == c_water_source || c_above == c_river_water_source); + bool river_water_above = c_above == c_river_water_source; + bool water_above = c_above == c_water_source || river_water_above; // If there is air or water above enable top/filler placement, otherwise force // nplaced to stone level by setting a number exceeding any possible filler depth. @@ -564,10 +566,11 @@ MgStoneType MapgenBasic::generateBiomes() biome = biomegen->getBiomeAtIndex(index, y); depth_top = biome->depth_top; - base_filler = MYMAX(depth_top - + biome->depth_filler - + noise_filler_depth->result[index], 0.f); + base_filler = MYMAX(depth_top + + biome->depth_filler + + noise_filler_depth->result[index], 0.f); depth_water_top = biome->depth_water_top; + depth_riverbed = biome->depth_riverbed; // Detect stone type for dungeons during every biome calculation. // This is more efficient than detecting per-node and will not @@ -590,7 +593,15 @@ MgStoneType MapgenBasic::generateBiomes() || c_below == c_river_water_source) nplaced = U16_MAX; - if (nplaced < depth_top) { + if (river_water_above) { + if (nplaced < depth_riverbed) { + vm->m_data[vi] = MapNode(biome->c_riverbed); + nplaced++; + } else { + nplaced = U16_MAX; // Disable top/filler placement + river_water_above = false; + } + } else if (nplaced < depth_top) { vm->m_data[vi] = MapNode(biome->c_top); nplaced++; } else if (nplaced < base_filler) { @@ -610,9 +621,10 @@ MgStoneType MapgenBasic::generateBiomes() water_above = true; } else if (c == c_river_water_source) { vm->m_data[vi] = MapNode(biome->c_river_water); - nplaced = depth_top; // Enable filler placement for next surface + nplaced = 0; // Enable riverbed placement for next surface air_above = false; water_above = true; + river_water_above = true; } else if (c == CONTENT_AIR) { nplaced = 0; // Enable top/filler placement for next surface air_above = true; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 2cd733d36..6581b792f 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -114,11 +114,6 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * // Resolve content to be used c_lava_source = ndef->getId("mapgen_lava_source"); - c_sand = ndef->getId("mapgen_sand"); - - // Fall back to more basic content if not defined - if (c_sand == CONTENT_IGNORE) - c_sand = c_stone; } @@ -493,7 +488,6 @@ int MapgenValleys::generateTerrain() MapNode n_air(CONTENT_AIR); MapNode n_river_water(c_river_water_source); - MapNode n_sand(c_sand); MapNode n_stone(c_stone); MapNode n_water(c_water_source); @@ -537,10 +531,7 @@ int MapgenValleys::generateTerrain() float surface_delta = (float)y - surface_y; bool river = y + 1 < river_y; - if (fabs(surface_delta) <= 0.5f && y > water_level && river) { - // river bottom - vm->m_data[index_data] = n_sand; - } else if (slope * fill > surface_delta) { + if (slope * fill > surface_delta) { // ground vm->m_data[index_data] = n_stone; if (y > heightmap[index_2d]) @@ -553,7 +544,7 @@ int MapgenValleys::generateTerrain() } else if (river) { // river vm->m_data[index_data] = n_river_water; - } else { + } else { // air vm->m_data[index_data] = n_air; } } diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp index df728af33..78034bf6c 100644 --- a/src/mg_biome.cpp +++ b/src/mg_biome.cpp @@ -46,6 +46,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef) : b->depth_top = 0; b->depth_filler = -MAX_MAP_GENERATION_LIMIT; b->depth_water_top = 0; + b->depth_riverbed = 0; b->y_min = -MAX_MAP_GENERATION_LIMIT; b->y_max = MAX_MAP_GENERATION_LIMIT; b->heat_point = 0.0; @@ -57,6 +58,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef) : b->m_nodenames.push_back("mapgen_water_source"); b->m_nodenames.push_back("mapgen_water_source"); b->m_nodenames.push_back("mapgen_river_water_source"); + b->m_nodenames.push_back("mapgen_stone"); b->m_nodenames.push_back("ignore"); m_ndef->pendNodeResolve(b); @@ -237,5 +239,6 @@ void Biome::resolveNodeNames() 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); } diff --git a/src/mg_biome.h b/src/mg_biome.h index 568d0b1ac..eb0a18a2f 100644 --- a/src/mg_biome.h +++ b/src/mg_biome.h @@ -54,11 +54,13 @@ public: content_t c_water_top; content_t c_water; content_t c_river_water; + content_t c_riverbed; content_t c_dust; s16 depth_top; s16 depth_filler; s16 depth_water_top; + s16 depth_riverbed; s16 y_min; s16 y_max; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 6baf217af..dc188f8a4 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -378,6 +378,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) b->depth_top = getintfield_default(L, index, "depth_top", 0); b->depth_filler = getintfield_default(L, index, "depth_filler", -31000); b->depth_water_top = getintfield_default(L, index, "depth_water_top", 0); + b->depth_riverbed = getintfield_default(L, index, "depth_riverbed", 0); b->y_min = getintfield_default(L, index, "y_min", -31000); b->y_max = getintfield_default(L, index, "y_max", 31000); b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f); @@ -391,6 +392,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) 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", "")); ndef->pendNodeResolve(b);