123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809 |
- /*
- Minetest
- Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- #include "lua_api/l_mapgen.h"
- #include "lua_api/l_internal.h"
- #include "lua_api/l_vmanip.h"
- #include "common/c_converter.h"
- #include "common/c_content.h"
- #include "cpp_api/s_security.h"
- #include "util/serialize.h"
- #include "server.h"
- #include "environment.h"
- #include "emerge.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[] =
- {
- {BIOMETYPE_NORMAL, "normal"},
- {0, NULL},
- };
- struct EnumString ModApiMapgen::es_DecorationType[] =
- {
- {DECO_SIMPLE, "simple"},
- {DECO_SCHEMATIC, "schematic"},
- {DECO_LSYSTEM, "lsystem"},
- {0, NULL},
- };
- struct EnumString ModApiMapgen::es_MapgenObject[] =
- {
- {MGOBJ_VMANIP, "voxelmanip"},
- {MGOBJ_HEIGHTMAP, "heightmap"},
- {MGOBJ_BIOMEMAP, "biomemap"},
- {MGOBJ_HEATMAP, "heatmap"},
- {MGOBJ_HUMIDMAP, "humiditymap"},
- {MGOBJ_GENNOTIFY, "gennotify"},
- {0, NULL},
- };
- struct EnumString ModApiMapgen::es_OreType[] =
- {
- {ORE_SCATTER, "scatter"},
- {ORE_SHEET, "sheet"},
- {ORE_PUFF, "puff"},
- {ORE_BLOB, "blob"},
- {ORE_VEIN, "vein"},
- {ORE_STRATUM, "stratum"},
- {0, NULL},
- };
- struct EnumString ModApiMapgen::es_Rotation[] =
- {
- {ROTATE_0, "0"},
- {ROTATE_90, "90"},
- {ROTATE_180, "180"},
- {ROTATE_270, "270"},
- {ROTATE_RAND, "random"},
- {0, NULL},
- };
- struct EnumString ModApiMapgen::es_SchematicFormatType[] =
- {
- {SCHEM_FMT_HANDLE, "handle"},
- {SCHEM_FMT_MTS, "mts"},
- {SCHEM_FMT_LUA, "lua"},
- {0, NULL},
- };
- ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr);
- Biome *get_or_load_biome(lua_State *L, int index,
- BiomeManager *biomemgr);
- 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::unordered_set<biome_t> *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, const NodeDefManager *ndef,
- StringMap *replace_names);
- Schematic *load_schematic_from_def(lua_State *L, int index,
- const NodeDefManager *ndef, StringMap *replace_names);
- bool read_schematic_def(lua_State *L, int index,
- Schematic *schem, std::vector<std::string> *names);
- bool read_deco_simple(lua_State *L, DecoSimple *deco);
- bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco);
- ///////////////////////////////////////////////////////////////////////////////
- ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr)
- {
- if (index < 0)
- index = lua_gettop(L) + 1 + index;
- // If a number, assume this is a handle to an object def
- if (lua_isnumber(L, index))
- return objmgr->get(lua_tointeger(L, index));
- // If a string, assume a name is given instead
- if (lua_isstring(L, index))
- return objmgr->getByName(lua_tostring(L, index));
- return NULL;
- }
- ///////////////////////////////////////////////////////////////////////////////
- Schematic *get_or_load_schematic(lua_State *L, int index,
- SchematicManager *schemmgr, StringMap *replace_names)
- {
- if (index < 0)
- index = lua_gettop(L) + 1 + index;
- Schematic *schem = (Schematic *)get_objdef(L, index, schemmgr);
- if (schem)
- return schem;
- schem = load_schematic(L, index, schemmgr->getNodeDef(),
- replace_names);
- if (!schem)
- return NULL;
- if (schemmgr->add(schem) == OBJDEF_INVALID_HANDLE) {
- delete schem;
- return NULL;
- }
- return schem;
- }
- Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef,
- StringMap *replace_names)
- {
- if (index < 0)
- index = lua_gettop(L) + 1 + index;
- Schematic *schem = NULL;
- if (lua_istable(L, index)) {
- schem = load_schematic_from_def(L, index, ndef,
- replace_names);
- if (!schem) {
- delete schem;
- return NULL;
- }
- } else if (lua_isnumber(L, index)) {
- return NULL;
- } else if (lua_isstring(L, index)) {
- schem = SchematicManager::create(SCHEMATIC_NORMAL);
- std::string filepath = lua_tostring(L, index);
- if (!fs::IsPathAbsolute(filepath))
- filepath = ModApiBase::getCurrentModPath(L) + DIR_DELIM + filepath;
- if (!schem->loadSchematicFromFile(filepath, ndef,
- replace_names)) {
- delete schem;
- return NULL;
- }
- }
- return schem;
- }
- Schematic *load_schematic_from_def(lua_State *L, int index,
- const NodeDefManager *ndef, StringMap *replace_names)
- {
- Schematic *schem = SchematicManager::create(SCHEMATIC_NORMAL);
- if (!read_schematic_def(L, index, schem, &schem->m_nodenames)) {
- delete schem;
- return NULL;
- }
- size_t num_nodes = schem->m_nodenames.size();
- schem->m_nnlistsizes.push_back(num_nodes);
- if (replace_names) {
- for (size_t i = 0; i != num_nodes; i++) {
- StringMap::iterator it = replace_names->find(schem->m_nodenames[i]);
- if (it != replace_names->end())
- schem->m_nodenames[i] = it->second;
- }
- }
- if (ndef)
- ndef->pendNodeResolve(schem);
- return schem;
- }
- bool read_schematic_def(lua_State *L, int index,
- Schematic *schem, std::vector<std::string> *names)
- {
- if (!lua_istable(L, index))
- return false;
- //// Get schematic size
- lua_getfield(L, index, "size");
- v3s16 size = check_v3s16(L, -1);
- lua_pop(L, 1);
- schem->size = size;
- //// Get schematic data
- lua_getfield(L, index, "data");
- luaL_checktype(L, -1, LUA_TTABLE);
- u32 numnodes = size.X * size.Y * size.Z;
- schem->schemdata = new MapNode[numnodes];
- size_t names_base = names->size();
- std::unordered_map<std::string, content_t> name_id_map;
- u32 i = 0;
- for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) {
- if (i >= numnodes)
- continue;
- //// Read name
- std::string name;
- if (!getstringfield(L, -1, "name", name))
- throw LuaError("Schematic data definition with missing name field");
- //// Read param1/prob
- u8 param1;
- if (!getintfield(L, -1, "param1", param1) &&
- !getintfield(L, -1, "prob", param1))
- param1 = MTSCHEM_PROB_ALWAYS_OLD;
- //// Read param2
- u8 param2 = getintfield_default(L, -1, "param2", 0);
- //// Find or add new nodename-to-ID mapping
- std::unordered_map<std::string, content_t>::iterator it = name_id_map.find(name);
- content_t name_index;
- if (it != name_id_map.end()) {
- name_index = it->second;
- } else {
- name_index = names->size() - names_base;
- name_id_map[name] = name_index;
- names->push_back(name);
- }
- //// Perform probability/force_place fixup on param1
- param1 >>= 1;
- if (getboolfield_default(L, -1, "force_place", false))
- param1 |= MTSCHEM_FORCE_PLACE;
- //// Actually set the node in the schematic
- schem->schemdata[i] = MapNode(name_index, param1, param2);
- }
- if (i != numnodes) {
- errorstream << "read_schematic_def: incorrect number of "
- "nodes provided in raw schematic data (got " << i <<
- ", expected " << numnodes << ")." << std::endl;
- return false;
- }
- //// Get Y-slice probability values (if present)
- schem->slice_probs = new u8[size.Y];
- for (i = 0; i != (u32) size.Y; i++)
- schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS;
- lua_getfield(L, index, "yslice_prob");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
- u16 ypos;
- if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) ||
- !getintfield(L, -1, "prob", schem->slice_probs[ypos]))
- continue;
- schem->slice_probs[ypos] >>= 1;
- }
- }
- return true;
- }
- void read_schematic_replacements(lua_State *L, int index, StringMap *replace_names)
- {
- if (index < 0)
- index = lua_gettop(L) + 1 + index;
- lua_pushnil(L);
- while (lua_next(L, index)) {
- std::string replace_from;
- std::string replace_to;
- 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);
- }
- replace_names->insert(std::make_pair(replace_from, replace_to));
- lua_pop(L, 1);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- Biome *get_or_load_biome(lua_State *L, int index, BiomeManager *biomemgr)
- {
- if (index < 0)
- index = lua_gettop(L) + 1 + index;
- Biome *biome = (Biome *)get_objdef(L, index, biomemgr);
- if (biome)
- return biome;
- biome = read_biome_def(L, index, biomemgr->getNodeDef());
- if (!biome)
- return NULL;
- if (biomemgr->add(biome) == OBJDEF_INVALID_HANDLE) {
- delete biome;
- return NULL;
- }
- return biome;
- }
- 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, 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->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->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<std::string> &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", ""));
- 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;
- }
- size_t get_biome_list(lua_State *L, int index,
- BiomeManager *biomemgr, std::unordered_set<biome_t> *biome_id_list)
- {
- if (index < 0)
- index = lua_gettop(L) + 1 + index;
- if (lua_isnil(L, index))
- return 0;
- bool is_single = true;
- if (lua_istable(L, index)) {
- lua_getfield(L, index, "name");
- is_single = !lua_isnil(L, -1);
- lua_pop(L, 1);
- }
- if (is_single) {
- Biome *biome = get_or_load_biome(L, index, biomemgr);
- if (!biome) {
- infostream << "get_biome_list: failed to get biome '"
- << (lua_isstring(L, index) ? lua_tostring(L, index) : "")
- << "'." << std::endl;
- return 1;
- }
- biome_id_list->insert(biome->index);
- return 0;
- }
- // returns number of failed resolutions
- size_t fail_count = 0;
- size_t count = 0;
- for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1)) {
- count++;
- Biome *biome = get_or_load_biome(L, -1, biomemgr);
- if (!biome) {
- fail_count++;
- infostream << "get_biome_list: failed to get biome '"
- << (lua_isstring(L, -1) ? lua_tostring(L, -1) : "")
- << "'" << std::endl;
- continue;
- }
- biome_id_list->insert(biome->index);
- }
- return fail_count;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // get_biome_id(biomename)
- // 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;
- const char *biome_str = luaL_checkstring(L, 1);
- const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager();
- if (!bmgr)
- return 0;
- const 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);
- const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager();
- if (!bmgr)
- return 0;
- const 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);
- const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen();
- if (!biomegen || biomegen->getType() != BIOMEGEN_ORIGINAL)
- return 0;
- float heat = ((BiomeGenOriginal*) biomegen)->calcHeatAtPoint(pos);
- 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);
- const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen();
- if (!biomegen || biomegen->getType() != BIOMEGEN_ORIGINAL)
- return 0;
- float humidity = ((BiomeGenOriginal*) biomegen)->calcHumidityAtPoint(pos);
- 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);
- const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen();
- if (!biomegen)
- return 0;
- const Biome *biome = biomegen->calcBiomeAtPoint(pos);
- if (!biome || biome->index == OBJDEF_INVALID_INDEX)
- return 0;
- lua_newtable(L);
- lua_pushinteger(L, biome->index);
- lua_setfield(L, -2, "biome");
- if (biomegen->getType() == BIOMEGEN_ORIGINAL) {
- float heat = ((BiomeGenOriginal*) biomegen)->calcHeatAtPoint(pos);
- float humidity = ((BiomeGenOriginal*) biomegen)->calcHumidityAtPoint(pos);
- lua_pushnumber(L, heat);
- lua_setfield(L, -2, "heat");
- lua_pushnumber(L, humidity);
- lua_setfield(L, -2, "humidity");
- }
- return 1;
- }
- // get_mapgen_object(objectname)
- // returns the requested object used during map generation
- int ModApiMapgen::l_get_mapgen_object(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- const char *mgobjstr = lua_tostring(L, 1);
- int mgobjint;
- if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
- return 0;
- enum MapgenObject mgobj = (MapgenObject)mgobjint;
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- Mapgen *mg = emerge->getCurrentMapgen();
- if (!mg)
- throw LuaError("Must only be called in a mapgen thread!");
- size_t maplen = mg->csize.X * mg->csize.Z;
- switch (mgobj) {
- case MGOBJ_VMANIP: {
- MMVManip *vm = mg->vm;
- // VoxelManip object
- LuaVoxelManip *o = new LuaVoxelManip(vm, true);
- *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
- luaL_getmetatable(L, "VoxelManip");
- lua_setmetatable(L, -2);
- // emerged min pos
- push_v3s16(L, vm->m_area.MinEdge);
- // emerged max pos
- push_v3s16(L, vm->m_area.MaxEdge);
- return 3;
- }
- case MGOBJ_HEIGHTMAP: {
- if (!mg->heightmap)
- return 0;
- lua_createtable(L, maplen, 0);
- for (size_t i = 0; i != maplen; i++) {
- lua_pushinteger(L, mg->heightmap[i]);
- lua_rawseti(L, -2, i + 1);
- }
- return 1;
- }
- case MGOBJ_BIOMEMAP: {
- if (!mg->biomegen)
- return 0;
- lua_createtable(L, maplen, 0);
- for (size_t i = 0; i != maplen; i++) {
- lua_pushinteger(L, mg->biomegen->biomemap[i]);
- lua_rawseti(L, -2, i + 1);
- }
- return 1;
- }
- case MGOBJ_HEATMAP: {
- if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL)
- return 0;
- BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen;
- lua_createtable(L, maplen, 0);
- for (size_t i = 0; i != maplen; i++) {
- lua_pushnumber(L, bg->heatmap[i]);
- lua_rawseti(L, -2, i + 1);
- }
- return 1;
- }
- case MGOBJ_HUMIDMAP: {
- if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL)
- return 0;
- BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen;
- lua_createtable(L, maplen, 0);
- for (size_t i = 0; i != maplen; i++) {
- lua_pushnumber(L, bg->humidmap[i]);
- lua_rawseti(L, -2, i + 1);
- }
- return 1;
- }
- case MGOBJ_GENNOTIFY: {
- std::map<std::string, std::vector<v3s16> >event_map;
- mg->gennotify.getEvents(event_map);
- lua_createtable(L, 0, event_map.size());
- for (auto it = event_map.begin(); it != event_map.end(); ++it) {
- lua_createtable(L, it->second.size(), 0);
- for (size_t j = 0; j != it->second.size(); j++) {
- push_v3s16(L, it->second[j]);
- lua_rawseti(L, -2, j + 1);
- }
- lua_setfield(L, -2, it->first.c_str());
- }
- return 1;
- }
- }
- return 0;
- }
- // 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;
- 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);
- settingsmgr->getMapSetting("mg_name", &value);
- lua_pushstring(L, value.c_str());
- lua_setfield(L, -2, "mgname");
- settingsmgr->getMapSetting("seed", &value);
- u64 seed = from_string<u64>(value);
- lua_pushinteger(L, seed);
- lua_setfield(L, -2, "seed");
- settingsmgr->getMapSetting("water_level", &value);
- lua_pushinteger(L, stoi(value, -32768, 32767));
- lua_setfield(L, -2, "water_level");
- settingsmgr->getMapSetting("chunksize", &value);
- lua_pushinteger(L, stoi(value, -32768, 32767));
- lua_setfield(L, -2, "chunksize");
- settingsmgr->getMapSetting("mg_flags", &value);
- lua_pushstring(L, value.c_str());
- lua_setfield(L, -2, "flags");
- return 1;
- }
- // set_mapgen_params(params)
- // set mapgen parameters
- 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;
- MapSettingsManager *settingsmgr =
- getServer(L)->getEmergeManager()->map_settings_mgr;
- lua_getfield(L, 1, "mgname");
- if (lua_isstring(L, -1))
- settingsmgr->setMapSetting("mg_name", readParam<std::string>(L, -1), true);
- lua_getfield(L, 1, "seed");
- if (lua_isnumber(L, -1))
- settingsmgr->setMapSetting("seed", readParam<std::string>(L, -1), true);
- lua_getfield(L, 1, "water_level");
- if (lua_isnumber(L, -1))
- settingsmgr->setMapSetting("water_level", readParam<std::string>(L, -1), true);
- lua_getfield(L, 1, "chunksize");
- if (lua_isnumber(L, -1))
- settingsmgr->setMapSetting("chunksize", readParam<std::string>(L, -1), true);
- lua_getfield(L, 1, "flags");
- if (lua_isstring(L, -1))
- settingsmgr->setMapSetting("mg_flags", readParam<std::string>(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;
- 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<bool>(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<bool>(L, 3, false);
- if (!settingsmgr->setMapSettingNoiseParams(name, &np, override_meta)) {
- errorstream << "set_mapgen_setting_noiseparams: cannot set '"
- << name << "' after initialization" << std::endl;
- }
- return 0;
- }
- // set_noiseparams(name, noiseparams, set_default)
- // set global config values for noise parameters
- int ModApiMapgen::l_set_noiseparams(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- const char *name = luaL_checkstring(L, 1);
- NoiseParams 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) || readParam<bool>(L, 3);
- Settings::getLayer(set_default ? SL_DEFAULTS : SL_GLOBAL)->setNoiseParams(name, np);
- return 0;
- }
- // get_noiseparams(name)
- int ModApiMapgen::l_get_noiseparams(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- std::string name = luaL_checkstring(L, 1);
- NoiseParams np;
- if (!g_settings->getNoiseParams(name, np))
- return 0;
- push_noiseparams(L, &np);
- return 1;
- }
- // set_gen_notify(flags, {deco_id_table})
- int ModApiMapgen::l_set_gen_notify(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- u32 flags = 0, flagmask = 0;
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
- emerge->gen_notify_on &= ~flagmask;
- emerge->gen_notify_on |= flags;
- }
- if (lua_istable(L, 2)) {
- lua_pushnil(L);
- while (lua_next(L, 2)) {
- if (lua_isnumber(L, -1))
- emerge->gen_notify_on_deco_ids.insert((u32)lua_tonumber(L, -1));
- lua_pop(L, 1);
- }
- }
- return 0;
- }
- // get_gen_notify()
- int ModApiMapgen::l_get_gen_notify(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- push_flags_string(L, flagdesc_gennotify, emerge->gen_notify_on,
- emerge->gen_notify_on);
- lua_newtable(L);
- int i = 1;
- 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;
- const DecorationManager *dmgr =
- getServer(L)->getEmergeManager()->getDecorationManager();
- 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)
- {
- NO_MAP_LOCK_REQUIRED;
- int index = 1;
- luaL_checktype(L, index, LUA_TTABLE);
- const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
- BiomeManager *bmgr = getServer(L)->getEmergeManager()->getWritableBiomeManager();
- Biome *biome = read_biome_def(L, index, ndef);
- if (!biome)
- return 0;
- ObjDefHandle handle = bmgr->add(biome);
- if (handle == OBJDEF_INVALID_HANDLE) {
- delete biome;
- return 0;
- }
- lua_pushinteger(L, handle);
- return 1;
- }
- // register_decoration({lots of stuff})
- int ModApiMapgen::l_register_decoration(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- int index = 1;
- luaL_checktype(L, index, LUA_TTABLE);
- const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- DecorationManager *decomgr = emerge->getWritableDecorationManager();
- BiomeManager *biomemgr = emerge->getWritableBiomeManager();
- SchematicManager *schemmgr = emerge->getWritableSchematicManager();
- enum DecorationType decotype = (DecorationType)getenumfield(L, index,
- "deco_type", es_DecorationType, -1);
- Decoration *deco = decomgr->create(decotype);
- if (!deco) {
- errorstream << "register_decoration: decoration placement type "
- << decotype << " not implemented" << std::endl;
- 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->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;
- delete deco;
- return 0;
- }
- //// Get node name(s) to place decoration on
- size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames);
- deco->m_nnlistsizes.push_back(nread);
- //// Get decoration flags
- getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL);
- //// Get NoiseParams to define how decoration is placed
- lua_getfield(L, index, "noise_params");
- if (read_noiseparams(L, -1, &deco->np))
- deco->flags |= DECO_USE_NOISE;
- lua_pop(L, 1);
- //// Get biomes associated with this decoration (if any)
- lua_getfield(L, index, "biomes");
- if (get_biome_list(L, -1, biomemgr, &deco->biomes))
- 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) {
- case DECO_SIMPLE:
- success = read_deco_simple(L, (DecoSimple *)deco);
- break;
- case DECO_SCHEMATIC:
- success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco);
- break;
- case DECO_LSYSTEM:
- break;
- }
- if (!success) {
- delete deco;
- return 0;
- }
- ndef->pendNodeResolve(deco);
- ObjDefHandle handle = decomgr->add(deco);
- if (handle == OBJDEF_INVALID_HANDLE) {
- delete deco;
- return 0;
- }
- lua_pushinteger(L, handle);
- return 1;
- }
- bool read_deco_simple(lua_State *L, DecoSimple *deco)
- {
- 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);
- if (deco->deco_height <= 0) {
- errorstream << "register_decoration: simple decoration height"
- " must be greater than 0" << std::endl;
- return false;
- }
- 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;
- }
- 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;
- }
- bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco)
- {
- int index = 1;
- deco->rotation = (Rotation)getenumfield(L, index, "rotation",
- ModApiMapgen::es_Rotation, ROTATE_0);
- StringMap replace_names;
- lua_getfield(L, index, "replacements");
- if (lua_istable(L, -1))
- read_schematic_replacements(L, -1, &replace_names);
- lua_pop(L, 1);
- lua_getfield(L, index, "schematic");
- Schematic *schem = get_or_load_schematic(L, -1, schemmgr, &replace_names);
- lua_pop(L, 1);
- deco->schematic = schem;
- return schem != NULL;
- }
- // register_ore({lots of stuff})
- int ModApiMapgen::l_register_ore(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- int index = 1;
- luaL_checktype(L, index, LUA_TTABLE);
- const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- BiomeManager *bmgr = emerge->getWritableBiomeManager();
- OreManager *oremgr = emerge->getWritableOreManager();
- enum OreType oretype = (OreType)getenumfield(L, index,
- "ore_type", es_OreType, ORE_SCATTER);
- Ore *ore = oremgr->create(oretype);
- if (!ore) {
- errorstream << "register_ore: ore_type " << oretype << " not implemented\n";
- return 0;
- }
- ore->name = getstringfield_default(L, index, "name", "");
- ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
- 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->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\".");
- warn_if_field_exists(L, index, "height_max",
- "Deprecated: new name is \"y_max\".");
- int ymin, ymax;
- if (!getintfield(L, index, "y_min", ymin) &&
- !getintfield(L, index, "height_min", ymin))
- ymin = -31000;
- if (!getintfield(L, index, "y_max", ymax) &&
- !getintfield(L, index, "height_max", ymax))
- ymax = 31000;
- ore->y_min = ymin;
- ore->y_max = ymax;
- if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
- errorstream << "register_ore: clust_scarcity and clust_num_ores"
- "must be greater than 0" << std::endl;
- delete ore;
- return 0;
- }
- //// Get flags
- getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);
- //// Get biomes associated with this decoration (if any)
- lua_getfield(L, index, "biomes");
- if (get_biome_list(L, -1, bmgr, &ore->biomes))
- infostream << "register_ore: couldn't get all biomes " << std::endl;
- lua_pop(L, 1);
- //// Get noise parameters if needed
- lua_getfield(L, index, "noise_params");
- if (read_noiseparams(L, -1, &ore->np)) {
- ore->flags |= OREFLAG_USE_NOISE;
- } else if (ore->needs_noise) {
- log_deprecated(L,
- "register_ore: ore type requires 'noise_params' but it is not specified, falling back to defaults");
- }
- lua_pop(L, 1);
- //// Get type-specific parameters
- switch (oretype) {
- case ORE_SHEET: {
- OreSheet *oresheet = (OreSheet *)ore;
- oresheet->column_height_min = getintfield_default(L, index,
- "column_height_min", 1);
- oresheet->column_height_max = getintfield_default(L, index,
- "column_height_max", ore->clust_size);
- oresheet->column_midpoint_factor = getfloatfield_default(L, index,
- "column_midpoint_factor", 0.5f);
- break;
- }
- case ORE_PUFF: {
- OrePuff *orepuff = (OrePuff *)ore;
- lua_getfield(L, index, "np_puff_top");
- read_noiseparams(L, -1, &orepuff->np_puff_top);
- lua_pop(L, 1);
- lua_getfield(L, index, "np_puff_bottom");
- read_noiseparams(L, -1, &orepuff->np_puff_bottom);
- lua_pop(L, 1);
- break;
- }
- case ORE_VEIN: {
- OreVein *orevein = (OreVein *)ore;
- orevein->random_factor = getfloatfield_default(L, index,
- "random_factor", 1.f);
- 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;
- }
- ObjDefHandle handle = oremgr->add(ore);
- if (handle == OBJDEF_INVALID_HANDLE) {
- delete ore;
- return 0;
- }
- ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", ""));
- size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames);
- ore->m_nnlistsizes.push_back(nnames);
- ndef->pendNodeResolve(ore);
- lua_pushinteger(L, handle);
- return 1;
- }
- // register_schematic({schematic}, replacements={})
- int ModApiMapgen::l_register_schematic(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- SchematicManager *schemmgr =
- getServer(L)->getEmergeManager()->getWritableSchematicManager();
- StringMap replace_names;
- if (lua_istable(L, 2))
- read_schematic_replacements(L, 2, &replace_names);
- Schematic *schem = load_schematic(L, 1, schemmgr->getNodeDef(),
- &replace_names);
- if (!schem)
- return 0;
- ObjDefHandle handle = schemmgr->add(schem);
- if (handle == OBJDEF_INVALID_HANDLE) {
- delete schem;
- return 0;
- }
- lua_pushinteger(L, handle);
- return 1;
- }
- // clear_registered_biomes()
- int ModApiMapgen::l_clear_registered_biomes(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- BiomeManager *bmgr =
- getServer(L)->getEmergeManager()->getWritableBiomeManager();
- bmgr->clear();
- return 0;
- }
- // clear_registered_decorations()
- int ModApiMapgen::l_clear_registered_decorations(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- DecorationManager *dmgr =
- getServer(L)->getEmergeManager()->getWritableDecorationManager();
- dmgr->clear();
- return 0;
- }
- // clear_registered_ores()
- int ModApiMapgen::l_clear_registered_ores(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- OreManager *omgr =
- getServer(L)->getEmergeManager()->getWritableOreManager();
- omgr->clear();
- return 0;
- }
- // clear_registered_schematics()
- int ModApiMapgen::l_clear_registered_schematics(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- SchematicManager *smgr =
- getServer(L)->getEmergeManager()->getWritableSchematicManager();
- smgr->clear();
- return 0;
- }
- // generate_ores(vm, p1, p2, [ore_id])
- int ModApiMapgen::l_generate_ores(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- if (!emerge || !emerge->mgparams)
- return 0;
- Mapgen mg;
- // Intentionally truncates to s32, see Mapgen::Mapgen()
- mg.seed = (s32)emerge->mgparams->seed;
- mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
- mg.ndef = getServer(L)->getNodeDefManager();
- v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) :
- mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE;
- v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) :
- mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE;
- sortBoxVerticies(pmin, pmax);
- u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed);
- emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax);
- return 0;
- }
- // generate_decorations(vm, p1, p2, [deco_id])
- int ModApiMapgen::l_generate_decorations(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- EmergeManager *emerge = getServer(L)->getEmergeManager();
- if (!emerge || !emerge->mgparams)
- return 0;
- Mapgen mg;
- // Intentionally truncates to s32, see Mapgen::Mapgen()
- mg.seed = (s32)emerge->mgparams->seed;
- mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
- mg.ndef = getServer(L)->getNodeDefManager();
- v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) :
- mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE;
- v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) :
- mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE;
- sortBoxVerticies(pmin, pmax);
- u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed);
- emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax);
- return 0;
- }
- // create_schematic(p1, p2, probability_list, filename, y_slice_prob_list)
- int ModApiMapgen::l_create_schematic(lua_State *L)
- {
- MAP_LOCK_REQUIRED;
- const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
- const char *filename = luaL_checkstring(L, 4);
- CHECK_SECURE_PATH(L, filename, true);
- Map *map = &(getEnv(L)->getMap());
- Schematic schem;
- v3s16 p1 = check_v3s16(L, 1);
- v3s16 p2 = check_v3s16(L, 2);
- sortBoxVerticies(p1, p2);
- std::vector<std::pair<v3s16, u8> > prob_list;
- if (lua_istable(L, 3)) {
- lua_pushnil(L);
- while (lua_next(L, 3)) {
- if (lua_istable(L, -1)) {
- lua_getfield(L, -1, "pos");
- v3s16 pos = check_v3s16(L, -1);
- lua_pop(L, 1);
- u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
- prob_list.emplace_back(pos, prob);
- }
- lua_pop(L, 1);
- }
- }
- std::vector<std::pair<s16, u8> > slice_prob_list;
- if (lua_istable(L, 5)) {
- lua_pushnil(L);
- while (lua_next(L, 5)) {
- 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.emplace_back(ypos, prob);
- }
- lua_pop(L, 1);
- }
- }
- if (!schem.getSchematicFromMap(map, p1, p2)) {
- errorstream << "create_schematic: failed to get schematic "
- "from map" << std::endl;
- return 0;
- }
- schem.applyProbabilities(p1, &prob_list, &slice_prob_list);
- schem.saveSchematicToFile(filename, ndef);
- actionstream << "create_schematic: saved schematic file '"
- << filename << "'." << std::endl;
- lua_pushboolean(L, true);
- return 1;
- }
- // place_schematic(p, schematic, rotation,
- // replacements, force_placement, flagstring)
- int ModApiMapgen::l_place_schematic(lua_State *L)
- {
- MAP_LOCK_REQUIRED;
- GET_ENV_PTR;
- ServerMap *map = &(env->getServerMap());
- SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
- //// Read position
- v3s16 p = check_v3s16(L, 1);
- //// Read rotation
- int rot = ROTATE_0;
- std::string enumstr = readParam<std::string>(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 = readParam<bool>(L, 5);
- //// Read node replacements
- StringMap replace_names;
- if (lua_istable(L, 4))
- read_schematic_replacements(L, 4, &replace_names);
- //// Read schematic
- Schematic *schem = get_or_load_schematic(L, 2, schemmgr, &replace_names);
- if (!schem) {
- errorstream << "place_schematic: failed to get schematic" << std::endl;
- return 0;
- }
- //// 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<std::string>(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<bool>(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)
- {
- NO_MAP_LOCK_REQUIRED;
- const SchematicManager *schemmgr = getServer(L)->getEmergeManager()->getSchematicManager();
- //// Read options
- bool use_comments = getboolfield_default(L, 3, "lua_use_comments", false);
- u32 indent_spaces = getintfield_default(L, 3, "lua_num_indent_spaces", 0);
- //// Get schematic
- bool was_loaded = false;
- const Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr);
- if (!schem) {
- schem = load_schematic(L, 1, NULL, NULL);
- was_loaded = true;
- }
- if (!schem) {
- errorstream << "serialize_schematic: failed to get schematic" << std::endl;
- return 0;
- }
- //// Read format of definition to save as
- int schem_format = SCHEM_FMT_MTS;
- std::string enumstr = readParam<std::string>(L, 2, "");
- if (!enumstr.empty())
- string_to_enum(es_SchematicFormatType, schem_format, enumstr);
- //// Serialize to binary string
- std::ostringstream os(std::ios_base::binary);
- switch (schem_format) {
- case SCHEM_FMT_MTS:
- schem->serializeToMts(&os);
- break;
- case SCHEM_FMT_LUA:
- schem->serializeToLua(&os, use_comments, indent_spaces);
- break;
- default:
- return 0;
- }
- if (was_loaded)
- delete schem;
- std::string ser = os.str();
- lua_pushlstring(L, ser.c_str(), ser.length());
- return 1;
- }
- // read_schematic(schematic, options={...})
- int ModApiMapgen::l_read_schematic(lua_State *L)
- {
- NO_MAP_LOCK_REQUIRED;
- const SchematicManager *schemmgr =
- getServer(L)->getEmergeManager()->getSchematicManager();
- //// Read options
- std::string write_yslice = getstringfield_default(L, 2, "write_yslice_prob", "all");
- //// Get schematic
- bool was_loaded = false;
- Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr);
- if (!schem) {
- schem = load_schematic(L, 1, NULL, NULL);
- was_loaded = true;
- }
- if (!schem) {
- errorstream << "read_schematic: failed to get schematic" << std::endl;
- return 0;
- }
- lua_pop(L, 2);
- //// Create the Lua table
- u32 numnodes = schem->size.X * schem->size.Y * schem->size.Z;
- const std::vector<std::string> &names = schem->m_nodenames;
- lua_createtable(L, 0, (write_yslice == "none") ? 2 : 3);
- // Create the size field
- push_v3s16(L, schem->size);
- lua_setfield(L, 1, "size");
- // Create the yslice_prob field
- if (write_yslice != "none") {
- lua_createtable(L, schem->size.Y, 0);
- for (u16 y = 0; y != schem->size.Y; ++y) {
- u8 probability = schem->slice_probs[y] & MTSCHEM_PROB_MASK;
- if (probability < MTSCHEM_PROB_ALWAYS || write_yslice != "low") {
- lua_createtable(L, 0, 2);
- lua_pushinteger(L, y);
- lua_setfield(L, 3, "ypos");
- lua_pushinteger(L, probability * 2);
- lua_setfield(L, 3, "prob");
- lua_rawseti(L, 2, y + 1);
- }
- }
- lua_setfield(L, 1, "yslice_prob");
- }
- // Create the data field
- lua_createtable(L, numnodes, 0); // data table
- for (u32 i = 0; i < numnodes; ++i) {
- MapNode node = schem->schemdata[i];
- u8 probability = node.param1 & MTSCHEM_PROB_MASK;
- bool force_place = node.param1 & MTSCHEM_FORCE_PLACE;
- lua_createtable(L, 0, force_place ? 4 : 3);
- lua_pushstring(L, names[schem->schemdata[i].getContent()].c_str());
- lua_setfield(L, 3, "name");
- lua_pushinteger(L, probability * 2);
- lua_setfield(L, 3, "prob");
- lua_pushinteger(L, node.param2);
- lua_setfield(L, 3, "param2");
- if (force_place) {
- lua_pushboolean(L, 1);
- lua_setfield(L, 3, "force_place");
- }
- lua_rawseti(L, 2, i + 1);
- }
- lua_setfield(L, 1, "data");
- if (was_loaded)
- delete schem;
- return 1;
- }
- 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);
- API_FCT(register_ore);
- API_FCT(register_schematic);
- API_FCT(clear_registered_biomes);
- API_FCT(clear_registered_decorations);
- API_FCT(clear_registered_ores);
- API_FCT(clear_registered_schematics);
- API_FCT(generate_ores);
- API_FCT(generate_decorations);
- API_FCT(create_schematic);
- API_FCT(place_schematic);
- API_FCT(place_schematic_on_vmanip);
- API_FCT(serialize_schematic);
- API_FCT(read_schematic);
- }
|