From 5a44a34420bf730ac76f8e6dc4973523c38b8c9b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 1 Sep 2018 10:43:26 -0400 Subject: [PATCH] wizidentify suppress unnecessary prompt; allow individual items for perm ID Don't display the selection to identify all items if there are none. Complete an item marked ToDo in cmd.c: allow selection of one or more particular items to permanently identify rather than just all or nothing. --- doc/fixes36.2 | 3 ++ include/extern.h | 3 +- src/cmd.c | 1 - src/invent.c | 114 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 576701c53..803c0abd9 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -154,6 +154,9 @@ sortloot option has been enhanced to improve object ordering; primarily, within each class or sub-class of objects YAFM when stumbling on an undetected monster while hallucinating Make it clear when a leprechaun dodges your attack +wizard mode #wizidentify can now select individual items for permanent + identification and don't display the selection to permanently + identify everything if everything is already fully identified Code Cleanup and Reorganization diff --git a/include/extern.h b/include/extern.h index bd1924a6b..abd4be118 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1525012590 2018/04/29 14:36:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.629 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1535812936 2018/09/01 14:42:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.636 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -973,6 +973,7 @@ E int FDECL(askchain, (struct obj **, const char *, int, int (*)(OBJ_P), int (*)(OBJ_P), int, const char *)); E void FDECL(fully_identify_obj, (struct obj *)); E int FDECL(identify, (struct obj *)); +E int FDECL(count_unidentified, (struct obj *)); E void FDECL(identify_pack, (int, BOOLEAN_P)); E void NDECL(learn_unseen_invent); E void FDECL(prinv, (const char *, struct obj *, long)); diff --git a/src/cmd.c b/src/cmd.c index 3afa198b0..d73d0e60e 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -652,7 +652,6 @@ wiz_identify(VOID_ARGS) it doesn't matter whether the command has been remapped */ if (display_inventory((char *) 0, TRUE) == C('I')) identify_pack(0, FALSE); - /* [TODO? if player picks a specific inventory item, ID it] */ iflags.override_ID = 0; } else pline("Unavailable command '%s'.", diff --git a/src/invent.c b/src/invent.c index 6355a255a..ea7868e1d 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2279,6 +2279,19 @@ int id_limit; } } } +/* count the unidentified items */ +int +count_unidentified(objchn) +struct obj *objchn; +{ + int unid_cnt = 0; + struct obj *obj; + + for (obj = objchn; obj; obj = obj->nobj) + if (not_fully_identified(obj)) + ++unid_cnt; + return unid_cnt; +} /* dialog with user to identify a given number of items; 0 means all */ void @@ -2286,28 +2299,21 @@ identify_pack(id_limit, learning_id) int id_limit; boolean learning_id; /* true if we just read unknown identify scroll */ { - struct obj *obj, *the_obj; - int n, unid_cnt; - - unid_cnt = 0; - the_obj = 0; /* if unid_cnt ends up 1, this will be it */ - for (obj = invent; obj; obj = obj->nobj) - if (not_fully_identified(obj)) - ++unid_cnt, the_obj = obj; + struct obj *obj; + int n, unid_cnt = count_unidentified(invent); if (!unid_cnt) { You("have already identified all %sof your possessions.", learning_id ? "the rest " : ""); } else if (!id_limit || id_limit >= unid_cnt) { /* identify everything */ - if (unid_cnt == 1) { - (void) identify(the_obj); - } else { - /* TODO: use fully_identify_obj and cornline/menu/whatever here - */ - for (obj = invent; obj; obj = obj->nobj) - if (not_fully_identified(obj)) - (void) identify(obj); + /* TODO: use fully_identify_obj and cornline/menu/whatever here */ + for (obj = invent; obj; obj = obj->nobj) { + if (not_fully_identified(obj)) { + (void) identify(obj); + if (unid_cnt == 1) + break; + } } } else { /* identify up to `id_limit' items */ @@ -2491,7 +2497,7 @@ boolean want_reply; long *out_cnt; { static const char not_carrying_anything[] = "Not carrying anything"; - struct obj *otmp; + struct obj *otmp, wizid_fakeobj; char ilet, ret; char *invlet = flags.inv_order; int n, classcount; @@ -2500,6 +2506,7 @@ long *out_cnt; menu_item *selected; unsigned sortflags; Loot *sortedinvent, *srtinv; + boolean wizid = FALSE; if (lets && !*lets) lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */ @@ -2582,22 +2589,30 @@ long *out_cnt; start_menu(win); any = zeroany; if (wizard && iflags.override_ID) { + int unid_cnt; char prompt[QBUFSZ]; - /* C('I') == ^I == default keystroke for wiz_identify; - it is guaranteed not to be in use as an inventory letter - (wiz_identify might be remapped to an ordinary letter, - making iflags.override_ID ambiguous as a return value) */ - any.a_char = C('I'); - /* wiz_identify stuffed the wiz_identify command character (^I) - into iflags.override_ID for our use as an accelerator; - it could be ambiguous as a selector but the only time it - is wanted is in case where no item is being selected */ - Sprintf(prompt, "Debug Identify (%s to permanently identify)", - visctrl(iflags.override_ID)); - add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE, - prompt, MENU_UNSELECTED); - } else if (xtra_choice) { + unid_cnt = count_unidentified(invent); + if (!unid_cnt) { + add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, + "(all items are permanently identified already)", + MENU_UNSELECTED); + } else { + any.a_obj = &wizid_fakeobj; + /* wiz_identify stuffed the wiz_identify command character (^I) + into iflags.override_ID for our use as an accelerator; + it could be ambiguous as a selector but the only time it + is wanted is in case where no item is being selected */ + Sprintf(prompt, + "Select any to identify permanently (%s for %s %d bolded item%s)", + visctrl(iflags.override_ID), + (unid_cnt == 1) ? "the" : "all", unid_cnt, + (unid_cnt > 1) ? "s" : ""); + add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE, + prompt, MENU_UNSELECTED); + wizid = TRUE; + } + } else if (xtra_choice) { /* wizard override ID and xtra_choice are mutually exclusive */ if (flags.sortpack) add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, @@ -2621,8 +2636,13 @@ nextclass: MENU_UNSELECTED); classcount++; } - any.a_char = ilet; - add_menu(win, obj_to_glyph(otmp), &any, ilet, 0, ATR_NONE, + if (wizid) + any.a_obj = otmp; + else + any.a_char = ilet; + add_menu(win, obj_to_glyph(otmp), &any, ilet, 0, + (wizid && not_fully_identified(otmp)) ? + ATR_BOLD : ATR_NONE, doname(otmp), MENU_UNSELECTED); } } @@ -2655,11 +2675,31 @@ nextclass: } end_menu(win, query && *query ? query : (char *) 0); - n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected); + n = select_menu(win, wizid ? PICK_ANY : + want_reply ? PICK_ONE : PICK_NONE, &selected); if (n > 0) { - ret = selected[0].item.a_char; - if (out_cnt) - *out_cnt = selected[0].count; + if (wizid) { + int i = n; + + ret = '\0'; + while (--i >= 0) { + otmp = selected[i].item.a_obj; + if (otmp == &wizid_fakeobj) { + /* C('I') == ^I == default keystroke for wiz_identify; + it is guaranteed not to be in use as an inventory letter + (wiz_identify might be remapped to an ordinary letter, + making iflags.override_ID ambiguous as a return value) */ + ret = C('I'); + } else { + if (not_fully_identified(otmp)) + (void) identify(otmp); + } + } + } else { + ret = selected[0].item.a_char; + if (out_cnt) + *out_cnt = selected[0].count; + } free((genericptr_t) selected); } else ret = !n ? '\0' : '\033'; /* cancelled */