OSDN Git Service

a2d707294044cbd9030bf731e52b88d62634b392
[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).%s//%s", i, s, pref);
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*//*\93ú\96{\8cê\82Å\82Í\8f\88\97\9d\82µ\82È\82¢*/
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 #endif
3369     /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
3370     if (strncmpi(bp, "samurai sword", 13))   /* not the "samurai" monster! */
3371         if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
3372             if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
3373                 if (strncmpi(bp, "master key",
3374                              10)) /* not the "master" rank */
3375                     if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
3376                         if (mntmp < LOW_PM && strlen(bp) > 2
3377                             && (mntmp = name_to_mon(bp)) >= LOW_PM) {
3378                             int mntmptoo,
3379                                 mntmplen; /* double check for rank title */
3380                             char *obp = bp;
3381                             mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
3382                             bp += mntmp != mntmptoo
3383                                       ? (int) strlen(mons[mntmp].mname)
3384                                       : mntmplen;
3385                             if (*bp == ' ')
3386                                 bp++;
3387                             else if (!strncmpi(bp, "s ", 2))
3388                                 bp += 2;
3389                             else if (!strncmpi(bp, "es ", 3))
3390                                 bp += 3;
3391                             else if (!*bp && !actualn && !dn && !un
3392                                      && !oclass) {
3393                                 /* no referent; they don't really mean a
3394                                  * monster type */
3395                                 bp = obp;
3396                                 mntmp = NON_PM;
3397                             }
3398                         }
3399
3400 #if 0 /*JP*//*\92P\90\94\89»\82Í\82µ\82È\82¢*/
3401     /* first change to singular if necessary */
3402     if (*bp) {
3403         char *sng = makesingular(bp);
3404         if (strcmp(bp, sng)) {
3405             if (cnt == 1)
3406                 cnt = 2;
3407             Strcpy(bp, sng);
3408         }
3409     }
3410 #endif
3411
3412 #if 0 /*JP*//*\83X\83y\83\8b\97h\82ê\8f\88\97\9d\82Í\82µ\82È\82¢*/
3413     /* Alternate spellings (pick-ax, silver sabre, &c) */
3414     {
3415         struct alt_spellings *as = spellings;
3416
3417         while (as->sp) {
3418             if (fuzzymatch(bp, as->sp, " -", TRUE)) {
3419                 typ = as->ob;
3420                 goto typfnd;
3421             }
3422             as++;
3423         }
3424         /* can't use spellings list for this one due to shuffling */
3425         if (!strncmpi(bp, "grey spell", 10))
3426             *(bp + 2) = 'a';
3427
3428         if ((p = strstri(bp, "armour")) != 0) {
3429             /* skip past "armo", then copy remainder beyond "u" */
3430             p += 4;
3431             while ((*p = *(p + 1)) != '\0')
3432                 ++p; /* self terminating */
3433         }
3434     }
3435 #endif
3436
3437     /* dragon scales - assumes order of dragons */
3438     if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON
3439         && mntmp <= PM_YELLOW_DRAGON) {
3440         typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3441         mntmp = NON_PM; /* no monster */
3442         goto typfnd;
3443     }
3444
3445     p = eos(bp);
3446 #if 0 /*JP*/
3447     if (!BSTRCMPI(bp, p - 10, "holy water")) {
3448         typ = POT_WATER;
3449         if ((p - bp) >= 12 && *(p - 12) == 'u')
3450             iscursed = 1; /* unholy water */
3451         else
3452             blessed = 1;
3453         goto typfnd;
3454     }
3455 #else /*JP:\90¹\90\85\82Æ\95s\8fò\82È\90\85\82ð\95Ê\82É\94»\92è*/
3456     if (!BSTRCMPI(bp, p - 4, "\90¹\90\85")) {
3457         typ = POT_WATER;
3458         blessed = 1;
3459         goto typfnd;
3460     }
3461     if (!BSTRCMPI(bp, p - 4, "\95s\8fò\82È\90\85")) {
3462         typ = POT_WATER;
3463         iscursed = 1;
3464         goto typfnd;
3465     }
3466 #endif
3467 #if 0 /*JP*/
3468     if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
3469 #else
3470     if (unlabeled && !BSTRCMPI(bp, p - 4, "\8aª\95¨")) {
3471 #endif
3472         typ = SCR_BLANK_PAPER;
3473         goto typfnd;
3474     }
3475 #if 0 /*JP*/
3476     if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
3477 #else
3478     if (unlabeled && !BSTRCMPI(bp, p - 6, "\96\82\96@\8f\91")) {
3479 #endif
3480         typ = SPE_BLANK_PAPER;
3481         goto typfnd;
3482     }
3483     /*
3484      * NOTE: Gold pieces are handled as objects nowadays, and therefore
3485      * this section should probably be reconsidered as well as the entire
3486      * gold/money concept.  Maybe we want to add other monetary units as
3487      * well in the future. (TH)
3488      */
3489 #if 0 /*JP*/
3490     if (!BSTRCMPI(bp, p - 10, "gold piece") || !BSTRCMPI(bp, p - 7, "zorkmid")
3491         || !strcmpi(bp, "gold") || !strcmpi(bp, "money")
3492         || !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
3493 #else
3494     if (!BSTRCMPI(bp, p - 4, "\8bà\89Ý") || !BSTRCMPI(bp, p - 8, "\83S\81[\83\8b\83h")
3495         || *bp == GOLD_SYM) {
3496 #endif
3497         if (cnt > 5000 && !wizard)
3498             cnt = 5000;
3499         else if (cnt < 1)
3500             cnt = 1;
3501         otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
3502         otmp->quan = (long) cnt;
3503         otmp->owt = weight(otmp);
3504         context.botl = 1;
3505         return otmp;
3506     }
3507
3508     /* check for single character object class code ("/" for wand, &c) */
3509     if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES
3510         && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
3511         oclass = i;
3512         goto any;
3513     }
3514
3515 #if 0 /*JP*/
3516     /*JP
3517       \89p\8cê\82È\82ç XXXXX potion \82Í\95s\8am\92è\96¼\81Apotion of XXXXX \82Í\8am\92è\96¼\82Æ\82¢\82¤
3518       \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¢
3519       */
3520     /* Search for class names: XXXXX potion, scroll of XXXXX.  Avoid */
3521     /* false hits on, e.g., rings for "ring mail". */
3522     if (strncmpi(bp, "enchant ", 8) && strncmpi(bp, "destroy ", 8)
3523         && strncmpi(bp, "detect food", 11)
3524         && strncmpi(bp, "food detection", 14) && strncmpi(bp, "ring mail", 9)
3525         && strncmpi(bp, "studded leather armor", 21)
3526         && strncmpi(bp, "leather armor", 13)
3527         && strncmpi(bp, "tooled horn", 11) && strncmpi(bp, "food ration", 11)
3528         && strncmpi(bp, "meat ring", 9))
3529         for (i = 0; i < (int) (sizeof wrpsym); i++) {
3530             register int j = strlen(wrp[i]);
3531             if (!strncmpi(bp, wrp[i], j)) {
3532                 oclass = wrpsym[i];
3533                 if (oclass != AMULET_CLASS) {
3534                     bp += j;
3535                     if (!strncmpi(bp, " of ", 4))
3536                         actualn = bp + 4;
3537                     /* else if(*bp) ?? */
3538                 } else
3539                     actualn = bp;
3540                 goto srch;
3541             }
3542             if (!BSTRCMPI(bp, p - j, wrp[i])) {
3543                 oclass = wrpsym[i];
3544                 p -= j;
3545                 *p = 0;
3546                 if (p > bp && p[-1] == ' ')
3547                     p[-1] = 0;
3548                 actualn = dn = bp;
3549                 goto srch;
3550             }
3551         }
3552 #endif
3553
3554     /* Wishing in wizard mode can create traps and furniture.
3555      * Part I:  distinguish between trap and object for the two
3556      * types of traps which have corresponding objects:  bear trap
3557      * and land mine.  "beartrap" (object) and "bear trap" (trap)
3558      * have a difference in spelling which we used to exploit by
3559      * adding a special case in wishymatch(), but "land mine" is
3560      * spelled the same either way so needs different handing.
3561      * Since we need something else for land mine, we've dropped
3562      * the bear trap hack so that both are handled exactly the
3563      * same.  To get an armed trap instead of a disarmed object,
3564      * the player can prefix either the object name or the trap
3565      * name with "trapped " (which ordinarily applies to chests
3566      * and tins), or append something--anything at all except for
3567      * " object", but " trap" is suggested--to either the trap
3568      * name or the object name.
3569      */
3570     if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
3571         boolean beartrap = (lowc(*bp) == 'b');
3572         char *zp = bp + 4; /* skip "bear"/"land" */
3573
3574         if (*zp == ' ')
3575             ++zp; /* embedded space is optional */
3576         if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
3577             zp += 4;
3578             if (trapped == 2 || !strcmpi(zp, " object")) {
3579                 /* "untrapped <foo>" or "<foo> object" */
3580                 typ = beartrap ? BEARTRAP : LAND_MINE;
3581                 goto typfnd;
3582             } else if (trapped == 1 || *zp != '\0') {
3583                 /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
3584                 int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
3585
3586                 /* use canonical trap spelling, skip object matching */
3587                 Strcpy(bp, defsyms[idx].explanation);
3588                 goto wiztrap;
3589             }
3590             /* [no prefix or suffix; we're going to end up matching
3591                the object name and getting a disarmed trap object] */
3592         }
3593     }
3594
3595 retry:
3596     /* "grey stone" check must be before general "stone" */
3597     for (i = 0; i < SIZE(o_ranges); i++)
3598         if (!strcmpi(bp, o_ranges[i].name)) {
3599             typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
3600             goto typfnd;
3601         }
3602
3603     if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) {
3604         p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0';
3605         oclass = GEM_CLASS;
3606         dn = actualn = bp;
3607         goto srch;
3608     } else if (!strcmpi(bp, "looking glass")) {
3609         ; /* avoid false hit on "* glass" */
3610     } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) {
3611         register char *g = bp;
3612         if (strstri(g, "broken"))
3613             return (struct obj *) 0;
3614         if (!strncmpi(g, "worthless ", 10))
3615             g += 10;
3616         if (!strncmpi(g, "piece of ", 9))
3617             g += 9;
3618         if (!strncmpi(g, "colored ", 8))
3619             g += 8;
3620         else if (!strncmpi(g, "coloured ", 9))
3621             g += 9;
3622         if (!strcmpi(g, "glass")) { /* choose random color */
3623             /* 9 different kinds */
3624             typ = LAST_GEM + rnd(9);
3625             if (objects[typ].oc_class == GEM_CLASS)
3626                 goto typfnd;
3627             else
3628                 typ = 0; /* somebody changed objects[]? punt */
3629         } else { /* try to construct canonical form */
3630             char tbuf[BUFSZ];
3631
3632             Strcpy(tbuf, "worthless piece of ");
3633             Strcat(tbuf, g); /* assume it starts with the color */
3634             Strcpy(bp, tbuf);
3635         }
3636     }
3637
3638     actualn = bp;
3639     if (!dn)
3640         dn = actualn; /* ex. "skull cap" */
3641 srch:
3642     /* check real names of gems first */
3643     if (!oclass && actualn) {
3644         for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
3645             register const char *zn;
3646
3647             if ((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
3648                 typ = i;
3649                 goto typfnd;
3650             }
3651         }
3652     }
3653     i = oclass ? bases[(int) oclass] : 1;
3654     while (i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)) {
3655         register const char *zn;
3656
3657         if (actualn && (zn = OBJ_NAME(objects[i])) != 0
3658             && wishymatch(actualn, zn, TRUE)) {
3659             typ = i;
3660             goto typfnd;
3661         }
3662 #if 0 /*JP*/
3663         if (dn && (zn = OBJ_DESCR(objects[i])) != 0
3664             && wishymatch(dn, zn, FALSE)) {
3665 #else /*JP
3666        * \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É
3667        * \82È\82ç\82È\82¢\82æ\82¤\82É\82·\82é\81B
3668        * \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
3669        */
3670         if (i != FAKE_AMULET_OF_YENDOR &&
3671             dn && (zn = OBJ_DESCR(objects[i])) != 0
3672             && wishymatch(dn, zn, FALSE)) {
3673 #endif
3674             /* don't match extra descriptions (w/o real name) */
3675             if (!OBJ_NAME(objects[i]))
3676                 return (struct obj *) 0;
3677             typ = i;
3678             goto typfnd;
3679         }
3680         if (un && (zn = objects[i].oc_uname) != 0
3681             && wishymatch(un, zn, FALSE)) {
3682             typ = i;
3683             goto typfnd;
3684         }
3685         i++;
3686     }
3687     if (actualn) {
3688         struct Jitem *j = Japanese_items;
3689
3690         while (j->item) {
3691             if (actualn && !strcmpi(actualn, j->name)) {
3692                 typ = j->item;
3693                 goto typfnd;
3694             }
3695             j++;
3696         }
3697     }
3698     /* if we've stripped off "armor" and failed to match anything
3699        in objects[], append "mail" and try again to catch misnamed
3700        requests like "plate armor" and "yellow dragon scale armor" */
3701     if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
3702         /* modifying bp's string is ok; we're about to resort
3703            to random armor if this also fails to match anything */
3704         Strcat(bp, " mail");
3705         goto retry;
3706     }
3707 #if 0 /*JP*/
3708     if (!strcmpi(bp, "spinach")) {
3709 #else
3710     if (!strcmp(bp, "\83z\83E\83\8c\83\93\91\90")) {
3711 #endif
3712         contents = SPINACH;
3713         typ = TIN;
3714         goto typfnd;
3715     }
3716     /* Note: not strcmpi.  2 fruits, one capital, one not, are possible.
3717        Also not strncmp.  We used to ignore trailing text with it, but
3718        that resulted in "grapefruit" matching "grape" if the latter came
3719        earlier than the former in the fruit list. */
3720     {
3721         char *fp;
3722         int l, cntf;
3723         int blessedf, iscursedf, uncursedf, halfeatenf;
3724
3725         blessedf = iscursedf = uncursedf = halfeatenf = 0;
3726         cntf = 0;
3727
3728         fp = fruitbuf;
3729         for (;;) {
3730             if (!fp || !*fp)
3731                 break;
3732             if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
3733                 cntf = 1;
3734             } else if (!cntf && digit(*fp)) {
3735                 cntf = atoi(fp);
3736                 while (digit(*fp))
3737                     fp++;
3738                 while (*fp == ' ')
3739                     fp++;
3740                 l = 0;
3741             } else if (!strncmpi(fp, "blessed ", l = 8)) {
3742                 blessedf = 1;
3743             } else if (!strncmpi(fp, "cursed ", l = 7)) {
3744                 iscursedf = 1;
3745             } else if (!strncmpi(fp, "uncursed ", l = 9)) {
3746                 uncursedf = 1;
3747             } else if (!strncmpi(fp, "partly eaten ", l = 13)
3748                        || !strncmpi(fp, "partially eaten ", l = 16)) {
3749                 halfeatenf = 1;
3750             } else
3751                 break;
3752             fp += l;
3753         }
3754
3755         for (f = ffruit; f; f = f->nextf) {
3756             /* match type: 0=none, 1=exact, 2=singular, 3=plural */
3757             int ftyp = 0;
3758
3759             if (!strcmp(fp, f->fname))
3760                 ftyp = 1;
3761             else if (!strcmp(fp, makesingular(f->fname)))
3762                 ftyp = 2;
3763             else if (!strcmp(fp, makeplural(f->fname)))
3764                 ftyp = 3;
3765             if (ftyp) {
3766                 typ = SLIME_MOLD;
3767                 blessed = blessedf;
3768                 iscursed = iscursedf;
3769                 uncursed = uncursedf;
3770                 halfeaten = halfeatenf;
3771                 /* adjust count if user explicitly asked for
3772                    singular amount (can't happen unless fruit
3773                    has been given an already pluralized name)
3774                    or for plural amount */
3775                 if (ftyp == 2 && !cntf)
3776                     cntf = 1;
3777                 else if (ftyp == 3 && !cntf)
3778                     cntf = 2;
3779                 cnt = cntf;
3780                 ftype = f->fid;
3781                 goto typfnd;
3782             }
3783         }
3784     }
3785
3786     if (!oclass && actualn) {
3787         short objtyp;
3788
3789         /* Perhaps it's an artifact specified by name, not type */
3790         name = artifact_name(actualn, &objtyp);
3791         if (name) {
3792             typ = objtyp;
3793             goto typfnd;
3794         }
3795     }
3796 /* Let wizards wish for traps and furniture.
3797  * Must come after objects check so wizards can still wish for
3798  * trap objects like beartraps.
3799  * Disallow such topology tweaks for WIZKIT startup wishes.
3800  */
3801 wiztrap:
3802     if (wizard && !program_state.wizkit_wishing) {
3803         struct rm *lev;
3804         int trap, x = u.ux, y = u.uy;
3805
3806         for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
3807             struct trap *t;
3808             const char *tname;
3809
3810             tname = defsyms[trap_to_defsym(trap)].explanation;
3811             if (strncmpi(tname, bp, strlen(tname)))
3812                 continue;
3813             /* found it; avoid stupid mistakes */
3814             if ((trap == TRAPDOOR || trap == HOLE) && !Can_fall_thru(&u.uz))
3815                 trap = ROCKTRAP;
3816             if ((t = maketrap(x, y, trap)) != 0) {
3817                 trap = t->ttyp;
3818                 tname = defsyms[trap_to_defsym(trap)].explanation;
3819                 pline("%s%s.", An(tname),
3820                       (trap != MAGIC_PORTAL) ? "" : " to nowhere");
3821             } else
3822                 pline("Creation of %s failed.", an(tname));
3823             return &zeroobj;
3824         }
3825
3826         /* furniture and terrain */
3827         lev = &levl[x][y];
3828         p = eos(bp);
3829         if (!BSTRCMPI(bp, p - 8, "fountain")) {
3830             lev->typ = FOUNTAIN;
3831             level.flags.nfountains++;
3832             if (!strncmpi(bp, "magic ", 6))
3833                 lev->blessedftn = 1;
3834             pline("A %sfountain.", lev->blessedftn ? "magic " : "");
3835             newsym(x, y);
3836             return &zeroobj;
3837         }
3838         if (!BSTRCMPI(bp, p - 6, "throne")) {
3839             lev->typ = THRONE;
3840             pline("A throne.");
3841             newsym(x, y);
3842             return &zeroobj;
3843         }
3844         if (!BSTRCMPI(bp, p - 4, "sink")) {
3845             lev->typ = SINK;
3846             level.flags.nsinks++;
3847             pline("A sink.");
3848             newsym(x, y);
3849             return &zeroobj;
3850         }
3851         /* ("water" matches "potion of water" rather than terrain) */
3852         if (!BSTRCMPI(bp, p - 4, "pool") || !BSTRCMPI(bp, p - 4, "moat")) {
3853             lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
3854             del_engr_at(x, y);
3855             pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
3856             /* Must manually make kelp! */
3857             water_damage_chain(level.objects[x][y], TRUE);
3858             newsym(x, y);
3859             return &zeroobj;
3860         }
3861         if (!BSTRCMPI(bp, p - 4, "lava")) { /* also matches "molten lava" */
3862             lev->typ = LAVAPOOL;
3863             del_engr_at(x, y);
3864             pline("A pool of molten lava.");
3865             if (!(Levitation || Flying))
3866                 (void) lava_effects();
3867             newsym(x, y);
3868             return &zeroobj;
3869         }
3870
3871         if (!BSTRCMPI(bp, p - 5, "altar")) {
3872             aligntyp al;
3873
3874             lev->typ = ALTAR;
3875             if (!strncmpi(bp, "chaotic ", 8))
3876                 al = A_CHAOTIC;
3877             else if (!strncmpi(bp, "neutral ", 8))
3878                 al = A_NEUTRAL;
3879             else if (!strncmpi(bp, "lawful ", 7))
3880                 al = A_LAWFUL;
3881             else if (!strncmpi(bp, "unaligned ", 10))
3882                 al = A_NONE;
3883             else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
3884                 al = (!rn2(6)) ? A_NONE : rn2((int) A_LAWFUL + 2) - 1;
3885             lev->altarmask = Align2amask(al);
3886             pline("%s altar.", An(align_str(al)));
3887             newsym(x, y);
3888             return &zeroobj;
3889         }
3890
3891         if (!BSTRCMPI(bp, p - 5, "grave")
3892             || !BSTRCMPI(bp, p - 9, "headstone")) {
3893             make_grave(x, y, (char *) 0);
3894             pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
3895                                             : "Can't place a grave here");
3896             newsym(x, y);
3897             return &zeroobj;
3898         }
3899
3900         if (!BSTRCMPI(bp, p - 4, "tree")) {
3901             lev->typ = TREE;
3902             pline("A tree.");
3903             newsym(x, y);
3904             block_point(x, y);
3905             return &zeroobj;
3906         }
3907
3908         if (!BSTRCMPI(bp, p - 4, "bars")) {
3909             lev->typ = IRONBARS;
3910             pline("Iron bars.");
3911             newsym(x, y);
3912             return &zeroobj;
3913         }
3914     }
3915
3916     if (!oclass && !typ) {
3917         if (!strncmpi(bp, "polearm", 7)) {
3918             typ = rnd_otyp_by_wpnskill(P_POLEARMS);
3919             goto typfnd;
3920         } else if (!strncmpi(bp, "hammer", 6)) {
3921             typ = rnd_otyp_by_wpnskill(P_HAMMER);
3922             goto typfnd;
3923         }
3924     }
3925
3926     if (!oclass)
3927         return ((struct obj *) 0);
3928 any:
3929     if (!oclass)
3930         oclass = wrpsym[rn2((int) sizeof(wrpsym))];
3931 typfnd:
3932     if (typ)
3933         oclass = objects[typ].oc_class;
3934
3935     /* handle some objects that are only allowed in wizard mode */
3936     if (typ && !wizard) {
3937         switch (typ) {
3938         case AMULET_OF_YENDOR:
3939             typ = FAKE_AMULET_OF_YENDOR;
3940             break;
3941         case CANDELABRUM_OF_INVOCATION:
3942             typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
3943             break;
3944         case BELL_OF_OPENING:
3945             typ = BELL;
3946             break;
3947         case SPE_BOOK_OF_THE_DEAD:
3948             typ = SPE_BLANK_PAPER;
3949             break;
3950         case MAGIC_LAMP:
3951             typ = OIL_LAMP;
3952             break;
3953         default:
3954             /* catch any other non-wishable objects (venom) */
3955             if (objects[typ].oc_nowish)
3956                 return (struct obj *) 0;
3957             break;
3958         }
3959     }
3960
3961     /*
3962      * Create the object, then fine-tune it.
3963      */
3964     otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
3965     typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
3966
3967     if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN
3968                   || Is_candle(otmp) || typ == POT_OIL)) {
3969         place_object(otmp, u.ux, u.uy); /* make it viable light source */
3970         begin_burn(otmp, FALSE);
3971         obj_extract_self(otmp); /* now release it for caller's use */
3972     }
3973
3974     /* if player specified a reasonable count, maybe honor it */
3975     if (cnt > 0 && objects[typ].oc_merge
3976         && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp))
3977             || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp))
3978                               || typ == ROCK || is_missile(otmp)))))
3979         otmp->quan = (long) cnt;
3980
3981     if (oclass == VENOM_CLASS)
3982         otmp->spe = 1;
3983
3984     if (spesgn == 0) {
3985         spe = otmp->spe;
3986     } else if (wizard) {
3987         ; /* no alteration to spe */
3988     } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
3989                || is_weptool(otmp)
3990                || (oclass == RING_CLASS && objects[typ].oc_charged)) {
3991         if (spe > rnd(5) && spe > otmp->spe)
3992             spe = 0;
3993         if (spe > 2 && Luck < 0)
3994             spesgn = -1;
3995     } else {
3996         if (oclass == WAND_CLASS) {
3997             if (spe > 1 && spesgn == -1)
3998                 spe = 1;
3999         } else {
4000             if (spe > 0 && spesgn == -1)
4001                 spe = 0;
4002         }
4003         if (spe > otmp->spe)
4004             spe = otmp->spe;
4005     }
4006
4007     if (spesgn == -1)
4008         spe = -spe;
4009
4010     /* set otmp->spe.  This may, or may not, use spe... */
4011     switch (typ) {
4012     case TIN:
4013         if (contents == EMPTY) {
4014             otmp->corpsenm = NON_PM;
4015             otmp->spe = 0;
4016         } else if (contents == SPINACH) {
4017             otmp->corpsenm = NON_PM;
4018             otmp->spe = 1;
4019         }
4020         break;
4021     case TOWEL:
4022         if (wetness)
4023             otmp->spe = wetness;
4024         break;
4025     case SLIME_MOLD:
4026         otmp->spe = ftype;
4027     /* Fall through */
4028     case SKELETON_KEY:
4029     case CHEST:
4030     case LARGE_BOX:
4031     case HEAVY_IRON_BALL:
4032     case IRON_CHAIN:
4033     case STATUE:
4034         /* otmp->cobj already done in mksobj() */
4035         break;
4036 #ifdef MAIL
4037     case SCR_MAIL:
4038         otmp->spe = 1;
4039         break;
4040 #endif
4041     case WAN_WISHING:
4042         if (!wizard) {
4043             otmp->spe = (rn2(10) ? -1 : 0);
4044             break;
4045         }
4046     /* fall through, if wizard */
4047     default:
4048         otmp->spe = spe;
4049     }
4050
4051     /* set otmp->corpsenm or dragon scale [mail] */
4052     if (mntmp >= LOW_PM) {
4053         if (mntmp == PM_LONG_WORM_TAIL)
4054             mntmp = PM_LONG_WORM;
4055
4056         switch (typ) {
4057         case TIN:
4058             otmp->spe = 0; /* No spinach */
4059             if (dead_species(mntmp, FALSE)) {
4060                 otmp->corpsenm = NON_PM; /* it's empty */
4061             } else if (!(mons[mntmp].geno & G_UNIQ)
4062                        && !(mvitals[mntmp].mvflags & G_NOCORPSE)
4063                        && mons[mntmp].cnutrit != 0) {
4064                 otmp->corpsenm = mntmp;
4065             }
4066             break;
4067         case CORPSE:
4068             if (!(mons[mntmp].geno & G_UNIQ)
4069                 && !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
4070                 if (mons[mntmp].msound == MS_GUARDIAN)
4071                     mntmp = genus(mntmp, 1);
4072                 set_corpsenm(otmp, mntmp);
4073             }
4074             break;
4075         case FIGURINE:
4076             if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4077 #ifdef MAIL
4078                 && mntmp != PM_MAIL_DAEMON
4079 #endif
4080                 )
4081                 otmp->corpsenm = mntmp;
4082             break;
4083         case EGG:
4084             mntmp = can_be_hatched(mntmp);
4085             /* this also sets hatch timer if appropriate */
4086             set_corpsenm(otmp, mntmp);
4087             break;
4088         case STATUE:
4089             otmp->corpsenm = mntmp;
4090             if (Has_contents(otmp) && verysmall(&mons[mntmp]))
4091                 delete_contents(otmp); /* no spellbook */
4092             otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
4093             break;
4094         case SCALE_MAIL:
4095             /* Dragon mail - depends on the order of objects & dragons. */
4096             if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON)
4097                 otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4098             break;
4099         }
4100     }
4101
4102     /* set blessed/cursed -- setting the fields directly is safe
4103      * since weight() is called below and addinv() will take care
4104      * of luck */
4105     if (iscursed) {
4106         curse(otmp);
4107     } else if (uncursed) {
4108         otmp->blessed = 0;
4109         otmp->cursed = (Luck < 0 && !wizard);
4110     } else if (blessed) {
4111         otmp->blessed = (Luck >= 0 || wizard);
4112         otmp->cursed = (Luck < 0 && !wizard);
4113     } else if (spesgn < 0) {
4114         curse(otmp);
4115     }
4116
4117     /* set eroded */
4118     if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
4119         if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
4120             otmp->oeroded = eroded;
4121         if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
4122             otmp->oeroded2 = eroded2;
4123
4124         /* set erodeproof */
4125         if (erodeproof && !eroded && !eroded2)
4126             otmp->oerodeproof = (Luck >= 0 || wizard);
4127     }
4128
4129     /* set otmp->recharged */
4130     if (oclass == WAND_CLASS) {
4131         /* prevent wishing abuse */
4132         if (otmp->otyp == WAN_WISHING && !wizard)
4133             rechrg = 1;
4134         otmp->recharged = (unsigned) rechrg;
4135     }
4136
4137     /* set poisoned */
4138     if (ispoisoned) {
4139         if (is_poisonable(otmp))
4140             otmp->opoisoned = (Luck >= 0);
4141         else if (oclass == FOOD_CLASS)
4142             /* try to taint by making it as old as possible */
4143             otmp->age = 1L;
4144     }
4145     /* and [un]trapped */
4146     if (trapped) {
4147         if (Is_box(otmp) || typ == TIN)
4148             otmp->otrapped = (trapped == 1);
4149     }
4150
4151     if (isgreased)
4152         otmp->greased = 1;
4153
4154     if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4155         otmp->odiluted = 1;
4156
4157     /* set tin variety */
4158     if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4159         set_tin_variety(otmp, tvariety);
4160
4161     if (name) {
4162         const char *aname;
4163         short objtyp;
4164
4165         /* an artifact name might need capitalization fixing */
4166         aname = artifact_name(name, &objtyp);
4167         if (aname && objtyp == otmp->otyp)
4168             name = aname;
4169
4170         /* 3.6.0 tribute - fix up novel */
4171         if (otmp->otyp == SPE_NOVEL) {
4172             const char *novelname;
4173
4174             novelname = lookup_novel(name, &otmp->novelidx);
4175             if (novelname)
4176                 name = novelname;
4177         }
4178
4179         otmp = oname(otmp, name);
4180         if (otmp->oartifact) {
4181             otmp->quan = 1L;
4182             u.uconduct.wisharti++; /* KMH, conduct */
4183         }
4184     }
4185
4186     /* more wishing abuse: don't allow wishing for certain artifacts */
4187     /* and make them pay; charge them for the wish anyway! */
4188     if ((is_quest_artifact(otmp)
4189          || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) {
4190         artifact_exists(otmp, safe_oname(otmp), FALSE);
4191         obfree(otmp, (struct obj *) 0);
4192         otmp = &zeroobj;
4193 /*JP
4194         pline("For a moment, you feel %s in your %s, but it disappears!",
4195 */
4196         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",
4197               something, makeplural(body_part(HAND)));
4198     }
4199
4200     if (halfeaten && otmp->oclass == FOOD_CLASS) {
4201         if (otmp->otyp == CORPSE)
4202             otmp->oeaten = mons[otmp->corpsenm].cnutrit;
4203         else
4204             otmp->oeaten = objects[otmp->otyp].oc_nutrition;
4205         /* (do this adjustment before setting up object's weight) */
4206         consume_oeaten(otmp, 1);
4207     }
4208     otmp->owt = weight(otmp);
4209     if (very && otmp->otyp == HEAVY_IRON_BALL)
4210         otmp->owt += 160;
4211
4212     return otmp;
4213 }
4214
4215 int
4216 rnd_class(first, last)
4217 int first, last;
4218 {
4219     int i, x, sum = 0;
4220
4221     if (first == last)
4222         return first;
4223     for (i = first; i <= last; i++)
4224         sum += objects[i].oc_prob;
4225     if (!sum) /* all zero */
4226         return first + rn2(last - first + 1);
4227     x = rnd(sum);
4228     for (i = first; i <= last; i++)
4229         if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
4230             return i;
4231     return 0;
4232 }
4233
4234 STATIC_OVL const char *
4235 Japanese_item_name(i)
4236 int i;
4237 {
4238     struct Jitem *j = Japanese_items;
4239
4240     while (j->item) {
4241         if (i == j->item)
4242             return j->name;
4243         j++;
4244     }
4245     return (const char *) 0;
4246 }
4247
4248 const char *
4249 suit_simple_name(suit)
4250 struct obj *suit;
4251 {
4252     const char *suitnm, *esuitp;
4253
4254     if (Is_dragon_mail(suit))
4255         return "dragon mail"; /* <color> dragon scale mail */
4256     else if (Is_dragon_scales(suit))
4257         return "dragon scales";
4258     suitnm = OBJ_NAME(objects[suit->otyp]);
4259     esuitp = eos((char *) suitnm);
4260     if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
4261         return "mail"; /* most suits fall into this category */
4262     else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
4263         return "jacket"; /* leather jacket */
4264     /* suit is lame but armor is ambiguous and body armor is absurd */
4265     return "suit";
4266 }
4267
4268 const char *
4269 cloak_simple_name(cloak)
4270 struct obj *cloak;
4271 {
4272     if (cloak) {
4273         switch (cloak->otyp) {
4274         case ROBE:
4275 /*JP
4276             return "robe";
4277 */
4278             return "\83\8d\81[\83u";
4279         case MUMMY_WRAPPING:
4280 /*JP
4281             return "wrapping";
4282 */
4283             return "\95ï\91Ñ";
4284         case ALCHEMY_SMOCK:
4285             return (objects[cloak->otyp].oc_name_known && cloak->dknown)
4286 /*JP
4287                        ? "smock"
4288 */
4289                        ? "\83X\83\82\83b\83N"
4290 /*JP
4291                        : "apron";
4292 */
4293                        : "\83G\83v\83\8d\83\93";
4294         default:
4295             break;
4296         }
4297     }
4298 /*JP
4299     return "cloak";
4300 */
4301     return "\83N\83\8d\81[\83N";
4302 }
4303
4304 /* helm vs hat for messages */
4305 const char *
4306 helm_simple_name(helmet)
4307 struct obj *helmet;
4308 {
4309     /*
4310      *  There is some wiggle room here; the result has been chosen
4311      *  for consistency with the "protected by hard helmet" messages
4312      *  given for various bonks on the head:  headgear that provides
4313      *  such protection is a "helm", that which doesn't is a "hat".
4314      *
4315      *      elven leather helm / leather hat    -> hat
4316      *      dwarvish iron helm / hard hat       -> helm
4317      *  The rest are completely straightforward:
4318      *      fedora, cornuthaum, dunce cap       -> hat
4319      *      all other types of helmets          -> helm
4320      */
4321 /*JP
4322     return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
4323 */
4324     return (helmet && !is_metallic(helmet)) ? "\96X\8eq" : "\8a\95";
4325 }
4326
4327 const char *
4328 mimic_obj_name(mtmp)
4329 struct monst *mtmp;
4330 {
4331     if (mtmp->m_ap_type == M_AP_OBJECT
4332         && mtmp->mappearance != STRANGE_OBJECT) {
4333         int idx = objects[mtmp->mappearance].oc_descr_idx;
4334         if (mtmp->mappearance == GOLD_PIECE)
4335 /*JP
4336             return "gold";
4337 */
4338             return "\8bà\89Ý";
4339         return obj_descr[idx].oc_name;
4340     }
4341 /*JP
4342     return "whatcha-may-callit";
4343 */
4344     return "\89½\82Æ\82©\82¢\82¤\82à\82Ì";
4345 }
4346
4347 /*
4348  * Construct a query prompt string, based around an object name, which is
4349  * guaranteed to fit within [QBUFSZ].  Takes an optional prefix, three
4350  * choices for filling in the middle (two object formatting functions and a
4351  * last resort literal which should be very short), and an optional suffix.
4352  */
4353 char *
4354 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
4355 char *qbuf; /* output buffer */
4356 const char *qprefix, *qsuffix;
4357 struct obj *obj;
4358 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
4359 const char *lastR;
4360 {
4361     char *bufp, *endp;
4362     /* convert size_t (or int for ancient systems) to ordinary unsigned */
4363     unsigned len, lenlimit,
4364         len_qpfx = (unsigned) (qprefix ? strlen(qprefix) : 0),
4365         len_qsfx = (unsigned) (qsuffix ? strlen(qsuffix) : 0),
4366         len_lastR = (unsigned) strlen(lastR);
4367
4368     lenlimit = QBUFSZ - 1;
4369     endp = qbuf + lenlimit;
4370     /* sanity check, aimed mainly at paniclog (it's conceivable for
4371        the result of short_oname() to be shorter than the length of
4372        the last resort string, but we ignore that possibility here) */
4373     if (len_qpfx > lenlimit)
4374         impossible("safe_qbuf: prefix too long (%u characters).", len_qpfx);
4375     else if (len_qpfx + len_qsfx > lenlimit)
4376         impossible("safe_qbuf: suffix too long (%u + %u characters).",
4377                    len_qpfx, len_qsfx);
4378     else if (len_qpfx + len_lastR + len_qsfx > lenlimit)
4379         impossible("safe_qbuf: filler too long (%u + %u + %u characters).",
4380                    len_qpfx, len_lastR, len_qsfx);
4381
4382     /* the output buffer might be the same as the prefix if caller
4383        has already partially filled it */
4384     if (qbuf == qprefix) {
4385         /* prefix is already in the buffer */
4386         *endp = '\0';
4387     } else if (qprefix) {
4388         /* put prefix into the buffer */
4389         (void) strncpy(qbuf, qprefix, lenlimit);
4390         *endp = '\0';
4391     } else {
4392         /* no prefix; output buffer starts out empty */
4393         qbuf[0] = '\0';
4394     }
4395     len = (unsigned) strlen(qbuf);
4396
4397     if (len + len_lastR + len_qsfx > lenlimit) {
4398         /* too long; skip formatting, last resort output is truncated */
4399         if (len < lenlimit) {
4400             (void) strncpy(&qbuf[len], lastR, lenlimit - len);
4401             *endp = '\0';
4402             len = (unsigned) strlen(qbuf);
4403             if (qsuffix && len < lenlimit) {
4404                 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
4405                 *endp = '\0';
4406                 /* len = (unsigned) strlen(qbuf); */
4407             }
4408         }
4409     } else {
4410         /* suffix and last resort are guaranteed to fit */
4411         len += len_qsfx; /* include the pending suffix */
4412         /* format the object */
4413         bufp = short_oname(obj, func, altfunc, lenlimit - len);
4414         if (len + strlen(bufp) <= lenlimit)
4415             Strcat(qbuf, bufp); /* formatted name fits */
4416         else
4417             Strcat(qbuf, lastR); /* use last resort */
4418         releaseobuf(bufp);
4419
4420         if (qsuffix)
4421             Strcat(qbuf, qsuffix);
4422     }
4423     /* assert( strlen(qbuf) < QBUFSZ ); */
4424     return qbuf;
4425 }
4426
4427 /*objnam.c*/