l_mapgen.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "lua_api/l_mapgen.h"
  17. #include "lua_api/l_internal.h"
  18. #include "lua_api/l_vmanip.h"
  19. #include "common/c_converter.h"
  20. #include "common/c_content.h"
  21. #include "cpp_api/s_security.h"
  22. #include "util/serialize.h"
  23. #include "server.h"
  24. #include "environment.h"
  25. #include "emerge.h"
  26. #include "mapgen/mg_biome.h"
  27. #include "mapgen/mg_ore.h"
  28. #include "mapgen/mg_decoration.h"
  29. #include "mapgen/mg_schematic.h"
  30. #include "mapgen/mapgen_v5.h"
  31. #include "mapgen/mapgen_v7.h"
  32. #include "filesys.h"
  33. #include "settings.h"
  34. #include "log.h"
  35. struct EnumString ModApiMapgen::es_BiomeTerrainType[] =
  36. {
  37. {BIOMETYPE_NORMAL, "normal"},
  38. {0, NULL},
  39. };
  40. struct EnumString ModApiMapgen::es_DecorationType[] =
  41. {
  42. {DECO_SIMPLE, "simple"},
  43. {DECO_SCHEMATIC, "schematic"},
  44. {DECO_LSYSTEM, "lsystem"},
  45. {0, NULL},
  46. };
  47. struct EnumString ModApiMapgen::es_MapgenObject[] =
  48. {
  49. {MGOBJ_VMANIP, "voxelmanip"},
  50. {MGOBJ_HEIGHTMAP, "heightmap"},
  51. {MGOBJ_BIOMEMAP, "biomemap"},
  52. {MGOBJ_HEATMAP, "heatmap"},
  53. {MGOBJ_HUMIDMAP, "humiditymap"},
  54. {MGOBJ_GENNOTIFY, "gennotify"},
  55. {0, NULL},
  56. };
  57. struct EnumString ModApiMapgen::es_OreType[] =
  58. {
  59. {ORE_SCATTER, "scatter"},
  60. {ORE_SHEET, "sheet"},
  61. {ORE_PUFF, "puff"},
  62. {ORE_BLOB, "blob"},
  63. {ORE_VEIN, "vein"},
  64. {ORE_STRATUM, "stratum"},
  65. {0, NULL},
  66. };
  67. struct EnumString ModApiMapgen::es_Rotation[] =
  68. {
  69. {ROTATE_0, "0"},
  70. {ROTATE_90, "90"},
  71. {ROTATE_180, "180"},
  72. {ROTATE_270, "270"},
  73. {ROTATE_RAND, "random"},
  74. {0, NULL},
  75. };
  76. struct EnumString ModApiMapgen::es_SchematicFormatType[] =
  77. {
  78. {SCHEM_FMT_HANDLE, "handle"},
  79. {SCHEM_FMT_MTS, "mts"},
  80. {SCHEM_FMT_LUA, "lua"},
  81. {0, NULL},
  82. };
  83. ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr);
  84. Biome *get_or_load_biome(lua_State *L, int index,
  85. BiomeManager *biomemgr);
  86. Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef);
  87. size_t get_biome_list(lua_State *L, int index,
  88. BiomeManager *biomemgr, std::unordered_set<biome_t> *biome_id_list);
  89. Schematic *get_or_load_schematic(lua_State *L, int index,
  90. SchematicManager *schemmgr, StringMap *replace_names);
  91. Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef,
  92. StringMap *replace_names);
  93. Schematic *load_schematic_from_def(lua_State *L, int index,
  94. const NodeDefManager *ndef, StringMap *replace_names);
  95. bool read_schematic_def(lua_State *L, int index,
  96. Schematic *schem, std::vector<std::string> *names);
  97. bool read_deco_simple(lua_State *L, DecoSimple *deco);
  98. bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco);
  99. ///////////////////////////////////////////////////////////////////////////////
  100. ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr)
  101. {
  102. if (index < 0)
  103. index = lua_gettop(L) + 1 + index;
  104. // If a number, assume this is a handle to an object def
  105. if (lua_isnumber(L, index))
  106. return objmgr->get(lua_tointeger(L, index));
  107. // If a string, assume a name is given instead
  108. if (lua_isstring(L, index))
  109. return objmgr->getByName(lua_tostring(L, index));
  110. return NULL;
  111. }
  112. ///////////////////////////////////////////////////////////////////////////////
  113. Schematic *get_or_load_schematic(lua_State *L, int index,
  114. SchematicManager *schemmgr, StringMap *replace_names)
  115. {
  116. if (index < 0)
  117. index = lua_gettop(L) + 1 + index;
  118. Schematic *schem = (Schematic *)get_objdef(L, index, schemmgr);
  119. if (schem)
  120. return schem;
  121. schem = load_schematic(L, index, schemmgr->getNodeDef(),
  122. replace_names);
  123. if (!schem)
  124. return NULL;
  125. if (schemmgr->add(schem) == OBJDEF_INVALID_HANDLE) {
  126. delete schem;
  127. return NULL;
  128. }
  129. return schem;
  130. }
  131. Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef,
  132. StringMap *replace_names)
  133. {
  134. if (index < 0)
  135. index = lua_gettop(L) + 1 + index;
  136. Schematic *schem = NULL;
  137. if (lua_istable(L, index)) {
  138. schem = load_schematic_from_def(L, index, ndef,
  139. replace_names);
  140. if (!schem) {
  141. delete schem;
  142. return NULL;
  143. }
  144. } else if (lua_isnumber(L, index)) {
  145. return NULL;
  146. } else if (lua_isstring(L, index)) {
  147. schem = SchematicManager::create(SCHEMATIC_NORMAL);
  148. std::string filepath = lua_tostring(L, index);
  149. if (!fs::IsPathAbsolute(filepath))
  150. filepath = ModApiBase::getCurrentModPath(L) + DIR_DELIM + filepath;
  151. if (!schem->loadSchematicFromFile(filepath, ndef,
  152. replace_names)) {
  153. delete schem;
  154. return NULL;
  155. }
  156. }
  157. return schem;
  158. }
  159. Schematic *load_schematic_from_def(lua_State *L, int index,
  160. const NodeDefManager *ndef, StringMap *replace_names)
  161. {
  162. Schematic *schem = SchematicManager::create(SCHEMATIC_NORMAL);
  163. if (!read_schematic_def(L, index, schem, &schem->m_nodenames)) {
  164. delete schem;
  165. return NULL;
  166. }
  167. size_t num_nodes = schem->m_nodenames.size();
  168. schem->m_nnlistsizes.push_back(num_nodes);
  169. if (replace_names) {
  170. for (size_t i = 0; i != num_nodes; i++) {
  171. StringMap::iterator it = replace_names->find(schem->m_nodenames[i]);
  172. if (it != replace_names->end())
  173. schem->m_nodenames[i] = it->second;
  174. }
  175. }
  176. if (ndef)
  177. ndef->pendNodeResolve(schem);
  178. return schem;
  179. }
  180. bool read_schematic_def(lua_State *L, int index,
  181. Schematic *schem, std::vector<std::string> *names)
  182. {
  183. if (!lua_istable(L, index))
  184. return false;
  185. //// Get schematic size
  186. lua_getfield(L, index, "size");
  187. v3s16 size = check_v3s16(L, -1);
  188. lua_pop(L, 1);
  189. schem->size = size;
  190. //// Get schematic data
  191. lua_getfield(L, index, "data");
  192. luaL_checktype(L, -1, LUA_TTABLE);
  193. u32 numnodes = size.X * size.Y * size.Z;
  194. schem->schemdata = new MapNode[numnodes];
  195. size_t names_base = names->size();
  196. std::unordered_map<std::string, content_t> name_id_map;
  197. u32 i = 0;
  198. for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) {
  199. if (i >= numnodes)
  200. continue;
  201. //// Read name
  202. std::string name;
  203. if (!getstringfield(L, -1, "name", name))
  204. throw LuaError("Schematic data definition with missing name field");
  205. //// Read param1/prob
  206. u8 param1;
  207. if (!getintfield(L, -1, "param1", param1) &&
  208. !getintfield(L, -1, "prob", param1))
  209. param1 = MTSCHEM_PROB_ALWAYS_OLD;
  210. //// Read param2
  211. u8 param2 = getintfield_default(L, -1, "param2", 0);
  212. //// Find or add new nodename-to-ID mapping
  213. std::unordered_map<std::string, content_t>::iterator it = name_id_map.find(name);
  214. content_t name_index;
  215. if (it != name_id_map.end()) {
  216. name_index = it->second;
  217. } else {
  218. name_index = names->size() - names_base;
  219. name_id_map[name] = name_index;
  220. names->push_back(name);
  221. }
  222. //// Perform probability/force_place fixup on param1
  223. param1 >>= 1;
  224. if (getboolfield_default(L, -1, "force_place", false))
  225. param1 |= MTSCHEM_FORCE_PLACE;
  226. //// Actually set the node in the schematic
  227. schem->schemdata[i] = MapNode(name_index, param1, param2);
  228. }
  229. if (i != numnodes) {
  230. errorstream << "read_schematic_def: incorrect number of "
  231. "nodes provided in raw schematic data (got " << i <<
  232. ", expected " << numnodes << ")." << std::endl;
  233. return false;
  234. }
  235. //// Get Y-slice probability values (if present)
  236. schem->slice_probs = new u8[size.Y];
  237. for (i = 0; i != (u32) size.Y; i++)
  238. schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS;
  239. lua_getfield(L, index, "yslice_prob");
  240. if (lua_istable(L, -1)) {
  241. for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
  242. u16 ypos;
  243. if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) ||
  244. !getintfield(L, -1, "prob", schem->slice_probs[ypos]))
  245. continue;
  246. schem->slice_probs[ypos] >>= 1;
  247. }
  248. }
  249. return true;
  250. }
  251. void read_schematic_replacements(lua_State *L, int index, StringMap *replace_names)
  252. {
  253. if (index < 0)
  254. index = lua_gettop(L) + 1 + index;
  255. lua_pushnil(L);
  256. while (lua_next(L, index)) {
  257. std::string replace_from;
  258. std::string replace_to;
  259. if (lua_istable(L, -1)) { // Old {{"x", "y"}, ...} format
  260. lua_rawgeti(L, -1, 1);
  261. if (!lua_isstring(L, -1))
  262. throw LuaError("schematics: replace_from field is not a string");
  263. replace_from = lua_tostring(L, -1);
  264. lua_pop(L, 1);
  265. lua_rawgeti(L, -1, 2);
  266. if (!lua_isstring(L, -1))
  267. throw LuaError("schematics: replace_to field is not a string");
  268. replace_to = lua_tostring(L, -1);
  269. lua_pop(L, 1);
  270. } else { // New {x = "y", ...} format
  271. if (!lua_isstring(L, -2))
  272. throw LuaError("schematics: replace_from field is not a string");
  273. replace_from = lua_tostring(L, -2);
  274. if (!lua_isstring(L, -1))
  275. throw LuaError("schematics: replace_to field is not a string");
  276. replace_to = lua_tostring(L, -1);
  277. }
  278. replace_names->insert(std::make_pair(replace_from, replace_to));
  279. lua_pop(L, 1);
  280. }
  281. }
  282. ///////////////////////////////////////////////////////////////////////////////
  283. Biome *get_or_load_biome(lua_State *L, int index, BiomeManager *biomemgr)
  284. {
  285. if (index < 0)
  286. index = lua_gettop(L) + 1 + index;
  287. Biome *biome = (Biome *)get_objdef(L, index, biomemgr);
  288. if (biome)
  289. return biome;
  290. biome = read_biome_def(L, index, biomemgr->getNodeDef());
  291. if (!biome)
  292. return NULL;
  293. if (biomemgr->add(biome) == OBJDEF_INVALID_HANDLE) {
  294. delete biome;
  295. return NULL;
  296. }
  297. return biome;
  298. }
  299. Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef)
  300. {
  301. if (!lua_istable(L, index))
  302. return NULL;
  303. BiomeType biometype = (BiomeType)getenumfield(L, index, "type",
  304. ModApiMapgen::es_BiomeTerrainType, BIOMETYPE_NORMAL);
  305. Biome *b = BiomeManager::create(biometype);
  306. b->name = getstringfield_default(L, index, "name", "");
  307. b->depth_top = getintfield_default(L, index, "depth_top", 0);
  308. b->depth_filler = getintfield_default(L, index, "depth_filler", -31000);
  309. b->depth_water_top = getintfield_default(L, index, "depth_water_top", 0);
  310. b->depth_riverbed = getintfield_default(L, index, "depth_riverbed", 0);
  311. b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f);
  312. b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f);
  313. b->vertical_blend = getintfield_default(L, index, "vertical_blend", 0);
  314. b->flags = 0; // reserved
  315. b->min_pos = getv3s16field_default(
  316. L, index, "min_pos", v3s16(-31000, -31000, -31000));
  317. getintfield(L, index, "y_min", b->min_pos.Y);
  318. b->max_pos = getv3s16field_default(
  319. L, index, "max_pos", v3s16(31000, 31000, 31000));
  320. getintfield(L, index, "y_max", b->max_pos.Y);
  321. std::vector<std::string> &nn = b->m_nodenames;
  322. nn.push_back(getstringfield_default(L, index, "node_top", ""));
  323. nn.push_back(getstringfield_default(L, index, "node_filler", ""));
  324. nn.push_back(getstringfield_default(L, index, "node_stone", ""));
  325. nn.push_back(getstringfield_default(L, index, "node_water_top", ""));
  326. nn.push_back(getstringfield_default(L, index, "node_water", ""));
  327. nn.push_back(getstringfield_default(L, index, "node_river_water", ""));
  328. nn.push_back(getstringfield_default(L, index, "node_riverbed", ""));
  329. nn.push_back(getstringfield_default(L, index, "node_dust", ""));
  330. size_t nnames = getstringlistfield(L, index, "node_cave_liquid", &nn);
  331. // If no cave liquids defined, set list to "ignore" to trigger old hardcoded
  332. // cave liquid behaviour.
  333. if (nnames == 0) {
  334. nn.emplace_back("ignore");
  335. nnames = 1;
  336. }
  337. b->m_nnlistsizes.push_back(nnames);
  338. nn.push_back(getstringfield_default(L, index, "node_dungeon", ""));
  339. nn.push_back(getstringfield_default(L, index, "node_dungeon_alt", ""));
  340. nn.push_back(getstringfield_default(L, index, "node_dungeon_stair", ""));
  341. ndef->pendNodeResolve(b);
  342. return b;
  343. }
  344. size_t get_biome_list(lua_State *L, int index,
  345. BiomeManager *biomemgr, std::unordered_set<biome_t> *biome_id_list)
  346. {
  347. if (index < 0)
  348. index = lua_gettop(L) + 1 + index;
  349. if (lua_isnil(L, index))
  350. return 0;
  351. bool is_single = true;
  352. if (lua_istable(L, index)) {
  353. lua_getfield(L, index, "name");
  354. is_single = !lua_isnil(L, -1);
  355. lua_pop(L, 1);
  356. }
  357. if (is_single) {
  358. Biome *biome = get_or_load_biome(L, index, biomemgr);
  359. if (!biome) {
  360. infostream << "get_biome_list: failed to get biome '"
  361. << (lua_isstring(L, index) ? lua_tostring(L, index) : "")
  362. << "'." << std::endl;
  363. return 1;
  364. }
  365. biome_id_list->insert(biome->index);
  366. return 0;
  367. }
  368. // returns number of failed resolutions
  369. size_t fail_count = 0;
  370. size_t count = 0;
  371. for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1)) {
  372. count++;
  373. Biome *biome = get_or_load_biome(L, -1, biomemgr);
  374. if (!biome) {
  375. fail_count++;
  376. infostream << "get_biome_list: failed to get biome '"
  377. << (lua_isstring(L, -1) ? lua_tostring(L, -1) : "")
  378. << "'" << std::endl;
  379. continue;
  380. }
  381. biome_id_list->insert(biome->index);
  382. }
  383. return fail_count;
  384. }
  385. ///////////////////////////////////////////////////////////////////////////////
  386. // get_biome_id(biomename)
  387. // returns the biome id as used in biomemap and returned by 'get_biome_data()'
  388. int ModApiMapgen::l_get_biome_id(lua_State *L)
  389. {
  390. NO_MAP_LOCK_REQUIRED;
  391. const char *biome_str = luaL_checkstring(L, 1);
  392. const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager();
  393. if (!bmgr)
  394. return 0;
  395. const Biome *biome = (Biome *)bmgr->getByName(biome_str);
  396. if (!biome || biome->index == OBJDEF_INVALID_INDEX)
  397. return 0;
  398. lua_pushinteger(L, biome->index);
  399. return 1;
  400. }
  401. // get_biome_name(biome_id)
  402. // returns the biome name string
  403. int ModApiMapgen::l_get_biome_name(lua_State *L)
  404. {
  405. NO_MAP_LOCK_REQUIRED;
  406. int biome_id = luaL_checkinteger(L, 1);
  407. const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager();
  408. if (!bmgr)
  409. return 0;
  410. const Biome *b = (Biome *)bmgr->getRaw(biome_id);
  411. lua_pushstring(L, b->name.c_str());
  412. return 1;
  413. }
  414. // get_heat(pos)
  415. // returns the heat at the position
  416. int ModApiMapgen::l_get_heat(lua_State *L)
  417. {
  418. NO_MAP_LOCK_REQUIRED;
  419. v3s16 pos = read_v3s16(L, 1);
  420. const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen();
  421. if (!biomegen || biomegen->getType() != BIOMEGEN_ORIGINAL)
  422. return 0;
  423. float heat = ((BiomeGenOriginal*) biomegen)->calcHeatAtPoint(pos);
  424. lua_pushnumber(L, heat);
  425. return 1;
  426. }
  427. // get_humidity(pos)
  428. // returns the humidity at the position
  429. int ModApiMapgen::l_get_humidity(lua_State *L)
  430. {
  431. NO_MAP_LOCK_REQUIRED;
  432. v3s16 pos = read_v3s16(L, 1);
  433. const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen();
  434. if (!biomegen || biomegen->getType() != BIOMEGEN_ORIGINAL)
  435. return 0;
  436. float humidity = ((BiomeGenOriginal*) biomegen)->calcHumidityAtPoint(pos);
  437. lua_pushnumber(L, humidity);
  438. return 1;
  439. }
  440. // get_biome_data(pos)
  441. // returns a table containing the biome id, heat and humidity at the position
  442. int ModApiMapgen::l_get_biome_data(lua_State *L)
  443. {
  444. NO_MAP_LOCK_REQUIRED;
  445. v3s16 pos = read_v3s16(L, 1);
  446. const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen();
  447. if (!biomegen)
  448. return 0;
  449. const Biome *biome = biomegen->calcBiomeAtPoint(pos);
  450. if (!biome || biome->index == OBJDEF_INVALID_INDEX)
  451. return 0;
  452. lua_newtable(L);
  453. lua_pushinteger(L, biome->index);
  454. lua_setfield(L, -2, "biome");
  455. if (biomegen->getType() == BIOMEGEN_ORIGINAL) {
  456. float heat = ((BiomeGenOriginal*) biomegen)->calcHeatAtPoint(pos);
  457. float humidity = ((BiomeGenOriginal*) biomegen)->calcHumidityAtPoint(pos);
  458. lua_pushnumber(L, heat);
  459. lua_setfield(L, -2, "heat");
  460. lua_pushnumber(L, humidity);
  461. lua_setfield(L, -2, "humidity");
  462. }
  463. return 1;
  464. }
  465. // get_mapgen_object(objectname)
  466. // returns the requested object used during map generation
  467. int ModApiMapgen::l_get_mapgen_object(lua_State *L)
  468. {
  469. NO_MAP_LOCK_REQUIRED;
  470. const char *mgobjstr = lua_tostring(L, 1);
  471. int mgobjint;
  472. if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
  473. return 0;
  474. enum MapgenObject mgobj = (MapgenObject)mgobjint;
  475. EmergeManager *emerge = getServer(L)->getEmergeManager();
  476. Mapgen *mg = emerge->getCurrentMapgen();
  477. if (!mg)
  478. throw LuaError("Must only be called in a mapgen thread!");
  479. size_t maplen = mg->csize.X * mg->csize.Z;
  480. switch (mgobj) {
  481. case MGOBJ_VMANIP: {
  482. MMVManip *vm = mg->vm;
  483. // VoxelManip object
  484. LuaVoxelManip *o = new LuaVoxelManip(vm, true);
  485. *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
  486. luaL_getmetatable(L, "VoxelManip");
  487. lua_setmetatable(L, -2);
  488. // emerged min pos
  489. push_v3s16(L, vm->m_area.MinEdge);
  490. // emerged max pos
  491. push_v3s16(L, vm->m_area.MaxEdge);
  492. return 3;
  493. }
  494. case MGOBJ_HEIGHTMAP: {
  495. if (!mg->heightmap)
  496. return 0;
  497. lua_createtable(L, maplen, 0);
  498. for (size_t i = 0; i != maplen; i++) {
  499. lua_pushinteger(L, mg->heightmap[i]);
  500. lua_rawseti(L, -2, i + 1);
  501. }
  502. return 1;
  503. }
  504. case MGOBJ_BIOMEMAP: {
  505. if (!mg->biomegen)
  506. return 0;
  507. lua_createtable(L, maplen, 0);
  508. for (size_t i = 0; i != maplen; i++) {
  509. lua_pushinteger(L, mg->biomegen->biomemap[i]);
  510. lua_rawseti(L, -2, i + 1);
  511. }
  512. return 1;
  513. }
  514. case MGOBJ_HEATMAP: {
  515. if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL)
  516. return 0;
  517. BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen;
  518. lua_createtable(L, maplen, 0);
  519. for (size_t i = 0; i != maplen; i++) {
  520. lua_pushnumber(L, bg->heatmap[i]);
  521. lua_rawseti(L, -2, i + 1);
  522. }
  523. return 1;
  524. }
  525. case MGOBJ_HUMIDMAP: {
  526. if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL)
  527. return 0;
  528. BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen;
  529. lua_createtable(L, maplen, 0);
  530. for (size_t i = 0; i != maplen; i++) {
  531. lua_pushnumber(L, bg->humidmap[i]);
  532. lua_rawseti(L, -2, i + 1);
  533. }
  534. return 1;
  535. }
  536. case MGOBJ_GENNOTIFY: {
  537. std::map<std::string, std::vector<v3s16> >event_map;
  538. mg->gennotify.getEvents(event_map);
  539. lua_createtable(L, 0, event_map.size());
  540. for (auto it = event_map.begin(); it != event_map.end(); ++it) {
  541. lua_createtable(L, it->second.size(), 0);
  542. for (size_t j = 0; j != it->second.size(); j++) {
  543. push_v3s16(L, it->second[j]);
  544. lua_rawseti(L, -2, j + 1);
  545. }
  546. lua_setfield(L, -2, it->first.c_str());
  547. }
  548. return 1;
  549. }
  550. }
  551. return 0;
  552. }
  553. // get_spawn_level(x = num, z = num)
  554. int ModApiMapgen::l_get_spawn_level(lua_State *L)
  555. {
  556. NO_MAP_LOCK_REQUIRED;
  557. s16 x = luaL_checkinteger(L, 1);
  558. s16 z = luaL_checkinteger(L, 2);
  559. EmergeManager *emerge = getServer(L)->getEmergeManager();
  560. int spawn_level = emerge->getSpawnLevelAtPoint(v2s16(x, z));
  561. // Unsuitable spawn point
  562. if (spawn_level == MAX_MAP_GENERATION_LIMIT)
  563. return 0;
  564. // 'findSpawnPos()' in server.cpp adds at least 1
  565. lua_pushinteger(L, spawn_level + 1);
  566. return 1;
  567. }
  568. int ModApiMapgen::l_get_mapgen_params(lua_State *L)
  569. {
  570. NO_MAP_LOCK_REQUIRED;
  571. log_deprecated(L, "get_mapgen_params is deprecated; "
  572. "use get_mapgen_setting instead");
  573. std::string value;
  574. MapSettingsManager *settingsmgr =
  575. getServer(L)->getEmergeManager()->map_settings_mgr;
  576. lua_newtable(L);
  577. settingsmgr->getMapSetting("mg_name", &value);
  578. lua_pushstring(L, value.c_str());
  579. lua_setfield(L, -2, "mgname");
  580. settingsmgr->getMapSetting("seed", &value);
  581. u64 seed = from_string<u64>(value);
  582. lua_pushinteger(L, seed);
  583. lua_setfield(L, -2, "seed");
  584. settingsmgr->getMapSetting("water_level", &value);
  585. lua_pushinteger(L, stoi(value, -32768, 32767));
  586. lua_setfield(L, -2, "water_level");
  587. settingsmgr->getMapSetting("chunksize", &value);
  588. lua_pushinteger(L, stoi(value, -32768, 32767));
  589. lua_setfield(L, -2, "chunksize");
  590. settingsmgr->getMapSetting("mg_flags", &value);
  591. lua_pushstring(L, value.c_str());
  592. lua_setfield(L, -2, "flags");
  593. return 1;
  594. }
  595. // set_mapgen_params(params)
  596. // set mapgen parameters
  597. int ModApiMapgen::l_set_mapgen_params(lua_State *L)
  598. {
  599. NO_MAP_LOCK_REQUIRED;
  600. log_deprecated(L, "set_mapgen_params is deprecated; "
  601. "use set_mapgen_setting instead");
  602. if (!lua_istable(L, 1))
  603. return 0;
  604. MapSettingsManager *settingsmgr =
  605. getServer(L)->getEmergeManager()->map_settings_mgr;
  606. lua_getfield(L, 1, "mgname");
  607. if (lua_isstring(L, -1))
  608. settingsmgr->setMapSetting("mg_name", readParam<std::string>(L, -1), true);
  609. lua_getfield(L, 1, "seed");
  610. if (lua_isnumber(L, -1))
  611. settingsmgr->setMapSetting("seed", readParam<std::string>(L, -1), true);
  612. lua_getfield(L, 1, "water_level");
  613. if (lua_isnumber(L, -1))
  614. settingsmgr->setMapSetting("water_level", readParam<std::string>(L, -1), true);
  615. lua_getfield(L, 1, "chunksize");
  616. if (lua_isnumber(L, -1))
  617. settingsmgr->setMapSetting("chunksize", readParam<std::string>(L, -1), true);
  618. lua_getfield(L, 1, "flags");
  619. if (lua_isstring(L, -1))
  620. settingsmgr->setMapSetting("mg_flags", readParam<std::string>(L, -1), true);
  621. return 0;
  622. }
  623. // get_mapgen_setting(name)
  624. int ModApiMapgen::l_get_mapgen_setting(lua_State *L)
  625. {
  626. NO_MAP_LOCK_REQUIRED;
  627. std::string value;
  628. MapSettingsManager *settingsmgr =
  629. getServer(L)->getEmergeManager()->map_settings_mgr;
  630. const char *name = luaL_checkstring(L, 1);
  631. if (!settingsmgr->getMapSetting(name, &value))
  632. return 0;
  633. lua_pushstring(L, value.c_str());
  634. return 1;
  635. }
  636. // get_mapgen_setting_noiseparams(name)
  637. int ModApiMapgen::l_get_mapgen_setting_noiseparams(lua_State *L)
  638. {
  639. NO_MAP_LOCK_REQUIRED;
  640. NoiseParams np;
  641. MapSettingsManager *settingsmgr =
  642. getServer(L)->getEmergeManager()->map_settings_mgr;
  643. const char *name = luaL_checkstring(L, 1);
  644. if (!settingsmgr->getMapSettingNoiseParams(name, &np))
  645. return 0;
  646. push_noiseparams(L, &np);
  647. return 1;
  648. }
  649. // set_mapgen_setting(name, value, override_meta)
  650. // set mapgen config values
  651. int ModApiMapgen::l_set_mapgen_setting(lua_State *L)
  652. {
  653. NO_MAP_LOCK_REQUIRED;
  654. MapSettingsManager *settingsmgr =
  655. getServer(L)->getEmergeManager()->map_settings_mgr;
  656. const char *name = luaL_checkstring(L, 1);
  657. const char *value = luaL_checkstring(L, 2);
  658. bool override_meta = readParam<bool>(L, 3, false);
  659. if (!settingsmgr->setMapSetting(name, value, override_meta)) {
  660. errorstream << "set_mapgen_setting: cannot set '"
  661. << name << "' after initialization" << std::endl;
  662. }
  663. return 0;
  664. }
  665. // set_mapgen_setting_noiseparams(name, noiseparams, set_default)
  666. // set mapgen config values for noise parameters
  667. int ModApiMapgen::l_set_mapgen_setting_noiseparams(lua_State *L)
  668. {
  669. NO_MAP_LOCK_REQUIRED;
  670. MapSettingsManager *settingsmgr =
  671. getServer(L)->getEmergeManager()->map_settings_mgr;
  672. const char *name = luaL_checkstring(L, 1);
  673. NoiseParams np;
  674. if (!read_noiseparams(L, 2, &np)) {
  675. errorstream << "set_mapgen_setting_noiseparams: cannot set '" << name
  676. << "'; invalid noiseparams table" << std::endl;
  677. return 0;
  678. }
  679. bool override_meta = readParam<bool>(L, 3, false);
  680. if (!settingsmgr->setMapSettingNoiseParams(name, &np, override_meta)) {
  681. errorstream << "set_mapgen_setting_noiseparams: cannot set '"
  682. << name << "' after initialization" << std::endl;
  683. }
  684. return 0;
  685. }
  686. // set_noiseparams(name, noiseparams, set_default)
  687. // set global config values for noise parameters
  688. int ModApiMapgen::l_set_noiseparams(lua_State *L)
  689. {
  690. NO_MAP_LOCK_REQUIRED;
  691. const char *name = luaL_checkstring(L, 1);
  692. NoiseParams np;
  693. if (!read_noiseparams(L, 2, &np)) {
  694. errorstream << "set_noiseparams: cannot set '" << name
  695. << "'; invalid noiseparams table" << std::endl;
  696. return 0;
  697. }
  698. bool set_default = !lua_isboolean(L, 3) || readParam<bool>(L, 3);
  699. Settings::getLayer(set_default ? SL_DEFAULTS : SL_GLOBAL)->setNoiseParams(name, np);
  700. return 0;
  701. }
  702. // get_noiseparams(name)
  703. int ModApiMapgen::l_get_noiseparams(lua_State *L)
  704. {
  705. NO_MAP_LOCK_REQUIRED;
  706. std::string name = luaL_checkstring(L, 1);
  707. NoiseParams np;
  708. if (!g_settings->getNoiseParams(name, np))
  709. return 0;
  710. push_noiseparams(L, &np);
  711. return 1;
  712. }
  713. // set_gen_notify(flags, {deco_id_table})
  714. int ModApiMapgen::l_set_gen_notify(lua_State *L)
  715. {
  716. NO_MAP_LOCK_REQUIRED;
  717. u32 flags = 0, flagmask = 0;
  718. EmergeManager *emerge = getServer(L)->getEmergeManager();
  719. if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
  720. emerge->gen_notify_on &= ~flagmask;
  721. emerge->gen_notify_on |= flags;
  722. }
  723. if (lua_istable(L, 2)) {
  724. lua_pushnil(L);
  725. while (lua_next(L, 2)) {
  726. if (lua_isnumber(L, -1))
  727. emerge->gen_notify_on_deco_ids.insert((u32)lua_tonumber(L, -1));
  728. lua_pop(L, 1);
  729. }
  730. }
  731. return 0;
  732. }
  733. // get_gen_notify()
  734. int ModApiMapgen::l_get_gen_notify(lua_State *L)
  735. {
  736. NO_MAP_LOCK_REQUIRED;
  737. EmergeManager *emerge = getServer(L)->getEmergeManager();
  738. push_flags_string(L, flagdesc_gennotify, emerge->gen_notify_on,
  739. emerge->gen_notify_on);
  740. lua_newtable(L);
  741. int i = 1;
  742. for (u32 gen_notify_on_deco_id : emerge->gen_notify_on_deco_ids) {
  743. lua_pushnumber(L, gen_notify_on_deco_id);
  744. lua_rawseti(L, -2, i++);
  745. }
  746. return 2;
  747. }
  748. // get_decoration_id(decoration_name)
  749. // returns the decoration ID as used in gennotify
  750. int ModApiMapgen::l_get_decoration_id(lua_State *L)
  751. {
  752. NO_MAP_LOCK_REQUIRED;
  753. const char *deco_str = luaL_checkstring(L, 1);
  754. if (!deco_str)
  755. return 0;
  756. const DecorationManager *dmgr =
  757. getServer(L)->getEmergeManager()->getDecorationManager();
  758. if (!dmgr)
  759. return 0;
  760. Decoration *deco = (Decoration *)dmgr->getByName(deco_str);
  761. if (!deco)
  762. return 0;
  763. lua_pushinteger(L, deco->index);
  764. return 1;
  765. }
  766. // register_biome({lots of stuff})
  767. int ModApiMapgen::l_register_biome(lua_State *L)
  768. {
  769. NO_MAP_LOCK_REQUIRED;
  770. int index = 1;
  771. luaL_checktype(L, index, LUA_TTABLE);
  772. const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
  773. BiomeManager *bmgr = getServer(L)->getEmergeManager()->getWritableBiomeManager();
  774. Biome *biome = read_biome_def(L, index, ndef);
  775. if (!biome)
  776. return 0;
  777. ObjDefHandle handle = bmgr->add(biome);
  778. if (handle == OBJDEF_INVALID_HANDLE) {
  779. delete biome;
  780. return 0;
  781. }
  782. lua_pushinteger(L, handle);
  783. return 1;
  784. }
  785. // register_decoration({lots of stuff})
  786. int ModApiMapgen::l_register_decoration(lua_State *L)
  787. {
  788. NO_MAP_LOCK_REQUIRED;
  789. int index = 1;
  790. luaL_checktype(L, index, LUA_TTABLE);
  791. const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
  792. EmergeManager *emerge = getServer(L)->getEmergeManager();
  793. DecorationManager *decomgr = emerge->getWritableDecorationManager();
  794. BiomeManager *biomemgr = emerge->getWritableBiomeManager();
  795. SchematicManager *schemmgr = emerge->getWritableSchematicManager();
  796. enum DecorationType decotype = (DecorationType)getenumfield(L, index,
  797. "deco_type", es_DecorationType, -1);
  798. Decoration *deco = decomgr->create(decotype);
  799. if (!deco) {
  800. errorstream << "register_decoration: decoration placement type "
  801. << decotype << " not implemented" << std::endl;
  802. return 0;
  803. }
  804. deco->name = getstringfield_default(L, index, "name", "");
  805. deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
  806. deco->y_min = getintfield_default(L, index, "y_min", -31000);
  807. deco->y_max = getintfield_default(L, index, "y_max", 31000);
  808. deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
  809. deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);
  810. deco->sidelen = getintfield_default(L, index, "sidelen", 8);
  811. if (deco->sidelen <= 0) {
  812. errorstream << "register_decoration: sidelen must be "
  813. "greater than 0" << std::endl;
  814. delete deco;
  815. return 0;
  816. }
  817. //// Get node name(s) to place decoration on
  818. size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames);
  819. deco->m_nnlistsizes.push_back(nread);
  820. //// Get decoration flags
  821. getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL);
  822. //// Get NoiseParams to define how decoration is placed
  823. lua_getfield(L, index, "noise_params");
  824. if (read_noiseparams(L, -1, &deco->np))
  825. deco->flags |= DECO_USE_NOISE;
  826. lua_pop(L, 1);
  827. //// Get biomes associated with this decoration (if any)
  828. lua_getfield(L, index, "biomes");
  829. if (get_biome_list(L, -1, biomemgr, &deco->biomes))
  830. infostream << "register_decoration: couldn't get all biomes " << std::endl;
  831. lua_pop(L, 1);
  832. //// Get node name(s) to 'spawn by'
  833. size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames);
  834. deco->m_nnlistsizes.push_back(nnames);
  835. if (nnames == 0 && deco->nspawnby != -1) {
  836. errorstream << "register_decoration: no spawn_by nodes defined,"
  837. " but num_spawn_by specified" << std::endl;
  838. }
  839. //// Handle decoration type-specific parameters
  840. bool success = false;
  841. switch (decotype) {
  842. case DECO_SIMPLE:
  843. success = read_deco_simple(L, (DecoSimple *)deco);
  844. break;
  845. case DECO_SCHEMATIC:
  846. success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco);
  847. break;
  848. case DECO_LSYSTEM:
  849. break;
  850. }
  851. if (!success) {
  852. delete deco;
  853. return 0;
  854. }
  855. ndef->pendNodeResolve(deco);
  856. ObjDefHandle handle = decomgr->add(deco);
  857. if (handle == OBJDEF_INVALID_HANDLE) {
  858. delete deco;
  859. return 0;
  860. }
  861. lua_pushinteger(L, handle);
  862. return 1;
  863. }
  864. bool read_deco_simple(lua_State *L, DecoSimple *deco)
  865. {
  866. int index = 1;
  867. int param2;
  868. int param2_max;
  869. deco->deco_height = getintfield_default(L, index, "height", 1);
  870. deco->deco_height_max = getintfield_default(L, index, "height_max", 0);
  871. if (deco->deco_height <= 0) {
  872. errorstream << "register_decoration: simple decoration height"
  873. " must be greater than 0" << std::endl;
  874. return false;
  875. }
  876. size_t nnames = getstringlistfield(L, index, "decoration", &deco->m_nodenames);
  877. deco->m_nnlistsizes.push_back(nnames);
  878. if (nnames == 0) {
  879. errorstream << "register_decoration: no decoration nodes "
  880. "defined" << std::endl;
  881. return false;
  882. }
  883. param2 = getintfield_default(L, index, "param2", 0);
  884. param2_max = getintfield_default(L, index, "param2_max", 0);
  885. if (param2 < 0 || param2 > 255 || param2_max < 0 || param2_max > 255) {
  886. errorstream << "register_decoration: param2 or param2_max out of bounds (0-255)"
  887. << std::endl;
  888. return false;
  889. }
  890. deco->deco_param2 = (u8)param2;
  891. deco->deco_param2_max = (u8)param2_max;
  892. return true;
  893. }
  894. bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco)
  895. {
  896. int index = 1;
  897. deco->rotation = (Rotation)getenumfield(L, index, "rotation",
  898. ModApiMapgen::es_Rotation, ROTATE_0);
  899. StringMap replace_names;
  900. lua_getfield(L, index, "replacements");
  901. if (lua_istable(L, -1))
  902. read_schematic_replacements(L, -1, &replace_names);
  903. lua_pop(L, 1);
  904. lua_getfield(L, index, "schematic");
  905. Schematic *schem = get_or_load_schematic(L, -1, schemmgr, &replace_names);
  906. lua_pop(L, 1);
  907. deco->schematic = schem;
  908. return schem != NULL;
  909. }
  910. // register_ore({lots of stuff})
  911. int ModApiMapgen::l_register_ore(lua_State *L)
  912. {
  913. NO_MAP_LOCK_REQUIRED;
  914. int index = 1;
  915. luaL_checktype(L, index, LUA_TTABLE);
  916. const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
  917. EmergeManager *emerge = getServer(L)->getEmergeManager();
  918. BiomeManager *bmgr = emerge->getWritableBiomeManager();
  919. OreManager *oremgr = emerge->getWritableOreManager();
  920. enum OreType oretype = (OreType)getenumfield(L, index,
  921. "ore_type", es_OreType, ORE_SCATTER);
  922. Ore *ore = oremgr->create(oretype);
  923. if (!ore) {
  924. errorstream << "register_ore: ore_type " << oretype << " not implemented\n";
  925. return 0;
  926. }
  927. ore->name = getstringfield_default(L, index, "name", "");
  928. ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
  929. ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
  930. ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
  931. ore->clust_size = getintfield_default(L, index, "clust_size", 0);
  932. ore->noise = NULL;
  933. ore->flags = 0;
  934. //// Get noise_threshold
  935. warn_if_field_exists(L, index, "noise_threshhold",
  936. "Deprecated: new name is \"noise_threshold\".");
  937. float nthresh;
  938. if (!getfloatfield(L, index, "noise_threshold", nthresh) &&
  939. !getfloatfield(L, index, "noise_threshhold", nthresh))
  940. nthresh = 0;
  941. ore->nthresh = nthresh;
  942. //// Get y_min/y_max
  943. warn_if_field_exists(L, index, "height_min",
  944. "Deprecated: new name is \"y_min\".");
  945. warn_if_field_exists(L, index, "height_max",
  946. "Deprecated: new name is \"y_max\".");
  947. int ymin, ymax;
  948. if (!getintfield(L, index, "y_min", ymin) &&
  949. !getintfield(L, index, "height_min", ymin))
  950. ymin = -31000;
  951. if (!getintfield(L, index, "y_max", ymax) &&
  952. !getintfield(L, index, "height_max", ymax))
  953. ymax = 31000;
  954. ore->y_min = ymin;
  955. ore->y_max = ymax;
  956. if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
  957. errorstream << "register_ore: clust_scarcity and clust_num_ores"
  958. "must be greater than 0" << std::endl;
  959. delete ore;
  960. return 0;
  961. }
  962. //// Get flags
  963. getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);
  964. //// Get biomes associated with this decoration (if any)
  965. lua_getfield(L, index, "biomes");
  966. if (get_biome_list(L, -1, bmgr, &ore->biomes))
  967. infostream << "register_ore: couldn't get all biomes " << std::endl;
  968. lua_pop(L, 1);
  969. //// Get noise parameters if needed
  970. lua_getfield(L, index, "noise_params");
  971. if (read_noiseparams(L, -1, &ore->np)) {
  972. ore->flags |= OREFLAG_USE_NOISE;
  973. } else if (ore->needs_noise) {
  974. log_deprecated(L,
  975. "register_ore: ore type requires 'noise_params' but it is not specified, falling back to defaults");
  976. }
  977. lua_pop(L, 1);
  978. //// Get type-specific parameters
  979. switch (oretype) {
  980. case ORE_SHEET: {
  981. OreSheet *oresheet = (OreSheet *)ore;
  982. oresheet->column_height_min = getintfield_default(L, index,
  983. "column_height_min", 1);
  984. oresheet->column_height_max = getintfield_default(L, index,
  985. "column_height_max", ore->clust_size);
  986. oresheet->column_midpoint_factor = getfloatfield_default(L, index,
  987. "column_midpoint_factor", 0.5f);
  988. break;
  989. }
  990. case ORE_PUFF: {
  991. OrePuff *orepuff = (OrePuff *)ore;
  992. lua_getfield(L, index, "np_puff_top");
  993. read_noiseparams(L, -1, &orepuff->np_puff_top);
  994. lua_pop(L, 1);
  995. lua_getfield(L, index, "np_puff_bottom");
  996. read_noiseparams(L, -1, &orepuff->np_puff_bottom);
  997. lua_pop(L, 1);
  998. break;
  999. }
  1000. case ORE_VEIN: {
  1001. OreVein *orevein = (OreVein *)ore;
  1002. orevein->random_factor = getfloatfield_default(L, index,
  1003. "random_factor", 1.f);
  1004. break;
  1005. }
  1006. case ORE_STRATUM: {
  1007. OreStratum *orestratum = (OreStratum *)ore;
  1008. lua_getfield(L, index, "np_stratum_thickness");
  1009. if (read_noiseparams(L, -1, &orestratum->np_stratum_thickness))
  1010. ore->flags |= OREFLAG_USE_NOISE2;
  1011. lua_pop(L, 1);
  1012. orestratum->stratum_thickness = getintfield_default(L, index,
  1013. "stratum_thickness", 8);
  1014. break;
  1015. }
  1016. default:
  1017. break;
  1018. }
  1019. ObjDefHandle handle = oremgr->add(ore);
  1020. if (handle == OBJDEF_INVALID_HANDLE) {
  1021. delete ore;
  1022. return 0;
  1023. }
  1024. ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", ""));
  1025. size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames);
  1026. ore->m_nnlistsizes.push_back(nnames);
  1027. ndef->pendNodeResolve(ore);
  1028. lua_pushinteger(L, handle);
  1029. return 1;
  1030. }
  1031. // register_schematic({schematic}, replacements={})
  1032. int ModApiMapgen::l_register_schematic(lua_State *L)
  1033. {
  1034. NO_MAP_LOCK_REQUIRED;
  1035. SchematicManager *schemmgr =
  1036. getServer(L)->getEmergeManager()->getWritableSchematicManager();
  1037. StringMap replace_names;
  1038. if (lua_istable(L, 2))
  1039. read_schematic_replacements(L, 2, &replace_names);
  1040. Schematic *schem = load_schematic(L, 1, schemmgr->getNodeDef(),
  1041. &replace_names);
  1042. if (!schem)
  1043. return 0;
  1044. ObjDefHandle handle = schemmgr->add(schem);
  1045. if (handle == OBJDEF_INVALID_HANDLE) {
  1046. delete schem;
  1047. return 0;
  1048. }
  1049. lua_pushinteger(L, handle);
  1050. return 1;
  1051. }
  1052. // clear_registered_biomes()
  1053. int ModApiMapgen::l_clear_registered_biomes(lua_State *L)
  1054. {
  1055. NO_MAP_LOCK_REQUIRED;
  1056. BiomeManager *bmgr =
  1057. getServer(L)->getEmergeManager()->getWritableBiomeManager();
  1058. bmgr->clear();
  1059. return 0;
  1060. }
  1061. // clear_registered_decorations()
  1062. int ModApiMapgen::l_clear_registered_decorations(lua_State *L)
  1063. {
  1064. NO_MAP_LOCK_REQUIRED;
  1065. DecorationManager *dmgr =
  1066. getServer(L)->getEmergeManager()->getWritableDecorationManager();
  1067. dmgr->clear();
  1068. return 0;
  1069. }
  1070. // clear_registered_ores()
  1071. int ModApiMapgen::l_clear_registered_ores(lua_State *L)
  1072. {
  1073. NO_MAP_LOCK_REQUIRED;
  1074. OreManager *omgr =
  1075. getServer(L)->getEmergeManager()->getWritableOreManager();
  1076. omgr->clear();
  1077. return 0;
  1078. }
  1079. // clear_registered_schematics()
  1080. int ModApiMapgen::l_clear_registered_schematics(lua_State *L)
  1081. {
  1082. NO_MAP_LOCK_REQUIRED;
  1083. SchematicManager *smgr =
  1084. getServer(L)->getEmergeManager()->getWritableSchematicManager();
  1085. smgr->clear();
  1086. return 0;
  1087. }
  1088. // generate_ores(vm, p1, p2, [ore_id])
  1089. int ModApiMapgen::l_generate_ores(lua_State *L)
  1090. {
  1091. NO_MAP_LOCK_REQUIRED;
  1092. EmergeManager *emerge = getServer(L)->getEmergeManager();
  1093. if (!emerge || !emerge->mgparams)
  1094. return 0;
  1095. Mapgen mg;
  1096. // Intentionally truncates to s32, see Mapgen::Mapgen()
  1097. mg.seed = (s32)emerge->mgparams->seed;
  1098. mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
  1099. mg.ndef = getServer(L)->getNodeDefManager();
  1100. v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) :
  1101. mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE;
  1102. v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) :
  1103. mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE;
  1104. sortBoxVerticies(pmin, pmax);
  1105. u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed);
  1106. emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax);
  1107. return 0;
  1108. }
  1109. // generate_decorations(vm, p1, p2, [deco_id])
  1110. int ModApiMapgen::l_generate_decorations(lua_State *L)
  1111. {
  1112. NO_MAP_LOCK_REQUIRED;
  1113. EmergeManager *emerge = getServer(L)->getEmergeManager();
  1114. if (!emerge || !emerge->mgparams)
  1115. return 0;
  1116. Mapgen mg;
  1117. // Intentionally truncates to s32, see Mapgen::Mapgen()
  1118. mg.seed = (s32)emerge->mgparams->seed;
  1119. mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
  1120. mg.ndef = getServer(L)->getNodeDefManager();
  1121. v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) :
  1122. mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE;
  1123. v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) :
  1124. mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE;
  1125. sortBoxVerticies(pmin, pmax);
  1126. u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed);
  1127. emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax);
  1128. return 0;
  1129. }
  1130. // create_schematic(p1, p2, probability_list, filename, y_slice_prob_list)
  1131. int ModApiMapgen::l_create_schematic(lua_State *L)
  1132. {
  1133. MAP_LOCK_REQUIRED;
  1134. const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
  1135. const char *filename = luaL_checkstring(L, 4);
  1136. CHECK_SECURE_PATH(L, filename, true);
  1137. Map *map = &(getEnv(L)->getMap());
  1138. Schematic schem;
  1139. v3s16 p1 = check_v3s16(L, 1);
  1140. v3s16 p2 = check_v3s16(L, 2);
  1141. sortBoxVerticies(p1, p2);
  1142. std::vector<std::pair<v3s16, u8> > prob_list;
  1143. if (lua_istable(L, 3)) {
  1144. lua_pushnil(L);
  1145. while (lua_next(L, 3)) {
  1146. if (lua_istable(L, -1)) {
  1147. lua_getfield(L, -1, "pos");
  1148. v3s16 pos = check_v3s16(L, -1);
  1149. lua_pop(L, 1);
  1150. u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
  1151. prob_list.emplace_back(pos, prob);
  1152. }
  1153. lua_pop(L, 1);
  1154. }
  1155. }
  1156. std::vector<std::pair<s16, u8> > slice_prob_list;
  1157. if (lua_istable(L, 5)) {
  1158. lua_pushnil(L);
  1159. while (lua_next(L, 5)) {
  1160. if (lua_istable(L, -1)) {
  1161. s16 ypos = getintfield_default(L, -1, "ypos", 0);
  1162. u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
  1163. slice_prob_list.emplace_back(ypos, prob);
  1164. }
  1165. lua_pop(L, 1);
  1166. }
  1167. }
  1168. if (!schem.getSchematicFromMap(map, p1, p2)) {
  1169. errorstream << "create_schematic: failed to get schematic "
  1170. "from map" << std::endl;
  1171. return 0;
  1172. }
  1173. schem.applyProbabilities(p1, &prob_list, &slice_prob_list);
  1174. schem.saveSchematicToFile(filename, ndef);
  1175. actionstream << "create_schematic: saved schematic file '"
  1176. << filename << "'." << std::endl;
  1177. lua_pushboolean(L, true);
  1178. return 1;
  1179. }
  1180. // place_schematic(p, schematic, rotation,
  1181. // replacements, force_placement, flagstring)
  1182. int ModApiMapgen::l_place_schematic(lua_State *L)
  1183. {
  1184. MAP_LOCK_REQUIRED;
  1185. GET_ENV_PTR;
  1186. ServerMap *map = &(env->getServerMap());
  1187. SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
  1188. //// Read position
  1189. v3s16 p = check_v3s16(L, 1);
  1190. //// Read rotation
  1191. int rot = ROTATE_0;
  1192. std::string enumstr = readParam<std::string>(L, 3, "");
  1193. if (!enumstr.empty())
  1194. string_to_enum(es_Rotation, rot, enumstr);
  1195. //// Read force placement
  1196. bool force_placement = true;
  1197. if (lua_isboolean(L, 5))
  1198. force_placement = readParam<bool>(L, 5);
  1199. //// Read node replacements
  1200. StringMap replace_names;
  1201. if (lua_istable(L, 4))
  1202. read_schematic_replacements(L, 4, &replace_names);
  1203. //// Read schematic
  1204. Schematic *schem = get_or_load_schematic(L, 2, schemmgr, &replace_names);
  1205. if (!schem) {
  1206. errorstream << "place_schematic: failed to get schematic" << std::endl;
  1207. return 0;
  1208. }
  1209. //// Read flags
  1210. u32 flags = 0;
  1211. read_flags(L, 6, flagdesc_deco, &flags, NULL);
  1212. schem->placeOnMap(map, p, flags, (Rotation)rot, force_placement);
  1213. lua_pushboolean(L, true);
  1214. return 1;
  1215. }
  1216. // place_schematic_on_vmanip(vm, p, schematic, rotation,
  1217. // replacements, force_placement, flagstring)
  1218. int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L)
  1219. {
  1220. NO_MAP_LOCK_REQUIRED;
  1221. SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
  1222. //// Read VoxelManip object
  1223. MMVManip *vm = LuaVoxelManip::checkobject(L, 1)->vm;
  1224. //// Read position
  1225. v3s16 p = check_v3s16(L, 2);
  1226. //// Read rotation
  1227. int rot = ROTATE_0;
  1228. std::string enumstr = readParam<std::string>(L, 4, "");
  1229. if (!enumstr.empty())
  1230. string_to_enum(es_Rotation, rot, std::string(enumstr));
  1231. //// Read force placement
  1232. bool force_placement = true;
  1233. if (lua_isboolean(L, 6))
  1234. force_placement = readParam<bool>(L, 6);
  1235. //// Read node replacements
  1236. StringMap replace_names;
  1237. if (lua_istable(L, 5))
  1238. read_schematic_replacements(L, 5, &replace_names);
  1239. //// Read schematic
  1240. Schematic *schem = get_or_load_schematic(L, 3, schemmgr, &replace_names);
  1241. if (!schem) {
  1242. errorstream << "place_schematic: failed to get schematic" << std::endl;
  1243. return 0;
  1244. }
  1245. //// Read flags
  1246. u32 flags = 0;
  1247. read_flags(L, 7, flagdesc_deco, &flags, NULL);
  1248. bool schematic_did_fit = schem->placeOnVManip(
  1249. vm, p, flags, (Rotation)rot, force_placement);
  1250. lua_pushboolean(L, schematic_did_fit);
  1251. return 1;
  1252. }
  1253. // serialize_schematic(schematic, format, options={...})
  1254. int ModApiMapgen::l_serialize_schematic(lua_State *L)
  1255. {
  1256. NO_MAP_LOCK_REQUIRED;
  1257. const SchematicManager *schemmgr = getServer(L)->getEmergeManager()->getSchematicManager();
  1258. //// Read options
  1259. bool use_comments = getboolfield_default(L, 3, "lua_use_comments", false);
  1260. u32 indent_spaces = getintfield_default(L, 3, "lua_num_indent_spaces", 0);
  1261. //// Get schematic
  1262. bool was_loaded = false;
  1263. const Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr);
  1264. if (!schem) {
  1265. schem = load_schematic(L, 1, NULL, NULL);
  1266. was_loaded = true;
  1267. }
  1268. if (!schem) {
  1269. errorstream << "serialize_schematic: failed to get schematic" << std::endl;
  1270. return 0;
  1271. }
  1272. //// Read format of definition to save as
  1273. int schem_format = SCHEM_FMT_MTS;
  1274. std::string enumstr = readParam<std::string>(L, 2, "");
  1275. if (!enumstr.empty())
  1276. string_to_enum(es_SchematicFormatType, schem_format, enumstr);
  1277. //// Serialize to binary string
  1278. std::ostringstream os(std::ios_base::binary);
  1279. switch (schem_format) {
  1280. case SCHEM_FMT_MTS:
  1281. schem->serializeToMts(&os);
  1282. break;
  1283. case SCHEM_FMT_LUA:
  1284. schem->serializeToLua(&os, use_comments, indent_spaces);
  1285. break;
  1286. default:
  1287. return 0;
  1288. }
  1289. if (was_loaded)
  1290. delete schem;
  1291. std::string ser = os.str();
  1292. lua_pushlstring(L, ser.c_str(), ser.length());
  1293. return 1;
  1294. }
  1295. // read_schematic(schematic, options={...})
  1296. int ModApiMapgen::l_read_schematic(lua_State *L)
  1297. {
  1298. NO_MAP_LOCK_REQUIRED;
  1299. const SchematicManager *schemmgr =
  1300. getServer(L)->getEmergeManager()->getSchematicManager();
  1301. //// Read options
  1302. std::string write_yslice = getstringfield_default(L, 2, "write_yslice_prob", "all");
  1303. //// Get schematic
  1304. bool was_loaded = false;
  1305. Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr);
  1306. if (!schem) {
  1307. schem = load_schematic(L, 1, NULL, NULL);
  1308. was_loaded = true;
  1309. }
  1310. if (!schem) {
  1311. errorstream << "read_schematic: failed to get schematic" << std::endl;
  1312. return 0;
  1313. }
  1314. lua_pop(L, 2);
  1315. //// Create the Lua table
  1316. u32 numnodes = schem->size.X * schem->size.Y * schem->size.Z;
  1317. const std::vector<std::string> &names = schem->m_nodenames;
  1318. lua_createtable(L, 0, (write_yslice == "none") ? 2 : 3);
  1319. // Create the size field
  1320. push_v3s16(L, schem->size);
  1321. lua_setfield(L, 1, "size");
  1322. // Create the yslice_prob field
  1323. if (write_yslice != "none") {
  1324. lua_createtable(L, schem->size.Y, 0);
  1325. for (u16 y = 0; y != schem->size.Y; ++y) {
  1326. u8 probability = schem->slice_probs[y] & MTSCHEM_PROB_MASK;
  1327. if (probability < MTSCHEM_PROB_ALWAYS || write_yslice != "low") {
  1328. lua_createtable(L, 0, 2);
  1329. lua_pushinteger(L, y);
  1330. lua_setfield(L, 3, "ypos");
  1331. lua_pushinteger(L, probability * 2);
  1332. lua_setfield(L, 3, "prob");
  1333. lua_rawseti(L, 2, y + 1);
  1334. }
  1335. }
  1336. lua_setfield(L, 1, "yslice_prob");
  1337. }
  1338. // Create the data field
  1339. lua_createtable(L, numnodes, 0); // data table
  1340. for (u32 i = 0; i < numnodes; ++i) {
  1341. MapNode node = schem->schemdata[i];
  1342. u8 probability = node.param1 & MTSCHEM_PROB_MASK;
  1343. bool force_place = node.param1 & MTSCHEM_FORCE_PLACE;
  1344. lua_createtable(L, 0, force_place ? 4 : 3);
  1345. lua_pushstring(L, names[schem->schemdata[i].getContent()].c_str());
  1346. lua_setfield(L, 3, "name");
  1347. lua_pushinteger(L, probability * 2);
  1348. lua_setfield(L, 3, "prob");
  1349. lua_pushinteger(L, node.param2);
  1350. lua_setfield(L, 3, "param2");
  1351. if (force_place) {
  1352. lua_pushboolean(L, 1);
  1353. lua_setfield(L, 3, "force_place");
  1354. }
  1355. lua_rawseti(L, 2, i + 1);
  1356. }
  1357. lua_setfield(L, 1, "data");
  1358. if (was_loaded)
  1359. delete schem;
  1360. return 1;
  1361. }
  1362. void ModApiMapgen::Initialize(lua_State *L, int top)
  1363. {
  1364. API_FCT(get_biome_id);
  1365. API_FCT(get_biome_name);
  1366. API_FCT(get_heat);
  1367. API_FCT(get_humidity);
  1368. API_FCT(get_biome_data);
  1369. API_FCT(get_mapgen_object);
  1370. API_FCT(get_spawn_level);
  1371. API_FCT(get_mapgen_params);
  1372. API_FCT(set_mapgen_params);
  1373. API_FCT(get_mapgen_setting);
  1374. API_FCT(set_mapgen_setting);
  1375. API_FCT(get_mapgen_setting_noiseparams);
  1376. API_FCT(set_mapgen_setting_noiseparams);
  1377. API_FCT(set_noiseparams);
  1378. API_FCT(get_noiseparams);
  1379. API_FCT(set_gen_notify);
  1380. API_FCT(get_gen_notify);
  1381. API_FCT(get_decoration_id);
  1382. API_FCT(register_biome);
  1383. API_FCT(register_decoration);
  1384. API_FCT(register_ore);
  1385. API_FCT(register_schematic);
  1386. API_FCT(clear_registered_biomes);
  1387. API_FCT(clear_registered_decorations);
  1388. API_FCT(clear_registered_ores);
  1389. API_FCT(clear_registered_schematics);
  1390. API_FCT(generate_ores);
  1391. API_FCT(generate_decorations);
  1392. API_FCT(create_schematic);
  1393. API_FCT(place_schematic);
  1394. API_FCT(place_schematic_on_vmanip);
  1395. API_FCT(serialize_schematic);
  1396. API_FCT(read_schematic);
  1397. }