From 338162f40c1e4b9b7a780983d17e0cc2d5e28f0f Mon Sep 17 00:00:00 2001 From: terencehill Date: Sun, 24 Jul 2022 20:20:51 +0200 Subject: [PATCH] Fix #2724 "Pressing escape opens wrong menu when watching demos". Since the Welcome dialog was opened and hidden instantly (not closed), on the next ESC press it popped up again and only on the next ESC press it was really closed. Fixed thanks to a new menu_cmd command that can close a specific dialog, or in the case of the Welcome dialog it allows initializing it without opening it --- qcsrc/client/main.qc | 22 +++++++++++++++++--- qcsrc/menu/command/menu_cmd.qc | 38 +++++++++++++++++++++++++++------- qcsrc/menu/menu.qc | 4 ++++ 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index b2825bc82..35845da03 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -1467,10 +1467,26 @@ void Welcome_Message_Show_Try() string welcomedialog_args = strcat("HOSTNAME \"", hostname, "\""); string msg = MakeConsoleSafe(strreplace("\n", "\\n", welcome_msg)); welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\""); - localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n"); + if (intermission || isdemo() || !autocvar_cl_welcome) - // close it after it's been initialized so it can still be opened manually - localcmd("\ntogglemenu 0\n"); + { + if (cvar("_menu_cmd_closemenu_available")) + { + // initialize the dialog without opening it + localcmd("\nmenu_cmd closemenu Welcome ", welcomedialog_args, "\n"); + } + else + { + // legacy code for clients with old menus + // since togglemenu 0 doesn't close the dialog but only hides it, + // playing back a demo the Welcome dialog will pop up on the first ESC press + localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n"); + // close it after it's been initialized so it can still be opened manually + localcmd("\ntogglemenu 0\n"); + } + } + else + localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n"); } strfree(welcome_msg); diff --git a/qcsrc/menu/command/menu_cmd.qc b/qcsrc/menu/command/menu_cmd.qc index 2f97712b6..184f13952 100644 --- a/qcsrc/menu/command/menu_cmd.qc +++ b/qcsrc/menu/command/menu_cmd.qc @@ -3,6 +3,7 @@ #include "../menu.qh" #include "../item.qh" +#include #include #include @@ -50,6 +51,7 @@ void GameCommand(string theCommand) LOG_HELP("Usage:^3 menu_cmd [], where possible commands are:"); LOG_HELP(" 'sync' reloads all cvars on the current menu page"); LOG_HELP(" 'directmenu' shows the menu window named (or the menu window containing an item named )"); + LOG_HELP(" 'closemenu' closes the menu window named (or the menu window containing an item named )"); LOG_HELP(" if is not specified it shows the list of available items in the console"); LOG_HELP(" 'dumptree' dumps the state of the menu as a tree to the console"); @@ -73,14 +75,25 @@ void GameCommand(string theCommand) return; } - if (argv(0) == "directmenu" || argv(0) == "directpanelhudmenu") + string cmd = argv(0); + string filter = string_null; + bool close_mode = false; + if (cmd == "closemenu") { - string filter = string_null; - if (argv(0) == "directpanelhudmenu") filter = "HUD"; + close_mode = true; + cmd = "directmenu"; + } + else if (cmd == "directpanelhudmenu") + { + filter = "HUD"; + cmd = "directmenu"; + } + if (cmd == "directmenu") + { if (argc == 1) { - LOG_HELP("Available items:"); + LOG_HELP("Available items (* = closable):"); FOREACH_ENTITY_ORDERED(it.name != "", { if (it.classname == "vtbl") continue; @@ -90,10 +103,13 @@ void GameCommand(string theCommand) if (!startsWith(s, filter)) continue; s = substring(s, strlen(filter), strlen(s) - strlen(filter)); } - LOG_HELP(" ", s); + if (it.instanceOfContainer && it.closable) + LOG_HELP(" * ", s); + else + LOG_HELP(" ", s); }); } - else if (argc == 2 && (!isdemo() || argv(1) == "Welcome")) // don't allow this command in demos + else if (argc == 2 && !close_mode && (!isdemo() || argv(1) == "Welcome")) // don't allow this command in demos { m_play_click_sound(MENU_SOUND_OPEN); m_goto(strcat(filter, argv(1))); // switch to a menu item @@ -113,10 +129,18 @@ void GameCommand(string theCommand) for(i = 2; i < argc; ++i) bufstr_add(argsbuf, argv(i), 1); e.readInputArgs(e, argsbuf); - m_goto(strcat(filter, s)); + if (!close_mode) + m_goto(strcat(filter, s)); } if(argsbuf >= 0) buf_del(argsbuf); + + // NOTE input args are read even in close mode + if (close_mode) + { + if (e.instanceOfContainer && e.closable && e.focused) + Dialog_Close(e, e); + } } } return; diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc index 933136410..b2226b831 100644 --- a/qcsrc/menu/menu.qc +++ b/qcsrc/menu/menu.qc @@ -83,6 +83,9 @@ void m_init() } } + registercvar("_menu_cmd_closemenu_available", "0", 0); + cvar_set("_menu_cmd_closemenu_available", "1"); + // needs to be done so early because of the constants they create static_init(); static_init_late(); @@ -910,6 +913,7 @@ void Shutdown() if (it.classname == "vtbl") continue; it.destroy(it); }); + cvar_set("_menu_cmd_closemenu_available", "0"); } void m_focus_item_chain(entity outermost, entity innermost) -- 2.39.2