1 /* NetHack 3.6 pager.c $NHDT-Date: 1448482543 2015/11/25 20:15:43 $ $NHDT-Branch: master $:$NHDT-Revision: 1.86 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
10 /* This file contains the command routines dowhatis() and dohelp() and */
11 /* a few other help related facilities */
16 STATIC_DCL boolean FDECL(is_swallow_sym, (int));
17 STATIC_DCL int FDECL(append_str, (char *, const char *));
18 STATIC_DCL void FDECL(look_at_object, (char *, int, int, int));
19 STATIC_DCL void FDECL(look_at_monster, (char *, char *,
20 struct monst *, int, int));
21 STATIC_DCL struct permonst *FDECL(lookat, (int, int, char *, char *));
22 STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
23 BOOLEAN_P, BOOLEAN_P));
24 STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
25 STATIC_DCL boolean FDECL(help_menu, (int *));
26 STATIC_DCL void NDECL(docontact);
28 extern void NDECL(port_help);
31 /* Returns "true" for characters that could represent a monster's stomach. */
38 for (i = S_sw_tl; i <= S_sw_br; i++)
39 if ((int) showsyms[i] == c)
45 * Append new_str to the end of buf if new_str doesn't already exist as
46 * a substring of buf. Return 1 if the string was appended, 0 otherwise.
47 * It is expected that buf is of size BUFSZ.
50 append_str(buf, new_str)
54 int space_left; /* space remaining in buf */
56 if (strstri(buf, new_str))
59 space_left = BUFSZ - strlen(buf) - 1;
61 (void) strncat(buf, " or ", space_left);
62 (void) strncat(buf, new_str, space_left - 4);
64 (void) strncat(buf, "
\82Ü
\82½
\82Í", space_left);
65 (void) strncat(buf, new_str, space_left - 6);
70 /* shared by monster probing (via query_objlist!) as well as lookat() */
77 /* include race with role unless polymorphed */
81 Sprintf(race, "%s ", urace.adj);
83 Sprintf(race, "%s", urace.adj);
85 Sprintf(outbuf, "%s%s%s called %s",
86 /* being blinded may hide invisibility from self */
87 (Invis && (senseself() || !Blind)) ? "invisible " : "", race,
88 mons[u.umonnum].mname, plname);
90 Sprintf(outbuf, "%s%s%s
\82Æ
\82¢
\82¤
\96¼
\82Ì%s",
91 (Invis && (senseself() || !Blind)) ? "
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢" : "", race,
93 mons[u.umonnum].mname);
97 Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
99 Sprintf(eos(outbuf), "
\81C%s
\82É
\8fæ
\82Á
\82Ä
\82¢
\82é", y_monnam(u.usteed));
103 /* extracted from lookat(); also used by namefloorobj() */
105 object_from_map(glyph, x, y, obj_p)
109 boolean fakeobj = FALSE;
111 struct obj *otmp = vobj_at(x, y);
112 int glyphotyp = glyph_to_obj(glyph);
114 *obj_p = (struct obj *) 0;
115 /* there might be a mimic here posing as an object */
117 if (mtmp && is_obj_mappear(mtmp, (unsigned) glyphotyp))
122 if (!otmp || otmp->otyp != glyphotyp) {
123 /* this used to exclude STRANGE_OBJECT; now caller deals with it */
124 otmp = mksobj(glyphotyp, FALSE, FALSE);
128 if (otmp->oclass == COIN_CLASS)
129 otmp->quan = 2L; /* to force pluralization */
130 else if (otmp->otyp == SLIME_MOLD)
131 otmp->spe = context.current_fruit; /* give it a type */
132 if (mtmp && has_mcorpsenm(mtmp)) /* mimic as corpse/statue */
133 otmp->corpsenm = MCORPSENM(mtmp);
135 /* if located at adjacent spot, mark it as having been seen up close */
136 if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination)
140 return fakeobj; /* when True, caller needs to dealloc *obj_p */
144 look_at_object(buf, x, y, glyph)
145 char *buf; /* output buffer */
148 struct obj *otmp = 0;
149 boolean fakeobj = object_from_map(glyph, x, y, &otmp);
152 Strcpy(buf, (otmp->otyp != STRANGE_OBJECT)
153 ? distant_name(otmp, xname)
154 : obj_descr[STRANGE_OBJECT].oc_name);
156 dealloc_obj(otmp), otmp = 0;
158 Strcpy(buf, something); /* sanity precaution */
160 if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
162 Strcat(buf, " embedded in stone");
164 Strcat(buf, "
\81C
\8aâ
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é");
165 else if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR)
167 Strcat(buf, " embedded in a wall");
169 Strcat(buf, "
\81C
\95Ç
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é");
170 else if (closed_door(x, y))
172 Strcat(buf, " embedded in a door");
174 Strcat(buf, "
\81C
\94à
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é");
175 else if (is_pool(x, y))
176 /*JP 3.4.3
\82±
\82Ì
\95\94\95ª
\82Í
\95¨
\91Ì
\82É
\82µ
\82©
\8eg
\82í
\82ê
\82È
\82¢ */
178 Strcat(buf, " in water");
180 Strcat(buf, "
\81C
\90\85\92\86\82É
\82 \82é");
181 else if (is_lava(x, y))
183 Strcat(buf, " in molten lava"); /* [can this ever happen?] */
185 Strcat(buf, "
\81C
\97n
\8aâ
\82Ì
\92\86\82É
\82 \82é"); /* [can this ever happen?] */
191 look_at_monster(buf, monbuf, mtmp, x, y)
192 char *buf, *monbuf; /* buf: output, monbuf: optional output */
196 char *name, monnambuf[BUFSZ];
197 boolean accurate = !Hallucination;
199 if (mtmp->data == &mons[PM_COYOTE] && accurate)
200 name = coyotename(mtmp, monnambuf);
202 name = distant_monnam(mtmp, ARTICLE_NONE, monnambuf);
205 Sprintf(buf, "%s%s%s",
206 (mtmp->mx != x || mtmp->my != y)
207 ? ((mtmp->isshk && accurate) ? "tail of " : "tail of a ")
209 (mtmp->mtame && accurate)
211 : (mtmp->mpeaceful && accurate)
216 Sprintf(buf, "%s%s%s",
217 (mtmp->mtame && accurate) ? "
\8eè
\82È
\82¸
\82¯
\82ç
\82ê
\82½" :
218 (mtmp->mpeaceful && accurate) ? "
\97F
\8dD
\93I
\82È" : "",
220 (mtmp->mx != x || mtmp->my != y) ?
221 ((mtmp->isshk && accurate)
222 ? "
\82Ì
\90K
\94ö" : "
\82Ì
\90K
\94ö") : "");
224 if (u.ustuck == mtmp)
225 Strcat(buf, (Upolyd && sticks(youmonst.data))
227 ? ", being held" : ", holding you");
229 ? "
\81C
\82 \82È
\82½
\82ª
\92Í
\82Ü
\82¦
\82Ä
\82¢
\82é" : "
\81C
\82 \82È
\82½
\82ð
\92Í
\82Ü
\82¦
\82Ä
\82¢
\82é");
232 Strcat(buf, ", leashed to you");
234 Strcat(buf, "
\81C
\95R
\82Å
\8c\8b\82Î
\82ê
\82Ä
\82¢
\82é");
236 if (mtmp->mtrapped && cansee(mtmp->mx, mtmp->my)) {
237 struct trap *t = t_at(mtmp->mx, mtmp->my);
238 int tt = t ? t->ttyp : NO_TRAP;
240 /* newsym lets you know of the trap, so mention it here */
241 if (tt == BEAR_TRAP || tt == PIT || tt == SPIKED_PIT || tt == WEB)
243 Sprintf(eos(buf), ", trapped in %s",
245 Sprintf(eos(buf), ", %s
\82É
\95ß
\82Ü
\82Á
\82Ä
\82¢
\82é",
246 an(defsyms[trap_to_defsym(tt)].explanation));
250 unsigned how_seen = howmonseen(mtmp);
253 if (how_seen != 0 && how_seen != MONSEEN_NORMAL) {
254 if (how_seen & MONSEEN_NORMAL) {
256 Strcat(monbuf, "normal vision");
258 Strcat(monbuf, "
\92Ê
\8fí
\82Ì
\8e\8b\8ao");
259 how_seen &= ~MONSEEN_NORMAL;
260 /* how_seen can't be 0 yet... */
262 Strcat(monbuf, ", ");
264 if (how_seen & MONSEEN_SEEINVIS) {
266 Strcat(monbuf, "see invisible");
268 Strcat(monbuf, "
\8c©
\82¦
\82È
\82¢
\82à
\82Ì
\82ð
\8c©
\82é
\8e\8b\8ao");
269 how_seen &= ~MONSEEN_SEEINVIS;
271 Strcat(monbuf, ", ");
273 if (how_seen & MONSEEN_INFRAVIS) {
275 Strcat(monbuf, "infravision");
277 Strcat(monbuf, "
\90Ô
\8aO
\90ü
\82ª
\8c©
\82¦
\82é
\8e\8b\8ao");
278 how_seen &= ~MONSEEN_INFRAVIS;
280 Strcat(monbuf, ", ");
282 if (how_seen & MONSEEN_TELEPAT) {
284 Strcat(monbuf, "telepathy");
286 Strcat(monbuf, "
\83e
\83\8c\83p
\83V
\81[");
287 how_seen &= ~MONSEEN_TELEPAT;
289 Strcat(monbuf, ", ");
291 if (how_seen & MONSEEN_XRAYVIS) {
292 /* Eyes of the Overworld */
294 Strcat(monbuf, "astral vision");
296 Strcat(monbuf, "
\90¸
\90_
\82É
\82æ
\82é
\8e\8b\8ao");
297 how_seen &= ~MONSEEN_XRAYVIS;
299 Strcat(monbuf, ", ");
301 if (how_seen & MONSEEN_DETECT) {
303 Strcat(monbuf, "monster detection");
305 Strcat(monbuf, "
\89ö
\95¨
\82ð
\94
\8c©
\82·
\82é
\94\
\97Í");
306 how_seen &= ~MONSEEN_DETECT;
308 Strcat(monbuf, ", ");
310 if (how_seen & MONSEEN_WARNMON) {
313 Strcat(monbuf, "paranoid delusion");
315 Strcat(monbuf, "
\95Î
\8e·
\93I
\96Ï
\91z");
318 Sprintf(eos(monbuf), "warned of %s",
320 Sprintf(eos(monbuf), "%s
\82ð
\8cx
\8d\90\82µ
\82Ä
\82¢
\82é",
321 makeplural(mtmp->data->mname));
322 how_seen &= ~MONSEEN_WARNMON;
324 Strcat(monbuf, ", ");
326 /* should have used up all the how_seen bits by now */
328 impossible("lookat: unknown method of seeing monster");
329 Sprintf(eos(monbuf), "(%u)", how_seen);
331 } /* seen by something other than normal vision */
332 } /* monbuf is non-null */
336 * Return the name of the glyph found at (x,y).
337 * If not hallucinating and the glyph is a monster, also monster data.
339 STATIC_OVL struct permonst *
340 lookat(x, y, buf, monbuf)
344 struct monst *mtmp = (struct monst *) 0;
345 struct permonst *pm = (struct permonst *) 0;
348 buf[0] = monbuf[0] = '\0';
349 glyph = glyph_at(x, y);
350 if (u.ux == x && u.uy == y && canspotself()) {
352 (void) self_lookat(buf);
354 /* file lookup can't distinguish between "gnomish wizard" monster
355 and correspondingly named player character, always picking the
356 former; force it to find the general "wizard" entry instead */
357 if (Role_if(PM_WIZARD) && Race_if(PM_GNOME) && !Upolyd)
358 pm = &mons[PM_WIZARD];
360 /* When you see yourself normally, no explanation is appended
361 (even if you could also see yourself via other means).
362 Sensing self while blind or swallowed is treated as if it
363 were by normal vision (cf canseeself()). */
364 if ((Invisible || u.uundetected) && !Blind && !u.uswallow) {
377 eos(buf), " [seen: %s%s%s%s%s]",
378 (how & 1) ? "infravision" : "",
379 /* add comma if telep and infrav */
380 ((how & 3) > 2) ? ", " : "", (how & 2) ? "telepathy" : "",
381 /* add comma if detect and (infrav or telep or both) */
382 ((how & 7) > 4) ? ", " : "",
383 (how & 4) ? "monster detection" : "");
386 eos(buf), " [
\8a´
\92m: %s%s%s%s%s]",
387 (how & 1) ? "
\90Ô
\8aO
\90ü" : "",
388 /* add comma if telep and infrav */
389 ((how & 3) > 2) ? ", " : "", (how & 2) ? "
\83e
\83\8c\83p
\83V
\81[" : "",
390 /* add comma if detect and (infrav or telep or both) */
391 ((how & 7) > 4) ? ", " : "",
392 (how & 4) ? "
\89ö
\95¨
\8a´
\92m" : "");
395 } else if (u.uswallow) {
396 /* all locations when swallowed other than the hero are the monster */
398 Sprintf(buf, "interior of %s",
399 Blind ? "a monster" : a_monnam(u.ustuck));
401 Sprintf(buf, "%s
\82Ì
\93à
\95\94",
402 Blind ? "
\89ö
\95¨" : a_monnam(u.ustuck));
405 } else if (glyph_is_monster(glyph)) {
408 if ((mtmp = m_at(x, y)) != 0) {
409 look_at_monster(buf, monbuf, mtmp, x, y);
412 } else if (glyph_is_object(glyph)) {
413 look_at_object(buf, x, y, glyph); /* fill in buf[] */
414 } else if (glyph_is_trap(glyph)) {
415 int tnum = what_trap(glyph_to_trap(glyph));
417 Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
418 } else if (!glyph_is_cmap(glyph)) {
420 Strcpy(buf, "unexplored area");
422 Strcpy(buf, "
\96¢
\92T
\8dõ
\82Ì
\8fê
\8f\8a");
424 switch (glyph_to_cmap(glyph)) {
427 Sprintf(buf, "%s %saltar",
429 Sprintf(buf, "%s%s
\8dÕ
\92d",
430 /* like endgame high priests, endgame high altars
431 are only recognizable when immediately adjacent */
432 (Is_astralevel(&u.uz) && distu(x, y) > 2)
438 Amask2align(levl[x][y].altarmask & ~AM_SHRINE)),
439 ((levl[x][y].altarmask & AM_SHRINE)
440 && (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)))
448 if (is_drawbridge_wall(x, y) >= 0)
450 Strcpy(buf, "open drawbridge portcullis");
452 Strcpy(buf,"
\8aJ
\82¢
\82Ä
\82¢
\82é
\92µ
\82Ë
\8b´");
453 else if ((levl[x][y].doormask & ~D_TRAPPED) == D_BROKEN)
455 Strcpy(buf, "broken door");
457 Strcpy(buf,"
\89ó
\82ê
\82½
\94à");
460 Strcpy(buf, "doorway");
462 Strcpy(buf,"
\8fo
\93ü
\82è
\8cû");
467 Is_airlevel(&u.uz) ? "cloudy area" : "fog/vapor cloud");
469 Is_airlevel(&u.uz) ? "
\93Ü
\82Á
\82Ä
\82¢
\82é
\8fê
\8f\8a" : "
\96¶/
\8fö
\8bC
\82Ì
\89_");
472 if (!levl[x][y].seenv) {
474 Strcpy(buf, "unexplored");
476 Strcpy(buf, "
\96¢
\92T
\8dõ");
478 } else if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR) {
480 Strcpy(buf, "stone");
482 Strcpy(buf, "
\8aâ
\94Õ");
487 Strcpy(buf, defsyms[glyph_to_cmap(glyph)].explanation);
491 return (pm && !Hallucination) ? pm : (struct permonst *) 0;
495 * Look in the "data" file for more info. Called if the user typed in the
496 * whole name (user_typed_name == TRUE), or we've found a possible match
497 * with a character/glyph and flags.help is TRUE.
499 * NOTE: when (user_typed_name == FALSE), inp is considered read-only and
500 * must not be changed directly, e.g. via lcase(). We want to force
501 * lcase() for data.base lookup so that we can have a clean key.
502 * Therefore, we create a copy of inp _just_ for data.base lookup.
505 checkfile(inp, pm, user_typed_name, without_asking)
508 boolean user_typed_name, without_asking;
511 char buf[BUFSZ], newstr[BUFSZ];
512 char *ep, *dbase_str;
513 unsigned long txt_offset = 0L;
515 boolean found_in_file = FALSE, skipping_entry = FALSE;
516 winid datawin = WIN_ERR;
518 fp = dlb_fopen(DATAFILE, "r");
521 pline("Cannot open data file!");
523 pline("
\83f
\81[
\83^
\83t
\83@
\83C
\83\8b\82ð
\8aJ
\82¯
\82È
\82¢
\81I");
529 * If someone passed us garbage, prevent fault.
531 if (!inp || (inp && strlen(inp) > (BUFSZ - 1))) {
532 pline("bad do_look buffer passed!");
536 /* To prevent the need for entries in data.base like *ngel to account
537 * for Angel and angel, make the lookup string the same for both
538 * user_typed_name and picked name.
540 if (pm != (struct permonst *) 0 && !user_typed_name)
541 dbase_str = strcpy(newstr, pm->mname);
543 dbase_str = strcpy(newstr, inp);
544 (void) lcase(dbase_str);
546 if (!strncmp(dbase_str, "interior of ", 12))
548 if (!strncmp(dbase_str, "a ", 2))
550 else if (!strncmp(dbase_str, "an ", 3))
552 else if (!strncmp(dbase_str, "the ", 4))
554 if (!strncmp(dbase_str, "tame ", 5))
556 else if (!strncmp(dbase_str, "peaceful ", 9))
558 if (!strncmp(dbase_str, "invisible ", 10))
560 if (!strncmp(dbase_str, "saddled ", 8))
562 if (!strncmp(dbase_str, "statue of ", 10))
564 else if (!strncmp(dbase_str, "figurine of ", 12))
567 /* Make sure the name is non-empty. */
569 /* adjust the input to remove "named " and convert to lower case */
570 char *alt = 0; /* alternate description */
572 if ((ep = strstri(dbase_str, " named ")) != 0)
575 ep = strstri(dbase_str, " called ");
577 ep = strstri(dbase_str, ", ");
578 if (ep && ep > dbase_str)
582 * If the object is named, then the name is the alternate description;
583 * otherwise, the result of makesingular() applied to the name is.
585 * isn't strictly optimal, but named objects of interest to the user
586 * will usually be found under their name, rather than under their
587 * object type, so looking for a singular form is pointless.
590 alt = makesingular(dbase_str);
592 /* skip first record; read second */
594 if (!dlb_fgets(buf, BUFSZ, fp) || !dlb_fgets(buf, BUFSZ, fp)) {
595 impossible("can't read 'data' file");
596 (void) dlb_fclose(fp);
598 } else if (sscanf(buf, "%8lx\n", &txt_offset) < 1 || txt_offset == 0L)
601 /* look for the appropriate entry */
602 while (dlb_fgets(buf, BUFSZ, fp)) {
604 break; /* we passed last entry without success */
607 /* a number indicates the end of current entry */
608 skipping_entry = FALSE;
609 } else if (!skipping_entry) {
610 if (!(ep = index(buf, '\n')))
613 /* if we match a key that begins with "~", skip this entry */
614 chk_skip = (*buf == '~') ? 1 : 0;
615 if (pmatch(&buf[chk_skip], dbase_str)
616 || (alt && pmatch(&buf[chk_skip], alt))) {
618 skipping_entry = TRUE;
621 found_in_file = TRUE;
634 /* skip over other possible matches for the info */
636 if (!dlb_fgets(buf, BUFSZ, fp))
638 } while (!digit(*buf));
639 if (sscanf(buf, "%ld,%d\n", &entry_offset, &entry_count) < 2) {
641 impossible("'data' file in wrong format or corrupted");
642 /* window will exist if we came here from below via 'goto' */
643 if (datawin != WIN_ERR)
644 destroy_nhwindow(datawin);
645 (void) dlb_fclose(fp);
650 if (user_typed_name || without_asking || yn("More info?") == 'y') {
652 if (user_typed_name || without_asking || yn("
\8fÚ
\8d×
\82ð
\8c©
\82é
\81H") == 'y') {
653 if (dlb_fseek(fp, (long) txt_offset + entry_offset, SEEK_SET)
656 pline("? Seek error on 'data' file!");
658 pline("'data'
\83t
\83@
\83C
\83\8b\82Ì
\83V
\81[
\83N
\83G
\83\89\81[
\81I");
659 (void) dlb_fclose(fp);
662 datawin = create_nhwindow(NHW_MENU);
663 for (i = 0; i < entry_count; i++) {
664 if (!dlb_fgets(buf, BUFSZ, fp))
666 if ((ep = index(buf, '\n')) != 0)
668 if (index(buf + 1, '\t') != 0)
669 (void) tabexpand(buf + 1);
670 putstr(datawin, 0, buf + 1);
672 display_nhwindow(datawin, FALSE);
673 destroy_nhwindow(datawin);
675 } else if (user_typed_name)
677 pline("I don't have any information on those things.");
679 pline("
\82»
\82ñ
\82È
\96¼
\91O
\82Í
\95·
\82¢
\82½
\82±
\82Æ
\82ª
\82È
\82¢
\81D");
681 (void) dlb_fclose(fp);
685 do_screen_description(cc, looked, sym, out_str, firstmatch)
690 const char **firstmatch;
692 boolean need_to_look = FALSE;
693 int glyph = NO_GLYPH;
694 static char look_buf[BUFSZ];
696 int found = 0; /* count of matching syms found */
698 int skipped_venom = 0;
702 static const char *mon_interior = "the interior of a monster";
704 static const char *mon_interior = "
\89ö
\95¨
\82Ì
\93à
\95\94";
710 glyph = glyph_at(cc.x, cc.y);
711 /* Convert glyph at selected position to a symbol for use below. */
712 (void) mapglyph(glyph, &sym, &oc, &os, cc.x, cc.y);
714 Sprintf(prefix, "%s ", encglyph(glyph));
716 Sprintf(prefix, "%c ", sym);
719 * Check all the possibilities, saving all explanations in a buffer.
720 * When all have been checked then the string is printed.
724 * Special case: if identifying from the screen, and we're swallowed,
725 * and looking at something other than our own symbol, then just say
726 * "the interior of a monster".
728 if (u.uswallow && looked
729 && (is_swallow_sym(sym) || (int) showsyms[S_stone] == sym)) {
731 Sprintf(out_str, "%s%s", prefix, mon_interior);
732 *firstmatch = mon_interior;
734 found += append_str(out_str, mon_interior);
740 /* Check for monsters */
741 for (i = 0; i < MAXMCLASSES; i++) {
742 if (sym == (looked ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym)
743 && def_monsyms[i].explain) {
746 Sprintf(out_str, "%s%s", prefix, an(def_monsyms[i].explain));
747 *firstmatch = def_monsyms[i].explain;
750 found += append_str(out_str, an(def_monsyms[i].explain));
754 /* handle '@' as a special case if it refers to you and you're
755 playing a character which isn't normally displayed by that
756 symbol; firstmatch is assumed to already be set for '@' */
757 if ((looked ? (sym == showsyms[S_HUMAN + SYM_OFF_M]
758 && cc.x == u.ux && cc.y == u.uy)
759 : (sym == def_monsyms[S_HUMAN].sym && !flags.showrace))
760 && !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
762 found += append_str(out_str, "you"); /* tack on "or you" */
764 found += append_str(out_str, "
\82 \82È
\82½"); /* tack on "or you" */
767 /* Now check for objects */
768 for (i = 1; i < MAXOCLASSES; i++) {
769 if (sym == (looked ? showsyms[i + SYM_OFF_O] : def_oc_syms[i].sym)) {
771 if (looked && i == VENOM_CLASS) {
776 Sprintf(out_str, "%s%s", prefix, an(def_oc_syms[i].explain));
777 *firstmatch = def_oc_syms[i].explain;
780 found += append_str(out_str, an(def_oc_syms[i].explain));
785 if (sym == DEF_INVISIBLE) {
787 Sprintf(out_str, "%s%s", prefix, an(invisexplain));
788 *firstmatch = invisexplain;
791 found += append_str(out_str, an(invisexplain));
795 #define is_cmap_trap(i) ((i) >= S_arrow_trap && (i) <= S_polymorph_trap)
796 #define is_cmap_drawbridge(i) ((i) >= S_vodbridge && (i) <= S_hcdbridge)
798 /* Now check for graphics symbols */
799 alt_i = (sym == (looked ? showsyms[0] : defsyms[0].sym)) ? 0 : (2 + 1);
800 for (hit_trap = FALSE, i = 0; i < MAXPCHARS; i++) {
801 /* when sym is the default background character, we process
802 i == 0 three times: unexplored, stone, dark part of a room */
805 x_str = !alt_i++ ? "unexplored" : "stone";
807 x_str = !alt_i++ ? "
\96¢
\92T
\8dõ" : "
\8aâ
\94Õ";
808 i = 0; /* for second iteration, undo loop increment */
809 /* alt_i is now 1 or 2 */
812 i = 0; /* undo loop increment */
813 x_str = defsyms[i].explanation;
814 /* alt_i is now 3 or more and no longer of interest */
816 if (sym == (looked ? showsyms[i] : defsyms[i].sym) && *x_str) {
817 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8aÖ
\8cW
\82È
\82¢*/
818 /* avoid "an unexplored", "an stone", "an air", "a water",
819 "a floor of a room", "a dark part of a room";
820 article==2 => "the", 1 => "an", 0 => (none) */
821 int article = strstri(x_str, " of a room") ? 2
823 || strcmp(x_str, "air") == 0
824 || strcmp(x_str, "water") == 0);
828 if (is_cmap_trap(i)) {
830 Sprintf(out_str, "%sa trap", prefix);
832 Sprintf(out_str, "%sã©", prefix);
836 Sprintf(out_str, "%s%s", prefix,
837 article == 2 ? the(x_str)
838 : article == 1 ? an(x_str) : x_str);
840 Sprintf(out_str, "%s%s", prefix, x_str);
845 } else if (!u.uswallow && !(hit_trap && is_cmap_trap(i))
846 && !(found >= 3 && is_cmap_drawbridge(i))
847 /* don't mention vibrating square outside of Gehennom
848 unless this happens to be one (hallucination?) */
849 && (i != S_vibrating_square || Inhell
850 || (looked && glyph_is_trap(glyph)
851 && glyph_to_trap(glyph) == VIBRATING_SQUARE))) {
853 found += append_str(out_str, (article == 2) ? the(x_str)
854 : (article == 1) ? an(x_str)
857 found += append_str(out_str, x_str);
863 if (i == S_altar || is_cmap_trap(i))
868 /* Now check for warning symbols */
869 for (i = 1; i < WARNCOUNT; i++) {
870 x_str = def_warnsyms[i].explanation;
871 if (sym == (looked ? warnsyms[i] : def_warnsyms[i].sym)) {
873 Sprintf(out_str, "%s%s", prefix, def_warnsyms[i].explanation);
874 *firstmatch = def_warnsyms[i].explanation;
877 found += append_str(out_str, def_warnsyms[i].explanation);
879 /* Kludge: warning trumps boulders on the display.
880 Reveal the boulder too or player can get confused */
881 if (looked && sobj_at(BOULDER, cc.x, cc.y))
882 Strcat(out_str, " co-located with a boulder");
883 break; /* out of for loop*/
887 /* if we ignored venom and list turned out to be short, put it back */
888 if (skipped_venom && found < 2) {
889 x_str = def_oc_syms[VENOM_CLASS].explain;
891 Sprintf(out_str, "%s%s", prefix, an(x_str));
895 found += append_str(out_str, an(x_str));
899 /* handle optional boulder symbol as a special case */
900 if (iflags.bouldersym && sym == iflags.bouldersym) {
903 *firstmatch = "boulder";
905 *firstmatch = "
\8aâ";
906 Sprintf(out_str, "%s%s", prefix, an(*firstmatch));
910 found += append_str(out_str, "boulder");
912 found += append_str(out_str, "
\8aâ");
917 * If we are looking at the screen, follow multiple possibilities or
918 * an ambiguous explanation by something more detailed.
922 if (found > 1 || need_to_look) {
924 char temp_buf[BUFSZ];
926 (void) lookat(cc.x, cc.y, look_buf, monbuf);
927 *firstmatch = look_buf;
928 if (*(*firstmatch)) {
929 Sprintf(temp_buf, " (%s)", *firstmatch);
930 (void) strncat(out_str, temp_buf,
931 BUFSZ - strlen(out_str) - 1);
932 found = 1; /* we have something to look up */
935 Sprintf(temp_buf, " [seen: %s]", monbuf);
936 (void) strncat(out_str, temp_buf,
937 BUFSZ - strlen(out_str) - 1);
945 /* getpos() return values */
946 #define LOOK_TRADITIONAL 0 /* '.' -- ask about "more info?" */
947 #define LOOK_QUICK 1 /* ',' -- skip "more info?" */
948 #define LOOK_ONCE 2 /* ';' -- skip and stop looping */
949 #define LOOK_VERBOSE 3 /* ':' -- show more info w/o asking */
951 /* also used by getpos hack in do_name.c */
953 const char what_is_an_unknown_object[] = "an unknown object";
955 const char what_is_an_unknown_object[] = "
\93ä
\82Ì
\95¨
\91Ì";
958 do_look(mode, click_cc)
962 boolean quick = (mode == 1); /* use cursor; don't search for "more info" */
963 boolean clicklook = (mode == 2); /* right mouse-click method */
965 const char *firstmatch = 0;
966 struct permonst *pm = 0;
967 int i = '\0', ans = 0;
968 int sym; /* typed symbol or converted glyph */
969 int found; /* count of matching syms found */
970 coord cc; /* screen pos of unknown glyph */
971 boolean save_verbose; /* saved value of flags.verbose */
972 boolean from_screen; /* question from the screen */
976 from_screen = TRUE; /* yes, we want to use the cursor */
981 menu_item *pick_list = (menu_item *) 0;
986 win = create_nhwindow(NHW_MENU);
989 /* 'y' and 'n' to keep backwards compatibility with previous
990 versions: "Specify unknown object by cursor?" */
991 add_menu(win, NO_GLYPH, &any,
992 flags.lootabc ? 0 : any.a_char, 'y', ATR_NONE,
994 "something on the map", MENU_UNSELECTED);
996 "
\92n
\90}
\8fã
\82É
\82 \82é
\82à
\82Ì", MENU_UNSELECTED);
998 add_menu(win, NO_GLYPH, &any,
999 flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
1001 "something you're carrying", MENU_UNSELECTED);
1003 "
\82 \82È
\82½
\82ª
\8e\9d\82Á
\82Ä
\82¢
\82é
\82à
\82Ì", MENU_UNSELECTED);
1005 add_menu(win, NO_GLYPH, &any,
1006 flags.lootabc ? 0 : any.a_char, 'n', ATR_NONE,
1008 "something else (by symbol or name)", MENU_UNSELECTED);
1010 "
\82»
\82ê
\88È
\8aO(
\83V
\83\93\83{
\83\8b\82©
\96¼
\91O
\82Å
\8ew
\92è)", MENU_UNSELECTED);
1011 if (!u.uswallow && !Hallucination) {
1013 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
1014 "", MENU_UNSELECTED);
1015 /* these options work sensibly for the swallowed case,
1016 but there's no reason for the player to use them then;
1017 objects work fine when hallucinating, but screen
1018 symbol/monster class letter doesn't match up with
1019 bogus monster type, so suppress when hallucinating */
1021 add_menu(win, NO_GLYPH, &any,
1022 flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
1024 "nearby monsters", MENU_UNSELECTED);
1026 "
\8bß
\82
\82É
\82¢
\82é
\89ö
\95¨", MENU_UNSELECTED);
1028 add_menu(win, NO_GLYPH, &any,
1029 flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
1031 "all monsters shown on map", MENU_UNSELECTED);
1033 "
\92n
\90}
\8fã
\82É
\82¢
\82é
\91S
\82Ä
\82Ì
\89ö
\95¨", MENU_UNSELECTED);
1035 add_menu(win, NO_GLYPH, &any,
1036 flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
1038 "nearby objects", MENU_UNSELECTED);
1040 "
\8bß
\82
\82É
\82 \82é
\82à
\82Ì", MENU_UNSELECTED);
1042 add_menu(win, NO_GLYPH, &any,
1043 flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
1045 "all objects shown on map", MENU_UNSELECTED);
1047 "
\92n
\90}
\8fã
\82É
\82 \82é
\91S
\82Ä
\82Ì
\82à
\82Ì", MENU_UNSELECTED);
1050 end_menu(win, "What do you want to look at:");
1052 end_menu(win, "
\89½
\82ð
\8c©
\82é
\81H");
1053 if (select_menu(win, PICK_ONE, &pick_list) > 0) {
1054 i = pick_list->item.a_char;
1055 free((genericptr_t) pick_list);
1057 destroy_nhwindow(win);
1076 invlet = display_inventory((const char *) 0, TRUE);
1077 if (!invlet || invlet == '\033')
1080 for (invobj = invent; invobj; invobj = invobj->nobj)
1081 if (invobj->invlet == invlet) {
1082 strcpy(out_str, singular(invobj, xname));
1086 checkfile(out_str, pm, TRUE, TRUE);
1090 from_screen = FALSE;
1092 getlin("Specify what? (type the word)", out_str);
1094 getlin("
\89½
\82ð
\92²
\82×
\82é
\81H(
\95¶
\8e\9a\82ð
\93ü
\82ê
\82Ä
\82Ë)", out_str);
1095 if (out_str[0] == '\0' || out_str[0] == '\033')
1098 if (out_str[1]) { /* user typed in a complete string */
1099 checkfile(out_str, pm, TRUE, TRUE);
1105 look_all(TRUE, TRUE); /* list nearby monsters */
1108 look_all(FALSE, TRUE); /* list all monsters */
1111 look_all(TRUE, FALSE); /* list nearby objects */
1114 look_all(FALSE, FALSE); /* list all objects */
1117 } else { /* clicklook */
1121 from_screen = FALSE;
1124 /* Save the verbose flag, we change it later. */
1125 save_verbose = flags.verbose;
1126 flags.verbose = flags.verbose && !quick;
1128 * The user typed one letter, or we're identifying from the screen.
1131 /* Reset some variables. */
1132 pm = (struct permonst *) 0;
1136 if (from_screen || clicklook) {
1140 pline("Please move the cursor to %s.",
1141 what_is_an_unknown_object);
1143 pline("
\83J
\81[
\83\
\83\8b\82ð
\95¨
\91Ì
\82É
\88Ú
\93®
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81D");
1147 pline("Pick an object.");
1149 pline("
\95¨
\91Ì
\82ð
\8ew
\92è
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81D");
1151 ans = getpos(&cc, quick, what_is_an_unknown_object);
1152 if (ans < 0 || cc.x < 0) {
1153 flags.verbose = save_verbose;
1154 return 0; /* done */
1156 flags.verbose = FALSE; /* only print long question once */
1160 found = do_screen_description(cc, (from_screen || clicklook), sym,
1161 out_str, &firstmatch);
1163 /* Finally, print out our explanation. */
1165 /* Used putmixed() because there may be an encoded glyph present
1167 putmixed(WIN_MESSAGE, 0, out_str);
1169 /* check the data file for information about this thing */
1170 if (found == 1 && ans != LOOK_QUICK && ans != LOOK_ONCE
1171 && (ans == LOOK_VERBOSE || (flags.help && !quick))
1173 char temp_buf[BUFSZ];
1175 Strcpy(temp_buf, firstmatch);
1176 checkfile(temp_buf, pm, FALSE,
1177 (boolean) (ans == LOOK_VERBOSE));
1181 pline("I've never heard of such things.");
1183 pline("
\82»
\82ñ
\82È
\96¼
\91O
\82Í
\95·
\82¢
\82½
\82±
\82Æ
\82ª
\82È
\82¢
\81D");
1186 } while (from_screen && !quick && ans != LOOK_ONCE && !clicklook);
1188 flags.verbose = save_verbose;
1193 look_all(nearby, do_mons)
1194 boolean nearby; /* True => within BOLTLIM, False => entire map */
1195 boolean do_mons; /* True => monsters, False => objects */
1198 int x, y, lo_x, lo_y, hi_x, hi_y, glyph, count = 0;
1199 char buf[BUFSZ], outbuf[BUFSZ], coordbuf[12], fmt[12]; /* "%02d,%02d" */
1201 /* row,column orientation rather than cartesian x,y */
1202 Sprintf(fmt, "%%%sd,%%%sd",
1203 (ROWNO <= 100) ? "02" : (ROWNO <= 1000) ? "03" : "",
1204 (COLNO <= 100) ? "02" : (COLNO <= 1000) ? "03" : "");
1206 win = create_nhwindow(NHW_TEXT);
1207 lo_y = nearby ? max(u.uy - BOLT_LIM, 0) : 0;
1208 lo_x = nearby ? max(u.ux - BOLT_LIM, 1) : 1;
1209 hi_y = nearby ? min(u.uy + BOLT_LIM, ROWNO - 1) : ROWNO - 1;
1210 hi_x = nearby ? min(u.ux + BOLT_LIM, COLNO - 1) : COLNO - 1;
1211 for (y = lo_y; y <= hi_y; y++) {
1212 for (x = lo_x; x <= hi_x; x++) {
1214 glyph = glyph_at(x, y);
1216 if (glyph_is_monster(glyph)) {
1219 bhitpos.x = x; /* [is this actually necessary?] */
1221 if (x == u.ux && y == u.uy && canspotself()) {
1222 (void) self_lookat(buf);
1224 } else if ((mtmp = m_at(x, y)) != 0) {
1225 look_at_monster(buf, (char *) 0, mtmp, x, y);
1228 } else if (glyph_is_invisible(glyph)) {
1229 /* remembered, unseen, creature */
1230 Strcpy(buf, invisexplain);
1232 } else if (glyph_is_warning(glyph)) {
1233 int warnindx = glyph_to_warning(glyph);
1235 Strcpy(buf, def_warnsyms[warnindx].explanation);
1238 } else { /* !do_mons */
1239 if (glyph_is_object(glyph)) {
1240 look_at_object(buf, x, y, glyph);
1248 Strcpy(which, do_mons ? "monsters" : "objects");
1250 Sprintf(coordbuf, fmt, u.uy, u.ux);
1251 Sprintf(outbuf, "%s currently shown near %s:",
1252 upstart(which), coordbuf);
1254 Sprintf(outbuf, "All %s currently shown on the map:",
1256 putstr(win, 0, outbuf);
1259 Sprintf(coordbuf, fmt, y, x);
1260 /* prefix: "C row,column " */
1261 Sprintf(outbuf, "%s %s ", encglyph(glyph), coordbuf);
1262 /* guard against potential overflow */
1263 buf[sizeof buf - 1 - strlen(outbuf)] = '\0';
1264 Strcat(outbuf, buf);
1265 putmixed(win, 0, outbuf);
1270 display_nhwindow(win, TRUE);
1273 pline("No %s are currently shown %s.",
1274 do_mons ? "monsters" : "objects",
1275 nearby ? "nearby" : "on the map");
1277 pline("
\8d¡
\82Ì
\82Æ
\82±
\82ë%s
\82É%s
\81D",
1278 nearby ? "
\8bß
\82" : "
\92n
\90}
\8fã",
1279 do_mons ? "
\89ö
\95¨
\82Í
\82¢
\82È
\82¢" : "
\82à
\82Ì
\82Í
\82È
\82¢");
1281 destroy_nhwindow(win);
1284 /* the '/' command */
1288 return do_look(0, (coord *) 0);
1291 /* the ';' command */
1295 return do_look(1, (coord *) 0);
1298 /* the '^' command */
1302 register struct trap *trap;
1309 for (trap = ftrap; trap; trap = trap->ntrap)
1310 if (trap->tx == x && trap->ty == y) {
1315 if (u.dz < 0 ? (tt == TRAPDOOR || tt == HOLE)
1321 pline("That is %s%s%s.",
1322 an(defsyms[trap_to_defsym(tt)].explanation),
1327 /* trap doors & spiked pits can't be made by
1328 player, and should be considered at least
1329 as much "set" as "dug" anyway */
1330 : (tt == HOLE || tt == PIT)
1333 !trap->madeby_u ? "" : " by you");
1335 pline("
\82»
\82ê
\82Í%s%s
\82¾
\81D",
1339 ? "
\82 \82È
\82½
\82ª
\92£
\82Á
\82½"
1340 : (tt == HOLE || tt == PIT)
1341 ? "
\82 \82È
\82½
\82ª
\8c@
\82Á
\82½"
1342 : "
\82 \82È
\82½
\82ª
\8ed
\8a|
\82¯
\82½",
1343 defsyms[trap_to_defsym(tt)].explanation);
1348 pline("I can't see a trap there.");
1350 pline("
\82»
\82±
\82É
\82Íã©
\82Í
\82Ý
\82 \82½
\82ç
\82È
\82¢
\81D");
1355 dowhatdoes_core(q, cbuf)
1361 register char *buf = &bufr[6], *ep, ctrl, meta;
1363 fp = dlb_fopen(CMDHELPFILE, "r");
1366 pline("Cannot open data file!");
1368 pline("
\83f
\81[
\83^
\83t
\83@
\83C
\83\8b\82ð
\8aJ
\82¯
\82È
\82¢
\81I");
1373 ctrl = ((q <= '\033') ? (q - 1 + 'A') : 0);
1374 meta = ((0x80 & q) ? (0x7f & q) : 0);
1375 while (dlb_fgets(buf, BUFSZ - 6, fp)) {
1376 if ((ctrl && *buf == '^' && *(buf + 1) == ctrl)
1377 || (meta && *buf == 'M' && *(buf + 1) == '-'
1378 && *(buf + 2) == meta) || *buf == q) {
1379 ep = index(buf, '\n');
1382 if (ctrl && buf[2] == '\t') {
1384 (void) strncpy(buf, "^? ", 8);
1386 } else if (meta && buf[3] == '\t') {
1388 (void) strncpy(buf, "M-? ", 8);
1390 } else if (buf[1] == '\t') {
1393 (void) strncpy(buf + 1, " ", 7);
1395 (void) dlb_fclose(fp);
1400 (void) dlb_fclose(fp);
1410 #if defined(UNIX) || defined(VMS)
1414 q = yn_function("What command?", (char *) 0, '\0');
1416 q = yn_function("
\82Ç
\82¤
\82¢
\82¤
\83R
\83}
\83\93\83h
\81H", (char *) 0, '\0');
1417 #if defined(UNIX) || defined(VMS)
1420 reslt = dowhatdoes_core(q, bufr);
1425 pline("I've never heard of such commands.");
1427 pline("
\82»
\82ñ
\82È
\83R
\83}
\83\93\83h
\82Í
\95·
\82¢
\82½
\82±
\82Æ
\82ª
\82È
\82¢
\81D");
1434 winid cwin = create_nhwindow(NHW_TEXT);
1437 if (sysopt.support) {
1438 /*XXX overflow possibilities*/
1439 Sprintf(buf, "To contact local support, %s", sysopt.support);
1440 putstr(cwin, 0, buf);
1441 putstr(cwin, 0, "");
1442 } else if (sysopt.fmtd_wizard_list) { /* formatted SYSCF WIZARDS */
1443 Sprintf(buf, "To contact local support, contact %s.",
1444 sysopt.fmtd_wizard_list);
1445 putstr(cwin, 0, buf);
1446 putstr(cwin, 0, "");
1448 putstr(cwin, 0, "To contact the NetHack development team directly,");
1449 /*XXX overflow possibilities*/
1450 Sprintf(buf, "see the 'Contact' form on our website or email <%s>.",
1452 putstr(cwin, 0, buf);
1453 putstr(cwin, 0, "");
1454 putstr(cwin, 0, "For more information on NetHack, or to report a bug,");
1455 Sprintf(buf, "visit our website \"%s\".", DEVTEAM_URL);
1456 putstr(cwin, 0, buf);
1457 display_nhwindow(cwin, FALSE);
1458 destroy_nhwindow(cwin);
1461 /* data for help_menu() */
1462 static const char *help_menu_items[] = {
1464 /* 0*/ "About NetHack (version information).",
1465 /* 1*/ "Long description of the game and commands.",
1466 /* 2*/ "List of game commands.",
1467 /* 3*/ "Concise history of NetHack.",
1468 /* 4*/ "Info on a character in the game display.",
1469 /* 5*/ "Info on what a given key does.",
1470 /* 6*/ "List of game options.",
1471 /* 7*/ "Longer explanation of game options.",
1472 /* 8*/ "List of extended commands.",
1473 /* 9*/ "The NetHack license.",
1474 /* 10*/ "Support information.",
1476 "%s-specific help and commands.",
1477 #define PORT_HELP_ID 100
1478 #define WIZHLP_SLOT 12
1480 #define WIZHLP_SLOT 11
1482 "List of wizard-mode commands.", "", (char *) 0
1484 /* 0*/ "NetHack
\82É
\82Â
\82¢
\82Ä(
\83o
\81[
\83W
\83\87\83\93\8fî
\95ñ)",
1485 /* 1*/ "
\83Q
\81[
\83\80\82¨
\82æ
\82Ñ
\83R
\83}
\83\93\83h
\82Ì
\89ð
\90à(
\92·
\95¶)",
1486 /* 2*/ "
\83R
\83}
\83\93\83h
\88ê
\97\97",
1487 /* 3*/ "NetHack
\82Ì
\8aÈ
\92P
\82È
\97ð
\8ej",
1488 /* 4*/ "
\89æ
\96Ê
\82É
\95\
\8e¦
\82³
\82ê
\82é
\95¶
\8e\9a\82Ì
\90à
\96¾",
1489 /* 5*/ "
\82±
\82Ì
\83L
\81[
\82ª
\89½
\82ð
\88Ó
\96¡
\82·
\82é
\82©
\82Ì
\90à
\96¾",
1490 /* 6*/ "
\83Q
\81[
\83\80\82Ì
\83I
\83v
\83V
\83\87\83\93\88ê
\97\97",
1491 /* 7*/ "
\83Q
\81[
\83\80\82Ì
\83I
\83v
\83V
\83\87\83\93\88ê
\97\97(
\92·
\95¶)",
1492 /* 8*/ "
\8ag
\92£
\83R
\83}
\83\93\83h
\88ê
\97\97",
1493 /* 9*/ "NetHack
\82Ì
\83\89\83C
\83Z
\83\93\83X",
1494 /* 10*/ "
\83T
\83|
\81[
\83g
\8fî
\95ñ",
1496 "%s
\82É
\93Á
\97L
\82Ì
\83w
\83\8b\83v
\82¨
\82æ
\82Ñ
\83R
\83}
\83\93\83h",
1497 #define PORT_HELP_ID 100
1498 #define WIZHLP_SLOT 12
1500 #define WIZHLP_SLOT 11
1502 "
\83E
\83B
\83U
\81[
\83h
\83\82\81[
\83h
\82Ì
\83R
\83}
\83\93\83h
\88ê
\97\97", "", (char *) 0
1510 winid tmpwin = create_nhwindow(NHW_MENU);
1512 char helpbuf[QBUFSZ];
1515 menu_item *selected;
1518 any = zeroany; /* zero all bits */
1521 help_menu_items[WIZHLP_SLOT] = "",
1522 help_menu_items[WIZHLP_SLOT + 1] = (char *) 0;
1523 for (i = 0; help_menu_items[i]; i++)
1525 /* port-specific line has a %s in it for the PORT_ID */
1526 if (help_menu_items[i][0] == '%') {
1527 Sprintf(helpbuf, help_menu_items[i], PORT_ID);
1528 any.a_int = PORT_HELP_ID + 1;
1529 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, helpbuf,
1534 any.a_int = (*help_menu_items[i]) ? i + 1 : 0;
1535 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
1536 help_menu_items[i], MENU_UNSELECTED);
1539 end_menu(tmpwin, "Select one item:");
1541 end_menu(tmpwin, "
\91I
\82ñ
\82Å
\82
\82¾
\82³
\82¢
\81F");
1542 n = select_menu(tmpwin, PICK_ONE, &selected);
1543 destroy_nhwindow(tmpwin);
1545 *sel = selected[0].item.a_int - 1;
1546 free((genericptr_t) selected);
1552 /* the '?' command */
1558 if (help_menu(&sel)) {
1561 (void) doextversion();
1564 display_file(HELP, TRUE);
1567 display_file(SHELP, TRUE);
1576 (void) dowhatdoes();
1582 display_file(OPTIONFILE, TRUE);
1588 display_file(LICENSE, TRUE);
1599 /* handle slot 11 or 12 */
1600 display_file(DEBUGHELP, TRUE);
1607 /* the 'V' command; also a choice for '?' */
1611 display_file(HISTORY, TRUE);