OSDN Git Service

add translation
[jnethack/source.git] / src / objnam.c
1 /* NetHack 3.6  objnam.c        $NHDT-Date: 1447490776 2015/11/14 08:46:16 $  $NHDT-Branch: master $:$NHDT-Revision: 1.154 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11
12 /* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */
13 #if 0 /*JP*/
14 #define PREFIX 80 /* (56) */
15 #else
16 /* \81u\8eô\82í\82ê\82Ä\82¢\82È\82¢\96û\82Ì\93h\82ç\82ê\82½\90H\82×\82©\82¯\82Ì\83N\83\8d\83}\83e\83B\83b\83N\81E\83h\83\89\83S\83\93(\82Ì\8e\80\91Ì)\81v*/
17 #define PREFIX 100
18 #endif
19 #define SCHAR_LIM 127
20 #define NUMOBUF 12
21
22 STATIC_DCL char *FDECL(strprepend, (char *, const char *));
23 STATIC_DCL short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P));
24 STATIC_DCL boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P));
25 STATIC_DCL char *NDECL(nextobuf);
26 STATIC_DCL void FDECL(releaseobuf, (char *));
27 STATIC_DCL char *FDECL(minimal_xname, (struct obj *));
28 STATIC_DCL void FDECL(add_erosion_words, (struct obj *, char *));
29 STATIC_DCL boolean
30 FDECL(singplur_lookup, (char *, char *, BOOLEAN_P, const char *const *));
31 STATIC_DCL char *FDECL(singplur_compound, (char *));
32 STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned));
33 #if 1 /*JP*/
34 static char *FDECL(substitute, (char *,     char *,     char *));
35 static char *FDECL(transpose, (char *buf,char *));
36 static char *FDECL(delete, (char *, char *str));
37 static int FDECL(digit_8, (int));
38 static int FDECL(atoi_8, (const char *));
39 #endif
40
41 struct Jitem {
42     int item;
43     const char *name;
44 };
45
46 #define BSTRCMPI(base, ptr, str) ((ptr) < base || strcmpi((ptr), str))
47 #define BSTRNCMPI(base, ptr, str, num) \
48     ((ptr) < base || strncmpi((ptr), str, num))
49 #define Strcasecpy(dst, src) (void) strcasecpy(dst, src)
50
51 /* true for gems/rocks that should have " stone" appended to their names */
52 #define GemStone(typ)                                                  \
53     (typ == FLINT                                                      \
54      || (objects[typ].oc_material == GEMSTONE                          \
55          && (typ != DILITHIUM_CRYSTAL && typ != RUBY && typ != DIAMOND \
56              && typ != SAPPHIRE && typ != BLACK_OPAL && typ != EMERALD \
57              && typ != OPAL)))
58
59 #if 0 /*JP*/
60 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "wakizashi" },
61                                              { BROADSWORD, "ninja-to" },
62                                              { FLAIL, "nunchaku" },
63                                              { GLAIVE, "naginata" },
64                                              { LOCK_PICK, "osaku" },
65                                              { WOODEN_HARP, "koto" },
66                                              { KNIFE, "shito" },
67                                              { PLATE_MAIL, "tanko" },
68                                              { HELMET, "kabuto" },
69                                              { LEATHER_GLOVES, "yugake" },
70                                              { FOOD_RATION, "gunyoki" },
71                                              { POT_BOOZE, "sake" },
72                                              { 0, "" } };
73 #else
74 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "\98e\8d·\82µ" },
75                                              { BROADSWORD, "\94E\8eÒ\93\81" },
76                                              { FLAIL, "\83k\83\93\83`\83\83\83N" },
77                                              { GLAIVE, "\82È\82¬\82È\82½" },
78                                              { LOCK_PICK, "\82¨\82³\82­" },
79                                              { WOODEN_HARP, "\8bÕ" },
80                                              { KNIFE, "\8eh\93\81" },
81                                              { PLATE_MAIL, "\92Z\8db" },
82                                              { HELMET, "\8a\95" },
83                                              { LEATHER_GLOVES, "\8b|\8c\9c" },
84                                              { FOOD_RATION, "\8aÛ\96ò" },
85                                              { POT_BOOZE, "\8eð" },
86                                              { 0, "" } };
87 #endif
88
89 STATIC_DCL const char *FDECL(Japanese_item_name, (int i));
90
91 STATIC_OVL char *
92 strprepend(s, pref)
93 register char *s;
94 register const char *pref;
95 {
96     register int i = (int) strlen(pref);
97
98     if (i > PREFIX) {
99         impossible("PREFIX too short (for %d).", i);
100         return s;
101     }
102     s -= i;
103     (void) strncpy(s, pref, i); /* do not copy trailing 0 */
104     return s;
105 }
106
107 /* manage a pool of BUFSZ buffers, so callers don't have to */
108 static char NEARDATA obufs[NUMOBUF][BUFSZ];
109 static int obufidx = 0;
110
111 STATIC_OVL char *
112 nextobuf()
113 {
114     obufidx = (obufidx + 1) % NUMOBUF;
115     return obufs[obufidx];
116 }
117
118 /* put the most recently allocated buffer back if possible */
119 STATIC_OVL void
120 releaseobuf(bufp)
121 char *bufp;
122 {
123     /* caller may not know whether bufp is the most recently allocated
124        buffer; if it isn't, do nothing */
125     if (bufp == obufs[obufidx])
126         obufidx = (obufidx - 1 + NUMOBUF) % NUMOBUF;
127 }
128
129 char *
130 obj_typename(otyp)
131 register int otyp;
132 {
133     char *buf = nextobuf();
134     register struct objclass *ocl = &objects[otyp];
135     register const char *actualn = OBJ_NAME(*ocl);
136     register const char *dn = OBJ_DESCR(*ocl);
137     register const char *un = ocl->oc_uname;
138     register int nn = ocl->oc_name_known;
139
140     if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
141         actualn = Japanese_item_name(otyp);
142 #if 1 /*JP*/
143     if(un)
144         Sprintf(buf, "%s\82Æ\8cÄ\82Î\82ê\82é", un);
145 #endif
146     switch (ocl->oc_class) {
147     case COIN_CLASS:
148 /*JP
149         Strcpy(buf, "coin");
150 */
151         Strcat(buf, "\8bà\89Ý");
152         break;
153     case POTION_CLASS:
154 /*JP
155         Strcpy(buf, "potion");
156 */
157         Strcat(buf, "\96ò");
158         break;
159     case SCROLL_CLASS:
160 /*JP
161         Strcpy(buf, "scroll");
162 */
163         Strcat(buf, "\8aª\95¨");
164         break;
165     case WAND_CLASS:
166 /*JP
167         Strcpy(buf, "wand");
168 */
169         Strcat(buf, "\8fñ");
170         break;
171     case SPBOOK_CLASS:
172 /*JP
173         Strcpy(buf, "spellbook");
174 */
175         Strcat(buf, "\96\82\96@\8f\91");
176         break;
177     case RING_CLASS:
178 /*JP
179         Strcpy(buf, "ring");
180 */
181         Strcat(buf, "\8ew\97Ö");
182         break;
183     case AMULET_CLASS:
184 #if 0 /*JP*/
185         if (nn)
186             Strcpy(buf, actualn);
187         else
188             Strcpy(buf, "amulet");
189         if (un)
190             Sprintf(eos(buf), " called %s", un);
191         if (dn)
192             Sprintf(eos(buf), " (%s)", dn);
193         return buf;
194 #else
195         if (nn)
196             Strcat(buf, actualn);
197         else if(un)
198             Strcat(buf, "\96\82\8f\9c\82¯");
199         break;
200 #endif
201 #if 1 /*JP*/
202     case GEM_CLASS:
203         if(nn)
204           Strcat(buf, actualn);
205         else if(un)
206           Strcat(buf, "\95ó\90Î");
207         break;
208 #endif
209     default:
210         if (nn) {
211 #if 0 /*JP*/
212             Strcpy(buf, actualn);
213             if (GemStone(otyp))
214                 Strcat(buf, " stone");
215             if (un)
216                 Sprintf(eos(buf), " called %s", un);
217             if (dn)
218                 Sprintf(eos(buf), " (%s)", dn);
219 #else
220             Strcat(buf, actualn);
221 #endif
222         } else {
223 #if 0 /*JP*/
224             Strcpy(buf, dn ? dn : actualn);
225             if (ocl->oc_class == GEM_CLASS)
226                 Strcat(buf,
227                        (ocl->oc_material == MINERAL) ? " stone" : " gem");
228             if (un)
229                 Sprintf(eos(buf), " called %s", un);
230 #else
231             Strcat(buf, dn ? dn : actualn);
232 #endif
233         }
234 #if 0 /*JP*/
235         return buf;
236 #else
237         break;
238 #endif
239     }
240     /* here for ring/scroll/potion/wand */
241     if (nn) {
242 #if 0 /*JP*/
243         if (ocl->oc_unique)
244             Strcpy(buf, actualn); /* avoid spellbook of Book of the Dead */
245         else
246             Sprintf(eos(buf), " of %s", actualn);
247 #else
248         Strcpy(buf, actualn);
249 #endif
250     }
251 #if 0 /*JP*/
252     if (un)
253         Sprintf(eos(buf), " called %s", un);
254 #endif
255     if (dn)
256 #if 0 /*JP*/
257         Sprintf(eos(buf), " (%s)", dn);
258 #else
259         Sprintf(eos(buf), "(%s)", dn);
260 #endif
261     return buf;
262 }
263
264 /* less verbose result than obj_typename(); either the actual name
265    or the description (but not both); user-assigned name is ignored */
266 char *
267 simple_typename(otyp)
268 int otyp;
269 {
270     char *bufp, *pp, *save_uname = objects[otyp].oc_uname;
271
272     objects[otyp].oc_uname = 0; /* suppress any name given by user */
273     bufp = obj_typename(otyp);
274     objects[otyp].oc_uname = save_uname;
275     if ((pp = strstri(bufp, " (")) != 0)
276         *pp = '\0'; /* strip the appended description */
277     return bufp;
278 }
279
280 boolean
281 obj_is_pname(obj)
282 struct obj *obj;
283 {
284     if (!obj->oartifact || !has_oname(obj))
285         return FALSE;
286     if (!program_state.gameover && !iflags.override_ID) {
287         if (not_fully_identified(obj))
288             return FALSE;
289     }
290     return TRUE;
291 }
292
293 /* Give the name of an object seen at a distance.  Unlike xname/doname,
294  * we don't want to set dknown if it's not set already.  The kludge used is
295  * to temporarily set Blind so that xname() skips the dknown setting.  This
296  * assumes that we don't want to do this too often; if this function becomes
297  * frequently used, it'd probably be better to pass a parameter to xname()
298  * or doname() instead.
299  */
300 char *
301 distant_name(obj, func)
302 struct obj *obj;
303 char *FDECL((*func), (OBJ_P));
304 {
305     char *str;
306
307     long save_Blinded = Blinded;
308     Blinded = 1;
309     str = (*func)(obj);
310     Blinded = save_Blinded;
311     return str;
312 }
313
314 /* convert player specified fruit name into corresponding fruit juice name
315    ("slice of pizza" -> "pizza juice" rather than "slice of pizza juice") */
316 char *
317 fruitname(juice)
318 boolean juice; /* whether or not to append " juice" to the name */
319 {
320 #if 1 /*JP*//*\93ú\96{\8cê\82Å\82Í\82»\82±\82Ü\82Å\82µ\82È\82¢*/
321     char *buf = nextobuf();
322     Sprintf(buf, "%s%s", pl_fruit, juice ? "\83W\83\85\81[\83X" : "");
323     return buf;
324 #else
325     char *buf = nextobuf();
326     const char *fruit_nam = strstri(pl_fruit, " of ");
327
328     if (fruit_nam)
329         fruit_nam += 4; /* skip past " of " */
330     else
331         fruit_nam = pl_fruit; /* use it as is */
332
333     Sprintf(buf, "%s%s", makesingular(fruit_nam), juice ? " juice" : "");
334     return buf;
335 #endif
336 }
337
338 char *
339 xname(obj)
340 struct obj *obj;
341 {
342     return xname_flags(obj, CXN_NORMAL);
343 }
344
345 char *
346 xname_flags(obj, cxn_flags)
347 register struct obj *obj;
348 unsigned cxn_flags; /* bitmask of CXN_xxx values */
349 {
350     register char *buf;
351     register int typ = obj->otyp;
352     register struct objclass *ocl = &objects[typ];
353     int nn = ocl->oc_name_known, omndx = obj->corpsenm;
354     const char *actualn = OBJ_NAME(*ocl);
355     const char *dn = OBJ_DESCR(*ocl);
356     const char *un = ocl->oc_uname;
357     boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
358     boolean known, dknown, bknown;
359
360     buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
361     if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
362         actualn = Japanese_item_name(typ);
363
364     buf[0] = '\0';
365     /*
366      * clean up known when it's tied to oc_name_known, eg after AD_DRIN
367      * This is only required for unique objects since the article
368      * printed for the object is tied to the combination of the two
369      * and printing the wrong article gives away information.
370      */
371     if (!nn && ocl->oc_uses_known && ocl->oc_unique)
372         obj->known = 0;
373     if (!Blind)
374         obj->dknown = TRUE;
375     if (Role_if(PM_PRIEST))
376         obj->bknown = TRUE;
377
378     if (iflags.override_ID) {
379         known = dknown = bknown = TRUE;
380         nn = 1;
381     } else {
382         known = obj->known;
383         dknown = obj->dknown;
384         bknown = obj->bknown;
385     }
386
387     if (obj_is_pname(obj))
388 #if 0 /*JP*/
389         goto nameit;
390 #else
391     {
392         Strcat(buf, ONAME(obj));
393         goto nameit;
394     }
395 #endif
396 #if 1 /*JP*/
397     if (has_oname(obj) && dknown) {
398         Strcat(buf, ONAME(obj));
399         Strcat(buf, "\82Æ\96¼\82Ã\82¯\82ç\82ê\82½");
400     }
401 #endif
402     switch (obj->oclass) {
403     case AMULET_CLASS:
404         if (!dknown)
405 /*JP
406             Strcpy(buf, "amulet");
407 */
408             Strcat(buf, "\96\82\8f\9c\82¯");  
409         else if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
410             /* each must be identified individually */
411             Strcpy(buf, known ? actualn : dn);
412         else if (nn)
413             Strcpy(buf, actualn);
414         else if (un)
415 /*JP
416             Sprintf(buf, "amulet called %s", un);
417 */
418             Sprintf(eos(buf), "%s\82Æ\8cÄ\82Î\82ê\82é\96\82\8f\9c\82¯", un);
419         else
420 /*JP
421             Sprintf(buf, "%s amulet", dn);
422 */
423             Sprintf(eos(buf), "%s", dn);
424         break;
425     case WEAPON_CLASS:
426         if (is_poisonable(obj) && obj->opoisoned)
427 /*JP
428             Strcpy(buf, "poisoned ");
429 */
430             Strcpy(buf, "\93Å\82Ì\93h\82ç\82ê\82½");
431     case VENOM_CLASS:
432     case TOOL_CLASS:
433 #if 1 /*JP*/
434         if (typ == FIGURINE)
435             Sprintf(eos(buf), "%s\82Ì", mons[obj->corpsenm].mname);
436 #endif
437         if (typ == LENSES)
438 /*JP
439             Strcpy(buf, "pair of ");
440 */
441             Strcpy(buf, "\88ê\91Î\82Ì");
442         else if (is_wet_towel(obj))
443 /*JP
444             Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
445 */
446             Strcpy(buf, (obj->spe < 3) ? "\8e¼\82Á\82½" : "\94G\82ê\82½");
447
448         if (!dknown)
449             Strcat(buf, dn ? dn : actualn);
450         else if (nn)
451             Strcat(buf, actualn);
452         else if (un) {
453 #if 0 /*JP*/
454             Strcat(buf, dn ? dn : actualn);
455             Strcat(buf, " called ");
456             Strcat(buf, un);
457 #else
458             Strcat(buf, un);
459             Strcat(buf, "\82Æ\8cÄ\82Î\82ê\82é");
460             Strcat(buf, dn ? dn : actualn);
461 #endif
462         } else
463             Strcat(buf, dn ? dn : actualn);
464 #if 0 /*JP*/ /*\82±\82ê\82Í\8cê\8f\87\82Ì\8aÖ\8cW\82©\82ç\8fã\82Ì\95û\82Å\92è\8b`*/
465         /* If we use an() here we'd have to remember never to use */
466         /* it whenever calling doname() or xname(). */
467         if (typ == FIGURINE && omndx != NON_PM) {
468             Sprintf(eos(buf), " of a%s %s",
469                     index(vowels, *mons[omndx].mname) ? "n" : "",
470                     mons[omndx].mname);
471         } else if (is_wet_towel(obj)) {
472 #else
473         if (is_wet_towel(obj)) {
474 #endif
475             if (wizard)
476                 Sprintf(eos(buf), " (%d)", obj->spe);
477         }
478         break;
479     case ARMOR_CLASS:
480         /* depends on order of the dragon scales objects */
481         if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
482 /*JP
483             Sprintf(buf, "set of %s", actualn);
484 */
485             Sprintf(buf, "%s\88ê\8e®", actualn);
486             break;
487         }
488         if (is_boots(obj) || is_gloves(obj))
489 /*JP
490             Strcpy(buf, "pair of ");
491 */
492             Strcat(buf,"\88ê\91Î\82Ì");
493
494         if (obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
495             && !dknown) {
496 /*JP
497             Strcpy(buf, "shield");
498 */
499             Strcat(buf, "\8f\82");
500             break;
501         }
502         if (obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
503 /*JP
504             Strcpy(buf, "smooth shield");
505 */
506             Strcat(buf, "\82·\82×\82·\82×\82µ\82½\8f\82");
507             break;
508         }
509
510         if (nn)
511             Strcat(buf, actualn);
512         else if (un) {
513 #if 0 /*JP*/
514             if (is_boots(obj))
515                 Strcat(buf, "boots");
516             else if (is_gloves(obj))
517                 Strcat(buf, "gloves");
518             else if (is_cloak(obj))
519                 Strcpy(buf, "cloak");
520             else if (is_helmet(obj))
521                 Strcpy(buf, "helmet");
522             else if (is_shield(obj))
523                 Strcpy(buf, "shield");
524             else
525                 Strcpy(buf, "armor");
526             Strcat(buf, " called ");
527             Strcat(buf, un);
528 #else
529             char *p;
530             if (is_boots(obj))
531                 p = "\8cC";
532             else if (is_gloves(obj))
533                 p = "\8f¬\8eè";
534             else if (is_cloak(obj))
535                 p = "\83N\83\8d\81[\83N";
536             else if (is_helmet(obj))
537                 p = "\8a\95";
538             else if (is_shield(obj))
539                 p = "\8f\82";
540             else
541                 p = "\8aZ";
542             Sprintf(eos(buf), "%s\82Æ\8cÄ\82Î\82ê\82é%s", un, p);
543 #endif
544         } else
545             Strcat(buf, dn);
546         break;
547     case FOOD_CLASS:
548         if (typ == SLIME_MOLD) {
549             register struct fruit *f;
550
551             for (f = ffruit; f; f = f->nextf) {
552                 if (f->fid == obj->spe) {
553                     Strcpy(buf, f->fname);
554                     break;
555                 }
556             }
557             if (!f) {
558                 impossible("Bad fruit #%d?", obj->spe);
559                 Strcpy(buf, "fruit");
560             } else if (pluralize) {
561                 /* ick; already pluralized fruit names
562                    are allowed--we want to try to avoid
563                    adding a redundant plural suffix */
564                 Strcpy(buf, makeplural(makesingular(buf)));
565                 pluralize = FALSE;
566             }
567             break;
568         }
569         if (Is_pudding(obj)) {
570             Sprintf(buf, "%s%s",
571                     (obj->owt < 100)
572 /*JP
573                        ? "small "
574 */
575                        ? "\8f¬\82³\82¢"
576                        : (obj->owt > 500)
577 /*JP
578                           ? "very large "
579 */
580                           ? "\82Æ\82Ä\82à\91å\82«\82¢"
581                           : (obj->owt > 300)
582 /*JP
583                              ? "large "
584 */
585                              ? "\91å\82«\82¢"
586                              : "",
587                     actualn);
588             break;
589         }
590
591 #if 0 /*JP*/
592         Strcpy(buf, actualn);
593         if (typ == TIN && known)
594             tin_details(obj, omndx, buf);
595 #else
596         if (typ == TIN && known)
597             /*JP \81u\81`\82Ì\93÷\82Ì\81v*/
598             tin_details(obj, omndx, buf);
599         Strcat(buf, actualn);
600 #endif
601         break;
602     case COIN_CLASS:
603     case CHAIN_CLASS:
604 #if 0 /*JP*/
605         Strcpy(buf, actualn);
606 #else
607         Strcat(buf, actualn);
608 #endif
609         break;
610     case ROCK_CLASS:
611         if (typ == STATUE && omndx != NON_PM)
612 #if 0 /*JP*/
613             Sprintf(buf, "%s%s of %s%s",
614                     (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
615                        ? "historic "
616                        : "",
617                     actualn,
618                     type_is_pname(&mons[omndx])
619                        ? ""
620                        : the_unique_pm(&mons[omndx])
621                           ? "the "
622                           : index(vowels, *mons[omndx].mname)
623                              ? "an "
624                              : "a ",
625                     mons[omndx].mname);
626 #else
627             Sprintf(eos(buf), "%s%s\82Ì%s", 
628                     (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
629                     ? "\97ð\8ej\93I\82È"
630                     : "",
631                     mons[obj->corpsenm].mname, actualn);
632 #endif
633         else
634 #if 0 /*JP*/
635             Strcpy(buf, actualn);
636 #else
637             Strcat(buf, actualn);
638 #endif
639         break;
640     case BALL_CLASS:
641 #if 0 /*JP*/
642         Sprintf(buf, "%sheavy iron ball",
643                 (obj->owt > ocl->oc_weight) ? "very " : "");
644 #else
645         Sprintf(eos(buf), "%s\8fd\82¢\93S\8b\85",
646                 (obj->owt > ocl->oc_weight) ? "\82Æ\82Ä\82à" : "");
647 #endif
648         break;
649     case POTION_CLASS:
650         if (dknown && obj->odiluted)
651 /*JP
652             Strcpy(buf, "diluted ");
653 */
654             Strcat(buf, "\94\96\82Ü\82Á\82½");
655         if (nn || un || !dknown) {
656 #if 0 /*JP*/
657             Strcat(buf, "potion");
658             if (!dknown)
659                 break;
660 #else
661             if (!dknown){
662                 Strcat(buf, "\96ò");
663                 break;
664             }
665 #endif
666             if (nn) {
667 #if 0 /*JP*/
668                 Strcat(buf, " of ");
669 #endif
670                 if (typ == POT_WATER && bknown
671                     && (obj->blessed || obj->cursed)) {
672 /*JP
673                     Strcat(buf, obj->blessed ? "holy " : "unholy ");
674 */
675                     Strcat(buf, obj->blessed ? "\90¹" : "\95s\8fò\82È");
676                 }
677                 Strcat(buf, actualn);
678             } else {
679 #if 0 /*JP*/
680                 Strcat(buf, " called ");
681                 Strcat(buf, un);
682 #else
683                 Strcat(buf, un);
684                 Strcat(buf, "\82Æ\8cÄ\82Î\82ê\82é\96ò");
685 #endif
686             }
687         } else {
688             Strcat(buf, dn);
689 #if 0 /*JP*//*\95s\8am\92è\96¼\82É\81u\96ò\81v\82Í\95t\82¢\82Ä\82¢\82é*/
690             Strcat(buf, " potion");
691 #endif
692         }
693         break;
694     case SCROLL_CLASS:
695 #if 0 /*JP*/
696         Strcpy(buf, "scroll");
697         if (!dknown)
698             break;
699 #else
700         if(!dknown){
701             Strcat(buf,"\8aª\95¨");
702             break;
703         }
704 #endif
705         if (nn) {
706 #if 0 /*JP*/
707             Strcat(buf, " of ");
708 #endif
709             Strcat(buf, actualn);
710         } else if (un) {
711 #if 0 /*JP*/
712             Strcat(buf, " called ");
713             Strcat(buf, un);
714 #else
715             Strcat(buf, un);
716             Strcat(buf, "\82Æ\8cÄ\82Î\82ê\82é\8aª\95¨");
717 #endif
718         } else if (ocl->oc_magic) {
719 #if 0 /*JP*/
720             Strcat(buf, " labeled ");
721 #endif
722             Strcat(buf, dn);
723         } else {
724 #if 0 /*JP*/
725             Strcpy(buf, dn);
726             Strcat(buf, " scroll");
727 #else
728             Strcat(buf, dn);
729 #endif
730         }
731         break;
732     case WAND_CLASS:
733         if (!dknown)
734 /*JP
735             Strcpy(buf, "wand");
736 */
737             Strcat(buf, "\8fñ");
738         else if (nn)
739 /*JP
740             Sprintf(buf, "wand of %s", actualn);
741 */
742             Strcat(buf, actualn);
743         else if (un)
744 /*JP
745             Sprintf(buf, "wand called %s", un);
746 */
747             Sprintf(eos(buf), "%s\82Æ\8cÄ\82Î\82ê\82é\8fñ", un);
748         else
749 /*JP
750             Sprintf(buf, "%s wand", dn);
751 */
752             Strcat(buf, dn);
753         break;
754     case SPBOOK_CLASS:
755         if (typ == SPE_NOVEL) { /* 3.6 tribute */
756             if (!dknown)
757                 Strcpy(buf, "book");
758             else if (nn)
759                 Strcpy(buf, actualn);
760             else if (un)
761                 Sprintf(buf, "novel called %s", un);
762             else
763                 Sprintf(buf, "%s book", dn);
764             break;
765             /* end of tribute */
766         } else if (!dknown) {
767 /*JP
768             Strcpy(buf, "spellbook");
769 */
770             Strcat(buf, "\96\82\96@\8f\91");
771         } else if (nn) {
772 #if 0 /*JP*/
773             if (typ != SPE_BOOK_OF_THE_DEAD)
774                 Strcpy(buf, "spellbook of ");
775 #endif
776             Strcat(buf, actualn);
777         } else if (un) {
778 /*JP
779             Sprintf(buf, "spellbook called %s", un);
780 */
781             Sprintf(eos(buf), "%s\82Æ\8cÄ\82Î\82ê\82é\96\82\96@\8f\91", un);
782         } else
783 /*JP
784             Sprintf(buf, "%s spellbook", dn);
785 */
786             Sprintf(eos(buf), "%s", dn);
787         break;
788     case RING_CLASS:
789         if (!dknown)
790 /*JP
791             Strcpy(buf, "ring");
792 */
793             Strcat(buf, "\8ew\97Ö");
794         else if (nn)
795 /*JP
796             Sprintf(buf, "ring of %s", actualn);
797 */
798             Strcat(buf, actualn);
799         else if (un)
800 /*JP
801             Sprintf(buf, "ring called %s", un);
802 */
803             Sprintf(eos(buf), "%s\82Æ\8cÄ\82Î\82ê\82é\8ew\97Ö", un);
804         else
805 /*JP
806             Sprintf(buf, "%s ring", dn);
807 */
808             Strcat(buf, dn);
809         break;
810     case GEM_CLASS: {
811 /*JP
812         const char *rock = (ocl->oc_material == MINERAL) ? "stone" : "gem";
813 */
814         const char *rock = (ocl->oc_material == MINERAL) ? "\90Î" : "\95ó\90Î";
815
816         if (!dknown) {
817 #if 0 /*JP*/
818             Strcpy(buf, rock);
819 #else
820             Strcat(buf, rock);
821 #endif
822         } else if (!nn) {
823             if (un)
824 /*JP
825                 Sprintf(buf, "%s called %s", rock, un);
826 */
827                 Sprintf(eos(buf), "%s\82Æ\8cÄ\82Î\82ê\82é%s", un, rock);
828             else
829 /*JP
830                 Sprintf(buf, "%s %s", dn, rock);
831 */
832                 Strcat(buf, dn);
833         } else {
834             Strcpy(buf, actualn);
835 #if 0 /*JP*/
836             if (GemStone(typ))
837                 Strcat(buf, " stone");
838 #endif
839         }
840         break;
841     }
842     default:
843         Sprintf(buf, "glorkum %d %d %d", obj->oclass, typ, obj->spe);
844     }
845 #if 0 /*JP*/
846     if (pluralize)
847         Strcpy(buf, makeplural(buf));
848 #endif
849
850     if (obj->otyp == T_SHIRT && program_state.gameover) {
851         char tmpbuf[BUFSZ];
852
853 /*JP
854         Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
855 */
856         Sprintf(eos(buf), "(\81u%s\81v\82Æ\8f\91\82¢\82Ä\82 \82é)", tshirt_text(obj, tmpbuf));
857     }
858
859 #if 0 /*JP*/
860     if (has_oname(obj) && dknown) {
861         Strcat(buf, " named ");
862     nameit:
863         Strcat(buf, ONAME(obj));
864     }
865
866     if (!strncmpi(buf, "the ", 4))
867         buf += 4;
868 #else
869 nameit:
870 #endif
871     return buf;
872 }
873
874 /* similar to simple_typename but minimal_xname operates on a particular
875    object rather than its general type; it formats the most basic info:
876      potion                     -- if description not known
877      brown potion               -- if oc_name_known not set
878      potion of object detection -- if discovered
879  */
880 static char *
881 minimal_xname(obj)
882 struct obj *obj;
883 {
884     char *bufp;
885     struct obj bareobj;
886     struct objclass saveobcls;
887     int otyp = obj->otyp;
888
889     /* suppress user-supplied name */
890     saveobcls.oc_uname = objects[otyp].oc_uname;
891     objects[otyp].oc_uname = 0;
892     /* suppress actual name if object's description is unknown */
893     saveobcls.oc_name_known = objects[otyp].oc_name_known;
894     if (!obj->dknown)
895         objects[otyp].oc_name_known = 0;
896
897     /* caveat: this makes a lot of assumptions about which fields
898        are required in order for xname() to yield a sensible result */
899     bareobj = zeroobj;
900     bareobj.otyp = otyp;
901     bareobj.oclass = obj->oclass;
902     bareobj.dknown = obj->dknown;
903     /* suppress known except for amulets (needed for fakes and real A-of-Y) */
904     bareobj.known = (obj->oclass == AMULET_CLASS)
905                         ? obj->known
906                         /* default is "on" for types which don't use it */
907                         : !objects[otyp].oc_uses_known;
908     bareobj.quan = 1L;         /* don't want plural */
909     bareobj.corpsenm = NON_PM; /* suppress statue and figurine details */
910     /* but suppressing fruit details leads to "bad fruit #0"
911        [perhaps we should force "slime mold" rather than use xname?] */
912     if (obj->otyp == SLIME_MOLD)
913         bareobj.spe = obj->spe;
914
915     bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
916 #if 0 /*JP*/
917     if (!strncmp(bufp, "uncursed ", 9))
918         bufp += 9; /* Role_if(PM_PRIEST) */
919 #else
920     if (!strncmp(bufp, "\8eô\82í\82ê\82Ä\82¢\82È\82¢", 14))
921         bufp += 14; /* Role_if(PM_PRIEST) */
922 #endif
923
924     objects[otyp].oc_uname = saveobcls.oc_uname;
925     objects[otyp].oc_name_known = saveobcls.oc_name_known;
926     return bufp;
927 }
928
929 /* xname() output augmented for multishot missile feedback */
930 char *
931 mshot_xname(obj)
932 struct obj *obj;
933 {
934     char tmpbuf[BUFSZ];
935     char *onm = xname(obj);
936
937     if (m_shot.n > 1 && m_shot.o == obj->otyp) {
938         /* "the Nth arrow"; value will eventually be passed to an() or
939            The(), both of which correctly handle this "the " prefix */
940 /*JP
941         Sprintf(tmpbuf, "the %d%s ", m_shot.i, ordin(m_shot.i));
942 */
943         Sprintf(tmpbuf, "%d%s\96Ú\82Ì", m_shot.i, numeral(obj));
944         onm = strprepend(onm, tmpbuf);
945     }
946     return onm;
947 }
948
949 /* used for naming "the unique_item" instead of "a unique_item" */
950 boolean
951 the_unique_obj(obj)
952 struct obj *obj;
953 {
954 #if 0 /*JP*/
955     boolean known = (obj->known || iflags.override_ID);
956
957     if (!obj->dknown && !iflags.override_ID)
958         return FALSE;
959     else if (obj->otyp == FAKE_AMULET_OF_YENDOR && !known)
960         return TRUE; /* lie */
961     else
962         return (boolean) (objects[obj->otyp].oc_unique
963                           && (known || obj->otyp == AMULET_OF_YENDOR));
964 #else
965     return FALSE;
966 #endif
967 }
968
969 /* should monster type be prefixed with "the"? (mostly used for corpses) */
970 boolean
971 the_unique_pm(ptr)
972 struct permonst *ptr;
973 {
974     boolean uniq;
975
976     /* even though monsters with personal names are unique, we want to
977        describe them as "Name" rather than "the Name" */
978     if (type_is_pname(ptr))
979         return FALSE;
980
981     uniq = (ptr->geno & G_UNIQ) ? TRUE : FALSE;
982     /* high priest is unique if it includes "of <deity>", otherwise not
983        (caller needs to handle the 1st possibility; we assume the 2nd);
984        worm tail should be irrelevant but is included for completeness */
985     if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
986         uniq = FALSE;
987     /* Wizard no longer needs this; he's flagged as unique these days */
988     if (ptr == &mons[PM_WIZARD_OF_YENDOR])
989         uniq = TRUE;
990     return uniq;
991 }
992
993 STATIC_OVL void
994 add_erosion_words(obj, prefix)
995 struct obj *obj;
996 char *prefix;
997 {
998     boolean iscrys = (obj->otyp == CRYSKNIFE);
999     boolean rknown;
1000
1001     rknown = (iflags.override_ID == 0) ? obj->rknown : TRUE;
1002
1003     if (!is_damageable(obj) && !iscrys)
1004         return;
1005
1006     /* The only cases where any of these bits do double duty are for
1007      * rotted food and diluted potions, which are all not is_damageable().
1008      */
1009     if (obj->oeroded && !iscrys) {
1010         switch (obj->oeroded) {
1011         case 2:
1012 /*JP
1013             Strcat(prefix, "very ");
1014 */
1015             Strcat(prefix, "\82Æ\82Ä\82à");
1016             break;
1017         case 3:
1018 /*JP
1019             Strcat(prefix, "thoroughly ");
1020 */
1021             Strcat(prefix, "\82©\82È\82è");
1022             break;
1023         }
1024 /*JP
1025         Strcat(prefix, is_rustprone(obj) ? "rusty " : "burnt ");
1026 */
1027         Strcat(prefix, is_rustprone(obj) ? "\8eK\82Ñ\82½" : "\8f\9d\82Â\82¢\82½");
1028     }
1029     if (obj->oeroded2 && !iscrys) {
1030         switch (obj->oeroded2) {
1031         case 2:
1032 /*JP
1033             Strcat(prefix, "very ");
1034 */
1035             Strcat(prefix, "\82Æ\82Ä\82à");
1036             break;
1037         case 3:
1038 /*JP
1039             Strcat(prefix, "thoroughly ");
1040 */
1041             Strcat(prefix, "\82©\82È\82è");
1042             break;
1043         }
1044 /*JP
1045         Strcat(prefix, is_corrodeable(obj) ? "corroded " : "rotted ");
1046 */
1047         Strcat(prefix, is_corrodeable(obj) ? "\95\85\90H\82µ\82½" : "\95\85\82Á\82½");
1048     }
1049     if (rknown && obj->oerodeproof)
1050         Strcat(prefix, iscrys
1051 /*JP
1052                           ? "fixed "
1053 */
1054                           ? "\88À\92è\82µ\82½"
1055                           : is_rustprone(obj)
1056 /*JP
1057                              ? "rustproof "
1058 */
1059                              ? "\8eK\82Ñ\82È\82¢"
1060                              : is_corrodeable(obj)
1061 #if 0 /*JP*/
1062                                 ? "corrodeproof " /* "stainless"? */
1063 #else
1064                                 ? "\95\85\90H\82µ\82È\82¢" /* "stainless"? */
1065 #endif
1066                                 : is_flammable(obj)
1067 /*JP
1068                                    ? "fireproof "
1069 */
1070                                    ? "\94R\82¦\82È\82¢"
1071                                    : "");
1072 }
1073
1074 static char *
1075 doname_base(obj, with_price)
1076 register struct obj *obj;
1077 boolean with_price;
1078 {
1079     boolean ispoisoned = FALSE;
1080     boolean known, cknown, bknown, lknown;
1081     int omndx = obj->corpsenm;
1082     char prefix[PREFIX];
1083 #if 0 /*JP*/
1084     char tmpbuf[PREFIX + 1]; /* for when we have to add something at
1085                                 the start of prefix instead of the
1086                                 end (Strcat is used on the end) */
1087 #endif
1088     register char *bp = xname(obj);
1089 #if 1 /*JP*//*\8f\87\8f\98\93ü\82ê\91Ö\82¦\82É\8eg\82¤*/
1090     char preprefix[PREFIX];
1091 #endif
1092
1093     if (iflags.override_ID) {
1094         known = cknown = bknown = lknown = TRUE;
1095     } else {
1096         known = obj->known;
1097         cknown = obj->cknown;
1098         bknown = obj->bknown;
1099         lknown = obj->lknown;
1100     }
1101
1102     /* When using xname, we want "poisoned arrow", and when using
1103      * doname, we want "poisoned +0 arrow".  This kludge is about the only
1104      * way to do it, at least until someone overhauls xname() and doname(),
1105      * combining both into one function taking a parameter.
1106      */
1107     /* must check opoisoned--someone can have a weirdly-named fruit */
1108 #if 0 /*JP*/
1109     if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
1110         bp += 9;
1111         ispoisoned = TRUE;
1112     }
1113 #else
1114     if (!strncmp(bp, "\93Å\82Ì\93h\82ç\82ê\82½", 12) && obj->opoisoned) {
1115         bp += 12;
1116         ispoisoned = TRUE;
1117     }
1118 #endif
1119 #if 1 /*JP*/
1120     /* JP
1121      *\81u\8eq\94L\82Ì\82½\82Ü\82Æ\96¼\82Ã\82¯\82ç\82ê\82½\8e\80\91Ì\81v\82æ\82è\81u\82½\82Ü\82Æ\96¼\82Ã\82¯\82ç\82ê\82½\8eq\94L\82Ì\8e\80\91Ì\81v
1122      *  \82Ì\82Ù\82¤\82ª\8e©\91R\82Å\82 \82é\81D
1123      */
1124     {
1125         char *tp;
1126         preprefix[0] = '\0';
1127         if((tp = strstri(bp, "\96¼\82Ã\82¯\82ç\82ê\82½")) != NULL){
1128             tp += 12; /* \81u\96¼\82Ã\82¯\82ç\82ê\82½\81v*/
1129             strncpy(preprefix, bp, tp - bp);
1130             preprefix[tp - bp] = '\0';
1131             bp = tp;
1132         }
1133         Strcpy(prefix, "");
1134     }
1135 #endif
1136
1137     if (obj->quan != 1L) {
1138 #if 0 /*JP*/
1139         Sprintf(prefix, "%ld ", obj->quan);
1140 #else /* \93ú\96{\8cê\82Æ\82µ\82Ä\82Í\90\94\8e\8c\82ª\82È\82¢\82Ì\82Í\95s\8e©\91R */
1141         Sprintf(prefix, "%ld%s\82Ì", obj->quan, numeral(obj));
1142 #endif
1143     } else if (obj->otyp == CORPSE) {
1144         /* skip article prefix for corpses [else corpse_xname()
1145            would have to be taught how to strip it off again] */
1146         *prefix = '\0';
1147 #if 0 /*JP*/ /* \8a¥\8e\8c\82Í\95s\97v */
1148     } else if (obj_is_pname(obj) || the_unique_obj(obj)) {
1149         if (!strncmpi(bp, "the ", 4))
1150             bp += 4;
1151         Strcpy(prefix, "the ");
1152     } else {
1153         Strcpy(prefix, "a ");
1154 #else /*prefix\82Ì\8f\89\8aú\89»*/
1155     } else {
1156         Strcpy(prefix, "");
1157 #endif
1158     }
1159
1160     /* "empty" goes at the beginning, but item count goes at the end */
1161     if (cknown
1162         /* bag of tricks: include "empty" prefix if it's known to
1163            be empty but its precise number of charges isn't known
1164            (when that is known, suffix of "(n:0)" will be appended,
1165            making the prefix be redundant; note that 'known' flag
1166            isn't set when emptiness gets discovered because then
1167            charging magic would yield known number of new charges) */
1168         && (obj->otyp == BAG_OF_TRICKS
1169              ? (obj->spe == 0 && !obj->known)
1170              /* not bag of tricks: empty if container which has no contents */
1171              : (Is_container(obj) || obj->otyp == STATUE)
1172             && !Has_contents(obj)))
1173 /*JP
1174         Strcat(prefix, "empty ");
1175 */
1176         Strcat(prefix, "\8bó\82Ì");
1177
1178     if (bknown && obj->oclass != COIN_CLASS
1179         && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
1180             || (!obj->cursed && !obj->blessed))) {
1181         /* allow 'blessed clear potion' if we don't know it's holy water;
1182          * always allow "uncursed potion of water"
1183          */
1184         if (obj->cursed)
1185 /*JP
1186             Strcat(prefix, "cursed ");
1187 */
1188             Strcat(prefix, "\8eô\82í\82ê\82½");
1189         else if (obj->blessed)
1190 /*JP
1191             Strcat(prefix, "blessed ");
1192 */
1193             Strcat(prefix, "\8fj\95\9f\82³\82ê\82½");
1194         else if (!iflags.implicit_uncursed
1195             /* For most items with charges or +/-, if you know how many
1196              * charges are left or what the +/- is, then you must have
1197              * totally identified the item, so "uncursed" is unnecessary,
1198              * because an identified object not described as "blessed" or
1199              * "cursed" must be uncursed.
1200              *
1201              * If the charges or +/- is not known, "uncursed" must be
1202              * printed to avoid ambiguity between an item whose curse
1203              * status is unknown, and an item known to be uncursed.
1204              */
1205                  || ((!known || !objects[obj->otyp].oc_charged
1206                       || obj->oclass == ARMOR_CLASS
1207                       || obj->oclass == RING_CLASS)
1208 #ifdef MAIL
1209                      && obj->otyp != SCR_MAIL
1210 #endif
1211                      && obj->otyp != FAKE_AMULET_OF_YENDOR
1212                      && obj->otyp != AMULET_OF_YENDOR
1213                      && !Role_if(PM_PRIEST)))
1214 /*JP
1215             Strcat(prefix, "uncursed ");
1216 */
1217             Strcat(prefix, "\8eô\82í\82ê\82Ä\82¢\82È\82¢");
1218     }
1219
1220     if (lknown && Is_box(obj)) {
1221         if (obj->obroken)
1222 /*JP
1223             Strcat(prefix, "unlockable ");
1224 */
1225             Strcat(prefix, "\8c®\82Ì\89ó\82ê\82½");
1226         else if (obj->olocked)
1227 /*JP
1228             Strcat(prefix, "locked ");
1229 */
1230             Strcat(prefix, "\8c®\82Ì\8a|\82©\82Á\82½");
1231         else
1232 /*JP
1233             Strcat(prefix, "unlocked ");
1234 */
1235             Strcat(prefix, "\8c®\82Ì\8a|\82©\82Á\82Ä\82¢\82È\82¢");
1236     }
1237
1238     if (obj->greased)
1239 /*JP
1240         Strcat(prefix, "greased ");
1241 */
1242         Strcat(prefix, "\96û\82Ì\93h\82ç\82ê\82½");
1243
1244     if (cknown && Has_contents(obj)) {
1245         /* we count all objects (obj->quantity); perhaps we should
1246            count separate stacks instead (or even introduce a user
1247            preference option to choose between the two alternatives)
1248            since it's somewhat odd so see "containing 1002 items"
1249            when there are 2 scrolls plus 1000 gold pieces */
1250         long itemcount = count_contents(obj, FALSE, FALSE, TRUE);
1251
1252 #if 0 /*JP*/
1253         Sprintf(eos(bp), " containing %ld item%s", itemcount,
1254                 plur(itemcount));
1255 #else
1256         Sprintf(eos(bp), "(%ld\8cÂ\93ü\82Á\82Ä\82¢\82é)", itemcount);
1257 #endif
1258     }
1259
1260     switch (obj->oclass) {
1261     case AMULET_CLASS:
1262         if (obj->owornmask & W_AMUL)
1263 /*JP
1264             Strcat(bp, " (being worn)");
1265 */
1266             Strcat(bp, "(\90g\82É\82Â\82¯\82Ä\82¢\82é)");
1267         break;
1268     case WEAPON_CLASS:
1269         if (ispoisoned)
1270 /*JP
1271             Strcat(prefix, "poisoned ");
1272 */
1273             Strcat(prefix, "\93Å\82Ì\93h\82ç\82ê\82½");
1274     plus:
1275         add_erosion_words(obj, prefix);
1276         if (known) {
1277             Strcat(prefix, sitoa(obj->spe));
1278             Strcat(prefix, " ");
1279         }
1280         break;
1281     case ARMOR_CLASS:
1282         if (obj->owornmask & W_ARMOR)
1283 /*JP
1284             Strcat(bp, (obj == uskin) ? " (embedded in your skin)"
1285 */
1286             Strcat(bp, (obj == uskin) ? "(\94§\82É\96\84\82ß\82±\82Ü\82ê\82Ä\82¢\82é)"
1287 /*JP
1288                                       : " (being worn)");
1289 */
1290                                       : "(\90g\82É\82Â\82¯\82Ä\82¢\82é)");
1291         goto plus;
1292     case TOOL_CLASS:
1293         /* weptools already get this done when we go to the +n code */
1294         if (!is_weptool(obj))
1295             add_erosion_words(obj, prefix);
1296         if (obj->owornmask & (W_TOOL /* blindfold */ | W_SADDLE)) {
1297 /*JP
1298             Strcat(bp, " (being worn)");
1299 */
1300             Strcat(bp, "(\90g\82É\82Â\82¯\82Ä\82¢\82é)");
1301             break;
1302         }
1303         if (obj->otyp == LEASH && obj->leashmon != 0) {
1304 /*JP
1305             Strcat(bp, " (in use)");
1306 */
1307             Strcat(bp, "(\8c\8b\82Ñ\82Â\82¯\82Ä\82¢\82é)");
1308             break;
1309         }
1310         if (is_weptool(obj))
1311             goto plus;
1312         if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1313 #if 0 /*JP*/
1314             if (!obj->spe)
1315                 Strcpy(tmpbuf, "no");
1316             else
1317                 Sprintf(tmpbuf, "%d", obj->spe);
1318             Sprintf(eos(bp), " (%s candle%s%s)", tmpbuf, plur(obj->spe),
1319                     !obj->lamplit ? " attached" : ", lit");
1320 #else
1321             if(!obj->spe)
1322                 Sprintf(eos(bp), "(\88ê\96{\82à\8eæ\82è\82Â\82¯\82ç\82ê\82Ä\82¢\82È\82¢)");
1323             else {
1324                 if(!obj->lamplit)
1325                   Sprintf(eos(bp), "(%d\96{\8eæ\82è\82Â\82¯\82ç\82ê\82Ä\82¢\82é)", obj->spe);
1326                 else
1327                   Sprintf(eos(bp), "(%d\96{\8cõ\82Á\82Ä\82¢\82é)", obj->spe);
1328             }
1329 #endif
1330             break;
1331         } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
1332                    || obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
1333             if (Is_candle(obj)
1334                 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
1335 /*JP
1336                 Strcat(prefix, "partly used ");
1337 */
1338                 Strcat(prefix, "\8eg\82¢\82³\82µ\82Ì");
1339             if (obj->lamplit)
1340 /*JP
1341                 Strcat(bp, " (lit)");
1342 */
1343                 Strcat(bp, "(\8cõ\82Á\82Ä\82¢\82é)");
1344             break;
1345         }
1346         if (objects[obj->otyp].oc_charged)
1347             goto charges;
1348         break;
1349     case WAND_CLASS:
1350         add_erosion_words(obj, prefix);
1351     charges:
1352         if (known)
1353 /*JP
1354             Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe);
1355 */
1356             Sprintf(eos(bp), "(%d:%d)", (int) obj->recharged, obj->spe);
1357         break;
1358     case POTION_CLASS:
1359         if (obj->otyp == POT_OIL && obj->lamplit)
1360 /*JP
1361             Strcat(bp, " (lit)");
1362 */
1363             Strcat(bp, "(\8cõ\82Á\82Ä\82¢\82é)");
1364         break;
1365     case RING_CLASS:
1366         add_erosion_words(obj, prefix);
1367     ring:
1368         if (obj->owornmask & W_RINGR)
1369 /*JP
1370             Strcat(bp, " (on right ");
1371 */
1372             Strcat(bp, "(\89E");
1373         if (obj->owornmask & W_RINGL)
1374 /*JP
1375             Strcat(bp, " (on left ");
1376 */
1377             Strcat(bp, "(\8d¶");
1378         if (obj->owornmask & W_RING) {
1379             Strcat(bp, body_part(HAND));
1380             Strcat(bp, ")");
1381         }
1382         if (known && objects[obj->otyp].oc_charged) {
1383 #if 1 /*JP*/
1384             Strcat(prefix, " ");
1385 #endif
1386             Strcat(prefix, sitoa(obj->spe));
1387             Strcat(prefix, " ");
1388         }
1389         break;
1390     case FOOD_CLASS:
1391         if (obj->oeaten)
1392 /*JP
1393             Strcat(prefix, "partly eaten ");
1394 */
1395             Strcat(prefix, "\90H\82×\82©\82¯\82Ì");
1396         if (obj->otyp == CORPSE) {
1397 #if 0 /*JP*/
1398             Sprintf(prefix, "%s ",
1399                     corpse_xname(obj, prefix, CXN_ARTICLE | CXN_NOCORPSE));
1400 #else
1401             Sprintf(prefix, "%s\82Ì",
1402                     corpse_xname(obj, prefix, CXN_ARTICLE | CXN_NOCORPSE));
1403 #endif
1404         } else if (obj->otyp == EGG) {
1405 #if 0 /* corpses don't tell if they're stale either */
1406             if (known && stale_egg(obj))
1407                 Strcat(prefix, "stale ");
1408 #endif
1409             if (omndx >= LOW_PM
1410                 && (known || (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
1411 #if 0 /*JP*/
1412                 Strcat(prefix, mons[omndx].mname);
1413                 Strcat(prefix, " ");
1414 #else
1415                 Strcat(prefix, mons[omndx].mname);
1416                 Strcat(prefix, "\82Ì");
1417 #endif
1418                 if (obj->spe)
1419 /*JP
1420                     Strcat(bp, " (laid by you)");
1421 */
1422                     Strcat(bp, "(\82 \82È\82½\82ª\8eY\82ñ\82¾)");
1423             }
1424         }
1425         if (obj->otyp == MEAT_RING)
1426             goto ring;
1427         break;
1428     case BALL_CLASS:
1429     case CHAIN_CLASS:
1430         add_erosion_words(obj, prefix);
1431         if (obj->owornmask & W_BALL)
1432 /*JP
1433             Strcat(bp, " (chained to you)");
1434 */
1435             Strcat(bp, "(\82 \82È\82½\82É\8cq\82ª\82ê\82Ä\82¢\82é)");
1436         break;
1437     }
1438
1439     if ((obj->owornmask & W_WEP) && !mrg_to_wielded) {
1440         if (obj->quan != 1L) {
1441 /*JP
1442             Strcat(bp, " (wielded)");
1443 */
1444             Strcat(bp, "(\91\95\94õ\82µ\82Ä\82¢\82é)");
1445         } else {
1446             const char *hand_s = body_part(HAND);
1447
1448             if (bimanual(obj))
1449                 hand_s = makeplural(hand_s);
1450 /*JP
1451             Sprintf(eos(bp), " (weapon in %s)", hand_s);
1452 */
1453             Sprintf(eos(bp), "(%s\82É\82µ\82Ä\82¢\82é)", hand_s);
1454
1455             if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
1456                 /* presumably can be felt when blind */
1457 #if 0 /*JP*/
1458                 Strcat(bp, " (glowing");
1459                 if (!Blind)
1460                     Sprintf(eos(bp), " %s", glow_color(obj->oartifact));
1461                 Strcat(bp, ")");
1462 #else
1463                 if (Blind)
1464                     Strcat(bp, " (\94M\82ð\8e\9d\82Á\82Ä\82¢\82é)");
1465                 else
1466                     Sprintf(eos(bp), " (%s\8bP\82¢\82Ä\82¢\82é)",
1467                             glow_color(obj->oartifact));
1468 #endif
1469             }
1470         }
1471     }
1472     if (obj->owornmask & W_SWAPWEP) {
1473         if (u.twoweap)
1474 /*JP
1475             Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND));
1476 */
1477             Sprintf(eos(bp), "(\8d¶%s\82É\82µ\82Ä\82¢\82é)", body_part(HAND));
1478         else
1479 /*JP
1480             Strcat(bp, " (alternate weapon; not wielded)");
1481 */
1482             Strcat(bp, "(\97\\94õ\82Ì\95\90\8aí;\91\95\94õ\82µ\82Ä\82¢\82È\82¢)");
1483     }
1484     if (obj->owornmask & W_QUIVER) {
1485         switch (obj->oclass) {
1486         case WEAPON_CLASS:
1487             if (is_ammo(obj)) {
1488                 if (objects[obj->otyp].oc_skill == -P_BOW) {
1489                     /* Ammo for a bow */
1490 /*JP
1491                     Strcat(bp, " (in quiver)");
1492 */
1493                     Strcat(bp, "(\96î\93\9b\82É\93ü\82Á\82Ä\82¢\82é)");
1494                     break;
1495                 } else {
1496                     /* Ammo not for a bow */
1497 /*JP
1498                     Strcat(bp, " (in quiver pouch)");
1499 */
1500                     Strcat(bp, "(\92e\93ü\82ê\82É\93ü\82Á\82Ä\82¢\82é)");
1501                     break;
1502                 }
1503             } else {
1504                 /* Weapons not considered ammo */
1505 /*JP
1506                 Strcat(bp, " (at the ready)");
1507 */
1508                 Strcat(bp, "(\8f\80\94õ\82µ\82Ä\82¢\82é)");
1509                 break;
1510             }
1511         /* Small things and ammo not for a bow */
1512         case RING_CLASS:
1513         case AMULET_CLASS:
1514         case WAND_CLASS:
1515         case COIN_CLASS:
1516         case GEM_CLASS:
1517 /*JP
1518             Strcat(bp, " (in quiver pouch)");
1519 */
1520             Strcat(bp, "(\92e\93ü\82ê\82É\93ü\82Á\82Ä\82¢\82é)");
1521             break;
1522         default: /* odd things */
1523 /*JP
1524             Strcat(bp, " (at the ready)");
1525 */
1526             Strcat(bp, "(\8f\80\94õ\82µ\82Ä\82¢\82é)");
1527         }
1528     }
1529     if (!iflags.suppress_price && is_unpaid(obj)) {
1530         long quotedprice = unpaid_cost(obj, TRUE);
1531
1532         Sprintf(eos(bp), " (%s, %ld %s)",
1533                 obj->unpaid ? "unpaid" : "contents",
1534                 quotedprice, currency(quotedprice));
1535     } else if (with_price) {
1536         long price = get_cost_of_shop_item(obj);
1537
1538         if (price > 0)
1539             Sprintf(eos(bp), " (%ld %s)", price, currency(price));
1540     }
1541 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\95s\97v*/
1542     if (!strncmp(prefix, "a ", 2)
1543         && index(vowels, *(prefix + 2) ? *(prefix + 2) : *bp)
1544         && (*(prefix + 2)
1545             || (strncmp(bp, "uranium", 7) && strncmp(bp, "unicorn", 7)
1546                 && strncmp(bp, "eucalyptus", 10)))) {
1547         Strcpy(tmpbuf, prefix);
1548         Strcpy(prefix, "an ");
1549         Strcpy(prefix + 3, tmpbuf + 2);
1550     }
1551 #endif
1552
1553     /* show weight for items (debug tourist info)
1554      * aum is stolen from Crawl's "Arbitrary Unit of Measure" */
1555     if (wizard) {
1556         Sprintf(eos(bp), " (%d aum)", obj->owt);
1557     }
1558 #if 0 /*JP*/
1559     bp = strprepend(bp, prefix);
1560 #else /*JP:\81u\96¼\95t\82¯\82ç\82ê\82½\81v\82ð\96ß\82·*/
1561     Strcat(preprefix, prefix);
1562     bp = strprepend(bp, preprefix);
1563 #endif
1564     return bp;
1565 }
1566
1567 char *
1568 doname(obj)
1569 register struct obj *obj;
1570 {
1571     return doname_base(obj, FALSE);
1572 }
1573
1574 /* Name of object including price. */
1575 char *
1576 doname_with_price(obj)
1577 register struct obj *obj;
1578 {
1579     return doname_base(obj, TRUE);
1580 }
1581
1582 /* used from invent.c */
1583 boolean
1584 not_fully_identified(otmp)
1585 register struct obj *otmp;
1586 {
1587     /* gold doesn't have any interesting attributes [yet?] */
1588     if (otmp->oclass == COIN_CLASS)
1589         return FALSE; /* always fully ID'd */
1590     /* check fundamental ID hallmarks first */
1591     if (!otmp->known || !otmp->dknown
1592 #ifdef MAIL
1593         || (!otmp->bknown && otmp->otyp != SCR_MAIL)
1594 #else
1595         || !otmp->bknown
1596 #endif
1597         || !objects[otmp->otyp].oc_name_known)
1598         return TRUE;
1599     if ((!otmp->cknown && (Is_container(otmp) || otmp->otyp == STATUE))
1600         || (!otmp->lknown && Is_box(otmp)))
1601         return TRUE;
1602     if (otmp->oartifact && undiscovered_artifact(otmp->oartifact))
1603         return TRUE;
1604     /* otmp->rknown is the only item of interest if we reach here */
1605     /*
1606      *  Note:  if a revision ever allows scrolls to become fireproof or
1607      *  rings to become shockproof, this checking will need to be revised.
1608      *  `rknown' ID only matters if xname() will provide the info about it.
1609      */
1610     if (otmp->rknown
1611         || (otmp->oclass != ARMOR_CLASS && otmp->oclass != WEAPON_CLASS
1612             && !is_weptool(otmp)            /* (redundant) */
1613             && otmp->oclass != BALL_CLASS)) /* (useless) */
1614         return FALSE;
1615     else /* lack of `rknown' only matters for vulnerable objects */
1616         return (boolean) (is_rustprone(otmp) || is_corrodeable(otmp)
1617                           || is_flammable(otmp));
1618 }
1619
1620 char *
1621 corpse_xname(otmp, adjective, cxn_flags)
1622 struct obj *otmp;
1623 const char *adjective;
1624 unsigned cxn_flags; /* bitmask of CXN_xxx values */
1625 {
1626     char *nambuf = nextobuf();
1627     int omndx = otmp->corpsenm;
1628     boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
1629             /* suppress "the" from "the unique monster corpse" */
1630         no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
1631             /* include "the" for "the woodchuck corpse */
1632         the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
1633             /* include "an" for "an ogre corpse */
1634         any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
1635             /* leave off suffix (do_name() appends "corpse" itself) */
1636         omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, possessive = FALSE;
1637     const char *mname;
1638
1639     if (omndx == NON_PM) { /* paranoia */
1640 /*JP
1641         mname = "thing";
1642 */
1643         mname = "\89½\82©";
1644         /* [Possible enhancement:  check whether corpse has monster traits
1645             attached in order to use priestname() for priests and minions.] */
1646     } else if (omndx == PM_ALIGNED_PRIEST) {
1647         /* avoid "aligned priest"; it just exposes internal details */
1648 /*JP
1649         mname = "priest";
1650 */
1651         mname = "\91m\97µ";
1652     } else {
1653         mname = mons[omndx].mname;
1654         if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
1655             mname = s_suffix(mname);
1656             possessive = TRUE;
1657             /* don't precede personal name like "Medusa" with an article */
1658             if (type_is_pname(&mons[omndx]))
1659                 no_prefix = TRUE;
1660             /* always precede non-personal unique monster name like
1661                "Oracle" with "the" unless explicitly overridden */
1662             else if (the_unique_pm(&mons[omndx]) && !no_prefix)
1663                 the_prefix = TRUE;
1664         }
1665     }
1666     if (no_prefix)
1667         the_prefix = any_prefix = FALSE;
1668     else if (the_prefix)
1669         any_prefix = FALSE; /* mutually exclusive */
1670
1671     *nambuf = '\0';
1672     /* can't use the() the way we use an() below because any capitalized
1673        Name causes it to assume a personal name and return Name as-is;
1674        that's usually the behavior wanted, but here we need to force "the"
1675        to precede capitalized unique monsters (pnames are handled above) */
1676 #if 0 /*JP*//*\93ú\96{\8cê\82É\92è\8a¥\8e\8c\82Í\95s\97v*/
1677     if (the_prefix)
1678         Strcat(nambuf, "the ");
1679 #endif
1680
1681     if (!adjective || !*adjective) {
1682         /* normal case:  newt corpse */
1683         Strcat(nambuf, mname);
1684     } else {
1685         /* adjective positioning depends upon format of monster name */
1686         if (possessive) /* Medusa's cursed partly eaten corpse */
1687 /*JP
1688             Sprintf(eos(nambuf), "%s %s", mname, adjective);
1689 */
1690             Sprintf(eos(nambuf), "%s%s", mname, adjective);
1691         else /* cursed partly eaten troll corpse */
1692 /*JP
1693             Sprintf(eos(nambuf), "%s %s", adjective, mname);
1694 */
1695             Sprintf(eos(nambuf), "%s%s", adjective, mname);
1696         /* in case adjective has a trailing space, squeeze it out */
1697         mungspaces(nambuf);
1698         /* doname() might include a count in the adjective argument;
1699            if so, don't prepend an article */
1700         if (digit(*adjective))
1701             any_prefix = FALSE;
1702     }
1703
1704     if (!omit_corpse) {
1705 #if 0 /*JP*/
1706         Strcat(nambuf, " corpse");
1707         /* makeplural(nambuf) => append "s" to "corpse" */
1708         if (otmp->quan > 1L && !ignore_quan) {
1709             Strcat(nambuf, "s");
1710             any_prefix = FALSE; /* avoid "a newt corpses" */
1711         }
1712 #else
1713         Strcat(nambuf, "\82Ì\8e\80\91Ì");
1714 #endif
1715     }
1716
1717     /* it's safe to overwrite our nambuf after an() has copied
1718        its old value into another buffer */
1719     if (any_prefix)
1720         Strcpy(nambuf, an(nambuf));
1721
1722     return nambuf;
1723 }
1724
1725 /* xname doesn't include monster type for "corpse"; cxname does */
1726 char *
1727 cxname(obj)
1728 struct obj *obj;
1729 {
1730     if (obj->otyp == CORPSE)
1731         return corpse_xname(obj, (const char *) 0, CXN_NORMAL);
1732     return xname(obj);
1733 }
1734
1735 /* like cxname, but ignores quantity */
1736 char *
1737 cxname_singular(obj)
1738 struct obj *obj;
1739 {
1740     if (obj->otyp == CORPSE)
1741         return corpse_xname(obj, (const char *) 0, CXN_SINGULAR);
1742     return xname_flags(obj, CXN_SINGULAR);
1743 }
1744
1745 /* treat an object as fully ID'd when it might be used as reason for death */
1746 char *
1747 killer_xname(obj)
1748 struct obj *obj;
1749 {
1750     struct obj save_obj;
1751     unsigned save_ocknown;
1752     char *buf, *save_ocuname, *save_oname = (char *) 0;
1753
1754     /* bypass object twiddling for artifacts */
1755     if (obj->oartifact)
1756         return bare_artifactname(obj);
1757
1758     /* remember original settings for core of the object;
1759        oextra structs other than oname don't matter here--since they
1760        aren't modified they don't need to be saved and restored */
1761     save_obj = *obj;
1762     if (has_oname(obj))
1763         save_oname = ONAME(obj);
1764
1765     /* killer name should be more specific than general xname; however, exact
1766        info like blessed/cursed and rustproof makes things be too verbose */
1767     obj->known = obj->dknown = 1;
1768     obj->bknown = obj->rknown = obj->greased = 0;
1769     /* if character is a priest[ess], bknown will get toggled back on */
1770     if (obj->otyp != POT_WATER)
1771         obj->blessed = obj->cursed = 0;
1772     else
1773         obj->bknown = 1; /* describe holy/unholy water as such */
1774     /* "killed by poisoned <obj>" would be misleading when poison is
1775        not the cause of death and "poisoned by poisoned <obj>" would
1776        be redundant when it is, so suppress "poisoned" prefix */
1777     obj->opoisoned = 0;
1778     /* strip user-supplied name; artifacts keep theirs */
1779     if (!obj->oartifact && save_oname)
1780         ONAME(obj) = (char *) 0;
1781     /* temporarily identify the type of object */
1782     save_ocknown = objects[obj->otyp].oc_name_known;
1783     objects[obj->otyp].oc_name_known = 1;
1784     save_ocuname = objects[obj->otyp].oc_uname;
1785     objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
1786
1787     /* format the object */
1788     if (obj->otyp == CORPSE) {
1789         buf = nextobuf();
1790         Strcpy(buf, corpse_xname(obj, (const char *) 0, CXN_NORMAL));
1791     } else if (obj->otyp == SLIME_MOLD) {
1792         /* concession to "most unique deaths competition" in the annual
1793            devnull tournament, suppress player supplied fruit names because
1794            those can be used to fake other objects and dungeon features */
1795         buf = nextobuf();
1796 /*JP
1797         Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
1798 */
1799         Strcpy(buf, "\8aë\8c¯\82È\82Ë\82Î\82Ë\82Î\83J\83r");
1800     } else {
1801         buf = xname(obj);
1802     }
1803     /* apply an article if appropriate; caller should always use KILLED_BY */
1804 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\95s\97v*/
1805     if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
1806         buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
1807 #endif
1808
1809     objects[obj->otyp].oc_name_known = save_ocknown;
1810     objects[obj->otyp].oc_uname = save_ocuname;
1811     *obj = save_obj; /* restore object's core settings */
1812     if (!obj->oartifact && save_oname)
1813         ONAME(obj) = save_oname;
1814
1815     return buf;
1816 }
1817
1818 /* xname,doname,&c with long results reformatted to omit some stuff */
1819 char *
1820 short_oname(obj, func, altfunc, lenlimit)
1821 struct obj *obj;
1822 char *FDECL((*func), (OBJ_P)),    /* main formatting routine */
1823      *FDECL((*altfunc), (OBJ_P)); /* alternate for shortest result */
1824 unsigned lenlimit;
1825 {
1826     struct obj save_obj;
1827     char unamebuf[12], onamebuf[12], *save_oname, *save_uname, *outbuf;
1828
1829     outbuf = (*func)(obj);
1830     if ((unsigned) strlen(outbuf) <= lenlimit)
1831         return outbuf;
1832
1833     /* shorten called string to fairly small amount */
1834     save_uname = objects[obj->otyp].oc_uname;
1835     if (save_uname && strlen(save_uname) >= sizeof unamebuf) {
1836         (void) strncpy(unamebuf, save_uname, sizeof unamebuf - 4);
1837         Strcpy(unamebuf + sizeof unamebuf - 4, "...");
1838         objects[obj->otyp].oc_uname = unamebuf;
1839         releaseobuf(outbuf);
1840         outbuf = (*func)(obj);
1841         objects[obj->otyp].oc_uname = save_uname; /* restore called string */
1842         if ((unsigned) strlen(outbuf) <= lenlimit)
1843             return outbuf;
1844     }
1845
1846     /* shorten named string to fairly small amount */
1847     save_oname = has_oname(obj) ? ONAME(obj) : 0;
1848     if (save_oname && strlen(save_oname) >= sizeof onamebuf) {
1849         (void) strncpy(onamebuf, save_oname, sizeof onamebuf - 4);
1850         Strcpy(onamebuf + sizeof onamebuf - 4, "...");
1851         ONAME(obj) = onamebuf;
1852         releaseobuf(outbuf);
1853         outbuf = (*func)(obj);
1854         ONAME(obj) = save_oname; /* restore named string */
1855         if ((unsigned) strlen(outbuf) <= lenlimit)
1856             return outbuf;
1857     }
1858
1859     /* shorten both called and named strings;
1860        unamebuf and onamebuf have both already been populated */
1861     if (save_uname && strlen(save_uname) >= sizeof unamebuf && save_oname
1862         && strlen(save_oname) >= sizeof onamebuf) {
1863         objects[obj->otyp].oc_uname = unamebuf;
1864         ONAME(obj) = onamebuf;
1865         releaseobuf(outbuf);
1866         outbuf = (*func)(obj);
1867         if ((unsigned) strlen(outbuf) <= lenlimit) {
1868             objects[obj->otyp].oc_uname = save_uname;
1869             ONAME(obj) = save_oname;
1870             return outbuf;
1871         }
1872     }
1873
1874     /* still long; strip several name-lengthening attributes;
1875        called and named strings are still in truncated form */
1876     save_obj = *obj;
1877     obj->bknown = obj->rknown = obj->greased = 0;
1878     obj->oeroded = obj->oeroded2 = 0;
1879     releaseobuf(outbuf);
1880     outbuf = (*func)(obj);
1881     if (altfunc && (unsigned) strlen(outbuf) > lenlimit) {
1882         /* still long; use the alternate function (usually one of
1883            the jackets around minimal_xname()) */
1884         releaseobuf(outbuf);
1885         outbuf = (*altfunc)(obj);
1886     }
1887     /* restore the object */
1888     *obj = save_obj;
1889     if (save_oname)
1890         ONAME(obj) = save_oname;
1891     if (save_uname)
1892         objects[obj->otyp].oc_uname = save_uname;
1893
1894     /* use whatever we've got, whether it's too long or not */
1895     return outbuf;
1896 }
1897
1898 /*
1899  * Used if only one of a collection of objects is named (e.g. in eat.c).
1900  */
1901 const char *
1902 singular(otmp, func)
1903 register struct obj *otmp;
1904 char *FDECL((*func), (OBJ_P));
1905 {
1906     long savequan;
1907     char *nam;
1908
1909     /* using xname for corpses does not give the monster type */
1910     if (otmp->otyp == CORPSE && func == xname)
1911         func = cxname;
1912
1913     savequan = otmp->quan;
1914     otmp->quan = 1L;
1915     nam = (*func)(otmp);
1916     otmp->quan = savequan;
1917     return nam;
1918 }
1919
1920 char *
1921 an(str)
1922 register const char *str;
1923 {
1924     char *buf = nextobuf();
1925
1926 #if 0 /*JP*//*\95s\92è\8a¥\8e\8c\82Í\95s\97v*/
1927     buf[0] = '\0';
1928
1929     if (strncmpi(str, "the ", 4) && strcmp(str, "molten lava")
1930         && strcmp(str, "iron bars") && strcmp(str, "ice")) {
1931         if (index(vowels, *str) && strncmp(str, "one-", 4)
1932             && strncmp(str, "useful", 6) && strncmp(str, "unicorn", 7)
1933             && strncmp(str, "uranium", 7) && strncmp(str, "eucalyptus", 10))
1934             Strcpy(buf, "an ");
1935         else
1936             Strcpy(buf, "a ");
1937     }
1938
1939     Strcat(buf, str);
1940 #else /*\92P\82É\83R\83s\81[*/
1941     Strcpy(buf, str);
1942 #endif
1943     return buf;
1944 }
1945
1946 char *
1947 An(str)
1948 const char *str;
1949 {
1950     char *tmp = an(str);
1951
1952 #if 0 /*JP*//*\91å\95\8e\9a\89»\82µ\82È\82¢*/
1953     *tmp = highc(*tmp);
1954 #endif
1955     return tmp;
1956 }
1957
1958 /*
1959  * Prepend "the" if necessary; assumes str is a subject derived from xname.
1960  * Use type_is_pname() for monster names, not the().  the() is idempotent.
1961  */
1962 char *
1963 the(str)
1964 const char *str;
1965 {
1966     char *buf = nextobuf();
1967 #if 0 /*JP*//*\92è\8a¥\8e\8c\82Í\95s\97v*/
1968     boolean insert_the = FALSE;
1969
1970     if (!strncmpi(str, "the ", 4)) {
1971         buf[0] = lowc(*str);
1972         Strcpy(&buf[1], str + 1);
1973         return buf;
1974     } else if (*str < 'A' || *str > 'Z') {
1975         /* not a proper name, needs an article */
1976         insert_the = TRUE;
1977     } else {
1978         /* Probably a proper name, might not need an article */
1979         register char *tmp, *named, *called;
1980         int l;
1981
1982         /* some objects have capitalized adjectives in their names */
1983         if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0)
1984             && (tmp[1] < 'A' || tmp[1] > 'Z')) {
1985             insert_the = TRUE;
1986         } else if (tmp && index(str, ' ') < tmp) { /* has spaces */
1987             /* it needs an article if the name contains "of" */
1988             tmp = strstri(str, " of ");
1989             named = strstri(str, " named ");
1990             called = strstri(str, " called ");
1991             if (called && (!named || called < named))
1992                 named = called;
1993
1994             if (tmp && (!named || tmp < named)) /* found an "of" */
1995                 insert_the = TRUE;
1996             /* stupid special case: lacks "of" but needs "the" */
1997             else if (!named && (l = strlen(str)) >= 31
1998                      && !strcmp(&str[l - 31],
1999                                 "Platinum Yendorian Express Card"))
2000                 insert_the = TRUE;
2001         }
2002     }
2003     if (insert_the)
2004         Strcpy(buf, "the ");
2005     else
2006         buf[0] = '\0';
2007     Strcat(buf, str);
2008
2009 #else /*\92P\82É\83R\83s\81[*/
2010     Strcpy(buf, str);
2011 #endif /*JP*/
2012     return buf;
2013 }
2014
2015 char *
2016 The(str)
2017 const char *str;
2018 {
2019     char *tmp = the(str);
2020
2021 #if 0 /*JP*//*\91å\95\8e\9a\89»\82µ\82È\82¢*/
2022     *tmp = highc(*tmp);
2023 #endif
2024     return tmp;
2025 }
2026
2027 #if 1 /*JP*/
2028 char *
2029 aobjnam(otmp, verb)
2030 register struct obj *otmp;
2031 register const char *verb;
2032 {
2033     return xname(otmp);
2034 }
2035
2036 #else
2037 /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */
2038 char *
2039 aobjnam(otmp, verb)
2040 struct obj *otmp;
2041 const char *verb;
2042 {
2043     char prefix[PREFIX];
2044     char *bp = cxname(otmp);
2045
2046     if (otmp->quan != 1L) {
2047         Sprintf(prefix, "%ld ", otmp->quan);
2048         bp = strprepend(bp, prefix);
2049     }
2050     if (verb) {
2051         Strcat(bp, " ");
2052         Strcat(bp, otense(otmp, verb));
2053     }
2054     return bp;
2055 }
2056 #endif /*JP*/
2057
2058 /* combine yname and aobjnam eg "your count cxname(otmp)" */
2059 char *
2060 yobjnam(obj, verb)
2061 struct obj *obj;
2062 const char *verb;
2063 {
2064     char *s = aobjnam(obj, verb);
2065
2066     /* leave off "your" for most of your artifacts, but prepend
2067      * "your" for unique objects and "foo of bar" quest artifacts */
2068     if (!carried(obj) || !obj_is_pname(obj)
2069         || obj->oartifact >= ART_ORB_OF_DETECTION) {
2070         char *outbuf = shk_your(nextobuf(), obj);
2071         int space_left = BUFSZ - 1 - strlen(outbuf);
2072
2073         s = strncat(outbuf, s, space_left);
2074     }
2075     return s;
2076 }
2077
2078 /* combine Yname2 and aobjnam eg "Your count cxname(otmp)" */
2079 char *
2080 Yobjnam2(obj, verb)
2081 struct obj *obj;
2082 const char *verb;
2083 {
2084     register char *s = yobjnam(obj, verb);
2085
2086 #if 0 /*JP*/
2087     *s = highc(*s);
2088 #endif
2089     return s;
2090 }
2091
2092 /* like aobjnam, but prepend "The", not count, and use xname */
2093 char *
2094 Tobjnam(otmp, verb)
2095 struct obj *otmp;
2096 const char *verb;
2097 {
2098     char *bp = The(xname(otmp));
2099
2100 #if 0 /*JP*//*\93ú\96{\8cê\82É\82Í\8eO\92P\8c»\82Ìs\82Í\82È\82¢*/
2101     if (verb) {
2102         Strcat(bp, " ");
2103         Strcat(bp, otense(otmp, verb));
2104     }
2105 #endif /*JP*/
2106     return bp;
2107 }
2108
2109 /* capitalized variant of doname() */
2110 char *
2111 Doname2(obj)
2112 struct obj *obj;
2113 {
2114     char *s = doname(obj);
2115
2116     *s = highc(*s);
2117     return s;
2118 }
2119
2120 /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */
2121 char *
2122 yname(obj)
2123 struct obj *obj;
2124 {
2125     char *s = cxname(obj);
2126
2127     /* leave off "your" for most of your artifacts, but prepend
2128      * "your" for unique objects and "foo of bar" quest artifacts */
2129     if (!carried(obj) || !obj_is_pname(obj)
2130         || obj->oartifact >= ART_ORB_OF_DETECTION) {
2131         char *outbuf = shk_your(nextobuf(), obj);
2132         int space_left = BUFSZ - 1 - strlen(outbuf);
2133
2134         s = strncat(outbuf, s, space_left);
2135     }
2136
2137     return s;
2138 }
2139
2140 /* capitalized variant of yname() */
2141 char *
2142 Yname2(obj)
2143 struct obj *obj;
2144 {
2145     char *s = yname(obj);
2146
2147 #if 0 /*JP*/
2148     *s = highc(*s);
2149 #endif
2150     return s;
2151 }
2152
2153 /* returns "your minimal_xname(obj)"
2154  * or "Foobar's minimal_xname(obj)"
2155  * or "the minimal_xname(obj)"
2156  */
2157 char *
2158 ysimple_name(obj)
2159 struct obj *obj;
2160 {
2161     char *outbuf = nextobuf();
2162     char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */
2163 #if 0 /*JP*/
2164     int space_left = BUFSZ - 1 - strlen(s);
2165
2166     return strncat(s, minimal_xname(obj), space_left);
2167 #else
2168     int space_left = BUFSZ - strlen(s);
2169
2170     return strncat(s, minimal_xname(obj), space_left);
2171 #endif
2172 }
2173
2174 /* capitalized variant of ysimple_name() */
2175 char *
2176 Ysimple_name2(obj)
2177 struct obj *obj;
2178 {
2179     char *s = ysimple_name(obj);
2180
2181 #if 0 /*JP*/
2182     *s = highc(*s);
2183 #endif
2184     return s;
2185 }
2186
2187 /* "scroll" or "scrolls" */
2188 char *
2189 simpleonames(obj)
2190 struct obj *obj;
2191 {
2192     char *simpleoname = minimal_xname(obj);
2193
2194 #if 0 /*JP*//*\93ú\96{\8cê\82Í\92P\95¡\93¯\8c^*/
2195     if (obj->quan != 1L)
2196         simpleoname = makeplural(simpleoname);
2197 #endif
2198     return simpleoname;
2199 }
2200
2201 /* "a scroll" or "scrolls"; "a silver bell" or "the Bell of Opening" */
2202 char *
2203 ansimpleoname(obj)
2204 struct obj *obj;
2205 {
2206     char *simpleoname = simpleonames(obj);
2207     int otyp = obj->otyp;
2208
2209     /* prefix with "the" if a unique item, or a fake one imitating same,
2210        has been formatted with its actual name (we let typename() handle
2211        any `known' and `dknown' checking necessary) */
2212     if (otyp == FAKE_AMULET_OF_YENDOR)
2213         otyp = AMULET_OF_YENDOR;
2214     if (objects[otyp].oc_unique
2215         && !strcmp(simpleoname, OBJ_NAME(objects[otyp])))
2216         return the(simpleoname);
2217
2218     /* simpleoname is singular if quan==1, plural otherwise */
2219     if (obj->quan == 1L)
2220         simpleoname = an(simpleoname);
2221     return simpleoname;
2222 }
2223
2224 /* "the scroll" or "the scrolls" */
2225 char *
2226 thesimpleoname(obj)
2227 struct obj *obj;
2228 {
2229     char *simpleoname = simpleonames(obj);
2230
2231     return the(simpleoname);
2232 }
2233
2234 /* artifact's name without any object type or known/dknown/&c feedback */
2235 char *
2236 bare_artifactname(obj)
2237 struct obj *obj;
2238 {
2239     char *outbuf;
2240
2241     if (obj->oartifact) {
2242         outbuf = nextobuf();
2243         Strcpy(outbuf, artiname(obj->oartifact));
2244 #if 0 /*JP*/
2245         if (!strncmp(outbuf, "The ", 4))
2246             outbuf[0] = lowc(outbuf[0]);
2247 #endif
2248     } else {
2249         outbuf = xname(obj);
2250     }
2251     return outbuf;
2252 }
2253
2254 static const char *wrp[] = {
2255     "wand",   "ring",      "potion",     "scroll", "gem",
2256     "amulet", "spellbook", "spell book",
2257     /* for non-specific wishes */
2258     "weapon", "armor",     "tool",       "food",   "comestible",
2259 };
2260 static const char wrpsym[] = { WAND_CLASS,   RING_CLASS,   POTION_CLASS,
2261                                SCROLL_CLASS, GEM_CLASS,    AMULET_CLASS,
2262                                SPBOOK_CLASS, SPBOOK_CLASS, WEAPON_CLASS,
2263                                ARMOR_CLASS,  TOOL_CLASS,   FOOD_CLASS,
2264                                FOOD_CLASS };
2265
2266 /* return form of the verb (input plural) if xname(otmp) were the subject */
2267 char *
2268 otense(otmp, verb)
2269 struct obj *otmp;
2270 const char *verb;
2271 {
2272     char *buf;
2273
2274     /*
2275      * verb is given in plural (without trailing s).  Return as input
2276      * if the result of xname(otmp) would be plural.  Don't bother
2277      * recomputing xname(otmp) at this time.
2278      */
2279 #if 0 /*JP*//*\93ú\96{\8cê\82É\82Í\8eO\92P\8c»\82Ìs\82Í\82È\82¢*/
2280     if (!is_plural(otmp))
2281         return vtense((char *) 0, verb);
2282 #endif /*JP*/
2283
2284     buf = nextobuf();
2285     Strcpy(buf, verb);
2286     return buf;
2287 }
2288
2289 /* various singular words that vtense would otherwise categorize as plural;
2290    also used by makesingular() to catch some special cases */
2291 static const char *const special_subjs[] = {
2292     "erinys",  "manes", /* this one is ambiguous */
2293     "Cyclops", "Hippocrates",     "Pelias",    "aklys",
2294     "amnesia", "detect monsters", "paralysis", "shape changers",
2295     "nemesis", 0
2296     /* note: "detect monsters" and "shape changers" are normally
2297        caught via "<something>(s) of <whatever>", but they can be
2298        wished for using the shorter form, so we include them here
2299        to accommodate usage by makesingular during wishing */
2300 };
2301
2302 /* return form of the verb (input plural) for present tense 3rd person subj */
2303 char *
2304 vtense(subj, verb)
2305 register const char *subj;
2306 register const char *verb;
2307 {
2308 #if 0 /*JP*//*\93ú\96{\8cê\82É\82Í\8eO\92P\8c»\82Ìs\82Í\82È\82¢*/
2309     char *buf = nextobuf(), *bspot;
2310     int len, ltmp;
2311     const char *sp, *spot;
2312     const char *const *spec;
2313
2314     /*
2315      * verb is given in plural (without trailing s).  Return as input
2316      * if subj appears to be plural.  Add special cases as necessary.
2317      * Many hard cases can already be handled by using otense() instead.
2318      * If this gets much bigger, consider decomposing makeplural.
2319      * Note: monster names are not expected here (except before corpse).
2320      *
2321      * Special case: allow null sobj to get the singular 3rd person
2322      * present tense form so we don't duplicate this code elsewhere.
2323      */
2324     if (subj) {
2325         if (!strncmpi(subj, "a ", 2) || !strncmpi(subj, "an ", 3))
2326             goto sing;
2327         spot = (const char *) 0;
2328         for (sp = subj; (sp = index(sp, ' ')) != 0; ++sp) {
2329             if (!strncmpi(sp, " of ", 4) || !strncmpi(sp, " from ", 6)
2330                 || !strncmpi(sp, " called ", 8) || !strncmpi(sp, " named ", 7)
2331                 || !strncmpi(sp, " labeled ", 9)) {
2332                 if (sp != subj)
2333                     spot = sp - 1;
2334                 break;
2335             }
2336         }
2337         len = (int) strlen(subj);
2338         if (!spot)
2339             spot = subj + len - 1;
2340
2341         /*
2342          * plural: anything that ends in 's', but not '*us' or '*ss'.
2343          * Guess at a few other special cases that makeplural creates.
2344          */
2345         if ((lowc(*spot) == 's' && spot != subj
2346              && !index("us", lowc(*(spot - 1))))
2347             || !BSTRNCMPI(subj, spot - 3, "eeth", 4)
2348             || !BSTRNCMPI(subj, spot - 3, "feet", 4)
2349             || !BSTRNCMPI(subj, spot - 1, "ia", 2)
2350             || !BSTRNCMPI(subj, spot - 1, "ae", 2)) {
2351             /* check for special cases to avoid false matches */
2352             len = (int) (spot - subj) + 1;
2353             for (spec = special_subjs; *spec; spec++) {
2354                 ltmp = strlen(*spec);
2355                 if (len == ltmp && !strncmpi(*spec, subj, len))
2356                     goto sing;
2357                 /* also check for <prefix><space><special_subj>
2358                    to catch things like "the invisible erinys" */
2359                 if (len > ltmp && *(spot - ltmp) == ' '
2360                     && !strncmpi(*spec, spot - ltmp + 1, ltmp))
2361                     goto sing;
2362             }
2363
2364             return strcpy(buf, verb);
2365         }
2366         /*
2367          * 3rd person plural doesn't end in telltale 's';
2368          * 2nd person singular behaves as if plural.
2369          */
2370         if (!strcmpi(subj, "they") || !strcmpi(subj, "you"))
2371             return strcpy(buf, verb);
2372     }
2373
2374 sing:
2375     Strcpy(buf, verb);
2376     len = (int) strlen(buf);
2377     bspot = buf + len - 1;
2378
2379     if (!strcmpi(buf, "are")) {
2380         Strcasecpy(buf, "is");
2381     } else if (!strcmpi(buf, "have")) {
2382         Strcasecpy(bspot - 1, "s");
2383     } else if (index("zxs", lowc(*bspot))
2384                || (len >= 2 && lowc(*bspot) == 'h'
2385                    && index("cs", lowc(*(bspot - 1))))
2386                || (len == 2 && lowc(*bspot) == 'o')) {
2387         /* Ends in z, x, s, ch, sh; add an "es" */
2388         Strcasecpy(bspot + 1, "es");
2389     } else if (lowc(*bspot) == 'y' && !index(vowels, lowc(*(bspot - 1)))) {
2390         /* like "y" case in makeplural */
2391         Strcasecpy(bspot, "ies");
2392     } else {
2393         Strcasecpy(bspot + 1, "s");
2394     }
2395
2396 #else
2397     char *buf;
2398
2399     buf = nextobuf();
2400     Strcpy(buf, verb);
2401 #endif /*JP*/
2402     return buf;
2403 }
2404
2405 struct sing_plur {
2406     const char *sing, *plur;
2407 };
2408
2409 /* word pairs that don't fit into formula-based transformations;
2410    also some suffices which have very few--often one--matches or
2411    which aren't systematically reversible (knives, staves) */
2412 static struct sing_plur one_off[] = {
2413     { "child",
2414       "children" },      /* (for wise guys who give their food funny names) */
2415     { "cubus", "cubi" }, /* in-/suc-cubus */
2416     { "culus", "culi" }, /* homunculus */
2417     { "djinni", "djinn" },
2418     { "erinys", "erinyes" },
2419     { "foot", "feet" },
2420     { "fungus", "fungi" },
2421     { "knife", "knives" },
2422     { "labrum", "labra" }, /* candelabrum */
2423     { "louse", "lice" },
2424     { "mouse", "mice" },
2425     { "mumak", "mumakil" },
2426     { "nemesis", "nemeses" },
2427     { "rtex", "rtices" }, /* vortex */
2428     { "tooth", "teeth" },
2429     { "staff", "staves" },
2430     { 0, 0 }
2431 };
2432
2433 static const char *const as_is[] = {
2434     /* makesingular() leaves these plural due to how they're used */
2435     "boots",   "shoes",     "gloves",    "lenses",   "scales",
2436     "eyes",    "gauntlets", "iron bars",
2437     /* both singular and plural are spelled the same */
2438     "deer",    "fish",      "tuna",      "yaki",     "-hai",
2439     "krill",   "manes",     "ninja",     "sheep",    "ronin",
2440     "roshi",   "shito",     "tengu",     "ki-rin",   "Nazgul",
2441     "gunyoki", "piranha",   "samurai",   "shuriken", 0,
2442     /* Note:  "fish" and "piranha" are collective plurals, suitable
2443        for "wiped out all <foo>".  For "3 <foo>", they should be
2444        "fishes" and "piranhas" instead.  We settle for collective
2445        variant instead of attempting to support both. */
2446 };
2447
2448 /* singularize/pluralize decisions common to both makesingular & makeplural
2449  */
2450 STATIC_OVL boolean
2451 singplur_lookup(basestr, endstring, to_plural, alt_as_is)
2452 char *basestr, *endstring;    /* base string, pointer to eos(string) */
2453 boolean to_plural;            /* true => makeplural, false => makesingular */
2454 const char *const *alt_as_is; /* another set like as_is[] */
2455 {
2456     const struct sing_plur *sp;
2457     const char *same, *other, *const *as;
2458     int al;
2459
2460     for (as = as_is; *as; ++as) {
2461         al = (int) strlen(*as);
2462         if (!BSTRCMPI(basestr, endstring - al, *as))
2463             return TRUE;
2464     }
2465     if (alt_as_is) {
2466         for (as = alt_as_is; *as; ++as) {
2467             al = (int) strlen(*as);
2468             if (!BSTRCMPI(basestr, endstring - al, *as))
2469                 return TRUE;
2470         }
2471     }
2472
2473     for (sp = one_off; sp->sing; sp++) {
2474         /* check whether endstring already matches */
2475         same = to_plural ? sp->plur : sp->sing;
2476         al = (int) strlen(same);
2477         if (!BSTRCMPI(basestr, endstring - al, same))
2478             return TRUE; /* use as-is */
2479         /* check whether it matches the inverse; if so, transform it */
2480         other = to_plural ? sp->sing : sp->plur;
2481         al = (int) strlen(other);
2482         if (!BSTRCMPI(basestr, endstring - al, other)) {
2483             Strcasecpy(endstring - al, same);
2484             return TRUE; /* one_off[] transformation */
2485         }
2486     }
2487     return FALSE;
2488 }
2489
2490 /* searches for common compounds, ex. lump of royal jelly */
2491 STATIC_OVL char *
2492 singplur_compound(str)
2493 char *str;
2494 {
2495     /* if new entries are added, be sure to keep compound_start[] in sync */
2496     static const char *const compounds[] =
2497         {
2498           " of ",     " labeled ", " called ",
2499           " named ",  " above", /* lurkers above */
2500           " versus ", " from ",    " in ",
2501           " on ",     " a la ",    " with", /* " with "? */
2502           " de ",     " d'",       " du ",
2503           "-in-",     "-at-",      0
2504         }, /* list of first characters for all compounds[] entries */
2505         compound_start[] = " -";
2506
2507     const char *const *cmpd;
2508     char *p;
2509
2510     for (p = str; *p; ++p) {
2511         /* substring starting at p can only match if *p is found
2512            within compound_start[] */
2513         if (!index(compound_start, *p))
2514             continue;
2515
2516         /* check current substring against all words in the compound[] list */
2517         for (cmpd = compounds; *cmpd; ++cmpd)
2518             if (!strncmpi(p, *cmpd, (int) strlen(*cmpd)))
2519                 return p;
2520     }
2521     /* wasn't recognized as a compound phrase */
2522     return 0;
2523 }
2524
2525 /* Plural routine; chiefly used for user-defined fruits.  We have to try to
2526  * account for everything reasonable the player has; something unreasonable
2527  * can still break the code.  However, it's still a lot more accurate than
2528  * "just add an s at the end", which Rogue uses...
2529  *
2530  * Also used for plural monster names ("Wiped out all homunculi." or the
2531  * vanquished monsters list) and body parts.  A lot of unique monsters have
2532  * names which get mangled by makeplural and/or makesingular.  They're not
2533  * genocidable, and vanquished-mon handling does its own special casing
2534  * (for uniques who've been revived and re-killed), so we don't bother
2535  * trying to get those right here.
2536  *
2537  * Also misused by muse.c to convert 1st person present verbs to 2nd person.
2538  * 3.6.0: made case-insensitive.
2539  */
2540 char *
2541 makeplural(oldstr)
2542 const char *oldstr;
2543 {
2544 #if 0 /*JP*//*\93ú\96{\8cê\82Í\92P\95¡\93¯\8c^*/
2545     register char *spot;
2546     char lo_c, *str = nextobuf();
2547     const char *excess = (char *) 0;
2548     int len;
2549
2550     if (oldstr)
2551         while (*oldstr == ' ')
2552             oldstr++;
2553     if (!oldstr || !*oldstr) {
2554         impossible("plural of null?");
2555         Strcpy(str, "s");
2556         return str;
2557     }
2558     Strcpy(str, oldstr);
2559
2560     /*
2561      * Skip changing "pair of" to "pairs of".  According to Webster, usual
2562      * English usage is use pairs for humans, e.g. 3 pairs of dancers,
2563      * and pair for objects and non-humans, e.g. 3 pair of boots.  We don't
2564      * refer to pairs of humans in this game so just skip to the bottom.
2565      */
2566     if (!strncmpi(str, "pair of ", 8))
2567         goto bottom;
2568
2569     /* look for "foo of bar" so that we can focus on "foo" */
2570     if ((spot = singplur_compound(str)) != 0) {
2571         excess = oldstr + (int) (spot - str);
2572         *spot = '\0';
2573     } else
2574         spot = eos(str);
2575
2576     spot--;
2577     while (spot > str && *spot == ' ')
2578         spot--; /* Strip blanks from end */
2579     *(spot + 1) = 0;
2580     /* Now spot is the last character of the string */
2581
2582     len = strlen(str);
2583
2584     /* Single letters */
2585     if (len == 1 || !letter(*spot)) {
2586         Strcpy(spot + 1, "'s");
2587         goto bottom;
2588     }
2589
2590     /* dispense with some words which don't need pluralization */
2591     {
2592         static const char *const already_plural[] = {
2593             "ae",  /* algae, larvae, &c */
2594             "men", /* also catches women, watchmen */
2595             "matzot", 0,
2596         };
2597
2598         /* spot+1: synch up with makesingular's usage */
2599         if (singplur_lookup(str, spot + 1, TRUE, already_plural))
2600             goto bottom;
2601
2602         /* more of same, but not suitable for blanket loop checking */
2603         if ((len == 2 && !strcmpi(str, "ya"))
2604             || (len >= 3 && !strcmpi(spot - 2, " ya")))
2605             goto bottom;
2606     }
2607
2608     /* man/men ("Wiped out all cavemen.") */
2609     if (len >= 3 && !strcmpi(spot - 2, "man")
2610         /* exclude shamans and humans */
2611         && (len < 6 || strcmpi(spot - 5, "shaman"))
2612         && (len < 5 || strcmpi(spot - 4, "human"))) {
2613         Strcasecpy(spot - 1, "en");
2614         goto bottom;
2615     }
2616     if (lowc(*spot) == 'f') { /* (staff handled via one_off[]) */
2617         lo_c = lowc(*(spot - 1));
2618         if (len >= 3 && !strcmpi(spot - 2, "erf")) {
2619             /* avoid "nerf" -> "nerves", "serf" -> "serves" */
2620             ; /* fall through to default (append 's') */
2621         } else if (index("lr", lo_c) || index(vowels, lo_c)) {
2622             /* [aeioulr]f to [aeioulr]ves */
2623             Strcasecpy(spot, "ves");
2624             goto bottom;
2625         }
2626     }
2627     /* ium/ia (mycelia, baluchitheria) */
2628     if (len >= 3 && !strcmpi(spot - 2, "ium")) {
2629         Strcasecpy(spot - 2, "ia");
2630         goto bottom;
2631     }
2632     /* algae, larvae, hyphae (another fungus part) */
2633     if ((len >= 4 && !strcmpi(spot - 3, "alga"))
2634         || (len >= 5
2635             && (!strcmpi(spot - 4, "hypha") || !strcmpi(spot - 4, "larva")))
2636         || (len >= 6 && !strcmpi(spot - 5, "amoeba"))
2637         || (len >= 8 && (!strcmpi(spot - 7, "vertebra")))) {
2638         /* a to ae */
2639         Strcasecpy(spot + 1, "e");
2640         goto bottom;
2641     }
2642     /* fungus/fungi, homunculus/homunculi, but buses, lotuses, wumpuses */
2643     if (len > 3 && !strcmpi(spot - 1, "us")
2644         && !((len >= 5 && !strcmpi(spot - 4, "lotus"))
2645              || (len >= 6 && !strcmpi(spot - 5, "wumpus")))) {
2646         Strcasecpy(spot - 1, "i");
2647         goto bottom;
2648     }
2649     /* sis/ses (nemesis) */
2650     if (len >= 3 && !strcmpi(spot - 2, "sis")) {
2651         Strcasecpy(spot - 1, "es");
2652         goto bottom;
2653     }
2654     /* matzoh/matzot, possible food name */
2655     if (len >= 6
2656         && (!strcmpi(spot - 5, "matzoh") || !strcmpi(spot - 5, "matzah"))) {
2657         Strcasecpy(spot - 1, "ot"); /* oh/ah -> ot */
2658         goto bottom;
2659     }
2660     if (len >= 5
2661         && (!strcmpi(spot - 4, "matzo") || !strcmpi(spot - 4, "matza"))) {
2662         Strcasecpy(spot, "ot"); /* o/a -> ot */
2663         goto bottom;
2664     }
2665
2666     /* note: -eau/-eaux (gateau, bordeau...) */
2667     /* note: ox/oxen, VAX/VAXen, goose/geese */
2668
2669     lo_c = lowc(*spot);
2670
2671     /* Ends in z, x, s, ch, sh; add an "es" */
2672     if (index("zxs", lo_c)
2673         || (len >= 2 && lo_c == 'h' && index("cs", lowc(*(spot - 1))))
2674         /* Kludge to get "tomatoes" and "potatoes" right */
2675         || (len >= 4 && !strcmpi(spot - 2, "ato"))
2676         || (len >= 5 && !strcmpi(spot - 4, "dingo"))) {
2677         Strcasecpy(spot + 1, "es"); /* append es */
2678         goto bottom;
2679     }
2680     /* Ends in y preceded by consonant (note: also "qu") change to "ies" */
2681     if (lo_c == 'y' && !index(vowels, lowc(*(spot - 1)))) {
2682         Strcasecpy(spot, "ies"); /* y -> ies */
2683         goto bottom;
2684     }
2685     /* Default: append an 's' */
2686     Strcasecpy(spot + 1, "s");
2687
2688 bottom:
2689     if (excess)
2690         Strcat(str, excess);
2691 #else /*JP*/
2692     char *str = nextobuf();
2693     Strcpy(str, oldstr);
2694 #endif
2695     return str;
2696 }
2697
2698 /*
2699  * Singularize a string the user typed in; this helps reduce the complexity
2700  * of readobjnam, and is also used in pager.c to singularize the string
2701  * for which help is sought.
2702  *
2703  * "Manes" is ambiguous: monster type (keep s), or horse body part (drop s)?
2704  * Its inclusion in as_is[]/special_subj[] makes it get treated as the former.
2705  *
2706  * A lot of unique monsters have names ending in s; plural, or singular
2707  * from plural, doesn't make much sense for them so we don't bother trying.
2708  * 3.6.0: made case-insensitive.
2709  */
2710 char *
2711 makesingular(oldstr)
2712 const char *oldstr;
2713 {
2714 #if 0 /*JP*//*\93ú\96{\8cê\82Í\92P\95¡\93¯\8c^*/
2715     register char *p, *bp;
2716     const char *excess = 0;
2717     char *str = nextobuf();
2718
2719     if (oldstr)
2720         while (*oldstr == ' ')
2721             oldstr++;
2722     if (!oldstr || !*oldstr) {
2723         impossible("singular of null?");
2724         str[0] = '\0';
2725         return str;
2726     }
2727
2728     bp = strcpy(str, oldstr);
2729
2730     /* check for "foo of bar" so that we can focus on "foo" */
2731     if ((p = singplur_compound(bp)) != 0) {
2732         excess = oldstr + (int) (p - bp);
2733         *p = '\0';
2734     } else
2735         p = eos(bp);
2736
2737     /* dispense with some words which don't need singularization */
2738     if (singplur_lookup(bp, p, FALSE, special_subjs))
2739         goto bottom;
2740
2741     /* remove -s or -es (boxes) or -ies (rubies) */
2742     if (p >= bp + 1 && lowc(p[-1]) == 's') {
2743         if (p >= bp + 2 && lowc(p[-2]) == 'e') {
2744             if (p >= bp + 3 && lowc(p[-3]) == 'i') { /* "ies" */
2745                 if (!BSTRCMPI(bp, p - 7, "cookies")
2746                     || !BSTRCMPI(bp, p - 4, "pies")
2747                     || !BSTRCMPI(bp, p - 5, "mbies") /* zombie */
2748                     || !BSTRCMPI(bp, p - 5, "yries")) /* valkyrie */
2749                     goto mins;
2750                 Strcasecpy(p - 3, "y"); /* ies -> y */
2751                 goto bottom;
2752             }
2753             /* wolves, but f to ves isn't fully reversible */
2754             if (p - 4 >= bp && (index("lr", lowc(*(p - 4)))
2755                                 || index(vowels, lowc(*(p - 4))))
2756                 && !BSTRCMPI(bp, p - 3, "ves")) {
2757                 if (!BSTRCMPI(bp, p - 6, "cloves")
2758                     || !BSTRCMPI(bp, p - 6, "nerves"))
2759                     goto mins;
2760                 Strcasecpy(p - 3, "f"); /* ves -> f */
2761                 goto bottom;
2762             }
2763             /* note: nurses, axes but boxes, wumpuses */
2764             if (!BSTRCMPI(bp, p - 4, "eses")
2765                 || !BSTRCMPI(bp, p - 4, "oxes") /* boxes, foxes */
2766                 || !BSTRCMPI(bp, p - 4, "nxes") /* lynxes */
2767                 || !BSTRCMPI(bp, p - 4, "ches")
2768                 || !BSTRCMPI(bp, p - 4, "uses") /* lotuses */
2769                 || !BSTRCMPI(bp, p - 4, "sses") /* priestesses */
2770                 || !BSTRCMPI(bp, p - 5, "atoes") /* tomatoes */
2771                 || !BSTRCMPI(bp, p - 7, "dingoes")
2772                 || !BSTRCMPI(bp, p - 7, "Aleaxes")) {
2773                 *(p - 2) = '\0'; /* drop es */
2774                 goto bottom;
2775             } /* else fall through to mins */
2776
2777             /* ends in 's' but not 'es' */
2778         } else if (!BSTRCMPI(bp, p - 2, "us")) { /* lotus, fungus... */
2779             if (BSTRCMPI(bp, p - 6, "tengus") /* but not these... */
2780                 && BSTRCMPI(bp, p - 7, "hezrous"))
2781                 goto bottom;
2782         } else if (!BSTRCMPI(bp, p - 2, "ss")
2783                    || !BSTRCMPI(bp, p - 5, " lens")
2784                    || (p - 4 == bp && !strcmpi(p - 4, "lens"))) {
2785             goto bottom;
2786         }
2787     mins:
2788         *(p - 1) = '\0'; /* drop s */
2789
2790     } else { /* input doesn't end in 's' */
2791
2792         if (!BSTRCMPI(bp, p - 3, "men")) {
2793             Strcasecpy(p - 2, "an");
2794             goto bottom;
2795         }
2796         /* matzot -> matzo, algae -> alga */
2797         if (!BSTRCMPI(bp, p - 6, "matzot") || !BSTRCMPI(bp, p - 2, "ae")) {
2798             *(p - 1) = '\0'; /* drop t/e */
2799             goto bottom;
2800         }
2801         /* balactheria -> balactherium */
2802         if (p - 4 >= bp && !strcmpi(p - 2, "ia")
2803             && index("lr", lowc(*(p - 3))) && lowc(*(p - 4)) == 'e') {
2804             Strcasecpy(p - 1, "um"); /* a -> um */
2805         }
2806
2807         /* here we cannot find the plural suffix */
2808     }
2809
2810 bottom:
2811     /* if we stripped off a suffix (" of bar" from "foo of bar"),
2812        put it back now [strcat() isn't actually 100% safe here...] */
2813     if (excess)
2814         Strcat(bp, excess);
2815
2816     return bp;
2817 #else /*JP*/
2818     char *str = nextobuf();
2819     Strcpy(str, oldstr);
2820     return str;
2821 #endif
2822 }
2823
2824 /* compare user string against object name string using fuzzy matching */
2825 STATIC_OVL boolean
2826 wishymatch(u_str, o_str, retry_inverted)
2827 const char *u_str;      /* from user, so might be variant spelling */
2828 const char *o_str;      /* from objects[], so is in canonical form */
2829 boolean retry_inverted; /* optional extra "of" handling */
2830 {
2831     static NEARDATA const char detect_SP[] = "detect ",
2832                                SP_detection[] = " detection";
2833     char *p, buf[BUFSZ];
2834
2835     /* ignore spaces & hyphens and upper/lower case when comparing */
2836     if (fuzzymatch(u_str, o_str, " -", TRUE))
2837         return TRUE;
2838
2839     if (retry_inverted) {
2840         const char *u_of, *o_of;
2841
2842         /* when just one of the strings is in the form "foo of bar",
2843            convert it into "bar foo" and perform another comparison */
2844         u_of = strstri(u_str, " of ");
2845         o_of = strstri(o_str, " of ");
2846         if (u_of && !o_of) {
2847             Strcpy(buf, u_of + 4);
2848             p = eos(strcat(buf, " "));
2849             while (u_str < u_of)
2850                 *p++ = *u_str++;
2851             *p = '\0';
2852             return fuzzymatch(buf, o_str, " -", TRUE);
2853         } else if (o_of && !u_of) {
2854             Strcpy(buf, o_of + 4);
2855             p = eos(strcat(buf, " "));
2856             while (o_str < o_of)
2857                 *p++ = *o_str++;
2858             *p = '\0';
2859             return fuzzymatch(u_str, buf, " -", TRUE);
2860         }
2861     }
2862
2863     /* [note: if something like "elven speed boots" ever gets added, these
2864        special cases should be changed to call wishymatch() recursively in
2865        order to get the "of" inversion handling] */
2866     if (!strncmp(o_str, "dwarvish ", 9)) {
2867         if (!strncmpi(u_str, "dwarven ", 8))
2868             return fuzzymatch(u_str + 8, o_str + 9, " -", TRUE);
2869     } else if (!strncmp(o_str, "elven ", 6)) {
2870         if (!strncmpi(u_str, "elvish ", 7))
2871             return fuzzymatch(u_str + 7, o_str + 6, " -", TRUE);
2872         else if (!strncmpi(u_str, "elfin ", 6))
2873             return fuzzymatch(u_str + 6, o_str + 6, " -", TRUE);
2874     } else if (!strncmp(o_str, detect_SP, sizeof detect_SP - 1)) {
2875         /* check for "detect <foo>" vs "<foo> detection" */
2876         if ((p = strstri(u_str, SP_detection)) != 0
2877             && !*(p + sizeof SP_detection - 1)) {
2878             /* convert "<foo> detection" into "detect <foo>" */
2879             *p = '\0';
2880             Strcat(strcpy(buf, detect_SP), u_str);
2881             /* "detect monster" -> "detect monsters" */
2882             if (!strcmpi(u_str, "monster"))
2883                 Strcat(buf, "s");
2884             *p = ' ';
2885             return fuzzymatch(buf, o_str, " -", TRUE);
2886         }
2887     } else if (strstri(o_str, SP_detection)) {
2888         /* and the inverse, "<foo> detection" vs "detect <foo>" */
2889         if (!strncmpi(u_str, detect_SP, sizeof detect_SP - 1)) {
2890             /* convert "detect <foo>s" into "<foo> detection" */
2891             p = makesingular(u_str + sizeof detect_SP - 1);
2892             Strcat(strcpy(buf, p), SP_detection);
2893             /* caller may be looping through objects[], so avoid
2894                churning through all the obufs */
2895             releaseobuf(p);
2896             return fuzzymatch(buf, o_str, " -", TRUE);
2897         }
2898     } else if (strstri(o_str, "ability")) {
2899         /* when presented with "foo of bar", makesingular() used to
2900            singularize both foo & bar, but now only does so for foo */
2901         /* catch "{potion(s),ring} of {gain,restore,sustain} abilities" */
2902         if ((p = strstri(u_str, "abilities")) != 0
2903             && !*(p + sizeof "abilities" - 1)) {
2904             (void) strncpy(buf, u_str, (unsigned) (p - u_str));
2905             Strcpy(buf + (p - u_str), "ability");
2906             return fuzzymatch(buf, o_str, " -", TRUE);
2907         }
2908     } else if (!strcmp(o_str, "aluminum")) {
2909         /* this special case doesn't really fit anywhere else... */
2910         /* (note that " wand" will have been stripped off by now) */
2911         if (!strcmpi(u_str, "aluminium"))
2912             return fuzzymatch(u_str + 9, o_str + 8, " -", TRUE);
2913     }
2914
2915     return FALSE;
2916 }
2917
2918 struct o_range {
2919     const char *name, oclass;
2920     int f_o_range, l_o_range;
2921 };
2922
2923 /* wishable subranges of objects */
2924 STATIC_OVL NEARDATA const struct o_range o_ranges[] = {
2925     { "bag", TOOL_CLASS, SACK, BAG_OF_TRICKS },
2926     { "lamp", TOOL_CLASS, OIL_LAMP, MAGIC_LAMP },
2927     { "candle", TOOL_CLASS, TALLOW_CANDLE, WAX_CANDLE },
2928     { "horn", TOOL_CLASS, TOOLED_HORN, HORN_OF_PLENTY },
2929     { "shield", ARMOR_CLASS, SMALL_SHIELD, SHIELD_OF_REFLECTION },
2930     { "hat", ARMOR_CLASS, FEDORA, DUNCE_CAP },
2931     { "helm", ARMOR_CLASS, ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY },
2932     { "gloves", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
2933     { "gauntlets", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
2934     { "boots", ARMOR_CLASS, LOW_BOOTS, LEVITATION_BOOTS },
2935     { "shoes", ARMOR_CLASS, LOW_BOOTS, IRON_SHOES },
2936     { "cloak", ARMOR_CLASS, MUMMY_WRAPPING, CLOAK_OF_DISPLACEMENT },
2937     { "shirt", ARMOR_CLASS, HAWAIIAN_SHIRT, T_SHIRT },
2938     { "dragon scales", ARMOR_CLASS, GRAY_DRAGON_SCALES,
2939       YELLOW_DRAGON_SCALES },
2940     { "dragon scale mail", ARMOR_CLASS, GRAY_DRAGON_SCALE_MAIL,
2941       YELLOW_DRAGON_SCALE_MAIL },
2942     { "sword", WEAPON_CLASS, SHORT_SWORD, KATANA },
2943     { "venom", VENOM_CLASS, BLINDING_VENOM, ACID_VENOM },
2944     { "gray stone", GEM_CLASS, LUCKSTONE, FLINT },
2945     { "grey stone", GEM_CLASS, LUCKSTONE, FLINT },
2946 };
2947
2948
2949 #if 0 /*JP*//*not used*/
2950 /* alternate spellings; if the difference is only the presence or
2951    absence of spaces and/or hyphens (such as "pickaxe" vs "pick axe"
2952    vs "pick-axe") then there is no need for inclusion in this list;
2953    likewise for ``"of" inversions'' ("boots of speed" vs "speed boots") */
2954 struct alt_spellings {
2955     const char *sp;
2956     int ob;
2957 } spellings[] = {
2958     { "pickax", PICK_AXE },
2959     { "whip", BULLWHIP },
2960     { "saber", SILVER_SABER },
2961     { "silver sabre", SILVER_SABER },
2962     { "smooth shield", SHIELD_OF_REFLECTION },
2963     { "grey dragon scale mail", GRAY_DRAGON_SCALE_MAIL },
2964     { "grey dragon scales", GRAY_DRAGON_SCALES },
2965     { "iron ball", HEAVY_IRON_BALL },
2966     { "lantern", BRASS_LANTERN },
2967     { "mattock", DWARVISH_MATTOCK },
2968     { "amulet of poison resistance", AMULET_VERSUS_POISON },
2969     { "potion of sleep", POT_SLEEPING },
2970     { "stone", ROCK },
2971     { "camera", EXPENSIVE_CAMERA },
2972     { "tee shirt", T_SHIRT },
2973     { "can", TIN },
2974     { "can opener", TIN_OPENER },
2975     { "kelp", KELP_FROND },
2976     { "eucalyptus", EUCALYPTUS_LEAF },
2977     { "royal jelly", LUMP_OF_ROYAL_JELLY },
2978     { "lembas", LEMBAS_WAFER },
2979     { "marker", MAGIC_MARKER },
2980     { "hook", GRAPPLING_HOOK },
2981     { "grappling iron", GRAPPLING_HOOK },
2982     { "grapnel", GRAPPLING_HOOK },
2983     { "grapple", GRAPPLING_HOOK },
2984     /* normally we wouldn't have to worry about unnecessary <space>, but
2985        " stone" will get stripped off, preventing a wishymatch; that actually
2986        lets "flint stone" be a match, so we also accept bogus "flintstone" */
2987     { "luck stone", LUCKSTONE },
2988     { "load stone", LOADSTONE },
2989     { "touch stone", TOUCHSTONE },
2990     { "flintstone", FLINT },
2991     { (const char *) 0, 0 },
2992 };
2993 #endif
2994
2995 short
2996 rnd_otyp_by_wpnskill(skill)
2997 schar skill;
2998 {
2999     int i, n = 0;
3000     short otyp = STRANGE_OBJECT;
3001     for (i = bases[WEAPON_CLASS];
3002          i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3003         if (objects[i].oc_skill == skill) {
3004             n++;
3005             otyp = i;
3006         }
3007     if (n > 0) {
3008         n = rn2(n);
3009         for (i = bases[WEAPON_CLASS];
3010              i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3011             if (objects[i].oc_skill == skill)
3012                 if (--n < 0)
3013                     return i;
3014     }
3015     return otyp;
3016 }
3017
3018 /*
3019  * Return something wished for.  Specifying a null pointer for
3020  * the user request string results in a random object.  Otherwise,
3021  * if asking explicitly for "nothing" (or "nil") return no_wish;
3022  * if not an object return &zeroobj; if an error (no matching object),
3023  * return null.
3024  */
3025
3026 struct obj *
3027 readobjnam(bp, no_wish)
3028 register char *bp;
3029 struct obj *no_wish;
3030 {
3031     register char *p;
3032     register int i;
3033     register struct obj *otmp;
3034     int cnt, spe, spesgn, typ, very, rechrg;
3035     int blessed, uncursed, iscursed, ispoisoned, isgreased;
3036     int eroded, eroded2, erodeproof;
3037     int halfeaten, mntmp, contents;
3038     int islit, unlabeled, ishistoric, isdiluted, trapped;
3039 #if 0 /*JP*/
3040     int tmp, tinv, tvariety;
3041 #else
3042     int tvariety;
3043 #endif
3044     int wetness;
3045     struct fruit *f;
3046     int ftype = context.current_fruit;
3047     char fruitbuf[BUFSZ];
3048     /* Fruits may not mess up the ability to wish for real objects (since
3049      * you can leave a fruit in a bones file and it will be added to
3050      * another person's game), so they must be checked for last, after
3051      * stripping all the possible prefixes and seeing if there's a real
3052      * name in there.  So we have to save the full original name.  However,
3053      * it's still possible to do things like "uncursed burnt Alaska",
3054      * or worse yet, "2 burned 5 course meals", so we need to loop to
3055      * strip off the prefixes again, this time stripping only the ones
3056      * possible on food.
3057      * We could get even more detailed so as to allow food names with
3058      * prefixes that _are_ possible on food, so you could wish for
3059      * "2 3 alarm chilis".  Currently this isn't allowed; options.c
3060      * automatically sticks 'candied' in front of such names.
3061      */
3062     char oclass;
3063     char *un, *dn, *actualn;
3064     const char *name = 0;
3065
3066     cnt = spe = spesgn = typ = very = rechrg = blessed = uncursed = iscursed =
3067         ispoisoned = isgreased = eroded = eroded2 = erodeproof = halfeaten =
3068             islit = unlabeled = ishistoric = isdiluted = trapped = 0;
3069     tvariety = RANDOM_TIN;
3070     mntmp = NON_PM;
3071 #define UNDEFINED 0
3072 #define EMPTY 1
3073 #define SPINACH 2
3074     contents = UNDEFINED;
3075     oclass = 0;
3076     actualn = dn = un = 0;
3077     wetness = 0;
3078
3079     if (!bp)
3080         goto any;
3081     /* first, remove extra whitespace they may have typed */
3082     (void) mungspaces(bp);
3083     /* allow wishing for "nothing" to preserve wishless conduct...
3084        [now requires "wand of nothing" if that's what was really wanted] */
3085 #if 0 /*JP*/
3086     if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil")
3087         || !strcmpi(bp, "none"))
3088 #else
3089     if (!strcmpi(bp, "\82È\82µ") || !strcmpi(bp, "\96³\82µ"))
3090 #endif
3091         return no_wish;
3092     /* save the [nearly] unmodified choice string */
3093     Strcpy(fruitbuf, bp);
3094
3095     for (;;) {
3096         register int l;
3097
3098         if (!bp || !*bp)
3099             goto any;
3100         if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) {
3101             cnt = 1;
3102         } else if (!strncmpi(bp, "the ", l = 4)) {
3103             ; /* just increment `bp' by `l' below */
3104         } else if (!cnt && digit(*bp) && strcmp(bp, "0")) {
3105             cnt = atoi(bp);
3106             while (digit(*bp))
3107                 bp++;
3108             while (*bp == ' ')
3109                 bp++;
3110             l = 0;
3111         } else if (*bp == '+' || *bp == '-') {
3112             spesgn = (*bp++ == '+') ? 1 : -1;
3113             spe = atoi(bp);
3114             while (digit(*bp))
3115                 bp++;
3116             while (*bp == ' ')
3117                 bp++;
3118             l = 0;
3119 #if 0 /*JP*/
3120         } else if (!strncmpi(bp, "blessed ", l = 8)
3121                    || !strncmpi(bp, "holy ", l = 5)) {
3122 #else
3123         } else if (!strncmpi(bp, "\8fj\95\9f\82³\82ê\82½", l = 10)) {
3124 #endif
3125             blessed = 1;
3126 #if 0 /*JP*/
3127         } else if (!strncmpi(bp, "moist ", l = 6)
3128                    || !strncmpi(bp, "wet ", l = 4)) {
3129 #else
3130         } else if (!strncmpi(bp, "\8e¼\82Á\82½", l = 6)
3131                    || !strncmpi(bp, "\94G\82ê\82½", l = 6)) {
3132 #endif
3133 #if 0 /*JP*/
3134             if (!strncmpi(bp, "wet ", 4))
3135 #else
3136             if (!strncmpi(bp, "\94G\82ê\82½", 4))
3137 #endif
3138                 wetness = rn2(3) + 3;
3139             else
3140                 wetness = rnd(2);
3141 #if 0 /*JP*/
3142         } else if (!strncmpi(bp, "cursed ", l = 7)
3143                    || !strncmpi(bp, "unholy ", l = 7)) {
3144 #else
3145         } else if (!strncmpi(bp, "\8eô\82í\82ê\82½", l = 8)) {
3146 #endif
3147             iscursed = 1;
3148 #if 0 /*JP*/
3149         } else if (!strncmpi(bp, "uncursed ", l = 9)) {
3150 #else
3151         } else if (!strncmpi(bp, "\8eô\82í\82ê\82Ä\82¢\82È\82¢", l = 9)) {
3152 #endif
3153             uncursed = 1;
3154 #if 0 /*JP*/
3155         } else if (!strncmpi(bp, "rustproof ", l = 10)
3156                    || !strncmpi(bp, "erodeproof ", l = 11)
3157                    || !strncmpi(bp, "corrodeproof ", l = 13)
3158                    || !strncmpi(bp, "fixed ", l = 6)
3159                    || !strncmpi(bp, "fireproof ", l = 10)
3160                    || !strncmpi(bp, "rotproof ", l = 9)) {
3161 #else
3162         } else if (!strncmpi(bp, "\8eK\82Ñ\82È\82¢", l = 8)
3163                    || !strncmpi(bp, "\95\85\90H\82µ\82È\82¢", l = 10)
3164                    || !strncmpi(bp, "\88À\92è\82µ\82½", l = 8)
3165                    || !strncmpi(bp, "\94R\82¦\82È\82¢", l = 8)) {
3166 #endif
3167             erodeproof = 1;
3168         } else if (!strncmpi(bp, "lit ", l = 4)
3169                    || !strncmpi(bp, "burning ", l = 8)) {
3170             islit = 1;
3171         } else if (!strncmpi(bp, "unlit ", l = 6)
3172                    || !strncmpi(bp, "extinguished ", l = 13)) {
3173             islit = 0;
3174             /* "unlabeled" and "blank" are synonymous */
3175         } else if (!strncmpi(bp, "unlabeled ", l = 10)
3176                    || !strncmpi(bp, "unlabelled ", l = 11)
3177                    || !strncmpi(bp, "blank ", l = 6)) {
3178             unlabeled = 1;
3179         } else if (!strncmpi(bp, "poisoned ", l = 9)) {
3180             ispoisoned = 1;
3181             /* "trapped" recognized but not honored outside wizard mode */
3182         } else if (!strncmpi(bp, "trapped ", l = 8)) {
3183             trapped = 0; /* undo any previous "untrapped" */
3184             if (wizard)
3185                 trapped = 1;
3186         } else if (!strncmpi(bp, "untrapped ", l = 10)) {
3187             trapped = 2; /* not trapped */
3188         } else if (!strncmpi(bp, "greased ", l = 8)) {
3189             isgreased = 1;
3190         } else if (!strncmpi(bp, "very ", l = 5)) {
3191             /* very rusted very heavy iron ball */
3192             very = 1;
3193         } else if (!strncmpi(bp, "thoroughly ", l = 11)) {
3194             very = 2;
3195         } else if (!strncmpi(bp, "rusty ", l = 6)
3196                    || !strncmpi(bp, "rusted ", l = 7)
3197                    || !strncmpi(bp, "burnt ", l = 6)
3198                    || !strncmpi(bp, "burned ", l = 7)) {
3199             eroded = 1 + very;
3200             very = 0;
3201         } else if (!strncmpi(bp, "corroded ", l = 9)
3202                    || !strncmpi(bp, "rotted ", l = 7)) {
3203             eroded2 = 1 + very;
3204             very = 0;
3205         } else if (!strncmpi(bp, "partly eaten ", l = 13)
3206                    || !strncmpi(bp, "partially eaten ", l = 16)) {
3207             halfeaten = 1;
3208         } else if (!strncmpi(bp, "historic ", l = 9)) {
3209             ishistoric = 1;
3210         } else if (!strncmpi(bp, "diluted ", l = 8)) {
3211             isdiluted = 1;
3212         } else if (!strncmpi(bp, "empty ", l = 6)) {
3213             contents = EMPTY;
3214         } else
3215             break;
3216         bp += l;
3217     }
3218     if (!cnt)
3219         cnt = 1; /* %% what with "gems" etc. ? */
3220     if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) {
3221         boolean keeptrailingchars = TRUE;
3222
3223         p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */
3224         ++p; /* advance past '(' */
3225         if (!strncmpi(p, "lit)", 4)) {
3226             islit = 1;
3227             p += 4 - 1; /* point at ')' */
3228         } else {
3229             spe = atoi(p);
3230             while (digit(*p))
3231                 p++;
3232             if (*p == ':') {
3233                 p++;
3234                 rechrg = spe;
3235                 spe = atoi(p);
3236                 while (digit(*p))
3237                     p++;
3238             }
3239             if (*p != ')') {
3240                 spe = rechrg = 0;
3241                 /* mis-matched parentheses; rest of string will be ignored
3242                  * [probably we should restore everything back to '('
3243                  * instead since it might be part of "named ..."]
3244                  */
3245                 keeptrailingchars = FALSE;
3246             } else {
3247                 spesgn = 1;
3248             }
3249         }
3250         if (keeptrailingchars) {
3251             char *pp = eos(bp);
3252
3253             /* 'pp' points at 'pb's terminating '\0',
3254                'p' points at ')' and will be incremented past it */
3255             do {
3256                 *pp++ = *++p;
3257             } while (*p);
3258         }
3259     }
3260     /*
3261      * otmp->spe is type schar, so we don't want spe to be any bigger or
3262      * smaller.  Also, spe should always be positive --some cheaters may
3263      * try to confuse atoi().
3264      */
3265     if (spe < 0) {
3266         spesgn = -1; /* cheaters get what they deserve */
3267         spe = abs(spe);
3268     }
3269     if (spe > SCHAR_LIM)
3270         spe = SCHAR_LIM;
3271     if (rechrg < 0 || rechrg > 7)
3272         rechrg = 7; /* recharge_limit */
3273
3274     /* now we have the actual name, as delivered by xname, say
3275      *  green potions called whisky
3276      *  scrolls labeled "QWERTY"
3277      *  egg
3278      *  fortune cookies
3279      *  very heavy iron ball named hoei
3280      *  wand of wishing
3281      *  elven cloak
3282      */
3283     if ((p = strstri(bp, " named ")) != 0) {
3284         *p = 0;
3285         name = p + 7;
3286     }
3287     if ((p = strstri(bp, " called ")) != 0) {
3288         *p = 0;
3289         un = p + 8;
3290         /* "helmet called telepathy" is not "helmet" (a specific type)
3291          * "shield called reflection" is not "shield" (a general type)
3292          */
3293         for (i = 0; i < SIZE(o_ranges); i++)
3294             if (!strcmpi(bp, o_ranges[i].name)) {
3295                 oclass = o_ranges[i].oclass;
3296                 goto srch;
3297             }
3298     }
3299     if ((p = strstri(bp, " labeled ")) != 0) {
3300         *p = 0;
3301         dn = p + 9;
3302     } else if ((p = strstri(bp, " labelled ")) != 0) {
3303         *p = 0;
3304         dn = p + 10;
3305     }
3306     if ((p = strstri(bp, " of spinach")) != 0) {
3307         *p = 0;
3308         contents = SPINACH;
3309     }
3310
3311 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\8f\88\97\9d\82µ\82È\82¢*/
3312     /*
3313     Skip over "pair of ", "pairs of", "set of" and "sets of".
3314
3315     Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
3316     English either way.  See makeplural() for more on pair/pairs.
3317
3318     We should only double count if the object in question is not
3319     referred to as a "pair of".  E.g. We should double if the player
3320     types "pair of spears", but not if the player types "pair of
3321     lenses".  Luckily (?) all objects that are referred to as pairs
3322     -- boots, gloves, and lenses -- are also not mergable, so cnt is
3323     ignored anyway.
3324     */
3325     if (!strncmpi(bp, "pair of ", 8)) {
3326         bp += 8;
3327         cnt *= 2;
3328     } else if (cnt > 1 && !strncmpi(bp, "pairs of ", 9)) {
3329         bp += 9;
3330         cnt *= 2;
3331     } else if (!strncmpi(bp, "set of ", 7)) {
3332         bp += 7;
3333     } else if (!strncmpi(bp, "sets of ", 8)) {
3334         bp += 8;
3335     }
3336 #endif
3337
3338 #if 0 /*JP*/
3339     /* intercept pudding globs here; they're a valid wish target,
3340      * but we need them to not get treated like a corpse.
3341      *
3342      * also don't let player wish for multiple globs.
3343      */
3344     if ((p = strstri(bp, "glob of ")) != 0
3345         || (p = strstri(bp, "globs of ")) != 0) {
3346         int globoffset = (*(p + 4) == 's') ? 9 : 8;
3347         if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE
3348             && mntmp <= PM_BLACK_PUDDING) {
3349             mntmp = NON_PM; /* lie to ourselves */
3350             cnt = 0;        /* force only one */
3351         }
3352     } else {
3353         /*
3354          * Find corpse type using "of" (figurine of an orc, tin of orc meat)
3355          * Don't check if it's a wand or spellbook.
3356          * (avoid "wand/finger of death" confusion).
3357          */
3358         if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ")
3359             && !strstri(bp, "finger ")) {
3360             if (((p = strstri(bp, "tin of ")) != 0)
3361                 && (tmp = tin_variety_txt(p + 7, &tinv))
3362                 && (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) {
3363                 *(p + 3) = 0;
3364                 tvariety = tinv;
3365             } else if ((p = strstri(bp, " of ")) != 0
3366                        && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
3367                 *p = 0;
3368         }
3369     }
3370     /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
3371     if (strncmpi(bp, "samurai sword", 13))   /* not the "samurai" monster! */
3372         if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
3373             if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
3374                 if (strncmpi(bp, "master key",
3375                              10)) /* not the "master" rank */
3376                     if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
3377                         if (mntmp < LOW_PM && strlen(bp) > 2
3378                             && (mntmp = name_to_mon(bp)) >= LOW_PM) {
3379                             int mntmptoo,
3380                                 mntmplen; /* double check for rank title */
3381                             char *obp = bp;
3382                             mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
3383                             bp += mntmp != mntmptoo
3384                                       ? (int) strlen(mons[mntmp].mname)
3385                                       : mntmplen;
3386                             if (*bp == ' ')
3387                                 bp++;
3388                             else if (!strncmpi(bp, "s ", 2))
3389                                 bp += 2;
3390                             else if (!strncmpi(bp, "es ", 3))
3391                                 bp += 3;
3392                             else if (!*bp && !actualn && !dn && !un
3393                                      && !oclass) {
3394                                 /* no referent; they don't really mean a
3395                                  * monster type */
3396                                 bp = obp;
3397                                 mntmp = NON_PM;
3398                             }
3399                         }
3400 #else /*JP:\81u(\89ö\95¨\96¼)\82Ì(\83A\83C\83e\83\80)\81v\91Î\89\9e */
3401     {
3402         if ((mntmp = name_to_mon(bp)) >= LOW_PM) {
3403             const char *mp = mons[mntmp].mname;
3404             bp = strstri(bp, mp) + strlen(mp) + 2;
3405         }
3406     }
3407 #endif
3408
3409 #if 0 /*JP*//*\92P\90\94\89»\82Í\82µ\82È\82¢*/
3410     /* first change to singular if necessary */
3411     if (*bp) {
3412         char *sng = makesingular(bp);
3413         if (strcmp(bp, sng)) {
3414             if (cnt == 1)
3415                 cnt = 2;
3416             Strcpy(bp, sng);
3417         }
3418     }
3419 #endif
3420
3421 #if 0 /*JP*//*\83X\83y\83\8b\97h\82ê\8f\88\97\9d\82Í\82µ\82È\82¢*/
3422     /* Alternate spellings (pick-ax, silver sabre, &c) */
3423     {
3424         struct alt_spellings *as = spellings;
3425
3426         while (as->sp) {
3427             if (fuzzymatch(bp, as->sp, " -", TRUE)) {
3428                 typ = as->ob;
3429                 goto typfnd;
3430             }
3431             as++;
3432         }
3433         /* can't use spellings list for this one due to shuffling */
3434         if (!strncmpi(bp, "grey spell", 10))
3435             *(bp + 2) = 'a';
3436
3437         if ((p = strstri(bp, "armour")) != 0) {
3438             /* skip past "armo", then copy remainder beyond "u" */
3439             p += 4;
3440             while ((*p = *(p + 1)) != '\0')
3441                 ++p; /* self terminating */
3442         }
3443     }
3444 #endif
3445
3446 #if 0 /*JP*/
3447     /* dragon scales - assumes order of dragons */
3448     if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON
3449         && mntmp <= PM_YELLOW_DRAGON) {
3450         typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3451         mntmp = NON_PM; /* no monster */
3452         goto typfnd;
3453     }
3454 #else
3455     /*JP: \81u\97Ø\8aZ\81v\82ð\90æ\82É\8f\88\97\9d\82µ\82Ä\82¨\82­ */
3456     if (!strcmpi(bp, "\97Ø\8aZ") && mntmp >= PM_GRAY_DRAGON
3457         && mntmp <= PM_YELLOW_DRAGON) {
3458         typ = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
3459         mntmp = NON_PM; /* no monster */
3460         goto typfnd;
3461     }
3462
3463     if (!strcmpi(bp, "\97Ø") && mntmp >= PM_GRAY_DRAGON
3464         && mntmp <= PM_YELLOW_DRAGON) {
3465         typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3466         mntmp = NON_PM; /* no monster */
3467         goto typfnd;
3468     }
3469 #endif
3470
3471     p = eos(bp);
3472 #if 0 /*JP*/
3473     if (!BSTRCMPI(bp, p - 10, "holy water")) {
3474         typ = POT_WATER;
3475         if ((p - bp) >= 12 && *(p - 12) == 'u')
3476             iscursed = 1; /* unholy water */
3477         else
3478             blessed = 1;
3479         goto typfnd;
3480     }
3481 #else /*JP:\90¹\90\85\82Æ\95s\8fò\82È\90\85\82ð\95Ê\82É\94»\92è*/
3482     if (!BSTRCMPI(bp, p - 4, "\90¹\90\85")) {
3483         typ = POT_WATER;
3484         blessed = 1;
3485         goto typfnd;
3486     }
3487     if (!BSTRCMPI(bp, p - 4, "\95s\8fò\82È\90\85")) {
3488         typ = POT_WATER;
3489         iscursed = 1;
3490         goto typfnd;
3491     }
3492 #endif
3493 #if 0 /*JP*/
3494     if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
3495 #else
3496     if (unlabeled && !BSTRCMPI(bp, p - 4, "\8aª\95¨")) {
3497 #endif
3498         typ = SCR_BLANK_PAPER;
3499         goto typfnd;
3500     }
3501 #if 0 /*JP*/
3502     if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
3503 #else
3504     if (unlabeled && !BSTRCMPI(bp, p - 6, "\96\82\96@\8f\91")) {
3505 #endif
3506         typ = SPE_BLANK_PAPER;
3507         goto typfnd;
3508     }
3509     /*
3510      * NOTE: Gold pieces are handled as objects nowadays, and therefore
3511      * this section should probably be reconsidered as well as the entire
3512      * gold/money concept.  Maybe we want to add other monetary units as
3513      * well in the future. (TH)
3514      */
3515 #if 0 /*JP*/
3516     if (!BSTRCMPI(bp, p - 10, "gold piece") || !BSTRCMPI(bp, p - 7, "zorkmid")
3517         || !strcmpi(bp, "gold") || !strcmpi(bp, "money")
3518         || !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
3519 #else
3520     if (!BSTRCMPI(bp, p - 4, "\8bà\89Ý") || !BSTRCMPI(bp, p - 8, "\83S\81[\83\8b\83h")
3521         || *bp == GOLD_SYM) {
3522 #endif
3523         if (cnt > 5000 && !wizard)
3524             cnt = 5000;
3525         else if (cnt < 1)
3526             cnt = 1;
3527         otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
3528         otmp->quan = (long) cnt;
3529         otmp->owt = weight(otmp);
3530         context.botl = 1;
3531         return otmp;
3532     }
3533
3534     /* check for single character object class code ("/" for wand, &c) */
3535     if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES
3536         && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
3537         oclass = i;
3538         goto any;
3539     }
3540
3541 #if 0 /*JP*/
3542     /*JP
3543       \89p\8cê\82È\82ç XXXXX potion \82Í\95s\8am\92è\96¼\81Apotion of XXXXX \82Í\8am\92è\96¼\82Æ\82¢\82¤
3544       \8bæ\95Ê\82ª\95t\82­\82ª\81A\93ú\96{\8cê\82Å\82Í\82Ç\82¿\82ç\82à\81uXXXXX\82Ì\96ò\81v\82È\82Ì\82Å\82±\82±\82Å\82Í\94»\95Ê\82µ\82È\82¢
3545       */
3546     /* Search for class names: XXXXX potion, scroll of XXXXX.  Avoid */
3547     /* false hits on, e.g., rings for "ring mail". */
3548     if (strncmpi(bp, "enchant ", 8) && strncmpi(bp, "destroy ", 8)
3549         && strncmpi(bp, "detect food", 11)
3550         && strncmpi(bp, "food detection", 14) && strncmpi(bp, "ring mail", 9)
3551         && strncmpi(bp, "studded leather armor", 21)
3552         && strncmpi(bp, "leather armor", 13)
3553         && strncmpi(bp, "tooled horn", 11) && strncmpi(bp, "food ration", 11)
3554         && strncmpi(bp, "meat ring", 9))
3555         for (i = 0; i < (int) (sizeof wrpsym); i++) {
3556             register int j = strlen(wrp[i]);
3557             if (!strncmpi(bp, wrp[i], j)) {
3558                 oclass = wrpsym[i];
3559                 if (oclass != AMULET_CLASS) {
3560                     bp += j;
3561                     if (!strncmpi(bp, " of ", 4))
3562                         actualn = bp + 4;
3563                     /* else if(*bp) ?? */
3564                 } else
3565                     actualn = bp;
3566                 goto srch;
3567             }
3568             if (!BSTRCMPI(bp, p - j, wrp[i])) {
3569                 oclass = wrpsym[i];
3570                 p -= j;
3571                 *p = 0;
3572                 if (p > bp && p[-1] == ' ')
3573                     p[-1] = 0;
3574                 actualn = dn = bp;
3575                 goto srch;
3576             }
3577         }
3578 #endif
3579
3580     /* Wishing in wizard mode can create traps and furniture.
3581      * Part I:  distinguish between trap and object for the two
3582      * types of traps which have corresponding objects:  bear trap
3583      * and land mine.  "beartrap" (object) and "bear trap" (trap)
3584      * have a difference in spelling which we used to exploit by
3585      * adding a special case in wishymatch(), but "land mine" is
3586      * spelled the same either way so needs different handing.
3587      * Since we need something else for land mine, we've dropped
3588      * the bear trap hack so that both are handled exactly the
3589      * same.  To get an armed trap instead of a disarmed object,
3590      * the player can prefix either the object name or the trap
3591      * name with "trapped " (which ordinarily applies to chests
3592      * and tins), or append something--anything at all except for
3593      * " object", but " trap" is suggested--to either the trap
3594      * name or the object name.
3595      */
3596     if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
3597         boolean beartrap = (lowc(*bp) == 'b');
3598         char *zp = bp + 4; /* skip "bear"/"land" */
3599
3600         if (*zp == ' ')
3601             ++zp; /* embedded space is optional */
3602         if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
3603             zp += 4;
3604             if (trapped == 2 || !strcmpi(zp, " object")) {
3605                 /* "untrapped <foo>" or "<foo> object" */
3606                 typ = beartrap ? BEARTRAP : LAND_MINE;
3607                 goto typfnd;
3608             } else if (trapped == 1 || *zp != '\0') {
3609                 /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
3610                 int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
3611
3612                 /* use canonical trap spelling, skip object matching */
3613                 Strcpy(bp, defsyms[idx].explanation);
3614                 goto wiztrap;
3615             }
3616             /* [no prefix or suffix; we're going to end up matching
3617                the object name and getting a disarmed trap object] */
3618         }
3619     }
3620
3621 retry:
3622     /* "grey stone" check must be before general "stone" */
3623     for (i = 0; i < SIZE(o_ranges); i++)
3624         if (!strcmpi(bp, o_ranges[i].name)) {
3625             typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
3626             goto typfnd;
3627         }
3628
3629     if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) {
3630         p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0';
3631         oclass = GEM_CLASS;
3632         dn = actualn = bp;
3633         goto srch;
3634     } else if (!strcmpi(bp, "looking glass")) {
3635         ; /* avoid false hit on "* glass" */
3636     } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) {
3637         register char *g = bp;
3638         if (strstri(g, "broken"))
3639             return (struct obj *) 0;
3640         if (!strncmpi(g, "worthless ", 10))
3641             g += 10;
3642         if (!strncmpi(g, "piece of ", 9))
3643             g += 9;
3644         if (!strncmpi(g, "colored ", 8))
3645             g += 8;
3646         else if (!strncmpi(g, "coloured ", 9))
3647             g += 9;
3648         if (!strcmpi(g, "glass")) { /* choose random color */
3649             /* 9 different kinds */
3650             typ = LAST_GEM + rnd(9);
3651             if (objects[typ].oc_class == GEM_CLASS)
3652                 goto typfnd;
3653             else
3654                 typ = 0; /* somebody changed objects[]? punt */
3655         } else { /* try to construct canonical form */
3656             char tbuf[BUFSZ];
3657
3658             Strcpy(tbuf, "worthless piece of ");
3659             Strcat(tbuf, g); /* assume it starts with the color */
3660             Strcpy(bp, tbuf);
3661         }
3662     }
3663
3664     actualn = bp;
3665     if (!dn)
3666         dn = actualn; /* ex. "skull cap" */
3667 srch:
3668     /* check real names of gems first */
3669     if (!oclass && actualn) {
3670         for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
3671             register const char *zn;
3672
3673             if ((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
3674                 typ = i;
3675                 goto typfnd;
3676             }
3677         }
3678     }
3679     i = oclass ? bases[(int) oclass] : 1;
3680     while (i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)) {
3681         register const char *zn;
3682
3683         if (actualn && (zn = OBJ_NAME(objects[i])) != 0
3684             && wishymatch(actualn, zn, TRUE)) {
3685             typ = i;
3686             goto typfnd;
3687         }
3688 #if 0 /*JP*/
3689         if (dn && (zn = OBJ_DESCR(objects[i])) != 0
3690             && wishymatch(dn, zn, FALSE)) {
3691 #else /*JP
3692        * \81u\83C\83F\83\93\83_\81[\82Ì\96\82\8f\9c\82¯\81v\82ð\8aè\82Á\82½\82Æ\82«\82É\82±\82±\82Å\82Í\8bU\95¨\82É
3693        * \82È\82ç\82È\82¢\82æ\82¤\82É\82·\82é\81B
3694        * \94ñ\83E\83B\83U\81[\83h\83\82\81[\83h\82Å\82Ì\93ü\82ê\91Ö\82¦\8f\88\97\9d\82Í\8cã\82É\82 \82é\81B
3695        */
3696         if (i != FAKE_AMULET_OF_YENDOR &&
3697             dn && (zn = OBJ_DESCR(objects[i])) != 0
3698             && wishymatch(dn, zn, FALSE)) {
3699 #endif
3700             /* don't match extra descriptions (w/o real name) */
3701             if (!OBJ_NAME(objects[i]))
3702                 return (struct obj *) 0;
3703             typ = i;
3704             goto typfnd;
3705         }
3706         if (un && (zn = objects[i].oc_uname) != 0
3707             && wishymatch(un, zn, FALSE)) {
3708             typ = i;
3709             goto typfnd;
3710         }
3711         i++;
3712     }
3713     if (actualn) {
3714         struct Jitem *j = Japanese_items;
3715
3716         while (j->item) {
3717             if (actualn && !strcmpi(actualn, j->name)) {
3718                 typ = j->item;
3719                 goto typfnd;
3720             }
3721             j++;
3722         }
3723     }
3724     /* if we've stripped off "armor" and failed to match anything
3725        in objects[], append "mail" and try again to catch misnamed
3726        requests like "plate armor" and "yellow dragon scale armor" */
3727     if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
3728         /* modifying bp's string is ok; we're about to resort
3729            to random armor if this also fails to match anything */
3730         Strcat(bp, " mail");
3731         goto retry;
3732     }
3733 #if 0 /*JP*/
3734     if (!strcmpi(bp, "spinach")) {
3735 #else
3736     if (!strcmp(bp, "\83z\83E\83\8c\83\93\91\90")) {
3737 #endif
3738         contents = SPINACH;
3739         typ = TIN;
3740         goto typfnd;
3741     }
3742     /* Note: not strcmpi.  2 fruits, one capital, one not, are possible.
3743        Also not strncmp.  We used to ignore trailing text with it, but
3744        that resulted in "grapefruit" matching "grape" if the latter came
3745        earlier than the former in the fruit list. */
3746     {
3747         char *fp;
3748         int l, cntf;
3749         int blessedf, iscursedf, uncursedf, halfeatenf;
3750
3751         blessedf = iscursedf = uncursedf = halfeatenf = 0;
3752         cntf = 0;
3753
3754         fp = fruitbuf;
3755         for (;;) {
3756             if (!fp || !*fp)
3757                 break;
3758             if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
3759                 cntf = 1;
3760             } else if (!cntf && digit(*fp)) {
3761                 cntf = atoi(fp);
3762                 while (digit(*fp))
3763                     fp++;
3764                 while (*fp == ' ')
3765                     fp++;
3766                 l = 0;
3767             } else if (!strncmpi(fp, "blessed ", l = 8)) {
3768                 blessedf = 1;
3769             } else if (!strncmpi(fp, "cursed ", l = 7)) {
3770                 iscursedf = 1;
3771             } else if (!strncmpi(fp, "uncursed ", l = 9)) {
3772                 uncursedf = 1;
3773             } else if (!strncmpi(fp, "partly eaten ", l = 13)
3774                        || !strncmpi(fp, "partially eaten ", l = 16)) {
3775                 halfeatenf = 1;
3776             } else
3777                 break;
3778             fp += l;
3779         }
3780
3781         for (f = ffruit; f; f = f->nextf) {
3782             /* match type: 0=none, 1=exact, 2=singular, 3=plural */
3783             int ftyp = 0;
3784
3785             if (!strcmp(fp, f->fname))
3786                 ftyp = 1;
3787             else if (!strcmp(fp, makesingular(f->fname)))
3788                 ftyp = 2;
3789             else if (!strcmp(fp, makeplural(f->fname)))
3790                 ftyp = 3;
3791             if (ftyp) {
3792                 typ = SLIME_MOLD;
3793                 blessed = blessedf;
3794                 iscursed = iscursedf;
3795                 uncursed = uncursedf;
3796                 halfeaten = halfeatenf;
3797                 /* adjust count if user explicitly asked for
3798                    singular amount (can't happen unless fruit
3799                    has been given an already pluralized name)
3800                    or for plural amount */
3801                 if (ftyp == 2 && !cntf)
3802                     cntf = 1;
3803                 else if (ftyp == 3 && !cntf)
3804                     cntf = 2;
3805                 cnt = cntf;
3806                 ftype = f->fid;
3807                 goto typfnd;
3808             }
3809         }
3810     }
3811
3812     if (!oclass && actualn) {
3813         short objtyp;
3814
3815         /* Perhaps it's an artifact specified by name, not type */
3816         name = artifact_name(actualn, &objtyp);
3817         if (name) {
3818             typ = objtyp;
3819             goto typfnd;
3820         }
3821     }
3822 /* Let wizards wish for traps and furniture.
3823  * Must come after objects check so wizards can still wish for
3824  * trap objects like beartraps.
3825  * Disallow such topology tweaks for WIZKIT startup wishes.
3826  */
3827 wiztrap:
3828     if (wizard && !program_state.wizkit_wishing) {
3829         struct rm *lev;
3830         int trap, x = u.ux, y = u.uy;
3831
3832         for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
3833             struct trap *t;
3834             const char *tname;
3835
3836             tname = defsyms[trap_to_defsym(trap)].explanation;
3837             if (strncmpi(tname, bp, strlen(tname)))
3838                 continue;
3839             /* found it; avoid stupid mistakes */
3840             if ((trap == TRAPDOOR || trap == HOLE) && !Can_fall_thru(&u.uz))
3841                 trap = ROCKTRAP;
3842             if ((t = maketrap(x, y, trap)) != 0) {
3843                 trap = t->ttyp;
3844                 tname = defsyms[trap_to_defsym(trap)].explanation;
3845                 pline("%s%s.", An(tname),
3846                       (trap != MAGIC_PORTAL) ? "" : " to nowhere");
3847             } else
3848                 pline("Creation of %s failed.", an(tname));
3849             return &zeroobj;
3850         }
3851
3852         /* furniture and terrain */
3853         lev = &levl[x][y];
3854         p = eos(bp);
3855         if (!BSTRCMPI(bp, p - 8, "fountain")) {
3856             lev->typ = FOUNTAIN;
3857             level.flags.nfountains++;
3858             if (!strncmpi(bp, "magic ", 6))
3859                 lev->blessedftn = 1;
3860             pline("A %sfountain.", lev->blessedftn ? "magic " : "");
3861             newsym(x, y);
3862             return &zeroobj;
3863         }
3864         if (!BSTRCMPI(bp, p - 6, "throne")) {
3865             lev->typ = THRONE;
3866             pline("A throne.");
3867             newsym(x, y);
3868             return &zeroobj;
3869         }
3870         if (!BSTRCMPI(bp, p - 4, "sink")) {
3871             lev->typ = SINK;
3872             level.flags.nsinks++;
3873             pline("A sink.");
3874             newsym(x, y);
3875             return &zeroobj;
3876         }
3877         /* ("water" matches "potion of water" rather than terrain) */
3878         if (!BSTRCMPI(bp, p - 4, "pool") || !BSTRCMPI(bp, p - 4, "moat")) {
3879             lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
3880             del_engr_at(x, y);
3881             pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
3882             /* Must manually make kelp! */
3883             water_damage_chain(level.objects[x][y], TRUE);
3884             newsym(x, y);
3885             return &zeroobj;
3886         }
3887         if (!BSTRCMPI(bp, p - 4, "lava")) { /* also matches "molten lava" */
3888             lev->typ = LAVAPOOL;
3889             del_engr_at(x, y);
3890             pline("A pool of molten lava.");
3891             if (!(Levitation || Flying))
3892                 (void) lava_effects();
3893             newsym(x, y);
3894             return &zeroobj;
3895         }
3896
3897         if (!BSTRCMPI(bp, p - 5, "altar")) {
3898             aligntyp al;
3899
3900             lev->typ = ALTAR;
3901             if (!strncmpi(bp, "chaotic ", 8))
3902                 al = A_CHAOTIC;
3903             else if (!strncmpi(bp, "neutral ", 8))
3904                 al = A_NEUTRAL;
3905             else if (!strncmpi(bp, "lawful ", 7))
3906                 al = A_LAWFUL;
3907             else if (!strncmpi(bp, "unaligned ", 10))
3908                 al = A_NONE;
3909             else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
3910                 al = (!rn2(6)) ? A_NONE : rn2((int) A_LAWFUL + 2) - 1;
3911             lev->altarmask = Align2amask(al);
3912             pline("%s altar.", An(align_str(al)));
3913             newsym(x, y);
3914             return &zeroobj;
3915         }
3916
3917         if (!BSTRCMPI(bp, p - 5, "grave")
3918             || !BSTRCMPI(bp, p - 9, "headstone")) {
3919             make_grave(x, y, (char *) 0);
3920             pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
3921                                             : "Can't place a grave here");
3922             newsym(x, y);
3923             return &zeroobj;
3924         }
3925
3926         if (!BSTRCMPI(bp, p - 4, "tree")) {
3927             lev->typ = TREE;
3928             pline("A tree.");
3929             newsym(x, y);
3930             block_point(x, y);
3931             return &zeroobj;
3932         }
3933
3934         if (!BSTRCMPI(bp, p - 4, "bars")) {
3935             lev->typ = IRONBARS;
3936             pline("Iron bars.");
3937             newsym(x, y);
3938             return &zeroobj;
3939         }
3940     }
3941
3942     if (!oclass && !typ) {
3943         if (!strncmpi(bp, "polearm", 7)) {
3944             typ = rnd_otyp_by_wpnskill(P_POLEARMS);
3945             goto typfnd;
3946         } else if (!strncmpi(bp, "hammer", 6)) {
3947             typ = rnd_otyp_by_wpnskill(P_HAMMER);
3948             goto typfnd;
3949         }
3950     }
3951
3952     if (!oclass)
3953         return ((struct obj *) 0);
3954 any:
3955     if (!oclass)
3956         oclass = wrpsym[rn2((int) sizeof(wrpsym))];
3957 typfnd:
3958     if (typ)
3959         oclass = objects[typ].oc_class;
3960
3961     /* handle some objects that are only allowed in wizard mode */
3962     if (typ && !wizard) {
3963         switch (typ) {
3964         case AMULET_OF_YENDOR:
3965             typ = FAKE_AMULET_OF_YENDOR;
3966             break;
3967         case CANDELABRUM_OF_INVOCATION:
3968             typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
3969             break;
3970         case BELL_OF_OPENING:
3971             typ = BELL;
3972             break;
3973         case SPE_BOOK_OF_THE_DEAD:
3974             typ = SPE_BLANK_PAPER;
3975             break;
3976         case MAGIC_LAMP:
3977             typ = OIL_LAMP;
3978             break;
3979         default:
3980             /* catch any other non-wishable objects (venom) */
3981             if (objects[typ].oc_nowish)
3982                 return (struct obj *) 0;
3983             break;
3984         }
3985     }
3986
3987     /*
3988      * Create the object, then fine-tune it.
3989      */
3990     otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
3991     typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
3992
3993     if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN
3994                   || Is_candle(otmp) || typ == POT_OIL)) {
3995         place_object(otmp, u.ux, u.uy); /* make it viable light source */
3996         begin_burn(otmp, FALSE);
3997         obj_extract_self(otmp); /* now release it for caller's use */
3998     }
3999
4000     /* if player specified a reasonable count, maybe honor it */
4001     if (cnt > 0 && objects[typ].oc_merge
4002         && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp))
4003             || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp))
4004                               || typ == ROCK || is_missile(otmp)))))
4005         otmp->quan = (long) cnt;
4006
4007     if (oclass == VENOM_CLASS)
4008         otmp->spe = 1;
4009
4010     if (spesgn == 0) {
4011         spe = otmp->spe;
4012     } else if (wizard) {
4013         ; /* no alteration to spe */
4014     } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
4015                || is_weptool(otmp)
4016                || (oclass == RING_CLASS && objects[typ].oc_charged)) {
4017         if (spe > rnd(5) && spe > otmp->spe)
4018             spe = 0;
4019         if (spe > 2 && Luck < 0)
4020             spesgn = -1;
4021     } else {
4022         if (oclass == WAND_CLASS) {
4023             if (spe > 1 && spesgn == -1)
4024                 spe = 1;
4025         } else {
4026             if (spe > 0 && spesgn == -1)
4027                 spe = 0;
4028         }
4029         if (spe > otmp->spe)
4030             spe = otmp->spe;
4031     }
4032
4033     if (spesgn == -1)
4034         spe = -spe;
4035
4036     /* set otmp->spe.  This may, or may not, use spe... */
4037     switch (typ) {
4038     case TIN:
4039         if (contents == EMPTY) {
4040             otmp->corpsenm = NON_PM;
4041             otmp->spe = 0;
4042         } else if (contents == SPINACH) {
4043             otmp->corpsenm = NON_PM;
4044             otmp->spe = 1;
4045         }
4046         break;
4047     case TOWEL:
4048         if (wetness)
4049             otmp->spe = wetness;
4050         break;
4051     case SLIME_MOLD:
4052         otmp->spe = ftype;
4053     /* Fall through */
4054     case SKELETON_KEY:
4055     case CHEST:
4056     case LARGE_BOX:
4057     case HEAVY_IRON_BALL:
4058     case IRON_CHAIN:
4059     case STATUE:
4060         /* otmp->cobj already done in mksobj() */
4061         break;
4062 #ifdef MAIL
4063     case SCR_MAIL:
4064         otmp->spe = 1;
4065         break;
4066 #endif
4067     case WAN_WISHING:
4068         if (!wizard) {
4069             otmp->spe = (rn2(10) ? -1 : 0);
4070             break;
4071         }
4072     /* fall through, if wizard */
4073     default:
4074         otmp->spe = spe;
4075     }
4076
4077     /* set otmp->corpsenm or dragon scale [mail] */
4078     if (mntmp >= LOW_PM) {
4079         if (mntmp == PM_LONG_WORM_TAIL)
4080             mntmp = PM_LONG_WORM;
4081
4082         switch (typ) {
4083         case TIN:
4084             otmp->spe = 0; /* No spinach */
4085             if (dead_species(mntmp, FALSE)) {
4086                 otmp->corpsenm = NON_PM; /* it's empty */
4087             } else if (!(mons[mntmp].geno & G_UNIQ)
4088                        && !(mvitals[mntmp].mvflags & G_NOCORPSE)
4089                        && mons[mntmp].cnutrit != 0) {
4090                 otmp->corpsenm = mntmp;
4091             }
4092             break;
4093         case CORPSE:
4094             if (!(mons[mntmp].geno & G_UNIQ)
4095                 && !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
4096                 if (mons[mntmp].msound == MS_GUARDIAN)
4097                     mntmp = genus(mntmp, 1);
4098                 set_corpsenm(otmp, mntmp);
4099             }
4100             break;
4101         case FIGURINE:
4102             if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4103 #ifdef MAIL
4104                 && mntmp != PM_MAIL_DAEMON
4105 #endif
4106                 )
4107                 otmp->corpsenm = mntmp;
4108             break;
4109         case EGG:
4110             mntmp = can_be_hatched(mntmp);
4111             /* this also sets hatch timer if appropriate */
4112             set_corpsenm(otmp, mntmp);
4113             break;
4114         case STATUE:
4115             otmp->corpsenm = mntmp;
4116             if (Has_contents(otmp) && verysmall(&mons[mntmp]))
4117                 delete_contents(otmp); /* no spellbook */
4118             otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
4119             break;
4120         case SCALE_MAIL:
4121             /* Dragon mail - depends on the order of objects & dragons. */
4122             if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON)
4123                 otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4124             break;
4125         }
4126     }
4127
4128     /* set blessed/cursed -- setting the fields directly is safe
4129      * since weight() is called below and addinv() will take care
4130      * of luck */
4131     if (iscursed) {
4132         curse(otmp);
4133     } else if (uncursed) {
4134         otmp->blessed = 0;
4135         otmp->cursed = (Luck < 0 && !wizard);
4136     } else if (blessed) {
4137         otmp->blessed = (Luck >= 0 || wizard);
4138         otmp->cursed = (Luck < 0 && !wizard);
4139     } else if (spesgn < 0) {
4140         curse(otmp);
4141     }
4142
4143     /* set eroded */
4144     if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
4145         if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
4146             otmp->oeroded = eroded;
4147         if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
4148             otmp->oeroded2 = eroded2;
4149
4150         /* set erodeproof */
4151         if (erodeproof && !eroded && !eroded2)
4152             otmp->oerodeproof = (Luck >= 0 || wizard);
4153     }
4154
4155     /* set otmp->recharged */
4156     if (oclass == WAND_CLASS) {
4157         /* prevent wishing abuse */
4158         if (otmp->otyp == WAN_WISHING && !wizard)
4159             rechrg = 1;
4160         otmp->recharged = (unsigned) rechrg;
4161     }
4162
4163     /* set poisoned */
4164     if (ispoisoned) {
4165         if (is_poisonable(otmp))
4166             otmp->opoisoned = (Luck >= 0);
4167         else if (oclass == FOOD_CLASS)
4168             /* try to taint by making it as old as possible */
4169             otmp->age = 1L;
4170     }
4171     /* and [un]trapped */
4172     if (trapped) {
4173         if (Is_box(otmp) || typ == TIN)
4174             otmp->otrapped = (trapped == 1);
4175     }
4176
4177     if (isgreased)
4178         otmp->greased = 1;
4179
4180     if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4181         otmp->odiluted = 1;
4182
4183     /* set tin variety */
4184     if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4185         set_tin_variety(otmp, tvariety);
4186
4187     if (name) {
4188         const char *aname;
4189         short objtyp;
4190
4191         /* an artifact name might need capitalization fixing */
4192         aname = artifact_name(name, &objtyp);
4193         if (aname && objtyp == otmp->otyp)
4194             name = aname;
4195
4196         /* 3.6.0 tribute - fix up novel */
4197         if (otmp->otyp == SPE_NOVEL) {
4198             const char *novelname;
4199
4200             novelname = lookup_novel(name, &otmp->novelidx);
4201             if (novelname)
4202                 name = novelname;
4203         }
4204
4205         otmp = oname(otmp, name);
4206         if (otmp->oartifact) {
4207             otmp->quan = 1L;
4208             u.uconduct.wisharti++; /* KMH, conduct */
4209         }
4210     }
4211
4212     /* more wishing abuse: don't allow wishing for certain artifacts */
4213     /* and make them pay; charge them for the wish anyway! */
4214     if ((is_quest_artifact(otmp)
4215          || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) {
4216         artifact_exists(otmp, safe_oname(otmp), FALSE);
4217         obfree(otmp, (struct obj *) 0);
4218         otmp = &zeroobj;
4219 /*JP
4220         pline("For a moment, you feel %s in your %s, but it disappears!",
4221 */
4222         pline("\88ê\8fu%s\82ª%s\82Ì\92\86\82É\82 \82é\82æ\82¤\82È\8a´\82\82ª\82µ\82½\82ª\81C\82·\82®\82É\8fÁ\82¦\82³\82Á\82½\81I",
4223               something, makeplural(body_part(HAND)));
4224     }
4225
4226     if (halfeaten && otmp->oclass == FOOD_CLASS) {
4227         if (otmp->otyp == CORPSE)
4228             otmp->oeaten = mons[otmp->corpsenm].cnutrit;
4229         else
4230             otmp->oeaten = objects[otmp->otyp].oc_nutrition;
4231         /* (do this adjustment before setting up object's weight) */
4232         consume_oeaten(otmp, 1);
4233     }
4234     otmp->owt = weight(otmp);
4235     if (very && otmp->otyp == HEAVY_IRON_BALL)
4236         otmp->owt += 160;
4237
4238     return otmp;
4239 }
4240
4241 int
4242 rnd_class(first, last)
4243 int first, last;
4244 {
4245     int i, x, sum = 0;
4246
4247     if (first == last)
4248         return first;
4249     for (i = first; i <= last; i++)
4250         sum += objects[i].oc_prob;
4251     if (!sum) /* all zero */
4252         return first + rn2(last - first + 1);
4253     x = rnd(sum);
4254     for (i = first; i <= last; i++)
4255         if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
4256             return i;
4257     return 0;
4258 }
4259
4260 STATIC_OVL const char *
4261 Japanese_item_name(i)
4262 int i;
4263 {
4264     struct Jitem *j = Japanese_items;
4265
4266     while (j->item) {
4267         if (i == j->item)
4268             return j->name;
4269         j++;
4270     }
4271     return (const char *) 0;
4272 }
4273
4274 const char *
4275 suit_simple_name(suit)
4276 struct obj *suit;
4277 {
4278     const char *suitnm, *esuitp;
4279
4280     if (Is_dragon_mail(suit))
4281         return "dragon mail"; /* <color> dragon scale mail */
4282     else if (Is_dragon_scales(suit))
4283         return "dragon scales";
4284     suitnm = OBJ_NAME(objects[suit->otyp]);
4285     esuitp = eos((char *) suitnm);
4286     if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
4287         return "mail"; /* most suits fall into this category */
4288     else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
4289         return "jacket"; /* leather jacket */
4290     /* suit is lame but armor is ambiguous and body armor is absurd */
4291     return "suit";
4292 }
4293
4294 const char *
4295 cloak_simple_name(cloak)
4296 struct obj *cloak;
4297 {
4298     if (cloak) {
4299         switch (cloak->otyp) {
4300         case ROBE:
4301 /*JP
4302             return "robe";
4303 */
4304             return "\83\8d\81[\83u";
4305         case MUMMY_WRAPPING:
4306 /*JP
4307             return "wrapping";
4308 */
4309             return "\95ï\91Ñ";
4310         case ALCHEMY_SMOCK:
4311             return (objects[cloak->otyp].oc_name_known && cloak->dknown)
4312 /*JP
4313                        ? "smock"
4314 */
4315                        ? "\83X\83\82\83b\83N"
4316 /*JP
4317                        : "apron";
4318 */
4319                        : "\83G\83v\83\8d\83\93";
4320         default:
4321             break;
4322         }
4323     }
4324 /*JP
4325     return "cloak";
4326 */
4327     return "\83N\83\8d\81[\83N";
4328 }
4329
4330 /* helm vs hat for messages */
4331 const char *
4332 helm_simple_name(helmet)
4333 struct obj *helmet;
4334 {
4335     /*
4336      *  There is some wiggle room here; the result has been chosen
4337      *  for consistency with the "protected by hard helmet" messages
4338      *  given for various bonks on the head:  headgear that provides
4339      *  such protection is a "helm", that which doesn't is a "hat".
4340      *
4341      *      elven leather helm / leather hat    -> hat
4342      *      dwarvish iron helm / hard hat       -> helm
4343      *  The rest are completely straightforward:
4344      *      fedora, cornuthaum, dunce cap       -> hat
4345      *      all other types of helmets          -> helm
4346      */
4347 /*JP
4348     return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
4349 */
4350     return (helmet && !is_metallic(helmet)) ? "\96X\8eq" : "\8a\95";
4351 }
4352
4353 const char *
4354 mimic_obj_name(mtmp)
4355 struct monst *mtmp;
4356 {
4357     if (mtmp->m_ap_type == M_AP_OBJECT
4358         && mtmp->mappearance != STRANGE_OBJECT) {
4359         int idx = objects[mtmp->mappearance].oc_descr_idx;
4360         if (mtmp->mappearance == GOLD_PIECE)
4361 /*JP
4362             return "gold";
4363 */
4364             return "\8bà\89Ý";
4365         return obj_descr[idx].oc_name;
4366     }
4367 /*JP
4368     return "whatcha-may-callit";
4369 */
4370     return "\89½\82Æ\82©\82¢\82¤\82à\82Ì";
4371 }
4372
4373 /*
4374  * Construct a query prompt string, based around an object name, which is
4375  * guaranteed to fit within [QBUFSZ].  Takes an optional prefix, three
4376  * choices for filling in the middle (two object formatting functions and a
4377  * last resort literal which should be very short), and an optional suffix.
4378  */
4379 char *
4380 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
4381 char *qbuf; /* output buffer */
4382 const char *qprefix, *qsuffix;
4383 struct obj *obj;
4384 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
4385 const char *lastR;
4386 {
4387     char *bufp, *endp;
4388     /* convert size_t (or int for ancient systems) to ordinary unsigned */
4389     unsigned len, lenlimit,
4390         len_qpfx = (unsigned) (qprefix ? strlen(qprefix) : 0),
4391         len_qsfx = (unsigned) (qsuffix ? strlen(qsuffix) : 0),
4392         len_lastR = (unsigned) strlen(lastR);
4393
4394     lenlimit = QBUFSZ - 1;
4395     endp = qbuf + lenlimit;
4396     /* sanity check, aimed mainly at paniclog (it's conceivable for
4397        the result of short_oname() to be shorter than the length of
4398        the last resort string, but we ignore that possibility here) */
4399     if (len_qpfx > lenlimit)
4400         impossible("safe_qbuf: prefix too long (%u characters).", len_qpfx);
4401     else if (len_qpfx + len_qsfx > lenlimit)
4402         impossible("safe_qbuf: suffix too long (%u + %u characters).",
4403                    len_qpfx, len_qsfx);
4404     else if (len_qpfx + len_lastR + len_qsfx > lenlimit)
4405         impossible("safe_qbuf: filler too long (%u + %u + %u characters).",
4406                    len_qpfx, len_lastR, len_qsfx);
4407
4408     /* the output buffer might be the same as the prefix if caller
4409        has already partially filled it */
4410     if (qbuf == qprefix) {
4411         /* prefix is already in the buffer */
4412         *endp = '\0';
4413     } else if (qprefix) {
4414         /* put prefix into the buffer */
4415         (void) strncpy(qbuf, qprefix, lenlimit);
4416         *endp = '\0';
4417     } else {
4418         /* no prefix; output buffer starts out empty */
4419         qbuf[0] = '\0';
4420     }
4421     len = (unsigned) strlen(qbuf);
4422
4423     if (len + len_lastR + len_qsfx > lenlimit) {
4424         /* too long; skip formatting, last resort output is truncated */
4425         if (len < lenlimit) {
4426             (void) strncpy(&qbuf[len], lastR, lenlimit - len);
4427             *endp = '\0';
4428             len = (unsigned) strlen(qbuf);
4429             if (qsuffix && len < lenlimit) {
4430                 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
4431                 *endp = '\0';
4432                 /* len = (unsigned) strlen(qbuf); */
4433             }
4434         }
4435     } else {
4436         /* suffix and last resort are guaranteed to fit */
4437         len += len_qsfx; /* include the pending suffix */
4438         /* format the object */
4439         bufp = short_oname(obj, func, altfunc, lenlimit - len);
4440         if (len + strlen(bufp) <= lenlimit)
4441             Strcat(qbuf, bufp); /* formatted name fits */
4442         else
4443             Strcat(qbuf, lastR); /* use last resort */
4444         releaseobuf(bufp);
4445
4446         if (qsuffix)
4447             Strcat(qbuf, qsuffix);
4448     }
4449     /* assert( strlen(qbuf) < QBUFSZ ); */
4450     return qbuf;
4451 }
4452
4453 /*objnam.c*/