From 8fcc15a860a15e3418cff1f98e80a31c287991cc Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 5 May 2026 11:02:55 -0400 Subject: [PATCH] mention_decor and tutorial K4372 Bug report stated: "If 'mention_decor' is set in config file or NETHACKOPTIONS, starting the game tells you that you are standing on stairs which lead out of the dungeon. But if you also start the tutorial, you won't be on those stairs--they won't even exist until the tutorial is exited. The stairs message can't be suppressed until the program knows whether the tutorial will be entered, and since prompting is one of the ways to decide that." What this does: Don't heed mention_decor option during the primary rcfile() processing. Do heed it after the tutorial. Note: If mention_decor is expected to actually be active during the tutorial, then the rcfile_only_this_option(opt_mention_decor) likely has to be moved to a different line, which should be easy enough. --- include/extern.h | 1 + src/allmain.c | 6 ++++++ src/cfgfiles.c | 16 ++++++++++++++++ src/end.c | 5 ++++- src/options.c | 7 +++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/extern.h b/include/extern.h index ec5173c12..accecff22 100644 --- a/include/extern.h +++ b/include/extern.h @@ -339,6 +339,7 @@ extern char *get_configfile(void); extern const char *get_default_configfile(void); extern void rcfile(void); extern void rcfile_interface_options(void); +extern void rcfile_only_this_option(enum opt); extern void heed_all_config_statements(void); extern void disregard_all_config_statements(void); extern void heed_this_config_statement(int); diff --git a/src/allmain.c b/src/allmain.c index 280beb39a..f7ee742ad 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -580,6 +580,9 @@ maybe_do_tutorial(void) vision_recalc(0); docrt(); iflags.nofollowers = FALSE; + } else { + /* no tutorial, so okay to process mention_decor now */ + rcfile_only_this_option(opt_mention_decor); } } @@ -591,6 +594,9 @@ moveloop(boolean resuming) if (!resuming) maybe_do_tutorial(); + /* process one deferred option post-tutorial */ + rcfile_only_this_option(opt_mention_decor); + for (;;) { moveloop_core(); } diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 4e169886b..e2ef65937 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -1975,6 +1975,22 @@ rcfile_interface_options(void) ignore_statement_errors = FALSE; } +void +rcfile_only_this_option(enum opt heeded_option) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(heeded_option); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + void heed_all_config_statements(void) { diff --git a/src/end.c b/src/end.c index 2573cace1..8a366d434 100644 --- a/src/end.c +++ b/src/end.c @@ -110,9 +110,12 @@ done2(void) u.usleep = 0; } - if (abandon_tutorial) + if (abandon_tutorial) { + /* mention_decor can be processed now */ + rcfile_only_this_option(opt_mention_decor); schedule_goto(&u.ucamefrom, UTOTYPE_ATSTAIRS, "Resuming regular play.", (char *) 0); + } return ECMD_OK; } diff --git a/src/options.c b/src/options.c index 05f4979ef..f5d24b1b1 100644 --- a/src/options.c +++ b/src/options.c @@ -7324,6 +7324,7 @@ void initoptions_finish(void) { nhsym sym = 0; + disregard_this_option(opt_mention_decor); /* defer this */ rcfile(); (void) fruitadd(svp.pl_fruit, (struct fruit *) 0); @@ -10184,6 +10185,9 @@ heed_all_options(void) { int i; + /* ensure OPTIONS= lines are enabled */ + heed_this_config_statement(0); /* index 0 == OPTIONS */ + for (i = 0; i < OPTCOUNT; i++) allopt[i].disregarded = FALSE; } @@ -10200,6 +10204,9 @@ disregard_all_options(void) void heed_this_option(enum opt optidx) { + /* ensure OPTIONS= lines are enabled */ + heed_this_config_statement(0); /* index 0 == OPTIONS */ + if (optidx >= 0 && optidx < (enum opt) OPTCOUNT) allopt[optidx].disregarded = FALSE; }