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;
122 goal = "desired location";
125 pline("(For instructions type a ?)");
127 pline("(?
\82Å
\83w
\83\8b\83v)");
135 curs(WIN_MAP, cx, cy);
138 lock_mouse_cursor(TRUE);
142 pline("Move cursor to %s:", goal);
143 curs(WIN_MAP, cx, cy);
145 show_goal_msg = FALSE;
146 } else if (auto_msg && !msg_given && !hilite_state) {
150 const char *firstmatch = NULL;
154 if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
156 curs(WIN_MAP, cx, cy);
161 c = nh_poskey(&tx, &ty, &sidx);
164 (*getpos_hilitefunc)(2);
165 hilite_state = FALSE;
166 curs(WIN_MAP, cx, cy);
175 msg_given = TRUE; /* force clear */
182 /* a mouse click event, just assign and return */
187 if ((cp = index(pick_chars, c)) != 0) {
188 /* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
189 result = (int) (cp - pick_chars);
192 for (i = 0; i < 8; i++) {
195 if (Cmd.dirchars[i] == c) {
196 /* a normal movement letter or digit */
199 } else if (Cmd.alphadirchars[i] == lowc((char) c)
200 || (Cmd.num_pad && Cmd.dirchars[i] == (c & 0177))) {
201 /* a shifted movement letter or Meta-digit */
207 /* truncate at map edge; diagonal moves complicate this... */
209 dy -= sgn(dy) * (1 - (cx + dx));
210 dx = 1 - cx; /* so that (cx+dx == 1) */
211 } else if (cx + dx > COLNO - 1) {
212 dy += sgn(dy) * ((COLNO - 1) - (cx + dx));
213 dx = (COLNO - 1) - cx;
216 dx -= sgn(dx) * (0 - (cy + dy));
217 dy = 0 - cy; /* so that (cy+dy == 0) */
218 } else if (cy + dy > ROWNO - 1) {
219 dx += sgn(dx) * ((ROWNO - 1) - (cy + dy));
220 dy = (ROWNO - 1) - cy;
227 if (c == '?' || redraw_cmd(c)) {
229 getpos_help(force, goal);
231 docrt(); /* redraw */
232 /* update message window to reflect that we're still targetting */
233 show_goal_msg = TRUE;
235 } else if ((c == '$') && (getpos_hilitefunc != NULL)) {
237 (*getpos_hilitefunc)(0);
238 (*getpos_hilitefunc)(1);
242 } else if (c == '#') {
243 auto_msg = !auto_msg;
244 pline("Automatic description %sis %s.",
245 flags.verbose ? "of features under cursor " : "",
246 auto_msg ? "on" : "off");
248 show_goal_msg = TRUE;
251 } else if (c == '@') {
256 if (!index(quitchars, c)) {
257 char matching[MAXPCHARS];
258 int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
259 (void) memset((genericptr_t) matching, 0, sizeof matching);
260 for (sidx = 1; sidx < MAXPCHARS; sidx++)
261 if (c == defsyms[sidx].sym || c == (int) showsyms[sidx])
262 matching[sidx] = (char) ++k;
264 for (pass = 0; pass <= 1; pass++) {
265 /* pass 0: just past current pos to lower right;
266 pass 1: upper left corner to current pos */
267 lo_y = (pass == 0) ? cy : 0;
268 hi_y = (pass == 0) ? ROWNO - 1 : cy;
269 for (ty = lo_y; ty <= hi_y; ty++) {
270 lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
271 hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
272 for (tx = lo_x; tx <= hi_x; tx++) {
273 /* look at dungeon feature, not at
274 * user-visible glyph */
275 k = back_to_glyph(tx, ty);
276 /* uninteresting background glyph */
278 && (IS_DOOR(levl[tx][ty].typ)
279 || glyph_to_cmap(k) == S_room
280 || glyph_to_cmap(k) == S_darkroom
281 || glyph_to_cmap(k) == S_corr
282 || glyph_to_cmap(k) == S_litcorr)) {
283 /* what hero remembers to be at tx,ty */
284 k = glyph_at(tx, ty);
287 && matching[glyph_to_cmap(k)]
288 && levl[tx][ty].seenv
289 && (!IS_WALL(levl[tx][ty].typ))
290 && (levl[tx][ty].typ != SDOOR)
291 && glyph_to_cmap(k) != S_room
292 && glyph_to_cmap(k) != S_corr
293 && glyph_to_cmap(k) != S_litcorr) {
296 clear_nhwindow(WIN_MESSAGE);
305 pline("Can't find dungeon feature '%c'.", c);
307 pline("'%c'
\81H", c);
315 Strcpy(note, "aborted");
317 Strcpy(note, "
\92\86\92f
\82µ
\82½");
320 Sprintf(note, "use %c%c%c%c or .", /* hjkl */
322 Sprintf(note, "%c%c%c%c
\82Å
\88Ú
\93®
\81C.
\82Å
\8fI
\97¹", /* hjkl */
324 Cmd.move_W, Cmd.move_S, Cmd.move_N,
327 pline("Unknown direction: '%s' (%s).", visctrl((char) c),
329 pline("
\82»
\82Ì
\95û
\8cü
\82Í
\82È
\82¢
\81F'%s' (%s)", visctrl((char) c),
332 } /* k => matching */
339 pline("
\88È
\8fã
\81D");
340 msg_given = FALSE; /* suppress clear */
343 result = 0; /* not -1 */
351 curs(WIN_MAP, cx, cy);
355 lock_mouse_cursor(FALSE);
358 clear_nhwindow(WIN_MESSAGE);
361 getpos_hilitefunc = NULL;
365 /* allocate space for a monster's name; removes old name if there is one */
369 int lth; /* desired length (caller handles adding 1 for terminator) */
372 /* allocate mextra if necessary; otherwise get rid of old name */
374 mon->mextra = newmextra();
376 free_mname(mon); /* already has mextra, might also have name */
377 MNAME(mon) = (char *) alloc((unsigned) lth);
379 /* zero length: the new name is empty; get rid of the old name */
385 /* release a monster's name; retains mextra even if all fields are now null */
390 if (has_mname(mon)) {
391 free((genericptr_t) MNAME(mon));
392 MNAME(mon) = (char *) 0;
396 /* allocate space for an object's name; removes old name if there is one */
400 int lth; /* desired length (caller handles adding 1 for terminator) */
403 /* allocate oextra if necessary; otherwise get rid of old name */
405 obj->oextra = newoextra();
407 free_oname(obj); /* already has oextra, might also have name */
408 ONAME(obj) = (char *) alloc((unsigned) lth);
410 /* zero length: the new name is empty; get rid of the old name */
416 /* release an object's name; retains oextra even if all fields are now null */
421 if (has_oname(obj)) {
422 free((genericptr_t) ONAME(obj));
423 ONAME(obj) = (char *) 0;
427 /* safe_oname() always returns a valid pointer to
428 * a string, either the pointer to an object's name
429 * if it has one, or a pointer to an empty string
441 /* historical note: this returns a monster pointer because it used to
442 allocate a new bigger block of memory to hold the monster and its name */
444 christen_monst(mtmp, name)
451 /* dogname & catname are PL_PSIZ arrays; object names have same limit */
452 lth = (name && *name) ? ((int) strlen(name) + 1) : 0;
455 if (is_kanji2(buf, lth - 1))
459 name = strncpy(buf, name, PL_PSIZ - 1);
460 buf[PL_PSIZ - 1] = '\0';
462 new_mname(mtmp, lth); /* removes old name if one is present */
464 Strcpy(MNAME(mtmp), name);
468 /* allow player to assign a name to some chosen monster */
472 char buf[BUFSZ], monnambuf[BUFSZ];
475 register struct monst *mtmp;
480 You("would never recognize it anyway.");
482 You("
\82»
\82ê
\82ð
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\81D");
488 if (getpos(&cc, FALSE, "the monster you want to name") < 0
490 if (getpos(&cc, FALSE, "
\82 \82È
\82½
\82ª
\96¼
\82Ã
\82¯
\82½
\82¢
\89ö
\95¨") < 0
495 if (cx == u.ux && cy == u.uy) {
496 if (u.usteed && canspotmon(u.usteed))
500 pline("This %s creature is called %s and cannot be renamed.",
502 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",
503 beautiful(), plname);
511 && (!(cansee(cx, cy) || see_with_infrared(mtmp))
512 || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE
513 || mtmp->m_ap_type == M_AP_OBJECT
514 || (mtmp->minvis && !See_invisible)))) {
516 pline("I see no monster there.");
518 pline("
\82»
\82±
\82É
\89ö
\95¨
\82Í
\82¢
\82È
\82¢
\81D");
521 /* special case similar to the one in lookat() */
523 Sprintf(qbuf, "What do you want to call %s?",
525 Sprintf(qbuf, "%s
\82ð
\89½
\82Æ
\8cÄ
\82Ñ
\82Ü
\82·
\82©
\81H",
526 distant_monnam(mtmp, ARTICLE_THE, monnambuf));
528 if (!*buf || *buf == '\033')
530 /* strip leading and trailing spaces; unnames monster if all spaces */
531 (void) mungspaces(buf);
533 /* unique monsters have their own specific names or titles;
534 shopkeepers, temple priests and other minions use alternate
535 name formatting routines which ignore any user-supplied name */
536 if (mtmp->data->geno & G_UNIQ)
538 pline("%s doesn't like being called names!", upstart(monnambuf));
540 pline("%s
\82Í
\82 \82¾
\96¼
\82Å
\8cÄ
\82Î
\82ê
\82é
\82Ì
\82ª
\8c\99\82¢
\82È
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
542 && !(Deaf || mtmp->msleeping || !mtmp->mcanmove
543 || mtmp->data->msound <= MS_ANIMAL))
545 verbalize("I'm %s, not %s.", shkname(mtmp), buf);
547 verbalize("
\8e\84\82Í%s
\82¾
\81C%s
\82Å
\82Í
\82È
\82¢
\81D", shkname(mtmp), buf);
548 else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk)
550 pline("%s will not accept the name %s.", upstart(monnambuf), buf);
552 pline("%s
\82Í%s
\82Æ
\82¢
\82¤
\96¼
\91O
\82ð
\8eó
\82¯
\82¢
\82ê
\82È
\82©
\82Á
\82½
\81D", monnambuf, buf);
554 (void) christen_monst(mtmp, buf);
558 * This routine changes the address of obj. Be careful not to call it
559 * when there might be pointers around in unknown places. For now: only
560 * when obj is in the inventory.
565 register struct obj *obj;
567 char *bufp, buf[BUFSZ], bufcpy[BUFSZ], qbuf[QBUFSZ];
571 boolean is_japanese = FALSE;
574 /* Do this now because there's no point in even asking for a name */
575 if (obj->otyp == SPE_NOVEL) {
577 pline("%s already has a published name.", Ysimple_name2(obj));
579 pline("%s
\82É
\82Í
\82·
\82Å
\82É
\8fo
\94Å
\8e\9e\82Ì
\96¼
\91O
\82ª
\82 \82é
\81D", Ysimple_name2(obj));
584 Sprintf(qbuf, "What do you want to name %s ",
585 is_plural(obj) ? "these" : "this");
586 (void) safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item");
588 (void) safe_qbuf(qbuf, "", "
\82ð
\89½
\82Æ
\96¼
\82Ã
\82¯
\82Ü
\82·
\82©
\81H", obj, xname, simpleonames, "item");
591 if (!*buf || *buf == '\033')
593 /* strip leading and trailing spaces; unnames item if all spaces */
594 (void) mungspaces(buf);
596 /* relax restrictions over proper capitalization for artifacts */
597 if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
602 is_japanese = is_kanji(*buf);
607 if (obj->oartifact) {
609 pline_The("artifact seems to resist the attempt.");
611 pline("
\90¹
\8aí
\82Í
\96¼
\82Ã
\82¯
\82ð
\8b\91\94Û
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D");
613 } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
614 /* this used to change one letter, substituting a value
615 of 'a' through 'y' (due to an off by one error, 'z'
616 would never be selected) and then force that to
617 upper case if such was the case of the input;
618 now, the hand slip scuffs one or two letters as if
619 the text had been trodden upon, sometimes picking
620 punctuation instead of an arbitrary letter;
621 unfortunately, we have to cover the possibility of
622 it targetting spaces so failing to make any change
623 (we know that it must eventually target a nonspace
624 because buf[] matches a valid artifact name) */
626 /* for "the Foo of Bar", only scuff "Foo of Bar" part */
627 bufp = !strncmpi(bufcpy, "the ", 4) ? (buf + 4) : buf;
629 wipeout_text(bufp, rnd(2), (unsigned) 0);
630 } while (!strcmp(buf, bufcpy));
632 pline("While engraving, your %s slips.", body_part(HAND));
634 pline("
\8d\8f\82ñ
\82Å
\82¢
\82é
\8aÔ
\82É%s
\82ª
\8a\8a\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", body_part(HAND));
635 display_nhwindow(WIN_MESSAGE, FALSE);
637 You("engrave: \"%s\".", buf);
639 You("
\8d\8f\82ñ
\82¾:
\81u%s
\81v
\81D",buf);
641 obj = oname(obj, buf);
652 lth = *name ? (int) (strlen(name) + 1) : 0;
656 name = strncpy(buf, name, PL_PSIZ - 1);
657 buf[PL_PSIZ - 1] = '\0';
659 if (is_kanji2(name, lth - 1))
661 name = strncpy(buf, name, lth - 1);
665 /* If named artifact exists in the game, do not create another.
666 * Also trying to create an artifact shouldn't de-artifact
667 * it (e.g. Excalibur from prayer). In this case the object
668 * will retain its current name. */
669 if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
672 new_oname(obj, lth); /* removes old name if one is present */
674 Strcpy(ONAME(obj), name);
677 artifact_exists(obj, name, TRUE);
678 if (obj->oartifact) {
679 /* can't dual-wield with artifact as secondary weapon */
682 /* activate warning if you've just named your weapon "Sting" */
684 set_artifact_intrinsic(obj, TRUE, W_WEP);
685 /* if obj is owned by a shop, increase your bill */
694 static NEARDATA const char callable[] = {
695 SCROLL_CLASS, POTION_CLASS, WAND_CLASS, RING_CLASS, AMULET_CLASS,
696 GEM_CLASS, SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0
700 objtyp_is_callable(i)
703 return (boolean) (objects[i].oc_uname
704 || (OBJ_DESCR(objects[i])
705 && index(callable, objects[i].oc_class)));
708 /* C and #name commands - player can name monster or object or type of obj */
715 menu_item *pick_list = 0;
716 char ch, allowall[2];
717 /* if player wants a,b,c instead of i,o when looting, do that here too */
718 boolean abc = flags.lootabc;
720 win = create_nhwindow(NHW_MENU);
723 any.a_char = 'm'; /* group accelerator 'C' */
724 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'C', ATR_NONE,
726 "a monster", MENU_UNSELECTED);
728 "
\89ö
\95¨", MENU_UNSELECTED);
730 /* we use y and n as accelerators so that we can accept user's
731 response keyed to old "name an individual object?" prompt */
732 any.a_char = 'i'; /* group accelerator 'y' */
733 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'y', ATR_NONE,
735 "a particular object in inventory", MENU_UNSELECTED);
737 "
\8e\9d\82¿
\95¨
\82Ì
\92\86\82Ì
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80", MENU_UNSELECTED);
738 any.a_char = 'o'; /* group accelerator 'n' */
739 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'n', ATR_NONE,
741 "the type of an object in inventory", MENU_UNSELECTED);
743 "
\8e\9d\82¿
\95¨
\82Ì
\92\86\82Ì
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80\82Ì
\8eí
\97Þ", MENU_UNSELECTED);
745 any.a_char = 'f'; /* group accelerator ',' (or ':' instead?) */
746 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, ',', ATR_NONE,
748 "the type of an object upon the floor", MENU_UNSELECTED);
750 "
\8f°
\82Ì
\8fã
\82É
\82 \82é
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80\82Ì
\8eí
\97Þ", MENU_UNSELECTED);
751 any.a_char = 'd'; /* group accelerator '\' */
752 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, '\\', ATR_NONE,
754 "the type of an object on discoveries list", MENU_UNSELECTED);
756 "
\94
\8c©
\95¨
\88ê
\97\97\82É
\82 \82é
\88ê
\82Â
\82Ì
\83A
\83C
\83e
\83\80\82Ì
\8eí
\97Þ", MENU_UNSELECTED);
757 any.a_char = 'a'; /* group accelerator 'l' */
758 add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'l', ATR_NONE,
760 "record an annotation for the current level", MENU_UNSELECTED);
762 "
\8c»
\8dÝ
\82Ì
\8aK
\82É
\91Î
\82·
\82é
\83\81\83\82\82Ì
\8bL
\98^", MENU_UNSELECTED);
764 end_menu(win, "What do you want to name?");
766 end_menu(win, "
\82Ç
\82ê
\82É
\96¼
\91O
\82ð
\82Â
\82¯
\82Ü
\82·
\82©
\81H");
767 if (select_menu(win, PICK_ONE, &pick_list) > 0) {
768 ch = pick_list[0].item.a_char;
769 free((genericptr_t) pick_list);
772 destroy_nhwindow(win);
778 case 'm': /* name a visible monster */
781 case 'i': /* name an individual object in inventory */
782 allowall[0] = ALL_CLASSES;
784 obj = getobj(allowall, "name");
788 case 'o': /* name a type of object in inventory */
789 obj = getobj(callable, "call");
791 /* behave as if examining it in inventory;
792 this might set dknown if it was picked up
793 while blind and the hero can now see */
798 You("would never recognize another one.");
800 You("
\91¼
\82É
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\81D");
802 } else if (!objtyp_is_callable(obj->otyp)) {
803 You("know those as well as you ever will.");
810 case 'f': /* name a type of object visible on the floor */
813 case 'd': /* name a type of object on the discoveries list */
816 case 'a': /* annotate level */
825 register struct obj *obj;
827 char buf[BUFSZ], qbuf[QBUFSZ];
829 register char **str1;
832 return; /* probably blind */
835 otemp.oextra = (struct oextra *) 0;
837 if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink)
838 /* kludge, meaning it's sink water */
840 Sprintf(qbuf, "Call a stream of %s fluid:",
842 Sprintf(qbuf, "%s
\89t
\91Ì:",
843 OBJ_DESCR(objects[otemp.otyp]));
846 Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
848 Sprintf(qbuf, "%s
\82É
\89½
\82Æ
\96¼
\91O
\82ð
\82Â
\82¯
\82é
\81H", an(xname(&otemp)));
850 if (!*buf || *buf == '\033')
854 str1 = &(objects[obj->otyp].oc_uname);
856 free((genericptr_t) *str1);
858 /* strip leading and trailing spaces; uncalls item if all spaces */
859 (void) mungspaces(buf);
861 if (*str1) { /* had name, so possibly remove from disco[] */
862 /* strip name first, for the update_inventory() call
863 from undiscover_object() */
865 undiscover_object(obj->otyp);
869 discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
880 boolean fakeobj = FALSE, use_plural;
882 cc.x = u.ux, cc.y = u.uy;
883 /* "dot for under/over you" only makes sense when the cursor hasn't
884 been moved off the hero's '@' yet, but there's no way to adjust
885 the help text once getpos() has started */
886 Sprintf(buf, "object on map (or '.' for one %s you)",
887 (u.uundetected && hides_under(youmonst.data)) ? "over" : "under");
888 if (getpos(&cc, FALSE, buf) < 0 || cc.x <= 0)
890 if (cc.x == u.ux && cc.y == u.uy) {
891 obj = vobj_at(u.ux, u.uy);
893 glyph = glyph_at(cc.x, cc.y);
894 if (glyph_is_object(glyph))
895 fakeobj = object_from_map(glyph, cc.x, cc.y, &obj);
896 /* else 'obj' stays null */
899 /* "under you" is safe here since there's no object to hide under */
900 pline("There doesn't seem to be any object %s.",
901 (cc.x == u.ux && cc.y == u.uy) ? "under you" : "there");
904 /* note well: 'obj' might be as instance of STRANGE_OBJECT if target
905 is a mimic; passing that to xname (directly or via simpleonames)
906 would yield "glorkum" so we need to handle it explicitly; it will
907 always fail the Hallucination test and pass the !callable test,
908 resulting in the "can't be assigned a type name" message */
909 Strcpy(buf, (obj->otyp != STRANGE_OBJECT)
911 : obj_descr[STRANGE_OBJECT].oc_name);
912 use_plural = (obj->quan > 1L);
914 const char *unames[6];
917 /* straight role name */
918 unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
921 /* random rank title for hero's role */
922 unames[1] = rank_of(rnd(30), Role_switch, flags.female);
923 /* random fake monster */
924 unames[2] = bogusmon(tmpbuf, (char *) 0);
925 /* increased chance for fake monster */
926 unames[3] = unames[2];
928 unames[4] = roguename();
930 unames[5] = "Wibbly Wobbly";
931 pline("%s %s to call you \"%s.\"",
932 The(buf), use_plural ? "decide" : "decides",
933 unames[rn2(SIZE(unames))]);
934 } else if (!objtyp_is_callable(obj->otyp)) {
935 pline("%s %s can't be assigned a type name.",
936 use_plural ? "Those" : "That", buf);
937 } else if (!obj->dknown) {
938 You("don't know %s %s well enough to name %s.",
939 use_plural ? "those" : "that", buf, use_plural ? "them" : "it");
947 static const char *const ghostnames[] = {
948 /* these names should have length < PL_NSIZ */
949 /* Capitalize the names for aesthetics -dgk */
950 "Adri", "Andries", "Andreas", "Bert", "David", "Dirk",
951 "Emile", "Frans", "Fred", "Greg", "Hether", "Jay",
952 "John", "Jon", "Karnov", "Kay", "Kenny", "Kevin",
953 "Maud", "Michiel", "Mike", "Peter", "Robert", "Ron",
954 "Tom", "Wilmar", "Nick Danger", "Phoenix", "Jiro", "Mizue",
955 "Stephan", "Lance Braccus", "Shadowhawk"
958 /* ghost names formerly set by x_monnam(), now by makemon() instead */
962 return rn2(7) ? ghostnames[rn2(SIZE(ghostnames))] : (const char *) plname;
966 * Monster naming functions:
967 * x_monnam is the generic monster-naming function.
968 * seen unseen detected named
969 * mon_nam: the newt it the invisible orc Fido
970 * noit_mon_nam:the newt (as if detected) the invisible orc Fido
971 * l_monnam: newt it invisible orc dog called Fido
972 * Monnam: The newt It The invisible orc Fido
973 * noit_Monnam: The newt (as if detected) The invisible orc Fido
974 * Adjmonnam: The poor newt It The poor invisible orc The poor Fido
975 * Amonnam: A newt It An invisible orc Fido
976 * a_monnam: a newt it an invisible orc Fido
977 * m_monnam: newt xan orc Fido
978 * y_monnam: your newt your xan your invisible orc Fido
981 /* Bug: if the monster is a priest or shopkeeper, not every one of these
982 * options works, since those are special cases.
985 x_monnam(mtmp, article, adjective, suppress, called)
986 register struct monst *mtmp;
988 /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
989 * ARTICLE_YOUR: "your" on pets, "the" on everything else
991 * If the monster would be referred to as "it" or if the monster has a name
992 * _and_ there is no adjective, "invisible", "saddled", etc., override this
993 * and always use no article.
995 const char *adjective;
997 /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
998 * EXACT_NAME: combination of all the above
1002 char *buf = nextmbuf();
1003 struct permonst *mdat = mtmp->data;
1004 const char *pm_name = mdat->mname;
1005 boolean do_hallu, do_invis, do_it, do_saddle;
1007 boolean name_at_start, has_adjectives;
1011 if (program_state.gameover)
1012 suppress |= SUPPRESS_HALLUCINATION;
1013 if (article == ARTICLE_YOUR && !mtmp->mtame)
1014 article = ARTICLE_THE;
1016 do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION);
1017 do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE);
1018 do_it = !canspotmon(mtmp) && article != ARTICLE_YOUR
1019 && !program_state.gameover && mtmp != u.usteed
1020 && !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
1021 do_saddle = !(suppress & SUPPRESS_SADDLE);
1025 /* unseen monsters, etc. Use "it" */
1030 Strcpy(buf, "
\89½
\8eÒ
\82©");
1034 /* priests and minions: don't even use this function */
1035 if (mtmp->ispriest || mtmp->isminion) {
1036 char priestnambuf[BUFSZ];
1038 long save_prop = EHalluc_resistance;
1039 unsigned save_invis = mtmp->minvis;
1041 /* when true name is wanted, explicitly block Hallucination */
1043 EHalluc_resistance = 1L;
1046 name = priestname(mtmp, priestnambuf);
1047 EHalluc_resistance = save_prop;
1048 mtmp->minvis = save_invis;
1050 if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
1053 return strcpy(buf, name);
1055 /* an "aligned priest" not flagged as a priest or minion should be
1056 "priest" or "priestess" (normally handled by priestname()) */
1057 if (mdat == &mons[PM_ALIGNED_PRIEST])
1058 pm_name = mtmp->female ? "priestess" : "priest";
1059 else if (mdat == &mons[PM_HIGH_PRIEST] && mtmp->female)
1060 pm_name = "high priestess";
1062 /* Shopkeepers: use shopkeeper name. For normal shopkeepers, just
1063 * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
1064 * shopkeeper" or "Asidonhopo the blue dragon". If hallucinating,
1065 * none of this applies.
1067 if (mtmp->isshk && !do_hallu) {
1069 if (adjective && article == ARTICLE_THE) {
1070 /* pathological case: "the angry Asidonhopo the blue dragon"
1072 Strcpy(buf, "the ");
1073 Strcat(strcat(buf, adjective), " ");
1074 Strcat(buf, shkname(mtmp));
1077 Strcat(buf, shkname(mtmp));
1078 if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
1080 Strcat(buf, " the ");
1082 Strcat(buf, "invisible ");
1083 Strcat(buf, pm_name);
1086 if (mdat == &mons[PM_SHOPKEEPER] && !do_invis){
1087 Strcpy(buf, shkname(mtmp));
1089 Sprintf(buf, "%s
\82Æ
\82¢
\82¤
\96¼
\82Ì%s%s",
1090 shkname(mtmp), do_invis ? "
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢" : "",
1097 /* Put the adjectives in the buffer */
1100 Strcat(strcat(buf, adjective), " ");
1102 Strcat(buf, adjective);
1105 Strcat(buf, "invisible ");
1107 Strcat(buf, "
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢");
1108 if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) && !Blind
1111 Strcat(buf, "saddled ");
1113 Strcat(buf, "
\88Æ
\82Ì
\82Â
\82¢
\82Ä
\82¢
\82é");
1116 has_adjectives = TRUE;
1118 has_adjectives = FALSE;
1121 /* Put the actual monster name or type into the buffer now */
1122 /* Be sure to remember whether the buffer starts with a name */
1125 char *rname = rndmonnam(&rnamecode);
1129 name_at_start = bogon_is_pname(rnamecode);
1131 } else if (has_mname(mtmp)) {
1132 char *name = MNAME(mtmp);
1134 if (mdat == &mons[PM_GHOST]) {
1136 Sprintf(eos(buf), "%s ghost", s_suffix(name));
1138 Sprintf(buf, "%s
\82Ì
\97H
\97ì", name);
1140 name_at_start = TRUE;
1142 } else if (called) {
1144 Sprintf(eos(buf), "%s called %s", pm_name, name);
1146 Sprintf(eos(buf), "%s
\82Æ
\82¢
\82¤
\96¼
\82Ì%s", name, pm_name);
1148 name_at_start = (boolean) type_is_pname(mdat);
1150 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Ì
\8f\88\97\9d\82Í
\95s
\97v*/
1151 } else if (is_mplayer(mdat) && (bp = strstri(name, " the ")) != 0) {
1152 /* <name> the <adjective> <invisible> <saddled> <rank> */
1156 pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
1159 Strcat(pbuf, bp + 5); /* append the rest of the name */
1161 article = ARTICLE_NONE;
1162 name_at_start = TRUE;
1167 name_at_start = TRUE;
1170 } else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
1173 Strcpy(pbuf, rank_of((int) mtmp->m_lev, monsndx(mdat),
1174 (boolean) mtmp->female));
1176 Strcat(buf, lcase(pbuf));
1181 name_at_start = FALSE;
1184 Strcat(buf, pm_name);
1186 name_at_start = (boolean) type_is_pname(mdat);
1190 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\8a¥
\8e\8c\82Í
\82È
\82¢*/
1191 if (name_at_start && (article == ARTICLE_YOUR || !has_adjectives)) {
1192 if (mdat == &mons[PM_WIZARD_OF_YENDOR])
1193 article = ARTICLE_THE;
1195 article = ARTICLE_NONE;
1196 } else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
1197 article = ARTICLE_THE;
1205 Strcpy(buf2, "your ");
1210 Strcpy(buf2, "the ");
1230 return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
1231 (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
1238 return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1239 (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
1242 /* print the name as if mon_nam() was called, but assume that the player
1243 * can always see the monster--used for probing and for monsters aggravating
1244 * the player with a cursed potion of invisibility
1250 return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1251 (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
1260 register char *bp = mon_nam(mtmp);
1270 register char *bp = noit_mon_nam(mtmp);
1276 /* monster's own name */
1281 return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, EXACT_NAME, FALSE);
1284 /* pet name: "your little dog" */
1289 int prefix, suppression_flag;
1291 prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
1292 suppression_flag = (has_mname(mtmp)
1293 /* "saddled" is redundant when mounted */
1294 || mtmp == u.usteed)
1298 return x_monnam(mtmp, prefix, (char *) 0, suppression_flag, FALSE);
1302 Adjmonnam(mtmp, adj)
1306 char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
1307 has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1317 return x_monnam(mtmp, ARTICLE_A, (char *) 0,
1318 has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1325 char *bp = a_monnam(mtmp);
1331 /* used for monster ID by the '/', ';', and 'C' commands to block remote
1332 identification of the endgame altars via their attending priests */
1334 distant_monnam(mon, article, outbuf)
1336 int article; /* only ARTICLE_NONE and ARTICLE_THE are handled here */
1339 /* high priest(ess)'s identity is concealed on the Astral Plane,
1340 unless you're adjacent (overridden for hallucination which does
1341 its own obfuscation) */
1342 if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination
1343 && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
1345 Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
1346 Strcat(outbuf, mon->female ? "high priestess" : "high priest");
1348 Strcpy(outbuf, "
\96@
\89¤");
1351 Strcpy(outbuf, x_monnam(mon, article, (char *) 0, 0, TRUE));
1356 /* fake monsters used to be in a hard-coded array, now in a data file */
1363 get_rnd_text(BOGUSMONFILE, buf);
1364 /* strip prefix if present */
1365 if (!letter(*mname)) {
1376 /* return a random monster name, for hallucination */
1381 static char buf[BUFSZ];
1384 #define BOGUSMONSIZE 100 /* arbitrary */
1390 name = rn1(SPECIAL_PM + BOGUSMONSIZE - LOW_PM, LOW_PM);
1391 } while (name < SPECIAL_PM
1392 && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
1394 if (name >= SPECIAL_PM) {
1395 mname = bogusmon(buf, code);
1397 mname = strcpy(buf, mons[name].mname);
1403 /* check bogusmon prefix to decide whether it's a personal name */
1405 bogon_is_pname(code)
1410 return index("-+=", code) ? TRUE : FALSE;
1413 /* name of a Rogue player */
1419 if ((opts = nh_getenv("ROGUEOPTS")) != 0) {
1420 for (i = opts; *i; i++)
1421 if (!strncmp("name=", i, 5)) {
1423 if ((j = index(i + 5, ',')) != 0)
1428 return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
1432 static NEARDATA const char *const hcolors[] = {
1434 "ultraviolet", "infrared", "bluish-orange", "reddish-green", "dark white",
1435 "light black", "sky blue-pink", "salty", "sweet", "sour", "bitter",
1436 "striped", "spiral", "swirly", "plaid", "checkered", "argyle", "paisley",
1437 "blotchy", "guernsey-spotted", "polka-dotted", "square", "round",
1438 "triangular", "cabernet", "sangria", "fuchsia", "wisteria", "lemon-lime",
1439 "strawberry-banana", "peppermint", "romantic", "incandescent",
1440 "octarine", /* Discworld: the Colour of Magic */
1442 "
\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Ì",
1443 "
\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¢",
1444 "
\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Ì",
1445 "
\82µ
\82Ý
\8fó
\82Ì", "
\90Â
\90F
\82Ì
\94Á
\93_
\8fó
\82Ì", "
\93_
\8fó
\82Ì", "
\8el
\8ap
\8c`
\8fó
\82Ì", "
\8aÛ
\8fó
\82Ì",
1446 "
\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Ì",
1447 "ä
\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Ì",
1448 "
\83I
\83N
\83^
\83\8a\83\93\90F
\82Ì",
1454 const char *colorpref;
1456 return (Hallucination || !colorpref) ? hcolors[rn2(SIZE(hcolors))]
1460 /* return a random real color unless hallucinating */
1464 int k = rn2(CLR_MAX);
1466 return Hallucination ? hcolor((char *) 0)
1468 : (k == NO_COLOR) ? "colorless"
1470 : (k == NO_COLOR) ? "
\96³
\90F
\82Ì"
1474 /* Aliases for road-runner nemesis
1476 static const char *const coynames[] = {
1477 "Carnivorous Vulgaris", "Road-Runnerus Digestus", "Eatibus Anythingus",
1478 "Famishus-Famishus", "Eatibus Almost Anythingus", "Eatius Birdius",
1479 "Famishius Fantasticus", "Eternalii Famishiis", "Famishus Vulgarus",
1480 "Famishius Vulgaris Ingeniusi", "Eatius-Slobbius", "Hardheadipus Oedipus",
1481 "Carnivorous Slobbius", "Hard-Headipus Ravenus", "Evereadii Eatibus",
1482 "Apetitius Giganticus", "Hungrii Flea-Bagius", "Overconfidentii Vulgaris",
1483 "Caninus Nervous Rex", "Grotesques Appetitus", "Nemesis Ridiculii",
1488 coyotename(mtmp, buf)
1493 Sprintf(buf, "%s - %s",
1494 x_monnam(mtmp, ARTICLE_NONE, (char *) 0, 0, TRUE),
1495 mtmp->mcan ? coynames[SIZE(coynames) - 1]
1496 : coynames[rn2(SIZE(coynames) - 1)]);
1501 /* make sure "The Colour of Magic" remains the first entry in here */
1502 static const char *const sir_Terry_novels[] = {
1503 "The Colour of Magic", "The Light Fantastic", "Equal Rites", "Mort",
1504 "Sourcery", "Wyrd Sisters", "Pyramids", "Guards! Guards!", "Eric",
1505 "Moving Pictures", "Reaper Man", "Witches Abroad", "Small Gods",
1506 "Lords and Ladies", "Men at Arms", "Soul Music", "Interesting Times",
1507 "Maskerade", "Feet of Clay", "Hogfather", "Jingo", "The Last Continent",
1508 "Carpe Jugulum", "The Fifth Elephant", "The Truth", "Thief of Time",
1509 "The Last Hero", "The Amazing Maurice and his Educated Rodents",
1510 "Night Watch", "The Wee Free Men", "Monstrous Regiment",
1511 "A Hat Full of Sky", "Going Postal", "Thud!", "Wintersmith",
1512 "Making Money", "Unseen Academicals", "I Shall Wear Midnight", "Snuff",
1513 "Raising Steam", "The Shepherd's Crown"
1520 int j, k = SIZE(sir_Terry_novels);
1526 else if (*novidx >= 0 && *novidx < k)
1529 return sir_Terry_novels[j];
1533 lookup_novel(lookname, idx)
1534 const char *lookname;
1539 /* Take American or U.K. spelling of this one */
1540 if (!strcmpi(The(lookname), "The Color of Magic"))
1541 lookname = sir_Terry_novels[0];
1543 for (k = 0; k < SIZE(sir_Terry_novels); ++k) {
1544 if (!strcmpi(lookname, sir_Terry_novels[k])
1545 || !strcmpi(The(lookname), sir_Terry_novels[k])) {
1548 return sir_Terry_novels[k];
1551 /* name not found; if novelidx is already set, override the name */
1552 if (idx && *idx >= 0 && *idx < SIZE(sir_Terry_novels))
1553 return sir_Terry_novels[*idx];
1555 return (const char *) 0;