diff --git a/dat/opthelp b/dat/opthelp index 29bf01e11..d9a89a9d2 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -120,11 +120,13 @@ packorder a list of default symbols for kinds of objects that gives the default order will be appended to the end.) paranoid_confirmation space separated list of situations where alternate prompting is desired [paranoid_confirmation:pray] - quit -- yes vs y to confirm quitting or to enter explore mode - die -- yes vs y to confirm dying (for explore or debug mode) - attack -- yes vs y to confirm attacking a peaceful monster - pray -- y to confirm an attempt to pray; on by default - Remove -- always pick from inventory for 'R' and 'T' even when + Confirm -- when requiring yes, also require no to reject + quit -- yes vs y to confirm quitting or to enter explore mode + die -- yes vs y to confirm dying (for explore or debug mode) + bones -- yes vs y to confirm saving bones data in debug mode + attack -- yes vs y to confirm attacking a peaceful monster + pray -- y to confirm an attempt to pray; on by default + Remove -- always pick from inventory for 'R' and 'T' even when wearing just one applicable item to remove or take off pickup_burden when you pick up an item that exceeds this encumberance level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 04278232a..c2764c954 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2121,16 +2121,21 @@ A space separated list of specific situations where alternate prompting is desired. The default is paranoid_confirmation:pray. .sd .si -quit - require "yes" rather than 'y' to confirm quitting - the game or switching into non-scoring explore mode; -die - require "yes" rather than 'y' to confirm dying (not - useful in normal play; applies to explore mode); -attack - require "yes" rather than 'y' to confirm attacking - a peaceful monster; -pray - require 'y' to confirm an attempt to pray rather - than immediately praying; on by default; -Remove - require selection from inventory for 'R' and 'T' - commands even when wearing just one applicable item. +Confirm - for any prompts which are set to require "yes" + rather than 'y', also require "no" to reject instead + of accepting any non-yes response as no +quit - require "yes" rather than 'y' to confirm quitting + the game or switching into non-scoring explore mode; +die - require "yes" rather than 'y' to confirm dying (not + useful in normal play; applies to explore mode); +bones - require "yes" rather than 'y' to confirm saving + bones data when dying in debug mode; +attack - require "yes" rather than 'y' to confirm attacking + a peaceful monster; +pray - require 'y' to confirm an attempt to pray rather + than immediately praying; on by default; +Remove - require selection from inventory for 'R' and 'T' + commands even when wearing just one applicable item. .ei .ed By default, the pray choice is enabled, the others disabled. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index ecb3e3e0d..6b235f2e8 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -33,7 +33,7 @@ \begin{document} % % input file: guidebook.mn -% $Revision: 1.114 $ $Date: 2011/04/23 20:27:05 $ +% $Revision: 1.115 $ $Date: 2011/04/24 21:12:06 $ % %.ds h0 " %.ds h1 %.ds h2 \% @@ -2603,22 +2603,29 @@ prompting is desired. The default is ``{\it paranoid\_confirmation:pray}''. %.sd %.si \newlength{\pcwidth} -\settowidth{\pcwidth}{\tt Remove} +\settowidth{\pcwidth}{\tt Confirm} \addtolength{\pcwidth}{\labelsep} \blist{\leftmargin \pcwidth \topsep 1mm \itemsep 0mm} -\item[{\tt quit~~}] +\item[{\tt Confirm}] +for any prompts which are set to require ``yes'' +rather than `y', also require ``no'' to reject instead +of accepting any non-yes response as no; +\item[{\tt quit~~~}] require ``{\tt yes}'' rather than `{\tt y}' to confirm quitting the game or switching into non-scoring explore mode; -\item[{\tt die~~~}] +\item[{\tt die~~~~}] require ``{\tt yes}'' rather than `{\tt y}' to confirm dying (not useful in normal play; applies to explore mode); -\item[{\tt attack}] +\item[{\tt bones~~}] +require ``{\tt yes}'' rather than `{\tt y}' to confirm saving +bones data when dying in debug mode +\item[{\tt attack~}] require ``{\tt yes}'' rather than `{\tt y}' to confirm attacking a peaceful monster; -\item[{\tt pray~~}] +\item[{\tt pray~~~}] require `{\tt y}' to confirm an attempt to pray rather than immediately praying; on by default; -\item[{\tt Remove}] require selection from inventory for `{\tt R}' and `{\tt T}' +\item[{\tt Remove~}] require selection from inventory for `{\tt R}' and `{\tt T}' commands even when wearing just one applicable item. \elist %.ei diff --git a/doc/fixes35.0 b/doc/fixes35.0 index c91ce80d9..a7b12e7cc 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -494,11 +494,14 @@ mimic posing as door might steal hero's key when [un]locking is attempted polymorphing into a dragon while wearing dragon scale mail will cause that mail to revert to dragon scales adopt/adapt/improve the Paranoid_Quit patch; default is paranoid_confirm:pray - paranoid_confirm:quit yes vs y to quit or to enter explore mode - paranoid_confirm:die yes vs y to die in explore or wizard mode - paranoid_confirm:attack yes vs y to attack a peaceful monster - paranoid_confirm:pray y to confirm #pray; supersedes prayconfirm - paranoid_confirm:Remove always pick from inventory for 'R' and 'T' + paranoid_confirm:Confirm when requiring "yes" instead of y to confirm, + also require explicit "no" to reject + paranoid_confirm:quit yes vs y to quit or to enter explore mode + paranoid_confirm:die yes vs y to die in explore or wizard mode + paranoid_confirm:bones yes vs y to save bones when dying in wizard mode + paranoid_confirm:attack yes vs y to attack a peaceful monster + paranoid_confirm:pray y to confirm #pray; supersedes prayconfirm + paranoid_confirm:Remove always pick from inventory for 'R' and 'T' Platform- and/or Interface-Specific New Features diff --git a/include/flag.h b/include/flag.h index 9f01c81d5..29af0ae1a 100644 --- a/include/flag.h +++ b/include/flag.h @@ -58,11 +58,13 @@ struct flag { #define NEW_MOON 0 #define FULL_MOON 4 int paranoia_bits; /* alternate confirmation prompting */ -#define PARANOID_QUIT 0x01 -#define PARANOID_DIE 0x02 -#define PARANOID_HIT 0x04 -#define PARANOID_PRAY 0x08 -#define PARANOID_REMOVE 0x10 +#define PARANOID_CONFIRM 0x01 +#define PARANOID_QUIT 0x02 +#define PARANOID_DIE 0x04 +#define PARANOID_BONES 0x08 +#define PARANOID_HIT 0x10 +#define PARANOID_PRAY 0x20 +#define PARANOID_REMOVE 0x40 int pickup_burden; /* maximum burden before prompt */ int pile_limit; /* controls feedback when walking over objects */ char inv_order[MAXOCLASSES]; @@ -345,10 +347,14 @@ extern NEARDATA struct instance_flags iflags; #define RUN_CRAWL 3 /* walk w/ extra delay after each update */ /* paranoid confirmation prompting */ +/* any yes confirmations also require explicit no (or ESC) to reject */ +#define ParanoidConfirm ((flags.paranoia_bits & PARANOID_CONFIRM) != 0) /* quit: yes vs y for "Really quit?" and "Enter explore mode?" */ #define ParanoidQuit ((flags.paranoia_bits & PARANOID_QUIT) != 0) /* die: yes vs y for "Die?" (dying in explore mode or wizard mode) */ #define ParanoidDie ((flags.paranoia_bits & PARANOID_DIE) != 0) +/* hit: yes vs y for "Save bones?" in wizard mode */ +#define ParanoidBones ((flags.paranoia_bits & PARANOID_BONES) != 0) /* hit: yes vs y for "Really attack ?" */ #define ParanoidHit ((flags.paranoia_bits & PARANOID_HIT) != 0) /* pray: ask "Really pray?" (accepts y answer, doesn't require yes), diff --git a/include/patchlevel.h b/include/patchlevel.h index 42c534229..9d2c149fb 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -13,7 +13,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 45 +#define EDITLEVEL 46 #define COPYRIGHT_BANNER_A \ "NetHack, Copyright 1985-2011" diff --git a/src/cmd.c b/src/cmd.c index 136822451..72190c1f4 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3651,15 +3651,27 @@ boolean be_paranoid; const char *prompt; { char qbuf[QBUFSZ], ans[BUFSZ]; + const char *responsetype, *promptprefix = ""; boolean confirmed_ok; /* when paranoid, player must respond with "yes" rather than just 'y' - to give the go-ahead for this query; default is "no", obviously */ + to give the go-ahead for this query; default is "no" unless the + ParanoidConfirm flag is set in which case there's no default */ if (be_paranoid) { - Sprintf(qbuf, "%s (yes) [no]", prompt); - getlin(qbuf, ans); - (void) mungspaces(ans); - confirmed_ok = !strcmpi(ans, "yes"); + /* in addition to being paranoid about this particular + query, we might be even more paranoid about all paranoia + responses (ie, ParanoidConfirm is set) in which case we + require "no" to reject in addition to "yes" to confirm + (except we won't loop if respose is ESC; it means no) */ + responsetype = ParanoidConfirm ? "(yes|no)" : "(yes) [no]"; + do { + Sprintf(qbuf, "%s%s %s", promptprefix, prompt, responsetype); + getlin(qbuf, ans); + (void) mungspaces(ans); + confirmed_ok = !strcmpi(ans, "yes"); + if (confirmed_ok || *ans == '\033') break; + promptprefix = "\"Yes\" or \"No\": "; + } while (ParanoidConfirm && strcmpi(ans, "no")); } else confirmed_ok = (yn(prompt) == 'y'); diff --git a/src/end.c b/src/end.c index 6ff9fabcd..d2ce1d17d 100644 --- a/src/end.c +++ b/src/end.c @@ -1031,7 +1031,7 @@ die: if (bones_ok) { #ifdef WIZARD - if (!wizard || yn("Save bones?") == 'y') + if (!wizard || paranoid_query(ParanoidBones, "Save bones?")) #endif savebones(corpse); /* corpse may be invalid pointer now so diff --git a/src/options.c b/src/options.c index b212a5360..e36f91ca7 100644 --- a/src/options.c +++ b/src/options.c @@ -1082,22 +1082,32 @@ STATIC_VAR const struct paranoia_opts { int synMinLen; const char *explain; /* for interactive menu */ } paranoia[] = { - /* there are two initial-letter conflicts: "a"ttack vs "a"ll, "attack" - takes precedence and "all" isn't present in the interactive menu; - and "d"ie vs "d"eath, synonyms for each other so doesn't matter */ - { PARANOID_QUIT, "quit", 1, "explore", 1, + /* there are some initial-letter conflicts: "a"ttack vs "a"ll, "attack" + takes precedence and "all" isn't present in the interactive menu, + and "d"ie vs "d"eath, synonyms for each other so doesn't matter; + (also "p"ray vs "P"aranoia, "pray" takes precedence since "Paranoia" + is just a synonym for "Confirm") */ + { PARANOID_CONFIRM, "Confirm", 1, "Paranoia", 2, + "for \"yes\" confirmations, require \"no\" to reject" }, + { PARANOID_QUIT, "quit", 1, "explore", 1, "yes vs y to quit or to enter explore mode" }, - { PARANOID_DIE, "die", 1, "death", 2, + { PARANOID_DIE, "die", 1, "death", 2, #ifdef WIZARD "yes vs y to die (explore mode or debug mode)" }, #else "yes vs y to die (explore mode only)" }, #endif - { PARANOID_HIT, "attack", 1, "hit", 1, + { PARANOID_BONES, "bones", 1, 0, 0, +#ifdef WIZARD + "yes vs y to save bones data when dying in debug mode" }, +#else + "(only applicable for debug mode)" }, +#endif + { PARANOID_HIT, "attack", 1, "hit", 1, "yes vs y to attack a peaceful monster" }, - { PARANOID_PRAY, "pray", 1, 0, 0, + { PARANOID_PRAY, "pray", 1, 0, 0, "y to pray (supersedes old \"prayconfirm\" option)" }, - { PARANOID_REMOVE, "Remove", 1, "Takeoff", 1, + { PARANOID_REMOVE, "Remove", 1, "Takeoff", 1, "always pick from inventory for Remove and Takeoff" }, /* for config file parsing; interactive menu skips these */ { 0, "none", 4, 0, 0, 0 }, /* require full word match */ @@ -3031,6 +3041,7 @@ boolean setinitial,setfromfile; start_menu(tmpwin); any = zeroany; for (i = 0; paranoia[i].flagmask != 0; ++i) { + if (paranoia[i].flagmask == PARANOID_BONES && !wizard) continue; any.a_int = paranoia[i].flagmask; add_menu(tmpwin, NO_GLYPH, &any, *paranoia[i].argname, 0, ATR_NONE, paranoia[i].explain, @@ -3748,11 +3759,13 @@ char *buf; char tmpbuf[QBUFSZ]; tmpbuf[0] = '\0'; - if (ParanoidQuit) Strcat(tmpbuf, " quit"); - if (ParanoidDie) Strcat(tmpbuf, " die"); - if (ParanoidHit) Strcat(tmpbuf, " attack"); - if (ParanoidPray) Strcat(tmpbuf, " pray"); - if (ParanoidRemove) Strcat(tmpbuf, " Remove"); + if (ParanoidConfirm) Strcat(tmpbuf, " Confirm"); + if (ParanoidQuit) Strcat(tmpbuf, " quit"); + if (ParanoidDie) Strcat(tmpbuf, " die"); + if (ParanoidBones) Strcat(tmpbuf, " bones"); + if (ParanoidHit) Strcat(tmpbuf, " attack"); + if (ParanoidPray) Strcat(tmpbuf, " pray"); + if (ParanoidRemove) Strcat(tmpbuf, " Remove"); Strcpy(buf, tmpbuf[0] ? &tmpbuf[1] : "none"); } else if (!strcmp(optname, "pettype")) Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat" :