OSDN Git Service

change potion un-id desc
[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 /*JP
123         goal = "desired location";
124 */
125         goal = "\96Ú\93I\92n";
126     if (flags.verbose) {
127 /*JP
128         pline("(For instructions type a ?)");
129 */
130         pline("(?\82Å\83w\83\8b\83v)");
131         msg_given = TRUE;
132     }
133     cx = ccp->x;
134     cy = ccp->y;
135 #ifdef CLIPPING
136     cliparound(cx, cy);
137 #endif
138     curs(WIN_MAP, cx, cy);
139     flush_screen(0);
140 #ifdef MAC
141     lock_mouse_cursor(TRUE);
142 #endif
143     for (;;) {
144         if (show_goal_msg) {
145 /*JP
146             pline("Move cursor to %s:", goal);
147 */
148             pline("\83J\81[\83\\83\8b\82ð%s\82É\93®\82©\82µ\82Ä\82­\82¾\82³\82¢:", goal);
149             curs(WIN_MAP, cx, cy);
150             flush_screen(0);
151             show_goal_msg = FALSE;
152         } else if (auto_msg && !msg_given && !hilite_state) {
153             coord cc;
154             int sym = 0;
155             char tmpbuf[BUFSZ];
156             const char *firstmatch = NULL;
157
158             cc.x = cx;
159             cc.y = cy;
160             if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
161                 pline1(firstmatch);
162                 curs(WIN_MAP, cx, cy);
163                 flush_screen(0);
164             }
165         }
166
167         c = nh_poskey(&tx, &ty, &sidx);
168
169         if (hilite_state) {
170             (*getpos_hilitefunc)(2);
171             hilite_state = FALSE;
172             curs(WIN_MAP, cx, cy);
173             flush_screen(0);
174         }
175
176         if (auto_msg)
177             msg_given = FALSE;
178
179         if (c == '\033') {
180             cx = cy = -10;
181             msg_given = TRUE; /* force clear */
182             result = -1;
183             break;
184         }
185         if (c == 0) {
186             if (!isok(tx, ty))
187                 continue;
188             /* a mouse click event, just assign and return */
189             cx = tx;
190             cy = ty;
191             break;
192         }
193         if ((cp = index(pick_chars, c)) != 0) {
194             /* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
195             result = (int) (cp - pick_chars);
196             break;
197         }
198         for (i = 0; i < 8; i++) {
199             int dx, dy;
200
201             if (Cmd.dirchars[i] == c) {
202                 /* a normal movement letter or digit */
203                 dx = xdir[i];
204                 dy = ydir[i];
205             } else if (Cmd.alphadirchars[i] == lowc((char) c)
206                        || (Cmd.num_pad && Cmd.dirchars[i] == (c & 0177))) {
207                 /* a shifted movement letter or Meta-digit */
208                 dx = 8 * xdir[i];
209                 dy = 8 * ydir[i];
210             } else
211                 continue;
212
213             /* truncate at map edge; diagonal moves complicate this... */
214             if (cx + dx < 1) {
215                 dy -= sgn(dy) * (1 - (cx + dx));
216                 dx = 1 - cx; /* so that (cx+dx == 1) */
217             } else if (cx + dx > COLNO - 1) {
218                 dy += sgn(dy) * ((COLNO - 1) - (cx + dx));
219                 dx = (COLNO - 1) - cx;
220             }
221             if (cy + dy < 0) {
222                 dx -= sgn(dx) * (0 - (cy + dy));
223                 dy = 0 - cy; /* so that (cy+dy == 0) */
224             } else if (cy + dy > ROWNO - 1) {
225                 dx += sgn(dx) * ((ROWNO - 1) - (cy + dy));
226                 dy = (ROWNO - 1) - cy;
227             }
228             cx += dx;
229             cy += dy;
230             goto nxtc;
231         }
232
233         if (c == '?' || redraw_cmd(c)) {
234             if (c == '?')
235                 getpos_help(force, goal);
236             else         /* ^R */
237                 docrt(); /* redraw */
238             /* update message window to reflect that we're still targetting */
239             show_goal_msg = TRUE;
240             msg_given = TRUE;
241         } else if ((c == '$') && (getpos_hilitefunc != NULL)) {
242             if (!hilite_state) {
243                 (*getpos_hilitefunc)(0);
244                 (*getpos_hilitefunc)(1);
245                 hilite_state = TRUE;
246             }
247             goto nxtc;
248         } else if (c == '#') {
249             auto_msg = !auto_msg;
250 #if 0 /*JP*/
251             pline("Automatic description %sis %s.",
252                   flags.verbose ? "of features under cursor " : "",
253                   auto_msg ? "on" : "off");
254 #else
255             pline("%s\90à\96¾\8e©\93®\95\\8e¦\81F%s",
256                   flags.verbose ? "\83J\81[\83\\83\8b\82Ì\89º\82É\82 \82é\82à\82Ì\82Ì" : "",
257                   auto_msg ? "\83I\83\93" : "\83I\83t");
258 #endif
259             if (!auto_msg)
260                 show_goal_msg = TRUE;
261             msg_given = TRUE;
262             goto nxtc;
263         } else if (c == '@') {
264             cx = u.ux;
265             cy = u.uy;
266             goto nxtc;
267         } else {
268             if (!index(quitchars, c)) {
269                 char matching[MAXPCHARS];
270                 int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
271                 (void) memset((genericptr_t) matching, 0, sizeof matching);
272                 for (sidx = 1; sidx < MAXPCHARS; sidx++)
273                     if (c == defsyms[sidx].sym || c == (int) showsyms[sidx])
274                         matching[sidx] = (char) ++k;
275                 if (k) {
276                     for (pass = 0; pass <= 1; pass++) {
277                         /* pass 0: just past current pos to lower right;
278                            pass 1: upper left corner to current pos */
279                         lo_y = (pass == 0) ? cy : 0;
280                         hi_y = (pass == 0) ? ROWNO - 1 : cy;
281                         for (ty = lo_y; ty <= hi_y; ty++) {
282                             lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
283                             hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
284                             for (tx = lo_x; tx <= hi_x; tx++) {
285                                 /* look at dungeon feature, not at
286                                  * user-visible glyph */
287                                 k = back_to_glyph(tx, ty);
288                                 /* uninteresting background glyph */
289                                 if (glyph_is_cmap(k)
290                                     && (IS_DOOR(levl[tx][ty].typ)
291                                         || glyph_to_cmap(k) == S_room
292                                         || glyph_to_cmap(k) == S_darkroom
293                                         || glyph_to_cmap(k) == S_corr
294                                         || glyph_to_cmap(k) == S_litcorr)) {
295                                     /* what hero remembers to be at tx,ty */
296                                     k = glyph_at(tx, ty);
297                                 }
298                                 if (glyph_is_cmap(k)
299                                     && matching[glyph_to_cmap(k)]
300                                     && levl[tx][ty].seenv
301                                     && (!IS_WALL(levl[tx][ty].typ))
302                                     && (levl[tx][ty].typ != SDOOR)
303                                     && glyph_to_cmap(k) != S_room
304                                     && glyph_to_cmap(k) != S_corr
305                                     && glyph_to_cmap(k) != S_litcorr) {
306                                     cx = tx, cy = ty;
307                                     if (msg_given) {
308                                         clear_nhwindow(WIN_MESSAGE);
309                                         msg_given = FALSE;
310                                     }
311                                     goto nxtc;
312                                 }
313                             } /* column */
314                         }     /* row */
315                     }         /* pass */
316 /*JP
317                     pline("Can't find dungeon feature '%c'.", c);
318 */
319                     pline("'%c'\81H", c);
320                     msg_given = TRUE;
321                     goto nxtc;
322                 } else {
323                     char note[QBUFSZ];
324
325                     if (!force)
326 /*JP
327                         Strcpy(note, "aborted");
328 */
329                         Strcpy(note, "\92\86\92f\82µ\82½");
330                     else
331 #if 0 /*JP*/
332                         Sprintf(note, "use %c%c%c%c or .", /* hjkl */
333 #else
334                         Sprintf(note, "%c%c%c%c\82Å\88Ú\93®\81C.\82Å\8fI\97¹", /* hjkl */
335 #endif
336                                 Cmd.move_W, Cmd.move_S, Cmd.move_N,
337                                 Cmd.move_E);
338 /*JP
339                     pline("Unknown direction: '%s' (%s).", visctrl((char) c),
340 */
341                     pline("\82»\82Ì\95û\8cü\82Í\82È\82¢\81F'%s' (%s)", visctrl((char) c),
342                           note);
343                     msg_given = TRUE;
344                 } /* k => matching */
345             }     /* !quitchars */
346             if (force)
347                 goto nxtc;
348 /*JP
349             pline("Done.");
350 */
351             pline("\88È\8fã\81D");
352             msg_given = FALSE; /* suppress clear */
353             cx = -1;
354             cy = 0;
355             result = 0; /* not -1 */
356             break;
357         }
358     nxtc:
359         ;
360 #ifdef CLIPPING
361         cliparound(cx, cy);
362 #endif
363         curs(WIN_MAP, cx, cy);
364         flush_screen(0);
365     }
366 #ifdef MAC
367     lock_mouse_cursor(FALSE);
368 #endif
369     if (msg_given)
370         clear_nhwindow(WIN_MESSAGE);
371     ccp->x = cx;
372     ccp->y = cy;
373     getpos_hilitefunc = NULL;
374     return result;
375 }
376
377 /* allocate space for a monster's name; removes old name if there is one */
378 void
379 new_mname(mon, lth)
380 struct monst *mon;
381 int lth; /* desired length (caller handles adding 1 for terminator) */
382 {
383     if (lth) {
384         /* allocate mextra if necessary; otherwise get rid of old name */
385         if (!mon->mextra)
386             mon->mextra = newmextra();
387         else
388             free_mname(mon); /* already has mextra, might also have name */
389         MNAME(mon) = (char *) alloc((unsigned) lth);
390     } else {
391         /* zero length: the new name is empty; get rid of the old name */
392         if (has_mname(mon))
393             free_mname(mon);
394     }
395 }
396
397 /* release a monster's name; retains mextra even if all fields are now null */
398 void
399 free_mname(mon)
400 struct monst *mon;
401 {
402     if (has_mname(mon)) {
403         free((genericptr_t) MNAME(mon));
404         MNAME(mon) = (char *) 0;
405     }
406 }
407
408 /* allocate space for an object's name; removes old name if there is one */
409 void
410 new_oname(obj, lth)
411 struct obj *obj;
412 int lth; /* desired length (caller handles adding 1 for terminator) */
413 {
414     if (lth) {
415         /* allocate oextra if necessary; otherwise get rid of old name */
416         if (!obj->oextra)
417             obj->oextra = newoextra();
418         else
419             free_oname(obj); /* already has oextra, might also have name */
420         ONAME(obj) = (char *) alloc((unsigned) lth);
421     } else {
422         /* zero length: the new name is empty; get rid of the old name */
423         if (has_oname(obj))
424             free_oname(obj);
425     }
426 }
427
428 /* release an object's name; retains oextra even if all fields are now null */
429 void
430 free_oname(obj)
431 struct obj *obj;
432 {
433     if (has_oname(obj)) {
434         free((genericptr_t) ONAME(obj));
435         ONAME(obj) = (char *) 0;
436     }
437 }
438
439 /*  safe_oname() always returns a valid pointer to
440  *  a string, either the pointer to an object's name
441  *  if it has one, or a pointer to an empty string
442  *  if it doesn't.
443  */
444 const char *
445 safe_oname(obj)
446 struct obj *obj;
447 {
448     if (has_oname(obj))
449         return ONAME(obj);
450     return "";
451 }
452
453 /* historical note: this returns a monster pointer because it used to
454    allocate a new bigger block of memory to hold the monster and its name */
455 struct monst *
456 christen_monst(mtmp, name)
457 struct monst *mtmp;
458 const char *name;
459 {
460     int lth;
461     char buf[PL_PSIZ];
462
463     /* dogname & catname are PL_PSIZ arrays; object names have same limit */
464     lth = (name && *name) ? ((int) strlen(name) + 1) : 0;
465     if (lth > PL_PSIZ) {
466 #if 1 /*JP*/
467         if (is_kanji2(buf, lth - 1))
468             --lth;
469 #endif
470         lth = PL_PSIZ;
471         name = strncpy(buf, name, PL_PSIZ - 1);
472         buf[PL_PSIZ - 1] = '\0';
473     }
474     new_mname(mtmp, lth); /* removes old name if one is present */
475     if (lth)
476         Strcpy(MNAME(mtmp), name);
477     return mtmp;
478 }
479
480 /* allow player to assign a name to some chosen monster */
481 STATIC_OVL void
482 do_mname()
483 {
484     char buf[BUFSZ], monnambuf[BUFSZ];
485     coord cc;
486     register int cx, cy;
487     register struct monst *mtmp;
488     char qbuf[QBUFSZ];
489
490     if (Hallucination) {
491 /*JP
492         You("would never recognize it anyway.");
493 */
494         You("\82»\82ê\82ð\94F\8e¯\82Å\82«\82È\82¢\81D");
495         return;
496     }
497     cc.x = u.ux;
498     cc.y = u.uy;
499 /*JP
500     if (getpos(&cc, FALSE, "the monster you want to name") < 0
501 */
502     if (getpos(&cc, FALSE, "\82 \82È\82½\82ª\96¼\82Ã\82¯\82½\82¢\89ö\95¨") < 0
503         || (cx = cc.x) < 0)
504         return;
505     cy = cc.y;
506
507     if (cx == u.ux && cy == u.uy) {
508         if (u.usteed && canspotmon(u.usteed))
509             mtmp = u.usteed;
510         else {
511 /*JP
512             pline("This %s creature is called %s and cannot be renamed.",
513 */
514             pline("\82±\82Ì%s\90\82«\95¨\82Í%s\82Æ\8cÄ\82Î\82ê\82Ä\82¢\82Ä\81C\96¼\91O\82Í\95Ï\8dX\82Å\82«\82È\82¢\81D",
515                   beautiful(), plname);
516             return;
517         }
518     } else
519         mtmp = m_at(cx, cy);
520
521     if (!mtmp
522         || (!sensemon(mtmp)
523             && (!(cansee(cx, cy) || see_with_infrared(mtmp))
524                 || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE
525                 || mtmp->m_ap_type == M_AP_OBJECT
526                 || (mtmp->minvis && !See_invisible)))) {
527 /*JP
528         pline("I see no monster there.");
529 */
530         pline("\82»\82±\82É\89ö\95¨\82Í\82¢\82È\82¢\81D");
531         return;
532     }
533     /* special case similar to the one in lookat() */
534 /*JP
535     Sprintf(qbuf, "What do you want to call %s?",
536 */
537     Sprintf(qbuf, "%s\82ð\89½\82Æ\8cÄ\82Ñ\82Ü\82·\82©\81H",
538             distant_monnam(mtmp, ARTICLE_THE, monnambuf));
539     getlin(qbuf, buf);
540     if (!*buf || *buf == '\033')
541         return;
542     /* strip leading and trailing spaces; unnames monster if all spaces */
543     (void) mungspaces(buf);
544
545     /* unique monsters have their own specific names or titles;
546        shopkeepers, temple priests and other minions use alternate
547        name formatting routines which ignore any user-supplied name */
548     if (mtmp->data->geno & G_UNIQ)
549 /*JP
550         pline("%s doesn't like being called names!", upstart(monnambuf));
551 */
552         pline("%s\82Í\82 \82¾\96¼\82Å\8cÄ\82Î\82ê\82é\82Ì\82ª\8c\99\82¢\82È\82æ\82¤\82¾\81I", Monnam(mtmp));
553     else if (mtmp->isshk
554              && !(Deaf || mtmp->msleeping || !mtmp->mcanmove
555                   || mtmp->data->msound <= MS_ANIMAL))
556 /*JP
557         verbalize("I'm %s, not %s.", shkname(mtmp), buf);
558 */
559         verbalize("\8e\84\82Í%s\82¾\81C%s\82Å\82Í\82È\82¢\81D", shkname(mtmp), buf);
560     else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk)
561 /*JP
562         pline("%s will not accept the name %s.", upstart(monnambuf), buf);
563 */
564         pline("%s\82Í%s\82Æ\82¢\82¤\96¼\91O\82ð\8eó\82¯\82¢\82ê\82È\82©\82Á\82½\81D", monnambuf, buf);
565     else
566         (void) christen_monst(mtmp, buf);
567 }
568
569 /*
570  * This routine changes the address of obj. Be careful not to call it
571  * when there might be pointers around in unknown places. For now: only
572  * when obj is in the inventory.
573  */
574 STATIC_OVL
575 void
576 do_oname(obj)
577 register struct obj *obj;
578 {
579     char *bufp, buf[BUFSZ], bufcpy[BUFSZ], qbuf[QBUFSZ];
580     const char *aname;
581     short objtyp;
582 #if 1 /*JP*/
583     boolean is_japanese = FALSE;
584 #endif
585
586     /* Do this now because there's no point in even asking for a name */
587     if (obj->otyp == SPE_NOVEL) {
588 /*JP
589         pline("%s already has a published name.", Ysimple_name2(obj));
590 */
591         pline("%s\82É\82Í\82·\82Å\82É\8fo\94Å\8e\9e\82Ì\96¼\91O\82ª\82 \82é\81D", Ysimple_name2(obj));
592         return;
593     }
594
595 #if 0 /*JP*/
596     Sprintf(qbuf, "What do you want to name %s ",
597             is_plural(obj) ? "these" : "this");
598     (void) safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item");
599 #else
600     (void) safe_qbuf(qbuf, "", "\82ð\89½\82Æ\96¼\82Ã\82¯\82Ü\82·\82©\81H", obj, xname, simpleonames, "item");
601 #endif
602     getlin(qbuf, buf);
603     if (!*buf || *buf == '\033')
604         return;
605     /* strip leading and trailing spaces; unnames item if all spaces */
606     (void) mungspaces(buf);
607
608     /* relax restrictions over proper capitalization for artifacts */
609     if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
610 #if 0 /*JP*/
611         Strcpy(buf, aname);
612 #else
613         {
614             is_japanese = is_kanji(*buf);
615             Strcpy(buf, aname);
616         }
617 #endif
618
619     if (obj->oartifact) {
620 /*JP
621         pline_The("artifact seems to resist the attempt.");
622 */
623         pline("\90¹\8aí\82Í\96¼\82Ã\82¯\82ð\8b\91\94Û\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D");
624         return;
625     } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
626         /* this used to change one letter, substituting a value
627            of 'a' through 'y' (due to an off by one error, 'z'
628            would never be selected) and then force that to
629            upper case if such was the case of the input;
630            now, the hand slip scuffs one or two letters as if
631            the text had been trodden upon, sometimes picking
632            punctuation instead of an arbitrary letter;
633            unfortunately, we have to cover the possibility of
634            it targetting spaces so failing to make any change
635            (we know that it must eventually target a nonspace
636            because buf[] matches a valid artifact name) */
637         Strcpy(bufcpy, buf);
638         /* for "the Foo of Bar", only scuff "Foo of Bar" part */
639         bufp = !strncmpi(bufcpy, "the ", 4) ? (buf + 4) : buf;
640         do {
641             wipeout_text(bufp, rnd(2), (unsigned) 0);
642         } while (!strcmp(buf, bufcpy));
643 /*JP
644         pline("While engraving, your %s slips.", body_part(HAND));
645 */
646         pline("\8d\8f\82ñ\82Å\82¢\82é\8aÔ\82É%s\82ª\8a\8a\82Á\82Ä\82µ\82Ü\82Á\82½\81D", body_part(HAND));
647         display_nhwindow(WIN_MESSAGE, FALSE);
648 /*JP
649         You("engrave: \"%s\".", buf);
650 */
651         You("\8d\8f\82ñ\82¾: \81u%s\81v\81D",buf);
652     }
653     obj = oname(obj, buf);
654 }
655
656 struct obj *
657 oname(obj, name)
658 struct obj *obj;
659 const char *name;
660 {
661     int lth;
662     char buf[PL_PSIZ];
663
664     lth = *name ? (int) (strlen(name) + 1) : 0;
665     if (lth > PL_PSIZ) {
666         lth = PL_PSIZ;
667 #if 0 /*JP*/
668         name = strncpy(buf, name, PL_PSIZ - 1);
669         buf[PL_PSIZ - 1] = '\0';
670 #else
671         if (is_kanji2(name, lth - 1))
672             --lth;
673         name = strncpy(buf, name, lth - 1);
674         buf[lth - 1] = '\0';
675 #endif
676     }
677     /* If named artifact exists in the game, do not create another.
678      * Also trying to create an artifact shouldn't de-artifact
679      * it (e.g. Excalibur from prayer). In this case the object
680      * will retain its current name. */
681     if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
682         return obj;
683
684     new_oname(obj, lth); /* removes old name if one is present */
685     if (lth)
686         Strcpy(ONAME(obj), name);
687
688     if (lth)
689         artifact_exists(obj, name, TRUE);
690     if (obj->oartifact) {
691         /* can't dual-wield with artifact as secondary weapon */
692         if (obj == uswapwep)
693             untwoweapon();
694         /* activate warning if you've just named your weapon "Sting" */
695         if (obj == uwep)
696             set_artifact_intrinsic(obj, TRUE, W_WEP);
697         /* if obj is owned by a shop, increase your bill */
698         if (obj->unpaid)
699             alter_cost(obj, 0L);
700     }
701     if (carried(obj))
702         update_inventory();
703     return obj;
704 }
705
706 static NEARDATA const char callable[] = {
707     SCROLL_CLASS, POTION_CLASS, WAND_CLASS,  RING_CLASS, AMULET_CLASS,
708     GEM_CLASS,    SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0
709 };
710
711 boolean
712 objtyp_is_callable(i)
713 int i;
714 {
715     return (boolean) (objects[i].oc_uname
716                       || (OBJ_DESCR(objects[i])
717                           && index(callable, objects[i].oc_class)));
718 }
719
720 /* C and #name commands - player can name monster or object or type of obj */
721 int
722 docallcmd()
723 {
724     struct obj *obj;
725     winid win;
726     anything any;
727     menu_item *pick_list = 0;
728     char ch, allowall[2];
729     /* if player wants a,b,c instead of i,o when looting, do that here too */
730     boolean abc = flags.lootabc;
731
732     win = create_nhwindow(NHW_MENU);
733     start_menu(win);
734     any = zeroany;
735     any.a_char = 'm'; /* group accelerator 'C' */
736     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'C', ATR_NONE,
737 /*JP
738              "a monster", MENU_UNSELECTED);
739 */
740              "\89ö\95¨", MENU_UNSELECTED);
741     if (invent) {
742         /* we use y and n as accelerators so that we can accept user's
743            response keyed to old "name an individual object?" prompt */
744         any.a_char = 'i'; /* group accelerator 'y' */
745         add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'y', ATR_NONE,
746 /*JP
747                  "a particular object in inventory", MENU_UNSELECTED);
748 */
749                  "\8e\9d\82¿\95¨\82Ì\92\86\82Ì\88ê\82Â\82Ì\83A\83C\83e\83\80", MENU_UNSELECTED);
750         any.a_char = 'o'; /* group accelerator 'n' */
751         add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'n', ATR_NONE,
752 /*JP
753                  "the type of an object in inventory", MENU_UNSELECTED);
754 */
755                  "\8e\9d\82¿\95¨\82Ì\92\86\82Ì\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
756     }
757     any.a_char = 'f'; /* group accelerator ',' (or ':' instead?) */
758     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, ',', ATR_NONE,
759 /*JP
760              "the type of an object upon the floor", MENU_UNSELECTED);
761 */
762              "\8f°\82Ì\8fã\82É\82 \82é\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
763     any.a_char = 'd'; /* group accelerator '\' */
764     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, '\\', ATR_NONE,
765 /*JP
766              "the type of an object on discoveries list", MENU_UNSELECTED);
767 */
768              "\94­\8c©\95¨\88ê\97\97\82É\82 \82é\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
769     any.a_char = 'a'; /* group accelerator 'l' */
770     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'l', ATR_NONE,
771 /*JP
772              "record an annotation for the current level", MENU_UNSELECTED);
773 */
774              "\8c»\8dÝ\82Ì\8aK\82É\91Î\82·\82é\83\81\83\82\82Ì\8bL\98^", MENU_UNSELECTED);
775 /*JP
776     end_menu(win, "What do you want to name?");
777 */
778     end_menu(win, "\82Ç\82ê\82É\96¼\91O\82ð\82Â\82¯\82Ü\82·\82©\81H");
779     if (select_menu(win, PICK_ONE, &pick_list) > 0) {
780         ch = pick_list[0].item.a_char;
781         free((genericptr_t) pick_list);
782     } else
783         ch = 'q';
784     destroy_nhwindow(win);
785
786     switch (ch) {
787     default:
788     case 'q':
789         break;
790     case 'm': /* name a visible monster */
791         do_mname();
792         break;
793     case 'i': /* name an individual object in inventory */
794         allowall[0] = ALL_CLASSES;
795         allowall[1] = '\0';
796         obj = getobj(allowall, "name");
797         if (obj)
798             do_oname(obj);
799         break;
800     case 'o': /* name a type of object in inventory */
801         obj = getobj(callable, "call");
802         if (obj) {
803             /* behave as if examining it in inventory;
804                this might set dknown if it was picked up
805                while blind and the hero can now see */
806             (void) xname(obj);
807
808             if (!obj->dknown) {
809 /*JP
810                 You("would never recognize another one.");
811 */
812                 You("\91¼\82É\94F\8e¯\82Å\82«\82È\82¢\81D");
813 #if 0
814             } else if (!objtyp_is_callable(obj->otyp)) {
815                 You("know those as well as you ever will.");
816 #endif
817             } else {
818                 docall(obj);
819             }
820         }
821         break;
822     case 'f': /* name a type of object visible on the floor */
823         namefloorobj();
824         break;
825     case 'd': /* name a type of object on the discoveries list */
826         rename_disco();
827         break;
828     case 'a': /* annotate level */
829         donamelevel();
830         break;
831     }
832     return 0;
833 }
834
835 void
836 docall(obj)
837 register struct obj *obj;
838 {
839     char buf[BUFSZ], qbuf[QBUFSZ];
840     struct obj otemp;
841     register char **str1;
842
843     if (!obj->dknown)
844         return; /* probably blind */
845     otemp = *obj;
846     otemp.quan = 1L;
847     otemp.oextra = (struct oextra *) 0;
848
849     if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink)
850         /* kludge, meaning it's sink water */
851 /*JP
852         Sprintf(qbuf, "Call a stream of %s fluid:",
853 */
854         Sprintf(qbuf, "%s\89t\91Ì:",
855                 OBJ_DESCR(objects[otemp.otyp]));
856     else
857 /*JP
858         Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
859 */
860         Sprintf(qbuf, "%s\82É\89½\82Æ\96¼\91O\82ð\82Â\82¯\82é\81H", an(xname(&otemp)));
861     getlin(qbuf, buf);
862     if (!*buf || *buf == '\033')
863         return;
864
865     /* clear old name */
866     str1 = &(objects[obj->otyp].oc_uname);
867     if (*str1)
868         free((genericptr_t) *str1);
869
870     /* strip leading and trailing spaces; uncalls item if all spaces */
871     (void) mungspaces(buf);
872     if (!*buf) {
873         if (*str1) { /* had name, so possibly remove from disco[] */
874             /* strip name first, for the update_inventory() call
875                from undiscover_object() */
876             *str1 = (char *) 0;
877             undiscover_object(obj->otyp);
878         }
879     } else {
880         *str1 = dupstr(buf);
881         discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
882     }
883 }
884
885 STATIC_OVL void
886 namefloorobj()
887 {
888     coord cc;
889     int glyph;
890     char buf[BUFSZ];
891     struct obj *obj = 0;
892     boolean fakeobj = FALSE, use_plural;
893
894     cc.x = u.ux, cc.y = u.uy;
895     /* "dot for under/over you" only makes sense when the cursor hasn't
896        been moved off the hero's '@' yet, but there's no way to adjust
897        the help text once getpos() has started */
898     Sprintf(buf, "object on map (or '.' for one %s you)",
899             (u.uundetected && hides_under(youmonst.data)) ? "over" : "under");
900     if (getpos(&cc, FALSE, buf) < 0 || cc.x <= 0)
901         return;
902     if (cc.x == u.ux && cc.y == u.uy) {
903         obj = vobj_at(u.ux, u.uy);
904     } else {
905         glyph = glyph_at(cc.x, cc.y);
906         if (glyph_is_object(glyph))
907             fakeobj = object_from_map(glyph, cc.x, cc.y, &obj);
908         /* else 'obj' stays null */
909     }
910     if (!obj) {
911         /* "under you" is safe here since there's no object to hide under */
912 #if 0 /*JP*/
913         pline("There doesn't seem to be any object %s.",
914               (cc.x == u.ux && cc.y == u.uy) ? "under you" : "there");
915 #else
916         pline("%s\82É\82Í\89½\82à\82È\82¢\82æ\82¤\82¾\81D",
917               (cc.x == u.ux && cc.y == u.uy) ? "\82 \82È\82½\82Ì\89º" : "\82»\82±");
918 #endif
919         return;
920     }
921     /* note well: 'obj' might be as instance of STRANGE_OBJECT if target
922        is a mimic; passing that to xname (directly or via simpleonames)
923        would yield "glorkum" so we need to handle it explicitly; it will
924        always fail the Hallucination test and pass the !callable test,
925        resulting in the "can't be assigned a type name" message */
926     Strcpy(buf, (obj->otyp != STRANGE_OBJECT)
927                  ? simpleonames(obj)
928                  : obj_descr[STRANGE_OBJECT].oc_name);
929     use_plural = (obj->quan > 1L);
930     if (Hallucination) {
931         const char *unames[6];
932         char tmpbuf[BUFSZ];
933
934         /* straight role name */
935         unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
936                      ? urole.name.f
937                      : urole.name.m;
938         /* random rank title for hero's role */
939         unames[1] = rank_of(rnd(30), Role_switch, flags.female);
940         /* random fake monster */
941         unames[2] = bogusmon(tmpbuf, (char *) 0);
942         /* increased chance for fake monster */
943         unames[3] = unames[2];
944         /* traditional */
945         unames[4] = roguename();
946         /* silly */
947 /*JP
948         unames[5] = "Wibbly Wobbly";
949 */
950         unames[5] = "\82¤\82ë\82¤\82ë";
951 #if 0 /*JP*/
952         pline("%s %s to call you \"%s.\"",
953               The(buf), use_plural ? "decide" : "decides",
954               unames[rn2(SIZE(unames))]);
955 #else
956         pline("%s\82Í\82 \82È\82½\82ð\81u%s\81v\82Æ\8cÄ\82Ô\82±\82Æ\82É\8c\88\82ß\82½\81D",
957               buf,
958               unames[rn2(SIZE(unames))]);
959 #endif
960     } else if (!objtyp_is_callable(obj->otyp)) {
961 #if 0 /*JP*/
962         pline("%s %s can't be assigned a type name.",
963               use_plural ? "Those" : "That", buf);
964 #else
965         pline("%s\82É\8eí\97Þ\82Ì\96¼\91O\82ð\8a\84\82è\93\96\82Ä\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
966               buf);
967 #endif
968     } else if (!obj->dknown) {
969 #if 0 /*JP*/
970         You("don't know %s %s well enough to name %s.",
971             use_plural ? "those" : "that", buf, use_plural ? "them" : "it");
972 #else
973         You("\96¼\91O\82ð\95t\82¯\82ç\82ê\82é\82Ù\82Ç%s\82Ì\82±\82Æ\82ð\82æ\82­\92m\82ç\82È\82¢\81D",
974             buf);
975 #endif
976     } else {
977         docall(obj);
978     }
979     if (fakeobj)
980         dealloc_obj(obj);
981 }
982
983 static const char *const ghostnames[] = {
984     /* these names should have length < PL_NSIZ */
985     /* Capitalize the names for aesthetics -dgk */
986     "Adri",    "Andries",       "Andreas",     "Bert",    "David",  "Dirk",
987     "Emile",   "Frans",         "Fred",        "Greg",    "Hether", "Jay",
988     "John",    "Jon",           "Karnov",      "Kay",     "Kenny",  "Kevin",
989     "Maud",    "Michiel",       "Mike",        "Peter",   "Robert", "Ron",
990     "Tom",     "Wilmar",        "Nick Danger", "Phoenix", "Jiro",   "Mizue",
991     "Stephan", "Lance Braccus", "Shadowhawk"
992 };
993
994 /* ghost names formerly set by x_monnam(), now by makemon() instead */
995 const char *
996 rndghostname()
997 {
998     return rn2(7) ? ghostnames[rn2(SIZE(ghostnames))] : (const char *) plname;
999 }
1000
1001 /*
1002  * Monster naming functions:
1003  * x_monnam is the generic monster-naming function.
1004  *                seen        unseen       detected               named
1005  * mon_nam:     the newt        it      the invisible orc       Fido
1006  * noit_mon_nam:the newt (as if detected) the invisible orc     Fido
1007  * l_monnam:    newt            it      invisible orc           dog called Fido
1008  * Monnam:      The newt        It      The invisible orc       Fido
1009  * noit_Monnam: The newt (as if detected) The invisible orc     Fido
1010  * Adjmonnam:   The poor newt   It      The poor invisible orc  The poor Fido
1011  * Amonnam:     A newt          It      An invisible orc        Fido
1012  * a_monnam:    a newt          it      an invisible orc        Fido
1013  * m_monnam:    newt            xan     orc                     Fido
1014  * y_monnam:    your newt     your xan  your invisible orc      Fido
1015  */
1016
1017 /* Bug: if the monster is a priest or shopkeeper, not every one of these
1018  * options works, since those are special cases.
1019  */
1020 char *
1021 x_monnam(mtmp, article, adjective, suppress, called)
1022 register struct monst *mtmp;
1023 int article;
1024 /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
1025  * ARTICLE_YOUR: "your" on pets, "the" on everything else
1026  *
1027  * If the monster would be referred to as "it" or if the monster has a name
1028  * _and_ there is no adjective, "invisible", "saddled", etc., override this
1029  * and always use no article.
1030  */
1031 const char *adjective;
1032 int suppress;
1033 /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
1034  * EXACT_NAME: combination of all the above
1035  */
1036 boolean called;
1037 {
1038     char *buf = nextmbuf();
1039     struct permonst *mdat = mtmp->data;
1040     const char *pm_name = mdat->mname;
1041     boolean do_hallu, do_invis, do_it, do_saddle;
1042 #if 0 /*JP*/
1043     boolean name_at_start, has_adjectives;
1044     char *bp;
1045 #endif
1046
1047     if (program_state.gameover)
1048         suppress |= SUPPRESS_HALLUCINATION;
1049     if (article == ARTICLE_YOUR && !mtmp->mtame)
1050         article = ARTICLE_THE;
1051
1052     do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION);
1053     do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE);
1054     do_it = !canspotmon(mtmp) && article != ARTICLE_YOUR
1055             && !program_state.gameover && mtmp != u.usteed
1056             && !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
1057     do_saddle = !(suppress & SUPPRESS_SADDLE);
1058
1059     buf[0] = '\0';
1060
1061     /* unseen monsters, etc.  Use "it" */
1062     if (do_it) {
1063 /*JP
1064         Strcpy(buf, "it");
1065 */
1066         Strcpy(buf, "\89½\8eÒ\82©");
1067         return buf;
1068     }
1069
1070     /* priests and minions: don't even use this function */
1071     if (mtmp->ispriest || mtmp->isminion) {
1072         char priestnambuf[BUFSZ];
1073         char *name;
1074         long save_prop = EHalluc_resistance;
1075         unsigned save_invis = mtmp->minvis;
1076
1077         /* when true name is wanted, explicitly block Hallucination */
1078         if (!do_hallu)
1079             EHalluc_resistance = 1L;
1080         if (!do_invis)
1081             mtmp->minvis = 0;
1082         name = priestname(mtmp, priestnambuf);
1083         EHalluc_resistance = save_prop;
1084         mtmp->minvis = save_invis;
1085 #if 0 /*JP*/
1086         if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
1087             name += 4;
1088 #endif
1089         return strcpy(buf, name);
1090     }
1091     /* an "aligned priest" not flagged as a priest or minion should be
1092        "priest" or "priestess" (normally handled by priestname()) */
1093     if (mdat == &mons[PM_ALIGNED_PRIEST])
1094 /*JP
1095         pm_name = mtmp->female ? "priestess" : "priest";
1096 */
1097         pm_name = mtmp->female ? "\93ò\91m" : "\91m\97µ";
1098     else if (mdat == &mons[PM_HIGH_PRIEST] && mtmp->female)
1099 /*JP
1100         pm_name = "high priestess";
1101 */
1102         pm_name = "\96@\89¤";
1103
1104     /* Shopkeepers: use shopkeeper name.  For normal shopkeepers, just
1105      * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
1106      * shopkeeper" or "Asidonhopo the blue dragon".  If hallucinating,
1107      * none of this applies.
1108      */
1109     if (mtmp->isshk && !do_hallu) {
1110 #if 0 /*JP*/
1111         if (adjective && article == ARTICLE_THE) {
1112             /* pathological case: "the angry Asidonhopo the blue dragon"
1113                sounds silly */
1114             Strcpy(buf, "the ");
1115             Strcat(strcat(buf, adjective), " ");
1116             Strcat(buf, shkname(mtmp));
1117             return buf;
1118         }
1119         Strcat(buf, shkname(mtmp));
1120         if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
1121             return buf;
1122         Strcat(buf, " the ");
1123         if (do_invis)
1124             Strcat(buf, "invisible ");
1125         Strcat(buf, pm_name);
1126         return buf;
1127 #else
1128         if (mdat == &mons[PM_SHOPKEEPER] && !do_invis){
1129             Strcpy(buf, shkname(mtmp));
1130         } else {
1131             Sprintf(buf, "%s\82Æ\82¢\82¤\96¼\82Ì%s%s",
1132                     shkname(mtmp), do_invis ? "\8ep\82Ì\8c©\82¦\82È\82¢" : "",
1133                     pm_name);
1134         }
1135         return buf;
1136 #endif
1137     }
1138
1139     /* Put the adjectives in the buffer */
1140     if (adjective)
1141 /*JP
1142         Strcat(strcat(buf, adjective), " ");
1143 */
1144         Strcat(buf, adjective);
1145     if (do_invis)
1146 /*JP
1147         Strcat(buf, "invisible ");
1148 */
1149         Strcat(buf, "\8ep\82Ì\8c©\82¦\82È\82¢");
1150     if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) && !Blind
1151         && !Hallucination)
1152 /*JP
1153         Strcat(buf, "saddled ");
1154 */
1155         Strcat(buf, "\88Æ\82Ì\82Â\82¢\82Ä\82¢\82é");
1156 #if 0 /*JP*/
1157     if (buf[0] != 0)
1158         has_adjectives = TRUE;
1159     else
1160         has_adjectives = FALSE;
1161 #endif
1162
1163     /* Put the actual monster name or type into the buffer now */
1164     /* Be sure to remember whether the buffer starts with a name */
1165     if (do_hallu) {
1166         char rnamecode;
1167         char *rname = rndmonnam(&rnamecode);
1168
1169         Strcat(buf, rname);
1170 #if 0 /*JP*/
1171         name_at_start = bogon_is_pname(rnamecode);
1172 #endif
1173     } else if (has_mname(mtmp)) {
1174         char *name = MNAME(mtmp);
1175
1176         if (mdat == &mons[PM_GHOST]) {
1177 /*JP
1178             Sprintf(eos(buf), "%s ghost", s_suffix(name));
1179 */
1180             Sprintf(buf, "%s\82Ì\97H\97ì", name);
1181 #if 0 /*JP*/
1182             name_at_start = TRUE;
1183 #endif
1184         } else if (called) {
1185 /*JP
1186             Sprintf(eos(buf), "%s called %s", pm_name, name);
1187 */
1188             Sprintf(eos(buf), "%s\82Æ\82¢\82¤\96¼\82Ì%s", name, pm_name);
1189 #if 0 /*JP*/
1190             name_at_start = (boolean) type_is_pname(mdat);
1191 #endif
1192 #if 0 /*JP*//*\92è\8a¥\8e\8c\82Ì\8f\88\97\9d\82Í\95s\97v*/
1193         } else if (is_mplayer(mdat) && (bp = strstri(name, " the ")) != 0) {
1194             /* <name> the <adjective> <invisible> <saddled> <rank> */
1195             char pbuf[BUFSZ];
1196
1197             Strcpy(pbuf, name);
1198             pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
1199             if (has_adjectives)
1200                 Strcat(pbuf, buf);
1201             Strcat(pbuf, bp + 5); /* append the rest of the name */
1202             Strcpy(buf, pbuf);
1203             article = ARTICLE_NONE;
1204             name_at_start = TRUE;
1205 #endif
1206         } else {
1207             Strcat(buf, name);
1208 #if 0 /*JP*/
1209             name_at_start = TRUE;
1210 #endif
1211         }
1212     } else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
1213         char pbuf[BUFSZ];
1214
1215         Strcpy(pbuf, rank_of((int) mtmp->m_lev, monsndx(mdat),
1216                              (boolean) mtmp->female));
1217 #if 0 /*JP*/
1218         Strcat(buf, lcase(pbuf));
1219 #else
1220         Strcat(buf, pbuf);
1221 #endif
1222 #if 0 /*JP*/
1223         name_at_start = FALSE;
1224 #endif
1225     } else {
1226         Strcat(buf, pm_name);
1227 #if 0 /*JP*/
1228         name_at_start = (boolean) type_is_pname(mdat);
1229 #endif
1230     }
1231
1232 #if 0 /*JP*//*\93ú\96{\8cê\82É\8a¥\8e\8c\82Í\82È\82¢*/
1233     if (name_at_start && (article == ARTICLE_YOUR || !has_adjectives)) {
1234         if (mdat == &mons[PM_WIZARD_OF_YENDOR])
1235             article = ARTICLE_THE;
1236         else
1237             article = ARTICLE_NONE;
1238     } else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
1239         article = ARTICLE_THE;
1240     }
1241
1242     {
1243         char buf2[BUFSZ];
1244
1245         switch (article) {
1246         case ARTICLE_YOUR:
1247             Strcpy(buf2, "your ");
1248             Strcat(buf2, buf);
1249             Strcpy(buf, buf2);
1250             return buf;
1251         case ARTICLE_THE:
1252             Strcpy(buf2, "the ");
1253             Strcat(buf2, buf);
1254             Strcpy(buf, buf2);
1255             return buf;
1256         case ARTICLE_A:
1257             return an(buf);
1258         case ARTICLE_NONE:
1259         default:
1260             return buf;
1261         }
1262     }
1263 #else
1264     return buf;
1265 #endif
1266 }
1267
1268 char *
1269 l_monnam(mtmp)
1270 struct monst *mtmp;
1271 {
1272     return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
1273                     (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
1274 }
1275
1276 char *
1277 mon_nam(mtmp)
1278 struct monst *mtmp;
1279 {
1280     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1281                     (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
1282 }
1283
1284 /* print the name as if mon_nam() was called, but assume that the player
1285  * can always see the monster--used for probing and for monsters aggravating
1286  * the player with a cursed potion of invisibility
1287  */
1288 char *
1289 noit_mon_nam(mtmp)
1290 struct monst *mtmp;
1291 {
1292     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
1293                     (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
1294                                        : SUPPRESS_IT,
1295                     FALSE);
1296 }
1297
1298 char *
1299 Monnam(mtmp)
1300 struct monst *mtmp;
1301 {
1302     register char *bp = mon_nam(mtmp);
1303
1304     *bp = highc(*bp);
1305     return  bp;
1306 }
1307
1308 char *
1309 noit_Monnam(mtmp)
1310 struct monst *mtmp;
1311 {
1312     register char *bp = noit_mon_nam(mtmp);
1313
1314     *bp = highc(*bp);
1315     return  bp;
1316 }
1317
1318 /* monster's own name */
1319 char *
1320 m_monnam(mtmp)
1321 struct monst *mtmp;
1322 {
1323     return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, EXACT_NAME, FALSE);
1324 }
1325
1326 /* pet name: "your little dog" */
1327 char *
1328 y_monnam(mtmp)
1329 struct monst *mtmp;
1330 {
1331     int prefix, suppression_flag;
1332
1333     prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
1334     suppression_flag = (has_mname(mtmp)
1335                         /* "saddled" is redundant when mounted */
1336                         || mtmp == u.usteed)
1337                            ? SUPPRESS_SADDLE
1338                            : 0;
1339
1340     return x_monnam(mtmp, prefix, (char *) 0, suppression_flag, FALSE);
1341 }
1342
1343 char *
1344 Adjmonnam(mtmp, adj)
1345 struct monst *mtmp;
1346 const char *adj;
1347 {
1348     char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
1349                         has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1350
1351     *bp = highc(*bp);
1352     return  bp;
1353 }
1354
1355 char *
1356 a_monnam(mtmp)
1357 struct monst *mtmp;
1358 {
1359     return x_monnam(mtmp, ARTICLE_A, (char *) 0,
1360                     has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
1361 }
1362
1363 char *
1364 Amonnam(mtmp)
1365 struct monst *mtmp;
1366 {
1367     char *bp = a_monnam(mtmp);
1368
1369     *bp = highc(*bp);
1370     return  bp;
1371 }
1372
1373 /* used for monster ID by the '/', ';', and 'C' commands to block remote
1374    identification of the endgame altars via their attending priests */
1375 char *
1376 distant_monnam(mon, article, outbuf)
1377 struct monst *mon;
1378 int article; /* only ARTICLE_NONE and ARTICLE_THE are handled here */
1379 char *outbuf;
1380 {
1381     /* high priest(ess)'s identity is concealed on the Astral Plane,
1382        unless you're adjacent (overridden for hallucination which does
1383        its own obfuscation) */
1384     if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination
1385         && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
1386 #if 0 /*JP*/
1387         Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
1388         Strcat(outbuf, mon->female ? "high priestess" : "high priest");
1389 #else
1390         Strcpy(outbuf, "\96@\89¤");
1391 #endif
1392     } else {
1393         Strcpy(outbuf, x_monnam(mon, article, (char *) 0, 0, TRUE));
1394     }
1395     return outbuf;
1396 }
1397
1398 /* fake monsters used to be in a hard-coded array, now in a data file */
1399 STATIC_OVL char *
1400 bogusmon(buf, code)
1401 char *buf, *code;
1402 {
1403     char *mname = buf;
1404
1405     get_rnd_text(BOGUSMONFILE, buf);
1406     /* strip prefix if present */
1407     if (!letter(*mname)) {
1408         if (code)
1409             *code = *mname;
1410         ++mname;
1411     } else {
1412         if (code)
1413             *code = '\0';
1414     }
1415     return mname;
1416 }
1417
1418 /* return a random monster name, for hallucination */
1419 char *
1420 rndmonnam(code)
1421 char *code;
1422 {
1423     static char buf[BUFSZ];
1424     char *mname;
1425     int name;
1426 #define BOGUSMONSIZE 100 /* arbitrary */
1427
1428     if (code)
1429         *code = '\0';
1430
1431     do {
1432         name = rn1(SPECIAL_PM + BOGUSMONSIZE - LOW_PM, LOW_PM);
1433     } while (name < SPECIAL_PM
1434              && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
1435
1436     if (name >= SPECIAL_PM) {
1437         mname = bogusmon(buf, code);
1438     } else {
1439         mname = strcpy(buf, mons[name].mname);
1440     }
1441     return mname;
1442 #undef BOGUSMONSIZE
1443 }
1444
1445 /* check bogusmon prefix to decide whether it's a personal name */
1446 boolean
1447 bogon_is_pname(code)
1448 char code;
1449 {
1450     if (!code)
1451         return FALSE;
1452     return index("-+=", code) ? TRUE : FALSE;
1453 }
1454
1455 /* name of a Rogue player */
1456 const char *
1457 roguename()
1458 {
1459     char *i, *opts;
1460
1461     if ((opts = nh_getenv("ROGUEOPTS")) != 0) {
1462         for (i = opts; *i; i++)
1463             if (!strncmp("name=", i, 5)) {
1464                 char *j;
1465                 if ((j = index(i + 5, ',')) != 0)
1466                     *j = (char) 0;
1467                 return i + 5;
1468             }
1469     }
1470     return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
1471                   : "Glenn Wichman";
1472 }
1473
1474 static NEARDATA const char *const hcolors[] = {
1475 #if 0 /*JP*/
1476     "ultraviolet", "infrared", "bluish-orange", "reddish-green", "dark white",
1477     "light black", "sky blue-pink", "salty", "sweet", "sour", "bitter",
1478     "striped", "spiral", "swirly", "plaid", "checkered", "argyle", "paisley",
1479     "blotchy", "guernsey-spotted", "polka-dotted", "square", "round",
1480     "triangular", "cabernet", "sangria", "fuchsia", "wisteria", "lemon-lime",
1481     "strawberry-banana", "peppermint", "romantic", "incandescent",
1482     "octarine", /* Discworld: the Colour of Magic */
1483 #else
1484     "\8e\87\8aO\90F\82Ì", "\90Ô\8aO\90F\82Ì", "\90Â\90F\82ª\82©\82Á\82½\83I\83\8c\83\93\83W\90F\82Ì", "\90Ô\82Ý\82ª\82©\82Á\82½\97Î\90F\82Ì", "\88Ã\82¢\94\92\90F\82Ì",
1485     "\96¾\82é\82¢\8d\95\82Ì", "\90\85\90F\82ª\82©\82Á\82½\83s\83\93\83N\90F\82Ì", "\89\96\90h\82¢", "\8aÃ\82¢", "\82·\82Á\82Ï\82¢", "\8bê\82¢",
1486     "\82µ\82Ü\96Í\97l\82Ì", "\82ç\82¹\82ñ\8fó\82Ì", "\94g\8fó\82Ì", "\8ai\8eq\96Í\97l\8fó\82Ì", "\83`\83F\83b\83N\8fó\82Ì", "\95ú\8eË\8fó\82Ì", "\83y\81[\83Y\83\8a\81[\96Í\97l\82Ì",
1487     "\82µ\82Ý\8fó\82Ì", "\90Â\90F\82Ì\94Á\93_\8fó\82Ì", "\93_\8fó\82Ì", "\8el\8ap\8c`\8fó\82Ì", "\8aÛ\8fó\82Ì",
1488     "\8eO\8ap\8fó\82Ì", "\83J\83x\83\8b\83l\90F\82Ì", "\83T\83\93\83O\83\8a\83A\90F\82Ì", "\91N\82â\82©\82È\90Ô\8e\87\90F\82Ì", "\93¡\90F\82Ì", "\83\8c\83\82\83\93\83\89\83C\83\80\90F\82Ì",
1489     "ä\95\83o\83i\83i\90F\82Ì", "\83y\83p\81[\83~\83\93\83g\90F\82Ì", "\83\8d\83}\83\93\83`\83b\83N\82È\90F\82Ì", "\94\92\94M\90F\82Ì",
1490     "\83I\83N\83^\83\8a\83\93\90F\82Ì",
1491 #endif
1492 };
1493
1494 const char *
1495 hcolor(colorpref)
1496 const char *colorpref;
1497 {
1498     return (Hallucination || !colorpref) ? hcolors[rn2(SIZE(hcolors))]
1499                                          : colorpref;
1500 }
1501
1502 /* return a random real color unless hallucinating */
1503 const char *
1504 rndcolor()
1505 {
1506     int k = rn2(CLR_MAX);
1507
1508     return Hallucination ? hcolor((char *) 0)
1509 /*JP
1510                          : (k == NO_COLOR) ? "colorless"
1511 */
1512                          : (k == NO_COLOR) ? "\96³\90F\82Ì"
1513                                            : c_obj_colors[k];
1514 }
1515
1516 /* Aliases for road-runner nemesis
1517  */
1518 static const char *const coynames[] = {
1519     "Carnivorous Vulgaris", "Road-Runnerus Digestus", "Eatibus Anythingus",
1520     "Famishus-Famishus", "Eatibus Almost Anythingus", "Eatius Birdius",
1521     "Famishius Fantasticus", "Eternalii Famishiis", "Famishus Vulgarus",
1522     "Famishius Vulgaris Ingeniusi", "Eatius-Slobbius", "Hardheadipus Oedipus",
1523     "Carnivorous Slobbius", "Hard-Headipus Ravenus", "Evereadii Eatibus",
1524     "Apetitius Giganticus", "Hungrii Flea-Bagius", "Overconfidentii Vulgaris",
1525     "Caninus Nervous Rex", "Grotesques Appetitus", "Nemesis Ridiculii",
1526     "Canis latrans"
1527 };
1528
1529 char *
1530 coyotename(mtmp, buf)
1531 struct monst *mtmp;
1532 char *buf;
1533 {
1534     if (mtmp && buf) {
1535         Sprintf(buf, "%s - %s",
1536                 x_monnam(mtmp, ARTICLE_NONE, (char *) 0, 0, TRUE),
1537                 mtmp->mcan ? coynames[SIZE(coynames) - 1]
1538                            : coynames[rn2(SIZE(coynames) - 1)]);
1539     }
1540     return buf;
1541 }
1542
1543 /* make sure "The Colour of Magic" remains the first entry in here */
1544 static const char *const sir_Terry_novels[] = {
1545     "The Colour of Magic", "The Light Fantastic", "Equal Rites", "Mort",
1546     "Sourcery", "Wyrd Sisters", "Pyramids", "Guards! Guards!", "Eric",
1547     "Moving Pictures", "Reaper Man", "Witches Abroad", "Small Gods",
1548     "Lords and Ladies", "Men at Arms", "Soul Music", "Interesting Times",
1549     "Maskerade", "Feet of Clay", "Hogfather", "Jingo", "The Last Continent",
1550     "Carpe Jugulum", "The Fifth Elephant", "The Truth", "Thief of Time",
1551     "The Last Hero", "The Amazing Maurice and his Educated Rodents",
1552     "Night Watch", "The Wee Free Men", "Monstrous Regiment",
1553     "A Hat Full of Sky", "Going Postal", "Thud!", "Wintersmith",
1554     "Making Money", "Unseen Academicals", "I Shall Wear Midnight", "Snuff",
1555     "Raising Steam", "The Shepherd's Crown"
1556 };
1557
1558 const char *
1559 noveltitle(novidx)
1560 int *novidx;
1561 {
1562     int j, k = SIZE(sir_Terry_novels);
1563
1564     j = rn2(k);
1565     if (novidx) {
1566         if (*novidx == -1)
1567             *novidx = j;
1568         else if (*novidx >= 0 && *novidx < k)
1569             j = *novidx;
1570     }
1571     return sir_Terry_novels[j];
1572 }
1573
1574 const char *
1575 lookup_novel(lookname, idx)
1576 const char *lookname;
1577 int *idx;
1578 {
1579     int k;
1580
1581     /* Take American or U.K. spelling of this one */
1582     if (!strcmpi(The(lookname), "The Color of Magic"))
1583         lookname = sir_Terry_novels[0];
1584
1585     for (k = 0; k < SIZE(sir_Terry_novels); ++k) {
1586         if (!strcmpi(lookname, sir_Terry_novels[k])
1587             || !strcmpi(The(lookname), sir_Terry_novels[k])) {
1588             if (idx)
1589                 *idx = k;
1590             return sir_Terry_novels[k];
1591         }
1592     }
1593     /* name not found; if novelidx is already set, override the name */
1594     if (idx && *idx >= 0 && *idx < SIZE(sir_Terry_novels))
1595         return sir_Terry_novels[*idx];
1596
1597     return (const char *) 0;
1598 }
1599
1600 /*do_name.c*/