struct TileAnimationParams read_animation_definition(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; struct TileAnimationParams anim; anim.type = TAT_NONE; if (!lua_istable(L, index)) return anim; anim.type = (TileAnimationType) getenumfield(L, index, "type", es_TileAnimationType, TAT_NONE); if (anim.type == TAT_VERTICAL_FRAMES) { // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} anim.vertical_frames.aspect_w = getintfield_default(L, index, "aspect_w", 16); anim.vertical_frames.aspect_h = getintfield_default(L, index, "aspect_h", 16); anim.vertical_frames.length = getfloatfield_default(L, index, "length", 1.0); } else if (anim.type == TAT_SHEET_2D) { // {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5} getintfield(L, index, "frames_w", anim.sheet_2d.frames_w); getintfield(L, index, "frames_h", anim.sheet_2d.frames_h); getfloatfield(L, index, "frame_length", anim.sheet_2d.frame_length); } return anim; }
bool read_noiseparams(lua_State *L, int index, NoiseParams *np) { if (index < 0) index = lua_gettop(L) + 1 + index; if (!lua_istable(L, index)) return false; getfloatfield(L, index, "offset", np->offset); getfloatfield(L, index, "scale", np->scale); getfloatfield(L, index, "persist", np->persist); getfloatfield(L, index, "persistence", np->persist); getfloatfield(L, index, "lacunarity", np->lacunarity); getintfield(L, index, "seed", np->seed); getintfield(L, index, "octaves", np->octaves); //freeminer: getfloatfield(L, index, "farscale", np->farscale); getfloatfield(L, index, "farspread", np->farspread); getfloatfield(L, index, "farpersist", np->farpersist); u32 flags = 0; u32 flagmask = 0; np->flags = getflagsfield(L, index, "flags", flagdesc_noiseparams, &flags, &flagmask) ? flags : NOISE_FLAG_DEFAULTS; lua_getfield(L, index, "spread"); np->spread = read_v3f(L, -1); lua_pop(L, 1); return true; }
int getintfield_default(lua_State *L, int table, const char *fieldname, int default_) { int result = default_; getintfield(L, table, fieldname, result); return result; }
// spawn_tree(pos, treedef) int ModApiEnvMod::l_spawn_tree(lua_State *L) { GET_ENV_PTR; v3s16 p0 = read_v3s16(L, 1); treegen::TreeDef tree_def; std::string trunk,leaves,fruit; INodeDefManager *ndef = env->getGameDef()->ndef(); if(lua_istable(L, 2)) { getstringfield(L, 2, "axiom", tree_def.initial_axiom); getstringfield(L, 2, "rules_a", tree_def.rules_a); getstringfield(L, 2, "rules_b", tree_def.rules_b); getstringfield(L, 2, "rules_c", tree_def.rules_c); getstringfield(L, 2, "rules_d", tree_def.rules_d); getstringfield(L, 2, "trunk", trunk); tree_def.trunknode=ndef->getId(trunk); getstringfield(L, 2, "leaves", leaves); tree_def.leavesnode=ndef->getId(leaves); tree_def.leaves2_chance=0; getstringfield(L, 2, "leaves2", leaves); if (leaves !="") { tree_def.leaves2node=ndef->getId(leaves); getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance); } getintfield(L, 2, "angle", tree_def.angle); getintfield(L, 2, "iterations", tree_def.iterations); if (!getintfield(L, 2, "random_level", tree_def.iterations_random_level)) tree_def.iterations_random_level = 0; getstringfield(L, 2, "trunk_type", tree_def.trunk_type); getboolfield(L, 2, "thin_branches", tree_def.thin_branches); tree_def.fruit_chance=0; getstringfield(L, 2, "fruit", fruit); if (fruit != "") { tree_def.fruitnode=ndef->getId(fruit); getintfield(L, 2, "fruit_chance",tree_def.fruit_chance); } tree_def.explicit_seed = getintfield(L, 2, "seed", tree_def.seed); } else return 0; treegen::error e; if ((e = treegen::spawn_ltree (env, p0, ndef, tree_def)) != treegen::SUCCESS) { if (e == treegen::UNBALANCED_BRACKETS) { luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket"); } else { luaL_error(L, "spawn_tree(): unknown error"); } } return 1; }
// spawn_tree(pos, treedef) int ModApiEnvMod::l_spawn_tree(lua_State *L) { GET_ENV_PTR; v3s16 p0 = read_v3s16(L, 1); treegen::TreeDef tree_def; std::string trunk,leaves,fruit; INodeDefManager *ndef = env->getGameDef()->ndef(); if(lua_istable(L, 2)) { getstringfield(L, 2, "axiom", tree_def.initial_axiom); getstringfield(L, 2, "rules_a", tree_def.rules_a); getstringfield(L, 2, "rules_b", tree_def.rules_b); getstringfield(L, 2, "rules_c", tree_def.rules_c); getstringfield(L, 2, "rules_d", tree_def.rules_d); getstringfield(L, 2, "trunk", trunk); tree_def.trunknode=ndef->getId(trunk); getstringfield(L, 2, "leaves", leaves); tree_def.leavesnode=ndef->getId(leaves); tree_def.leaves2_chance=0; getstringfield(L, 2, "leaves2", leaves); if (leaves !="") { tree_def.leaves2node=ndef->getId(leaves); getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance); } getintfield(L, 2, "angle", tree_def.angle); getintfield(L, 2, "iterations", tree_def.iterations); getintfield(L, 2, "random_level", tree_def.iterations_random_level); getstringfield(L, 2, "trunk_type", tree_def.trunk_type); getboolfield(L, 2, "thin_branches", tree_def.thin_branches); tree_def.fruit_chance=0; getstringfield(L, 2, "fruit", fruit); if (fruit != "") { tree_def.fruitnode=ndef->getId(fruit); getintfield(L, 2, "fruit_chance",tree_def.fruit_chance); } getintfield(L, 2, "seed", tree_def.seed); } else return 0; treegen::spawn_ltree (env, p0, ndef, tree_def); return 1; }
bool read_schematic_def(lua_State *L, int index, Schematic *schem, std::vector<std::string> *names) { if (!lua_istable(L, index)) return false; //// Get schematic size lua_getfield(L, index, "size"); v3s16 size = check_v3s16(L, -1); lua_pop(L, 1); schem->size = size; //// Get schematic data lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); u32 numnodes = size.X * size.Y * size.Z; schem->schemdata = new MapNode[numnodes]; size_t names_base = names->size(); UNORDERED_MAP<std::string, content_t> name_id_map; u32 i = 0; for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) { if (i >= numnodes) continue; //// Read name std::string name; if (!getstringfield(L, -1, "name", name)) throw LuaError("Schematic data definition with missing name field"); //// Read param1/prob u8 param1; if (!getintfield(L, -1, "param1", param1) && !getintfield(L, -1, "prob", param1)) param1 = MTSCHEM_PROB_ALWAYS_OLD; //// Read param2 u8 param2 = getintfield_default(L, -1, "param2", 0); //// Find or add new nodename-to-ID mapping UNORDERED_MAP<std::string, content_t>::iterator it = name_id_map.find(name); content_t name_index; if (it != name_id_map.end()) { name_index = it->second; } else { name_index = names->size() - names_base; name_id_map[name] = name_index; names->push_back(name); } //// Perform probability/force_place fixup on param1 param1 >>= 1; if (getboolfield_default(L, -1, "force_place", false)) param1 |= MTSCHEM_FORCE_PLACE; //// Actually set the node in the schematic schem->schemdata[i] = MapNode(name_index, param1, param2); } if (i != numnodes) { errorstream << "read_schematic_def: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } //// Get Y-slice probability values (if present) schem->slice_probs = new u8[size.Y]; for (i = 0; i != (u32) size.Y; i++) schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS; lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { u16 ypos; if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) || !getintfield(L, -1, "prob", schem->slice_probs[ypos])) continue; schem->slice_probs[ypos] >>= 1; } } return true; }
// register_ore({lots of stuff}) int ModApiMapgen::l_register_ore(lua_State *L) { NO_MAP_LOCK_REQUIRED; int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = oremgr->create(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented\n"; return 0; } ore->name = getstringfield_default(L, index, "name", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->noise = NULL; ore->flags = 0; //// Get noise_threshold warn_if_field_exists(L, index, "noise_threshhold", "Deprecated: new name is \"noise_threshold\"."); float nthresh; if (!getfloatfield(L, index, "noise_threshold", nthresh) && !getfloatfield(L, index, "noise_threshhold", nthresh)) nthresh = 0; ore->nthresh = nthresh; //// Get y_min/y_max warn_if_field_exists(L, index, "height_min", "Deprecated: new name is \"y_min\"."); warn_if_field_exists(L, index, "height_max", "Deprecated: new name is \"y_max\"."); int ymin, ymax; if (!getintfield(L, index, "y_min", ymin) && !getintfield(L, index, "height_min", ymin)) ymin = -31000; if (!getintfield(L, index, "y_max", ymax) && !getintfield(L, index, "height_max", ymax)) ymax = 31000; ore->y_min = ymin; ore->y_max = ymax; if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { errorstream << "register_ore: clust_scarcity and clust_num_ores" "must be greater than 0" << std::endl; delete ore; return 0; } //// Get flags getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, bmgr, &ore->biomes)) errorstream << "register_ore: couldn't get all biomes " << std::endl; lua_pop(L, 1); //// Get noise parameters if needed lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &ore->np)) { ore->flags |= OREFLAG_USE_NOISE; } else if (ore->NEEDS_NOISE) { errorstream << "register_ore: specified ore type requires valid " "noise parameters" << std::endl; delete ore; return 0; } lua_pop(L, 1); //// Get type-specific parameters switch (oretype) { case ORE_SHEET: { OreSheet *oresheet = (OreSheet *)ore; oresheet->column_height_min = getintfield_default(L, index, "column_height_min", 1); oresheet->column_height_max = getintfield_default(L, index, "column_height_max", ore->clust_size); oresheet->column_midpoint_factor = getfloatfield_default(L, index, "column_midpoint_factor", 0.5f); break; } case ORE_PUFF: { OrePuff *orepuff = (OrePuff *)ore; lua_getfield(L, index, "np_puff_top"); read_noiseparams(L, -1, &orepuff->np_puff_top); lua_pop(L, 1); lua_getfield(L, index, "np_puff_bottom"); read_noiseparams(L, -1, &orepuff->np_puff_bottom); lua_pop(L, 1); break; } case ORE_VEIN: { OreVein *orevein = (OreVein *)ore; orevein->random_factor = getfloatfield_default(L, index, "random_factor", 1.f); break; } default: break; } ObjDefHandle handle = oremgr->add(ore); if (handle == OBJDEF_INVALID_HANDLE) { delete ore; return 0; } ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", "")); size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames); ore->m_nnlistsizes.push_back(nnames); ndef->pendNodeResolve(ore); lua_pushinteger(L, handle); return 1; }
bool read_schematic(lua_State *L, int index, Schematic *schem, INodeDefManager *ndef, std::map<std::string, std::string> &replace_names) { //// Get schematic size lua_getfield(L, index, "size"); v3s16 size = read_v3s16(L, -1); lua_pop(L, 1); //// Get schematic data lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); int numnodes = size.X * size.Y * size.Z; MapNode *schemdata = new MapNode[numnodes]; int i = 0; lua_pushnil(L); while (lua_next(L, -2)) { if (i >= numnodes) { i++; lua_pop(L, 1); continue; } // same as readnode, except param1 default is MTSCHEM_PROB_CONST lua_getfield(L, -1, "name"); std::string name = luaL_checkstring(L, -1); lua_pop(L, 1); u8 param1; lua_getfield(L, -1, "param1"); param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS; lua_pop(L, 1); u8 param2; lua_getfield(L, -1, "param2"); param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0; lua_pop(L, 1); std::map<std::string, std::string>::iterator it; it = replace_names.find(name); if (it != replace_names.end()) name = it->second; schemdata[i] = MapNode(ndef, name, param1, param2); i++; lua_pop(L, 1); } if (i != numnodes) { errorstream << "read_schematic: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; delete schemdata; return false; } //// Get Y-slice probability values (if present) u8 *slice_probs = new u8[size.Y]; for (i = 0; i != size.Y; i++) slice_probs[i] = MTSCHEM_PROB_ALWAYS; lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) { slice_probs[i] = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); } lua_pop(L, 1); } } // Here, we read the nodes directly from the INodeDefManager - there is no // need for pending node resolutions so we'll mark this schematic as updated schem->flags = SCHEM_CIDS_UPDATED; schem->size = size; schem->schemdata = schemdata; schem->slice_probs = slice_probs; return true; }
// register_ore({lots of stuff}) int ModApiMapgen::l_register_ore(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_TYPE_SCATTER); Ore *ore = oremgr->create(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented"; return 0; } ore->name = getstringfield_default(L, index, "name", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0); ore->noise = NULL; ore->flags = 0; warn_if_field_exists(L, index, "height_min", "Deprecated: new name is \"y_min\"."); warn_if_field_exists(L, index, "height_max", "Deprecated: new name is \"y_max\"."); int ymin, ymax; if (!getintfield(L, index, "y_min", ymin) && !getintfield(L, index, "height_min", ymin)) ymin = -31000; if (!getintfield(L, index, "y_max", ymax) && !getintfield(L, index, "height_max", ymax)) ymax = 31000; ore->y_min = ymin; ore->y_max = ymax; if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { errorstream << "register_ore: clust_scarcity and clust_num_ores" "must be greater than 0" << std::endl; delete ore; return 0; } getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &ore->np)) { ore->flags |= OREFLAG_USE_NOISE; } else if (ore->NEEDS_NOISE) { errorstream << "register_ore: specified ore type requires valid " "noise parameters" << std::endl; delete ore; return 0; } lua_pop(L, 1); if (oretype == ORE_TYPE_VEIN) { OreVein *orevein = (OreVein *)ore; orevein->random_factor = getfloatfield_default(L, index, "random_factor", 1.f); } u32 id = oremgr->add(ore); if (id == (u32)-1) { delete ore; return 0; } NodeResolveInfo *nri = new NodeResolveInfo(ore); nri->nodenames.push_back(getstringfield_default(L, index, "ore", "")); std::vector<const char *> wherein_names; getstringlistfield(L, index, "wherein", wherein_names); nri->nodelistinfo.push_back(NodeListInfo(wherein_names.size())); for (size_t i = 0; i != wherein_names.size(); i++) nri->nodenames.push_back(wherein_names[i]); ndef->pendNodeResolve(nri); verbosestream << "register_ore: " << ore->name << std::endl; lua_pushinteger(L, id); return 1; }
ToolCapabilities read_tool_capabilities( lua_State *L, int table) { ToolCapabilities toolcap; getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); getintfield(L, table, "max_drop_level", toolcap.max_drop_level); lua_getfield(L, table, "groupcaps"); if(lua_istable(L, -1)){ int table_groupcaps = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_groupcaps) != 0){ // key at index -2 and value at index -1 std::string groupname = luaL_checkstring(L, -2); if(lua_istable(L, -1)){ int table_groupcap = lua_gettop(L); // This will be created ToolGroupCap groupcap; // Read simple parameters getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel); getintfield(L, table_groupcap, "uses", groupcap.uses); // DEPRECATED: maxwear float maxwear = 0; if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){ if(maxwear != 0) groupcap.uses = 1.0/maxwear; else groupcap.uses = 0; infostream<<script_get_backtrace(L)<<std::endl; infostream<<"WARNING: field \"maxwear\" is deprecated; " <<"should replace with uses=1/maxwear"<<std::endl; } // Read "times" table lua_getfield(L, table_groupcap, "times"); if(lua_istable(L, -1)){ int table_times = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_times) != 0){ // key at index -2 and value at index -1 int rating = luaL_checkinteger(L, -2); float time = luaL_checknumber(L, -1); groupcap.times[rating] = time; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); // Insert groupcap into toolcap toolcap.groupcaps[groupname] = groupcap; } // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, table, "damage_groups"); if(lua_istable(L, -1)){ int table_damage_groups = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_damage_groups) != 0){ // key at index -2 and value at index -1 std::string groupname = luaL_checkstring(L, -2); u16 value = luaL_checkinteger(L, -1); toolcap.damageGroups[groupname] = value; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); return toolcap; }
void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env) { SCRIPTAPI_PRECHECKHEADER verbosestream<<"scriptapi_add_environment"<<std::endl; setEnv(env); /* Add ActiveBlockModifiers to environment */ // Get core.registered_abms lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_abms"); luaL_checktype(L, -1, LUA_TTABLE); int registered_abms = lua_gettop(L); if(lua_istable(L, registered_abms)){ int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 int id = lua_tonumber(L, -2); int current_abm = lua_gettop(L); std::set<std::string> trigger_contents; lua_getfield(L, current_abm, "nodenames"); if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TSTRING); trigger_contents.insert(lua_tostring(L, -1)); // removes value, keeps key for next iteration lua_pop(L, 1); } } else if(lua_isstring(L, -1)){ trigger_contents.insert(lua_tostring(L, -1)); } lua_pop(L, 1); std::set<std::string> required_neighbors; lua_getfield(L, current_abm, "neighbors"); if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TSTRING); required_neighbors.insert(lua_tostring(L, -1)); // removes value, keeps key for next iteration lua_pop(L, 1); } } else if(lua_isstring(L, -1)){ required_neighbors.insert(lua_tostring(L, -1)); } lua_pop(L, 1); float trigger_interval = 10.0; getfloatfield(L, current_abm, "interval", trigger_interval); int trigger_chance = 50; getintfield(L, current_abm, "chance", trigger_chance); int neighbors_range = 1; getintfield(L, current_abm, "neighbors_range", neighbors_range); LuaABM *abm = new LuaABM(L, id, trigger_contents, required_neighbors, neighbors_range, trigger_interval, trigger_chance); env->addActiveBlockModifier(abm); // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); }
bool read_schematic(lua_State *L, int index, DecoSchematic *dschem, Server *server) { if (index < 0) index = lua_gettop(L) + 1 + index; INodeDefManager *ndef = server->getNodeDefManager(); if (lua_istable(L, index)) { lua_getfield(L, index, "size"); v3s16 size = read_v3s16(L, -1); lua_pop(L, 1); int numnodes = size.X * size.Y * size.Z; MapNode *schemdata = new MapNode[numnodes]; int i = 0; // Get schematic data lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); lua_pushnil(L); while (lua_next(L, -2)) { if (i < numnodes) { // same as readnode, except param1 default is MTSCHEM_PROB_CONST lua_getfield(L, -1, "name"); const char *name = luaL_checkstring(L, -1); lua_pop(L, 1); u8 param1; lua_getfield(L, -1, "param1"); param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS; lua_pop(L, 1); u8 param2; lua_getfield(L, -1, "param2"); param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0; lua_pop(L, 1); schemdata[i] = MapNode(ndef, name, param1, param2); } i++; lua_pop(L, 1); } if (i != numnodes) { errorstream << "read_schematic: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } u8 *sliceprobs = new u8[size.Y]; for (i = 0; i != size.Y; i++) sliceprobs[i] = MTSCHEM_PROB_ALWAYS; // Get Y-slice probability values (if present) lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) { sliceprobs[i] = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); } lua_pop(L, 1); } } dschem->size = size; dschem->schematic = schemdata; dschem->slice_probs = sliceprobs; } else if (lua_isstring(L, index)) { dschem->filename = std::string(lua_tostring(L, index)); } else { errorstream << "read_schematic: missing schematic " "filename or raw schematic data" << std::endl; return false; } return true; }
bool read_schematic_def(lua_State *L, int index, Schematic *schem, std::vector<std::string> *names) { if (!lua_istable(L, index)) return false; //// Get schematic size lua_getfield(L, index, "size"); v3s16 size = check_v3s16(L, -1); lua_pop(L, 1); schem->size = size; //// Get schematic data lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); int numnodes = size.X * size.Y * size.Z; schem->schemdata = new MapNode[numnodes]; int i = 0; size_t names_base = names->size(); std::map<std::string, content_t> name_id_map; lua_pushnil(L); while (lua_next(L, -2)) { if (i >= numnodes) { i++; lua_pop(L, 1); continue; } // same as readnode, except param1 default is MTSCHEM_PROB_CONST lua_getfield(L, -1, "name"); std::string name = luaL_checkstring(L, -1); lua_pop(L, 1); u8 param1; lua_getfield(L, -1, "param1"); param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS; lua_pop(L, 1); u8 param2; lua_getfield(L, -1, "param2"); param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0; lua_pop(L, 1); std::map<std::string, content_t>::iterator it = name_id_map.find(name); content_t name_index; if (it != name_id_map.end()) { name_index = it->second; } else { name_index = names->size() - names_base; name_id_map[name] = name_index; names->push_back(name); } schem->schemdata[i] = MapNode(name_index, param1, param2); i++; lua_pop(L, 1); } if (i != numnodes) { errorstream << "read_schematic_def: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } //// Get Y-slice probability values (if present) schem->slice_probs = new u8[size.Y]; for (i = 0; i != size.Y; i++) schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS; lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) { schem->slice_probs[i] = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); } lua_pop(L, 1); } } return true; }
// register_ore({lots of stuff}) int ModApiMapgen::l_register_ore(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = oremgr->create(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented"; return 0; } ore->name = getstringfield_default(L, index, "name", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0); ore->noise = NULL; ore->flags = 0; warn_if_field_exists(L, index, "height_min", "Deprecated: new name is \"y_min\"."); warn_if_field_exists(L, index, "height_max", "Deprecated: new name is \"y_max\"."); int ymin, ymax; if (!getintfield(L, index, "y_min", ymin) && !getintfield(L, index, "height_min", ymin)) ymin = -31000; if (!getintfield(L, index, "y_max", ymax) && !getintfield(L, index, "height_max", ymax)) ymax = 31000; ore->y_min = ymin; ore->y_max = ymax; if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { errorstream << "register_ore: clust_scarcity and clust_num_ores" "must be greater than 0" << std::endl; delete ore; return 0; } getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &ore->np)) { ore->flags |= OREFLAG_USE_NOISE; } else if (ore->NEEDS_NOISE) { errorstream << "register_ore: specified ore type requires valid " "noise parameters" << std::endl; delete ore; return 0; } lua_pop(L, 1); if (oretype == ORE_VEIN) { OreVein *orevein = (OreVein *)ore; orevein->random_factor = getfloatfield_default(L, index, "random_factor", 1.f); } ObjDefHandle handle = oremgr->add(ore); if (handle == OBJDEF_INVALID_HANDLE) { delete ore; return 0; } ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", "")); size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames); ore->m_nnlistsizes.push_back(nnames); ndef->pendNodeResolve(ore, NODE_RESOLVE_DEFERRED); lua_pushinteger(L, handle); return 1; }