diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index 1333a75ba..040016333 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -239,3 +239,7 @@ else end +function core.close_formspec(player_name, formname) + return minetest.show_formspec(player_name, formname, "") +end + diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 80e66020d..760a829d3 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2316,6 +2316,13 @@ and `minetest.auth_reload` call the authetification handler. * `formname`: name passed to `on_player_receive_fields` callbacks. It should follow the `"modname:"` naming convention * `formspec`: formspec to display +* `minetest.close_formspec(playername, formname)` + * `playername`: name of player to close formspec + * `formname`: has to exactly match the one given in show_formspec, or the formspec will + not close. + * calling show_formspec(playername, formname, "") is equal to this expression + * to close a formspec regardless of the formname, call + minetest.close_formspec(playername, ""). USE THIS ONLY WHEN ABSOLUTELY NECESSARY! * `minetest.formspec_escape(string)`: returns a string * escapes the characters "[", "]", "\", "," and ";", which can not be used in formspecs * `minetest.explode_table_event(string)`: returns a table diff --git a/src/game.cpp b/src/game.cpp index 16287fe0d..671682348 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1205,6 +1205,7 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec, (*cur_formspec)->setFormSource(fs_src); (*cur_formspec)->setTextDest(txt_dest); } + } #ifdef __ANDROID__ @@ -1753,6 +1754,8 @@ private: ChatBackend *chat_backend; GUIFormSpecMenu *current_formspec; + //default: "". If other than "", empty show_formspec packets will only close the formspec when the formname matches + std::string cur_formname; EventManager *eventmgr; QuicktuneShortcutter *quicktune; @@ -1841,6 +1844,7 @@ Game::Game() : soundmaker(NULL), chat_backend(NULL), current_formspec(NULL), + cur_formname(""), eventmgr(NULL), quicktune(NULL), gui_chat_console(NULL), @@ -3005,6 +3009,7 @@ void Game::openInventory() create_formspec_menu(¤t_formspec, client, gamedef, texture_src, device, &input->joystick, fs_src, txt_dst, client); + cur_formname = ""; InventoryLocation inventoryloc; inventoryloc.setCurrentPlayer(); @@ -3484,14 +3489,21 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash) player->hurt_tilt_strength = 0; } else if (event.type == CE_SHOW_FORMSPEC) { - FormspecFormSource *fs_src = - new FormspecFormSource(*(event.show_formspec.formspec)); - TextDestPlayerInventory *txt_dst = - new TextDestPlayerInventory(client, *(event.show_formspec.formname)); + if (*(event.show_formspec.formspec) == "") { + if (current_formspec && ( *(event.show_formspec.formname) == "" || *(event.show_formspec.formname) == cur_formname) ){ + current_formspec->quitMenu(); + } + } else { + FormspecFormSource *fs_src = + new FormspecFormSource(*(event.show_formspec.formspec)); + TextDestPlayerInventory *txt_dst = + new TextDestPlayerInventory(client, *(event.show_formspec.formname)); - create_formspec_menu(¤t_formspec, client, gamedef, - texture_src, device, &input->joystick, - fs_src, txt_dst, client); + create_formspec_menu(¤t_formspec, client, gamedef, + texture_src, device, &input->joystick, + fs_src, txt_dst, client); + cur_formname = *(event.show_formspec.formname); + } delete(event.show_formspec.formspec); delete(event.show_formspec.formname); @@ -3955,6 +3967,7 @@ void Game::handlePointingAtNode(GameRunData *runData, create_formspec_menu(¤t_formspec, client, gamedef, texture_src, device, &input->joystick, fs_src, txt_dst, client); + cur_formname = ""; current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc); } else { diff --git a/src/server.cpp b/src/server.cpp index 48331e4f8..fae375425 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1647,8 +1647,12 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, DSTACK(FUNCTION_NAME); NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0 , peer_id); - - pkt.putLongString(FORMSPEC_VERSION_STRING + formspec); + if (formspec == "" ){ + //the client should close the formspec + pkt.putLongString(""); + } else { + pkt.putLongString(FORMSPEC_VERSION_STRING + formspec); + } pkt << formname; Send(&pkt);