diff options
Diffstat (limited to 'src/script/lua_api')
-rw-r--r-- | src/script/lua_api/l_areastore.cpp | 1 | ||||
-rw-r--r-- | src/script/lua_api/l_camera.cpp | 21 | ||||
-rw-r--r-- | src/script/lua_api/l_client.cpp | 16 | ||||
-rw-r--r-- | src/script/lua_api/l_craft.cpp | 10 | ||||
-rw-r--r-- | src/script/lua_api/l_env.cpp | 32 | ||||
-rw-r--r-- | src/script/lua_api/l_http.cpp | 15 | ||||
-rw-r--r-- | src/script/lua_api/l_item.cpp | 11 | ||||
-rw-r--r-- | src/script/lua_api/l_item.h | 3 | ||||
-rw-r--r-- | src/script/lua_api/l_localplayer.cpp | 22 | ||||
-rw-r--r-- | src/script/lua_api/l_mainmenu.cpp | 28 | ||||
-rw-r--r-- | src/script/lua_api/l_mainmenu.h | 4 | ||||
-rw-r--r-- | src/script/lua_api/l_mapgen.cpp | 89 | ||||
-rw-r--r-- | src/script/lua_api/l_mapgen.h | 3 | ||||
-rw-r--r-- | src/script/lua_api/l_nodemeta.cpp | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_object.cpp | 125 | ||||
-rw-r--r-- | src/script/lua_api/l_object.h | 11 | ||||
-rw-r--r-- | src/script/lua_api/l_server.cpp | 4 | ||||
-rw-r--r-- | src/script/lua_api/l_vmanip.cpp | 2 |
18 files changed, 321 insertions, 78 deletions
diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp index d53d74aa8..908c766b0 100644 --- a/src/script/lua_api/l_areastore.cpp +++ b/src/script/lua_api/l_areastore.cpp @@ -185,6 +185,7 @@ int LuaAreaStore::l_insert_area(lua_State *L) if (lua_isnumber(L, 5)) a.id = lua_tonumber(L, 5); + // Insert & assign a new ID if necessary if (!ast->insertArea(&a)) return 0; diff --git a/src/script/lua_api/l_camera.cpp b/src/script/lua_api/l_camera.cpp index 462006777..80071b3b8 100644 --- a/src/script/lua_api/l_camera.cpp +++ b/src/script/lua_api/l_camera.cpp @@ -31,19 +31,24 @@ LuaCamera::LuaCamera(Camera *m) : m_camera(m) void LuaCamera::create(lua_State *L, Camera *m) { + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + lua_getfield(L, -1, "camera"); + + // Duplication check + if (lua_type(L, -1) == LUA_TUSERDATA) { + lua_pop(L, 1); + return; + } + LuaCamera *o = new LuaCamera(m); *(void **)(lua_newuserdata(L, sizeof(void *))) = o; luaL_getmetatable(L, className); lua_setmetatable(L, -2); - int camera_object = lua_gettop(L); - - lua_getglobal(L, "core"); - luaL_checktype(L, -1, LUA_TTABLE); - int coretable = lua_gettop(L); - - lua_pushvalue(L, camera_object); - lua_setfield(L, coretable, "camera"); + lua_pushvalue(L, lua_gettop(L)); + lua_setfield(L, objectstable, "camera"); } int LuaCamera::l_set_camera_mode(lua_State *L) diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 6d9d832b7..6345fc75f 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -210,17 +210,13 @@ int ModApiClient::l_get_language(lua_State *L) int ModApiClient::l_get_wielded_item(lua_State *L) { Client *client = getClient(L); + LocalPlayer *player = client->getEnv().getLocalPlayer(); + if (!player) + return 0; - Inventory local_inventory(client->idef()); - client->getLocalInventory(local_inventory); - - InventoryList *mlist = local_inventory.getList("main"); - - if (mlist && client->getPlayerItem() < mlist->getSize()) { - LuaItemStack::create(L, mlist->getItem(client->getPlayerItem())); - } else { - LuaItemStack::create(L, ItemStack()); - } + ItemStack selected_item; + player->getWieldedItem(&selected_item, nullptr); + LuaItemStack::create(L, selected_item); return 1; } diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index 0899b945e..18622ee00 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -294,7 +294,7 @@ int ModApiCraft::l_clear_craft(lua_State *L) std::string type = getstringfield_default(L, table, "type", "shaped"); CraftOutput c_output(output, 0); if (!output.empty()) { - if (craftdef->clearCraftRecipesByOutput(c_output, getServer(L))) { + if (craftdef->clearCraftsByOutput(c_output, getServer(L))) { lua_pushboolean(L, true); return 1; } @@ -351,7 +351,13 @@ int ModApiCraft::l_clear_craft(lua_State *L) throw LuaError("Unknown crafting definition type: \"" + type + "\""); } - if (!craftdef->clearCraftRecipesByInput(method, width, recipe, getServer(L))) { + std::vector<ItemStack> items; + items.reserve(recipe.size()); + for (const auto &item : recipe) + items.emplace_back(item, 1, 0, getServer(L)->idef()); + CraftInput input(method, width, items); + + if (!craftdef->clearCraftsByInput(input, getServer(L))) { warningstream << "No craft recipe matches input" << std::endl; lua_pushboolean(L, false); return 1; diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 711bd3fdd..a56b1cb0b 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -350,7 +350,7 @@ int ModApiEnvMod::l_get_node(lua_State *L) // pos v3s16 pos = read_v3s16(L, 1); // Do it - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); // Return node pushnode(L, n, env->getGameDef()->ndef()); return 1; @@ -366,7 +366,7 @@ int ModApiEnvMod::l_get_node_or_nil(lua_State *L) v3s16 pos = read_v3s16(L, 1); // Do it bool pos_ok; - MapNode n = env->getMap().getNodeNoEx(pos, &pos_ok); + MapNode n = env->getMap().getNode(pos, &pos_ok); if (pos_ok) { // Return node pushnode(L, n, env->getGameDef()->ndef()); @@ -392,7 +392,7 @@ int ModApiEnvMod::l_get_node_light(lua_State *L) u32 dnr = time_to_daynight_ratio(time_of_day, true); bool is_position_ok; - MapNode n = env->getMap().getNodeNoEx(pos, &is_position_ok); + MapNode n = env->getMap().getNode(pos, &is_position_ok); if (is_position_ok) { const NodeDefManager *ndef = env->getGameDef()->ndef(); lua_pushinteger(L, n.getLightBlend(dnr, ndef)); @@ -417,7 +417,7 @@ int ModApiEnvMod::l_place_node(lua_State *L) MapNode n = readnode(L, 2, ndef); // Don't attempt to load non-loaded area as of now - MapNode n_old = env->getMap().getNodeNoEx(pos); + MapNode n_old = env->getMap().getNode(pos); if(n_old.getContent() == CONTENT_IGNORE){ lua_pushboolean(L, false); return 1; @@ -446,7 +446,7 @@ int ModApiEnvMod::l_dig_node(lua_State *L) v3s16 pos = read_v3s16(L, 1); // Don't attempt to load non-loaded area as of now - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); if(n.getContent() == CONTENT_IGNORE){ lua_pushboolean(L, false); return 1; @@ -469,7 +469,7 @@ int ModApiEnvMod::l_punch_node(lua_State *L) v3s16 pos = read_v3s16(L, 1); // Don't attempt to load non-loaded area as of now - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); if(n.getContent() == CONTENT_IGNORE){ lua_pushboolean(L, false); return 1; @@ -491,7 +491,7 @@ int ModApiEnvMod::l_get_node_max_level(lua_State *L) } v3s16 pos = read_v3s16(L, 1); - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); lua_pushnumber(L, n.getMaxLevel(env->getGameDef()->ndef())); return 1; } @@ -506,7 +506,7 @@ int ModApiEnvMod::l_get_node_level(lua_State *L) } v3s16 pos = read_v3s16(L, 1); - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); lua_pushnumber(L, n.getLevel(env->getGameDef()->ndef())); return 1; } @@ -522,7 +522,7 @@ int ModApiEnvMod::l_set_node_level(lua_State *L) u8 level = 1; if(lua_isnumber(L, 2)) level = lua_tonumber(L, 2); - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); lua_pushnumber(L, n.setLevel(env->getGameDef()->ndef(), level)); env->setNode(pos, n); return 1; @@ -539,7 +539,7 @@ int ModApiEnvMod::l_add_node_level(lua_State *L) u8 level = 1; if(lua_isnumber(L, 2)) level = lua_tonumber(L, 2); - MapNode n = env->getMap().getNodeNoEx(pos); + MapNode n = env->getMap().getNode(pos); lua_pushnumber(L, n.addLevel(env->getGameDef()->ndef(), level)); env->setNode(pos, n); return 1; @@ -780,7 +780,7 @@ int ModApiEnvMod::l_find_node_near(lua_State *L) std::vector<v3s16> list = FacePositionCache::getFacePositions(d); for (const v3s16 &i : list) { v3s16 p = pos + i; - content_t c = env->getMap().getNodeNoEx(p).getContent(); + content_t c = env->getMap().getNode(p).getContent(); if (CONTAINS(filter, c)) { push_v3s16(L, p); return 1; @@ -832,7 +832,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L) for (s16 y = minp.Y; y <= maxp.Y; y++) for (s16 z = minp.Z; z <= maxp.Z; z++) { v3s16 p(x, y, z); - content_t c = env->getMap().getNodeNoEx(p).getContent(); + content_t c = env->getMap().getNode(p).getContent(); std::vector<content_t>::iterator it = std::find(filter.begin(), filter.end(), c); if (it != filter.end()) { @@ -898,10 +898,10 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L) for (s16 z = minp.Z; z <= maxp.Z; z++) { s16 y = minp.Y; v3s16 p(x, y, z); - content_t c = env->getMap().getNodeNoEx(p).getContent(); + content_t c = env->getMap().getNode(p).getContent(); for (; y <= maxp.Y; y++) { v3s16 psurf(x, y + 1, z); - content_t csurf = env->getMap().getNodeNoEx(psurf).getContent(); + content_t csurf = env->getMap().getNode(psurf).getContent(); if (c != CONTENT_AIR && csurf == CONTENT_AIR && CONTAINS(filter, c)) { push_v3s16(L, v3s16(x, y, z)); @@ -1035,7 +1035,7 @@ int ModApiEnvMod::l_fix_light(lua_State *L) for (auto &modified_block : modified_blocks) event.modified_blocks.insert(modified_block.first); - map.dispatchEvent(&event); + map.dispatchEvent(event); } lua_pushboolean(L, success); @@ -1144,7 +1144,7 @@ int ModApiEnvMod::l_delete_area(lua_State *L) } } - map.dispatchEvent(&event); + map.dispatchEvent(event); lua_pushboolean(L, success); return 1; } diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp index ac261cd60..2ff651cb5 100644 --- a/src/script/lua_api/l_http.cpp +++ b/src/script/lua_api/l_http.cpp @@ -53,9 +53,8 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req) lua_getfield(L, 1, "post_data"); if (lua_istable(L, 2)) { lua_pushnil(L); - while (lua_next(L, 2) != 0) - { - req.post_fields[luaL_checkstring(L, -2)] = luaL_checkstring(L, -1); + while (lua_next(L, 2) != 0) { + req.post_fields[readParam<std::string>(L, -2)] = readParam<std::string>(L, -1); lua_pop(L, 1); } } else if (lua_isstring(L, 2)) { @@ -66,10 +65,8 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req) lua_getfield(L, 1, "extra_headers"); if (lua_istable(L, 2)) { lua_pushnil(L); - while (lua_next(L, 2) != 0) - { - const char *header = luaL_checkstring(L, -1); - req.extra_headers.emplace_back(header); + while (lua_next(L, 2) != 0) { + req.extra_headers.emplace_back(readParam<std::string>(L, -1)); lua_pop(L, 1); } } @@ -83,7 +80,7 @@ void ModApiHttp::push_http_fetch_result(lua_State *L, HTTPFetchResult &res, bool setboolfield(L, -1, "timeout", res.timeout); setboolfield(L, -1, "completed", completed); setintfield(L, -1, "code", res.response_code); - setstringfield(L, -1, "data", res.data.c_str()); + setstringfield(L, -1, "data", res.data); } // http_api.fetch_async(HTTPRequest definition) @@ -94,7 +91,7 @@ int ModApiHttp::l_http_fetch_async(lua_State *L) HTTPFetchRequest req; read_http_fetch_request(L, req); - actionstream << "Mod performs HTTP request with URL " << req.url << std::endl; + infostream << "Mod performs HTTP request with URL " << req.url << std::endl; httpfetch_async(req); // Convert handle to hex string since lua can't handle 64-bit integers diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index e41d23fd1..f9708b560 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -175,6 +175,16 @@ int LuaItemStack::l_set_metadata(lua_State *L) return 1; } +// get_description(self) +int LuaItemStack::l_get_description(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + std::string desc = o->m_stack.getDescription(getGameDef(L)->idef()); + lua_pushstring(L, desc.c_str()); + return 1; +} + // clear(self) -> true int LuaItemStack::l_clear(lua_State *L) { @@ -470,6 +480,7 @@ const luaL_Reg LuaItemStack::methods[] = { luamethod(LuaItemStack, get_meta), luamethod(LuaItemStack, get_metadata), luamethod(LuaItemStack, set_metadata), + luamethod(LuaItemStack, get_description), luamethod(LuaItemStack, clear), luamethod(LuaItemStack, replace), luamethod(LuaItemStack, to_string), diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index 5ff715b2a..6fab58045 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -66,6 +66,9 @@ private: // set_metadata(self, string) static int l_set_metadata(lua_State *L); + // get_description(self) + static int l_get_description(lua_State *L); + // clear(self) -> true static int l_clear(lua_State *L); diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index 7444d0e88..3e14e48e4 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -30,20 +30,24 @@ LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m) : m_localplayer(m) void LuaLocalPlayer::create(lua_State *L, LocalPlayer *m) { + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + lua_getfield(L, -1, "localplayer"); + + // Duplication check + if (lua_type(L, -1) == LUA_TUSERDATA) { + lua_pop(L, 1); + return; + } + LuaLocalPlayer *o = new LuaLocalPlayer(m); *(void **)(lua_newuserdata(L, sizeof(void *))) = o; luaL_getmetatable(L, className); lua_setmetatable(L, -2); - // Keep localplayer object stack id - int localplayer_object = lua_gettop(L); - - lua_getglobal(L, "core"); - luaL_checktype(L, -1, LUA_TTABLE); - int coretable = lua_gettop(L); - - lua_pushvalue(L, localplayer_object); - lua_setfield(L, coretable, "localplayer"); + lua_pushvalue(L, lua_gettop(L)); + lua_setfield(L, objectstable, "localplayer"); } int LuaLocalPlayer::l_get_velocity(lua_State *L) diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 2557f448a..76db7ed13 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -107,6 +107,21 @@ int ModApiMainMenu::l_update_formspec(lua_State *L) } /******************************************************************************/ +int ModApiMainMenu::l_set_formspec_prepend(lua_State *L) +{ + GUIEngine *engine = getGuiEngine(L); + sanity_check(engine != NULL); + + if (engine->m_startgame) + return 0; + + std::string formspec(luaL_checkstring(L, 1)); + engine->setFormspecPrepend(formspec); + + return 0; +} + +/******************************************************************************/ int ModApiMainMenu::l_start(lua_State *L) { GUIEngine* engine = getGuiEngine(L); @@ -867,6 +882,16 @@ bool ModApiMainMenu::mayModifyPath(const std::string &path) return false; } + +/******************************************************************************/ +int ModApiMainMenu::l_may_modify_path(lua_State *L) +{ + const char *target = luaL_checkstring(L, 1); + std::string absolute_destination = fs::RemoveRelativePathComponents(target); + lua_pushboolean(L, ModApiMainMenu::mayModifyPath(absolute_destination)); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_show_path_select_dialog(lua_State *L) { @@ -1031,6 +1056,7 @@ int ModApiMainMenu::l_do_async_callback(lua_State *L) void ModApiMainMenu::Initialize(lua_State *L, int top) { API_FCT(update_formspec); + API_FCT(set_formspec_prepend); API_FCT(set_clouds); API_FCT(get_textlist_index); API_FCT(get_table_index); @@ -1057,6 +1083,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(delete_dir); API_FCT(copy_dir); API_FCT(extract_zip); + API_FCT(may_modify_path); API_FCT(get_mainmenu_path); API_FCT(show_path_select_dialog); API_FCT(download_file); @@ -1086,6 +1113,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) API_FCT(delete_dir); API_FCT(copy_dir); //API_FCT(extract_zip); //TODO remove dependency to GuiEngine + API_FCT(may_modify_path); API_FCT(download_file); //API_FCT(gettext); (gettext lib isn't threadsafe) } diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 4a664359a..b2ca49320 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -104,6 +104,8 @@ private: static int l_update_formspec(lua_State *L); + static int l_set_formspec_prepend(lua_State *L); + static int l_get_screen_info(lua_State *L); //filesystem @@ -130,6 +132,8 @@ private: static int l_extract_zip(lua_State *L); + static int l_may_modify_path(lua_State *L); + static int l_download_file(lua_State *L); static int l_get_video_drivers(lua_State *L); diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 92ed4377e..2e0cba8dd 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -405,7 +405,16 @@ Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef) 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", "")); - nn.push_back(getstringfield_default(L, index, "node_cave_liquid", "")); + + size_t nnames = getstringlistfield(L, index, "node_cave_liquid", &nn); + // If no cave liquids defined, set list to "ignore" to trigger old hardcoded + // cave liquid behaviour. + if (nnames == 0) { + nn.emplace_back("ignore"); + nnames = 1; + } + b->m_nnlistsizes.push_back(nnames); + nn.push_back(getstringfield_default(L, index, "node_dungeon", "")); nn.push_back(getstringfield_default(L, index, "node_dungeon_alt", "")); nn.push_back(getstringfield_default(L, index, "node_dungeon_stair", "")); @@ -1745,6 +1754,83 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L) return 1; } +// read_schematic(schematic, options={...}) +int ModApiMapgen::l_read_schematic(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + + //// Read options + std::string write_yslice = getstringfield_default(L, 2, "write_yslice_prob", "all"); + + //// Get schematic + bool was_loaded = false; + Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr); + if (!schem) { + schem = load_schematic(L, 1, NULL, NULL); + was_loaded = true; + } + if (!schem) { + errorstream << "read_schematic: failed to get schematic" << std::endl; + return 0; + } + lua_pop(L, 2); + + //// Create the Lua table + u32 numnodes = schem->size.X * schem->size.Y * schem->size.Z; + const std::vector<std::string> &names = schem->m_nodenames; + + lua_createtable(L, 0, (write_yslice == "none") ? 2 : 3); + + // Create the size field + push_v3s16(L, schem->size); + lua_setfield(L, 1, "size"); + + // Create the yslice_prob field + if (write_yslice != "none") { + lua_createtable(L, schem->size.Y, 0); + for (u16 y = 0; y != schem->size.Y; ++y) { + u8 probability = schem->slice_probs[y] & MTSCHEM_PROB_MASK; + if (probability < MTSCHEM_PROB_ALWAYS || write_yslice != "low") { + lua_createtable(L, 0, 2); + lua_pushinteger(L, y); + lua_setfield(L, 3, "ypos"); + lua_pushinteger(L, probability * 2); + lua_setfield(L, 3, "prob"); + lua_rawseti(L, 2, y + 1); + } + } + lua_setfield(L, 1, "yslice_prob"); + } + + // Create the data field + lua_createtable(L, numnodes, 0); // data table + for (u32 i = 0; i < numnodes; ++i) { + MapNode node = schem->schemdata[i]; + u8 probability = node.param1 & MTSCHEM_PROB_MASK; + bool force_place = node.param1 & MTSCHEM_FORCE_PLACE; + lua_createtable(L, 0, force_place ? 4 : 3); + lua_pushstring(L, names[schem->schemdata[i].getContent()].c_str()); + lua_setfield(L, 3, "name"); + lua_pushinteger(L, probability * 2); + lua_setfield(L, 3, "prob"); + lua_pushinteger(L, node.param2); + lua_setfield(L, 3, "param2"); + if (force_place) { + lua_pushboolean(L, 1); + lua_setfield(L, 3, "force_place"); + } + lua_rawseti(L, 2, i + 1); + } + lua_setfield(L, 1, "data"); + + if (was_loaded) + delete schem; + + return 1; +} + void ModApiMapgen::Initialize(lua_State *L, int top) { @@ -1784,4 +1870,5 @@ void ModApiMapgen::Initialize(lua_State *L, int top) API_FCT(place_schematic); API_FCT(place_schematic_on_vmanip); API_FCT(serialize_schematic); + API_FCT(read_schematic); } diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h index 1339791f3..4a6a9ccf4 100644 --- a/src/script/lua_api/l_mapgen.h +++ b/src/script/lua_api/l_mapgen.h @@ -131,6 +131,9 @@ private: // serialize_schematic(schematic, format, options={...}) static int l_serialize_schematic(lua_State *L); + // read_schematic(schematic, options={...}) + static int l_read_schematic(lua_State *L); + public: static void Initialize(lua_State *L, int top); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 22fc61782..229ce73db 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -68,7 +68,7 @@ void NodeMetaRef::reportMetadataChange(const std::string *name) event.type = MEET_BLOCK_NODE_METADATA_CHANGED; event.p = m_p; event.is_private_change = name && meta && meta->isPrivate(*name); - m_env->getMap().dispatchEvent(&event); + m_env->getMap().dispatchEvent(event); } // Exported functions diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index b3ed39c7c..efdb345c9 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -170,8 +170,8 @@ int ObjectRef::l_punch(lua_State *L) ObjectRef *puncher_ref = checkobject(L, 2); ServerActiveObject *co = getobject(ref); ServerActiveObject *puncher = getobject(puncher_ref); - if (co == NULL) return 0; - if (puncher == NULL) return 0; + if (!co || !puncher) + return 0; v3f dir; if (lua_type(L, 5) != LUA_TTABLE) dir = co->getBasePosition() - puncher->getBasePosition(); @@ -187,12 +187,14 @@ int ObjectRef::l_punch(lua_State *L) u16 dst_origin_hp = puncher->getHP(); // Do it - co->punch(dir, &toolcap, puncher, time_from_last_punch); + u16 wear = co->punch(dir, &toolcap, puncher, time_from_last_punch); + lua_pushnumber(L, wear); // If the punched is a player, and its HP changed if (src_original_hp != co->getHP() && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); + getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, + PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); } // If the puncher is a player, and its HP changed @@ -201,7 +203,7 @@ int ObjectRef::l_punch(lua_State *L) getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher, PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, co)); } - return 0; + return 1; } // right_click(self, clicker); clicker = an another ObjectRef @@ -307,8 +309,9 @@ int ObjectRef::l_get_wield_list(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; - // Do it + if (!co) + return 0; + lua_pushstring(L, co->getWieldList().c_str()); return 1; } @@ -319,8 +322,9 @@ int ObjectRef::l_get_wield_index(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; - // Do it + if (!co) + return 0; + lua_pushinteger(L, co->getWieldIndex() + 1); return 1; } @@ -331,13 +335,15 @@ int ObjectRef::l_get_wielded_item(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) { + if (!co) { // Empty ItemStack LuaItemStack::create(L, ItemStack()); return 1; } - // Do it - LuaItemStack::create(L, co->getWieldedItem()); + + ItemStack selected_item; + co->getWieldedItem(&selected_item, nullptr); + LuaItemStack::create(L, selected_item); return 1; } @@ -352,7 +358,7 @@ int ObjectRef::l_set_wielded_item(lua_State *L) ItemStack item = read_item(L, 2, getServer(L)->idef()); bool success = co->setWieldedItem(item); if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - getServer(L)->SendInventory(((PlayerSAO*)co)); + getServer(L)->SendInventory((PlayerSAO *)co, true); } lua_pushboolean(L, success); return 1; @@ -583,6 +589,24 @@ int ObjectRef::l_get_eye_offset(lua_State *L) return 2; } +// send_mapblock(self, pos) +int ObjectRef::l_send_mapblock(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + v3s16 p = read_v3s16(L, 2); + + session_t peer_id = player->getPeerId(); + bool r = getServer(L)->SendBlock(peer_id, p); + + lua_pushboolean(L, r); + return 1; +} + // set_animation_frame_speed(self, frame_speed) int ObjectRef::l_set_animation_frame_speed(lua_State *L) { @@ -731,17 +755,14 @@ int ObjectRef::l_set_properties(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if (co == NULL) return 0; + if (!co) + return 0; + ObjectProperties *prop = co->accessObjectProperties(); if (!prop) return 0; - read_object_properties(L, 2, prop, getServer(L)->idef()); - if (prop->hp_max < co->getHP()) { - PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP); - co->setHP(prop->hp_max, reason); - if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) - getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason); - } + + read_object_properties(L, 2, co, prop, getServer(L)->idef()); co->notifyObjectPropertiesModified(); return 0; } @@ -1074,6 +1095,27 @@ int ObjectRef::l_get_player_velocity(lua_State *L) return 1; } +// add_player_velocity(self, {x=num, y=num, z=num}) +int ObjectRef::l_add_player_velocity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + v3f vel = checkFloatPos(L, 2); + + RemotePlayer *player = getplayer(ref); + PlayerSAO *co = getplayersao(ref); + if (!player || !co) + return 0; + + session_t peer_id = player->getPeerId(); + if (peer_id == PEER_ID_INEXISTENT) + return 0; + // Do it + co->setMaxSpeedOverride(vel); + getServer(L)->SendPlayerSpeed(peer_id, vel); + return 0; +} + // get_look_dir(self) int ObjectRef::l_get_look_dir(lua_State *L) { @@ -1210,6 +1252,37 @@ int ObjectRef::l_set_look_yaw(lua_State *L) return 1; } +// set_fov(self, degrees[, is_multiplier]) +int ObjectRef::l_set_fov(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + + player->setFov({ static_cast<f32>(luaL_checknumber(L, 2)), readParam<bool>(L, 3) }); + getServer(L)->SendPlayerFov(player->getPeerId()); + + return 0; +} + +// get_fov(self) +int ObjectRef::l_get_fov(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + + PlayerFovSpec fov_spec = player->getFov(); + lua_pushnumber(L, fov_spec.fov); + lua_pushboolean(L, fov_spec.is_multiplier); + + return 2; +} + // set_breath(self, breath) int ObjectRef::l_set_breath(lua_State *L) { @@ -1239,6 +1312,9 @@ int ObjectRef::l_get_breath(lua_State *L) // set_attribute(self, attribute, value) int ObjectRef::l_set_attribute(lua_State *L) { + log_deprecated(L, + "Deprecated call to set_attribute, use MetaDataRef methods instead."); + ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); if (co == NULL) @@ -1257,6 +1333,9 @@ int ObjectRef::l_set_attribute(lua_State *L) // get_attribute(self, attribute) int ObjectRef::l_get_attribute(lua_State *L) { + log_deprecated(L, + "Deprecated call to get_attribute, use MetaDataRef methods instead."); + ObjectRef *ref = checkobject(L, 1); PlayerSAO* co = getplayersao(ref); if (co == NULL) @@ -1907,6 +1986,7 @@ luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, is_player_connected), luamethod(ObjectRef, get_player_name), luamethod(ObjectRef, get_player_velocity), + luamethod(ObjectRef, add_player_velocity), luamethod(ObjectRef, get_look_dir), luamethod(ObjectRef, get_look_pitch), luamethod(ObjectRef, get_look_yaw), @@ -1916,6 +1996,8 @@ luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, set_look_vertical), luamethod(ObjectRef, set_look_yaw), luamethod(ObjectRef, set_look_pitch), + luamethod(ObjectRef, get_fov), + luamethod(ObjectRef, set_fov), luamethod(ObjectRef, get_breath), luamethod(ObjectRef, set_breath), luamethod(ObjectRef, get_attribute), @@ -1951,5 +2033,6 @@ luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, get_local_animation), luamethod(ObjectRef, set_eye_offset), luamethod(ObjectRef, get_eye_offset), + luamethod(ObjectRef, send_mapblock), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index c7d963d87..e817e1d33 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -212,6 +212,12 @@ private: // get_player_velocity(self) static int l_get_player_velocity(lua_State *L); + // add_player_velocity(self, {x=num, y=num, z=num}) + static int l_add_player_velocity(lua_State *L); + + // get_fov(self) + static int l_get_fov(lua_State *L); + // get_look_dir(self) static int l_get_look_dir(lua_State *L); @@ -229,6 +235,9 @@ private: // get_look_yaw2(self) static int l_get_look_horizontal(lua_State *L); + // set_fov(self, degrees, is_multiplier) + static int l_set_fov(lua_State *L); + // set_look_vertical(self, radians) static int l_set_look_vertical(lua_State *L); @@ -351,4 +360,6 @@ private: // get_nametag_attributes(self) static int l_get_nametag_attributes(lua_State *L); + // send_mapblock(pos) + static int l_send_mapblock(lua_State *L); }; diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 6017a5475..7c083e652 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -233,6 +233,10 @@ int ModApiServer::l_get_player_information(lua_State *L) lua_pushnumber(L, prot_vers); lua_settable(L, table); + lua_pushstring(L, "formspec_version"); + lua_pushnumber(L, player->formspec_version); + lua_settable(L, table); + #ifndef NDEBUG lua_pushstring(L,"serialization_version"); lua_pushnumber(L, ser_vers); diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index c92983bd3..fd73d21d1 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -126,7 +126,7 @@ int LuaVoxelManip::l_write_to_map(lua_State *L) for (const auto &modified_block : o->modified_blocks) event.modified_blocks.insert(modified_block.first); - map->dispatchEvent(&event); + map->dispatchEvent(event); o->modified_blocks.clear(); return 0; |