X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fscript%2Flua_api%2Fl_mapgen.cpp;h=e7e002c160fc439e374929403cbf5aa927fa122b;hb=cfef466d4ef2eee5586bbd8afacc64e4a1939d88;hp=7adb6a534d70d76e9de43952ff0309ebff0b6314;hpb=d69ef6acd386ccfd5ff456002591b97b92a26956;p=oweals%2Fminetest.git diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 7adb6a534..e7e002c16 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -27,23 +27,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server.h" #include "environment.h" #include "emerge.h" -#include "mg_biome.h" -#include "mg_ore.h" -#include "mg_decoration.h" -#include "mg_schematic.h" -#include "mapgen_v5.h" -#include "mapgen_v7.h" +#include "mapgen/mg_biome.h" +#include "mapgen/mg_ore.h" +#include "mapgen/mg_decoration.h" +#include "mapgen/mg_schematic.h" +#include "mapgen/mapgen_v5.h" +#include "mapgen/mapgen_v7.h" #include "filesys.h" #include "settings.h" #include "log.h" struct EnumString ModApiMapgen::es_BiomeTerrainType[] = { - {BIOME_NORMAL, "normal"}, - {BIOME_LIQUID, "liquid"}, - {BIOME_NETHER, "nether"}, - {BIOME_AETHER, "aether"}, - {BIOME_FLAT, "flat"}, + {BIOMETYPE_NORMAL, "normal"}, {0, NULL}, }; @@ -73,6 +69,7 @@ struct EnumString ModApiMapgen::es_OreType[] = {ORE_PUFF, "puff"}, {ORE_BLOB, "blob"}, {ORE_VEIN, "vein"}, + {ORE_STRATUM, "stratum"}, {0, NULL}, }; @@ -98,16 +95,16 @@ ObjDef *get_objdef(lua_State *L, int index, ObjDefManager *objmgr); Biome *get_or_load_biome(lua_State *L, int index, BiomeManager *biomemgr); -Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef); +Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef); size_t get_biome_list(lua_State *L, int index, - BiomeManager *biomemgr, std::set *biome_id_list); + BiomeManager *biomemgr, std::unordered_set *biome_id_list); Schematic *get_or_load_schematic(lua_State *L, int index, SchematicManager *schemmgr, StringMap *replace_names); -Schematic *load_schematic(lua_State *L, int index, INodeDefManager *ndef, +Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef, StringMap *replace_names); Schematic *load_schematic_from_def(lua_State *L, int index, - INodeDefManager *ndef, StringMap *replace_names); + const NodeDefManager *ndef, StringMap *replace_names); bool read_schematic_def(lua_State *L, int index, Schematic *schem, std::vector *names); @@ -159,7 +156,7 @@ Schematic *get_or_load_schematic(lua_State *L, int index, } -Schematic *load_schematic(lua_State *L, int index, INodeDefManager *ndef, +Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef, StringMap *replace_names) { if (index < 0) @@ -195,7 +192,7 @@ Schematic *load_schematic(lua_State *L, int index, INodeDefManager *ndef, Schematic *load_schematic_from_def(lua_State *L, int index, - INodeDefManager *ndef, StringMap *replace_names) + const NodeDefManager *ndef, StringMap *replace_names) { Schematic *schem = SchematicManager::create(SCHEMATIC_NORMAL); @@ -244,7 +241,7 @@ bool read_schematic_def(lua_State *L, int index, schem->schemdata = new MapNode[numnodes]; size_t names_base = names->size(); - std::map name_id_map; + std::unordered_map name_id_map; u32 i = 0; for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) { @@ -266,7 +263,7 @@ bool read_schematic_def(lua_State *L, int index, u8 param2 = getintfield_default(L, -1, "param2", 0); //// Find or add new nodename-to-ID mapping - std::map::iterator it = name_id_map.find(name); + std::unordered_map::iterator it = name_id_map.find(name); content_t name_index; if (it != name_id_map.end()) { name_index = it->second; @@ -325,14 +322,22 @@ void read_schematic_replacements(lua_State *L, int index, StringMap *replace_nam if (lua_istable(L, -1)) { // Old {{"x", "y"}, ...} format lua_rawgeti(L, -1, 1); + if (!lua_isstring(L, -1)) + throw LuaError("schematics: replace_from field is not a string"); replace_from = lua_tostring(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); + if (!lua_isstring(L, -1)) + throw LuaError("schematics: replace_to field is not a string"); replace_to = lua_tostring(L, -1); lua_pop(L, 1); } else { // New {x = "y", ...} format + if (!lua_isstring(L, -2)) + throw LuaError("schematics: replace_from field is not a string"); replace_from = lua_tostring(L, -2); + if (!lua_isstring(L, -1)) + throw LuaError("schematics: replace_to field is not a string"); replace_to = lua_tostring(L, -1); } @@ -365,33 +370,54 @@ Biome *get_or_load_biome(lua_State *L, int index, BiomeManager *biomemgr) } -Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) +Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef) { if (!lua_istable(L, index)) return NULL; BiomeType biometype = (BiomeType)getenumfield(L, index, "type", - ModApiMapgen::es_BiomeTerrainType, BIOME_NORMAL); + ModApiMapgen::es_BiomeTerrainType, BIOMETYPE_NORMAL); Biome *b = BiomeManager::create(biometype); b->name = getstringfield_default(L, index, "name", ""); 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->y_min = getintfield_default(L, index, "y_min", -31000); - b->y_max = getintfield_default(L, index, "y_max", 31000); + b->depth_riverbed = getintfield_default(L, index, "depth_riverbed", 0); b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f); b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f); - b->flags = 0; //reserved + b->vertical_blend = getintfield_default(L, index, "vertical_blend", 0); + b->flags = 0; // reserved + + b->min_pos = getv3s16field_default( + L, index, "min_pos", v3s16(-31000, -31000, -31000)); + getintfield(L, index, "y_min", b->min_pos.Y); + b->max_pos = getv3s16field_default( + L, index, "max_pos", v3s16(31000, 31000, 31000)); + 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_dust", "")); + 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", "")); + + 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.emplace_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", "")); ndef->pendNodeResolve(b); return b; @@ -399,7 +425,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) size_t get_biome_list(lua_State *L, int index, - BiomeManager *biomemgr, std::set *biome_id_list) + BiomeManager *biomemgr, std::unordered_set *biome_id_list) { if (index < 0) index = lua_gettop(L) + 1 + index; @@ -417,7 +443,7 @@ size_t get_biome_list(lua_State *L, int index, if (is_single) { Biome *biome = get_or_load_biome(L, index, biomemgr); if (!biome) { - errorstream << "get_biome_list: failed to get biome '" + infostream << "get_biome_list: failed to get biome '" << (lua_isstring(L, index) ? lua_tostring(L, index) : "") << "'." << std::endl; return 1; @@ -436,7 +462,7 @@ size_t get_biome_list(lua_State *L, int index, Biome *biome = get_or_load_biome(L, -1, biomemgr); if (!biome) { fail_count++; - errorstream << "get_biome_list: failed to get biome '" + infostream << "get_biome_list: failed to get biome '" << (lua_isstring(L, -1) ? lua_tostring(L, -1) : "") << "'" << std::endl; continue; @@ -451,7 +477,7 @@ size_t get_biome_list(lua_State *L, int index, /////////////////////////////////////////////////////////////////////////////// // get_biome_id(biomename) -// returns the biome id used in biomemap +// returns the biome id as used in biomemap and returned by 'get_biome_data()' int ModApiMapgen::l_get_biome_id(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -461,16 +487,181 @@ int ModApiMapgen::l_get_biome_id(lua_State *L) return 0; BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; - if (!bmgr) return 0; Biome *biome = (Biome *)bmgr->getByName(biome_str); + if (!biome || biome->index == OBJDEF_INVALID_INDEX) + return 0; + + lua_pushinteger(L, biome->index); + + return 1; +} + + +// get_biome_name(biome_id) +// returns the biome name string +int ModApiMapgen::l_get_biome_name(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + int biome_id = luaL_checkinteger(L, 1); + + BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + if (!bmgr) + return 0; + + Biome *b = (Biome *)bmgr->getRaw(biome_id); + lua_pushstring(L, b->name.c_str()); + + return 1; +} + + +// get_heat(pos) +// returns the heat at the position +int ModApiMapgen::l_get_heat(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + + NoiseParams np_heat; + NoiseParams np_heat_blend; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + if (!settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat", + &np_heat) || + !settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat_blend", + &np_heat_blend)) + return 0; + + std::string value; + if (!settingsmgr->getMapSetting("seed", &value)) + return 0; + std::istringstream ss(value); + u64 seed; + ss >> seed; + + BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + if (!bmgr) + return 0; + + float heat = bmgr->getHeatAtPosOriginal(pos, np_heat, np_heat_blend, seed); + if (!heat) + return 0; + + lua_pushnumber(L, heat); + + return 1; +} + + +// get_humidity(pos) +// returns the humidity at the position +int ModApiMapgen::l_get_humidity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + + NoiseParams np_humidity; + NoiseParams np_humidity_blend; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + if (!settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity", + &np_humidity) || + !settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity_blend", + &np_humidity_blend)) + return 0; + + std::string value; + if (!settingsmgr->getMapSetting("seed", &value)) + return 0; + std::istringstream ss(value); + u64 seed; + ss >> seed; + + BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + if (!bmgr) + return 0; + + float humidity = bmgr->getHumidityAtPosOriginal(pos, np_humidity, + np_humidity_blend, seed); + if (!humidity) + return 0; + + lua_pushnumber(L, humidity); + + return 1; +} + + +// get_biome_data(pos) +// returns a table containing the biome id, heat and humidity at the position +int ModApiMapgen::l_get_biome_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + + NoiseParams np_heat; + NoiseParams np_heat_blend; + NoiseParams np_humidity; + NoiseParams np_humidity_blend; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + if (!settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat", + &np_heat) || + !settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat_blend", + &np_heat_blend) || + !settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity", + &np_humidity) || + !settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity_blend", + &np_humidity_blend)) + return 0; + + std::string value; + if (!settingsmgr->getMapSetting("seed", &value)) + return 0; + std::istringstream ss(value); + u64 seed; + ss >> seed; + + BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + if (!bmgr) + return 0; + + float heat = bmgr->getHeatAtPosOriginal(pos, np_heat, np_heat_blend, seed); + if (!heat) + return 0; + + float humidity = bmgr->getHumidityAtPosOriginal(pos, np_humidity, + np_humidity_blend, seed); + if (!humidity) + return 0; + + Biome *biome = (Biome *)bmgr->getBiomeFromNoiseOriginal(heat, humidity, pos); if (!biome || biome->index == OBJDEF_INVALID_INDEX) return 0; + lua_newtable(L); + lua_pushinteger(L, biome->index); + lua_setfield(L, -2, "biome"); + + lua_pushnumber(L, heat); + lua_setfield(L, -2, "heat"); + + lua_pushnumber(L, humidity); + lua_setfield(L, -2, "humidity"); return 1; } @@ -528,24 +719,26 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L) return 1; } case MGOBJ_BIOMEMAP: { - if (!mg->biomemap) + if (!mg->biomegen) return 0; lua_newtable(L); for (size_t i = 0; i != maplen; i++) { - lua_pushinteger(L, mg->biomemap[i]); + lua_pushinteger(L, mg->biomegen->biomemap[i]); lua_rawseti(L, -2, i + 1); } return 1; } case MGOBJ_HEATMAP: { - if (!mg->heatmap) + if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL) return 0; + BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen; + lua_newtable(L); for (size_t i = 0; i != maplen; i++) { - lua_pushnumber(L, mg->heatmap[i]); + lua_pushnumber(L, bg->heatmap[i]); lua_rawseti(L, -2, i + 1); } @@ -553,12 +746,14 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L) } case MGOBJ_HUMIDMAP: { - if (!mg->humidmap) + if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL) return 0; + BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen; + lua_newtable(L); for (size_t i = 0; i != maplen; i++) { - lua_pushnumber(L, mg->humidmap[i]); + lua_pushnumber(L, bg->humidmap[i]); lua_rawseti(L, -2, i + 1); } @@ -590,28 +785,62 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L) } +// get_spawn_level(x = num, z = num) +int ModApiMapgen::l_get_spawn_level(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + s16 x = luaL_checkinteger(L, 1); + s16 z = luaL_checkinteger(L, 2); + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + int spawn_level = emerge->getSpawnLevelAtPoint(v2s16(x, z)); + // Unsuitable spawn point + if (spawn_level == MAX_MAP_GENERATION_LIMIT) + return 0; + + // 'findSpawnPos()' in server.cpp adds at least 1 + lua_pushinteger(L, spawn_level + 1); + + return 1; +} + + int ModApiMapgen::l_get_mapgen_params(lua_State *L) { NO_MAP_LOCK_REQUIRED; - MapgenParams *params = &getServer(L)->getEmergeManager()->params; + log_deprecated(L, "get_mapgen_params is deprecated; " + "use get_mapgen_setting instead"); + + std::string value; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; lua_newtable(L); - lua_pushstring(L, params->mg_name.c_str()); + settingsmgr->getMapSetting("mg_name", &value); + lua_pushstring(L, value.c_str()); lua_setfield(L, -2, "mgname"); - lua_pushinteger(L, params->seed); + settingsmgr->getMapSetting("seed", &value); + std::istringstream ss(value); + u64 seed; + ss >> seed; + lua_pushinteger(L, seed); lua_setfield(L, -2, "seed"); - lua_pushinteger(L, params->water_level); + settingsmgr->getMapSetting("water_level", &value); + lua_pushinteger(L, stoi(value, -32768, 32767)); lua_setfield(L, -2, "water_level"); - lua_pushinteger(L, params->chunksize); + settingsmgr->getMapSetting("chunksize", &value); + lua_pushinteger(L, stoi(value, -32768, 32767)); lua_setfield(L, -2, "chunksize"); - std::string flagstr = writeFlagString(params->flags, flagdesc_mapgen, U32_MAX); - lua_pushstring(L, flagstr.c_str()); + settingsmgr->getMapSetting("mg_flags", &value); + lua_pushstring(L, value.c_str()); lua_setfield(L, -2, "flags"); return 1; @@ -624,44 +853,120 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L) { NO_MAP_LOCK_REQUIRED; + log_deprecated(L, "set_mapgen_params is deprecated; " + "use set_mapgen_setting instead"); + if (!lua_istable(L, 1)) return 0; - EmergeManager *emerge = getServer(L)->getEmergeManager(); - if (emerge->isRunning()) - throw LuaError("Cannot set parameters while mapgen is running"); - - MapgenParams *params = &emerge->params; - u32 flags = 0, flagmask = 0; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; lua_getfield(L, 1, "mgname"); - if (lua_isstring(L, -1)) { - params->mg_name = lua_tostring(L, -1); - delete params->sparams; - params->sparams = NULL; - } + if (lua_isstring(L, -1)) + settingsmgr->setMapSetting("mg_name", readParam(L, -1), true); lua_getfield(L, 1, "seed"); if (lua_isnumber(L, -1)) - params->seed = lua_tointeger(L, -1); + settingsmgr->setMapSetting("seed", readParam(L, -1), true); lua_getfield(L, 1, "water_level"); if (lua_isnumber(L, -1)) - params->water_level = lua_tointeger(L, -1); + settingsmgr->setMapSetting("water_level", readParam(L, -1), true); lua_getfield(L, 1, "chunksize"); if (lua_isnumber(L, -1)) - params->chunksize = lua_tointeger(L, -1); + settingsmgr->setMapSetting("chunksize", readParam(L, -1), true); warn_if_field_exists(L, 1, "flagmask", "Deprecated: flags field now includes unset flags."); - lua_getfield(L, 1, "flagmask"); + + lua_getfield(L, 1, "flags"); if (lua_isstring(L, -1)) - params->flags &= ~readFlagString(lua_tostring(L, -1), flagdesc_mapgen, NULL); + settingsmgr->setMapSetting("mg_flags", readParam(L, -1), true); + + return 0; +} + +// get_mapgen_setting(name) +int ModApiMapgen::l_get_mapgen_setting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string value; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + if (!settingsmgr->getMapSetting(name, &value)) + return 0; + + lua_pushstring(L, value.c_str()); + return 1; +} + +// get_mapgen_setting_noiseparams(name) +int ModApiMapgen::l_get_mapgen_setting_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + NoiseParams np; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + if (!settingsmgr->getMapSettingNoiseParams(name, &np)) + return 0; + + push_noiseparams(L, &np); + return 1; +} + +// set_mapgen_setting(name, value, override_meta) +// set mapgen config values +int ModApiMapgen::l_set_mapgen_setting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; - if (getflagsfield(L, 1, "flags", flagdesc_mapgen, &flags, &flagmask)) { - params->flags &= ~flagmask; - params->flags |= flags; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + const char *value = luaL_checkstring(L, 2); + bool override_meta = readParam(L, 3, false); + + if (!settingsmgr->setMapSetting(name, value, override_meta)) { + errorstream << "set_mapgen_setting: cannot set '" + << name << "' after initialization" << std::endl; + } + + return 0; +} + + +// set_mapgen_setting_noiseparams(name, noiseparams, set_default) +// set mapgen config values for noise parameters +int ModApiMapgen::l_set_mapgen_setting_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + + NoiseParams np; + if (!read_noiseparams(L, 2, &np)) { + errorstream << "set_mapgen_setting_noiseparams: cannot set '" << name + << "'; invalid noiseparams table" << std::endl; + return 0; + } + + bool override_meta = readParam(L, 3, false); + + if (!settingsmgr->setMapSettingNoiseParams(name, &np, override_meta)) { + errorstream << "set_mapgen_setting_noiseparams: cannot set '" + << name << "' after initialization" << std::endl; } return 0; @@ -677,10 +982,13 @@ int ModApiMapgen::l_set_noiseparams(lua_State *L) const char *name = luaL_checkstring(L, 1); NoiseParams np; - if (!read_noiseparams(L, 2, &np)) + if (!read_noiseparams(L, 2, &np)) { + errorstream << "set_noiseparams: cannot set '" << name + << "'; invalid noiseparams table" << std::endl; return 0; + } - bool set_default = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : true; + bool set_default = !lua_isboolean(L, 3) || readParam(L, 3); g_settings->setNoiseParams(name, np, set_default); @@ -741,16 +1049,40 @@ int ModApiMapgen::l_get_gen_notify(lua_State *L) lua_newtable(L); int i = 1; - for (std::set::iterator it = emerge->gen_notify_on_deco_ids.begin(); - it != emerge->gen_notify_on_deco_ids.end(); ++it) { - lua_pushnumber(L, *it); - lua_rawseti(L, -2, i); - i++; + for (u32 gen_notify_on_deco_id : emerge->gen_notify_on_deco_ids) { + lua_pushnumber(L, gen_notify_on_deco_id); + lua_rawseti(L, -2, i++); } return 2; } +// get_decoration_id(decoration_name) +// returns the decoration ID as used in gennotify +int ModApiMapgen::l_get_decoration_id(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *deco_str = luaL_checkstring(L, 1); + if (!deco_str) + return 0; + + DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr; + + if (!dmgr) + return 0; + + Decoration *deco = (Decoration *)dmgr->getByName(deco_str); + + if (!deco) + return 0; + + lua_pushinteger(L, deco->index); + + return 1; +} + + // register_biome({lots of stuff}) int ModApiMapgen::l_register_biome(lua_State *L) { @@ -759,8 +1091,8 @@ int ModApiMapgen::l_register_biome(lua_State *L) int index = 1; luaL_checktype(L, index, LUA_TTABLE); - INodeDefManager *ndef = getServer(L)->getNodeDefManager(); - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; Biome *biome = read_biome_def(L, index, ndef); if (!biome) @@ -785,7 +1117,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L) int index = 1; luaL_checktype(L, index, LUA_TTABLE); - INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr; BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr; SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; @@ -800,11 +1132,13 @@ int ModApiMapgen::l_register_decoration(lua_State *L) return 0; } - deco->name = getstringfield_default(L, index, "name", ""); - deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); - deco->y_min = getintfield_default(L, index, "y_min", -31000); - deco->y_max = getintfield_default(L, index, "y_max", 31000); - deco->sidelen = getintfield_default(L, index, "sidelen", 8); + deco->name = getstringfield_default(L, index, "name", ""); + deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); + deco->y_min = getintfield_default(L, index, "y_min", -31000); + deco->y_max = getintfield_default(L, index, "y_max", 31000); + deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); + deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0); + deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; @@ -828,9 +1162,17 @@ int ModApiMapgen::l_register_decoration(lua_State *L) //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, biomemgr, &deco->biomes)) - errorstream << "register_decoration: couldn't get all biomes " << std::endl; + infostream << "register_decoration: couldn't get all biomes " << std::endl; lua_pop(L, 1); + //// Get node name(s) to 'spawn by' + size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames); + deco->m_nnlistsizes.push_back(nnames); + if (nnames == 0 && deco->nspawnby != -1) { + errorstream << "register_decoration: no spawn_by nodes defined," + " but num_spawn_by specified" << std::endl; + } + //// Handle decoration type-specific parameters bool success = false; switch (decotype) { @@ -864,12 +1206,12 @@ int ModApiMapgen::l_register_decoration(lua_State *L) bool read_deco_simple(lua_State *L, DecoSimple *deco) { - size_t nnames; int index = 1; + int param2; + int param2_max; deco->deco_height = getintfield_default(L, index, "height", 1); deco->deco_height_max = getintfield_default(L, index, "height_max", 0); - deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); if (deco->deco_height <= 0) { errorstream << "register_decoration: simple decoration height" @@ -877,22 +1219,27 @@ bool read_deco_simple(lua_State *L, DecoSimple *deco) return false; } - nnames = getstringlistfield(L, index, "decoration", &deco->m_nodenames); + size_t nnames = getstringlistfield(L, index, "decoration", &deco->m_nodenames); deco->m_nnlistsizes.push_back(nnames); + if (nnames == 0) { errorstream << "register_decoration: no decoration nodes " "defined" << std::endl; return false; } - nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames); - deco->m_nnlistsizes.push_back(nnames); - if (nnames == 0 && deco->nspawnby != -1) { - errorstream << "register_decoration: no spawn_by nodes defined," - " but num_spawn_by specified" << std::endl; + param2 = getintfield_default(L, index, "param2", 0); + param2_max = getintfield_default(L, index, "param2_max", 0); + + if (param2 < 0 || param2 > 255 || param2_max < 0 || param2_max > 255) { + errorstream << "register_decoration: param2 or param2_max out of bounds (0-255)" + << std::endl; return false; } + deco->deco_param2 = (u8)param2; + deco->deco_param2_max = (u8)param2_max; + return true; } @@ -927,7 +1274,7 @@ int ModApiMapgen::l_register_ore(lua_State *L) int index = 1; luaL_checktype(L, index, LUA_TTABLE); - INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; @@ -944,10 +1291,19 @@ int ModApiMapgen::l_register_ore(lua_State *L) ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); - ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0); ore->noise = NULL; ore->flags = 0; + //// Get noise_threshold + warn_if_field_exists(L, index, "noise_threshhold", + "Deprecated: new name is \"noise_threshold\"."); + + float nthresh; + if (!getfloatfield(L, index, "noise_threshold", nthresh) && + !getfloatfield(L, index, "noise_threshhold", nthresh)) + nthresh = 0; + ore->nthresh = nthresh; + //// Get y_min/y_max warn_if_field_exists(L, index, "height_min", "Deprecated: new name is \"y_min\"."); @@ -977,7 +1333,7 @@ int ModApiMapgen::l_register_ore(lua_State *L) //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, bmgr, &ore->biomes)) - errorstream << "register_ore: couldn't get all biomes " << std::endl; + infostream << "register_ore: couldn't get all biomes " << std::endl; lua_pop(L, 1); //// Get noise parameters if needed @@ -986,7 +1342,7 @@ int ModApiMapgen::l_register_ore(lua_State *L) ore->flags |= OREFLAG_USE_NOISE; } else if (ore->NEEDS_NOISE) { errorstream << "register_ore: specified ore type requires valid " - "noise parameters" << std::endl; + "'noise_params' parameter" << std::endl; delete ore; return 0; } @@ -1027,6 +1383,19 @@ int ModApiMapgen::l_register_ore(lua_State *L) break; } + case ORE_STRATUM: { + OreStratum *orestratum = (OreStratum *)ore; + + lua_getfield(L, index, "np_stratum_thickness"); + if (read_noiseparams(L, -1, &orestratum->np_stratum_thickness)) + ore->flags |= OREFLAG_USE_NOISE2; + lua_pop(L, 1); + + orestratum->stratum_thickness = getintfield_default(L, index, + "stratum_thickness", 8); + + break; + } default: break; } @@ -1128,7 +1497,7 @@ int ModApiMapgen::l_generate_ores(lua_State *L) EmergeManager *emerge = getServer(L)->getEmergeManager(); Mapgen mg; - mg.seed = emerge->params.seed; + mg.seed = emerge->mgparams->seed; mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; mg.ndef = getServer(L)->getNodeDefManager(); @@ -1154,7 +1523,7 @@ int ModApiMapgen::l_generate_decorations(lua_State *L) EmergeManager *emerge = getServer(L)->getEmergeManager(); Mapgen mg; - mg.seed = emerge->params.seed; + mg.seed = emerge->mgparams->seed; mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; mg.ndef = getServer(L)->getNodeDefManager(); @@ -1177,10 +1546,10 @@ int ModApiMapgen::l_create_schematic(lua_State *L) { MAP_LOCK_REQUIRED; - INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); const char *filename = luaL_checkstring(L, 4); - CHECK_SECURE_PATH_OPTIONAL(L, filename); + CHECK_SECURE_PATH(L, filename, true); Map *map = &(getEnv(L)->getMap()); Schematic schem; @@ -1199,7 +1568,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L) lua_pop(L, 1); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); - prob_list.push_back(std::make_pair(pos, prob)); + prob_list.emplace_back(pos, prob); } lua_pop(L, 1); @@ -1213,7 +1582,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L) if (lua_istable(L, -1)) { s16 ypos = getintfield_default(L, -1, "ypos", 0); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); - slice_prob_list.push_back(std::make_pair(ypos, prob)); + slice_prob_list.emplace_back(ypos, prob); } lua_pop(L, 1); @@ -1237,12 +1606,15 @@ int ModApiMapgen::l_create_schematic(lua_State *L) } -// place_schematic(p, schematic, rotation, replacement) +// place_schematic(p, schematic, rotation, +// replacements, force_placement, flagstring) int ModApiMapgen::l_place_schematic(lua_State *L) { MAP_LOCK_REQUIRED; - Map *map = &(getEnv(L)->getMap()); + GET_ENV_PTR; + + ServerMap *map = &(env->getServerMap()); SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; //// Read position @@ -1250,14 +1622,14 @@ int ModApiMapgen::l_place_schematic(lua_State *L) //// Read rotation int rot = ROTATE_0; - const char *enumstr = lua_tostring(L, 3); - if (enumstr) - string_to_enum(es_Rotation, rot, std::string(enumstr)); + std::string enumstr = readParam(L, 3, ""); + if (!enumstr.empty()) + string_to_enum(es_Rotation, rot, enumstr); //// Read force placement bool force_placement = true; if (lua_isboolean(L, 5)) - force_placement = lua_toboolean(L, 5); + force_placement = readParam(L, 5); //// Read node replacements StringMap replace_names; @@ -1271,12 +1643,66 @@ int ModApiMapgen::l_place_schematic(lua_State *L) return 0; } - schem->placeStructure(map, p, 0, (Rotation)rot, force_placement); + //// Read flags + u32 flags = 0; + read_flags(L, 6, flagdesc_deco, &flags, NULL); + + schem->placeOnMap(map, p, flags, (Rotation)rot, force_placement); lua_pushboolean(L, true); return 1; } + +// place_schematic_on_vmanip(vm, p, schematic, rotation, +// replacements, force_placement, flagstring) +int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + + //// Read VoxelManip object + MMVManip *vm = LuaVoxelManip::checkobject(L, 1)->vm; + + //// Read position + v3s16 p = check_v3s16(L, 2); + + //// Read rotation + int rot = ROTATE_0; + std::string enumstr = readParam(L, 4, ""); + if (!enumstr.empty()) + string_to_enum(es_Rotation, rot, std::string(enumstr)); + + //// Read force placement + bool force_placement = true; + if (lua_isboolean(L, 6)) + force_placement = readParam(L, 6); + + //// Read node replacements + StringMap replace_names; + if (lua_istable(L, 5)) + read_schematic_replacements(L, 5, &replace_names); + + //// Read schematic + Schematic *schem = get_or_load_schematic(L, 3, schemmgr, &replace_names); + if (!schem) { + errorstream << "place_schematic: failed to get schematic" << std::endl; + return 0; + } + + //// Read flags + u32 flags = 0; + read_flags(L, 7, flagdesc_deco, &flags, NULL); + + bool schematic_did_fit = schem->placeOnVManip( + vm, p, flags, (Rotation)rot, force_placement); + + lua_pushboolean(L, schematic_did_fit); + return 1; +} + + // serialize_schematic(schematic, format, options={...}) int ModApiMapgen::l_serialize_schematic(lua_State *L) { @@ -1302,9 +1728,9 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L) //// Read format of definition to save as int schem_format = SCHEM_FMT_MTS; - const char *enumstr = lua_tostring(L, 2); - if (enumstr) - string_to_enum(es_SchematicFormatType, schem_format, std::string(enumstr)); + std::string enumstr = readParam(L, 2, ""); + if (!enumstr.empty()) + string_to_enum(es_SchematicFormatType, schem_format, enumstr); //// Serialize to binary string std::ostringstream os(std::ios_base::binary); @@ -1332,14 +1758,24 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L) void ModApiMapgen::Initialize(lua_State *L, int top) { API_FCT(get_biome_id); + API_FCT(get_biome_name); + API_FCT(get_heat); + API_FCT(get_humidity); + API_FCT(get_biome_data); API_FCT(get_mapgen_object); + API_FCT(get_spawn_level); API_FCT(get_mapgen_params); API_FCT(set_mapgen_params); + API_FCT(get_mapgen_setting); + API_FCT(set_mapgen_setting); + API_FCT(get_mapgen_setting_noiseparams); + API_FCT(set_mapgen_setting_noiseparams); API_FCT(set_noiseparams); API_FCT(get_noiseparams); API_FCT(set_gen_notify); API_FCT(get_gen_notify); + API_FCT(get_decoration_id); API_FCT(register_biome); API_FCT(register_decoration); @@ -1355,5 +1791,6 @@ void ModApiMapgen::Initialize(lua_State *L, int top) API_FCT(generate_decorations); API_FCT(create_schematic); API_FCT(place_schematic); + API_FCT(place_schematic_on_vmanip); API_FCT(serialize_schematic); }