From 32d951e3128d9b8a8637ac817cce26a0aef16024 Mon Sep 17 00:00:00 2001 From: Asher Baker Date: Sun, 18 Jul 2021 20:57:13 +0100 Subject: [PATCH] Detect invalid menu item selections in L4D-based games (#1543) Some games have implemented CHudMenu::SelectMenuItem to close the menu even if an invalid slot has been selected, which causes us a problem as we'll never get any notification from the client and we'll keep the menu alive on our end indefinitely. For these games, pretend that every slot is valid for selection so we're guaranteed to get a menuselect command. We don't want to do this for every game as the common SelectMenuItem implementation ignores invalid selections and keeps the menu open, which is a much nicer user experience. Fixes #1385 --- core/MenuStyle_Radio.cpp | 19 +++++++++++++++++-- gamedata/core.games/common.games.txt | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/MenuStyle_Radio.cpp b/core/MenuStyle_Radio.cpp index 65e1960fb..9e556d778 100644 --- a/core/MenuStyle_Radio.cpp +++ b/core/MenuStyle_Radio.cpp @@ -61,7 +61,7 @@ unsigned int g_RadioMenuTimeout = 0; #define MAX_MENUSLOT_KEYS 10 static unsigned int s_RadioMaxPageItems = MAX_MENUSLOT_KEYS; - +static bool s_RadioClosesOnInvalidSlot = false; CRadioStyle::CRadioStyle() { @@ -124,6 +124,12 @@ void CRadioStyle::OnSourceModLevelChange(const char *mapName) } } + const char *closes = g_pGameConf->GetKeyValue("RadioMenuClosesOnInvalidSlot"); + if (closes != nullptr && strcmp(closes, "yes") == 0) + { + s_RadioClosesOnInvalidSlot = true; + } + g_Menus.SetDefaultStyle(this); g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false); @@ -464,7 +470,16 @@ void CRadioMenuPlayer::Radio_Init(int keys, const char *title, const char *text) sizeof(display_pkt), text); } - display_keys = keys; + + // Some games have implemented CHudMenu::SelectMenuItem to close the menu + // even if an invalid slot has been selected, which causes us a problem as + // we'll never get any notification from the client and we'll keep the menu + // alive on our end indefinitely. For these games, pretend that every slot + // is valid for selection so we're guaranteed to get a menuselect command. + // We don't want to do this for every game as the common SelectMenuItem + // implementation ignores invalid selections and keeps the menu open, which + // is a much nicer user experience. + display_keys = s_RadioClosesOnInvalidSlot ? 0x7ff : keys; } void CRadioMenuPlayer::Radio_Refresh() diff --git a/gamedata/core.games/common.games.txt b/gamedata/core.games/common.games.txt index 32f540af9..09bb54367 100644 --- a/gamedata/core.games/common.games.txt +++ b/gamedata/core.games/common.games.txt @@ -197,7 +197,7 @@ } } - "#default" + "#default" { "#supported" { @@ -366,4 +366,19 @@ "RadioMenuMaxPageItems" "6" } } + + "#default" + { + "#supported" + { + "engine" "left4dead" + "engine" "left4dead2" + "engine" "nucleardawn" + } + + "Keys" + { + "RadioMenuClosesOnInvalidSlot" "yes" + } + } }