void read_server_sound_params(lua_State *L, int index, ServerSoundParams ¶ms) { if(index < 0) index = lua_gettop(L) + 1 + index; // Clear params = ServerSoundParams(); if(lua_istable(L, index)){ getfloatfield(L, index, "gain", params.gain); getstringfield(L, index, "to_player", params.to_player); lua_getfield(L, index, "pos"); if(!lua_isnil(L, -1)){ v3f p = read_v3f(L, -1)*BS; params.pos = p; params.type = ServerSoundParams::SSP_POSITIONAL; } lua_pop(L, 1); lua_getfield(L, index, "object"); if(!lua_isnil(L, -1)){ ObjectRef *ref = ObjectRef::checkobject(L, -1); ServerActiveObject *sao = ObjectRef::getobject(ref); if(sao){ params.object = sao->getId(); params.type = ServerSoundParams::SSP_OBJECT; } } lua_pop(L, 1); params.max_hear_distance = BS*getfloatfield_default(L, index, "max_hear_distance", params.max_hear_distance/BS); getboolfield(L, index, "loop", params.loop); } }
// register_biome({lots of stuff}) int ModApiMapgen::l_register_biome(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; enum BiomeType biometype = (BiomeType)getenumfield(L, index, "type", es_BiomeTerrainType, BIOME_TYPE_NORMAL); Biome *b = bmgr->create(biometype); b->name = getstringfield_default(L, index, "name", ""); b->depth_top = getintfield_default(L, index, "depth_top", 1); b->depth_filler = getintfield_default(L, index, "depth_filler", 3); b->height_shore = getintfield_default(L, index, "height_shore", 3); b->depth_water_top = getintfield_default(L, index, "depth_water_top", 0); b->y_min = getintfield_default(L, index, "y_min", -31000); b->y_max = getintfield_default(L, index, "y_max", 31000); b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f); b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f); b->flags = 0; //reserved u32 id = bmgr->add(b); if (id == (u32)-1) { delete b; return 0; } NodeResolveInfo *nri = new NodeResolveInfo(b); std::list<std::string> &nnames = nri->nodenames; nnames.push_back(getstringfield_default(L, index, "node_top", "")); nnames.push_back(getstringfield_default(L, index, "node_filler", "")); nnames.push_back(getstringfield_default(L, index, "node_shore_top", "")); nnames.push_back(getstringfield_default(L, index, "node_shore_filler", "")); nnames.push_back(getstringfield_default(L, index, "node_underwater", "")); nnames.push_back(getstringfield_default(L, index, "node_stone", "")); nnames.push_back(getstringfield_default(L, index, "node_water_top", "")); nnames.push_back(getstringfield_default(L, index, "node_water", "")); nnames.push_back(getstringfield_default(L, index, "node_dust", "")); ndef->pendNodeResolve(nri); verbosestream << "register_biome: " << b->name << std::endl; lua_pushinteger(L, id); return 1; }
// register_biome({lots of stuff}) int ModApiMapgen::l_register_biome(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef; if (!bmgr) { verbosestream << "register_biome: BiomeDefManager not active" << std::endl; return 0; } enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index, "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL); Biome *b = bmgr->createBiome(terrain); b->name = getstringfield_default(L, index, "name", "<no name>"); b->nname_top = getstringfield_default(L, index, "node_top", "mapgen_dirt_with_grass"); b->nname_filler = getstringfield_default(L, index, "node_filler", "mapgen_dirt"); b->nname_water = getstringfield_default(L, index, "node_water", "mapgen_water_source"); b->nname_dust = getstringfield_default(L, index, "node_dust", "air"); b->nname_dust_water = getstringfield_default(L, index, "node_dust_water", "mapgen_water_source"); b->depth_top = getintfield_default(L, index, "depth_top", 1); b->depth_filler = getintfield_default(L, index, "depth_filler", 3); b->height_min = getintfield_default(L, index, "height_min", 0); b->height_max = getintfield_default(L, index, "height_max", 0); b->heat_point = getfloatfield_default(L, index, "heat_point", 0.); b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.); b->flags = 0; //reserved b->c_top = CONTENT_IGNORE; b->c_filler = CONTENT_IGNORE; b->c_water = CONTENT_IGNORE; b->c_dust = CONTENT_IGNORE; b->c_dust_water = CONTENT_IGNORE; verbosestream << "register_biome: " << b->name << std::endl; bmgr->addBiome(b); return 0; }
// set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=}) int ObjectRef::l_set_clouds(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); RemotePlayer *player = getplayer(ref); if (!player) return 0; if (!lua_istable(L, 2)) return 0; CloudParams cloud_params = player->getCloudParams(); cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density); lua_getfield(L, 2, "color"); if (!lua_isnil(L, -1)) read_color(L, -1, &cloud_params.color_bright); lua_pop(L, 1); lua_getfield(L, 2, "ambient"); if (!lua_isnil(L, -1)) read_color(L, -1, &cloud_params.color_ambient); lua_pop(L, 1); cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height ); cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness); lua_getfield(L, 2, "speed"); if (lua_istable(L, -1)) { v2f new_speed; new_speed.X = getfloatfield_default(L, -1, "x", 0); new_speed.Y = getfloatfield_default(L, -1, "y", 0); cloud_params.speed = new_speed; } lua_pop(L, 1); if (!getServer(L)->setClouds(player, cloud_params.density, cloud_params.color_bright, cloud_params.color_ambient, cloud_params.height, cloud_params.thickness, cloud_params.speed)) return 0; player->setCloudParams(cloud_params); lua_pushboolean(L, true); return 1; }
bool read_noiseparams_nc(lua_State *L, int index, NoiseParams *np) { if (index < 0) index = lua_gettop(L) + 1 + index; if (!lua_istable(L, index)) return false; np->offset = getfloatfield_default(L, index, "offset", 0.0); np->scale = getfloatfield_default(L, index, "scale", 0.0); np->persist = getfloatfield_default(L, index, "persist", 0.0); np->seed = getintfield_default(L, index, "seed", 0); np->octaves = getintfield_default(L, index, "octaves", 0); lua_getfield(L, index, "spread"); np->spread = read_v3f(L, -1); lua_pop(L, 1); return true; }
/* NoiseParams */ NoiseParams *read_noiseparams(lua_State *L, int index) { if (index < 0) index = lua_gettop(L) + 1 + index; if (!lua_istable(L, index)) return NULL; NoiseParams *np = new NoiseParams; np->offset = getfloatfield_default(L, index, "offset", 0.0); np->scale = getfloatfield_default(L, index, "scale", 0.0); lua_getfield(L, index, "spread"); np->spread = read_v3f(L, -1); np->seed = getintfield_default(L, index, "seed", 0); np->octaves = getintfield_default(L, index, "octaves", 0); np->persist = getfloatfield_default(L, index, "persist", 0.0); return np; }
Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) { if (!lua_istable(L, index)) return NULL; BiomeType biometype = (BiomeType)getenumfield(L, index, "type", ModApiMapgen::es_BiomeTerrainType, BIOMETYPE_NORMAL); Biome *b = BiomeManager::create(biometype); b->name = getstringfield_default(L, index, "name", ""); b->depth_top = getintfield_default(L, index, "depth_top", 0); b->depth_filler = getintfield_default(L, index, "depth_filler", -31000); b->depth_water_top = getintfield_default(L, index, "depth_water_top", 0); b->depth_riverbed = getintfield_default(L, index, "depth_riverbed", 0); b->y_min = getintfield_default(L, index, "y_min", -31000); b->y_max = getintfield_default(L, index, "y_max", 31000); b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f); b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f); b->flags = 0; //reserved std::vector<std::string> &nn = b->m_nodenames; nn.push_back(getstringfield_default(L, index, "node_top", "")); nn.push_back(getstringfield_default(L, index, "node_filler", "")); nn.push_back(getstringfield_default(L, index, "node_stone", "")); nn.push_back(getstringfield_default(L, index, "node_water_top", "")); nn.push_back(getstringfield_default(L, index, "node_water", "")); nn.push_back(getstringfield_default(L, index, "node_river_water", "")); nn.push_back(getstringfield_default(L, index, "node_riverbed", "")); nn.push_back(getstringfield_default(L, index, "node_dust", "")); //freeminer: nn.push_back(getstringfield_default(L, index, "node_ice", "mapgen_ice")); nn.push_back(getstringfield_default(L, index, "node_top_cold", "mapgen_dirt_with_snow")); ndef->pendNodeResolve(b); return b; }
// set_physics_override(self, physics_override_speed, physics_override_jump, // physics_override_gravity, sneak, sneak_glitch, new_move) int ObjectRef::l_set_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); PlayerSAO *co = (PlayerSAO *) getobject(ref); if (co == NULL) return 0; // Do it if (lua_istable(L, 2)) { co->m_physics_override_speed = getfloatfield_default( L, 2, "speed", co->m_physics_override_speed); co->m_physics_override_jump = getfloatfield_default( L, 2, "jump", co->m_physics_override_jump); co->m_physics_override_gravity = getfloatfield_default( L, 2, "gravity", co->m_physics_override_gravity); co->m_physics_override_sneak = getboolfield_default( L, 2, "sneak", co->m_physics_override_sneak); co->m_physics_override_sneak_glitch = getboolfield_default( L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch); co->m_physics_override_new_move = getboolfield_default( L, 2, "new_move", co->m_physics_override_new_move); co->m_physics_override_sent = false; } else { // old, non-table format if (!lua_isnil(L, 2)) { co->m_physics_override_speed = lua_tonumber(L, 2); co->m_physics_override_sent = false; } if (!lua_isnil(L, 3)) { co->m_physics_override_jump = lua_tonumber(L, 3); co->m_physics_override_sent = false; } if (!lua_isnil(L, 4)) { co->m_physics_override_gravity = lua_tonumber(L, 4); co->m_physics_override_sent = false; } } return 0; }
int ModApiBasic::l_register_ore(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); EmergeManager *emerge = getServer(L)->getEmergeManager(); enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = createOre(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented"; return 0; } ore->ore_name = getstringfield_default(L, index, "ore", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->wherein_name = getstringfield_default(L, index, "wherein", ""); 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->height_min = getintfield_default(L, index, "height_min", 0); ore->height_max = getintfield_default(L, index, "height_max", 0); ore->flags = getflagsfield(L, index, "flags", flagdesc_ore); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.); lua_getfield(L, index, "noise_params"); ore->np = read_noiseparams(L, -1); lua_pop(L, 1); ore->noise = NULL; 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; } emerge->ores.push_back(ore); verbosestream << "register_ore: ore '" << ore->ore_name << "' registered" << std::endl; return 0; }
TileDef read_tiledef(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; TileDef tiledef; // key at index -2 and value at index if(lua_isstring(L, index)){ // "default_lava.png" tiledef.name = lua_tostring(L, index); } else if(lua_istable(L, index)) { // {name="default_lava.png", animation={}} tiledef.name = ""; getstringfield(L, index, "name", tiledef.name); getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat. tiledef.backface_culling = getboolfield_default( L, index, "backface_culling", true); // animation = {} lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} tiledef.animation.type = (TileAnimationType) getenumfield(L, -1, "type", es_TileAnimationType, TAT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = getintfield_default(L, -1, "aspect_h", 16); tiledef.animation.length = getfloatfield_default(L, -1, "length", 1.0); } lua_pop(L, 1); } return tiledef; }
// register_decoration({lots of stuff}) int ModApiMapgen::l_register_decoration(lua_State *L) { NO_MAP_LOCK_REQUIRED; int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr; BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr; SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); Decoration *deco = decomgr->create(decotype); if (!deco) { errorstream << "register_decoration: decoration placement type " << decotype << " not implemented" << std::endl; return 0; } deco->name = getstringfield_default(L, index, "name", ""); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); deco->y_min = getintfield_default(L, index, "y_min", -31000); deco->y_max = getintfield_default(L, index, "y_max", 31000); deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; delete deco; return 0; } //// Get node name(s) to place decoration on size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames); deco->m_nnlistsizes.push_back(nread); //// Get decoration flags getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL); //// Get NoiseParams to define how decoration is placed lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &deco->np)) deco->flags |= DECO_USE_NOISE; lua_pop(L, 1); //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, biomemgr, &deco->biomes)) errorstream << "register_decoration: couldn't get all biomes " << std::endl; lua_pop(L, 1); //// Get node name(s) to 'spawn by' size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames); deco->m_nnlistsizes.push_back(nnames); if (nnames == 0 && deco->nspawnby != -1) { errorstream << "register_decoration: no spawn_by nodes defined," " but num_spawn_by specified" << std::endl; } //// Handle decoration type-specific parameters bool success = false; switch (decotype) { case DECO_SIMPLE: success = read_deco_simple(L, (DecoSimple *)deco); break; case DECO_SCHEMATIC: success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco); break; case DECO_LSYSTEM: break; } if (!success) { delete deco; return 0; } ndef->pendNodeResolve(deco); ObjDefHandle handle = decomgr->add(deco); if (handle == OBJDEF_INVALID_HANDLE) { delete deco; return 0; } lua_pushinteger(L, handle); return 1; }
// 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; }
// 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; }
// register_decoration({lots of stuff}) int ModApiMapgen::l_register_decoration(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr; BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); Decoration *deco = decomgr->create(decotype); if (!deco) { errorstream << "register_decoration: decoration placement type " << decotype << " not implemented"; return 0; } deco->name = getstringfield_default(L, index, "name", ""); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); deco->y_min = getintfield_default(L, index, "y_min", -31000); deco->y_max = getintfield_default(L, index, "y_max", 31000); deco->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; } NodeResolveInfo *nri = new NodeResolveInfo(deco); //// Get node name(s) to place decoration on std::vector<const char *> place_on_names; getstringlistfield(L, index, "place_on", place_on_names); nri->nodelistinfo.push_back(NodeListInfo(place_on_names.size())); for (size_t i = 0; i != place_on_names.size(); i++) nri->nodenames.push_back(place_on_names[i]); getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL); //// Get NoiseParams to define how decoration is placed lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &deco->np)) deco->flags |= DECO_USE_NOISE; lua_pop(L, 1); //// Get biomes associated with this decoration (if any) std::vector<const char *> biome_list; getstringlistfield(L, index, "biomes", biome_list); for (size_t i = 0; i != biome_list.size(); i++) { Biome *b = (Biome *)biomemgr->getByName(biome_list[i]); if (!b) continue; deco->biomes.insert(b->id); } //// Handle decoration type-specific parameters bool success = false; switch (decotype) { case DECO_SIMPLE: success = regDecoSimple(L, nri, (DecoSimple *)deco); break; case DECO_SCHEMATIC: success = regDecoSchematic(L, ndef, (DecoSchematic *)deco); break; case DECO_LSYSTEM: break; } ndef->pendNodeResolve(nri); if (!success) { delete deco; return 0; } u32 id = decomgr->add(deco); if (id == (u32)-1) { delete deco; return 0; } verbosestream << "register_decoration: " << deco->name << std::endl; lua_pushinteger(L, id); return 1; }
// add_particle({pos=, velocity=, acceleration=, expirationtime=, // size=, collisiondetection=, vertical=, texture=, player=}) // pos/velocity/acceleration = {x=num, y=num, z=num} // expirationtime = num (seconds) // size = num // collisiondetection = bool // vertical = bool // texture = e.g."default_wood.png" int ModApiParticles::l_add_particle(lua_State *L) { // Get parameters v3f pos, vel, acc; pos = vel = acc = v3f(0, 0, 0); float expirationtime, size; expirationtime = size = 1; bool collisiondetection, vertical; collisiondetection = vertical = false; std::string texture = ""; std::string playername = ""; if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); pos = check_v3f(L, 1); vel = check_v3f(L, 2); acc = check_v3f(L, 3); expirationtime = luaL_checknumber(L, 4); size = luaL_checknumber(L, 5); collisiondetection = lua_toboolean(L, 6); texture = luaL_checkstring(L, 7); if (lua_gettop(L) == 8) // only spawn for a single player playername = luaL_checkstring(L, 8); } else if (lua_istable(L, 1)) { lua_getfield(L, 1, "pos"); pos = lua_istable(L, -1) ? check_v3f(L, -1) : v3f(); lua_pop(L, 1); lua_getfield(L, 1, "vel"); if (lua_istable(L, -1)) { vel = check_v3f(L, -1); log_deprecated(L, "The use of vel is deprecated. " "Use velocity instead"); } lua_pop(L, 1); lua_getfield(L, 1, "velocity"); vel = lua_istable(L, -1) ? check_v3f(L, -1) : vel; lua_pop(L, 1); lua_getfield(L, 1, "acc"); if (lua_istable(L, -1)) { acc = check_v3f(L, -1); log_deprecated(L, "The use of acc is deprecated. " "Use acceleration instead"); } lua_pop(L, 1); lua_getfield(L, 1, "acceleration"); acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); } getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, collisiondetection, vertical, texture); return 1; }
ItemDefinition read_item_definition(lua_State* L,int index, ItemDefinition default_def) { if(index < 0) index = lua_gettop(L) + 1 + index; // Read the item definition ItemDefinition def = default_def; def.type = (ItemType)getenumfield(L, index, "type", es_ItemType, ITEM_NONE); getstringfield(L, index, "name", def.name); getstringfield(L, index, "description", def.description); getstringfield(L, index, "inventory_image", def.inventory_image); getstringfield(L, index, "wield_image", def.wield_image); lua_getfield(L, index, "wield_scale"); if(lua_istable(L, -1)){ def.wield_scale = check_v3f(L, -1); } lua_pop(L, 1); def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max); if(def.stack_max == 0) def.stack_max = 1; lua_getfield(L, index, "on_use"); def.usable = lua_isfunction(L, -1); lua_pop(L, 1); getboolfield(L, index, "liquids_pointable", def.liquids_pointable); warn_if_field_exists(L, index, "tool_digging_properties", "deprecated: use tool_capabilities"); lua_getfield(L, index, "tool_capabilities"); if(lua_istable(L, -1)){ def.tool_capabilities = new ToolCapabilities( read_tool_capabilities(L, -1)); } // If name is "" (hand), ensure there are ToolCapabilities // because it will be looked up there whenever any other item has // no ToolCapabilities if(def.name == "" && def.tool_capabilities == NULL){ def.tool_capabilities = new ToolCapabilities(); } lua_getfield(L, index, "groups"); read_groups(L, -1, def.groups); lua_pop(L, 1); lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "place"); read_soundspec(L, -1, def.sound_place); lua_pop(L, 1); } lua_pop(L, 1); def.range = getfloatfield_default(L, index, "range", def.range); // Client shall immediately place this node when player places the item. // Server will update the precise end result a moment later. // "" = no prediction getstringfield(L, index, "node_placement_prediction", def.node_placement_prediction); return def; }
// add_particlespawner({amount=, time=, // minpos=, maxpos=, // minvel=, maxvel=, // minacc=, maxacc=, // minexptime=, maxexptime=, // minsize=, maxsize=, // collisiondetection=, // vertical=, // texture=, // player=}) // minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num} // minexptime/maxexptime = num (seconds) // minsize/maxsize = num // collisiondetection = bool // vertical = bool // texture = e.g."default_wood.png" int ModApiParticles::l_add_particlespawner(lua_State *L) { // Get parameters u16 amount = 1; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; bool collisiondetection, vertical; collisiondetection= vertical= false; std::string texture = ""; std::string playername = ""; if (lua_gettop(L) > 1) //deprecated { log_deprecated(L,"Deprecated add_particlespawner call with individual parameters instead of definition"); amount = luaL_checknumber(L, 1); time = luaL_checknumber(L, 2); minpos = check_v3f(L, 3); maxpos = check_v3f(L, 4); minvel = check_v3f(L, 5); maxvel = check_v3f(L, 6); minacc = check_v3f(L, 7); maxacc = check_v3f(L, 8); minexptime = luaL_checknumber(L, 9); maxexptime = luaL_checknumber(L, 10); minsize = luaL_checknumber(L, 11); maxsize = luaL_checknumber(L, 12); collisiondetection = lua_toboolean(L, 13); texture = luaL_checkstring(L, 14); if (lua_gettop(L) == 15) // only spawn for a single player playername = luaL_checkstring(L, 15); } else if (lua_istable(L, 1)) { amount = getintfield_default(L, 1, "amount", amount); time = getfloatfield_default(L, 1, "time", time); lua_getfield(L, 1, "minpos"); minpos = lua_istable(L, -1) ? check_v3f(L, -1) : minpos; lua_pop(L, 1); lua_getfield(L, 1, "maxpos"); maxpos = lua_istable(L, -1) ? check_v3f(L, -1) : maxpos; lua_pop(L, 1); lua_getfield(L, 1, "minvel"); minvel = lua_istable(L, -1) ? check_v3f(L, -1) : minvel; lua_pop(L, 1); lua_getfield(L, 1, "maxvel"); maxvel = lua_istable(L, -1) ? check_v3f(L, -1) : maxvel; lua_pop(L, 1); lua_getfield(L, 1, "minacc"); minacc = lua_istable(L, -1) ? check_v3f(L, -1) : minacc; lua_pop(L, 1); lua_getfield(L, 1, "maxacc"); maxacc = lua_istable(L, -1) ? check_v3f(L, -1) : maxacc; lua_pop(L, 1); minexptime = getfloatfield_default(L, 1, "minexptime", minexptime); maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); } u32 id = getServer(L)->addParticleSpawner(amount, time, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, vertical, texture, playername); lua_pushnumber(L, id); return 1; }
// register_decoration({lots of stuff}) int ModApiBasic::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->sidelen = getintfield_default(L, index, "sidelen", 8); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); 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 *decoschematic = (DecoSchematic *)deco; break; } case DECO_LSYSTEM: { //DecoLSystem *decolsystem = (DecoLSystem *)deco; break; } } if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; delete deco; return 0; } emerge->decorations.push_back(deco); verbosestream << "register_decoration: decoration '" << deco->getName() << "' registered" << std::endl; return 0; }
// 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; }
// add_particlespawner({amount=, time=, // minpos=, maxpos=, // minvel=, maxvel=, // minacc=, maxacc=, // minexptime=, maxexptime=, // minsize=, maxsize=, // collisiondetection=, // collision_removal=, // object_collision=, // vertical=, // texture=, // player=}) // minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num} // minexptime/maxexptime = num (seconds) // minsize/maxsize = num // collisiondetection = bool // collision_removal = bool // object_collision = bool // vertical = bool // texture = e.g."default_wood.png" // animation = TileAnimation definition // glow = num int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; float time, minexptime, maxexptime, minsize, maxsize; time = minexptime = maxexptime = minsize = maxsize = 1; bool collisiondetection, vertical, collision_removal, object_collision; collisiondetection = vertical = collision_removal = object_collision = false; struct TileAnimationParams animation; animation.type = TAT_NONE; ServerActiveObject *attached = NULL; std::string texture; std::string playername; u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { log_deprecated(L,"Deprecated add_particlespawner call with individual parameters instead of definition"); amount = luaL_checknumber(L, 1); time = luaL_checknumber(L, 2); minpos = check_v3f(L, 3); maxpos = check_v3f(L, 4); minvel = check_v3f(L, 5); maxvel = check_v3f(L, 6); minacc = check_v3f(L, 7); maxacc = check_v3f(L, 8); minexptime = luaL_checknumber(L, 9); maxexptime = luaL_checknumber(L, 10); minsize = luaL_checknumber(L, 11); maxsize = luaL_checknumber(L, 12); collisiondetection = readParam<bool>(L, 13); texture = luaL_checkstring(L, 14); if (lua_gettop(L) == 15) // only spawn for a single player playername = luaL_checkstring(L, 15); } else if (lua_istable(L, 1)) { amount = getintfield_default(L, 1, "amount", amount); time = getfloatfield_default(L, 1, "time", time); lua_getfield(L, 1, "minpos"); minpos = lua_istable(L, -1) ? check_v3f(L, -1) : minpos; lua_pop(L, 1); lua_getfield(L, 1, "maxpos"); maxpos = lua_istable(L, -1) ? check_v3f(L, -1) : maxpos; lua_pop(L, 1); lua_getfield(L, 1, "minvel"); minvel = lua_istable(L, -1) ? check_v3f(L, -1) : minvel; lua_pop(L, 1); lua_getfield(L, 1, "maxvel"); maxvel = lua_istable(L, -1) ? check_v3f(L, -1) : maxvel; lua_pop(L, 1); lua_getfield(L, 1, "minacc"); minacc = lua_istable(L, -1) ? check_v3f(L, -1) : minacc; lua_pop(L, 1); lua_getfield(L, 1, "maxacc"); maxacc = lua_istable(L, -1) ? check_v3f(L, -1) : maxacc; lua_pop(L, 1); minexptime = getfloatfield_default(L, 1, "minexptime", minexptime); maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, "collision_removal", collision_removal); object_collision = getboolfield_default(L, 1, "object_collision", object_collision); lua_getfield(L, 1, "animation"); animation = read_animation_definition(L, -1); lua_pop(L, 1); lua_getfield(L, 1, "attached"); if (!lua_isnil(L, -1)) { ObjectRef *ref = ObjectRef::checkobject(L, -1); lua_pop(L, 1); attached = ObjectRef::getobject(ref); } vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, object_collision, attached, vertical, texture, playername, animation, glow); lua_pushnumber(L, id); return 1; }
TileDef read_tiledef(lua_State *L, int index, u8 drawtype) { if(index < 0) index = lua_gettop(L) + 1 + index; TileDef tiledef; bool default_tiling = true; bool default_culling = true; switch (drawtype) { case NDT_PLANTLIKE: case NDT_FIRELIKE: default_tiling = false; // "break" is omitted here intentionaly, as PLANTLIKE // FIRELIKE drawtype both should default to having // backface_culling to false. case NDT_MESH: case NDT_LIQUID: default_culling = false; break; default: break; } // key at index -2 and value at index if(lua_isstring(L, index)){ // "default_lava.png" tiledef.name = lua_tostring(L, index); tiledef.tileable_vertical = default_tiling; tiledef.tileable_horizontal = default_tiling; tiledef.backface_culling = default_culling; } else if(lua_istable(L, index)) { // {name="default_lava.png", animation={}} tiledef.name = ""; getstringfield(L, index, "name", tiledef.name); getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat. tiledef.backface_culling = getboolfield_default( L, index, "backface_culling", default_culling); tiledef.tileable_horizontal = getboolfield_default( L, index, "tileable_horizontal", default_tiling); tiledef.tileable_vertical = getboolfield_default( L, index, "tileable_vertical", default_tiling); // animation = {} lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} tiledef.animation.type = (TileAnimationType) getenumfield(L, -1, "type", es_TileAnimationType, TAT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = getintfield_default(L, -1, "aspect_h", 16); tiledef.animation.length = getfloatfield_default(L, -1, "length", 1.0); } lua_pop(L, 1); } return tiledef; }
// add_particle({pos=, velocity=, acceleration=, expirationtime=, // size=, collisiondetection=, collision_removal=, object_collision=, // vertical=, texture=, player=}) // pos/velocity/acceleration = {x=num, y=num, z=num} // expirationtime = num (seconds) // size = num // collisiondetection = bool // collision_removal = bool // object_collision = bool // vertical = bool // texture = e.g."default_wood.png" // animation = TileAnimation definition // glow = num int ModApiParticles::l_add_particle(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters v3f pos, vel, acc; float expirationtime, size; expirationtime = size = 1; bool collisiondetection, vertical, collision_removal, object_collision; collisiondetection = vertical = collision_removal = object_collision = false; struct TileAnimationParams animation; animation.type = TAT_NONE; std::string texture; std::string playername; u8 glow = 0; if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); pos = check_v3f(L, 1); vel = check_v3f(L, 2); acc = check_v3f(L, 3); expirationtime = luaL_checknumber(L, 4); size = luaL_checknumber(L, 5); collisiondetection = readParam<bool>(L, 6); texture = luaL_checkstring(L, 7); if (lua_gettop(L) == 8) // only spawn for a single player playername = luaL_checkstring(L, 8); } else if (lua_istable(L, 1)) { lua_getfield(L, 1, "pos"); pos = lua_istable(L, -1) ? check_v3f(L, -1) : v3f(); lua_pop(L, 1); lua_getfield(L, 1, "vel"); if (lua_istable(L, -1)) { vel = check_v3f(L, -1); log_deprecated(L, "The use of vel is deprecated. " "Use velocity instead"); } lua_pop(L, 1); lua_getfield(L, 1, "velocity"); vel = lua_istable(L, -1) ? check_v3f(L, -1) : vel; lua_pop(L, 1); lua_getfield(L, 1, "acc"); if (lua_istable(L, -1)) { acc = check_v3f(L, -1); log_deprecated(L, "The use of acc is deprecated. " "Use acceleration instead"); } lua_pop(L, 1); lua_getfield(L, 1, "acceleration"); acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, "collision_removal", collision_removal); object_collision = getboolfield_default(L, 1, "object_collision", object_collision); vertical = getboolfield_default(L, 1, "vertical", vertical); lua_getfield(L, 1, "animation"); animation = read_animation_definition(L, -1); lua_pop(L, 1); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); glow = getintfield_default(L, 1, "glow", 0); } getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, collisiondetection, collision_removal, object_collision, vertical, texture, animation, glow); return 1; }
// register_craft({output=item, recipe={{item00,item10},{item01,item11}}) int ModApiCraft::l_register_craft(lua_State *L) { NO_MAP_LOCK_REQUIRED; //infostream<<"register_craft"<<std::endl; luaL_checktype(L, 1, LUA_TTABLE); int table = 1; // Get the writable craft definition manager from the server IWritableCraftDefManager *craftdef = getServer(L)->getWritableCraftDefManager(); std::string type = getstringfield_default(L, table, "type", "shaped"); /* CraftDefinitionShaped */ if(type == "shaped"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") throw LuaError("Crafting definition is missing an output"); int width = 0; std::vector<std::string> recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) throw LuaError("Crafting definition is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShaped(L, -1, width, recipe)) throw LuaError("Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; lua_getfield(L, table, "replacements"); if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) throw LuaError("Invalid replacements" " (output=\"" + output + "\")"); } CraftDefinition *def = new CraftDefinitionShaped( output, width, recipe, replacements); craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionShapeless */ else if(type == "shapeless"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") throw LuaError("Crafting definition (shapeless)" " is missing an output"); std::vector<std::string> recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) throw LuaError("Crafting definition (shapeless)" " is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShapeless(L, -1, recipe)) throw LuaError("Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; lua_getfield(L, table, "replacements"); if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) throw LuaError("Invalid replacements" " (output=\"" + output + "\")"); } CraftDefinition *def = new CraftDefinitionShapeless( output, recipe, replacements); craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionToolRepair */ else if(type == "toolrepair"){ float additional_wear = getfloatfield_default(L, table, "additional_wear", 0.0); CraftDefinition *def = new CraftDefinitionToolRepair( additional_wear); craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionCooking */ else if(type == "cooking"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") throw LuaError("Crafting definition (cooking)" " is missing an output"); std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") throw LuaError("Crafting definition (cooking)" " is missing a recipe" " (output=\"" + output + "\")"); float cooktime = getfloatfield_default(L, table, "cooktime", 3.0); CraftReplacements replacements; lua_getfield(L, table, "replacements"); if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) throw LuaError("Invalid replacements" " (cooking output=\"" + output + "\")"); } CraftDefinition *def = new CraftDefinitionCooking( output, recipe, cooktime, replacements); craftdef->registerCraft(def, getServer(L)); } /* CraftDefinitionFuel */ else if(type == "fuel"){ std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") throw LuaError("Crafting definition (fuel)" " is missing a recipe"); float burntime = getfloatfield_default(L, table, "burntime", 1.0); CraftReplacements replacements; lua_getfield(L, table, "replacements"); if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) throw LuaError("Invalid replacements" " (fuel recipe=\"" + recipe + "\")"); } CraftDefinition *def = new CraftDefinitionFuel( recipe, burntime, replacements); craftdef->registerCraft(def, getServer(L)); } else { throw LuaError("Unknown crafting definition type: \"" + type + "\""); } lua_pop(L, 1); return 0; /* number of results */ }
// 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; }