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