From d4fda38474ee0922296c94ad1ed893fef8bc8548 Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Thu, 1 Jan 2026 09:54:31 -0500 Subject: [PATCH 1/2] Fix warning of unbound keys for newer controls Under some circumstances, FSO will warn the player if a key is unbound if that they need to press to complete a training event. This logic though only works for keys with XSTRs from 507-619. Any control that was added with a different XSTR will not be picked up correctly, and thus the message displayed to the player will be incorrect, confusing, and not helpful. To fix this `missiontraining.cpp` around line 757 needs to account for the newer controls as well. This PR adds those needed checks, and this fixes the issue. This fix is especially needed for mods that use training missions with newer controls such as FotG. Note, we do ship with a full default controls table with all the needed keys bound, but we have found players will be players and simply change all their controls before even starting the training missions. Thus they unbind key training controls, and with this bug they are unable to correct their controls. With this fix they are properly able to update their controls as needed to complete the training missions. Fixes #7172. --- code/mission/missiontraining.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/code/mission/missiontraining.cpp b/code/mission/missiontraining.cpp index b4ba3a6e6f4..400aa47928e 100644 --- a/code/mission/missiontraining.cpp +++ b/code/mission/missiontraining.cpp @@ -754,10 +754,17 @@ SCP_string message_translate_tokens(const char *text) if (!stricmp(ptr, NOX("none")) && (Training_bind_warning != Missiontime)) { // check if a warning message should be displayed if the key is unbound if ( (The_mission.game_type & MISSION_TYPE_TRAINING) || (Always_warn_player_about_unbound_keys && (The_mission.game_type & MISSION_TYPE_SINGLE)) ) { + int index_to_use; + if (Control_config[Failed_key_index].indexXSTR > 1) { + index_to_use = Control_config[Failed_key_index].indexXSTR; + } else if (Control_config[Failed_key_index].indexXSTR == 1) { + index_to_use = CONTROL_CONFIG_XSTR + Failed_key_index; + } else { + index_to_use = -1; + } r = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, XSTR( "&Bind Control", 424), XSTR( "&Abort mission", 425), XSTR( "Warning\nYou have no control bound to the action \"%s\". You must do so before you can continue with your training.", 426), - XSTR(Control_config[Failed_key_index].text.c_str(), CONTROL_CONFIG_XSTR + Failed_key_index)); - + XSTR(Control_config[Failed_key_index].text.c_str(), index_to_use)); if (r) { // do they want to abort the mission? gameseq_post_event(GS_EVENT_END_GAME); return buf; From e0637ce5610a333ca54f77933ed24580a7f8681c Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Sat, 3 Jan 2026 16:33:53 -0500 Subject: [PATCH 2/2] var name update --- code/mission/missiontraining.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/mission/missiontraining.cpp b/code/mission/missiontraining.cpp index 400aa47928e..4f2b58d792c 100644 --- a/code/mission/missiontraining.cpp +++ b/code/mission/missiontraining.cpp @@ -754,17 +754,17 @@ SCP_string message_translate_tokens(const char *text) if (!stricmp(ptr, NOX("none")) && (Training_bind_warning != Missiontime)) { // check if a warning message should be displayed if the key is unbound if ( (The_mission.game_type & MISSION_TYPE_TRAINING) || (Always_warn_player_about_unbound_keys && (The_mission.game_type & MISSION_TYPE_SINGLE)) ) { - int index_to_use; + int xstr_index; if (Control_config[Failed_key_index].indexXSTR > 1) { - index_to_use = Control_config[Failed_key_index].indexXSTR; + xstr_index = Control_config[Failed_key_index].indexXSTR; } else if (Control_config[Failed_key_index].indexXSTR == 1) { - index_to_use = CONTROL_CONFIG_XSTR + Failed_key_index; + xstr_index = CONTROL_CONFIG_XSTR + Failed_key_index; } else { - index_to_use = -1; + xstr_index = -1; } r = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, XSTR( "&Bind Control", 424), XSTR( "&Abort mission", 425), XSTR( "Warning\nYou have no control bound to the action \"%s\". You must do so before you can continue with your training.", 426), - XSTR(Control_config[Failed_key_index].text.c_str(), index_to_use)); + XSTR(Control_config[Failed_key_index].text.c_str(), xstr_index)); if (r) { // do they want to abort the mission? gameseq_post_event(GS_EVENT_END_GAME); return buf;