This patch adds a new option "ynconfirm". You can toggle confirmations for saving, quitting, praying, looting, key usage, untrapping and wand breaking. Eg. Putting YNCONFIRM=-plus into .nethackrc turns off confirmations for praying, looting, untrapping and saving. You can also change the values in the game Options. s saving q quitting p praying l looting k key usage u untrapping w breaking a wand Note: When you have key usage confirmation off, applying a key opens only the first container in a pile. Bugs: -First version of this patch had a bug that prevented opening any containers when key usage confirmation was off. Pasi Kallinen pkalli@cs.joensuu.fi diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/include/decl.h nethack-3.4.1-ynconfirm/include/decl.h --- nethack-3.4.1-orig/include/decl.h 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/include/decl.h 2003-08-20 14:20:44.000000000 +0300 @@ -284,6 +284,22 @@ /* The names of the colors used for gems, etc. */ E const char *c_obj_colors[]; +/* confirmations */ +#define CONFIRM_SAVE 0x01 +#define CONFIRM_QUIT 0x02 +#define CONFIRM_PRAY 0x04 +#define CONFIRM_LOOT 0x08 +#define CONFIRM_KEYUSE 0x10 +#define CONFIRM_UNTRAP 0x20 +#define CONFIRM_BREAKWAND 0x40 +#define CONFIRM_ALL 0xff + +E const struct _ynconfirmdat { + char match; + int flag; + const char *name; +} ynconfirmdat[]; + E struct c_common_strings { const char *const c_nothing_happens, *const c_thats_enough_tries, *const c_silly_thing_to, *const c_shudder_for_moment, diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/include/extern.h nethack-3.4.1-ynconfirm/include/extern.h --- nethack-3.4.1-orig/include/extern.h 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/include/extern.h 2003-08-20 14:20:44.000000000 +0300 @@ -612,6 +612,9 @@ E int FDECL(open_levelfile, (int,char *)); E void FDECL(delete_levelfile, (int)); E void NDECL(clearlocks); +E void NDECL(set_unconfirmmenu); +E void FDECL(set_ynconfirmstr, (char *)); +E char *NDECL(get_ynconfirmstr); E int FDECL(create_bonesfile, (d_level*,char **, char *)); #ifdef MFLOPPY E void NDECL(cancel_bonesfile); diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/include/flag.h nethack-3.4.1-ynconfirm/include/flag.h --- nethack-3.4.1-orig/include/flag.h 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/include/flag.h 2003-08-20 14:20:44.000000000 +0300 @@ -262,6 +262,7 @@ boolean showrace; /* show hero glyph by race rather than by role */ boolean travelcmd; /* allow travel command */ int runmode; /* update screen display during run moves */ + int ynconfirm; /* confirm yn-prompts; CONFIRM_foo */ }; /* diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/apply.c nethack-3.4.1-ynconfirm/src/apply.c --- nethack-3.4.1-orig/src/apply.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/apply.c 2003-08-20 14:20:44.000000000 +0300 @@ -2545,8 +2545,10 @@ char confirm[QBUFSZ], the_wand[BUFSZ], buf[BUFSZ]; Strcpy(the_wand, yname(obj)); - Sprintf(confirm, "Are you really sure you want to break %s?", the_wand); - if (yn(confirm) == 'n' ) return 0; + if (iflags.ynconfirm & CONFIRM_BREAKWAND) { + Sprintf(confirm, "Are you really sure you want to break %s?", the_wand); + if (yn(confirm) == 'n' ) return 0; + } if (nohands(youmonst.data)) { You_cant("break %s without hands!", the_wand); diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/decl.c nethack-3.4.1-ynconfirm/src/decl.c --- nethack-3.4.1-orig/src/decl.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/decl.c 2003-08-20 14:20:44.000000000 +0300 @@ -235,6 +235,17 @@ "white", /* CLR_WHITE */ }; +const struct _ynconfirmdat ynconfirmdat[] = { + { 's', CONFIRM_SAVE, "saving" }, + { 'q', CONFIRM_QUIT, "quitting" }, + { 'p', CONFIRM_PRAY, "praying" }, + { 'l', CONFIRM_LOOT, "looting" }, + { 'k', CONFIRM_KEYUSE, "key usage" }, + { 'u', CONFIRM_UNTRAP, "untrapping" }, + { 'w', CONFIRM_BREAKWAND, "breaking a wand" }, + { 0, 0, 0 } +}; + struct c_common_strings c_common_strings = { "Nothing happens.", "That's enough tries!", "That is a silly thing to %s.", "shudder for a moment.", diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/end.c nethack-3.4.1-ynconfirm/src/end.c --- nethack-3.4.1-orig/src/end.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/end.c 2003-08-20 14:20:44.000000000 +0300 @@ -112,7 +112,7 @@ int done2() { - if(yn("Really quit?") == 'n') { + if((iflags.ynconfirm & CONFIRM_QUIT) && yn("Really quit?") == 'n') { #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done1); #endif diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/files.c nethack-3.4.1-ynconfirm/src/files.c --- nethack-3.4.1-orig/src/files.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/files.c 2003-08-20 14:20:44.000000000 +0300 @@ -1606,6 +1606,85 @@ /*NOTREACHED*/ } +void +set_ynconfirmmenu() +{ + winid win; + anything any; + menu_item *pick_list; + int i, n; + + any.a_void = 0; + win = create_nhwindow(NHW_MENU); + start_menu(win); + + for (i = 0; ynconfirmdat[i].name; i++) { + any.a_int = i+1; + add_menu(win, NO_GLYPH, &any, ynconfirmdat[i].match, + 0, ATR_NONE, ynconfirmdat[i].name, + (iflags.ynconfirm & ynconfirmdat[i].flag) ? MENU_SELECTED : MENU_UNSELECTED); + } + end_menu(win, "Confirm which actions with yes/no prompts?"); + n = select_menu(win, PICK_ANY, &pick_list); + destroy_nhwindow(win); + if (n >= 0) { + iflags.ynconfirm = 0; + for (i = 0; i < n; i++) + iflags.ynconfirm |= ynconfirmdat[pick_list[i].item.a_int-1].flag; + } + + if (iflags.ynconfirm & CONFIRM_PRAY) + flags.prayconfirm = TRUE; + + free((genericptr_t) pick_list); +} + +void +set_ynconfirmstr(bufp) +char *bufp; +{ + int i; + boolean clr = TRUE; + + if (!bufp) return; + + while (*bufp) { + if (*bufp == '+') clr = TRUE; + else if (*bufp == '-') clr = FALSE; + else for (i = 0; ynconfirmdat[i].name; i++) + if (strchr(bufp, ynconfirmdat[i].match)) { + if (clr) + iflags.ynconfirm |= ynconfirmdat[i].flag; + else + iflags.ynconfirm &= (CONFIRM_ALL - ynconfirmdat[i].flag); + } + bufp++; + } + + if (iflags.ynconfirm & CONFIRM_PRAY) + flags.prayconfirm = TRUE; +} + +char * +get_ynconfirmstr() +{ + int i, z = 0; + char ch; + static char buf[BUFSZ]; + + for (i = 0; ynconfirmdat[i].name; i++) { + if (iflags.ynconfirm & ynconfirmdat[i].flag) + ch = '+'; + else ch ='-'; + buf[z++] = ch; + buf[z++] = ynconfirmdat[i].match; + if (ynconfirmdat[i+1].name) buf[z++] = ' '; + } + buf[z] = '\0'; + + return buf; +} + #ifdef NOCWD_ASSUMPTIONS STATIC_OVL void adjust_prefix(bufp, prefixid) @@ -1746,6 +1825,8 @@ } else if (match_varname(buf, "BOULDER", 3)) { (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, 1, "BOULDER"); + } else if (match_varname(buf, "YNCONFIRM", 3)) { + set_ynconfirmstr(bufp); } else if (match_varname(buf, "GRAPHICS", 4)) { len = get_uchars(fp, buf, bufp, translate, FALSE, MAXPCHARS, "GRAPHICS"); diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/lock.c nethack-3.4.1-ynconfirm/src/lock.c --- nethack-3.4.1-orig/src/lock.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/lock.c 2003-08-20 14:57:20.000000000 +0300 @@ -306,12 +306,14 @@ else if (!otmp->olocked) verb = "lock", it = 1; else if (picktyp != LOCK_PICK) verb = "unlock", it = 1; else verb = "pick"; - Sprintf(qbuf, "There is %s here, %s %s?", - doname(otmp), verb, it ? "it" : "its lock"); + if (iflags.ynconfirm & CONFIRM_KEYUSE) { + Sprintf(qbuf, "There is %s here, %s %s?", + doname(otmp), verb, it ? "it" : "its lock"); - c = ynq(qbuf); - if(c == 'q') return(0); - if(c == 'n') continue; + c = ynq(qbuf); + if(c == 'q') return(0); + if(c == 'n') continue; + } else c = 'y'; if (otmp->obroken) { You_cant("fix its broken lock with %s.", doname(pick)); @@ -393,12 +395,13 @@ return(0); } #endif + if (iflags.ynconfirm & CONFIRM_KEYUSE) { + Sprintf(qbuf,"%sock it?", + (door->doormask & D_LOCKED) ? "Unl" : "L" ); - Sprintf(qbuf,"%sock it?", - (door->doormask & D_LOCKED) ? "Unl" : "L" ); - - c = yn(qbuf); - if(c == 'n') return(0); + c = yn(qbuf); + if(c == 'n') return(0); + } switch(picktyp) { #ifdef TOURIST diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/options.c nethack-3.4.1-ynconfirm/src/options.c --- nethack-3.4.1-orig/src/options.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/options.c 2003-08-20 14:20:44.000000000 +0300 @@ -320,6 +320,7 @@ { "windowcolors", "the foreground/background colors of windows", /*WC*/ 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, + { "ynconfirm", "the yes/no questions to confirm", 40, SET_IN_GAME }, { (char *)0, (char *)0, 0, 0 } }; @@ -509,6 +510,7 @@ iflags.bouldersym = 0; flags.warnlevel = 1; flags.warntype = 0L; + iflags.ynconfirm = CONFIRM_ALL; /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */ (void)memcpy((genericptr_t)flags.inv_order, @@ -2417,7 +2419,10 @@ /* Special handling of menustyle, pickup_burden, and pickup_types, disclose, runmode, and msg_window options. */ - if (!strcmp("menustyle", optname)) { + if (!strcmp("ynconfirm", optname)) { + set_ynconfirmmenu(); + retval = TRUE; + } else if (!strcmp("menustyle", optname)) { const char *style_name; menu_item *style_pick = (menu_item *)0; tmpwin = create_nhwindow(NHW_MENU); @@ -2635,6 +2640,8 @@ defopt); else if (!strcmp(optname,"align")) Sprintf(buf, "%s", rolestring(flags.initalign, aligns, adj)); + else if (!strcmp(optname, "ynconfirm")) + Sprintf(buf, "%s", get_ynconfirmstr()); else if (!strcmp(optname, "boulder")) Sprintf(buf, "%c", iflags.bouldersym ? iflags.bouldersym : oc_syms[(int)objects[BOULDER].oc_class]); diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/pickup.c nethack-3.4.1-ynconfirm/src/pickup.c --- nethack-3.4.1-orig/src/pickup.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/pickup.c 2003-08-20 14:20:44.000000000 +0300 @@ -1445,10 +1445,12 @@ nobj = cobj->nexthere; if (Is_container(cobj)) { - Sprintf(qbuf, "There is %s here, loot it?", doname(cobj)); - c = ynq(qbuf); - if (c == 'q') return (timepassed); - if (c == 'n') continue; + if (iflags.ynconfirm & CONFIRM_LOOT) { + Sprintf(qbuf, "There is %s here, loot it?", doname(cobj)); + c = ynq(qbuf); + if (c == 'q') return (timepassed); + if (c == 'n') continue; + } any = TRUE; if (cobj->olocked) { diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/pray.c nethack-3.4.1-ynconfirm/src/pray.c --- nethack-3.4.1-orig/src/pray.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/pray.c 2003-08-20 14:20:44.000000000 +0300 @@ -1527,7 +1527,7 @@ dopray() { /* Confirm accidental slips of Alt-P */ - if (flags.prayconfirm) + if (flags.prayconfirm || (iflags.ynconfirm & CONFIRM_PRAY)) if (yn("Are you sure you want to pray?") == 'n') return 0; diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/save.c nethack-3.4.1-ynconfirm/src/save.c --- nethack-3.4.1-orig/src/save.c 2003-06-15 13:13:55.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/save.c 2003-08-20 14:20:44.000000000 +0300 @@ -55,7 +55,7 @@ dosave() { clear_nhwindow(WIN_MESSAGE); - if(yn("Really save?") == 'n') { + if((iflags.ynconfirm & CONFIRM_SAVE) && yn("Really save?") == 'n') { clear_nhwindow(WIN_MESSAGE); if(multi > 0) nomul(0); } else { diff -Nurd --exclude-from=diff_ignore_files.txt nethack-3.4.1-orig/src/trap.c nethack-3.4.1-ynconfirm/src/trap.c --- nethack-3.4.1-orig/src/trap.c 2003-06-15 13:13:56.000000000 +0300 +++ nethack-3.4.1-ynconfirm/src/trap.c 2003-08-20 14:20:44.000000000 +0300 @@ -3320,10 +3320,12 @@ if(!u.dx && !u.dy) { for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) if(Is_box(otmp)) { - Sprintf(qbuf, "There is %s here. Check it for traps?", doname(otmp)); - switch (ynq(qbuf)) { - case 'q': return(0); - case 'n': continue; + if (iflags.ynconfirm & CONFIRM_UNTRAP) { + Sprintf(qbuf, "There is %s here. Check it for traps?", doname(otmp)); + switch (ynq(qbuf)) { + case 'q': return(0); + case 'n': continue; + } } if((otmp->otrapped && (force || (!confused @@ -3332,9 +3334,11 @@ You("find a trap on %s!", the(xname(otmp))); exercise(A_WIS, TRUE); - switch (ynq("Disarm it?")) { - case 'q': return(1); - case 'n': trap_skipped = TRUE; continue; + if (iflags.ynconfirm & CONFIRM_UNTRAP) { + switch (ynq("Disarm it?")) { + case 'q': return(1); + case 'n': trap_skipped = TRUE; continue; + } } if(otmp->otrapped) { @@ -3397,7 +3401,7 @@ || (!force && confused && !rn2(3))) { You("find a trap on the door!"); exercise(A_WIS, TRUE); - if (ynq("Disarm it?") != 'y') return(1); + if ((iflags.ynconfirm & CONFIRM_UNTRAP) && ynq("Disarm it?") != 'y') return(1); if (levl[x][y].doormask & D_TRAPPED) { ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel*3 : u.ulevel); exercise(A_DEX, TRUE);