diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 94944bd90..d0dc6f856 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ General Fixes and Modified Features ----------------------------------- @@ -507,7 +507,7 @@ new monsters: displacer beast ('f') and genetic engineer ('Q') make camera flash which reveals previously unseen map features or objects or monsters record those on the hero's map; monsters revert to 'unseen' boolean options can optionally have the form "name:value" with value taken - from among "true", "yes", "on", or "false", "no", "off" + from among "true", "yes", "on", or 1 and "false", "no", "off", or 0 record number of wishes and artifact wishes in xlogfile give feedback for '#chat' directed at walls add 'Sokoban' conduct, tracking the number of times the special Sokoban rules diff --git a/src/options.c b/src/options.c index 236e04ff5..07a38f97c 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1597357458 2020/08/13 22:24:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.470 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.471 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4445,6 +4445,8 @@ char *op; return optn_ok; } if (req == do_set) { + boolean nosexchange = FALSE; + if (!allopt[optidx].addr) return optn_ok; /* silent retreat */ @@ -4460,18 +4462,23 @@ char *op; config_error_add( "Negated boolean '%s' should not have a parameter", allopt[optidx].name); - return optn_err; + return optn_silenterr; } + /* length is greater than 0 or we wouldn't have gotten here */ ln = (int) strlen(op); - if (!strncmpi(op, "true", max(ln, 3)) - || !strcmpi(op, "yes") || !strcmpi(op, "on")) { + if (!strncmpi(op, "true", ln) + || !strncmpi(op, "yes", ln) + || !strcmpi(op, "on") + || (digit(*op) && atoi(op) == 1)) { negated = FALSE; - } else if (!strncmpi(op, "false", max(ln, 3)) - || !strcmpi(op, "no") || !strcmpi(op, "off")) { + } else if (!strncmpi(op, "false", ln) + || !strncmpi(op, "no", ln) + || !strcmpi(op, "off") + || (digit(*op) && atoi(op) == 0)) { negated = TRUE; } else if (!allopt[optidx].valok) { - config_error_add("Illegal parameter for a boolean"); - return optn_err; + config_error_add("'%s' is not valid for a boolean", opts); + return optn_silenterr; } } if (iflags.debug_fuzzer && !g.opt_initial) { @@ -4484,8 +4491,7 @@ char *op; case opt_female: if (!strncmpi(opts, "female", 3)) { if (!g.opt_initial && flags.female == negated) { - config_error_add("That is not anatomically possible."); - return optn_err; + nosexchange = TRUE; } else { flags.initgend = flags.female = !negated; return optn_ok; @@ -4493,8 +4499,7 @@ char *op; } if (!strncmpi(opts, "male", 3)) { if (!g.opt_initial && flags.female != negated) { - config_error_add("That is not anatomically possible."); - return optn_err; + nosexchange = TRUE; } else { flags.initgend = flags.female = negated; return optn_ok; @@ -4502,6 +4507,19 @@ char *op; } break; } + /* this dates from when 'O' prompted for a line of options text + rather than use a menu to control access to which options can + be modified during play; it was possible to attempt to use + 'O' to specify female or negate male when playing as male or + to specify male or negate female when playing as female; + options processing rejects that for !opt_initial; not possible + now but kept in case someone brings the old 'O' behavior back */ + if (nosexchange) { + /* can't arbitrarily change sex after game has started; + magic (amulet or polymorph) is required for that */ + config_error_add("'%s' is not anatomically possible.", opts); + return optn_silenterr; + } *(allopt[optidx].addr) = !negated; /* <==== SET IT HERE */