// place_schematic(p, schematic, rotation) int ModApiBasic::l_place_schematic(lua_State *L) { DecoSchematic dschem; Map *map = &(getEnv(L)->getMap()); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); v3s16 p = read_v3s16(L, 1); if (!read_schematic(L, 2, &dschem, getServer(L))) return 0; Rotation rot = ROTATE_0; if (lua_isstring(L, 3)) string_to_enum(es_Rotation, (int &)rot, std::string(lua_tostring(L, 3))); dschem.rotation = rot; if (!dschem.filename.empty()) { if (!dschem.loadSchematicFile()) { errorstream << "place_schematic: failed to load schematic file '" << dschem.filename << "'" << std::endl; return 0; } dschem.resolveNodeNames(ndef); } dschem.placeStructure(map, p); return 1; }
// create_schematic(p1, p2, probability_list, filename) int ModApiMapgen::l_create_schematic(lua_State *L) { DecoSchematic dschem; Map *map = &(getEnv(L)->getMap()); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); v3s16 p1 = read_v3s16(L, 1); v3s16 p2 = read_v3s16(L, 2); sortBoxVerticies(p1, p2); std::vector<std::pair<v3s16, u8> > prob_list; if (lua_istable(L, 3)) { lua_pushnil(L); while (lua_next(L, 3)) { if (lua_istable(L, -1)) { lua_getfield(L, -1, "pos"); v3s16 pos = read_v3s16(L, -1); lua_pop(L, 1); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); prob_list.push_back(std::make_pair(pos, prob)); } lua_pop(L, 1); } } std::vector<std::pair<s16, u8> > slice_prob_list; if (lua_istable(L, 5)) { lua_pushnil(L); while (lua_next(L, 5)) { if (lua_istable(L, -1)) { s16 ypos = getintfield_default(L, -1, "ypos", 0); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); slice_prob_list.push_back(std::make_pair(ypos, prob)); } lua_pop(L, 1); } } const char *s = lua_tostring(L, 4); dschem.filename = std::string(s ? s : ""); if (!dschem.getSchematicFromMap(map, p1, p2)) { errorstream << "create_schematic: failed to get schematic " "from map" << std::endl; return 0; } dschem.applyProbabilities(p1, &prob_list, &slice_prob_list); dschem.saveSchematicFile(ndef); actionstream << "create_schematic: saved schematic file '" << dschem.filename << "'." << std::endl; return 1; }
// place_schematic(p, schematic, rotation, replacement) int ModApiMapgen::l_place_schematic(lua_State *L) { DecoSchematic dschem; Map *map = &(getEnv(L)->getMap()); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); v3s16 p = read_v3s16(L, 1); if (!read_schematic(L, 2, &dschem, getServer(L))) return 0; int rot = ROTATE_0; if (lua_isstring(L, 3)) string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3))); dschem.rotation = (Rotation)rot; if (lua_istable(L, 4)) { lua_pushnil(L); while (lua_next(L, 4) != 0) { // key at index -2 and value at index -1 lua_rawgeti(L, -1, 1); std::string replace_from = lua_tostring(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); std::string replace_to = lua_tostring(L, -1); lua_pop(L, 1); dschem.replacements[replace_from] = replace_to; // removes value, keeps key for next iteration lua_pop(L, 1); } } bool force_placement = true; if (lua_isboolean(L, 5)) force_placement = lua_toboolean(L, 5); if (!dschem.filename.empty()) { if (!dschem.loadSchematicFile()) { errorstream << "place_schematic: failed to load schematic file '" << dschem.filename << "'" << std::endl; return 0; } dschem.resolveNodeNames(ndef); } dschem.placeStructure(map, p, force_placement); return 1; }
// create_schematic(p1, p2, probability_list, filename) int ModApiBasic::l_create_schematic(lua_State *L) { DecoSchematic dschem; Map *map = &(getEnv(L)->getMap()); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); v3s16 p1 = read_v3s16(L, 1); v3s16 p2 = read_v3s16(L, 2); sortBoxVerticies(p1, p2); std::vector<std::pair<v3s16, s16> > probability_list; if (lua_istable(L, 3)) { lua_pushnil(L); while (lua_next(L, 3)) { if (lua_istable(L, -1)) { lua_getfield(L, -1, "pos"); v3s16 pos = read_v3s16(L, -1); lua_pop(L, 1); s16 prob = getintfield_default(L, -1, "prob", 0); if (prob < -1 || prob >= UCHAR_MAX) { errorstream << "create_schematic: probability value of " << prob << " at " << PP(pos) << " out of range" << std::endl; } else { probability_list.push_back(std::make_pair(pos, prob)); } } lua_pop(L, 1); } } dschem.filename = std::string(lua_tostring(L, 4)); if (!dschem.getSchematicFromMap(map, p1, p2)) { errorstream << "create_schematic: failed to get schematic " "from map" << std::endl; return 0; } dschem.applyProbabilities(&probability_list, p1); dschem.saveSchematicFile(ndef); actionstream << "create_schematic: saved schematic file '" << dschem.filename << "'." << std::endl; return 1; }
// register_decoration({lots of stuff}) int ModApiMapgen::l_register_decoration(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); EmergeManager *emerge = getServer(L)->getEmergeManager(); BiomeDefManager *bdef = emerge->biomedef; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); if (decotype == -1) { errorstream << "register_decoration: unrecognized " "decoration placement type"; return 0; } Decoration *deco = createDecoration(decotype); if (!deco) { errorstream << "register_decoration: decoration placement type " << decotype << " not implemented"; return 0; } deco->c_place_on = CONTENT_IGNORE; deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore"); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; delete deco; return 0; } lua_getfield(L, index, "noise_params"); deco->np = read_noiseparams(L, -1); lua_pop(L, 1); lua_getfield(L, index, "biomes"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { const char *s = lua_tostring(L, -1); u8 biomeid = bdef->getBiomeIdByName(s); if (biomeid) deco->biomes.insert(biomeid); lua_pop(L, 1); } lua_pop(L, 1); } switch (decotype) { case DECO_SIMPLE: { DecoSimple *dsimple = (DecoSimple *)deco; dsimple->c_deco = CONTENT_IGNORE; dsimple->c_spawnby = CONTENT_IGNORE; dsimple->spawnby_name = getstringfield_default(L, index, "spawn_by", "air"); dsimple->deco_height = getintfield_default(L, index, "height", 1); dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0); dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); lua_getfield(L, index, "decoration"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { const char *s = lua_tostring(L, -1); std::string str(s); dsimple->decolist_names.push_back(str); lua_pop(L, 1); } } else if (lua_isstring(L, -1)) { dsimple->deco_name = std::string(lua_tostring(L, -1)); } else { dsimple->deco_name = std::string("air"); } lua_pop(L, 1); if (dsimple->deco_height <= 0) { errorstream << "register_decoration: simple decoration height" " must be greater than 0" << std::endl; delete dsimple; return 0; } break; } case DECO_SCHEMATIC: { DecoSchematic *dschem = (DecoSchematic *)deco; dschem->flags = 0; getflagsfield(L, index, "flags", flagdesc_deco_schematic, &dschem->flags, NULL); dschem->rotation = (Rotation)getenumfield(L, index, "rotation", es_Rotation, ROTATE_0); lua_getfield(L, index, "replacements"); if (lua_istable(L, -1)) { int i = lua_gettop(L); lua_pushnil(L); while (lua_next(L, i) != 0) { // key at index -2 and value at index -1 lua_rawgeti(L, -1, 1); std::string replace_from = lua_tostring(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); std::string replace_to = lua_tostring(L, -1); lua_pop(L, 1); dschem->replacements[replace_from] = replace_to; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, index, "schematic"); if (!read_schematic(L, -1, dschem, getServer(L))) { delete dschem; return 0; } lua_pop(L, -1); if (!dschem->filename.empty() && !dschem->loadSchematicFile()) { errorstream << "register_decoration: failed to load schematic file '" << dschem->filename << "'" << std::endl; delete dschem; return 0; } break; } case DECO_LSYSTEM: { //DecoLSystem *decolsystem = (DecoLSystem *)deco; break; } } emerge->decorations.push_back(deco); verbosestream << "register_decoration: decoration '" << deco->getName() << "' registered" << std::endl; return 0; }