From 8db748562c40b07660b8154073c1a6f7f7c6ad19 Mon Sep 17 00:00:00 2001 From: swagtoy Date: Wed, 26 Jun 2024 23:02:58 -0400 Subject: [PATCH] Finish pause menu --- builtin/client/pause_menu.lua | 69 +++++++++++++++++-- src/client/game.cpp | 115 ++++---------------------------- src/gui/mainmenumanager.h | 7 ++ src/script/cpp_api/s_client.cpp | 11 ++- src/script/cpp_api/s_client.h | 2 +- 5 files changed, 91 insertions(+), 113 deletions(-) diff --git a/builtin/client/pause_menu.lua b/builtin/client/pause_menu.lua index 6df4032eb..41d25f302 100644 --- a/builtin/client/pause_menu.lua +++ b/builtin/client/pause_menu.lua @@ -1,12 +1,35 @@ local SIZE_TAG = "size[11,5.5,true]" -local function menu_formspec() - local simple_singleplayer_mode = true +local function avoid_noid() + return "label[1,1;Avoid the Noid!]" +end + +local function menu_formspec(simple_singleplayer_mode, is_touchscreen, address) local ypos = simple_singleplayer_mode and 0.7 or 0.1 + local control_text = "" + + if is_touchscreen then + control_text = fgettext([[Controls: +No menu open: +- slide finger: look around +- tap: place/punch/use (default) +- long tap: dig/use (default) +Menu/inventory open: +- double tap (outside): + --> close +- touch stack, touch slot: + --> move stack +- touch&drag, tap 2nd finger + --> place single item to slot +]]) + end + local fs = { "formspec_version[1]", - SIZE_TAG + SIZE_TAG, + ("button_exit[4,%f;3,0.5;btn_continue;%s]"):format(ypos, fgettext("Continue")) } + ypos = ypos + 1 if not simple_singleplayer_mode then fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_change_password;%s]"):format( @@ -14,7 +37,6 @@ local function menu_formspec() else fs[#fs + 1] = "field[4.95,0;5,1.5;;" .. fgettext("Game paused") .. ";]" end - ypos = ypos + 1 fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_key_config;%s]"):format( ypos, fgettext("Controls")) @@ -29,11 +51,44 @@ local function menu_formspec() ypos, fgettext("Exit to OS")) ypos = ypos + 1 + -- Controls + if control_text ~= "" then + fs[#fs + 1] = ("textarea[7.5,0.25;3.9,6.25;;%s;]"):format(control_text) + end + + -- Server info + local info = minetest.get_version() + fs[#fs + 1] = ("textarea[0.4,0.25;3.9,6.25;;%s %s\n\n%s\n"):format( + info.project, info.hash or info.string, fgettext("Game info:")) + + fs[#fs + 1] = "- Mode: " .. (simple_singleplayer_mode and "Singleplayer" or + ((not address) and "Hosting server" or "Remote server")) + + if not address then + local enable_damage = minetest.settings:get_bool("enable_damage") + local enable_pvp = minetest.settings:get_bool("enable_pvp") + local server_announce = minetest.settings:get_bool("server_announce") + local server_name = minetest.settings:get("server_name") + table.insert_all(fs, { + "\n", + enable_damage and + ("- PvP: " .. (enable_pvp and "On" or "Off")) or "", + "\n", + "- Public: " .. (server_announce and "On" or "Off"), + "\n", + (server_announce and server_name) and + ("- Server Name: " .. minetest.formspec_escape(server_name)) or "" + }) + end + + fs[#fs + 1] = ";]" + + return table.concat(fs, "") end -function core.show_pause_menu() - local fs = menu_formspec() +function core.show_pause_menu(is_singleplayer, is_touchscreen, address) + minetest.log(dump(core)) - minetest.show_formspec("MT_PAUSE_MENU", fs) + minetest.show_formspec("MT_PAUSE_MENU", menu_formspec(is_singleplayer, is_touchscreen, address)) end diff --git a/src/client/game.cpp b/src/client/game.cpp index cb5010406..9a05cd1a5 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -159,6 +159,10 @@ struct LocalFormspecHandler : public TextDest g_gamecallback->keyConfig(); return; } + + else if (fields.find("btn_settings") != fields.end()) { + g_gamecallback->showSettings(); + } else if (fields.find("btn_exit_menu") != fields.end()) { g_gamecallback->disconnect(); @@ -1882,6 +1886,11 @@ inline bool Game::handleCallbacks() m_is_paused = false; g_gamecallback->unpause_requested = false; } + + if (g_gamecallback->show_settings_requested) { + + g_gamecallback->show_settings_requested = false; + } if (!g_gamecallback->show_open_url_dialog.empty()) { (new GUIOpenURLMenu(guienv, guiroot, -1, @@ -4458,111 +4467,11 @@ void Game::showPauseMenu() { if (client->modsLoaded()) { - client->getScript()->show_pause_menu(); + client->getScript()->show_pause_menu(simple_singleplayer_mode, + g_touchscreengui, + client->getAddressName()); m_is_paused = true; } - return; - - std::string control_text; - - if (g_touchscreengui) { - control_text = strgettext("Controls:\n" - "No menu open:\n" - "- slide finger: look around\n" - "- tap: place/punch/use (default)\n" - "- long tap: dig/use (default)\n" - "Menu/inventory open:\n" - "- double tap (outside):\n" - " --> close\n" - "- touch stack, touch slot:\n" - " --> move stack\n" - "- touch&drag, tap 2nd finger\n" - " --> place single item to slot\n" - ); - } - - float ypos = simple_singleplayer_mode ? 0.7f : 0.1f; - std::ostringstream os; - - os << "formspec_version[1]" << SIZE_TAG - << "button_exit[4," << (ypos++) << ";3,0.5;btn_continue;" - << strgettext("Continue") << "]"; - - if (!simple_singleplayer_mode) { - os << "button_exit[4," << (ypos++) << ";3,.5;btn_change_password;" - << strgettext("Change Password") << "]"; - } else { - os << "field[4.95,0;5,1.5;;" << strgettext("Game paused") << ";]"; - } - -#ifndef __ANDROID__ -#if USE_SOUND - if (g_settings->getBool("enable_sound")) { - os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;" - << strgettext("Sound Volume") << "]"; - } -#endif - os << "button_exit[4," << (ypos++) << ";3,0.5;btn_key_config;" - << strgettext("Controls") << "]"; -#endif - os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_menu;" - << strgettext("Exit to Menu") << "]"; - os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_os;" - << strgettext("Exit to OS") << "]"; - if (!control_text.empty()) { - os << "textarea[7.5,0.25;3.9,6.25;;" << control_text << ";]"; - } - os << "textarea[0.4,0.25;3.9,6.25;;" << PROJECT_NAME_C " " VERSION_STRING "\n" - << "\n" - << strgettext("Game info:") << "\n"; - const std::string &address = client->getAddressName(); - os << strgettext("- Mode: "); - if (!simple_singleplayer_mode) { - if (address.empty()) - os << strgettext("Hosting server"); - else - os << strgettext("Remote server"); - } else { - os << strgettext("Singleplayer"); - } - os << "\n"; - if (simple_singleplayer_mode || address.empty()) { - static const std::string on = strgettext("On"); - static const std::string off = strgettext("Off"); - // Note: Status of enable_damage and creative_mode settings is intentionally - // NOT shown here because the game might roll its own damage system and/or do - // a per-player Creative Mode, in which case writing it here would mislead. - bool damage = g_settings->getBool("enable_damage"); - const std::string &announced = g_settings->getBool("server_announce") ? on : off; - if (!simple_singleplayer_mode) { - if (damage) { - const std::string &pvp = g_settings->getBool("enable_pvp") ? on : off; - //~ PvP = Player versus Player - os << strgettext("- PvP: ") << pvp << "\n"; - } - os << strgettext("- Public: ") << announced << "\n"; - std::string server_name = g_settings->get("server_name"); - str_formspec_escape(server_name); - if (announced == on && !server_name.empty()) - os << strgettext("- Server Name: ") << server_name; - - } - } - os << ";]"; - - /* Create menu */ - /* Note: FormspecFormSource and LocalFormspecHandler * - * are deleted by guiFormSpecMenu */ - FormspecFormSource *fs_src = new FormspecFormSource(os.str()); - LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU"); - - auto *&formspec = m_game_ui->getFormspecGUI(); - GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(), - &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), - sound_manager.get()); - formspec->setFocus("btn_continue"); - // game will be paused in next step, if in singleplayer (see m_is_paused) - formspec->doPause = true; } /****************************************************************************/ diff --git a/src/gui/mainmenumanager.h b/src/gui/mainmenumanager.h index 7d4035ad3..06c8d22c2 100644 --- a/src/gui/mainmenumanager.h +++ b/src/gui/mainmenumanager.h @@ -35,6 +35,7 @@ class IGameCallback virtual void changePassword() = 0; virtual void changeVolume() = 0; virtual void unpause() = 0; + virtual void showSettings() = 0; virtual void showOpenURLDialog(const std::string &url) = 0; virtual void signalKeyConfigChange() = 0; }; @@ -152,6 +153,11 @@ class MainGameCallback : public IGameCallback { unpause_requested = true; } + + void showSettings() override + { + show_settings_requested = true; + } bool disconnect_requested = false; bool changepassword_requested = false; @@ -159,6 +165,7 @@ class MainGameCallback : public IGameCallback bool keyconfig_requested = false; bool shutdown_requested = false; bool unpause_requested = false; + bool show_settings_requested = false; bool keyconfig_changed = false; std::string show_open_url_dialog = ""; }; diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index c4a86ffac..5b1cb4be2 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -290,7 +290,7 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory) return readParam(L, -1); } -void ScriptApiClient::show_pause_menu() +void ScriptApiClient::show_pause_menu(bool is_singleplayer, bool is_touchscreen, const std::string& server_address) { SCRIPTAPI_PRECHECKHEADER @@ -299,7 +299,14 @@ void ScriptApiClient::show_pause_menu() lua_getglobal(L, "core"); lua_getfield(L, -1, "show_pause_menu"); - PCALL_RES(lua_pcall(L, 0, 0, error_handler)); + lua_pushboolean(L, is_singleplayer); + lua_pushboolean(L, is_touchscreen); + if (!server_address.empty()) + lua_pushstring(L, server_address.c_str()); + else + lua_pushnil(L); + + PCALL_RES(lua_pcall(L, 3, 0, error_handler)); lua_pop(L, 1); } diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index 88a6e4b59..f5c48530c 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -60,7 +60,7 @@ class ScriptApiClient : virtual public ScriptApiBase bool on_inventory_open(Inventory *inventory); - void show_pause_menu(); + void show_pause_menu(bool is_singleplayer, bool is_touchscreen, const std::string& server_address); void setEnv(ClientEnvironment *env); };