From 16e81690e31550506a811662977e25aeb1a9dea9 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 15 Sep 2011 04:16:29 +0000 Subject: [PATCH] new command '`' to show discoveries for one class (trunk only) Use the grave accent (back tick) character as the keystroke for a new command which prompts for an object class and then shows a subset of the discovered objects list covering just the selected class. Similar to the 'I' variant of 'i' for viewing inventory, and mainly useful once the '\' discoveries list has grown long. --- dat/cmdhelp | 1 + dat/help | 1 + dat/hh | 1 + doc/Guidebook.mn | 4 +- doc/Guidebook.tex | 9 ++- doc/fixes35.0 | 1 + include/extern.h | 1 + src/artifact.c | 2 + src/cmd.c | 2 + src/invent.c | 3 +- src/o_init.c | 179 +++++++++++++++++++++++++++++++++++++++++++++- 11 files changed, 195 insertions(+), 9 deletions(-) diff --git a/dat/cmdhelp b/dat/cmdhelp index b47beb84c..811c9bdda 100644 --- a/dat/cmdhelp +++ b/dat/cmdhelp @@ -82,6 +82,7 @@ Z Zap (cast) a spell & Tell what a command does ! Do a shell escape (only if defined) \ Show what object types have been discovered +` Show discovered types for one class of objects _ Travel via a shortest-path algorithm to a point on the map . Rest one move while doing nothing Rest one move while doing nothing (if rest_on_space option is on) diff --git a/dat/help b/dat/help index 28f681440..7f9ee92ab 100644 --- a/dat/help +++ b/dat/help @@ -166,6 +166,7 @@ Commands: $ Count your gold pieces. + List the spells you know; also rearrange them if desired. \ Show what types of objects have been discovered. + ` Show discovered types for one class of objects. ! Escape to a shell, if supported in your version and OS. # Introduces one of the "extended" commands. To get a list of the commands you can use with "#" type "#?". The extended diff --git a/dat/hh b/dat/hh index 75a11f0b2..1887547c7 100644 --- a/dat/hh +++ b/dat/hh @@ -79,6 +79,7 @@ Z Zap cast a spell (use Y instead of Z if number_pad is -1) * ask for combination of ),[,=,",( all at once $ gold count your gold + spells list the spells you know; also rearrange them if desired +` classkn display known items for one class of objects _ travel move via a shortest-path algorithm to a point on the map . rest wait a moment , pickup pick up all you can carry diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 6a654a2fd..218ad1865 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -5,7 +5,7 @@ .ds vr "NetHack 3.5 .ds f0 "\*(vr .ds f1 -.ds f2 "April 17, 2011 +.ds f2 "September 14, 2011 .\" labeled paragraph start (should be part of tmac.n, but I don't want to .\" make changes to that file) .\" .PS word @@ -767,6 +767,8 @@ be added to the end of the list rather than be inserted into the sorted ordering.) .lp "\e Show what types of objects have been discovered. +.lp ` +Show discovered types for one class of objects. .lp ! Escape to a shell. .lp # diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 6b235f2e8..93fe2794b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -33,7 +33,7 @@ \begin{document} % % input file: guidebook.mn -% $Revision: 1.115 $ $Date: 2011/04/24 21:12:06 $ +% $Revision: 1.116 $ $Date: 2011/04/25 03:29:41 $ % %.ds h0 " %.ds h1 %.ds h2 \% @@ -46,7 +46,7 @@ %.au \author{Eric S. Raymond\\ (Extensively edited and expanded for 3.5)} -\date{April 17, 2011} +\date{September 14, 2011} \maketitle @@ -491,7 +491,7 @@ An amulet or a spider web. \item[\tb{*}] A gem or rock (possibly valuable, possibly worthless). %.lp -\item[\tb{`}] +\item[\tb{\`}] A boulder or statue. %.lp \item[\tb{0}] @@ -957,6 +957,9 @@ ordering.) \item[\tb{$\backslash$}] Show what types of objects have been discovered. %.lp +\item[\tb{\`}] +Show discovered types for one class of objects. +%.lp \item[\tb{!}] Escape to a shell. %.lp diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 771d4d470..f55f7780b 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -522,6 +522,7 @@ adopt/adapt/improve the Paranoid_Quit patch; default is paranoid_confirm:pray flexibility for specifying "detect " vs " detection" when wishing when a sokoban puzzle has been completed (last pit or hole filled in), stop assessing luck penalties and lift most movement restrictions +'`' command to show discoveries for one class of objects Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index d029c70d6..c7fd206e8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1538,6 +1538,7 @@ E void FDECL(restnames, (int)); E void FDECL(discover_object, (int,BOOLEAN_P,BOOLEAN_P)); E void FDECL(undiscover_object, (int)); E int NDECL(dodiscovered); +E int NDECL(doclassdisco); E void NDECL(rename_disco); /* ### objects.c ### */ diff --git a/src/artifact.c b/src/artifact.c index 6f3a7aa27..fdfe1de2e 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -835,6 +835,8 @@ winid tmpwin; /* supplied by dodiscover() */ for (i = 0; i < NROFARTIFACTS; i++) { if (artidisco[i] == 0) break; /* empty slot implies end of list */ + if (tmpwin == WIN_ERR) continue; /* for WIN_ERR, we just count */ + if (i == 0) putstr(tmpwin, iflags.menu_headings, "Artifacts"); m = artidisco[i]; otyp = artilist[m].otyp; diff --git a/src/cmd.c b/src/cmd.c index c1ffd7be6..079b184fe 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -78,6 +78,7 @@ extern int NDECL(doopen); /**/ extern int NDECL(doclose); /**/ extern int NDECL(dosh); /**/ extern int NDECL(dodiscovered); /**/ +extern int NDECL(doclassdisco); /**/ extern int NDECL(doset); /**/ extern int NDECL(dotogglepickup); /**/ extern int NDECL(dowhatis); /**/ @@ -2261,6 +2262,7 @@ static const struct func_tab cmdlist[] = { {';', TRUE, doquickwhatis}, {'^', TRUE, doidtrap}, {'\\', TRUE, dodiscovered}, /* Robert Viduya */ + {'`', TRUE, doclassdisco}, {'@', TRUE, dotogglepickup}, {M('2'), FALSE, dotwoweapon}, {WEAPON_SYM, TRUE, doprwep}, diff --git a/src/invent.c b/src/invent.c index cc5f4e180..9d2ca7dbd 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,5 +1,4 @@ /* NetHack 3.5 invent.c $Date$ $Revision$ */ -/* SCCS Id: @(#)invent.c 3.5 2008/10/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2859,7 +2858,7 @@ long numused; STATIC_VAR NEARDATA const char *names[] = { 0, "Illegal objects", "Weapons", "Armor", "Rings", "Amulets", "Tools", "Comestibles", "Potions", "Scrolls", "Spellbooks", - "Wands", "Coins", "Gems", "Boulders/Statues", "Iron balls", + "Wands", "Coins", "Gems/Stones", "Boulders/Statues", "Iron balls", "Chains", "Venoms" }; diff --git a/src/o_init.c b/src/o_init.c index ad13cf073..d078707db 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,5 +1,4 @@ /* NetHack 3.5 o_init.c $Date$ $Revision$ */ -/* SCCS Id: @(#)o_init.c 3.5 2007/05/21 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -10,7 +9,7 @@ STATIC_DCL void FDECL(setgemprobs, (d_level*)); STATIC_DCL void FDECL(shuffle,(int,int,BOOLEAN_P)); STATIC_DCL void NDECL(shuffle_all); STATIC_DCL boolean FDECL(interesting_to_discover,(int)); - +STATIC_DCL char *FDECL(oclass_to_name, (CHAR_P,char *)); static NEARDATA short disco[NUM_OBJECTS] = DUMMY; @@ -404,6 +403,7 @@ static short uniq_objs[] = { BELL_OF_OPENING, }; +/* the '\' command - show discovered object types */ int dodiscovered() /* free after Robert Viduya */ { @@ -421,7 +421,7 @@ dodiscovered() /* free after Robert Viduya */ for (i = dis = 0; i < SIZE(uniq_objs); i++) if (objects[uniq_objs[i]].oc_name_known) { if (!dis++) - putstr(tmpwin, iflags.menu_headings, "Unique Items"); + putstr(tmpwin, iflags.menu_headings, "Unique items"); Sprintf(buf, " %s", OBJ_NAME(objects[uniq_objs[i]])); putstr(tmpwin, 0, buf); ++ct; @@ -463,6 +463,179 @@ dodiscovered() /* free after Robert Viduya */ return 0; } +/* lower case let_to_name() output, which differs from def_oc_syms[].name */ +STATIC_OVL char * +oclass_to_name(oclass, buf) +char oclass; +char *buf; +{ + char *s; + + Strcpy(buf, let_to_name(oclass, FALSE)); + for (s = buf; *s; ++s) *s = lowc(*s); + return buf; +} + +/* the '`' command - show discovered object types for one class */ +int +doclassdisco() +{ + static NEARDATA const char + prompt[] = "View discoveries for which sort of objects?", + havent_discovered_any[] = "haven't discovered any %s yet.", + unique_items[] = "unique items", artifact_items[] = "artifacts"; + char *s, c, oclass, menulet, + allclasses[MAXOCLASSES], discosyms[2+MAXOCLASSES+1], buf[BUFSZ]; + int i, ct, dis, xtras; + boolean traditional; + winid tmpwin; + anything any; + menu_item *pick_list = 0; + + discosyms[0] = '\0'; + traditional = (flags.menu_style == MENU_TRADITIONAL || + flags.menu_style == MENU_COMBINATION); + tmpwin = !traditional ? create_nhwindow(NHW_MENU) : WIN_ERR; + any = zeroany; + menulet = 'a'; + + /* check whether we've discovered any unique objects */ + for (i = 0; i < SIZE(uniq_objs); i++) + if (objects[uniq_objs[i]].oc_name_known) { + Strcat(discosyms, "u"); + if (!traditional) { + any.a_int = 'u'; + add_menu(tmpwin, NO_GLYPH, &any, menulet++, 0, ATR_NONE, + unique_items, MENU_UNSELECTED); + } + break; + } + + /* check whether we've discovered any artifacts */ + if (disp_artifact_discoveries(WIN_ERR) > 0) { + Strcat(discosyms, "a"); + if (!traditional) { + any.a_int = 'a'; + add_menu(tmpwin, NO_GLYPH, &any, menulet++, 0, ATR_NONE, + artifact_items, MENU_UNSELECTED); + } + } + + /* collect classes with discoveries, in packorder ordering; several + classes are omitted from packorder and one is of interest here */ + Strcpy(allclasses, flags.inv_order); + if (!index(allclasses, VENOM_CLASS)) + Sprintf(eos(allclasses), "%c", VENOM_CLASS); + /* construct discosyms[] */ + for (s = allclasses; *s; ++s) { + oclass = *s; + c = def_oc_syms[oclass].sym; + for (i = bases[(int)oclass]; + i < NUM_OBJECTS && objects[i].oc_class == oclass; ++i) + if ((dis = disco[i]) != 0 && interesting_to_discover(dis)) { + if (!index(discosyms, c)) { + Sprintf(eos(discosyms), "%c", c); + if (!traditional) { + any.a_int = c; + add_menu(tmpwin, NO_GLYPH, &any, + menulet++, c, ATR_NONE, + oclass_to_name(oclass, buf), MENU_UNSELECTED); + } + } + } + } + + /* there might not be anything for us to do... */ + if (!discosyms[0]) { + You(havent_discovered_any, "items"); + if (tmpwin != WIN_ERR) destroy_nhwindow(tmpwin); + return 0; + } + + /* have player choose a class */ + c = '\0'; /* class not chosen yet */ + if (traditional) { + /* we'll prompt even if there's only one viable class; we add all + nonviable classes as unseen acceptable choices so player can ask + for discoveries of any class whether it has discoveries or not */ + for (s = allclasses, xtras = 0; *s; ++s) { + c = def_oc_syms[*s].sym; + if (!index(discosyms, c)) { + if (!xtras++) Sprintf(eos(discosyms), "%c", '\033'); + Sprintf(eos(discosyms), "%c", c); + } + } + /* get the class (via its symbol character) */ + c = yn_function(prompt, discosyms, '\0'); +#ifdef REDO + savech(c); +#endif + if (!c) + clear_nhwindow(WIN_MESSAGE); + } else { + /* menustyle:full or menustyle:partial */ + if (!discosyms[1] && flags.menu_style == MENU_PARTIAL) { + /* only one class; menustyle:partial normally jumps past class + filtering straight to final menu so skip class filter here */ + c = discosyms[0]; + } else { + /* more than one choice, or menustyle:full which normally has + an intermediate class selection menu before the final menu */ + end_menu(tmpwin, prompt); + i = select_menu(tmpwin, PICK_ONE, &pick_list); + if (i > 0) { + c = pick_list[0].item.a_int; + free((genericptr_t) pick_list); + } /* else c stays 0 */ + } + destroy_nhwindow(tmpwin); + } + if (!c) return 0; /* player declined to make a selection */ + + /* + * show discoveries for object class c + */ + tmpwin = create_nhwindow(NHW_MENU); + ct = 0; + switch (c) { + case 'u': + putstr(tmpwin, iflags.menu_headings, + upstart(strcpy(buf, unique_items))); + for (i = 0; i < SIZE(uniq_objs); i++) + if (objects[uniq_objs[i]].oc_name_known) { + Sprintf(buf, " %s", OBJ_NAME(objects[uniq_objs[i]])); + putstr(tmpwin, 0, buf); + ++ct; + } + if (!ct) You(havent_discovered_any, unique_items); + break; + case 'a': + /* disp_artifact_discoveries() includes a header */ + ct = disp_artifact_discoveries(tmpwin); + if (!ct) You(havent_discovered_any, artifact_items); + break; + default: + oclass = def_char_to_objclass(c); + Sprintf(buf, "Discovered %s", let_to_name(oclass, FALSE)); + putstr(tmpwin, iflags.menu_headings, buf); + for (i = bases[(int)oclass]; + i < NUM_OBJECTS && objects[i].oc_class == oclass; ++i) { + if ((dis = disco[i]) != 0 && interesting_to_discover(dis)) { + Sprintf(buf, "%s %s", + objects[dis].oc_pre_discovered ? "*" : " ", + obj_typename(dis)); + putstr(tmpwin, 0, buf); + ++ct; + } + } + if (!ct) You(havent_discovered_any, oclass_to_name(oclass, buf)); + break; + } + if (ct) display_nhwindow(tmpwin, TRUE); + destroy_nhwindow(tmpwin); + return 0; +} + /* put up nameable subset of discoveries list as a menu */ void rename_disco() -- 2.40.0