OSDN Git Service

patch artifact
[jnethack/source.git] / src / do_name.c
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. */
4
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. */
9
10 #include "hack.h"
11
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 *));
18
19 extern const char what_is_an_unknown_object[]; /* from pager.c */
20
21 #define NUMMBUF 5
22
23 /* manage a pool of BUFSZ buffers, so callers don't have to */
24 STATIC_OVL char *
25 nextmbuf()
26 {
27     static char NEARDATA bufs[NUMMBUF][BUFSZ];
28     static int bufidx = 0;
29
30     bufidx = (bufidx + 1) % NUMMBUF;
31     return bufs[bufidx];
32 }
33
34 /* function for getpos() to highlight desired map locations.
35  * parameter value 0 = initialize, 1 = highlight, 2 = done
36  */
37 void FDECL((*getpos_hilitefunc), (int)) = (void FDECL((*), (int))) 0;
38
39 void
40 getpos_sethilite(f)
41 void FDECL((*f), (int));
42 {
43     getpos_hilitefunc = f;
44 }
45
46 /* the response for '?' help request in getpos() */
47 STATIC_OVL void
48 getpos_help(force, goal)
49 boolean force;
50 const char *goal;
51 {
52     char sbuf[BUFSZ];
53     boolean doing_what_is;
54     winid tmpwin = create_nhwindow(NHW_MENU);
55
56 #if 0 /*JP*/
57     Sprintf(sbuf, "Use [%c%c%c%c] to move the cursor to %s.", /* hjkl */
58 #else
59     Sprintf(sbuf, "[%c%c%c%c]\82Å%s\82Ö\88Ú\93®\82Å\82«\82é\81D",
60 #endif
61             Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, goal);
62     putstr(tmpwin, 0, sbuf);
63 /*JP
64     putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
65 */
66     putstr(tmpwin, 0, "[HJKL]\82Å\88ê\93x\82É8\95à\88Ú\93®\82Å\82«\82é\81D");
67 /*JP
68     putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
69 */
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");
71 /*JP
72     putstr(tmpwin, 0, "Use @ to move the cursor on yourself.");
73 */
74     putstr(tmpwin, 0, "@\82Å\8e©\95ª\8e©\90g\82Ì\88Ê\92u\82É\88Ú\93®\82·\82é\81D");
75     if (getpos_hilitefunc != NULL)
76 /*JP
77         putstr(tmpwin, 0, "Use $ to display valid locations.");
78 */
79         putstr(tmpwin, 0, "$\82Å\89Â\94\\82È\88Ê\92u\82ð\95\\8e¦\82·\82é\81D");
80 /*JP
81     putstr(tmpwin, 0, "Use # to toggle automatic description.");
82 */
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);
87 #if 0 /*JP:T*/
88     Sprintf(sbuf, "Type a .%s when you are at the right place.",
89             doing_what_is ? " or , or ; or :" : "");
90 #else
91     Sprintf(sbuf, "[.]%s\82Å\8c\88\92è\81D",
92             doing_what_is ? "[,][;][:]" : "");
93 #endif
94     putstr(tmpwin, 0, sbuf);
95     if (!force)
96 /*JP
97         putstr(tmpwin, 0, "Type Space or Escape when you're done.");
98 */
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);
103 }
104
105 int
106 getpos(ccp, force, goal)
107 coord *ccp;
108 boolean force;
109 const char *goal;
110 {
111     int result = 0;
112     int cx, cy, i, c;
113     int sidx, tx, ty;
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[] = ".,;:";
118     const char *cp;
119     boolean hilite_state = FALSE;
120
121     if (!goal)
122         goal = "desired location";
123     if (flags.verbose) {
124 /*JP
125         pline("(For instructions type a ?)");
126 */
127         pline("(?\82Å\83w\83\8b\83v)");
128         msg_given = TRUE;
129     }
130     cx = ccp->x;
131     cy = ccp->y;
132 #ifdef CLIPPING
133     cliparound(cx, cy);
134 #endif
135     curs(WIN_MAP, cx, cy);
136     flush_screen(0);
137 #ifdef MAC
138     lock_mouse_cursor(TRUE);
139 #endif
140     for (;;) {
141         if (show_goal_msg) {
142             pline("Move cursor to %s:", goal);
143             curs(WIN_MAP, cx, cy);
144             flush_screen(0);
145             show_goal_msg = FALSE;
146         } else if (auto_msg && !msg_given && !hilite_state) {
147             coord cc;
148             int sym = 0;
149             char tmpbuf[BUFSZ];
150             const char *firstmatch = NULL;
151
152             cc.x = cx;
153             cc.y = cy;
154             if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
155                 pline1(firstmatch);
156                 curs(WIN_MAP, cx, cy);
157                 flush_screen(0);
158             }
159         }
160
161         c = nh_poskey(&tx, &ty, &sidx);
162
163         if (hilite_state) {
164             (*getpos_hilitefunc)(2);
165             hilite_state = FALSE;
166             curs(WIN_MAP, cx, cy);
167             flush_screen(0);
168         }
169
170         if (auto_msg)
171             msg_given = FALSE;
172
173         if (c == '\033') {
174             cx = cy = -10;
175             msg_given = TRUE; /* force clear */
176             result = -1;
177             break;
178         }
179         if (c == 0) {
180             if (!isok(tx, ty))
181                 continue;
182             /* a mouse click event, just assign and return */
183             cx = tx;
184             cy = ty;
185             break;
186         }
187         if ((cp = index(pick_chars, c)) != 0) {
188             /* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
189             result = (int) (cp - pick_chars);
190             break;
191         }
192         for (i = 0; i < 8; i++) {
193             int dx, dy;
194
195             if (Cmd.dirchars[i] == c) {
196                 /* a normal movement letter or digit */
197                 dx = xdir[i];
198                 dy = ydir[i];
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 */
202                 dx = 8 * xdir[i];
203                 dy = 8 * ydir[i];
204             } else
205                 continue;
206
207             /* truncate at map edge; diagonal moves complicate this... */
208             if (cx + dx < 1) {
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;
214             }
215             if (cy + dy < 0) {
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;
221             }
222             cx += dx;
223             cy += dy;
224             goto nxtc;
225         }
226
227         if (c == '?' || redraw_cmd(c)) {
228             if (c == '?')
229                 getpos_help(force, goal);
230             else         /* ^R */
231                 docrt(); /* redraw */
232             /* update message window to reflect that we're still targetting */
233             show_goal_msg = TRUE;
234             msg_given = TRUE;
235         } else if ((c == '$') && (getpos_hilitefunc != NULL)) {
236             if (!hilite_state) {
237                 (*getpos_hilitefunc)(0);
238                 (*getpos_hilitefunc)(1);
239                 hilite_state = TRUE;
240             }
241             goto nxtc;
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");
247             if (!auto_msg)
248                 show_goal_msg = TRUE;
249             msg_given = TRUE;
250             goto nxtc;
251         } else if (c == '@') {
252             cx = u.ux;
253             cy = u.uy;
254             goto nxtc;
255         } else {
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;
263                 if (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 */
277                                 if (glyph_is_cmap(k)
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);
285                                 }
286                                 if (glyph_is_cmap(k)
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) {
294                                     cx = tx, cy = ty;
295                                     if (msg_given) {
296                                         clear_nhwindow(WIN_MESSAGE);
297                                         msg_given = FALSE;
298                                     }
299                                     goto nxtc;
300                                 }
301                             } /* column */
302                         }     /* row */
303                     }         /* pass */
304 /*JP
305                     pline("Can't find dungeon feature '%c'.", c);
306 */
307                     pline("'%c'\81H", c);
308                     msg_given = TRUE;
309                     goto nxtc;
310                 } else {
311                     char note[QBUFSZ];
312
313                     if (!force)
314 /*JP
315                         Strcpy(note, "aborted");
316 */
317                         Strcpy(note, "\92\86\92f\82µ\82½");
318                     else
319 #if 0 /*JP*/
320                         Sprintf(note, "use %c%c%c%c or .", /* hjkl */
321 #else
322                         Sprintf(note, "%c%c%c%c\82Å\88Ú\93®\81C.\82Å\8fI\97¹", /* hjkl */
323 #endif
324                                 Cmd.move_W, Cmd.move_S, Cmd.move_N,
325                                 Cmd.move_E);
326 /*JP
327                     pline("Unknown direction: '%s' (%s).", visctrl((char) c),
328 */
329                     pline("\82»\82Ì\95û\8cü\82Í\82È\82¢\81F'%s' (%s)", visctrl((char) c),
330                           note);
331                     msg_given = TRUE;
332                 } /* k => matching */
333             }     /* !quitchars */
334             if (force)
335                 goto nxtc;
336 /*JP
337             pline("Done.");
338 */
339             pline("\88È\8fã\81D");
340             msg_given = FALSE; /* suppress clear */
341             cx = -1;
342             cy = 0;
343             result = 0; /* not -1 */
344             break;
345         }
346     nxtc:
347         ;
348 #ifdef CLIPPING
349         cliparound(cx, cy);
350 #endif
351         curs(WIN_MAP, cx, cy);
352         flush_screen(0);
353     }
354 #ifdef MAC
355     lock_mouse_cursor(FALSE);
356 #endif
357     if (msg_given)
358         clear_nhwindow(WIN_MESSAGE);
359     ccp->x = cx;
360     ccp->y = cy;
361     getpos_hilitefunc = NULL;
362     return result;
363 }
364
365 /* allocate space for a monster's name; removes old name if there is one */
366 void
367 new_mname(mon, lth)
368 struct monst *mon;
369 int lth; /* desired length (caller handles adding 1 for terminator) */
370 {
371     if (lth) {
372         /* allocate mextra if necessary; otherwise get rid of old name */
373         if (!mon->mextra)
374             mon->mextra = newmextra();
375         else
376             free_mname(mon); /* already has mextra, might also have name */
377         MNAME(mon) = (char *) alloc((unsigned) lth);
378     } else {
379         /* zero length: the new name is empty; get rid of the old name */
380         if (has_mname(mon))
381             free_mname(mon);
382     }
383 }
384
385 /* release a monster's name; retains mextra even if all fields are now null */
386 void
387 free_mname(mon)
388 struct monst *mon;
389 {
390     if (has_mname(mon)) {
391         free((genericptr_t) MNAME(mon));
392         MNAME(mon) = (char *) 0;
393     }
394 }
395
396 /* allocate space for an object's name; removes old name if there is one */
397 void
398 new_oname(obj, lth)
399 struct obj *obj;
400 int lth; /* desired length (caller handles adding 1 for terminator) */
401 {
402     if (lth) {
403         /* allocate oextra if necessary; otherwise get rid of old name */
404         if (!obj->oextra)
405             obj->oextra = newoextra();
406         else
407             free_oname(obj); /* already has oextra, might also have name */
408         ONAME(obj) = (char *) alloc((unsigned) lth);
409     } else {
410         /* zero length: the new name is empty; get rid of the old name */
411         if (has_oname(obj))
412             free_oname(obj);
413     }
414 }
415
416 /* release an object's name; retains oextra even if all fields are now null */
417 void
418 free_oname(obj)
419 struct obj *obj;
420 {
421     if (has_oname(obj)) {
422         free((genericptr_t) ONAME(obj));
423         ONAME(obj) = (char *) 0;
424     }
425 }
426
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
430  *  if it doesn't.
431  */
432 const char *
433 safe_oname(obj)
434 struct obj *obj;
435 {
436     if (has_oname(obj))
437         return ONAME(obj);
438     return "";
439 }
440
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 */
443 struct monst *
444 christen_monst(mtmp, name)
445 struct monst *mtmp;
446 const char *name;
447 {
448     int lth;
449     char buf[PL_PSIZ];
450
451     /* dogname & catname are PL_PSIZ arrays; object names have same limit */
452     lth = (name && *name) ? ((int) strlen(name) + 1) : 0;
453     if (lth > PL_PSIZ) {
454 #if 1 /*JP*/
455         if (is_kanji2(buf, lth - 1))
456             --lth;
457 #endif
458         lth = PL_PSIZ;
459         name = strncpy(buf, name, PL_PSIZ - 1);
460         buf[PL_PSIZ - 1] = '\0';
461     }
462     new_mname(mtmp, lth); /* removes old name if one is present */
463     if (lth)
464         Strcpy(MNAME(mtmp), name);
465     return mtmp;
466 }
467
468 /* allow player to assign a name to some chosen monster */
469 STATIC_OVL void
470 do_mname()
471 {
472     char buf[BUFSZ], monnambuf[BUFSZ];
473     coord cc;
474     register int cx, cy;
475     register struct monst *mtmp;
476     char qbuf[QBUFSZ];
477
478     if (Hallucination) {
479 /*JP
480         You("would never recognize it anyway.");
481 */
482         You("\82»\82ê\82ð\94F\8e¯\82Å\82«\82È\82¢\81D");
483         return;
484     }
485     cc.x = u.ux;
486     cc.y = u.uy;
487 /*JP
488     if (getpos(&cc, FALSE, "the monster you want to name") < 0
489 */
490     if (getpos(&cc, FALSE, "\82 \82È\82½\82ª\96¼\82Ã\82¯\82½\82¢\89ö\95¨") < 0
491         || (cx = cc.x) < 0)
492         return;
493     cy = cc.y;
494
495     if (cx == u.ux && cy == u.uy) {
496         if (u.usteed && canspotmon(u.usteed))
497             mtmp = u.usteed;
498         else {
499 /*JP
500             pline("This %s creature is called %s and cannot be renamed.",
501 */
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);
504             return;
505         }
506     } else
507         mtmp = m_at(cx, cy);
508
509     if (!mtmp
510         || (!sensemon(mtmp)
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)))) {
515 /*JP
516         pline("I see no monster there.");
517 */
518         pline("\82»\82±\82É\89ö\95¨\82Í\82¢\82È\82¢\81D");
519         return;
520     }
521     /* special case similar to the one in lookat() */
522 /*JP
523     Sprintf(qbuf, "What do you want to call %s?",
524 */
525     Sprintf(qbuf, "%s\82ð\89½\82Æ\8cÄ\82Ñ\82Ü\82·\82©\81H",
526             distant_monnam(mtmp, ARTICLE_THE, monnambuf));
527     getlin(qbuf, buf);
528     if (!*buf || *buf == '\033')
529         return;
530     /* strip leading and trailing spaces; unnames monster if all spaces */
531     (void) mungspaces(buf);
532
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)
537 /*JP
538         pline("%s doesn't like being called names!", upstart(monnambuf));
539 */
540         pline("%s\82Í\82 \82¾\96¼\82Å\8cÄ\82Î\82ê\82é\82Ì\82ª\8c\99\82¢\82È\82æ\82¤\82¾\81I", Monnam(mtmp));
541     else if (mtmp->isshk
542              && !(Deaf || mtmp->msleeping || !mtmp->mcanmove
543                   || mtmp->data->msound <= MS_ANIMAL))
544 /*JP
545         verbalize("I'm %s, not %s.", shkname(mtmp), buf);
546 */
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)
549 /*JP
550         pline("%s will not accept the name %s.", upstart(monnambuf), buf);
551 */
552         pline("%s\82Í%s\82Æ\82¢\82¤\96¼\91O\82ð\8eó\82¯\82¢\82ê\82È\82©\82Á\82½\81D", monnambuf, buf);
553     else
554         (void) christen_monst(mtmp, buf);
555 }
556
557 /*
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.
561  */
562 STATIC_OVL
563 void
564 do_oname(obj)
565 register struct obj *obj;
566 {
567     char *bufp, buf[BUFSZ], bufcpy[BUFSZ], qbuf[QBUFSZ];
568     const char *aname;
569     short objtyp;
570 #if 1 /*JP*/
571     boolean is_japanese = FALSE;
572 #endif
573
574     /* Do this now because there's no point in even asking for a name */
575     if (obj->otyp == SPE_NOVEL) {
576 /*JP
577         pline("%s already has a published name.", Ysimple_name2(obj));
578 */
579         pline("%s\82É\82Í\82·\82Å\82É\8fo\94Å\8e\9e\82Ì\96¼\91O\82ª\82 \82é\81D", Ysimple_name2(obj));
580         return;
581     }
582
583 #if 0 /*JP*/
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");
587 #else
588     (void) safe_qbuf(qbuf, "", "\82ð\89½\82Æ\96¼\82Ã\82¯\82Ü\82·\82©\81H", obj, xname, simpleonames, "item");
589 #endif
590     getlin(qbuf, buf);
591     if (!*buf || *buf == '\033')
592         return;
593     /* strip leading and trailing spaces; unnames item if all spaces */
594     (void) mungspaces(buf);
595
596     /* relax restrictions over proper capitalization for artifacts */
597     if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
598 #if 0 /*JP*/
599         Strcpy(buf, aname);
600 #else
601         {
602             is_japanese = is_kanji(*buf);
603             Strcpy(buf, aname);
604         }
605 #endif
606
607     if (obj->oartifact) {
608 /*JP
609         pline_The("artifact seems to resist the attempt.");
610 */
611         pline("\90¹\8aí\82Í\96¼\82Ã\82¯\82ð\8b\91\94Û\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D");
612         return;
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) */
625         Strcpy(bufcpy, buf);
626         /* for "the Foo of Bar", only scuff "Foo of Bar" part */
627         bufp = !strncmpi(bufcpy, "the ", 4) ? (buf + 4) : buf;
628         do {
629             wipeout_text(bufp, rnd(2), (unsigned) 0);
630         } while (!strcmp(buf, bufcpy));
631 /*JP
632         pline("While engraving, your %s slips.", body_part(HAND));
633 */
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);
636 /*JP
637         You("engrave: \"%s\".", buf);
638 */
639         You("\8d\8f\82ñ\82¾: \81u%s\81v\81D",buf);
640     }
641     obj = oname(obj, buf);
642 }
643
644 struct obj *
645 oname(obj, name)
646 struct obj *obj;
647 const char *name;
648 {
649     int lth;
650     char buf[PL_PSIZ];
651
652     lth = *name ? (int) (strlen(name) + 1) : 0;
653     if (lth > PL_PSIZ) {
654         lth = PL_PSIZ;
655 #if 0 /*JP*/
656         name = strncpy(buf, name, PL_PSIZ - 1);
657         buf[PL_PSIZ - 1] = '\0';
658 #else
659         if (is_kanji2(name, lth - 1))
660             --lth;
661         name = strncpy(buf, name, lth - 1);
662         buf[lth - 1] = '\0';
663 #endif
664     }
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)))
670         return obj;
671
672     new_oname(obj, lth); /* removes old name if one is present */
673     if (lth)
674         Strcpy(ONAME(obj), name);
675
676     if (lth)
677         artifact_exists(obj, name, TRUE);
678     if (obj->oartifact) {
679         /* can't dual-wield with artifact as secondary weapon */
680         if (obj == uswapwep)
681             untwoweapon();
682         /* activate warning if you've just named your weapon "Sting" */
683         if (obj == uwep)
684             set_artifact_intrinsic(obj, TRUE, W_WEP);
685         /* if obj is owned by a shop, increase your bill */
686         if (obj->unpaid)
687             alter_cost(obj, 0L);
688     }
689     if (carried(obj))
690         update_inventory();
691     return obj;
692 }
693
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
697 };
698
699 boolean
700 objtyp_is_callable(i)
701 int i;
702 {
703     return (boolean) (objects[i].oc_uname
704                       || (OBJ_DESCR(objects[i])
705                           && index(callable, objects[i].oc_class)));
706 }
707
708 /* C and #name commands - player can name monster or object or type of obj */
709 int
710 docallcmd()
711 {
712     struct obj *obj;
713     winid win;
714     anything any;
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;
719
720     win = create_nhwindow(NHW_MENU);
721     start_menu(win);
722     any = zeroany;
723     any.a_char = 'm'; /* group accelerator 'C' */
724     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'C', ATR_NONE,
725 /*JP
726              "a monster", MENU_UNSELECTED);
727 */
728              "\89ö\95¨", MENU_UNSELECTED);
729     if (invent) {
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,
734 /*JP
735                  "a particular object in inventory", MENU_UNSELECTED);
736 */
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,
740 /*JP
741                  "the type of an object in inventory", MENU_UNSELECTED);
742 */
743                  "\8e\9d\82¿\95¨\82Ì\92\86\82Ì\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
744     }
745     any.a_char = 'f'; /* group accelerator ',' (or ':' instead?) */
746     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, ',', ATR_NONE,
747 /*JP
748              "the type of an object upon the floor", MENU_UNSELECTED);
749 */
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,
753 /*JP
754              "the type of an object on discoveries list", MENU_UNSELECTED);
755 */
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,
759 /*JP
760              "record an annotation for the current level", MENU_UNSELECTED);
761 */
762              "\8c»\8dÝ\82Ì\8aK\82É\91Î\82·\82é\83\81\83\82\82Ì\8bL\98^", MENU_UNSELECTED);
763 /*JP
764     end_menu(win, "What do you want to name?");
765 */
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);
770     } else
771         ch = 'q';
772     destroy_nhwindow(win);
773
774     switch (ch) {
775     default:
776     case 'q':
777         break;
778     case 'm': /* name a visible monster */
779         do_mname();
780         break;
781     case 'i': /* name an individual object in inventory */
782         allowall[0] = ALL_CLASSES;
783         allowall[1] = '\0';
784         obj = getobj(allowall, "name");
785         if (obj)
786             do_oname(obj);
787         break;
788     case 'o': /* name a type of object in inventory */
789         obj = getobj(callable, "call");
790         if (obj) {
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 */
794             (void) xname(obj);
795
796             if (!obj->dknown) {
797 /*JP
798                 You("would never recognize another one.");
799 */
800                 You("\91¼\82É\94F\8e¯\82Å\82«\82È\82¢\81D");
801 #if 0
802             } else if (!objtyp_is_callable(obj->otyp)) {
803                 You("know those as well as you ever will.");
804 #endif
805             } else {
806                 docall(obj);
807             }
808         }
809         break;
810     case 'f': /* name a type of object visible on the floor */
811         namefloorobj();
812         break;
813     case 'd': /* name a type of object on the discoveries list */
814         rename_disco();
815         break;
816     case 'a': /* annotate level */
817         donamelevel();
818         break;
819     }
820     return 0;
821 }
822
823 void
824 docall(obj)
825 register struct obj *obj;
826 {
827     char buf[BUFSZ], qbuf[QBUFSZ];
828     struct obj otemp;
829     register char **str1;
830
831     if (!obj->dknown)
832         return; /* probably blind */
833     otemp = *obj;
834     otemp.quan = 1L;
835     otemp.oextra = (struct oextra *) 0;
836
837     if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink)
838         /* kludge, meaning it's sink water */
839 /*JP
840         Sprintf(qbuf, "Call a stream of %s fluid:",
841 */
842         Sprintf(qbuf, "%s\89t\91Ì:",
843                 OBJ_DESCR(objects[otemp.otyp]));
844     else
845 /*JP
846         Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
847 */
848         Sprintf(qbuf, "%s\82É\89½\82Æ\96¼\91O\82ð\82Â\82¯\82é\81H", an(xname(&otemp)));
849     getlin(qbuf, buf);
850     if (!*buf || *buf == '\033')
851         return;
852
853     /* clear old name */
854     str1 = &(objects[obj->otyp].oc_uname);
855     if (*str1)
856         free((genericptr_t) *str1);
857
858     /* strip leading and trailing spaces; uncalls item if all spaces */
859     (void) mungspaces(buf);
860     if (!*buf) {
861         if (*str1) { /* had name, so possibly remove from disco[] */
862             /* strip name first, for the update_inventory() call
863                from undiscover_object() */
864             *str1 = (char *) 0;
865             undiscover_object(obj->otyp);
866         }
867     } else {
868         *str1 = dupstr(buf);
869         discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
870     }
871 }
872
873 STATIC_OVL void
874 namefloorobj()
875 {
876     coord cc;
877     int glyph;
878     char buf[BUFSZ];
879     struct obj *obj = 0;
880     boolean fakeobj = FALSE, use_plural;
881
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)
889         return;
890     if (cc.x == u.ux && cc.y == u.uy) {
891         obj = vobj_at(u.ux, u.uy);
892     } else {
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 */
897     }
898     if (!obj) {
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");
902         return;
903     }
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)
910                  ? simpleonames(obj)
911                  : obj_descr[STRANGE_OBJECT].oc_name);
912     use_plural = (obj->quan > 1L);
913     if (Hallucination) {
914         const char *unames[6];
915         char tmpbuf[BUFSZ];
916
917         /* straight role name */
918         unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
919                      ? urole.name.f
920                      : urole.name.m;
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];
927         /* traditional */
928         unames[4] = roguename();
929         /* silly */
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");
940     } else {
941         docall(obj);
942     }
943     if (fakeobj)
944         dealloc_obj(obj);
945 }
946
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"
956 };
957
958 /* ghost names formerly set by x_monnam(), now by makemon() instead */
959 const char *
960 rndghostname()
961 {
962     return rn2(7) ? ghostnames[rn2(SIZE(ghostnames))] : (const char *) plname;
963 }
964
965 /*
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
979  */
980
981 /* Bug: if the monster is a priest or shopkeeper, not every one of these
982  * options works, since those are special cases.
983  */
984 char *
985 x_monnam(mtmp, article, adjective, suppress, called)
986 register struct monst *mtmp;
987 int article;
988 /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
989  * ARTICLE_YOUR: "your" on pets, "the" on everything else
990  *
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.
994  */
995 const char *adjective;
996 int suppress;
997 /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
998  * EXACT_NAME: combination of all the above
999  */
1000 boolean called;
1001 {
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;
1006 #if 0 /*JP*/
1007     boolean name_at_start, has_adjectives;
1008     char *bp;
1009 #endif
1010
1011     if (program_state.gameover)
1012         suppress |= SUPPRESS_HALLUCINATION;
1013     if (article == ARTICLE_YOUR && !mtmp->mtame)
1014         article = ARTICLE_THE;
1015
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);
1022
1023     buf[0] = '\0';
1024
1025     /* unseen monsters, etc.  Use "it" */
1026     if (do_it) {
1027 /*JP
1028         Strcpy(buf, "it");
1029 */
1030         Strcpy(buf, "\89½\8eÒ\82©");
1031         return buf;
1032     }
1033
1034     /* priests and minions: don't even use this function */
1035     if (mtmp->ispriest || mtmp->isminion) {
1036         char priestnambuf[BUFSZ];
1037         char *name;
1038         long save_prop = EHalluc_resistance;
1039         unsigned save_invis = mtmp->minvis;
1040
1041         /* when true name is wanted, explicitly block Hallucination */
1042         if (!do_hallu)
1043             EHalluc_resistance = 1L;
1044         if (!do_invis)
1045             mtmp->minvis = 0;
1046         name = priestname(mtmp, priestnambuf);
1047         EHalluc_resistance = save_prop;
1048         mtmp->minvis = save_invis;
1049 #if 0 /*JP*/
1050         if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
1051             name += 4;
1052 #endif
1053         return strcpy(buf, name);
1054     }
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";
1061
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.
1066      */
1067     if (mtmp->isshk && !do_hallu) {
1068 #if 0 /*JP*/
1069         if (adjective && article == ARTICLE_THE) {
1070             /* pathological case: "the angry Asidonhopo the blue dragon"
1071                sounds silly */
1072             Strcpy(buf, "the ");
1073             Strcat(strcat(buf, adjective), " ");
1074             Strcat(buf, shkname(mtmp));
1075             return buf;
1076         }
1077         Strcat(buf, shkname(mtmp));
1078         if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
1079             return buf;
1080         Strcat(buf, " the ");
1081         if (do_invis)
1082             Strcat(buf, "invisible ");
1083         Strcat(buf, pm_name);
1084         return buf;
1085 #else
1086         if (mdat == &mons[PM_SHOPKEEPER] && !do_invis){
1087             Strcpy(buf, shkname(mtmp));
1088         } else {
1089             Sprintf(buf, "%s\82Æ\82¢\82¤\96¼\82Ì%s%s",
1090                     shkname(mtmp), do_invis ? "\8ep\82Ì\8c©\82¦\82È\82¢" : "",
1091                     pm_name);
1092         }
1093         return buf;
1094 #endif
1095     }
1096
1097     /* Put the adjectives in the buffer */
1098     if (adjective)
1099 /*JP
1100         Strcat(strcat(buf, adjective), " ");
1101 */
1102         Strcat(buf, adjective);
1103     if (do_invis)
1104 /*JP
1105         Strcat(buf, "invisible ");
1106 */
1107         Strcat(buf, "\8ep\82Ì\8c©\82¦\82È\82¢");
1108     if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) && !Blind
1109         && !Hallucination)
1110 /*JP
1111         Strcat(buf, "saddled ");
1112 */
1113         Strcat(buf, "\88Æ\82Ì\82Â\82¢\82Ä\82¢\82é");
1114 #if 0 /*JP*/
1115     if (buf[0] != 0)
1116         has_adjectives = TRUE;
1117     else
1118         has_adjectives = FALSE;
1119 #endif
1120
1121     /* Put the actual monster name or type into the buffer now */
1122     /* Be sure to remember whether the buffer starts with a name */
1123     if (do_hallu) {
1124         char rnamecode;
1125         char *rname = rndmonnam(&rnamecode);
1126
1127         Strcat(buf, rname);
1128 #if 0 /*JP*/
1129         name_at_start = bogon_is_pname(rnamecode);
1130 #endif
1131     } else if (has_mname(mtmp)) {
1132         char *name = MNAME(mtmp);
1133
1134         if (mdat == &mons[PM_GHOST]) {
1135 /*JP
1136             Sprintf(eos(buf), "%s ghost", s_suffix(name));
1137 */
1138             Sprintf(buf, "%s\82Ì\97H\97ì", name);
1139 #if 0 /*JP*/
1140             name_at_start = TRUE;
1141 #endif
1142         } else if (called) {
1143 /*JP
1144             Sprintf(eos(buf), "%s called %s", pm_name, name);
1145 */
1146             Sprintf(eos(buf), "%s\82Æ\82¢\82¤\96¼\82Ì%s", name, pm_name);
1147 #if 0 /*JP*/
1148             name_at_start = (boolean) type_is_pname(mdat);
1149 #endif
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> */
1153             char pbuf[BUFSZ];
1154
1155             Strcpy(pbuf, name);
1156             pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
1157             if (has_adjectives)
1158                 Strcat(pbuf, buf);
1159             Strcat(pbuf, bp + 5); /* append the rest of the name */
1160             Strcpy(buf, pbuf);
1161             article = ARTICLE_NONE;
1162             name_at_start = TRUE;
1163 #endif
1164         } else {
1165             Strcat(buf, name);
1166 #if 0 /*JP*/
1167             name_at_start = TRUE;
1168 #endif
1169         }
1170     } else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
1171         char pbuf[BUFSZ];
1172
1173         Strcpy(pbuf, rank_of((int) mtmp->m_lev, monsndx(mdat),
1174                              (boolean) mtmp->female));
1175 #if 0 /*JP*/
1176         Strcat(buf, lcase(pbuf));
1177 #else
1178         Strcat(buf, pbuf);
1179 #endif
1180 #if 0 /*JP*/
1181         name_at_start = FALSE;
1182 #endif
1183     } else {
1184         Strcat(buf, pm_name);
1185 #if 0 /*JP*/
1186         name_at_start = (boolean) type_is_pname(mdat);
1187 #endif
1188     }
1189
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;
1194         else
1195             article = ARTICLE_NONE;
1196     } else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
1197         article = ARTICLE_THE;
1198     }
1199
1200     {
1201         char buf2[BUFSZ];
1202
1203         switch (article) {
1204         case ARTICLE_YOUR:
1205             Strcpy(buf2, "your ");
1206             Strcat(buf2, buf);
1207             Strcpy(buf, buf2);
1208             return buf;
1209         case ARTICLE_THE:
1210             Strcpy(buf2, "the ");
1211             Strcat(buf2, buf);
1212             Strcpy(buf, buf2);
1213             return buf;
1214         case ARTICLE_A:
1215             return an(buf);
1216         case ARTICLE_NONE:
1217         default:
1218             return buf;
1219         }
1220     }
1221 #else
1222     return buf;
1223 #endif
1224 }
1225
1226 char *
1227 l_monnam(mtmp)
1228 struct monst *mtmp;
1229 {
1230     return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
1231                     (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
1232 }
1233
1234 char *
1235 mon_nam(mtmp)
1236 struct monst *mtmp;
1237 {
1238     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1239                     (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
1240 }
1241
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
1245  */
1246 char *
1247 noit_mon_nam(mtmp)
1248 struct monst *mtmp;
1249 {
1250     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1251                     (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
1252                                        : SUPPRESS_IT,
1253                     FALSE);
1254 }
1255
1256 char *
1257 Monnam(mtmp)
1258 struct monst *mtmp;
1259 {
1260     register char *bp = mon_nam(mtmp);
1261
1262     *bp = highc(*bp);
1263     return  bp;
1264 }
1265
1266 char *
1267 noit_Monnam(mtmp)
1268 struct monst *mtmp;
1269 {
1270     register char *bp = noit_mon_nam(mtmp);
1271
1272     *bp = highc(*bp);
1273     return  bp;
1274 }
1275
1276 /* monster's own name */
1277 char *
1278 m_monnam(mtmp)
1279 struct monst *mtmp;
1280 {
1281     return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, EXACT_NAME, FALSE);
1282 }
1283
1284 /* pet name: "your little dog" */
1285 char *
1286 y_monnam(mtmp)
1287 struct monst *mtmp;
1288 {
1289     int prefix, suppression_flag;
1290
1291     prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
1292     suppression_flag = (has_mname(mtmp)
1293                         /* "saddled" is redundant when mounted */
1294                         || mtmp == u.usteed)
1295                            ? SUPPRESS_SADDLE
1296                            : 0;
1297
1298     return x_monnam(mtmp, prefix, (char *) 0, suppression_flag, FALSE);
1299 }
1300
1301 char *
1302 Adjmonnam(mtmp, adj)
1303 struct monst *mtmp;
1304 const char *adj;
1305 {
1306     char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
1307                         has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1308
1309     *bp = highc(*bp);
1310     return  bp;
1311 }
1312
1313 char *
1314 a_monnam(mtmp)
1315 struct monst *mtmp;
1316 {
1317     return x_monnam(mtmp, ARTICLE_A, (char *) 0,
1318                     has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1319 }
1320
1321 char *
1322 Amonnam(mtmp)
1323 struct monst *mtmp;
1324 {
1325     char *bp = a_monnam(mtmp);
1326
1327     *bp = highc(*bp);
1328     return  bp;
1329 }
1330
1331 /* used for monster ID by the '/', ';', and 'C' commands to block remote
1332    identification of the endgame altars via their attending priests */
1333 char *
1334 distant_monnam(mon, article, outbuf)
1335 struct monst *mon;
1336 int article; /* only ARTICLE_NONE and ARTICLE_THE are handled here */
1337 char *outbuf;
1338 {
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) {
1344 #if 0 /*JP*/
1345         Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
1346         Strcat(outbuf, mon->female ? "high priestess" : "high priest");
1347 #else
1348         Strcpy(outbuf, "\96@\89¤");
1349 #endif
1350     } else {
1351         Strcpy(outbuf, x_monnam(mon, article, (char *) 0, 0, TRUE));
1352     }
1353     return outbuf;
1354 }
1355
1356 /* fake monsters used to be in a hard-coded array, now in a data file */
1357 STATIC_OVL char *
1358 bogusmon(buf, code)
1359 char *buf, *code;
1360 {
1361     char *mname = buf;
1362
1363     get_rnd_text(BOGUSMONFILE, buf);
1364     /* strip prefix if present */
1365     if (!letter(*mname)) {
1366         if (code)
1367             *code = *mname;
1368         ++mname;
1369     } else {
1370         if (code)
1371             *code = '\0';
1372     }
1373     return mname;
1374 }
1375
1376 /* return a random monster name, for hallucination */
1377 char *
1378 rndmonnam(code)
1379 char *code;
1380 {
1381     static char buf[BUFSZ];
1382     char *mname;
1383     int name;
1384 #define BOGUSMONSIZE 100 /* arbitrary */
1385
1386     if (code)
1387         *code = '\0';
1388
1389     do {
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)));
1393
1394     if (name >= SPECIAL_PM) {
1395         mname = bogusmon(buf, code);
1396     } else {
1397         mname = strcpy(buf, mons[name].mname);
1398     }
1399     return mname;
1400 #undef BOGUSMONSIZE
1401 }
1402
1403 /* check bogusmon prefix to decide whether it's a personal name */
1404 boolean
1405 bogon_is_pname(code)
1406 char code;
1407 {
1408     if (!code)
1409         return FALSE;
1410     return index("-+=", code) ? TRUE : FALSE;
1411 }
1412
1413 /* name of a Rogue player */
1414 const char *
1415 roguename()
1416 {
1417     char *i, *opts;
1418
1419     if ((opts = nh_getenv("ROGUEOPTS")) != 0) {
1420         for (i = opts; *i; i++)
1421             if (!strncmp("name=", i, 5)) {
1422                 char *j;
1423                 if ((j = index(i + 5, ',')) != 0)
1424                     *j = (char) 0;
1425                 return i + 5;
1426             }
1427     }
1428     return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
1429                   : "Glenn Wichman";
1430 }
1431
1432 static NEARDATA const char *const hcolors[] = {
1433 #if 0 /*JP*/
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 */
1441 #else
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Ì",
1449 #endif
1450 };
1451
1452 const char *
1453 hcolor(colorpref)
1454 const char *colorpref;
1455 {
1456     return (Hallucination || !colorpref) ? hcolors[rn2(SIZE(hcolors))]
1457                                          : colorpref;
1458 }
1459
1460 /* return a random real color unless hallucinating */
1461 const char *
1462 rndcolor()
1463 {
1464     int k = rn2(CLR_MAX);
1465
1466     return Hallucination ? hcolor((char *) 0)
1467 /*JP
1468                          : (k == NO_COLOR) ? "colorless"
1469 */
1470                          : (k == NO_COLOR) ? "\96³\90F\82Ì"
1471                                            : c_obj_colors[k];
1472 }
1473
1474 /* Aliases for road-runner nemesis
1475  */
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",
1484     "Canis latrans"
1485 };
1486
1487 char *
1488 coyotename(mtmp, buf)
1489 struct monst *mtmp;
1490 char *buf;
1491 {
1492     if (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)]);
1497     }
1498     return buf;
1499 }
1500
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"
1514 };
1515
1516 const char *
1517 noveltitle(novidx)
1518 int *novidx;
1519 {
1520     int j, k = SIZE(sir_Terry_novels);
1521
1522     j = rn2(k);
1523     if (novidx) {
1524         if (*novidx == -1)
1525             *novidx = j;
1526         else if (*novidx >= 0 && *novidx < k)
1527             j = *novidx;
1528     }
1529     return sir_Terry_novels[j];
1530 }
1531
1532 const char *
1533 lookup_novel(lookname, idx)
1534 const char *lookname;
1535 int *idx;
1536 {
1537     int k;
1538
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];
1542
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])) {
1546             if (idx)
1547                 *idx = k;
1548             return sir_Terry_novels[k];
1549         }
1550     }
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];
1554
1555     return (const char *) 0;
1556 }
1557
1558 /*do_name.c*/