// hud_add(self, form) int ObjectRef::l_hud_add(lua_State *L) { ObjectRef *ref = checkobject(L, 1); Player *player = getplayer(ref); if (player == NULL) return 0; HudElement *elem = new HudElement; elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type", es_HudElementType, HUD_ELEM_TEXT); lua_getfield(L, 2, "position"); elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "scale"); elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "size"); elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32(); lua_pop(L, 1); elem->name = getstringfield_default(L, 2, "name", ""); elem->text = getstringfield_default(L, 2, "text", ""); elem->number = getintfield_default(L, 2, "number", 0); elem->item = getintfield_default(L, 2, "item", 0); elem->dir = getintfield_default(L, 2, "direction", 0); // Deprecated, only for compatibility's sake if (elem->dir == 0) elem->dir = getintfield_default(L, 2, "dir", 0); lua_getfield(L, 2, "alignment"); elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "offset"); elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "world_pos"); elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f(); lua_pop(L, 1); /* check for known deprecated element usage */ if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32())) { log_deprecated(L,"Deprecated usage of statbar without size!"); } u32 id = getServer(L)->hudAdd(player, elem); if (id == (u32)-1) { delete elem; return 0; } lua_pushnumber(L, id); return 1; }
// register_biome({lots of stuff}) int ModApiBasic::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", ""); b->top_nodename = getstringfield_default(L, index, "top_node", ""); b->top_depth = getintfield_default(L, index, "top_depth", 0); b->filler_nodename = getstringfield_default(L, index, "filler_node", ""); b->filler_height = getintfield_default(L, index, "filler_height", 0); 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; verbosestream << "register_biome: " << b->name << std::endl; bmgr->addBiome(b); return 0; }
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", "")); ndef->pendNodeResolve(b); return b; }
ItemStack read_item(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; if(lua_isnil(L, index)) { return ItemStack(); } else if(lua_isuserdata(L, index)) { // Convert from LuaItemStack LuaItemStack *o = LuaItemStack::checkobject(L, index); return o->getItem(); } else if(lua_isstring(L, index)) { // Convert from itemstring std::string itemstring = lua_tostring(L, index); IItemDefManager *idef = get_server(L)->idef(); try { ItemStack item; item.deSerialize(itemstring, idef); return item; } catch(SerializationError &e) { infostream<<"WARNING: unable to create item from itemstring" <<": "<<itemstring<<std::endl; return ItemStack(); } } else if(lua_istable(L, index)) { // Convert from table IItemDefManager *idef = get_server(L)->idef(); std::string name = getstringfield_default(L, index, "name", ""); int count = getintfield_default(L, index, "count", 1); int wear = getintfield_default(L, index, "wear", 0); std::string metadata = getstringfield_default(L, index, "metadata", ""); return ItemStack(name, count, wear, metadata, idef); } else { throw LuaError(L, "Expecting itemstack, itemstring, table or nil"); } }
// set_nametag_attributes(self, attributes) int ObjectRef::l_set_nametag_attributes(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); if (co == NULL) return 0; ObjectProperties *prop = co->accessObjectProperties(); if (!prop) return 0; lua_getfield(L, 2, "color"); if (!lua_isnil(L, -1)) { video::SColor color = prop->nametag_color; read_color(L, -1, &color); prop->nametag_color = color; } lua_pop(L, 1); std::string nametag = getstringfield_default(L, 2, "text", ""); prop->nametag = nametag; co->notifyObjectPropertiesModified(); lua_pushboolean(L, true); return 1; }
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->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, "wherein"); if (lua_istable(L, -1)) { int i = lua_gettop(L); lua_pushnil(L); while(lua_next(L, i) != 0) { ore->wherein_names.push_back(lua_tostring(L, -1)); lua_pop(L, 1); } } else if (lua_isstring(L, -1)) { ore->wherein_names.push_back(lua_tostring(L, -1)); } else { ore->wherein_names.push_back(""); } lua_pop(L, 1); 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; }
u32 getflagsfield(lua_State *L, int table, const char *fieldname, FlagDesc *flagdesc) { std::string flagstring; flagstring = getstringfield_default(L, table, fieldname, ""); return readFlagString(flagstring, flagdesc); }
// hud_add(self, form) int ObjectRef::l_hud_add(lua_State *L) { ObjectRef *ref = checkobject(L, 1); Player *player = getplayer(ref); if (player == NULL) return 0; HudElement *elem = new HudElement; elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type", es_HudElementType, HUD_ELEM_TEXT); lua_getfield(L, 2, "position"); elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "scale"); elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); elem->name = getstringfield_default(L, 2, "name", ""); elem->text = getstringfield_default(L, 2, "text", ""); elem->number = getintfield_default(L, 2, "number", 0); elem->item = getintfield_default(L, 2, "item", 0); elem->dir = getintfield_default(L, 2, "dir", 0); lua_getfield(L, 2, "alignment"); elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "offset"); elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); lua_pop(L, 1); lua_getfield(L, 2, "world_pos"); elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f(); lua_pop(L, 1); u32 id = getServer(L)->hudAdd(player, elem); if (id == (u32)-1) { delete elem; return 0; } lua_pushnumber(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); 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; }
int getenumfield(lua_State *L, int table, const char *fieldname, const EnumString *spec, int default_) { int result = default_; string_to_enum(spec, result, getstringfield_default(L, table, fieldname, "")); return result; }
void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn) { #ifdef SCRIPTAPI_DEBUG lua_State *L = getStack(); m_last_run_mod = lua_istable(L, index) ? getstringfield_default(L, index, "mod_origin", "") : ""; //printf(">>>> running %s for mod: %s\n", fxn, m_last_run_mod.c_str()); #endif }
// get_craft_result(input) int ModApiCraft::l_get_craft_result(lua_State *L) { NO_MAP_LOCK_REQUIRED; int input_i = 1; std::string method_s = getstringfield_default(L, input_i, "method", "normal"); enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method", es_CraftMethod, CRAFT_METHOD_NORMAL); int width = 1; lua_getfield(L, input_i, "width"); if(lua_isnumber(L, -1)) width = luaL_checkinteger(L, -1); lua_pop(L, 1); lua_getfield(L, input_i, "items"); std::vector<ItemStack> items = read_items(L, -1,getServer(L)); lua_pop(L, 1); // items IGameDef *gdef = getServer(L); ICraftDefManager *cdef = gdef->cdef(); CraftInput input(method, width, items); CraftOutput output; std::vector<ItemStack> output_replacements; bool got = cdef->getCraftResult(input, output, output_replacements, true, gdef); lua_newtable(L); // output table if (got) { ItemStack item; item.deSerialize(output.item, gdef->idef()); LuaItemStack::create(L, item); lua_setfield(L, -2, "item"); setintfield(L, -1, "time", output.time); push_items(L, output_replacements); lua_setfield(L, -2, "replacements"); } else { LuaItemStack::create(L, ItemStack()); lua_setfield(L, -2, "item"); setintfield(L, -1, "time", 0); lua_newtable(L); lua_setfield(L, -2, "replacements"); } lua_newtable(L); // decremented input table lua_pushstring(L, method_s.c_str()); lua_setfield(L, -2, "method"); lua_pushinteger(L, width); lua_setfield(L, -2, "width"); push_items(L, input.items); lua_setfield(L, -2, "items"); return 2; }
// 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; }
// 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; }
// 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; }
// 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; }
// 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; }
// clear_craft({[output=item], [recipe={{item00,item10},{item01,item11}}]) int ModApiCraft::l_clear_craft(lua_State *L) { NO_MAP_LOCK_REQUIRED; 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 output = getstringfield_default(L, table, "output", ""); std::string type = getstringfield_default(L, table, "type", "shaped"); CraftOutput c_output(output, 0); if (output != "") { if (craftdef->clearCraftRecipesByOutput(c_output, getServer(L))) return 0; else throw LuaError("No craft recipe known for output" " (output=\"" + output + "\")"); } std::vector<std::string> recipe; int width = 0; CraftMethod method = CRAFT_METHOD_NORMAL; /* CraftDefinitionShaped */ if (type == "shaped") { lua_getfield(L, table, "recipe"); if (lua_isnil(L, -1)) throw LuaError("Either output or recipe has to be defined"); if (!readCraftRecipeShaped(L, -1, width, recipe)) throw LuaError("Invalid crafting recipe"); } /* CraftDefinitionShapeless */ else if (type == "shapeless") { lua_getfield(L, table, "recipe"); if (lua_isnil(L, -1)) throw LuaError("Either output or recipe has to be defined"); if (!readCraftRecipeShapeless(L, -1, recipe)) throw LuaError("Invalid crafting recipe"); } /* CraftDefinitionCooking */ else if (type == "cooking") { method = CRAFT_METHOD_COOKING; std::string rec = getstringfield_default(L, table, "recipe", ""); if (rec == "") throw LuaError("Crafting definition (cooking)" " is missing a recipe"); recipe.push_back(rec); } /* CraftDefinitionFuel */ else if (type == "fuel") { method = CRAFT_METHOD_FUEL; std::string rec = getstringfield_default(L, table, "recipe", ""); if (rec == "") throw LuaError("Crafting definition (fuel)" " is missing a recipe"); recipe.push_back(rec); } else { throw LuaError("Unknown crafting definition type: \"" + type + "\""); } if (!craftdef->clearCraftRecipesByInput(method, width, recipe, getServer(L))) throw LuaError("No crafting specified for input"); lua_pop(L, 1); return 0; }
// 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; }
// 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; }
// 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; }
ItemStack read_item(lua_State* L, int index,Server* srv) { if(index < 0) index = lua_gettop(L) + 1 + index; if(lua_isnil(L, index)) { return ItemStack(); } else if(lua_isuserdata(L, index)) { // Convert from LuaItemStack LuaItemStack *o = LuaItemStack::checkobject(L, index); return o->getItem(); } else if(lua_isstring(L, index)) { // Convert from itemstring std::string itemstring = lua_tostring(L, index); IItemDefManager *idef = srv->idef(); try { ItemStack item; item.deSerialize(itemstring, idef); return item; } catch(SerializationError &e) { warningstream<<"unable to create item from itemstring" <<": "<<itemstring<<std::endl; return ItemStack(); } } else if(lua_istable(L, index)) { // Convert from table IItemDefManager *idef = srv->idef(); std::string name = getstringfield_default(L, index, "name", ""); int count = getintfield_default(L, index, "count", 1); int wear = getintfield_default(L, index, "wear", 0); ItemStack istack(name, count, wear, idef); lua_getfield(L, index, "metadata"); // Support old metadata format by checking type int fieldstable = lua_gettop(L); if (lua_istable(L, fieldstable)) { lua_pushnil(L); while (lua_next(L, fieldstable) != 0) { // key at index -2 and value at index -1 std::string key = lua_tostring(L, -2); size_t value_len; const char *value_cs = lua_tolstring(L, -1, &value_len); std::string value(value_cs, value_len); istack.metadata.setString(name, value); lua_pop(L, 1); // removes value, keeps key for next iteration } } else { // BACKWARDS COMPATIBLITY std::string value = getstringfield_default(L, index, "metadata", ""); istack.metadata.setString("", value); } lua_getfield(L, index, "meta"); fieldstable = lua_gettop(L); if (lua_istable(L, fieldstable)) { lua_pushnil(L); while (lua_next(L, fieldstable) != 0) { // key at index -2 and value at index -1 std::string key = lua_tostring(L, -2); size_t value_len; const char *value_cs = lua_tolstring(L, -1, &value_len); std::string value(value_cs, value_len); istack.metadata.setString(name, value); lua_pop(L, 1); // removes value, keeps key for next iteration } } return istack; } else { throw LuaError("Expecting itemstack, itemstring, table or nil"); } }
// 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; }