From 51f486589c2ed9a980ae6f28dfe9ef4698f564d6 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 21 May 2026 09:10:31 +0300 Subject: [PATCH] Add sysconf MAX_REROLLS option Public servers probably want to set this. --- doc/fixes5-0-1.txt | 1 + include/sys.h | 1 + src/cfgfiles.c | 15 +++++++++++++++ src/invent.c | 27 +++++++++++++++++++++++---- src/sys.c | 1 + sys/unix/sysconf | 4 ++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index daa4ae615..1aa287b92 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -138,6 +138,7 @@ tty: allow custom glyph colors if they're basic 16 nethack colors General New Features -------------------- +sysconf option MAX_REROLLS to limit number of rerolls Platform- and/or Interface-Specific New Features diff --git a/include/sys.h b/include/sys.h index 2ea704cdb..6ad569dce 100644 --- a/include/sys.h +++ b/include/sys.h @@ -25,6 +25,7 @@ struct sysopt_s { * -1: getenv() didn't find a value for DEBUGFILES. */ int maxplayers; + int maxrerolls; int seduce; int check_save_uid; /* restoring savefile checks UID? */ int check_plname; /* use plname for checking wizards/explorers/shellers */ diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 4e410c880..6e870169e 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -74,6 +74,7 @@ staticfn boolean cnf_line_CHECK_PLNAME(char *); staticfn boolean cnf_line_SEDUCE(char *); staticfn boolean cnf_line_HIDEUSAGE(char *); staticfn boolean cnf_line_MAXPLAYERS(char *); +staticfn boolean cnf_line_MAX_REROLLS(char *); staticfn boolean cnf_line_PERSMAX(char *); staticfn boolean cnf_line_PERS_IS_UID(char *); staticfn boolean cnf_line_ENTRYMAX(char *); @@ -968,6 +969,19 @@ cnf_line_MAXPLAYERS(char *bufp) return TRUE; } +staticfn boolean +cnf_line_MAX_REROLLS(char *bufp) +{ + int n = atoi(bufp); + + if (n < 0 || n > 255) { + config_error_add("Illegal value in MAX_REROLLS (maximum is 255)"); + n = 10; + } + sysopt.maxrerolls = n; + return TRUE; +} + staticfn boolean cnf_line_PERSMAX(char *bufp) { @@ -1349,6 +1363,7 @@ static const struct match_config_line_stmt { CNFL_S(SEDUCE, 6), CNFL_S(HIDEUSAGE, 9), CNFL_S(MAXPLAYERS, 10), + CNFL_S(MAX_REROLLS, 10), CNFL_S(PERSMAX, 7), CNFL_S(PERS_IS_UID, 11), CNFL_S(ENTRYMAX, 8), diff --git a/src/invent.c b/src/invent.c index 078c3c5d5..228eacd12 100644 --- a/src/invent.c +++ b/src/invent.c @@ -26,6 +26,7 @@ staticfn int ckvalidcat(struct obj *); staticfn int ckunpaid(struct obj *); staticfn char *safeq_xprname(struct obj *); staticfn char *safeq_shortxprname(struct obj *); +staticfn boolean hit_reroll_limit(int); staticfn char display_pickinv(const char *, const char *, const char *, boolean, boolean, long *); staticfn char display_used_invlets(char); @@ -2540,6 +2541,15 @@ askchain( return cnt; } +staticfn boolean +hit_reroll_limit(int curr) +{ +#ifdef SYSCF + if (sysopt.maxrerolls && curr >= (sysopt.maxrerolls-1)) + return TRUE; +#endif /*SYSCF*/ + return FALSE; +} /* The menu for rerolling attributes and inventory. @@ -2569,9 +2579,17 @@ reroll_menu(void) ATR_NONE, NO_COLOR, "start the game with this character", MENU_ITEMFLAGS_NONE); any.a_char = 'y'; + Strcat(buf, "reroll another character"); +#ifdef SYSCF + if (sysopt.maxrerolls > 0) { + char *bp = eos(buf); + + Sprintf(bp, " (%li/%i)", + u.uroleplay.numrerolls+1, sysopt.maxrerolls); + } +#endif /*SYSCF*/ add_menu(win, &nul_glyphinfo, &any, flags.lootabc ? 0 : 'r', 0, - ATR_NONE, NO_COLOR, "reroll another character", - MENU_ITEMFLAGS_NONE); + ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); any.a_char = 0; add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, "", MENU_ITEMFLAGS_NONE); @@ -2600,7 +2618,7 @@ reroll_menu(void) if (select_menu(win, PICK_ONE, &pick_list) > 0) { option = pick_list[0].item.a_char; free((genericptr_t) pick_list); - } else { + } else if (!hit_reroll_limit(u.uroleplay.numrerolls)) { /* user closed the menu without selecting; unclear what their choice is here so ask again; but (e.g. for hangup handling) stop asking if the user cancels out again */ @@ -2610,7 +2628,8 @@ reroll_menu(void) if (option == 'y') { ++u.uroleplay.numrerolls; - return TRUE; + if (!hit_reroll_limit(u.uroleplay.numrerolls)) + return TRUE; } return FALSE; } diff --git a/src/sys.c b/src/sys.c index 758a93667..a5a0e87e0 100644 --- a/src/sys.c +++ b/src/sys.c @@ -59,6 +59,7 @@ sys_early_init(void) sysopt.genericusers = (char *) 0; sysopt.msghandler = (char *) 0; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ + sysopt.maxrerolls = 0; sysopt.bones_pools = 0; sysopt.livelog = LL_NONE; diff --git a/sys/unix/sysconf b/sys/unix/sysconf index e960bd522..a8b136410 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -55,6 +55,10 @@ GENERICUSERS=play player game games nethack nethacker ec2-user # letter and "lock" (eg. alock, block, ...) MAXPLAYERS=10 +# Limit the number of rerolls +# Default is 0 (meaning infinite), valid values are 0-255 +MAX_REROLLS=0 + # If not null, added to string "To get local support, " in the support # information help. #SUPPORT=call Izchak at extension 42.