Skip to content

Commit 68075df

Browse files
committed
consistent handling of text token replacement
Just as special tokens are replaced in debriefings, replace them in command briefings and briefings as well. Change `string_replace_tokens_with_keys` to `message_translate_tokens` (since it's the same thing) and add a `replaceContainers` script API function to complement `replaceVariables` and `replaceTokens`. Also replace every category of token in `sexp_modify_variable` and add comments to places where token replacement might be expected but happens elsewhere.
1 parent f78ac49 commit 68075df

9 files changed

Lines changed: 65 additions & 21 deletions

File tree

code/camera/camera.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
732732
text_buf = in_text;
733733
sexp_replace_variable_names_with_values(text_buf);
734734
sexp_container_replace_refs_with_values(text_buf);
735+
// (message_translate_tokens is called when the subtitle is queued, so does not need to be called here)
735736
in_text = text_buf.c_str();
736737
}
737738

code/mission/missiontraining.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,8 @@ char *translate_message_token(char *str)
720720
return NULL;
721721
}
722722

723-
void string_replace_tokens_with_keys(SCP_string& text) {
723+
void message_translate_tokens(SCP_string &text)
724+
{
724725
text = message_translate_tokens(text.c_str());
725726
}
726727

code/mission/missiontraining.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void training_mission_shutdown();
4141
void training_check_objectives();
4242
void message_training_queue(const char *text, TIMESTAMP timestamp, int length = -1);
4343
SCP_string message_translate_tokens(const char *text);
44-
void string_replace_tokens_with_keys(SCP_string& text);
44+
void message_translate_tokens(SCP_string &text);
4545
void training_fail();
4646
void message_training_update_frame();
4747

code/missionui/missionbrief.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "mission/missioncampaign.h"
3434
#include "mission/missiongoals.h"
3535
#include "mission/missionmessage.h"
36+
#include "mission/missiontraining.h"
3637
#include "missionui/chatbox.h"
3738
#include "missionui/missionbrief.h"
3839
#include "missionui/missionscreencommon.h"
@@ -311,6 +312,7 @@ int Brief_max_line_width[GR_NUM_RESOLUTIONS] = {
311312
int brief_setup_closeup(brief_icon *bi, bool api_access = false);
312313
void brief_maybe_blit_scene_cut(float frametime);
313314
void brief_transition_reset();
315+
void brief_replace_stage_text(brief_stage &stage);
314316

315317
const char *brief_tooltip_handler(const char *str)
316318
{
@@ -800,10 +802,7 @@ void brief_compact_stages()
800802
num = 0;
801803
while ( num < Briefing->num_stages ) {
802804
if ( eval_sexp(Briefing->stages[num].formula) ) {
803-
// Goober5000 - replace any variables (probably persistent variables) with their values
804-
sexp_replace_variable_names_with_values(Briefing->stages[num].text);
805-
// karajorma/jg18 - replace container references as well
806-
sexp_container_replace_refs_with_values(Briefing->stages[num].text);
805+
brief_replace_stage_text(Briefing->stages[num]);
807806
} else {
808807
// clean up unused briefing stage
809808
Briefing->stages[num].text = "";
@@ -2232,3 +2231,13 @@ int brief_only_allow_briefing()
22322231

22332232
return 0;
22342233
}
2234+
2235+
// Goober5000 - replace any variables (probably persistent variables) with their values
2236+
// karajorma/jg18 - replace container references as well
2237+
// Goober5000 - replace keybinds also
2238+
void brief_replace_stage_text(brief_stage &stage)
2239+
{
2240+
sexp_replace_variable_names_with_values(stage.text);
2241+
sexp_container_replace_refs_with_values(stage.text);
2242+
message_translate_tokens(stage.text);
2243+
}

code/missionui/missioncmdbrief.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "io/timer.h"
2222
#include "mission/missionparse.h"
2323
#include "mission/missionbriefcommon.h"
24+
#include "mission/missiontraining.h"
2425
#include "missionui/missioncmdbrief.h"
2526
#include "missionui/missionscreencommon.h"
2627
#include "missionui/missionshipchoice.h"
@@ -191,6 +192,11 @@ static int Uses_scroll_buttons = 0;
191192

192193
int Cmd_brief_overlay_id;
193194

195+
// --------------------------------------------------------------------------------------
196+
// Forward declarations
197+
// --------------------------------------------------------------------------------------
198+
void cmd_brief_replace_stage_text(cmd_brief_stage &stage);
199+
194200
void cmd_brief_init_voice()
195201
{
196202
int i;
@@ -562,16 +568,13 @@ void cmd_brief_init(int team)
562568
Cmd_brief_inited = 0;
563569
Cur_cmd_brief = &Cmd_briefs[team];
564570

565-
// Goober5000 - replace any variables (probably persistent variables) with their values
566-
// karajorma/jg18 - replace container references as well
567-
for (i = 0; i < Cur_cmd_brief->num_stages; i++) {
568-
sexp_replace_variable_names_with_values(Cur_cmd_brief->stage[i].text);
569-
sexp_container_replace_refs_with_values(Cur_cmd_brief->stage[i].text);
570-
}
571-
572571
if (Cur_cmd_brief->num_stages <= 0)
573572
return;
574573

574+
for (i = 0; i < Cur_cmd_brief->num_stages; i++) {
575+
cmd_brief_replace_stage_text(Cur_cmd_brief->stage[i]);
576+
}
577+
575578
// for multiplayer, change the state in my netplayer structure
576579
if (Game_mode & GM_MULTIPLAYER) {
577580
Net_player->state = NETPLAYER_STATE_CMD_BRIEFING;
@@ -779,3 +782,13 @@ int mission_has_cmd_brief()
779782
{
780783
return (Cur_cmd_brief != NULL && Cur_cmd_brief->num_stages > 0);
781784
}
785+
786+
// Goober5000 - replace any variables (probably persistent variables) with their values
787+
// karajorma/jg18 - replace container references as well
788+
// Goober5000 - replace keybinds also
789+
void cmd_brief_replace_stage_text(cmd_brief_stage &stage)
790+
{
791+
sexp_replace_variable_names_with_values(stage.text);
792+
sexp_container_replace_refs_with_values(stage.text);
793+
message_translate_tokens(stage.text);
794+
}

code/missionui/missiondebrief.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,7 +2606,6 @@ void debrief_replace_stage_text(debrief_stage &stage)
26062606
sexp_replace_variable_names_with_values(stage.recommendation_text);
26072607
sexp_container_replace_refs_with_values(stage.text);
26082608
sexp_container_replace_refs_with_values(stage.recommendation_text);
2609-
2610-
stage.text = message_translate_tokens(stage.text.c_str());
2611-
stage.recommendation_text = message_translate_tokens(stage.recommendation_text.c_str());
2609+
message_translate_tokens(stage.text);
2610+
message_translate_tokens(stage.recommendation_text);
26122611
}

code/parse/sexp.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13415,9 +13415,9 @@ void sexp_hud_set_xstr(int n)
1341513415
lcl_ext_localize(xstr, translated_string);
1341613416

1341713417
// Now replace tokens and variables
13418-
string_replace_tokens_with_keys(translated_string);
1341913418
sexp_replace_variable_names_with_values(translated_string);
1342013419
sexp_container_replace_refs_with_values(translated_string);
13420+
message_translate_tokens(translated_string);
1342113421

1342213422
HudGauge* cg = hud_get_custom_gauge(gaugename);
1342313423
if (cg) {
@@ -13437,9 +13437,9 @@ void sexp_hud_set_message(int n)
1343713437
if ( !stricmp(text, Messages[i].name) ) {
1343813438
message = Messages[i].message;
1343913439

13440-
string_replace_tokens_with_keys(message);
1344113440
sexp_replace_variable_names_with_values(message);
1344213441
sexp_container_replace_refs_with_values(message);
13442+
message_translate_tokens(message);
1344313443

1344413444
HudGauge* cg = hud_get_custom_gauge(gaugename);
1344513445
if (cg) {
@@ -35520,11 +35520,13 @@ void sexp_modify_variable(const char *text, int index, bool sexp_callback)
3552035520
Assert( !MULTIPLAYER_CLIENT );
3552135521
const size_t maxCopyLen = TOKEN_LENGTH - 1;
3552235522

35523-
if (strchr(text, '$') != nullptr)
35523+
if (strchr(text, '$') != nullptr || strchr(text, sexp_container::DELIM) != nullptr)
3552435524
{
35525-
// we want to use the same variable substitution that's in messages etc.
35525+
// we want to use the same text substitution that's in messages etc.
3552635526
SCP_string temp_text = text;
3552735527
sexp_replace_variable_names_with_values(temp_text);
35528+
sexp_container_replace_refs_with_values(temp_text);
35529+
message_translate_tokens(temp_text);
3552835530

3552935531
if (temp_text.length() > maxCopyLen)
3553035532
Warning(LOCATION, "String too long. Only " SIZE_T_ARG " characters will be assigned to %s.\n\nOriginal string:\n%s", maxCopyLen, Sexp_variables[index].variable_name, temp_text.c_str());

code/scripting/api/libs/base.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,24 @@ ADE_FUNC(replaceVariables,
584584
return ade_set_args(L, "s", translated_str.c_str());
585585
}
586586

587+
ADE_FUNC(replaceContainers,
588+
l_Base,
589+
"string text",
590+
"Returns a string that replaces any container reference with the container value (same as text in Briefings, Debriefings, or Messages). Container ref must be preceded by '&' for replacement to work.",
591+
"string",
592+
"Updated string or nil if invalid")
593+
{
594+
const char* untranslated_str;
595+
if (!ade_get_args(L, "s", &untranslated_str)) {
596+
return ADE_RETURN_NIL;
597+
}
598+
599+
SCP_string translated_str = untranslated_str;
600+
sexp_container_replace_refs_with_values(translated_str);
601+
602+
return ade_set_args(L, "s", translated_str.c_str());
603+
}
604+
587605
ADE_FUNC(inMissionEditor, l_Base, nullptr, "Determine if the current script is running in the mission editor (e.g. FRED2). This should be used to control which code paths will be executed even if running in the editor.", "boolean", "true when we are in the mission editor, false otherwise") {
588606
return ade_set_args(L, "b", Fred_running != 0);
589607
}

code/scripting/api/objs/message.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ ADE_VIRTVAR(Persona, l_Message, "persona", "The persona of the message", "person
191191
return ade_set_args(L, "o", l_Persona.Set(Messages[idx].persona_index));
192192
}
193193

194-
ADE_FUNC(getMessage, l_Message, "[boolean replaceVars = true]", "Gets the text of the message and optionally replaces SEXP variables with their respective values.", "string", "The message or an empty string if handle is invalid")
194+
ADE_FUNC(getMessage, l_Message, "[boolean replaceStuff = true]", "Gets the text of the message and optionally replaces SEXP variable and container references with their respective values.", "string", "The message or an empty string if handle is invalid")
195195
{
196196
int idx = -1;
197197
bool replace = true;
@@ -210,6 +210,7 @@ ADE_FUNC(getMessage, l_Message, "[boolean replaceVars = true]", "Gets the text o
210210

211211
sexp_replace_variable_names_with_values(temp_buf, MESSAGE_LENGTH - 1);
212212
sexp_container_replace_refs_with_values(temp_buf, MESSAGE_LENGTH - 1);
213+
// (message_translate_tokens is called in message_queue_process)
213214

214215
return ade_set_args(L, "s", temp_buf);
215216
}

0 commit comments

Comments
 (0)