1 /* NetHack 3.6 do_name.c $NHDT-Date: 1446808440 2015/11/06 11:14:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.77 $ */
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. */
12 STATIC_DCL char *NDECL(nextmbuf);
13 STATIC_DCL void FDECL(getpos_help, (BOOLEAN_P, const char *));
14 STATIC_DCL void NDECL(do_mname);
15 STATIC_DCL void FDECL(do_oname, (struct obj *));
16 STATIC_DCL void NDECL(namefloorobj);
17 STATIC_DCL char *FDECL(bogusmon, (char *,char *));
19 extern const char what_is_an_unknown_object[]; /* from pager.c */
23 /* manage a pool of BUFSZ buffers, so callers don't have to */
27 static char NEARDATA bufs[NUMMBUF][BUFSZ];
28 static int bufidx = 0;
30 bufidx = (bufidx + 1) % NUMMBUF;
34 /* function for getpos() to highlight desired map locations.
35 * parameter value 0 = initialize, 1 = highlight, 2 = done
37 void FDECL((*getpos_hilitefunc), (int)) = (void FDECL((*), (int))) 0;
41 void FDECL((*f), (int));
43 getpos_hilitefunc = f;
46 /* the response for '?' help request in getpos() */
48 getpos_help(force, goal)
53 boolean doing_what_is;
54 winid tmpwin = create_nhwindow(NHW_MENU);
57 Sprintf(sbuf, "Use [%c%c%c%c] to move the cursor to %s.", /* hjkl */
59 Sprintf(sbuf, "[%c%c%c%c]
\82Å%s
\82Ö
\88Ú
\93®
\82Å
\82«
\82é
\81D",
61 Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, goal);
62 putstr(tmpwin, 0, sbuf);
64 putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
66 putstr(tmpwin, 0, "[HJKL]
\82Å
\88ê
\93x
\82É8
\95à
\88Ú
\93®
\82Å
\82«
\82é
\81D");
68 putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
70 putstr(tmpwin, 0, "
\94w
\8ci
\82Ì
\83V
\83\93\83{
\83\8b\82ð
\93ü
\97Í
\82·
\82é
\82Æ
\82»
\82Ì
\88Ê
\92u
\82É
\88Ú
\93®
\82·
\82é(
\97á
\81F<)
\81D");
72 putstr(tmpwin, 0, "Use @ to move the cursor on yourself.");
74 putstr(tmpwin, 0, "@
\82Å
\8e©
\95ª
\8e©
\90g
\82Ì
\88Ê
\92u
\82É
\88Ú
\93®
\82·
\82é
\81D");
75 if (getpos_hilitefunc != NULL)
77 putstr(tmpwin, 0, "Use $ to display valid locations.");
79 putstr(tmpwin, 0, "$
\82Å
\89Â
\94\
\82È
\88Ê
\92u
\82ð
\95\
\8e¦
\82·
\82é
\81D");
81 putstr(tmpwin, 0, "Use # to toggle automatic description.");
83 putstr(tmpwin, 0, "#
\82Å
\90à
\96¾
\82Ì
\8e©
\93®
\95\
\8e¦
\82ð
\90Ø
\82è
\91Ö
\82¦
\82é
\81D");
84 /* disgusting hack; the alternate selection characters work for any
85 getpos call, but they only matter for dowhatis (and doquickwhatis) */
86 doing_what_is = (goal == what_is_an_unknown_object);
88 Sprintf(sbuf, "Type a .%s when you are at the right place.",
89 doing_what_is ? " or , or ; or :" : "");
91 Sprintf(sbuf, "[.]%s
\82Å
\8c\88\92è
\81D",
92 doing_what_is ? "[,][;][:]" : "");
94 putstr(tmpwin, 0, sbuf);
97 putstr(tmpwin, 0, "Type Space or Escape when you're done.");
99 putstr(tmpwin, 0, "
\83X
\83y
\81[
\83X
\82Ü
\82½
\82Í
\83G
\83X
\83P
\81[
\83v
\82Å
\8fI
\97¹
\81D");
100 putstr(tmpwin, 0, "");
101 display_nhwindow(tmpwin, TRUE);
102 destroy_nhwindow(tmpwin);
106 getpos(ccp, force, goal)
114 boolean msg_given = TRUE; /* clear message window by default */
115 boolean auto_msg = FALSE;
116 boolean show_goal_msg = FALSE;
117 static const char pick_chars[] = ".,;:";
119 boolean hilite_state = FALSE;
123 goal = "desired location";
125 goal = "
\96Ú
\93I
\92n";
128 pline("(For instructions type a ?)");
130 pline("(?
\82Å
\83w
\83\8b\83v)");
138 curs(WIN_MAP, cx, cy);
141 lock_mouse_cursor(TRUE);
146 pline("Move cursor to %s:", goal);
148 pline("
\83J
\81[
\83\
\83\8b\82ð%s
\82É
\93®
\82©
\82µ
\82Ä
\82
\82¾
\82³
\82¢:", goal);
149 curs(WIN_MAP, cx, cy);
151 show_goal_msg = FALSE;
152 } else if (auto_msg && !msg_given && !hilite_state) {
156 const char *firstmatch = NULL;
160 if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
162 curs(WIN_MAP, cx, cy);
167 c = nh_poskey(&tx, &ty, &sidx);
170 (*getpos_hilitefunc)(2);
171 hilite_state = FALSE;
172 curs(WIN_MAP, cx, cy);
181 msg_given = TRUE; /* force clear */
188 /* a mouse click event, just assign and return */
193 if ((cp = index(pick_chars, c)) != 0) {
194 /* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
195 result = (int) (cp - pick_chars);
198 for (i = 0; i < 8; i++) {
201 if (Cmd.dirchars[i] == c) {
202 /* a normal movement letter or digit */
205 } else if (Cmd.alphadirchars[i] == lowc((char) c)
206 || (Cmd.num_pad && Cmd.dirchars[i] == (c & 0177))) {
207 /* a shifted movement letter or Meta-digit */
213 /* truncate at map edge; diagonal moves complicate this... */
215 dy -= sgn(dy) * (1 - (cx + dx));
216 dx = 1 - cx; /* so that (cx+dx == 1) */
217 } else if (cx + dx > COLNO - 1) {
218 dy += sgn(dy) * ((COLNO - 1) - (cx + dx));
219 dx = (COLNO - 1) - cx;
222 dx -= sgn(dx) * (0 - (cy + dy));
223 dy = 0 - cy; /* so that (cy+dy == 0) */
224 } else if (cy + dy > ROWNO - 1) {
225 dx += sgn(dx) * ((ROWNO - 1) - (cy + dy));
226 dy = (ROWNO - 1) - cy;
233 if (c == '?' || redraw_cmd(c)) {
235 getpos_help(force, goal);
237 docrt(); /* redraw */
238 /* update message window to reflect that we're still targetting */
239 show_goal_msg = TRUE;
241 } else if ((c == '$') && (getpos_hilitefunc != NULL)) {
243 (*getpos_hilitefunc)(0);
244 (*getpos_hilitefunc)(1);
248 } else if (c == '#') {
249 auto_msg = !auto_msg;
251 pline("Automatic description %sis %s.",
252 flags.verbose ? "of features under cursor " : "",
253 auto_msg ? "on" : "off");
255 pline("%s
\90à
\96¾
\8e©
\93®
\95\
\8e¦
\81F%s",
256 flags.verbose ? "
\83J
\81[
\83\
\83\8b\82Ì
\89º
\82É
\82 \82é
\82à
\82Ì
\82Ì" : "",
257 auto_msg ? "
\83I
\83\93" : "
\83I
\83t");
260 show_goal_msg = TRUE;
263 } else if (c == '@') {
268 if (!index(quitchars, c)) {
269 char matching[MAXPCHARS];
270 int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
271 (void) memset((genericptr_t) matching, 0, sizeof matching);
272 for (sidx = 1; sidx < MAXPCHARS; sidx++)
273 if (c == defsyms[sidx].sym || c == (int) showsyms[sidx])
274 matching[sidx] = (char) ++k;
276 for (pass = 0; pass <= 1; pass++) {
277 /* pass 0: just past current pos to lower right;
278 pass 1: upper left corner to current pos */
279 lo_y = (pass == 0) ? cy : 0;
280 hi_y = (pass == 0) ? ROWNO - 1 : cy;
281 for (ty = lo_y; ty <= hi_y; ty++) {
282 lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
283 hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
284 for (tx = lo_x; tx <= hi_x; tx++) {
285 /* look at dungeon feature, not at
286 * user-visible glyph */
287 k = back_to_glyph(tx, ty);
288 /* uninteresting background glyph */
290 && (IS_DOOR(levl[tx][ty].typ)
291 || glyph_to_cmap(k) == S_room
292 || glyph_to_cmap(k) == S_darkroom
293 || glyph_to_cmap(k) == S_corr
294 || glyph_to_cmap(k) == S_litcorr)) {
295 /* what hero remembers to be at tx,ty */
296 k = glyph_at(tx, ty);
299 && matching[glyph_to_cmap(k)]
300 && levl[tx][ty].seenv
301 && (!IS_WALL(levl[tx][ty].typ))
302 && (levl[tx][ty].typ != SDOOR)
303 && glyph_to_cmap(k) != S_room
304 && glyph_to_cmap(k) != S_corr
305 && glyph_to_cmap(k) != S_litcorr) {
308 clear_nhwindow(WIN_MESSAGE);
317 pline("Can't find dungeon feature '%c'.", c);
319 pline("'%c'
\81H", c);
327 Strcpy(note, "aborted");
329 Strcpy(note, "
\92\86\92f
\82µ
\82½");
332 Sprintf(note, "use %c%c%c%c or .", /* hjkl */
334 Sprintf(note, "%c%c%c%c
\82Å
\88Ú
\93®
\81C.
\82Å
\8fI
\97¹", /* hjkl */
336 Cmd.move_W, Cmd.move_S, Cmd.move_N,
339 pline("Unknown direction: '%s' (%s).", visctrl((char) c),
341 pline("
\82»
\82Ì
\95û
\8cü
\82Í
\82È
\82¢
\81F'%s' (%s)", visctrl((char) c),
344 } /* k => matching */
351 pline("
\88È
\8fã
\81D");
352 msg_given = FALSE; /* suppress clear */
355 result = 0; /* not -1 */
363 curs(WIN_MAP, cx, cy);
367 lock_mouse_cursor(FALSE);
370 clear_nhwindow(WIN_MESSAGE);
373 getpos_hilitefunc = NULL;
377 /* allocate space for a monster's name; removes old name if there is one */
381 int lth; /* desired length (caller handles adding 1 for terminator) */
384 /* allocate mextra if necessary; otherwise get rid of old name */
386 mon->mextra = newmextra();
388 free_mname(mon); /* already has mextra, might also have name */
389 MNAME(mon) = (char *) alloc((unsigned) lth);
391 /* zero length: the new name is empty; get rid of the old name */
397 /* release a monster's name; retains mextra even if all fields are now null */
402 if (has_mname(mon)) {
403 free((genericptr_t) MNAME(mon));
404 MNAME(mon) = (char *) 0;
408 /* allocate space for an object's name; removes old name if there is one */
412 int lth; /* desired length (caller handles adding 1 for terminator) */
415 /* allocate oextra if necessary; otherwise get rid of old name */
417 obj->oextra = newoextra();
419 free_oname(obj); /* already has oextra, might also have name */
420 ONAME(obj) = (char *) alloc((unsigned) lth);
422 /* zero length: the new name is empty; get rid of the old name */
428 /* release an object's name; retains oextra even if all fields are now null */
433 if (has_oname(obj)) {
434 free((genericptr_t) ONAME(obj));
435 ONAME(obj) = (char *) 0;
439 /* safe_oname() always returns a valid pointer to
440 * a string, either the pointer to an object's name
441 * if it has one, or a pointer to an empty string
453 /* historical note: this returns a monster pointer because it used to
454 allocate a new bigger block of memory to hold the monster and its name */
456 christen_monst(mtmp, name)
463 /* dogname & catname are PL_PSIZ arrays; object names have same limit */
464 lth = (name && *name) ? ((int) strlen(name) + 1) : 0;
467 if (is_kanji2(buf, lth - 1))
471 name = strncpy(buf, name, PL_PSIZ - 1);
472 buf[PL_PSIZ - 1] = '\0';
474 new_mname(mtmp, lth); /* removes old name if one is present */
476 Strcpy(MNAME(mtmp), name);
480 /* allow player to assign a name to some chosen monster */
484 char buf[BUFSZ], monnambuf[BUFSZ];
487 register struct monst *mtmp;
492 You("would never recognize it anyway.");
494 You("
\82»
\82ê
\82ð
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\81D");
500 if (getpos(&cc, FALSE, "the monster you want to name") < 0
502 if (getpos(&cc, FALSE, "
\82 \82È
\82½
\82ª
\96¼
\82Ã
\82¯
\82½
\82¢
\89ö
\95¨") < 0
507 if (cx == u.ux && cy == u.uy) {
508 if (u.usteed && canspotmon(u.usteed))
512 pline("This %s creature is called %s and cannot be renamed.",
514 pline("
\82±
\82Ì%s
\90¶
\82«
\95¨
\82Í%s
\82Æ
\8cÄ
\82Î
\82ê
\82Ä
\82¢
\82Ä
\81C
\96¼
\91O
\82Í
\95Ï
\8dX
\82Å
\82«
\82È
\82¢
\81D",
515 beautiful(), plname);
523 && (!(cansee(cx, cy) || see_with_infrared(mtmp))
524 || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE
525 || mtmp->m_ap_type == M_AP_OBJECT
526 || (mtmp->minvis && !See_invisible)))) {
528 pline("I see no monster there.");
530 pline("
\82»
\82±
\82É
\89ö
\95¨
\82Í
\82¢
\82È
\82¢
\81D");
533 /* special case similar to the one in lookat() */
535 Sprintf(qbuf, "What do you want to call %s?",
537 Sprintf(qbuf, "%s
\82ð
\89½
\82Æ
\8cÄ
\82Ñ
\82Ü
\82·
\82©
\81H",
538 distant_monnam(mtmp, ARTICLE_THE, monnambuf));
540 if (!*buf || *buf == '\033')
542 /* strip leading and trailing spaces; unnames monster if all spaces */
543 (void) mungspaces(buf);
545 /* unique monsters have their own specific names or titles;
546 shopkeepers, temple priests and other minions use alternate
547 name formatting routines which ignore any user-supplied name */
548 if (mtmp->data->geno & G_UNIQ)
550 pline("%s doesn't like being called names!", upstart(monnambuf));
552 pline("%s
\82Í
\82 \82¾
\96¼
\82Å
\8cÄ
\82Î
\82ê
\82é
\82Ì
\82ª
\8c\99\82¢
\82È
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
554 && !(Deaf || mtmp->msleeping || !mtmp->mcanmove
555 || mtmp->data->msound <= MS_ANIMAL))
557 verbalize("I'm %s, not %s.", shkname(mtmp), buf);
559 verbalize("
\8e\84\82Í%s
\82¾
\81C%s
\82Å
\82Í
\82È
\82¢
\81D", shkname(mtmp), buf);
560 else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk)
562 pline("%s will not accept the name %s.", upstart(monnambuf), buf);
564 pline("%s
\82Í%s
\82Æ
\82¢
\82¤
\96¼
\91O
\82ð
\8eó
\82¯
\82¢
\82ê
\82È
\82©
\82Á
\82½
\81D", monnambuf, buf);
566 (void) christen_monst(mtmp, buf);
570 * This routine changes the address of obj. Be careful not to call it
571 * when there might be pointers around in unknown places. For now: only
572 * when obj is in the inventory.
577 register struct obj *obj;
579 char *bufp, buf[BUFSZ], bufcpy[BUFSZ], qbuf[QBUFSZ];
583 boolean is_japanese = FALSE;
586 /* Do this now because there's no point in even asking for a name */
587 if (obj->otyp == SPE_NOVEL) {
589 pline("%s already has a published name.", Ysimple_name2(obj));
591 pline("%s
\82É
\82Í
\82·
\82Å
\82É
\8fo
\94Å
\8e\9e\82Ì
\96¼
\91O
\82ª
\82 \82é
\81D", Ysimple_name2(obj));
596 Sprintf(qbuf, "What do you want to name %s ",
597 is_plural(obj) ? "these" : "this");
598 (void) safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item");
600 (void) safe_qbuf(qbuf, "", "
\82ð
\89½
\82Æ
\96¼
\82Ã
\82¯
\82Ü
\82·
\82©
\81H", obj, xname, simpleonames, "item");
603 if (!*buf || *buf == '\033')
605 /* strip leading and trailing spaces; unnames item if all spaces */
606 (void) mungspaces(buf);
608 /* relax restrictions over proper capitalization for artifacts */
609 if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
614 is_japanese = is_kanji(*buf);
619 if (obj->oartifact) {
621 pline_The("artifact seems to resist the attempt.");
623 pline("
\90¹
\8aí
\82Í
\96¼
\82Ã
\82¯
\82ð
\8b\91\94Û
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D");
625 } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
626 /* this used to change one letter, substituting a value
627 of 'a' through 'y' (due to an off by one error, 'z'
628 would never be selected) and then force that to
629 upper case if such was the case of the input;
630 now, the hand slip scuffs one or two letters as if
631 the text had been trodden upon, sometimes picking
632 punctuation instead of an arbitrary letter;
633 unfortunately, we have to cover the possibility of
634 it targetting spaces so failing to make any change
635 (we know that it must eventually target a nonspace
636 because buf[] matches a valid artifact name) */
638 /* for "the Foo of Bar", only scuff "Foo of Bar" part */
639 bufp = !strncmpi(bufcpy, "the ", 4) ? (buf + 4) : buf;
641 wipeout_text(bufp, rnd(2), (unsigned) 0);
642 } while (!strcmp(buf, bufcpy));
644 pline("While engraving, your %s slips.", body_part(HAND));
646 pline("
\8d\8f\82ñ
\82Å
\82¢
\82é
\8aÔ
\82É%s
\82ª
\8a\8a\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", body_part(HAND));
647 display_nhwindow(WIN_MESSAGE, FALSE);
649 You("engrave: \"%s\".", buf);
651 You("
\8d\8f\82ñ
\82¾:
\81u%s
\81v
\81D",buf);
653 obj = oname(obj, buf);
664 lth = *name ? (int) (strlen(name) + 1) : 0;
668 name = strncpy(buf, name, PL_PSIZ - 1);
669 buf[PL_PSIZ - 1] = '\0';
671 if (is_kanji2(name, lth - 1))
673 name = strncpy(buf, name, lth - 1);
677 /* If named artifact exists in the game, do not create another.
678 * Also trying to create an artifact shouldn't de-artifact
679 * it (e.g. Excalibur from prayer). In this case the object
680 * will retain its current name. */
681 if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
684 new_oname(obj, lth); /* removes old name if one is present */
686 Strcpy(ONAME(obj), name);
689 artifact_exists(obj, name, TRUE);
690 if (obj->oartifact) {
691 /* can't dual-wield with artifact as secondary weapon */
694 /* activate warning if you've just named your weapon "Sting" */
696 set_artifact_intrinsic(obj, TRUE, W_WEP);
697 /* if obj is owned by a shop, increase your bill */
706 static NEARDATA const char callable[] = {
707 SCROLL_CLASS, POTION_CLASS, WAND_CLASS, RING_CLASS, AMULET_CLASS,
708 GEM_CLASS, SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0
712 objtyp_is_callable(i)
715 return (boolean) (objects[i].oc_uname
716 || (OBJ_DESCR(objects[i])
717 && index(callable, objects[i].oc_class)));
720 /* C and #name commands - player can name monster or object or type of obj */
727 menu_item *pick_list = 0;
728 char ch, allowall[2];
729 /* if player wants a,b,c instead of i,o when looting, do that here too */
730 boolean abc = flags.lootabc;
732 win = create_nhwindow(NHW_MENU);
735 any.a_char = 'm'; /* group accelerator 'C' */
736 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'C', ATR_NONE,
738 "a monster", MENU_UNSELECTED);
740 "
\89ö
\95¨", MENU_UNSELECTED);
742 /* we use y and n as accelerators so that we can accept user's
743 response keyed to old "name an individual object?" prompt */
744 any.a_char = 'i'; /* group accelerator 'y' */
745 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'y', ATR_NONE,
747 "a particular object in inventory", MENU_UNSELECTED);
749 "
\8e\9d\82¿
\95¨
\82Ì
\92\86\82Ì
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80", MENU_UNSELECTED);
750 any.a_char = 'o'; /* group accelerator 'n' */
751 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'n', ATR_NONE,
753 "the type of an object in inventory", MENU_UNSELECTED);
755 "
\8e\9d\82¿
\95¨
\82Ì
\92\86\82Ì
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80\82Ì
\8eí
\97Þ", MENU_UNSELECTED);
757 any.a_char = 'f'; /* group accelerator ',' (or ':' instead?) */
758 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, ',', ATR_NONE,
760 "the type of an object upon the floor", MENU_UNSELECTED);
762 "
\8f°
\82Ì
\8fã
\82É
\82 \82é
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80\82Ì
\8eí
\97Þ", MENU_UNSELECTED);
763 any.a_char = 'd'; /* group accelerator '\' */
764 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, '\\', ATR_NONE,
766 "the type of an object on discoveries list", MENU_UNSELECTED);
768 "
\94
\8c©
\95¨
\88ê
\97\97\82É
\82 \82é
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80\82Ì
\8eí
\97Þ", MENU_UNSELECTED);
769 any.a_char = 'a'; /* group accelerator 'l' */
770 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'l', ATR_NONE,
772 "record an annotation for the current level", MENU_UNSELECTED);
774 "
\8c»
\8dÝ
\82Ì
\8aK
\82É
\91Î
\82·
\82é
\83\81\83\82\82Ì
\8bL
\98^", MENU_UNSELECTED);
776 end_menu(win, "What do you want to name?");
778 end_menu(win, "
\82Ç
\82ê
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82Ü
\82·
\82©
\81H");
779 if (select_menu(win, PICK_ONE, &pick_list) > 0) {
780 ch = pick_list[0].item.a_char;
781 free((genericptr_t) pick_list);
784 destroy_nhwindow(win);
790 case 'm': /* name a visible monster */
793 case 'i': /* name an individual object in inventory */
794 allowall[0] = ALL_CLASSES;
796 obj = getobj(allowall, "name");
800 case 'o': /* name a type of object in inventory */
801 obj = getobj(callable, "call");
803 /* behave as if examining it in inventory;
804 this might set dknown if it was picked up
805 while blind and the hero can now see */
810 You("would never recognize another one.");
812 You("
\91¼
\82É
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\81D");
814 } else if (!objtyp_is_callable(obj->otyp)) {
815 You("know those as well as you ever will.");
822 case 'f': /* name a type of object visible on the floor */
825 case 'd': /* name a type of object on the discoveries list */
828 case 'a': /* annotate level */
837 register struct obj *obj;
839 char buf[BUFSZ], qbuf[QBUFSZ];
841 register char **str1;
844 return; /* probably blind */
847 otemp.oextra = (struct oextra *) 0;
849 if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink)
850 /* kludge, meaning it's sink water */
852 Sprintf(qbuf, "Call a stream of %s fluid:",
854 Sprintf(qbuf, "%s
\89t
\91Ì:",
855 OBJ_DESCR(objects[otemp.otyp]));
858 Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
860 Sprintf(qbuf, "%s
\82É
\89½
\82Æ
\96¼
\91O
\82ð
\82Â
\82¯
\82é
\81H", an(xname(&otemp)));
862 if (!*buf || *buf == '\033')
866 str1 = &(objects[obj->otyp].oc_uname);
868 free((genericptr_t) *str1);
870 /* strip leading and trailing spaces; uncalls item if all spaces */
871 (void) mungspaces(buf);
873 if (*str1) { /* had name, so possibly remove from disco[] */
874 /* strip name first, for the update_inventory() call
875 from undiscover_object() */
877 undiscover_object(obj->otyp);
881 discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
892 boolean fakeobj = FALSE, use_plural;
894 cc.x = u.ux, cc.y = u.uy;
895 /* "dot for under/over you" only makes sense when the cursor hasn't
896 been moved off the hero's '@' yet, but there's no way to adjust
897 the help text once getpos() has started */
898 Sprintf(buf, "object on map (or '.' for one %s you)",
899 (u.uundetected && hides_under(youmonst.data)) ? "over" : "under");
900 if (getpos(&cc, FALSE, buf) < 0 || cc.x <= 0)
902 if (cc.x == u.ux && cc.y == u.uy) {
903 obj = vobj_at(u.ux, u.uy);
905 glyph = glyph_at(cc.x, cc.y);
906 if (glyph_is_object(glyph))
907 fakeobj = object_from_map(glyph, cc.x, cc.y, &obj);
908 /* else 'obj' stays null */
911 /* "under you" is safe here since there's no object to hide under */
913 pline("There doesn't seem to be any object %s.",
914 (cc.x == u.ux && cc.y == u.uy) ? "under you" : "there");
916 pline("%s
\82É
\82Í
\89½
\82à
\82È
\82¢
\82æ
\82¤
\82¾
\81D",
917 (cc.x == u.ux && cc.y == u.uy) ? "
\82 \82È
\82½
\82Ì
\89º" : "
\82»
\82±");
921 /* note well: 'obj' might be as instance of STRANGE_OBJECT if target
922 is a mimic; passing that to xname (directly or via simpleonames)
923 would yield "glorkum" so we need to handle it explicitly; it will
924 always fail the Hallucination test and pass the !callable test,
925 resulting in the "can't be assigned a type name" message */
926 Strcpy(buf, (obj->otyp != STRANGE_OBJECT)
928 : obj_descr[STRANGE_OBJECT].oc_name);
929 use_plural = (obj->quan > 1L);
931 const char *unames[6];
934 /* straight role name */
935 unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
938 /* random rank title for hero's role */
939 unames[1] = rank_of(rnd(30), Role_switch, flags.female);
940 /* random fake monster */
941 unames[2] = bogusmon(tmpbuf, (char *) 0);
942 /* increased chance for fake monster */
943 unames[3] = unames[2];
945 unames[4] = roguename();
948 unames[5] = "Wibbly Wobbly";
950 unames[5] = "
\82¤
\82ë
\82¤
\82ë";
952 pline("%s %s to call you \"%s.\"",
953 The(buf), use_plural ? "decide" : "decides",
954 unames[rn2(SIZE(unames))]);
956 pline("%s
\82Í
\82 \82È
\82½
\82ð
\81u%s
\81v
\82Æ
\8cÄ
\82Ô
\82±
\82Æ
\82É
\8c\88\82ß
\82½
\81D",
958 unames[rn2(SIZE(unames))]);
960 } else if (!objtyp_is_callable(obj->otyp)) {
962 pline("%s %s can't be assigned a type name.",
963 use_plural ? "Those" : "That", buf);
965 pline("%s
\82É
\8eí
\97Þ
\82Ì
\96¼
\91O
\82ð
\8a\84\82è
\93\96\82Ä
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
968 } else if (!obj->dknown) {
970 You("don't know %s %s well enough to name %s.",
971 use_plural ? "those" : "that", buf, use_plural ? "them" : "it");
973 You("
\96¼
\91O
\82ð
\95t
\82¯
\82ç
\82ê
\82é
\82Ù
\82Ç%s
\82Ì
\82±
\82Æ
\82ð
\82æ
\82
\92m
\82ç
\82È
\82¢
\81D",
983 static const char *const ghostnames[] = {
984 /* these names should have length < PL_NSIZ */
985 /* Capitalize the names for aesthetics -dgk */
986 "Adri", "Andries", "Andreas", "Bert", "David", "Dirk",
987 "Emile", "Frans", "Fred", "Greg", "Hether", "Jay",
988 "John", "Jon", "Karnov", "Kay", "Kenny", "Kevin",
989 "Maud", "Michiel", "Mike", "Peter", "Robert", "Ron",
990 "Tom", "Wilmar", "Nick Danger", "Phoenix", "Jiro", "Mizue",
991 "Stephan", "Lance Braccus", "Shadowhawk"
994 /* ghost names formerly set by x_monnam(), now by makemon() instead */
998 return rn2(7) ? ghostnames[rn2(SIZE(ghostnames))] : (const char *) plname;
1002 * Monster naming functions:
1003 * x_monnam is the generic monster-naming function.
1004 * seen unseen detected named
1005 * mon_nam: the newt it the invisible orc Fido
1006 * noit_mon_nam:the newt (as if detected) the invisible orc Fido
1007 * l_monnam: newt it invisible orc dog called Fido
1008 * Monnam: The newt It The invisible orc Fido
1009 * noit_Monnam: The newt (as if detected) The invisible orc Fido
1010 * Adjmonnam: The poor newt It The poor invisible orc The poor Fido
1011 * Amonnam: A newt It An invisible orc Fido
1012 * a_monnam: a newt it an invisible orc Fido
1013 * m_monnam: newt xan orc Fido
1014 * y_monnam: your newt your xan your invisible orc Fido
1017 /* Bug: if the monster is a priest or shopkeeper, not every one of these
1018 * options works, since those are special cases.
1021 x_monnam(mtmp, article, adjective, suppress, called)
1022 register struct monst *mtmp;
1024 /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
1025 * ARTICLE_YOUR: "your" on pets, "the" on everything else
1027 * If the monster would be referred to as "it" or if the monster has a name
1028 * _and_ there is no adjective, "invisible", "saddled", etc., override this
1029 * and always use no article.
1031 const char *adjective;
1033 /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
1034 * EXACT_NAME: combination of all the above
1038 char *buf = nextmbuf();
1039 struct permonst *mdat = mtmp->data;
1040 const char *pm_name = mdat->mname;
1041 boolean do_hallu, do_invis, do_it, do_saddle;
1043 boolean name_at_start, has_adjectives;
1047 if (program_state.gameover)
1048 suppress |= SUPPRESS_HALLUCINATION;
1049 if (article == ARTICLE_YOUR && !mtmp->mtame)
1050 article = ARTICLE_THE;
1052 do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION);
1053 do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE);
1054 do_it = !canspotmon(mtmp) && article != ARTICLE_YOUR
1055 && !program_state.gameover && mtmp != u.usteed
1056 && !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
1057 do_saddle = !(suppress & SUPPRESS_SADDLE);
1061 /* unseen monsters, etc. Use "it" */
1066 Strcpy(buf, "
\89½
\8eÒ
\82©");
1070 /* priests and minions: don't even use this function */
1071 if (mtmp->ispriest || mtmp->isminion) {
1072 char priestnambuf[BUFSZ];
1074 long save_prop = EHalluc_resistance;
1075 unsigned save_invis = mtmp->minvis;
1077 /* when true name is wanted, explicitly block Hallucination */
1079 EHalluc_resistance = 1L;
1082 name = priestname(mtmp, priestnambuf);
1083 EHalluc_resistance = save_prop;
1084 mtmp->minvis = save_invis;
1086 if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
1089 return strcpy(buf, name);
1091 /* an "aligned priest" not flagged as a priest or minion should be
1092 "priest" or "priestess" (normally handled by priestname()) */
1093 if (mdat == &mons[PM_ALIGNED_PRIEST])
1095 pm_name = mtmp->female ? "priestess" : "priest";
1097 pm_name = mtmp->female ? "
\93ò
\91m" : "
\91m
\97µ";
1098 else if (mdat == &mons[PM_HIGH_PRIEST] && mtmp->female)
1100 pm_name = "high priestess";
1102 pm_name = "
\96@
\89¤";
1104 /* Shopkeepers: use shopkeeper name. For normal shopkeepers, just
1105 * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
1106 * shopkeeper" or "Asidonhopo the blue dragon". If hallucinating,
1107 * none of this applies.
1109 if (mtmp->isshk && !do_hallu) {
1111 if (adjective && article == ARTICLE_THE) {
1112 /* pathological case: "the angry Asidonhopo the blue dragon"
1114 Strcpy(buf, "the ");
1115 Strcat(strcat(buf, adjective), " ");
1116 Strcat(buf, shkname(mtmp));
1119 Strcat(buf, shkname(mtmp));
1120 if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
1122 Strcat(buf, " the ");
1124 Strcat(buf, "invisible ");
1125 Strcat(buf, pm_name);
1128 if (mdat == &mons[PM_SHOPKEEPER] && !do_invis){
1129 Strcpy(buf, shkname(mtmp));
1131 Sprintf(buf, "%s
\82Æ
\82¢
\82¤
\96¼
\82Ì%s%s",
1132 shkname(mtmp), do_invis ? "
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢" : "",
1139 /* Put the adjectives in the buffer */
1142 Strcat(strcat(buf, adjective), " ");
1144 Strcat(buf, adjective);
1147 Strcat(buf, "invisible ");
1149 Strcat(buf, "
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢");
1150 if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) && !Blind
1153 Strcat(buf, "saddled ");
1155 Strcat(buf, "
\88Æ
\82Ì
\82Â
\82¢
\82Ä
\82¢
\82é");
1158 has_adjectives = TRUE;
1160 has_adjectives = FALSE;
1163 /* Put the actual monster name or type into the buffer now */
1164 /* Be sure to remember whether the buffer starts with a name */
1167 char *rname = rndmonnam(&rnamecode);
1171 name_at_start = bogon_is_pname(rnamecode);
1173 } else if (has_mname(mtmp)) {
1174 char *name = MNAME(mtmp);
1176 if (mdat == &mons[PM_GHOST]) {
1178 Sprintf(eos(buf), "%s ghost", s_suffix(name));
1180 Sprintf(buf, "%s
\82Ì
\97H
\97ì", name);
1182 name_at_start = TRUE;
1184 } else if (called) {
1186 Sprintf(eos(buf), "%s called %s", pm_name, name);
1188 Sprintf(eos(buf), "%s
\82Æ
\82¢
\82¤
\96¼
\82Ì%s", name, pm_name);
1190 name_at_start = (boolean) type_is_pname(mdat);
1192 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Ì
\8f\88\97\9d\82Í
\95s
\97v*/
1193 } else if (is_mplayer(mdat) && (bp = strstri(name, " the ")) != 0) {
1194 /* <name> the <adjective> <invisible> <saddled> <rank> */
1198 pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
1201 Strcat(pbuf, bp + 5); /* append the rest of the name */
1203 article = ARTICLE_NONE;
1204 name_at_start = TRUE;
1209 name_at_start = TRUE;
1212 } else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
1215 Strcpy(pbuf, rank_of((int) mtmp->m_lev, monsndx(mdat),
1216 (boolean) mtmp->female));
1218 Strcat(buf, lcase(pbuf));
1223 name_at_start = FALSE;
1226 Strcat(buf, pm_name);
1228 name_at_start = (boolean) type_is_pname(mdat);
1232 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\8a¥
\8e\8c\82Í
\82È
\82¢*/
1233 if (name_at_start && (article == ARTICLE_YOUR || !has_adjectives)) {
1234 if (mdat == &mons[PM_WIZARD_OF_YENDOR])
1235 article = ARTICLE_THE;
1237 article = ARTICLE_NONE;
1238 } else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
1239 article = ARTICLE_THE;
1247 Strcpy(buf2, "your ");
1252 Strcpy(buf2, "the ");
1272 return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
1273 (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
1280 return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1281 (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
1284 /* print the name as if mon_nam() was called, but assume that the player
1285 * can always see the monster--used for probing and for monsters aggravating
1286 * the player with a cursed potion of invisibility
1292 return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1293 (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
1302 register char *bp = mon_nam(mtmp);
1312 register char *bp = noit_mon_nam(mtmp);
1318 /* monster's own name */
1323 return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, EXACT_NAME, FALSE);
1326 /* pet name: "your little dog" */
1331 int prefix, suppression_flag;
1333 prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
1334 suppression_flag = (has_mname(mtmp)
1335 /* "saddled" is redundant when mounted */
1336 || mtmp == u.usteed)
1340 return x_monnam(mtmp, prefix, (char *) 0, suppression_flag, FALSE);
1344 Adjmonnam(mtmp, adj)
1348 char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
1349 has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1359 return x_monnam(mtmp, ARTICLE_A, (char *) 0,
1360 has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1367 char *bp = a_monnam(mtmp);
1373 /* used for monster ID by the '/', ';', and 'C' commands to block remote
1374 identification of the endgame altars via their attending priests */
1376 distant_monnam(mon, article, outbuf)
1378 int article; /* only ARTICLE_NONE and ARTICLE_THE are handled here */
1381 /* high priest(ess)'s identity is concealed on the Astral Plane,
1382 unless you're adjacent (overridden for hallucination which does
1383 its own obfuscation) */
1384 if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination
1385 && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
1387 Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
1388 Strcat(outbuf, mon->female ? "high priestess" : "high priest");
1390 Strcpy(outbuf, "
\96@
\89¤");
1393 Strcpy(outbuf, x_monnam(mon, article, (char *) 0, 0, TRUE));
1398 /* fake monsters used to be in a hard-coded array, now in a data file */
1405 get_rnd_text(BOGUSMONFILE, buf);
1406 /* strip prefix if present */
1407 if (!letter(*mname)) {
1418 /* return a random monster name, for hallucination */
1423 static char buf[BUFSZ];
1426 #define BOGUSMONSIZE 100 /* arbitrary */
1432 name = rn1(SPECIAL_PM + BOGUSMONSIZE - LOW_PM, LOW_PM);
1433 } while (name < SPECIAL_PM
1434 && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
1436 if (name >= SPECIAL_PM) {
1437 mname = bogusmon(buf, code);
1439 mname = strcpy(buf, mons[name].mname);
1445 /* check bogusmon prefix to decide whether it's a personal name */
1447 bogon_is_pname(code)
1452 return index("-+=", code) ? TRUE : FALSE;
1455 /* name of a Rogue player */
1461 if ((opts = nh_getenv("ROGUEOPTS")) != 0) {
1462 for (i = opts; *i; i++)
1463 if (!strncmp("name=", i, 5)) {
1465 if ((j = index(i + 5, ',')) != 0)
1470 return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
1474 static NEARDATA const char *const hcolors[] = {
1476 "ultraviolet", "infrared", "bluish-orange", "reddish-green", "dark white",
1477 "light black", "sky blue-pink", "salty", "sweet", "sour", "bitter",
1478 "striped", "spiral", "swirly", "plaid", "checkered", "argyle", "paisley",
1479 "blotchy", "guernsey-spotted", "polka-dotted", "square", "round",
1480 "triangular", "cabernet", "sangria", "fuchsia", "wisteria", "lemon-lime",
1481 "strawberry-banana", "peppermint", "romantic", "incandescent",
1482 "octarine", /* Discworld: the Colour of Magic */
1484 "
\8e\87\8aO
\90F
\82Ì", "
\90Ô
\8aO
\90F
\82Ì", "
\90Â
\90F
\82ª
\82©
\82Á
\82½
\83I
\83\8c\83\93\83W
\90F
\82Ì", "
\90Ô
\82Ý
\82ª
\82©
\82Á
\82½
\97Î
\90F
\82Ì", "
\88Ã
\82¢
\94\92\90F
\82Ì",
1485 "
\96¾
\82é
\82¢
\8d\95\82Ì", "
\90\85\90F
\82ª
\82©
\82Á
\82½
\83s
\83\93\83N
\90F
\82Ì", "
\89\96\90h
\82¢", "
\8aÃ
\82¢", "
\82·
\82Á
\82Ï
\82¢", "
\8bê
\82¢",
1486 "
\82µ
\82Ü
\96Í
\97l
\82Ì", "
\82ç
\82¹
\82ñ
\8fó
\82Ì", "
\94g
\8fó
\82Ì", "
\8ai
\8eq
\96Í
\97l
\8fó
\82Ì", "
\83`
\83F
\83b
\83N
\8fó
\82Ì", "
\95ú
\8eË
\8fó
\82Ì", "
\83y
\81[
\83Y
\83\8a\81[
\96Í
\97l
\82Ì",
1487 "
\82µ
\82Ý
\8fó
\82Ì", "
\90Â
\90F
\82Ì
\94Á
\93_
\8fó
\82Ì", "
\93_
\8fó
\82Ì", "
\8el
\8ap
\8c`
\8fó
\82Ì", "
\8aÛ
\8fó
\82Ì",
1488 "
\8eO
\8ap
\8fó
\82Ì", "
\83J
\83x
\83\8b\83l
\90F
\82Ì", "
\83T
\83\93\83O
\83\8a\83A
\90F
\82Ì", "
\91N
\82â
\82©
\82È
\90Ô
\8e\87\90F
\82Ì", "
\93¡
\90F
\82Ì", "
\83\8c\83\82\83\93\83\89\83C
\83\80\90F
\82Ì",
1489 "ä
\95\83o
\83i
\83i
\90F
\82Ì", "
\83y
\83p
\81[
\83~
\83\93\83g
\90F
\82Ì", "
\83\8d\83}
\83\93\83`
\83b
\83N
\82È
\90F
\82Ì", "
\94\92\94M
\90F
\82Ì",
1490 "
\83I
\83N
\83^
\83\8a\83\93\90F
\82Ì",
1496 const char *colorpref;
1498 return (Hallucination || !colorpref) ? hcolors[rn2(SIZE(hcolors))]
1502 /* return a random real color unless hallucinating */
1506 int k = rn2(CLR_MAX);
1508 return Hallucination ? hcolor((char *) 0)
1510 : (k == NO_COLOR) ? "colorless"
1512 : (k == NO_COLOR) ? "
\96³
\90F
\82Ì"
1516 /* Aliases for road-runner nemesis
1518 static const char *const coynames[] = {
1519 "Carnivorous Vulgaris", "Road-Runnerus Digestus", "Eatibus Anythingus",
1520 "Famishus-Famishus", "Eatibus Almost Anythingus", "Eatius Birdius",
1521 "Famishius Fantasticus", "Eternalii Famishiis", "Famishus Vulgarus",
1522 "Famishius Vulgaris Ingeniusi", "Eatius-Slobbius", "Hardheadipus Oedipus",
1523 "Carnivorous Slobbius", "Hard-Headipus Ravenus", "Evereadii Eatibus",
1524 "Apetitius Giganticus", "Hungrii Flea-Bagius", "Overconfidentii Vulgaris",
1525 "Caninus Nervous Rex", "Grotesques Appetitus", "Nemesis Ridiculii",
1530 coyotename(mtmp, buf)
1535 Sprintf(buf, "%s - %s",
1536 x_monnam(mtmp, ARTICLE_NONE, (char *) 0, 0, TRUE),
1537 mtmp->mcan ? coynames[SIZE(coynames) - 1]
1538 : coynames[rn2(SIZE(coynames) - 1)]);
1543 /* make sure "The Colour of Magic" remains the first entry in here */
1544 static const char *const sir_Terry_novels[] = {
1545 "The Colour of Magic", "The Light Fantastic", "Equal Rites", "Mort",
1546 "Sourcery", "Wyrd Sisters", "Pyramids", "Guards! Guards!", "Eric",
1547 "Moving Pictures", "Reaper Man", "Witches Abroad", "Small Gods",
1548 "Lords and Ladies", "Men at Arms", "Soul Music", "Interesting Times",
1549 "Maskerade", "Feet of Clay", "Hogfather", "Jingo", "The Last Continent",
1550 "Carpe Jugulum", "The Fifth Elephant", "The Truth", "Thief of Time",
1551 "The Last Hero", "The Amazing Maurice and his Educated Rodents",
1552 "Night Watch", "The Wee Free Men", "Monstrous Regiment",
1553 "A Hat Full of Sky", "Going Postal", "Thud!", "Wintersmith",
1554 "Making Money", "Unseen Academicals", "I Shall Wear Midnight", "Snuff",
1555 "Raising Steam", "The Shepherd's Crown"
1562 int j, k = SIZE(sir_Terry_novels);
1568 else if (*novidx >= 0 && *novidx < k)
1571 return sir_Terry_novels[j];
1575 lookup_novel(lookname, idx)
1576 const char *lookname;
1581 /* Take American or U.K. spelling of this one */
1582 if (!strcmpi(The(lookname), "The Color of Magic"))
1583 lookname = sir_Terry_novels[0];
1585 for (k = 0; k < SIZE(sir_Terry_novels); ++k) {
1586 if (!strcmpi(lookname, sir_Terry_novels[k])
1587 || !strcmpi(The(lookname), sir_Terry_novels[k])) {
1590 return sir_Terry_novels[k];
1593 /* name not found; if novelidx is already set, override the name */
1594 if (idx && *idx >= 0 && *idx < SIZE(sir_Terry_novels))
1595 return sir_Terry_novels[*idx];
1597 return (const char *) 0;