OSDN Git Service

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