OSDN Git Service

remove unused code
[jnethack/source.git] / src / do_name.c
1 /* NetHack 3.6  do_name.c       $NHDT-Date: 1519420054 2018/02/23 21:07:34 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.128 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Pasi Kallinen, 2018. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 STATIC_DCL char *NDECL(nextmbuf);
14 STATIC_DCL void FDECL(getpos_help, (BOOLEAN_P, const char *));
15 STATIC_DCL int FDECL(CFDECLSPEC cmp_coord_distu, (const void *, const void *));
16 STATIC_DCL boolean FDECL(gather_locs_interesting, (int, int, int));
17 STATIC_DCL void FDECL(gather_locs, (coord **, int *, int));
18 STATIC_DCL int FDECL(gloc_filter_floodfill_matcharea, (int, int));
19 STATIC_DCL void FDECL(auto_describe, (int, int));
20 STATIC_DCL void NDECL(do_mname);
21 STATIC_DCL boolean FDECL(alreadynamed, (struct monst *, char *, char *));
22 STATIC_DCL void FDECL(do_oname, (struct obj *));
23 STATIC_PTR char *FDECL(docall_xname, (struct obj *));
24 STATIC_DCL void NDECL(namefloorobj);
25 STATIC_DCL char *FDECL(bogusmon, (char *,char *));
26
27 extern const char what_is_an_unknown_object[]; /* from pager.c */
28
29 #define NUMMBUF 5
30
31 /* manage a pool of BUFSZ buffers, so callers don't have to */
32 STATIC_OVL char *
33 nextmbuf()
34 {
35     static char NEARDATA bufs[NUMMBUF][BUFSZ];
36     static int bufidx = 0;
37
38     bufidx = (bufidx + 1) % NUMMBUF;
39     return bufs[bufidx];
40 }
41
42 /* function for getpos() to highlight desired map locations.
43  * parameter value 0 = initialize, 1 = highlight, 2 = done
44  */
45 static void FDECL((*getpos_hilitefunc), (int)) = (void FDECL((*), (int))) 0;
46 static boolean FDECL((*getpos_getvalid), (int, int)) =
47                                            (boolean FDECL((*), (int, int))) 0;
48
49 void
50 getpos_sethilite(gp_hilitef, gp_getvalidf)
51 void FDECL((*gp_hilitef), (int));
52 boolean FDECL((*gp_getvalidf), (int, int));
53 {
54     getpos_hilitefunc = gp_hilitef;
55     getpos_getvalid = gp_getvalidf;
56 }
57
58 /*JP:
59   [0] "cannot see %s"
60   [1] "pick a %s"
61   [2] "use XXX to move the cursor to %s"
62   */
63 const char *const gloc_descr[NUM_GLOCS][4] = {
64 #if 0 /*JP*/
65     { "any monsters", "monster", "next monster", "monsters" },
66     { "any items", "item", "next object", "objects" },
67     { "any doors", "door", "next door or doorway", "doors or doorways" },
68     { "any unexplored areas", "unexplored area", "unexplored location",
69       "unexplored locations" },
70     { "anything interesting", "interesting thing", "anything interesting",
71       "anything interesting" }
72 #else
73     { "\89ö\95¨", "\89ö\95¨", "\89ö\95¨\82Ì\97×", "\89ö\95¨" },
74     { "\95¨", "\95¨", "\95¨\82Ì\97×", "\95¨" },
75     { "\94à", "\94à", "\94à\82â\8fo\93ü\82è\8cû\82Ì\97×", "\94à\82â\8fo\93ü\82è\8cû" },
76     { "\96¢\92T\8dõ\95\94\95ª", "\96¢\92T\8dõ\95\94\95ª", "\96¢\92T\8dõ\82Ì\88Ê\92u", "\96¢\92T\8dõ\82Ì\88Ê\92u" },
77     { "\8aÖ\90S\82Ì\82 \82é\82à\82Ì", "\8aÖ\90S\82Ì\82 \82é\82à\82Ì", "\8aÖ\90S\82Ì\82 \82é\82à\82Ì", "\8aÖ\90S\82Ì\82 \82é\82à\82Ì" }
78 #endif
79 };
80
81 const char *const gloc_filtertxt[NUM_GFILTER] = {
82 #if 0 /*JP*/
83     "",
84     " in view",
85     " in this area"
86 #else
87     "",
88     "\8e\8b\8aE\82Ì\92\86\82Ì",
89     "\82±\82Ì\83G\83\8a\83A\82Ì"
90 #endif
91 };
92
93 void
94 getpos_help_keyxhelp(tmpwin, k1, k2, gloc)
95 winid tmpwin;
96 const char *k1;
97 const char *k2;
98 int gloc;
99 {
100     char sbuf[BUFSZ];
101
102 #if 0 /*JP*/
103     Sprintf(sbuf, "Use '%s' or '%s' to %s%s%s.",
104             k1, k2,
105             iflags.getloc_usemenu ? "get a menu of "
106                                   : "move the cursor to ",
107             gloc_descr[gloc][2 + iflags.getloc_usemenu],
108             gloc_filtertxt[iflags.getloc_filter]);
109 #else
110     Sprintf(sbuf, "'%s'\82©'%s'\82Å%s%s%s\81D",
111             k1, k2,
112             gloc_filtertxt[iflags.getloc_filter],
113             gloc_descr[gloc][2 + iflags.getloc_usemenu],
114             iflags.getloc_usemenu ? "\82Ì\83\81\83j\83\85\81[\82ð\8fo\82·"
115                                   : "\82É\83J\81[\83\\83\8b\82ð\93®\82©\82·");
116 #endif
117     putstr(tmpwin, 0, sbuf);
118 }
119
120 /* the response for '?' help request in getpos() */
121 STATIC_OVL void
122 getpos_help(force, goal)
123 boolean force;
124 const char *goal;
125 {
126     char sbuf[BUFSZ];
127     boolean doing_what_is;
128     winid tmpwin = create_nhwindow(NHW_MENU);
129 #if 0 /*JP*/
130     const char *const fastmovemode[2] = { "8 units at a time",
131                                           "skipping same glyphs" };
132 #else
133     const char *const fastmovemode[2] = { "\88ê\93x\82É8\83}\83X",
134                                           "\93¯\82\92n\8c`\82ð\94ò\82Î\82µ\82Ä" };
135 #endif
136
137     Sprintf(sbuf,
138 #if 0 /*JP*/
139             "Use '%c', '%c', '%c', '%c' to move the cursor to %s.", /* hjkl */
140 #else
141             "[%c%c%c%c]\82Å%s\82Ö\88Ú\93®\82Å\82«\82é\81D",
142 #endif
143             Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, goal);
144     putstr(tmpwin, 0, sbuf);
145 #if 0 /*JP*/
146     Sprintf(sbuf,
147             "Use 'H', 'J', 'K', 'L' to fast-move the cursor, %s.",
148             fastmovemode[iflags.getloc_moveskip]);
149 #else
150     Sprintf(sbuf,
151             "'H', 'J', 'K', 'L' \82Å%s\88Ú\93®\82Å\82«\82é\81D",
152             fastmovemode[iflags.getloc_moveskip]);
153 #endif
154     putstr(tmpwin, 0, sbuf);
155 /*JP
156     putstr(tmpwin, 0, "Or enter a background symbol (ex. '<').");
157 */
158     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");
159 #if 0 /*JP*/
160     Sprintf(sbuf, "Use '%s' to move the cursor on yourself.",
161            visctrl(Cmd.spkeys[NHKF_GETPOS_SELF]));
162 #else
163     Sprintf(sbuf, "'%s'\82Å\8e©\95ª\8e©\90g\82Ì\88Ê\92u\82É\88Ú\93®\82·\82é\81D",
164            visctrl(Cmd.spkeys[NHKF_GETPOS_SELF]));
165 #endif
166     putstr(tmpwin, 0, sbuf);
167     if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) {
168         getpos_help_keyxhelp(tmpwin,
169                              visctrl(Cmd.spkeys[NHKF_GETPOS_MON_NEXT]),
170                              visctrl(Cmd.spkeys[NHKF_GETPOS_MON_PREV]),
171                              GLOC_MONS);
172     }
173     if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) {
174         getpos_help_keyxhelp(tmpwin,
175                              visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_NEXT]),
176                              visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_PREV]),
177                              GLOC_OBJS);
178     }
179     if (!iflags.terrainmode || (iflags.terrainmode & TER_MAP) != 0) {
180         /* these are primarily useful when choosing a travel
181            destination for the '_' command */
182         getpos_help_keyxhelp(tmpwin,
183                              visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_NEXT]),
184                              visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_PREV]),
185                              GLOC_DOOR);
186         getpos_help_keyxhelp(tmpwin,
187                              visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_NEXT]),
188                              visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_PREV]),
189                              GLOC_EXPLORE);
190         getpos_help_keyxhelp(tmpwin,
191                              visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_NEXT]),
192                              visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_PREV]),
193                              GLOC_INTERESTING);
194     }
195 #if 0 /*JP*/
196     Sprintf(sbuf, "Use '%s' to change fast-move mode to %s.",
197             visctrl(Cmd.spkeys[NHKF_GETPOS_MOVESKIP]),
198             fastmovemode[!iflags.getloc_moveskip]);
199 #else
200     Sprintf(sbuf, "'%s'\82Å\8d\82\91¬\88Ú\93®\83\82\81[\83h\82ð%s\88Ú\93®\82É\82·\82é\81D",
201             visctrl(Cmd.spkeys[NHKF_GETPOS_MOVESKIP]),
202             fastmovemode[!iflags.getloc_moveskip]);
203 #endif
204     putstr(tmpwin, 0, sbuf);
205     if (!iflags.terrainmode || (iflags.terrainmode & TER_DETECT) == 0) {
206 #if 0 /*JP*/
207         Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.",
208                 visctrl(Cmd.spkeys[NHKF_GETPOS_MENU]));
209 #else
210         Sprintf(sbuf, "'%s'\82Å\89Â\94\\82È\83^\81[\83Q\83b\83g\82Ì\83\81\83j\83\85\81[\95\\8e¦\82ð\90Ø\82è\91Ö\82¦\82é\81D",
211                 visctrl(Cmd.spkeys[NHKF_GETPOS_MENU]));
212 #endif
213         putstr(tmpwin, 0, sbuf);
214 #if 0 /*JP*/
215         Sprintf(sbuf,
216                 "Use '%s' to change the mode of limiting possible targets.",
217                 visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]));
218 #else
219         Sprintf(sbuf,
220                 "'%s'\82Å\90§\8cÀ\82³\82ê\82½\89Â\94\\82È\83^\81[\83Q\83b\83g\82Ì\83\82\81[\83h\82ð\90Ø\82è\91Ö\82¦\82é\81D",
221                 visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]));
222 #endif
223         putstr(tmpwin, 0, sbuf);
224     }
225     if (!iflags.terrainmode) {
226         char kbuf[BUFSZ];
227
228         if (getpos_getvalid) {
229 #if 0 /*JP*/
230             Sprintf(sbuf, "Use '%s' or '%s' to move to valid locations.",
231                     visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_NEXT]),
232                     visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_PREV]));
233 #else
234             Sprintf(sbuf, "'%s'\82©'%s'\82Å\90³\93\96\82È\88Ê\92u\82É\88Ú\93®\82·\82é\81D",
235                     visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_NEXT]),
236                     visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_PREV]));
237 #endif
238             putstr(tmpwin, 0, sbuf);
239         }
240         if (getpos_hilitefunc) {
241 #if 0 /*JP:T*/
242             Sprintf(sbuf, "Use '%s' to display valid locations.",
243                     visctrl(Cmd.spkeys[NHKF_GETPOS_SHOWVALID]));
244 #else
245             Sprintf(sbuf, "'%s'\82Å\89Â\94\\82È\88Ê\92u\82ð\95\\8e¦\82·\82é\81D",
246                     visctrl(Cmd.spkeys[NHKF_GETPOS_SHOWVALID]));
247 #endif
248             putstr(tmpwin, 0, sbuf);
249         }
250 #if 0 /*JP:T*/
251         Sprintf(sbuf, "Use '%s' to toggle automatic description.",
252                 visctrl(Cmd.spkeys[NHKF_GETPOS_AUTODESC]));
253 #else
254         Sprintf(sbuf, "'%s'\82Å\90à\96¾\82Ì\8e©\93®\95\\8e¦\82ð\90Ø\82è\91Ö\82¦\82é\81D",
255                 visctrl(Cmd.spkeys[NHKF_GETPOS_AUTODESC]));
256 #endif
257         putstr(tmpwin, 0, sbuf);
258         if (iflags.cmdassist) { /* assisting the '/' command, I suppose... */
259 #if 0 /*JP*/
260             Sprintf(sbuf,
261                     (iflags.getpos_coords == GPCOORDS_NONE)
262          ? "(Set 'whatis_coord' option to include coordinates with '%s' text.)"
263          : "(Reset 'whatis_coord' option to omit coordinates from '%s' text.)",
264                     visctrl(Cmd.spkeys[NHKF_GETPOS_AUTODESC]));
265 #else
266             Sprintf(sbuf,
267                     (iflags.getpos_coords == GPCOORDS_NONE)
268          ? "('%s'\82É\8dÀ\95W\82ð\8aÜ\82Þ\82É\82Í'whatis_coord'\83I\83v\83V\83\87\83\93\82ð\83I\83\93\82É\82·\82é\81D)"
269          : "('%s'\82©\82ç\8dÀ\95W\82ð\8f\9c\82­\82É\82Í'whatis_coord'\83I\83v\83V\83\87\83\93\82ð\83I\83t\82É\82·\82é\81D)",
270                     visctrl(Cmd.spkeys[NHKF_GETPOS_AUTODESC]));
271 #endif
272         }
273         /* disgusting hack; the alternate selection characters work for any
274            getpos call, but only matter for dowhatis (and doquickwhatis) */
275         doing_what_is = (goal == what_is_an_unknown_object);
276         if (doing_what_is) {
277 #if 0 /*JP*/
278             Sprintf(kbuf, "'%s' or '%s' or '%s' or '%s'",
279                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
280                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_Q]),
281                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_O]),
282                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V]));
283 #else
284             Sprintf(kbuf, "'%s'\82©'%s'\82©'%s'\82©'%s'",
285                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
286                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_Q]),
287                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_O]),
288                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V]));
289 #endif
290         } else {
291             Sprintf(kbuf, "'%s'", visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]));
292         }
293 #if 0 /*JP:T*/
294         Sprintf(sbuf, "Type a %s when you are at the right place.", kbuf);
295 #else
296         Sprintf(sbuf, "[.]%s\82Å\8c\88\92è\81D", kbuf);
297 #endif
298         putstr(tmpwin, 0, sbuf);
299         if (doing_what_is) {
300 #if 0 /*JP*/
301             Sprintf(sbuf,
302        "  '%s' describe current spot, show 'more info', move to another spot.",
303                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V]));
304 #else
305             Sprintf(sbuf,
306        "  '%s'\82Í\8c»\8dÝ\82Ì\88Ê\92u\82ð\90à\96¾\82µ\81A\92Ç\89Á\8fî\95ñ\82ð\95\\8e¦\82µ\81A\8e\9f\82Ì\88Ê\92u\82É\88Ú\93®\82·\82é\81D",
307                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V]));
308 #endif
309             putstr(tmpwin, 0, sbuf);
310 #if 0 /*JP*/
311             Sprintf(sbuf,
312                     "  '%s' describe current spot,%s move to another spot;",
313                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
314                     flags.help ? " prompt if 'more info'," : "");
315 #else
316             Sprintf(sbuf,
317                     "  '%s'\82Í\8c»\8dÝ\82Ì\88Ê\92u\82ð\90à\96¾\82µ\81C%s\8e\9f\82Ì\88Ê\92u\82É\88Ú\93®\82·\82é;",
318                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]),
319                     flags.help ? "\92Ç\89Á\8fî\95ñ\82ª\82 \82ê\82Î\8am\94F\82µ\81C" : "");
320 #endif
321             putstr(tmpwin, 0, sbuf);
322 #if 0 /*JP*/
323             Sprintf(sbuf,
324                     "  '%s' describe current spot, move to another spot;",
325                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_Q]));
326 #else
327             Sprintf(sbuf,
328                     "  '%s'\82Í\8c»\8dÝ\82Ì\88Ê\92u\82ð\90à\96¾\82µ\81C\8e\9f\82Ì\88Ê\92u\82É\88Ú\93®\82·\82é;",
329                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_Q]));
330 #endif
331             putstr(tmpwin, 0, sbuf);
332 #if 0 /*JP*/
333             Sprintf(sbuf,
334                     "  '%s' describe current spot, stop looking at things;",
335                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_O]));
336 #else
337             Sprintf(sbuf,
338                     "  '%s'\82Í\8c»\8dÝ\82Ì\88Ê\92u\82ð\90à\96¾\82µ\81C\8c©\82é\82Ì\82ð\82â\82ß\82é;",
339                     visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_O]));
340 #endif
341             putstr(tmpwin, 0, sbuf);
342         }
343     }
344     if (!force)
345 /*JP
346         putstr(tmpwin, 0, "Type Space or Escape when you're done.");
347 */
348         putstr(tmpwin, 0, "\83X\83y\81[\83X\82Ü\82½\82Í\83G\83X\83P\81[\83v\82Å\8fI\97¹\81D");
349     putstr(tmpwin, 0, "");
350     display_nhwindow(tmpwin, TRUE);
351     destroy_nhwindow(tmpwin);
352 }
353
354 STATIC_OVL int
355 cmp_coord_distu(a, b)
356 const void *a;
357 const void *b;
358 {
359     const coord *c1 = a;
360     const coord *c2 = b;
361     int dx, dy, dist_1, dist_2;
362
363     dx = u.ux - c1->x;
364     dy = u.uy - c1->y;
365     dist_1 = max(abs(dx), abs(dy));
366     dx = u.ux - c2->x;
367     dy = u.uy - c2->y;
368     dist_2 = max(abs(dx), abs(dy));
369
370     if (dist_1 == dist_2)
371         return (c1->y != c2->y) ? (c1->y - c2->y) : (c1->x - c2->x);
372
373     return dist_1 - dist_2;
374 }
375
376 #define IS_UNEXPLORED_LOC(x,y) \
377     (isok((x), (y))                                     \
378      && glyph_is_cmap(levl[(x)][(y)].glyph)             \
379      && glyph_to_cmap(levl[(x)][(y)].glyph) == S_stone  \
380      && !levl[(x)][(y)].seenv)
381
382 static struct opvar *gloc_filter_map = (struct opvar *) 0;
383
384 #define GLOC_SAME_AREA(x,y)                                     \
385     (isok((x), (y))                                             \
386      && (selection_getpoint((x),(y), gloc_filter_map)))
387
388 static int gloc_filter_floodfill_match_glyph;
389
390 int
391 gloc_filter_classify_glyph(glyph)
392 int glyph;
393 {
394     int c;
395
396     if (!glyph_is_cmap(glyph))
397         return 0;
398
399     c = glyph_to_cmap(glyph);
400
401     if (is_cmap_room(c) || is_cmap_furniture(c))
402         return 1;
403     else if (is_cmap_wall(c) || c == S_tree)
404         return 2;
405     else if (is_cmap_corr(c))
406         return 3;
407     else if (is_cmap_water(c))
408         return 4;
409     else if (is_cmap_lava(c))
410         return 5;
411     return 0;
412 }
413
414 STATIC_OVL int
415 gloc_filter_floodfill_matcharea(x,y)
416 int x,y;
417 {
418     int glyph = back_to_glyph(x, y);
419
420     if (!levl[x][y].seenv)
421         return FALSE;
422
423     if (glyph == gloc_filter_floodfill_match_glyph)
424         return TRUE;
425
426     if (gloc_filter_classify_glyph(glyph)
427         == gloc_filter_classify_glyph(gloc_filter_floodfill_match_glyph))
428         return TRUE;
429
430     return FALSE;
431 }
432
433 void
434 gloc_filter_floodfill(x, y)
435 int x, y;
436 {
437     gloc_filter_floodfill_match_glyph = back_to_glyph(x, y);
438
439     set_selection_floodfillchk(gloc_filter_floodfill_matcharea);
440     selection_floodfill(gloc_filter_map, x, y, FALSE);
441 }
442
443 void
444 gloc_filter_init()
445 {
446     if (iflags.getloc_filter == GFILTER_AREA) {
447         if (!gloc_filter_map) {
448             gloc_filter_map = selection_opvar(NULL);
449         }
450         /* special case: if we're in a doorway, try to figure out which
451            direction we're moving, and use that side of the doorway */
452         if (IS_DOOR(levl[u.ux][u.uy].typ)) {
453             if (u.dx || u.dy) {
454                 gloc_filter_floodfill(u.ux + u.dx, u.uy + u.dy);
455             } else {
456                 /* TODO: maybe add both sides of the doorway? */
457             }
458         } else {
459             gloc_filter_floodfill(u.ux, u.uy);
460         }
461
462
463     }
464 }
465
466 void
467 gloc_filter_done()
468 {
469     if (gloc_filter_map) {
470         opvar_free_x(gloc_filter_map);
471         gloc_filter_map = NULL;
472     }
473 }
474
475 STATIC_OVL boolean
476 gather_locs_interesting(x, y, gloc)
477 int x, y, gloc;
478 {
479     /* TODO: if glyph is a pile glyph, convert to ordinary one
480      *       in order to keep tail/boulder/rock check simple.
481      */
482     int glyph = glyph_at(x, y);
483
484     if (iflags.getloc_filter == GFILTER_VIEW && !cansee(x, y))
485         return FALSE;
486     if (iflags.getloc_filter == GFILTER_AREA && !GLOC_SAME_AREA(x, y)
487         && !GLOC_SAME_AREA(x - 1, y) && !GLOC_SAME_AREA(x, y - 1)
488         && !GLOC_SAME_AREA(x + 1, y) && !GLOC_SAME_AREA(x, y + 1))
489         return FALSE;
490
491     switch (gloc) {
492     default:
493     case GLOC_MONS:
494         /* unlike '/M', this skips monsters revealed by
495            warning glyphs and remembered unseen ones */
496         return (glyph_is_monster(glyph)
497                 && glyph != monnum_to_glyph(PM_LONG_WORM_TAIL));
498     case GLOC_OBJS:
499         return (glyph_is_object(glyph)
500                 && glyph != objnum_to_glyph(BOULDER)
501                 && glyph != objnum_to_glyph(ROCK));
502     case GLOC_DOOR:
503         return (glyph_is_cmap(glyph)
504                 && (is_cmap_door(glyph_to_cmap(glyph))
505                     || is_cmap_drawbridge(glyph_to_cmap(glyph))
506                     || glyph_to_cmap(glyph) == S_ndoor));
507     case GLOC_EXPLORE:
508         return (glyph_is_cmap(glyph)
509                 && (is_cmap_door(glyph_to_cmap(glyph))
510                     || is_cmap_drawbridge(glyph_to_cmap(glyph))
511                     || glyph_to_cmap(glyph) == S_ndoor
512                     || glyph_to_cmap(glyph) == S_room
513                     || glyph_to_cmap(glyph) == S_darkroom
514                     || glyph_to_cmap(glyph) == S_corr
515                     || glyph_to_cmap(glyph) == S_litcorr)
516                 && (IS_UNEXPLORED_LOC(x + 1, y)
517                     || IS_UNEXPLORED_LOC(x - 1, y)
518                     || IS_UNEXPLORED_LOC(x, y + 1)
519                     || IS_UNEXPLORED_LOC(x, y - 1)));
520     case GLOC_INTERESTING:
521         return gather_locs_interesting(x,y, GLOC_DOOR)
522             || !(glyph_is_cmap(glyph)
523                  && (is_cmap_wall(glyph_to_cmap(glyph))
524                      || glyph_to_cmap(glyph) == S_tree
525                      || glyph_to_cmap(glyph) == S_bars
526                      || glyph_to_cmap(glyph) == S_ice
527                      || glyph_to_cmap(glyph) == S_air
528                      || glyph_to_cmap(glyph) == S_cloud
529                      || glyph_to_cmap(glyph) == S_lava
530                      || glyph_to_cmap(glyph) == S_water
531                      || glyph_to_cmap(glyph) == S_pool
532                      || glyph_to_cmap(glyph) == S_ndoor
533                      || glyph_to_cmap(glyph) == S_room
534                      || glyph_to_cmap(glyph) == S_darkroom
535                      || glyph_to_cmap(glyph) == S_corr
536                      || glyph_to_cmap(glyph) == S_litcorr));
537     case GLOC_VALID:
538         return (getpos_getvalid && getpos_getvalid(x,y));
539     }
540     /*NOTREACHED*/
541     return FALSE;
542 }
543
544 /* gather locations for monsters or objects shown on the map */
545 STATIC_OVL void
546 gather_locs(arr_p, cnt_p, gloc)
547 coord **arr_p;
548 int *cnt_p;
549 int gloc;
550 {
551     int x, y, pass, idx;
552
553     /*
554      * We always include the hero's location even if there is no monster
555      * (invisible hero without see invisible) or object (usual case)
556      * displayed there.  That way, the count will always be at least 1,
557      * and player has a visual indicator (cursor returns to hero's spot)
558      * highlighting when successive 'm's or 'o's have cycled all the way
559      * through all monsters or objects.
560      *
561      * Hero's spot will always sort to array[0] because it will always
562      * be the shortest distance (namely, 0 units) away from <u.ux,u.uy>.
563      */
564
565     gloc_filter_init();
566
567     *cnt_p = idx = 0;
568     for (pass = 0; pass < 2; pass++) {
569         for (x = 1; x < COLNO; x++)
570             for (y = 0; y < ROWNO; y++) {
571                 if ((x == u.ux && y == u.uy)
572                     || gather_locs_interesting(x, y, gloc)) {
573                     if (!pass) {
574                         ++*cnt_p;
575                     } else {
576                         (*arr_p)[idx].x = x;
577                         (*arr_p)[idx].y = y;
578                         ++idx;
579                     }
580                 }
581             }
582
583         if (!pass) /* end of first pass */
584             *arr_p = (coord *) alloc(*cnt_p * sizeof (coord));
585         else /* end of second pass */
586             qsort(*arr_p, *cnt_p, sizeof (coord), cmp_coord_distu);
587     } /* pass */
588
589     gloc_filter_done();
590 }
591
592 char *
593 dxdy_to_dist_descr(dx, dy, fulldir)
594 int dx, dy;
595 boolean fulldir;
596 {
597     static char buf[30];
598     int dst;
599
600     if (!dx && !dy) {
601 /*JP
602         Sprintf(buf, "here");
603 */
604         Sprintf(buf, "\82±\82±");
605     } else if ((dst = xytod(dx, dy)) != -1) {
606         /* explicit direction; 'one step' is implicit */
607         Sprintf(buf, "%s", directionname(dst));
608     } else {
609         const char *dirnames[4][2] = {
610 #if 0 /*JP*/
611             { "n", "north" },
612             { "s", "south" },
613             { "w", "west" },
614             { "e", "east" } };
615 #else
616             { "n", "\96k" },
617             { "s", "\93ì" },
618             { "w", "\90¼" },
619             { "e", "\93\8c" } };
620 #endif
621         buf[0] = '\0';
622         /* 9999: protect buf[] against overflow caused by invalid values */
623         if (dy) {
624             if (abs(dy) > 9999)
625                 dy = sgn(dy) * 9999;
626             Sprintf(eos(buf), "%d%s%s", abs(dy), dirnames[(dy > 0)][fulldir],
627                     dx ? "," : "");
628         }
629         if (dx) {
630             if (abs(dx) > 9999)
631                 dx = sgn(dx) * 9999;
632             Sprintf(eos(buf), "%d%s", abs(dx),
633                     dirnames[2 + (dx > 0)][fulldir]);
634         }
635     }
636     return buf;
637 }
638
639 /* coordinate formatting for 'whatis_coord' option */
640 char *
641 coord_desc(x, y, outbuf, cmode)
642 int x, y;
643 char *outbuf, cmode;
644 {
645     static char screen_fmt[16]; /* [12] suffices: "[%02d,%02d]" */
646     int dx, dy;
647
648     outbuf[0] = '\0';
649     switch (cmode) {
650     default:
651         break;
652     case GPCOORDS_COMFULL:
653     case GPCOORDS_COMPASS:
654         /* "east", "3s", "2n,4w" */
655         dx = x - u.ux;
656         dy = y - u.uy;
657         Sprintf(outbuf, "(%s)",
658                 dxdy_to_dist_descr(dx, dy, cmode == GPCOORDS_COMFULL));
659         break;
660     case GPCOORDS_MAP: /* x,y */
661         /* upper left corner of map is <1,0>;
662            with default COLNO,ROWNO lower right corner is <79,20> */
663         Sprintf(outbuf, "<%d,%d>", x, y);
664         break;
665     case GPCOORDS_SCREEN: /* y+2,x */
666         /* for normal map sizes, force a fixed-width formatting so that
667            /m, /M, /o, and /O output lines up cleanly; map sizes bigger
668            than Nx999 or 999xM will still work, but not line up like normal
669            when displayed in a column setting */
670         if (!*screen_fmt)
671             Sprintf(screen_fmt, "[%%%sd,%%%sd]",
672                     (ROWNO - 1 + 2 < 100) ? "02" :  "03",
673                     (COLNO - 1 < 100) ? "02" : "03");
674         /* map line 0 is screen row 2;
675            map column 0 isn't used, map column 1 is screen column 1 */
676         Sprintf(outbuf, screen_fmt, y + 2, x);
677         break;
678     }
679     return outbuf;
680 }
681
682 STATIC_OVL void
683 auto_describe(cx, cy)
684 int cx, cy;
685 {
686     coord cc;
687     int sym = 0;
688     char tmpbuf[BUFSZ];
689 /*JP
690     const char *firstmatch = "unknown";
691 */
692     const char *firstmatch = "\95s\96¾";
693
694     cc.x = cx;
695     cc.y = cy;
696     if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
697         (void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords);
698 #if 0 /*JP*/
699         custompline(SUPPRESS_HISTORY,
700                     "%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
701                     (iflags.autodescribe
702                      && getpos_getvalid && !getpos_getvalid(cx, cy))
703                       ? " (illegal)" : "",
704                     (iflags.getloc_travelmode && !is_valid_travelpt(cx, cy))
705                       ? " (no travel path)" : "");
706 #else
707         custompline(SUPPRESS_HISTORY,
708                     "%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
709                     (iflags.autodescribe
710                      && getpos_getvalid && !getpos_getvalid(cx, cy))
711                       ? " (\95s\90³)" : "",
712                     (iflags.getloc_travelmode && !is_valid_travelpt(cx, cy))
713                       ? " (\8co\98H\82È\82µ)" : "");
714 #endif
715         curs(WIN_MAP, cx, cy);
716         flush_screen(0);
717     }
718 }
719
720 boolean
721 getpos_menu(ccp, gloc)
722 coord *ccp;
723 int gloc;
724 {
725     coord *garr = DUMMY;
726     int gcount = 0;
727     winid tmpwin;
728     anything any;
729     int i, pick_cnt;
730     menu_item *picks = (menu_item *) 0;
731     char tmpbuf[BUFSZ];
732
733     gather_locs(&garr, &gcount, gloc);
734
735     if (gcount < 2) { /* gcount always includes the hero */
736         free((genericptr_t) garr);
737 #if 0 /*JP*/
738         You("cannot %s %s.",
739             iflags.getloc_filter == GFILTER_VIEW ? "see" : "detect",
740             gloc_descr[gloc][0]);
741 #else
742         You("%s\82ð%s\82±\82Æ\82ª\82Å\82«\82È\82¢\81D",
743             gloc_descr[gloc][0],
744             iflags.getloc_filter == GFILTER_VIEW ? "\8c©\82é" : "\8c©\82Â\82¯\82é");
745 #endif
746         return FALSE;
747     }
748
749     tmpwin = create_nhwindow(NHW_MENU);
750     start_menu(tmpwin);
751     any = zeroany;
752
753     /* gather_locs returns array[0] == you. skip it. */
754     for (i = 1; i < gcount; i++) {
755         char fullbuf[BUFSZ];
756         coord tmpcc;
757 /*JP
758         const char *firstmatch = "unknown";
759 */
760         const char *firstmatch = "\95s\96¾";
761         int sym = 0;
762         any.a_int = i + 1;
763         tmpcc.x = garr[i].x;
764         tmpcc.y = garr[i].y;
765         if (do_screen_description(tmpcc, TRUE, sym, tmpbuf, &firstmatch)) {
766             (void) coord_desc(garr[i].x, garr[i].y, tmpbuf,
767                               iflags.getpos_coords);
768             Sprintf(fullbuf, "%s%s%s", firstmatch,
769                     (*tmpbuf ? " " : ""), tmpbuf);
770             add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, fullbuf,
771                      MENU_UNSELECTED);
772         }
773     }
774
775 #if 0 /*JP*/
776     Sprintf(tmpbuf, "Pick a target %s%s%s",
777             gloc_descr[gloc][1],
778             gloc_filtertxt[iflags.getloc_filter],
779             iflags.getloc_travelmode ? " for travel" : "");
780 #else
781     Sprintf(tmpbuf, "%s%s\82Å\96Ú\95W\82Æ\82·\82é%s\82ð\91I\91ð\82µ\82Ä\82­\82¾\82³\82¢",
782             iflags.getloc_travelmode ? "\88Ú\93®\82Ì\82½\82ß\82É" : "",
783             gloc_filtertxt[iflags.getloc_filter],
784             gloc_descr[gloc][1]);
785 #endif
786     end_menu(tmpwin, tmpbuf);
787     pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
788     destroy_nhwindow(tmpwin);
789     if (pick_cnt > 0) {
790         ccp->x = garr[picks->item.a_int - 1].x;
791         ccp->y = garr[picks->item.a_int - 1].y;
792         free((genericptr_t) picks);
793     }
794     free((genericptr_t) garr);
795     return (pick_cnt > 0);
796 }
797
798 int
799 getpos(ccp, force, goal)
800 coord *ccp;
801 boolean force;
802 const char *goal;
803 {
804     const char *cp;
805     struct {
806         int nhkf, ret;
807     } const pick_chars_def[] = {
808         { NHKF_GETPOS_PICK, LOOK_TRADITIONAL },
809         { NHKF_GETPOS_PICK_Q, LOOK_QUICK },
810         { NHKF_GETPOS_PICK_O, LOOK_ONCE },
811         { NHKF_GETPOS_PICK_V, LOOK_VERBOSE }
812     };
813     const int mMoOdDxX_def[] = {
814         NHKF_GETPOS_MON_NEXT,
815         NHKF_GETPOS_MON_PREV,
816         NHKF_GETPOS_OBJ_NEXT,
817         NHKF_GETPOS_OBJ_PREV,
818         NHKF_GETPOS_DOOR_NEXT,
819         NHKF_GETPOS_DOOR_PREV,
820         NHKF_GETPOS_UNEX_NEXT,
821         NHKF_GETPOS_UNEX_PREV,
822         NHKF_GETPOS_INTERESTING_NEXT,
823         NHKF_GETPOS_INTERESTING_PREV,
824         NHKF_GETPOS_VALID_NEXT,
825         NHKF_GETPOS_VALID_PREV
826     };
827     char pick_chars[6];
828     char mMoOdDxX[13];
829     int result = 0;
830     int cx, cy, i, c;
831     int sidx, tx, ty;
832     boolean msg_given = TRUE; /* clear message window by default */
833     boolean show_goal_msg = FALSE;
834     boolean hilite_state = FALSE;
835     coord *garr[NUM_GLOCS] = DUMMY;
836     int gcount[NUM_GLOCS] = DUMMY;
837     int gidx[NUM_GLOCS] = DUMMY;
838
839     for (i = 0; i < SIZE(pick_chars_def); i++)
840         pick_chars[i] = Cmd.spkeys[pick_chars_def[i].nhkf];
841     pick_chars[SIZE(pick_chars_def)] = '\0';
842
843     for (i = 0; i < SIZE(mMoOdDxX_def); i++)
844         mMoOdDxX[i] = Cmd.spkeys[mMoOdDxX_def[i]];
845     mMoOdDxX[SIZE(mMoOdDxX_def)] = '\0';
846
847     if (!goal)
848 /*JP
849         goal = "desired location";
850 */
851         goal = "\96Ú\93I\92n";
852     if (flags.verbose) {
853 #if 0 /*JP*/
854         pline("(For instructions type a '%s')",
855               visctrl(Cmd.spkeys[NHKF_GETPOS_HELP]));
856 #else
857         pline("('%s'\82Å\83w\83\8b\83v)",
858               visctrl(Cmd.spkeys[NHKF_GETPOS_HELP]));
859 #endif
860         msg_given = TRUE;
861     }
862     cx = ccp->x;
863     cy = ccp->y;
864 #ifdef CLIPPING
865     cliparound(cx, cy);
866 #endif
867     curs(WIN_MAP, cx, cy);
868     flush_screen(0);
869 #ifdef MAC
870     lock_mouse_cursor(TRUE);
871 #endif
872     for (;;) {
873         if (show_goal_msg) {
874 /*JP
875             pline("Move cursor to %s:", goal);
876 */
877             pline("\83J\81[\83\\83\8b\82ð%s\82É\93®\82©\82µ\82Ä\82­\82¾\82³\82¢:", goal);
878             curs(WIN_MAP, cx, cy);
879             flush_screen(0);
880             show_goal_msg = FALSE;
881         } else if (iflags.autodescribe && !msg_given && !hilite_state) {
882             auto_describe(cx, cy);
883         }
884
885         c = nh_poskey(&tx, &ty, &sidx);
886
887         if (hilite_state) {
888             (*getpos_hilitefunc)(2);
889             hilite_state = FALSE;
890             curs(WIN_MAP, cx, cy);
891             flush_screen(0);
892         }
893
894         if (iflags.autodescribe)
895             msg_given = FALSE;
896
897         if (c == Cmd.spkeys[NHKF_ESC]) {
898             cx = cy = -10;
899             msg_given = TRUE; /* force clear */
900             result = -1;
901             break;
902         }
903         if (c == 0) {
904             if (!isok(tx, ty))
905                 continue;
906             /* a mouse click event, just assign and return */
907             cx = tx;
908             cy = ty;
909             break;
910         }
911         if ((cp = index(pick_chars, c)) != 0) {
912             /* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
913             result = pick_chars_def[(int) (cp - pick_chars)].ret;
914             break;
915         }
916         for (i = 0; i < 8; i++) {
917             int dx, dy;
918
919             if (Cmd.dirchars[i] == c) {
920                 /* a normal movement letter or digit */
921                 dx = xdir[i];
922                 dy = ydir[i];
923             } else if (Cmd.alphadirchars[i] == lowc((char) c)
924                        || (Cmd.num_pad && Cmd.dirchars[i] == (c & 0177))) {
925                 /* a shifted movement letter or Meta-digit */
926                 if (iflags.getloc_moveskip) {
927                     /* skip same glyphs */
928                     int glyph = glyph_at(cx, cy);
929
930                     dx = xdir[i];
931                     dy = ydir[i];
932                     while (isok(cx + dx, cy + dy)
933                            && glyph == glyph_at(cx + dx, cy + dy)
934                            && isok(cx + dx + xdir[i], cy + dy + ydir[i])
935                            && glyph == glyph_at(cx + dx + xdir[i],
936                                                 cy + dy + ydir[i])) {
937                         dx += xdir[i];
938                         dy += ydir[i];
939                     }
940                 } else {
941                     dx = 8 * xdir[i];
942                     dy = 8 * ydir[i];
943                 }
944             } else
945                 continue;
946
947             /* truncate at map edge; diagonal moves complicate this... */
948             if (cx + dx < 1) {
949                 dy -= sgn(dy) * (1 - (cx + dx));
950                 dx = 1 - cx; /* so that (cx+dx == 1) */
951             } else if (cx + dx > COLNO - 1) {
952                 dy += sgn(dy) * ((COLNO - 1) - (cx + dx));
953                 dx = (COLNO - 1) - cx;
954             }
955             if (cy + dy < 0) {
956                 dx -= sgn(dx) * (0 - (cy + dy));
957                 dy = 0 - cy; /* so that (cy+dy == 0) */
958             } else if (cy + dy > ROWNO - 1) {
959                 dx += sgn(dx) * ((ROWNO - 1) - (cy + dy));
960                 dy = (ROWNO - 1) - cy;
961             }
962             cx += dx;
963             cy += dy;
964             goto nxtc;
965         }
966
967         if (c == Cmd.spkeys[NHKF_GETPOS_HELP] || redraw_cmd(c)) {
968             if (c == Cmd.spkeys[NHKF_GETPOS_HELP])
969                 getpos_help(force, goal);
970             else /* ^R */
971                 docrt(); /* redraw */
972             /* update message window to reflect that we're still targetting */
973             show_goal_msg = TRUE;
974             msg_given = TRUE;
975         } else if (c == Cmd.spkeys[NHKF_GETPOS_SHOWVALID]
976                    && getpos_hilitefunc) {
977             if (!hilite_state) {
978                 (*getpos_hilitefunc)(0);
979                 (*getpos_hilitefunc)(1);
980                 hilite_state = TRUE;
981             }
982             goto nxtc;
983         } else if (c == Cmd.spkeys[NHKF_GETPOS_AUTODESC]) {
984             iflags.autodescribe = !iflags.autodescribe;
985 #if 0 /*JP:T*/
986             pline("Automatic description %sis %s.",
987                   flags.verbose ? "of features under cursor " : "",
988                   iflags.autodescribe ? "on" : "off");
989 #else
990             pline("%s\90à\96¾\8e©\93®\95\\8e¦\81F%s",
991                   flags.verbose ? "\83J\81[\83\\83\8b\82Ì\89º\82É\82 \82é\82à\82Ì\82Ì" : "",
992                   iflags.autodescribe ? "\83I\83\93" : "\83I\83t");
993 #endif
994             if (!iflags.autodescribe)
995                 show_goal_msg = TRUE;
996             msg_given = TRUE;
997             goto nxtc;
998         } else if (c == Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]) {
999             const char *const view_filters[NUM_GFILTER] = {
1000 #if 0 /*JP*/
1001                 "Not limiting targets",
1002                 "Limiting targets to in sight",
1003                 "Limiting targets to in same area"
1004 #else
1005                 "\83^\81[\83Q\83b\83g\82ð\90§\8cÀ\82µ\82È\82¢",
1006                 "\8e\8b\8aE\93à\82É\83^\81[\83Q\83b\83g\82ð\90§\8cÀ\82·\82é",
1007                 "\93¯\82\83G\83\8a\83A\82É\83^\81[\83Q\83b\83g\82ð\90§\8cÀ\82·\82é"
1008 #endif
1009             };
1010             iflags.getloc_filter = (iflags.getloc_filter + 1) % NUM_GFILTER;
1011             for (i = 0; i < NUM_GLOCS; i++) {
1012                 if (garr[i]) {
1013                     free((genericptr_t) garr[i]);
1014                     garr[i] = NULL;
1015                 }
1016                 gidx[i] = gcount[i] = 0;
1017             }
1018 /*JP
1019             pline("%s.", view_filters[iflags.getloc_filter]);
1020 */
1021             pline("%s\81D", view_filters[iflags.getloc_filter]);
1022             msg_given = TRUE;
1023             goto nxtc;
1024         } else if (c == Cmd.spkeys[NHKF_GETPOS_MENU]) {
1025             iflags.getloc_usemenu = !iflags.getloc_usemenu;
1026 #if 0 /*JP*/
1027             pline("%s a menu to show possible targets.",
1028                   iflags.getloc_usemenu ? "Using" : "Not using");
1029 #else
1030             pline("\89Â\94\\82È\83^\81[\83Q\83b\83g\82ð\8c©\82é\82Ì\82É\83\81\83j\83\85\81[\82ð\8eg%s\81D",
1031                   iflags.getloc_usemenu ? "\82¤" : "\82í\82È\82¢");
1032 #endif
1033             msg_given = TRUE;
1034             goto nxtc;
1035         } else if (c == Cmd.spkeys[NHKF_GETPOS_SELF]) {
1036             /* reset 'm&M', 'o&O', &c; otherwise, there's no way for player
1037                to achieve that except by manually cycling through all spots */
1038             for (i = 0; i < NUM_GLOCS; i++)
1039                 gidx[i] = 0;
1040             cx = u.ux;
1041             cy = u.uy;
1042             goto nxtc;
1043         } else if (c == Cmd.spkeys[NHKF_GETPOS_MOVESKIP]) {
1044             iflags.getloc_moveskip = !iflags.getloc_moveskip;
1045 #if 0 /*JP*/
1046             pline("%skipping over similar terrain when fastmoving the cursor.",
1047                   iflags.getloc_moveskip ? "S" : "Not s");
1048 #else
1049             pline("\83J\81[\83\\83\8b\82ð\8d\82\91¬\88Ú\93®\82³\82¹\82é\82Æ\82«\82É\8e\97\82½\82æ\82¤\82È\92n\8c`\82ð\94ò\82Î%s\81D",
1050                   iflags.getloc_moveskip ? "\82·" : "\82³\82È\82¢");
1051 #endif
1052         } else if ((cp = index(mMoOdDxX, c)) != 0) { /* 'm|M', 'o|O', &c */
1053             /* nearest or farthest monster or object or door or unexplored */
1054             int gtmp = (int) (cp - mMoOdDxX), /* 0..7 */
1055                 gloc = gtmp >> 1;             /* 0..3 */
1056
1057             if (iflags.getloc_usemenu) {
1058                 coord tmpcrd;
1059                 if (getpos_menu(&tmpcrd, gloc)) {
1060                     cx = tmpcrd.x;
1061                     cy = tmpcrd.y;
1062                 }
1063                 goto nxtc;
1064             }
1065
1066             if (!garr[gloc]) {
1067                 gather_locs(&garr[gloc], &gcount[gloc], gloc);
1068                 gidx[gloc] = 0; /* garr[][0] is hero's spot */
1069             }
1070             if (!(gtmp & 1)) {  /* c=='m' || c=='o' || c=='d' || c=='x') */
1071                 gidx[gloc] = (gidx[gloc] + 1) % gcount[gloc];
1072             } else {            /* c=='M' || c=='O' || c=='D' || c=='X') */
1073                 if (--gidx[gloc] < 0)
1074                     gidx[gloc] = gcount[gloc] - 1;
1075             }
1076             cx = garr[gloc][gidx[gloc]].x;
1077             cy = garr[gloc][gidx[gloc]].y;
1078             goto nxtc;
1079         } else {
1080             if (!index(quitchars, c)) {
1081                 char matching[MAXPCHARS];
1082                 int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
1083
1084                 (void) memset((genericptr_t) matching, 0, sizeof matching);
1085                 for (sidx = 1; sidx < MAXPCHARS; sidx++) { /* [0] left as 0 */
1086                     if (IS_DOOR(sidx) || IS_WALL(sidx)
1087                         || sidx == SDOOR || sidx == SCORR
1088                         || glyph_to_cmap(k) == S_room
1089                         || glyph_to_cmap(k) == S_darkroom
1090                         || glyph_to_cmap(k) == S_corr
1091                         || glyph_to_cmap(k) == S_litcorr)
1092                         continue;
1093                     if (c == defsyms[sidx].sym || c == (int) showsyms[sidx])
1094                         matching[sidx] = (char) ++k;
1095                 }
1096                 if (k) {
1097                     for (pass = 0; pass <= 1; pass++) {
1098                         /* pass 0: just past current pos to lower right;
1099                            pass 1: upper left corner to current pos */
1100                         lo_y = (pass == 0) ? cy : 0;
1101                         hi_y = (pass == 0) ? ROWNO - 1 : cy;
1102                         for (ty = lo_y; ty <= hi_y; ty++) {
1103                             lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
1104                             hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
1105                             for (tx = lo_x; tx <= hi_x; tx++) {
1106                                 /* first, look at what is currently visible
1107                                    (might be monster) */
1108                                 k = glyph_at(tx, ty);
1109                                 if (glyph_is_cmap(k)
1110                                     && matching[glyph_to_cmap(k)])
1111                                     goto foundc;
1112                                 /* next, try glyph that's remembered here
1113                                    (might be trap or object) */
1114                                 if (level.flags.hero_memory
1115                                     /* !terrainmode: don't move to remembered
1116                                        trap or object if not currently shown */
1117                                     && !iflags.terrainmode) {
1118                                     k = levl[tx][ty].glyph;
1119                                     if (glyph_is_cmap(k)
1120                                         && matching[glyph_to_cmap(k)])
1121                                         goto foundc;
1122                                 }
1123                                 /* last, try actual terrain here (shouldn't
1124                                    we be using lastseentyp[][] instead?) */
1125                                 if (levl[tx][ty].seenv) {
1126                                     k = back_to_glyph(tx, ty);
1127                                     if (glyph_is_cmap(k)
1128                                         && matching[glyph_to_cmap(k)])
1129                                         goto foundc;
1130                                 }
1131                                 continue;
1132                             foundc:
1133                                 cx = tx, cy = ty;
1134                                 if (msg_given) {
1135                                     clear_nhwindow(WIN_MESSAGE);
1136                                     msg_given = FALSE;
1137                                 }
1138                                 goto nxtc;
1139                             } /* column */
1140                         }     /* row */
1141                     }         /* pass */
1142 /*JP
1143                     pline("Can't find dungeon feature '%c'.", c);
1144 */
1145                     pline("'%c'\81H", c);
1146                     msg_given = TRUE;
1147                     goto nxtc;
1148                 } else {
1149                     char note[QBUFSZ];
1150
1151                     if (!force)
1152 /*JP
1153                         Strcpy(note, "aborted");
1154 */
1155                         Strcpy(note, "\92\86\92f\82µ\82½");
1156                     else /* hjkl */
1157 #if 0 /*JP*/
1158                         Sprintf(note, "use '%c', '%c', '%c', '%c' or '%s'",
1159                                 Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E,
1160                                 visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]));
1161 #else
1162                         Sprintf(note, "%c%c%c%c\82Å\88Ú\93®\81C%s\82Å\8fI\97¹",
1163                                 Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E,
1164                                 visctrl(Cmd.spkeys[NHKF_GETPOS_PICK]));
1165 #endif
1166 /*JP
1167                     pline("Unknown direction: '%s' (%s).", visctrl((char) c),
1168 */
1169                     pline("\82»\82Ì\95û\8cü\82Í\82È\82¢\81F'%s' (%s)", visctrl((char) c),
1170                           note);
1171                     msg_given = TRUE;
1172                 } /* k => matching */
1173             }     /* !quitchars */
1174             if (force)
1175                 goto nxtc;
1176 /*JP
1177             pline("Done.");
1178 */
1179             pline("\88È\8fã\81D");
1180             msg_given = FALSE; /* suppress clear */
1181             cx = -1;
1182             cy = 0;
1183             result = 0; /* not -1 */
1184             break;
1185         }
1186     nxtc:
1187         ;
1188 #ifdef CLIPPING
1189         cliparound(cx, cy);
1190 #endif
1191         curs(WIN_MAP, cx, cy);
1192         flush_screen(0);
1193     }
1194 #ifdef MAC
1195     lock_mouse_cursor(FALSE);
1196 #endif
1197     if (msg_given)
1198         clear_nhwindow(WIN_MESSAGE);
1199     ccp->x = cx;
1200     ccp->y = cy;
1201     for (i = 0; i < NUM_GLOCS; i++)
1202         if (garr[i])
1203             free((genericptr_t) garr[i]);
1204     getpos_hilitefunc = (void FDECL((*), (int))) 0;
1205     getpos_getvalid = (boolean FDECL((*), (int, int))) 0;
1206     return result;
1207 }
1208
1209 /* allocate space for a monster's name; removes old name if there is one */
1210 void
1211 new_mname(mon, lth)
1212 struct monst *mon;
1213 int lth; /* desired length (caller handles adding 1 for terminator) */
1214 {
1215     if (lth) {
1216         /* allocate mextra if necessary; otherwise get rid of old name */
1217         if (!mon->mextra)
1218             mon->mextra = newmextra();
1219         else
1220             free_mname(mon); /* already has mextra, might also have name */
1221         MNAME(mon) = (char *) alloc((unsigned) lth);
1222     } else {
1223         /* zero length: the new name is empty; get rid of the old name */
1224         if (has_mname(mon))
1225             free_mname(mon);
1226     }
1227 }
1228
1229 /* release a monster's name; retains mextra even if all fields are now null */
1230 void
1231 free_mname(mon)
1232 struct monst *mon;
1233 {
1234     if (has_mname(mon)) {
1235         free((genericptr_t) MNAME(mon));
1236         MNAME(mon) = (char *) 0;
1237     }
1238 }
1239
1240 /* allocate space for an object's name; removes old name if there is one */
1241 void
1242 new_oname(obj, lth)
1243 struct obj *obj;
1244 int lth; /* desired length (caller handles adding 1 for terminator) */
1245 {
1246     if (lth) {
1247         /* allocate oextra if necessary; otherwise get rid of old name */
1248         if (!obj->oextra)
1249             obj->oextra = newoextra();
1250         else
1251             free_oname(obj); /* already has oextra, might also have name */
1252         ONAME(obj) = (char *) alloc((unsigned) lth);
1253     } else {
1254         /* zero length: the new name is empty; get rid of the old name */
1255         if (has_oname(obj))
1256             free_oname(obj);
1257     }
1258 }
1259
1260 /* release an object's name; retains oextra even if all fields are now null */
1261 void
1262 free_oname(obj)
1263 struct obj *obj;
1264 {
1265     if (has_oname(obj)) {
1266         free((genericptr_t) ONAME(obj));
1267         ONAME(obj) = (char *) 0;
1268     }
1269 }
1270
1271 /*  safe_oname() always returns a valid pointer to
1272  *  a string, either the pointer to an object's name
1273  *  if it has one, or a pointer to an empty string
1274  *  if it doesn't.
1275  */
1276 const char *
1277 safe_oname(obj)
1278 struct obj *obj;
1279 {
1280     if (has_oname(obj))
1281         return ONAME(obj);
1282     return "";
1283 }
1284
1285 /* historical note: this returns a monster pointer because it used to
1286    allocate a new bigger block of memory to hold the monster and its name */
1287 struct monst *
1288 christen_monst(mtmp, name)
1289 struct monst *mtmp;
1290 const char *name;
1291 {
1292     int lth;
1293     char buf[PL_PSIZ];
1294
1295     /* dogname & catname are PL_PSIZ arrays; object names have same limit */
1296     lth = (name && *name) ? ((int) strlen(name) + 1) : 0;
1297     if (lth > PL_PSIZ) {
1298 #if 1 /*JP*/
1299         if (is_kanji2(buf, lth - 1))
1300             --lth;
1301 #endif
1302         lth = PL_PSIZ;
1303         name = strncpy(buf, name, PL_PSIZ - 1);
1304         buf[PL_PSIZ - 1] = '\0';
1305     }
1306     new_mname(mtmp, lth); /* removes old name if one is present */
1307     if (lth)
1308         Strcpy(MNAME(mtmp), name);
1309     return mtmp;
1310 }
1311
1312 /* check whether user-supplied name matches or nearly matches an unnameable
1313    monster's name; if so, give an alternate reject message for do_mname() */
1314 STATIC_OVL boolean
1315 alreadynamed(mtmp, monnambuf, usrbuf)
1316 struct monst *mtmp;
1317 char *monnambuf, *usrbuf;
1318 {
1319     char pronounbuf[10], *p;
1320
1321     if (fuzzymatch(usrbuf, monnambuf, " -_", TRUE)
1322         /* catch trying to name "the Oracle" as "Oracle" */
1323         || (!strncmpi(monnambuf, "the ", 4)
1324             && fuzzymatch(usrbuf, monnambuf + 4, " -_", TRUE))
1325         /* catch trying to name "invisible Orcus" as "Orcus" */
1326         || ((p = strstri(monnambuf, "invisible ")) != 0
1327             && fuzzymatch(usrbuf, p + 10, " -_", TRUE))
1328         /* catch trying to name "the {priest,Angel} of Crom" as "Crom" */
1329         || ((p = strstri(monnambuf, " of ")) != 0
1330             && fuzzymatch(usrbuf, p + 4, " -_", TRUE))) {
1331 #if 0 /*JP*/
1332         pline("%s is already called %s.",
1333               upstart(strcpy(pronounbuf, mhe(mtmp))), monnambuf);
1334 #else
1335         pline("%s\82Í\8aù\82É%s\82Æ\8cÄ\82Î\82ê\82Ä\82¢\82é\81D",
1336               upstart(strcpy(pronounbuf, mhe(mtmp))), monnambuf);
1337 #endif
1338         return TRUE;
1339 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\8eg\82í\82È\82¢*/
1340     } else if (mtmp->data == &mons[PM_JUIBLEX]
1341                && strstri(monnambuf, "Juiblex")
1342                && !strcmpi(usrbuf, "Jubilex")) {
1343         pline("%s doesn't like being called %s.", upstart(monnambuf), usrbuf);
1344         return TRUE;
1345 #endif
1346     }
1347     return FALSE;
1348 }
1349
1350 /* allow player to assign a name to some chosen monster */
1351 STATIC_OVL void
1352 do_mname()
1353 {
1354     char buf[BUFSZ] = DUMMY, monnambuf[BUFSZ], qbuf[QBUFSZ];
1355     coord cc;
1356     int cx, cy;
1357     struct monst *mtmp = 0;
1358
1359     if (Hallucination) {
1360 /*JP
1361         You("would never recognize it anyway.");
1362 */
1363         You("\82»\82ê\82ð\94F\8e¯\82Å\82«\82È\82¢\81D");
1364         return;
1365     }
1366     cc.x = u.ux;
1367     cc.y = u.uy;
1368 /*JP
1369     if (getpos(&cc, FALSE, "the monster you want to name") < 0
1370 */
1371     if (getpos(&cc, FALSE, "\82 \82È\82½\82ª\96¼\82Ã\82¯\82½\82¢\89ö\95¨") < 0
1372         || (cx = cc.x) < 0)
1373         return;
1374     cy = cc.y;
1375
1376     if (cx == u.ux && cy == u.uy) {
1377         if (u.usteed && canspotmon(u.usteed)) {
1378             mtmp = u.usteed;
1379         } else {
1380 /*JP
1381             pline("This %s creature is called %s and cannot be renamed.",
1382 */
1383             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",
1384                   beautiful(), plname);
1385             return;
1386         }
1387     } else
1388         mtmp = m_at(cx, cy);
1389
1390     if (!mtmp
1391         || (!sensemon(mtmp)
1392             && (!(cansee(cx, cy) || see_with_infrared(mtmp))
1393                 || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE
1394                 || mtmp->m_ap_type == M_AP_OBJECT
1395                 || (mtmp->minvis && !See_invisible)))) {
1396 /*JP
1397         pline("I see no monster there.");
1398 */
1399         pline("\82»\82±\82É\89ö\95¨\82Í\82¢\82È\82¢\81D");
1400         return;
1401     }
1402     /* special case similar to the one in lookat() */
1403 /*JP
1404     Sprintf(qbuf, "What do you want to call %s?",
1405 */
1406     Sprintf(qbuf, "%s\82ð\89½\82Æ\8cÄ\82Ñ\82Ü\82·\82©\81H",
1407             distant_monnam(mtmp, ARTICLE_THE, monnambuf));
1408     getlin(qbuf, buf);
1409     if (!*buf || *buf == '\033')
1410         return;
1411     /* strip leading and trailing spaces; unnames monster if all spaces */
1412     (void) mungspaces(buf);
1413
1414     /* Unique monsters have their own specific names or titles.
1415      * Shopkeepers, temple priests and other minions use alternate
1416      * name formatting routines which ignore any user-supplied name.
1417      *
1418      * Don't say the name is being rejected if it happens to match
1419      * the existing name.
1420      */
1421     if ((mtmp->data->geno & G_UNIQ) && !mtmp->ispriest) {
1422         if (!alreadynamed(mtmp, monnambuf, buf))
1423 /*JP
1424         pline("%s doesn't like being called names!", upstart(monnambuf));
1425 */
1426         pline("%s\82Í\82 \82¾\96¼\82Å\8cÄ\82Î\82ê\82é\82Ì\82ª\8c\99\82¢\82È\82æ\82¤\82¾\81I", Monnam(mtmp));
1427     } else if (mtmp->isshk
1428                && !(Deaf || mtmp->msleeping || !mtmp->mcanmove
1429                     || mtmp->data->msound <= MS_ANIMAL)) {
1430         if (!alreadynamed(mtmp, monnambuf, buf))
1431 /*JP
1432         verbalize("I'm %s, not %s.", shkname(mtmp), buf);
1433 */
1434         verbalize("\8e\84\82Í%s\82¾\81C%s\82Å\82Í\82È\82¢\81D", shkname(mtmp), buf);
1435     } else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk) {
1436         if (!alreadynamed(mtmp, monnambuf, buf))
1437 /*JP
1438         pline("%s will not accept the name %s.", upstart(monnambuf), buf);
1439 */
1440         pline("%s\82Í%s\82Æ\82¢\82¤\96¼\91O\82ð\8eó\82¯\82¢\82ê\82È\82©\82Á\82½\81D", monnambuf, buf);
1441     } else
1442         (void) christen_monst(mtmp, buf);
1443 }
1444
1445 STATIC_VAR int via_naming = 0;
1446
1447 /*
1448  * This routine used to change the address of 'obj' so be unsafe if not
1449  * used with extreme care.  Applying a name to an object no longer
1450  * allocates a replacement object, so that old risk is gone.
1451  */
1452 STATIC_OVL
1453 void
1454 do_oname(obj)
1455 register struct obj *obj;
1456 {
1457     char *bufp, buf[BUFSZ] = DUMMY, bufcpy[BUFSZ], qbuf[QBUFSZ];
1458     const char *aname;
1459     short objtyp;
1460
1461     /* Do this now because there's no point in even asking for a name */
1462     if (obj->otyp == SPE_NOVEL) {
1463 /*JP
1464         pline("%s already has a published name.", Ysimple_name2(obj));
1465 */
1466         pline("%s\82É\82Í\82·\82Å\82É\8fo\94Å\8e\9e\82Ì\96¼\91O\82ª\82 \82é\81D", Ysimple_name2(obj));
1467         return;
1468     }
1469
1470 #if 0 /*JP*/
1471     Sprintf(qbuf, "What do you want to name %s ",
1472             is_plural(obj) ? "these" : "this");
1473     (void) safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item");
1474 #else
1475     (void) safe_qbuf(qbuf, "", "\82ð\89½\82Æ\96¼\82Ã\82¯\82Ü\82·\82©\81H", obj, xname, simpleonames, "item");
1476 #endif
1477     getlin(qbuf, buf);
1478     if (!*buf || *buf == '\033')
1479         return;
1480     /* strip leading and trailing spaces; unnames item if all spaces */
1481     (void) mungspaces(buf);
1482
1483     /*
1484      * We don't violate illiteracy conduct here, although it is
1485      * arguable that we should for anything other than "X".  Doing so
1486      * would make attaching player's notes to hero's inventory have an
1487      * in-game effect, which may or may not be the correct thing to do.
1488      *
1489      * We do violate illiteracy in oname() if player creates Sting or
1490      * Orcrist, clearly being literate (no pun intended...).
1491      */
1492
1493     /* relax restrictions over proper capitalization for artifacts */
1494     if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
1495         Strcpy(buf, aname);
1496
1497     if (obj->oartifact) {
1498 /*JP
1499         pline_The("artifact seems to resist the attempt.");
1500 */
1501         pline("\90¹\8aí\82Í\96¼\82Ã\82¯\82ð\8b\91\94Û\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D");
1502         return;
1503     } else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
1504         /* this used to change one letter, substituting a value
1505            of 'a' through 'y' (due to an off by one error, 'z'
1506            would never be selected) and then force that to
1507            upper case if such was the case of the input;
1508            now, the hand slip scuffs one or two letters as if
1509            the text had been trodden upon, sometimes picking
1510            punctuation instead of an arbitrary letter;
1511            unfortunately, we have to cover the possibility of
1512            it targetting spaces so failing to make any change
1513            (we know that it must eventually target a nonspace
1514            because buf[] matches a valid artifact name) */
1515         Strcpy(bufcpy, buf);
1516         /* for "the Foo of Bar", only scuff "Foo of Bar" part */
1517         bufp = !strncmpi(bufcpy, "the ", 4) ? (buf + 4) : buf;
1518         do {
1519             wipeout_text(bufp, rnd(2), (unsigned) 0);
1520         } while (!strcmp(buf, bufcpy));
1521 /*JP
1522         pline("While engraving, your %s slips.", body_part(HAND));
1523 */
1524         pline("\8d\8f\82ñ\82Å\82¢\82é\8aÔ\82É%s\82ª\8a\8a\82Á\82Ä\82µ\82Ü\82Á\82½\81D", body_part(HAND));
1525         display_nhwindow(WIN_MESSAGE, FALSE);
1526 /*JP
1527         You("engrave: \"%s\".", buf);
1528 */
1529         You("\8d\8f\82ñ\82¾: \81u%s\81v\81D",buf);
1530         /* violate illiteracy conduct since hero attempted to write
1531            a valid artifact name */
1532         u.uconduct.literate++;
1533     }
1534     ++via_naming; /* This ought to be an argument rather than a static... */
1535     obj = oname(obj, buf);
1536     --via_naming; /* ...but oname() is used in a lot of places, so defer. */
1537 }
1538
1539 struct obj *
1540 oname(obj, name)
1541 struct obj *obj;
1542 const char *name;
1543 {
1544     int lth;
1545     char buf[PL_PSIZ];
1546
1547     lth = *name ? (int) (strlen(name) + 1) : 0;
1548     if (lth > PL_PSIZ) {
1549         lth = PL_PSIZ;
1550 #if 0 /*JP*/
1551         name = strncpy(buf, name, PL_PSIZ - 1);
1552         buf[PL_PSIZ - 1] = '\0';
1553 #else
1554         if (is_kanji2(name, lth - 1))
1555             --lth;
1556         name = strncpy(buf, name, lth - 1);
1557         buf[lth - 1] = '\0';
1558 #endif
1559     }
1560     /* If named artifact exists in the game, do not create another.
1561      * Also trying to create an artifact shouldn't de-artifact
1562      * it (e.g. Excalibur from prayer). In this case the object
1563      * will retain its current name. */
1564     if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
1565         return obj;
1566
1567     new_oname(obj, lth); /* removes old name if one is present */
1568     if (lth)
1569         Strcpy(ONAME(obj), name);
1570
1571     if (lth)
1572         artifact_exists(obj, name, TRUE);
1573     if (obj->oartifact) {
1574         /* can't dual-wield with artifact as secondary weapon */
1575         if (obj == uswapwep)
1576             untwoweapon();
1577         /* activate warning if you've just named your weapon "Sting" */
1578         if (obj == uwep)
1579             set_artifact_intrinsic(obj, TRUE, W_WEP);
1580         /* if obj is owned by a shop, increase your bill */
1581         if (obj->unpaid)
1582             alter_cost(obj, 0L);
1583         if (via_naming) {
1584             /* violate illiteracy conduct since successfully wrote arti-name */
1585             u.uconduct.literate++;
1586         }
1587     }
1588     if (carried(obj))
1589         update_inventory();
1590     return obj;
1591 }
1592
1593 static NEARDATA const char callable[] = {
1594     SCROLL_CLASS, POTION_CLASS, WAND_CLASS,  RING_CLASS, AMULET_CLASS,
1595     GEM_CLASS,    SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0
1596 };
1597
1598 boolean
1599 objtyp_is_callable(i)
1600 int i;
1601 {
1602     return (boolean) (objects[i].oc_uname
1603                       || (OBJ_DESCR(objects[i])
1604                           && index(callable, objects[i].oc_class)));
1605 }
1606
1607 /* C and #name commands - player can name monster or object or type of obj */
1608 int
1609 docallcmd()
1610 {
1611     struct obj *obj;
1612     winid win;
1613     anything any;
1614     menu_item *pick_list = 0;
1615     char ch, allowall[2];
1616     /* if player wants a,b,c instead of i,o when looting, do that here too */
1617     boolean abc = flags.lootabc;
1618
1619     win = create_nhwindow(NHW_MENU);
1620     start_menu(win);
1621     any = zeroany;
1622     any.a_char = 'm'; /* group accelerator 'C' */
1623     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'C', ATR_NONE,
1624 /*JP
1625              "a monster", MENU_UNSELECTED);
1626 */
1627              "\89ö\95¨", MENU_UNSELECTED);
1628     if (invent) {
1629         /* we use y and n as accelerators so that we can accept user's
1630            response keyed to old "name an individual object?" prompt */
1631         any.a_char = 'i'; /* group accelerator 'y' */
1632         add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'y', ATR_NONE,
1633 /*JP
1634                  "a particular object in inventory", MENU_UNSELECTED);
1635 */
1636                  "\8e\9d\82¿\95¨\82Ì\92\86\82Ì\88ê\82Â\82Ì\83A\83C\83e\83\80", MENU_UNSELECTED);
1637         any.a_char = 'o'; /* group accelerator 'n' */
1638         add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'n', ATR_NONE,
1639 /*JP
1640                  "the type of an object in inventory", MENU_UNSELECTED);
1641 */
1642                  "\8e\9d\82¿\95¨\82Ì\92\86\82Ì\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
1643     }
1644     any.a_char = 'f'; /* group accelerator ',' (or ':' instead?) */
1645     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, ',', ATR_NONE,
1646 /*JP
1647              "the type of an object upon the floor", MENU_UNSELECTED);
1648 */
1649              "\8f°\82Ì\8fã\82É\82 \82é\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
1650     any.a_char = 'd'; /* group accelerator '\' */
1651     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, '\\', ATR_NONE,
1652 /*JP
1653              "the type of an object on discoveries list", MENU_UNSELECTED);
1654 */
1655              "\94­\8c©\95¨\88ê\97\97\82É\82 \82é\88ê\82Â\82Ì\83A\83C\83e\83\80\82Ì\8eí\97Þ", MENU_UNSELECTED);
1656     any.a_char = 'a'; /* group accelerator 'l' */
1657     add_menu(win, NO_GLYPH, &any, abc ? 0 : any.a_char, 'l', ATR_NONE,
1658 /*JP
1659              "record an annotation for the current level", MENU_UNSELECTED);
1660 */
1661              "\8c»\8dÝ\82Ì\8aK\82É\91Î\82·\82é\83\81\83\82\82Ì\8bL\98^", MENU_UNSELECTED);
1662 /*JP
1663     end_menu(win, "What do you want to name?");
1664 */
1665     end_menu(win, "\82Ç\82ê\82É\96¼\91O\82ð\82Â\82¯\82Ü\82·\82©\81H");
1666     if (select_menu(win, PICK_ONE, &pick_list) > 0) {
1667         ch = pick_list[0].item.a_char;
1668         free((genericptr_t) pick_list);
1669     } else
1670         ch = 'q';
1671     destroy_nhwindow(win);
1672
1673     switch (ch) {
1674     default:
1675     case 'q':
1676         break;
1677     case 'm': /* name a visible monster */
1678         do_mname();
1679         break;
1680     case 'i': /* name an individual object in inventory */
1681         allowall[0] = ALL_CLASSES;
1682         allowall[1] = '\0';
1683         obj = getobj(allowall, "name");
1684         if (obj)
1685             do_oname(obj);
1686         break;
1687     case 'o': /* name a type of object in inventory */
1688         obj = getobj(callable, "call");
1689         if (obj) {
1690             /* behave as if examining it in inventory;
1691                this might set dknown if it was picked up
1692                while blind and the hero can now see */
1693             (void) xname(obj);
1694
1695             if (!obj->dknown) {
1696 /*JP
1697                 You("would never recognize another one.");
1698 */
1699                 You("\91¼\82É\94F\8e¯\82Å\82«\82È\82¢\81D");
1700 #if 0
1701             } else if (!objtyp_is_callable(obj->otyp)) {
1702                 You("know those as well as you ever will.");
1703 #endif
1704             } else {
1705                 docall(obj);
1706             }
1707         }
1708         break;
1709     case 'f': /* name a type of object visible on the floor */
1710         namefloorobj();
1711         break;
1712     case 'd': /* name a type of object on the discoveries list */
1713         rename_disco();
1714         break;
1715     case 'a': /* annotate level */
1716         donamelevel();
1717         break;
1718     }
1719     return 0;
1720 }
1721
1722 /* for use by safe_qbuf() */
1723 STATIC_PTR char *
1724 docall_xname(obj)
1725 struct obj *obj;
1726 {
1727     struct obj otemp;
1728
1729     otemp = *obj;
1730     otemp.oextra = (struct oextra *) 0;
1731     otemp.quan = 1L;
1732     /* in case water is already known, convert "[un]holy water" to "water" */
1733     otemp.blessed = otemp.cursed = 0;
1734     /* remove attributes that are doname() caliber but get formatted
1735        by xname(); most of these fixups aren't really needed because the
1736        relevant type of object isn't callable so won't reach this far */
1737     if (otemp.oclass == WEAPON_CLASS)
1738         otemp.opoisoned = 0; /* not poisoned */
1739     else if (otemp.oclass == POTION_CLASS)
1740         otemp.odiluted = 0; /* not diluted */
1741     else if (otemp.otyp == TOWEL || otemp.otyp == STATUE)
1742         otemp.spe = 0; /* not wet or historic */
1743     else if (otemp.otyp == TIN)
1744         otemp.known = 0; /* suppress tin type (homemade, &c) and mon type */
1745     else if (otemp.otyp == FIGURINE)
1746         otemp.corpsenm = NON_PM; /* suppress mon type */
1747     else if (otemp.otyp == HEAVY_IRON_BALL)
1748         otemp.owt = objects[HEAVY_IRON_BALL].oc_weight; /* not "very heavy" */
1749     else if (otemp.oclass == FOOD_CLASS && otemp.globby)
1750         otemp.owt = 120; /* 6*20, neither a small glob nor a large one */
1751
1752     return an(xname(&otemp));
1753 }
1754
1755 void
1756 docall(obj)
1757 struct obj *obj;
1758 {
1759     char buf[BUFSZ] = DUMMY, qbuf[QBUFSZ];
1760     char **str1;
1761
1762     if (!obj->dknown)
1763         return; /* probably blind */
1764
1765     if (obj->oclass == POTION_CLASS && obj->fromsink)
1766         /* kludge, meaning it's sink water */
1767 /*JP
1768         Sprintf(qbuf, "Call a stream of %s fluid:",
1769 */
1770         Sprintf(qbuf, "%s\89t\91Ì:",
1771                 OBJ_DESCR(objects[obj->otyp]));
1772     else
1773 #if 0 /*JP*/
1774         (void) safe_qbuf(qbuf, "Call ", ":", obj,
1775                          docall_xname, simpleonames, "thing");
1776 #else
1777         (void) safe_qbuf(qbuf, "", "\82É\89½\82Æ\96¼\91O\82ð\95t\82¯\82é\81H", obj,
1778                          docall_xname, simpleonames, "\82±\82ê");
1779 #endif
1780     getlin(qbuf, buf);
1781     if (!*buf || *buf == '\033')
1782         return;
1783
1784     /* clear old name */
1785     str1 = &(objects[obj->otyp].oc_uname);
1786     if (*str1)
1787         free((genericptr_t) *str1);
1788
1789     /* strip leading and trailing spaces; uncalls item if all spaces */
1790     (void) mungspaces(buf);
1791     if (!*buf) {
1792         if (*str1) { /* had name, so possibly remove from disco[] */
1793             /* strip name first, for the update_inventory() call
1794                from undiscover_object() */
1795             *str1 = (char *) 0;
1796             undiscover_object(obj->otyp);
1797         }
1798     } else {
1799         *str1 = dupstr(buf);
1800         discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
1801     }
1802 }
1803
1804 STATIC_OVL void
1805 namefloorobj()
1806 {
1807     coord cc;
1808     int glyph;
1809     char buf[BUFSZ];
1810     struct obj *obj = 0;
1811 #if 0 /*JP*/
1812     boolean fakeobj = FALSE, use_plural;
1813 #else
1814     boolean fakeobj = FALSE;
1815 #endif
1816
1817     cc.x = u.ux, cc.y = u.uy;
1818     /* "dot for under/over you" only makes sense when the cursor hasn't
1819        been moved off the hero's '@' yet, but there's no way to adjust
1820        the help text once getpos() has started */
1821 #if 0 /*JP*/
1822     Sprintf(buf, "object on map (or '.' for one %s you)",
1823             (u.uundetected && hides_under(youmonst.data)) ? "over" : "under");
1824 #else
1825     Strcpy(buf, "\92n\90}\8fã\82Ì\95¨\91Ì(\82 \82é\82¢\82Í'.'\82Å\82 \82È\82½\82Ì\82¢\82é\8fê\8f\8a");
1826 #endif
1827     if (getpos(&cc, FALSE, buf) < 0 || cc.x <= 0)
1828         return;
1829     if (cc.x == u.ux && cc.y == u.uy) {
1830         obj = vobj_at(u.ux, u.uy);
1831     } else {
1832         glyph = glyph_at(cc.x, cc.y);
1833         if (glyph_is_object(glyph))
1834             fakeobj = object_from_map(glyph, cc.x, cc.y, &obj);
1835         /* else 'obj' stays null */
1836     }
1837     if (!obj) {
1838         /* "under you" is safe here since there's no object to hide under */
1839 #if 0 /*JP*/
1840         pline("There doesn't seem to be any object %s.",
1841               (cc.x == u.ux && cc.y == u.uy) ? "under you" : "there");
1842 #else
1843         pline("%s\82É\82Í\89½\82à\82È\82¢\82æ\82¤\82¾\81D",
1844               (cc.x == u.ux && cc.y == u.uy) ? "\82 \82È\82½\82Ì\89º" : "\82»\82±");
1845 #endif
1846         return;
1847     }
1848     /* note well: 'obj' might be as instance of STRANGE_OBJECT if target
1849        is a mimic; passing that to xname (directly or via simpleonames)
1850        would yield "glorkum" so we need to handle it explicitly; it will
1851        always fail the Hallucination test and pass the !callable test,
1852        resulting in the "can't be assigned a type name" message */
1853     Strcpy(buf, (obj->otyp != STRANGE_OBJECT)
1854                  ? simpleonames(obj)
1855                  : obj_descr[STRANGE_OBJECT].oc_name);
1856 #if 0 /*JP*/
1857     use_plural = (obj->quan > 1L);
1858 #endif
1859     if (Hallucination) {
1860         const char *unames[6];
1861         char tmpbuf[BUFSZ];
1862
1863         /* straight role name */
1864         unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
1865                      ? urole.name.f
1866                      : urole.name.m;
1867         /* random rank title for hero's role */
1868         unames[1] = rank_of(rnd(30), Role_switch, flags.female);
1869         /* random fake monster */
1870         unames[2] = bogusmon(tmpbuf, (char *) 0);
1871         /* increased chance for fake monster */
1872         unames[3] = unames[2];
1873         /* traditional */
1874         unames[4] = roguename();
1875         /* silly */
1876 /*JP
1877         unames[5] = "Wibbly Wobbly";
1878 */
1879         unames[5] = "\82¤\82ë\82¤\82ë";
1880 #if 0 /*JP*/
1881         pline("%s %s to call you \"%s.\"",
1882               The(buf), use_plural ? "decide" : "decides",
1883               unames[rn2(SIZE(unames))]);
1884 #else
1885         pline("%s\82Í\82 \82È\82½\82ð\81u%s\81v\82Æ\8cÄ\82Ô\82±\82Æ\82É\8c\88\82ß\82½\81D",
1886               buf,
1887               unames[rn2(SIZE(unames))]);
1888 #endif
1889     } else if (!objtyp_is_callable(obj->otyp)) {
1890 #if 0 /*JP*/
1891         pline("%s %s can't be assigned a type name.",
1892               use_plural ? "Those" : "That", buf);
1893 #else
1894         pline("%s\82É\8eí\97Þ\82Ì\96¼\91O\82ð\8a\84\82è\93\96\82Ä\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
1895               buf);
1896 #endif
1897     } else if (!obj->dknown) {
1898 #if 0 /*JP*/
1899         You("don't know %s %s well enough to name %s.",
1900             use_plural ? "those" : "that", buf, use_plural ? "them" : "it");
1901 #else
1902         You("\96¼\91O\82ð\95t\82¯\82ç\82ê\82é\82Ù\82Ç%s\82Ì\82±\82Æ\82ð\82æ\82­\92m\82ç\82È\82¢\81D",
1903             buf);
1904 #endif
1905     } else {
1906         docall(obj);
1907     }
1908     if (fakeobj)
1909         dealloc_obj(obj);
1910 }
1911
1912 static const char *const ghostnames[] = {
1913     /* these names should have length < PL_NSIZ */
1914     /* Capitalize the names for aesthetics -dgk */
1915     "Adri",    "Andries",       "Andreas",     "Bert",    "David",  "Dirk",
1916     "Emile",   "Frans",         "Fred",        "Greg",    "Hether", "Jay",
1917     "John",    "Jon",           "Karnov",      "Kay",     "Kenny",  "Kevin",
1918     "Maud",    "Michiel",       "Mike",        "Peter",   "Robert", "Ron",
1919     "Tom",     "Wilmar",        "Nick Danger", "Phoenix", "Jiro",   "Mizue",
1920     "Stephan", "Lance Braccus", "Shadowhawk"
1921 };
1922
1923 /* ghost names formerly set by x_monnam(), now by makemon() instead */
1924 const char *
1925 rndghostname()
1926 {
1927     return rn2(7) ? ghostnames[rn2(SIZE(ghostnames))] : (const char *) plname;
1928 }
1929
1930 /*
1931  * Monster naming functions:
1932  * x_monnam is the generic monster-naming function.
1933  *                seen        unseen       detected               named
1934  * mon_nam:     the newt        it      the invisible orc       Fido
1935  * noit_mon_nam:the newt (as if detected) the invisible orc     Fido
1936  * l_monnam:    newt            it      invisible orc           dog called Fido
1937  * Monnam:      The newt        It      The invisible orc       Fido
1938  * noit_Monnam: The newt (as if detected) The invisible orc     Fido
1939  * Adjmonnam:   The poor newt   It      The poor invisible orc  The poor Fido
1940  * Amonnam:     A newt          It      An invisible orc        Fido
1941  * a_monnam:    a newt          it      an invisible orc        Fido
1942  * m_monnam:    newt            xan     orc                     Fido
1943  * y_monnam:    your newt     your xan  your invisible orc      Fido
1944  * noname_monnam(mon,article):
1945  *              article newt    art xan art invisible orc       art dog
1946  */
1947
1948 /* Bug: if the monster is a priest or shopkeeper, not every one of these
1949  * options works, since those are special cases.
1950  */
1951 char *
1952 x_monnam(mtmp, article, adjective, suppress, called)
1953 register struct monst *mtmp;
1954 int article;
1955 /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
1956  * ARTICLE_YOUR: "your" on pets, "the" on everything else
1957  *
1958  * If the monster would be referred to as "it" or if the monster has a name
1959  * _and_ there is no adjective, "invisible", "saddled", etc., override this
1960  * and always use no article.
1961  */
1962 const char *adjective;
1963 int suppress;
1964 /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
1965  * EXACT_NAME: combination of all the above
1966  * SUPPRESS_NAME: omit monster's assigned name (unless uniq w/ pname).
1967  */
1968 boolean called;
1969 {
1970     char *buf = nextmbuf();
1971     struct permonst *mdat = mtmp->data;
1972     const char *pm_name = mdat->mname;
1973     boolean do_hallu, do_invis, do_it, do_saddle, do_name;
1974 #if 0 /*JP*/
1975     boolean name_at_start, has_adjectives;
1976     char *bp;
1977 #endif
1978
1979     if (program_state.gameover)
1980         suppress |= SUPPRESS_HALLUCINATION;
1981     if (article == ARTICLE_YOUR && !mtmp->mtame)
1982         article = ARTICLE_THE;
1983
1984     do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION);
1985     do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE);
1986     do_it = !canspotmon(mtmp) && article != ARTICLE_YOUR
1987             && !program_state.gameover && mtmp != u.usteed
1988             && !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
1989     do_saddle = !(suppress & SUPPRESS_SADDLE);
1990     do_name = !(suppress & SUPPRESS_NAME) || type_is_pname(mdat);
1991
1992     buf[0] = '\0';
1993
1994     /* unseen monsters, etc.  Use "it" */
1995     if (do_it) {
1996 /*JP
1997         Strcpy(buf, "it");
1998 */
1999         Strcpy(buf, "\89½\8eÒ\82©");
2000         return buf;
2001     }
2002
2003     /* priests and minions: don't even use this function */
2004     if (mtmp->ispriest || mtmp->isminion) {
2005         char priestnambuf[BUFSZ];
2006         char *name;
2007         long save_prop = EHalluc_resistance;
2008         unsigned save_invis = mtmp->minvis;
2009
2010         /* when true name is wanted, explicitly block Hallucination */
2011         if (!do_hallu)
2012             EHalluc_resistance = 1L;
2013         if (!do_invis)
2014             mtmp->minvis = 0;
2015         name = priestname(mtmp, priestnambuf);
2016         EHalluc_resistance = save_prop;
2017         mtmp->minvis = save_invis;
2018 #if 0 /*JP*/
2019         if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
2020             name += 4;
2021 #endif
2022         return strcpy(buf, name);
2023     }
2024     /* an "aligned priest" not flagged as a priest or minion should be
2025        "priest" or "priestess" (normally handled by priestname()) */
2026     if (mdat == &mons[PM_ALIGNED_PRIEST])
2027 /*JP
2028         pm_name = mtmp->female ? "priestess" : "priest";
2029 */
2030         pm_name = mtmp->female ? "\93ò\91m" : "\91m\97µ";
2031     else if (mdat == &mons[PM_HIGH_PRIEST] && mtmp->female)
2032 /*JP
2033         pm_name = "high priestess";
2034 */
2035         pm_name = "\96@\89¤";
2036
2037     /* Shopkeepers: use shopkeeper name.  For normal shopkeepers, just
2038      * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
2039      * shopkeeper" or "Asidonhopo the blue dragon".  If hallucinating,
2040      * none of this applies.
2041      */
2042     if (mtmp->isshk && !do_hallu) {
2043 #if 0 /*JP*/
2044         if (adjective && article == ARTICLE_THE) {
2045             /* pathological case: "the angry Asidonhopo the blue dragon"
2046                sounds silly */
2047             Strcpy(buf, "the ");
2048             Strcat(strcat(buf, adjective), " ");
2049             Strcat(buf, shkname(mtmp));
2050             return buf;
2051         }
2052         Strcat(buf, shkname(mtmp));
2053         if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
2054             return buf;
2055         Strcat(buf, " the ");
2056         if (do_invis)
2057             Strcat(buf, "invisible ");
2058         Strcat(buf, pm_name);
2059         return buf;
2060 #else
2061         if (mdat == &mons[PM_SHOPKEEPER] && !do_invis){
2062             Strcpy(buf, shkname(mtmp));
2063         } else {
2064             Sprintf(buf, "%s\82Æ\82¢\82¤\96¼\82Ì%s%s",
2065                     shkname(mtmp), do_invis ? "\8ep\82Ì\8c©\82¦\82È\82¢" : "",
2066                     pm_name);
2067         }
2068         return buf;
2069 #endif
2070     }
2071
2072     /* Put the adjectives in the buffer */
2073     if (adjective)
2074 /*JP
2075         Strcat(strcat(buf, adjective), " ");
2076 */
2077         Strcat(buf, adjective);
2078     if (do_invis)
2079 /*JP
2080         Strcat(buf, "invisible ");
2081 */
2082         Strcat(buf, "\8ep\82Ì\8c©\82¦\82È\82¢");
2083     if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) && !Blind
2084         && !Hallucination)
2085 /*JP
2086         Strcat(buf, "saddled ");
2087 */
2088         Strcat(buf, "\88Æ\82Ì\82Â\82¢\82Ä\82¢\82é");
2089 #if 0 /*JP*/
2090     if (buf[0] != 0)
2091         has_adjectives = TRUE;
2092     else
2093         has_adjectives = FALSE;
2094 #endif
2095
2096     /* Put the actual monster name or type into the buffer now */
2097     /* Be sure to remember whether the buffer starts with a name */
2098     if (do_hallu) {
2099         char rnamecode;
2100         char *rname = rndmonnam(&rnamecode);
2101
2102         Strcat(buf, rname);
2103 #if 0 /*JP*/
2104         name_at_start = bogon_is_pname(rnamecode);
2105 #endif
2106     } else if (do_name && has_mname(mtmp)) {
2107         char *name = MNAME(mtmp);
2108
2109         if (mdat == &mons[PM_GHOST]) {
2110 /*JP
2111             Sprintf(eos(buf), "%s ghost", s_suffix(name));
2112 */
2113             Sprintf(buf, "%s\82Ì\97H\97ì", name);
2114 #if 0 /*JP*/
2115             name_at_start = TRUE;
2116 #endif
2117         } else if (called) {
2118 /*JP
2119             Sprintf(eos(buf), "%s called %s", pm_name, name);
2120 */
2121             Sprintf(eos(buf), "%s\82Æ\82¢\82¤\96¼\82Ì%s", name, pm_name);
2122 #if 0 /*JP*/
2123             name_at_start = (boolean) type_is_pname(mdat);
2124 #endif
2125 #if 0 /*JP*//*\92è\8a¥\8e\8c\82Ì\8f\88\97\9d\82Í\95s\97v*/
2126         } else if (is_mplayer(mdat) && (bp = strstri(name, " the ")) != 0) {
2127             /* <name> the <adjective> <invisible> <saddled> <rank> */
2128             char pbuf[BUFSZ];
2129
2130             Strcpy(pbuf, name);
2131             pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
2132             if (has_adjectives)
2133                 Strcat(pbuf, buf);
2134             Strcat(pbuf, bp + 5); /* append the rest of the name */
2135             Strcpy(buf, pbuf);
2136             article = ARTICLE_NONE;
2137             name_at_start = TRUE;
2138 #endif
2139         } else {
2140             Strcat(buf, name);
2141 #if 0 /*JP*/
2142             name_at_start = TRUE;
2143 #endif
2144         }
2145     } else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
2146         char pbuf[BUFSZ];
2147
2148         Strcpy(pbuf, rank_of((int) mtmp->m_lev, monsndx(mdat),
2149                              (boolean) mtmp->female));
2150 #if 0 /*JP*/
2151         Strcat(buf, lcase(pbuf));
2152 #else
2153         Strcat(buf, pbuf);
2154 #endif
2155 #if 0 /*JP*/
2156         name_at_start = FALSE;
2157 #endif
2158     } else {
2159         Strcat(buf, pm_name);
2160 #if 0 /*JP*/
2161         name_at_start = (boolean) type_is_pname(mdat);
2162 #endif
2163     }
2164
2165 #if 0 /*JP*//*\93ú\96{\8cê\82É\8a¥\8e\8c\82Í\82È\82¢*/
2166     if (name_at_start && (article == ARTICLE_YOUR || !has_adjectives)) {
2167         if (mdat == &mons[PM_WIZARD_OF_YENDOR])
2168             article = ARTICLE_THE;
2169         else
2170             article = ARTICLE_NONE;
2171     } else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
2172         article = ARTICLE_THE;
2173     }
2174
2175     {
2176         char buf2[BUFSZ];
2177
2178         switch (article) {
2179         case ARTICLE_YOUR:
2180             Strcpy(buf2, "your ");
2181             Strcat(buf2, buf);
2182             Strcpy(buf, buf2);
2183             return buf;
2184         case ARTICLE_THE:
2185             Strcpy(buf2, "the ");
2186             Strcat(buf2, buf);
2187             Strcpy(buf, buf2);
2188             return buf;
2189         case ARTICLE_A:
2190             return an(buf);
2191         case ARTICLE_NONE:
2192         default:
2193             return buf;
2194         }
2195     }
2196 #else
2197     return buf;
2198 #endif
2199 }
2200
2201 char *
2202 l_monnam(mtmp)
2203 struct monst *mtmp;
2204 {
2205     return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
2206                     (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
2207 }
2208
2209 char *
2210 mon_nam(mtmp)
2211 struct monst *mtmp;
2212 {
2213     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
2214                     (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
2215 }
2216
2217 /* print the name as if mon_nam() was called, but assume that the player
2218  * can always see the monster--used for probing and for monsters aggravating
2219  * the player with a cursed potion of invisibility
2220  */
2221 char *
2222 noit_mon_nam(mtmp)
2223 struct monst *mtmp;
2224 {
2225     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
2226                     (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
2227                                       : SUPPRESS_IT,
2228                     FALSE);
2229 }
2230
2231 char *
2232 Monnam(mtmp)
2233 struct monst *mtmp;
2234 {
2235     register char *bp = mon_nam(mtmp);
2236
2237     *bp = highc(*bp);
2238     return  bp;
2239 }
2240
2241 char *
2242 noit_Monnam(mtmp)
2243 struct monst *mtmp;
2244 {
2245     register char *bp = noit_mon_nam(mtmp);
2246
2247     *bp = highc(*bp);
2248     return  bp;
2249 }
2250
2251 /* return "a dog" rather than "Fido", honoring hallucination and visibility */
2252 char *
2253 noname_monnam(mtmp, article)
2254 struct monst *mtmp;
2255 int article;
2256 {
2257     return x_monnam(mtmp, article, (char *) 0, SUPPRESS_NAME, FALSE);
2258 }
2259
2260 /* monster's own name -- overrides hallucination and [in]visibility
2261    so shouldn't be used in ordinary messages (mainly for disclosure) */
2262 char *
2263 m_monnam(mtmp)
2264 struct monst *mtmp;
2265 {
2266     return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, EXACT_NAME, FALSE);
2267 }
2268
2269 /* pet name: "your little dog" */
2270 char *
2271 y_monnam(mtmp)
2272 struct monst *mtmp;
2273 {
2274     int prefix, suppression_flag;
2275
2276     prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
2277     suppression_flag = (has_mname(mtmp)
2278                         /* "saddled" is redundant when mounted */
2279                         || mtmp == u.usteed)
2280                            ? SUPPRESS_SADDLE
2281                            : 0;
2282
2283     return x_monnam(mtmp, prefix, (char *) 0, suppression_flag, FALSE);
2284 }
2285
2286 char *
2287 Adjmonnam(mtmp, adj)
2288 struct monst *mtmp;
2289 const char *adj;
2290 {
2291     char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
2292                         has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
2293
2294     *bp = highc(*bp);
2295     return  bp;
2296 }
2297
2298 char *
2299 a_monnam(mtmp)
2300 struct monst *mtmp;
2301 {
2302     return x_monnam(mtmp, ARTICLE_A, (char *) 0,
2303                     has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
2304 }
2305
2306 char *
2307 Amonnam(mtmp)
2308 struct monst *mtmp;
2309 {
2310     char *bp = a_monnam(mtmp);
2311
2312     *bp = highc(*bp);
2313     return  bp;
2314 }
2315
2316 /* used for monster ID by the '/', ';', and 'C' commands to block remote
2317    identification of the endgame altars via their attending priests */
2318 char *
2319 distant_monnam(mon, article, outbuf)
2320 struct monst *mon;
2321 int article; /* only ARTICLE_NONE and ARTICLE_THE are handled here */
2322 char *outbuf;
2323 {
2324     /* high priest(ess)'s identity is concealed on the Astral Plane,
2325        unless you're adjacent (overridden for hallucination which does
2326        its own obfuscation) */
2327     if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination
2328         && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
2329 #if 0 /*JP*/
2330         Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
2331         Strcat(outbuf, mon->female ? "high priestess" : "high priest");
2332 #else
2333         Strcpy(outbuf, "\96@\89¤");
2334 #endif
2335     } else {
2336         Strcpy(outbuf, x_monnam(mon, article, (char *) 0, 0, TRUE));
2337     }
2338     return outbuf;
2339 }
2340
2341 /* fake monsters used to be in a hard-coded array, now in a data file */
2342 STATIC_OVL char *
2343 bogusmon(buf, code)
2344 char *buf, *code;
2345 {
2346     char *mname = buf;
2347
2348     get_rnd_text(BOGUSMONFILE, buf);
2349     /* strip prefix if present */
2350     if (!letter(*mname)) {
2351         if (code)
2352             *code = *mname;
2353         ++mname;
2354     } else {
2355         if (code)
2356             *code = '\0';
2357     }
2358     return mname;
2359 }
2360
2361 /* return a random monster name, for hallucination */
2362 char *
2363 rndmonnam(code)
2364 char *code;
2365 {
2366     static char buf[BUFSZ];
2367     char *mname;
2368     int name;
2369 #define BOGUSMONSIZE 100 /* arbitrary */
2370
2371     if (code)
2372         *code = '\0';
2373
2374     do {
2375         name = rn1(SPECIAL_PM + BOGUSMONSIZE - LOW_PM, LOW_PM);
2376     } while (name < SPECIAL_PM
2377              && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
2378
2379     if (name >= SPECIAL_PM) {
2380         mname = bogusmon(buf, code);
2381     } else {
2382         mname = strcpy(buf, mons[name].mname);
2383     }
2384     return mname;
2385 #undef BOGUSMONSIZE
2386 }
2387
2388 /* check bogusmon prefix to decide whether it's a personal name */
2389 boolean
2390 bogon_is_pname(code)
2391 char code;
2392 {
2393     if (!code)
2394         return FALSE;
2395     return index("-+=", code) ? TRUE : FALSE;
2396 }
2397
2398 /* name of a Rogue player */
2399 const char *
2400 roguename()
2401 {
2402     char *i, *opts;
2403
2404     if ((opts = nh_getenv("ROGUEOPTS")) != 0) {
2405         for (i = opts; *i; i++)
2406             if (!strncmp("name=", i, 5)) {
2407                 char *j;
2408                 if ((j = index(i + 5, ',')) != 0)
2409                     *j = (char) 0;
2410                 return i + 5;
2411             }
2412     }
2413     /*JP:Rogue\82Ì\8aJ\94­\8eÒ\82Ì\96¼\91O*/
2414     return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
2415                   : "Glenn Wichman";
2416 }
2417
2418 static NEARDATA const char *const hcolors[] = {
2419 #if 0 /*JP*/
2420     "ultraviolet", "infrared", "bluish-orange", "reddish-green", "dark white",
2421     "light black", "sky blue-pink", "salty", "sweet", "sour", "bitter",
2422     "striped", "spiral", "swirly", "plaid", "checkered", "argyle", "paisley",
2423     "blotchy", "guernsey-spotted", "polka-dotted", "square", "round",
2424     "triangular", "cabernet", "sangria", "fuchsia", "wisteria", "lemon-lime",
2425     "strawberry-banana", "peppermint", "romantic", "incandescent",
2426     "octarine", /* Discworld: the Colour of Magic */
2427 #else
2428     "\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Ì",
2429     "\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¢",
2430     "\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Ì",
2431     "\82µ\82Ý\8fó\82Ì", "\90Â\90F\82Ì\94Á\93_\8fó\82Ì", "\93_\8fó\82Ì", "\8el\8ap\8c`\8fó\82Ì", "\8aÛ\8fó\82Ì",
2432     "\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Ì",
2433     "ä\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Ì",
2434     "\83I\83N\83^\83\8a\83\93\90F\82Ì",
2435 #endif
2436 };
2437
2438 const char *
2439 hcolor(colorpref)
2440 const char *colorpref;
2441 {
2442     return (Hallucination || !colorpref) ? hcolors[rn2(SIZE(hcolors))]
2443                                          : colorpref;
2444 }
2445
2446 /* return a random real color unless hallucinating */
2447 const char *
2448 rndcolor()
2449 {
2450     int k = rn2(CLR_MAX);
2451
2452     return Hallucination ? hcolor((char *) 0)
2453 /*JP
2454                          : (k == NO_COLOR) ? "colorless"
2455 */
2456                          : (k == NO_COLOR) ? "\96³\90F\82Ì"
2457                                            : c_obj_colors[k];
2458 }
2459
2460 static NEARDATA const char *const hliquids[] = {
2461 #if 0 /*JP*/
2462     "yoghurt", "oobleck", "clotted blood", "diluted water", "purified water",
2463     "instant coffee", "tea", "herbal infusion", "liquid rainbow",
2464     "creamy foam", "mulled wine", "bouillon", "nectar", "grog", "flubber",
2465     "ketchup", "slow light", "oil", "vinaigrette", "liquid crystal", "honey",
2466     "caramel sauce", "ink", "aqueous humour", "milk substitute", "fruit juice",
2467     "glowing lava", "gastric acid", "mineral water", "cough syrup", "quicksilver",
2468     "sweet vitriol", "grey goo", "pink slime",
2469 #else
2470     "\83\88\81[\83O\83\8b\83g", "\83E\81[\83u\83\8c\83b\83N", "\8c\8c\8cÐ", "\8fö\97¯\90\85", "\90¸\90»\90\85",
2471     "\83C\83\93\83X\83^\83\93\83g\83R\81[\83q\81[", "\8dg\92\83", "\83n\81[\83u\89t", "\89t\91Ì\82Ì\93ø",
2472     "\83N\83\8a\81[\83~\81[\83t\83H\81[\83\80", "\83z\83b\83g\83\8f\83C\83\93", "\83u\83C\83\88\83\93", "\89Ê\8f`", "\83O\83\8d\83b\83O", "\83t\83\89\83o\81[",
2473     "\83P\83`\83\83\83b\83v", "\92á\91¬\8cõ", "\96û", "\83r\83l\83O\83\8c\83b\83g\83\\81[\83X", "\89t\91Ì\90\85\8f»", "\96I\96¨",
2474     "\83J\83\89\83\81\83\8b\83\\81[\83X", "\83C\83\93\83N", "\96[\90\85", "\91ã\97p\93û", "\83t\83\8b\81[\83c\83W\83\85\81[\83X",
2475     "\97¬\82ê\82é\97n\8aâ", "\88Ý\8e_", "\83~\83l\83\89\83\8b\83E\83H\81[\83^\81[", "\8aP\8e~\82ß\83V\83\8d\83b\83v", "\90\85\8bâ",
2476     "\83W\83G\83`\83\8b\83G\81[\83e\83\8b", "\83O\83\8c\83C\83O\81[", "\83s\83\93\83N\83X\83\89\83C\83\80",
2477 #endif
2478 };
2479
2480 const char *
2481 hliquid(liquidpref)
2482 const char *liquidpref;
2483 {
2484     return (Hallucination || !liquidpref) ? hliquids[rn2(SIZE(hliquids))]
2485                                          : liquidpref;
2486 }
2487
2488 /* Aliases for road-runner nemesis
2489  */
2490 static const char *const coynames[] = {
2491     "Carnivorous Vulgaris", "Road-Runnerus Digestus", "Eatibus Anythingus",
2492     "Famishus-Famishus", "Eatibus Almost Anythingus", "Eatius Birdius",
2493     "Famishius Fantasticus", "Eternalii Famishiis", "Famishus Vulgarus",
2494     "Famishius Vulgaris Ingeniusi", "Eatius-Slobbius", "Hardheadipus Oedipus",
2495     "Carnivorous Slobbius", "Hard-Headipus Ravenus", "Evereadii Eatibus",
2496     "Apetitius Giganticus", "Hungrii Flea-Bagius", "Overconfidentii Vulgaris",
2497     "Caninus Nervous Rex", "Grotesques Appetitus", "Nemesis Ridiculii",
2498     "Canis latrans"
2499 };
2500
2501 char *
2502 coyotename(mtmp, buf)
2503 struct monst *mtmp;
2504 char *buf;
2505 {
2506     if (mtmp && buf) {
2507         Sprintf(buf, "%s - %s",
2508                 x_monnam(mtmp, ARTICLE_NONE, (char *) 0, 0, TRUE),
2509                 mtmp->mcan ? coynames[SIZE(coynames) - 1]
2510                            : coynames[mtmp->m_id % (SIZE(coynames) - 1)]);
2511     }
2512     return buf;
2513 }
2514
2515 /* make sure "The Colour of Magic" remains the first entry in here */
2516 static const char *const sir_Terry_novels[] = {
2517     "The Colour of Magic", "The Light Fantastic", "Equal Rites", "Mort",
2518     "Sourcery", "Wyrd Sisters", "Pyramids", "Guards! Guards!", "Eric",
2519     "Moving Pictures", "Reaper Man", "Witches Abroad", "Small Gods",
2520     "Lords and Ladies", "Men at Arms", "Soul Music", "Interesting Times",
2521     "Maskerade", "Feet of Clay", "Hogfather", "Jingo", "The Last Continent",
2522     "Carpe Jugulum", "The Fifth Elephant", "The Truth", "Thief of Time",
2523     "The Last Hero", "The Amazing Maurice and His Educated Rodents",
2524     "Night Watch", "The Wee Free Men", "Monstrous Regiment",
2525     "A Hat Full of Sky", "Going Postal", "Thud!", "Wintersmith",
2526     "Making Money", "Unseen Academicals", "I Shall Wear Midnight", "Snuff",
2527     "Raising Steam", "The Shepherd's Crown"
2528 };
2529
2530 const char *
2531 noveltitle(novidx)
2532 int *novidx;
2533 {
2534     int j, k = SIZE(sir_Terry_novels);
2535
2536     j = rn2(k);
2537     if (novidx) {
2538         if (*novidx == -1)
2539             *novidx = j;
2540         else if (*novidx >= 0 && *novidx < k)
2541             j = *novidx;
2542     }
2543     return sir_Terry_novels[j];
2544 }
2545
2546 const char *
2547 lookup_novel(lookname, idx)
2548 const char *lookname;
2549 int *idx;
2550 {
2551     int k;
2552
2553     /* Take American or U.K. spelling of this one */
2554     if (!strcmpi(The(lookname), "The Color of Magic"))
2555         lookname = sir_Terry_novels[0];
2556
2557     for (k = 0; k < SIZE(sir_Terry_novels); ++k) {
2558         if (!strcmpi(lookname, sir_Terry_novels[k])
2559             || !strcmpi(The(lookname), sir_Terry_novels[k])) {
2560             if (idx)
2561                 *idx = k;
2562             return sir_Terry_novels[k];
2563         }
2564     }
2565     /* name not found; if novelidx is already set, override the name */
2566     if (idx && *idx >= 0 && *idx < SIZE(sir_Terry_novels))
2567         return sir_Terry_novels[*idx];
2568
2569     return (const char *) 0;
2570 }
2571
2572 /*do_name.c*/