OSDN Git Service

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