OSDN Git Service

19de3c24abcf7f413843cceecc63620443a5dab8
[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             char anbuf[10];
767
768 #if 0 /*JP*/
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     char fruitbuf[BUFSZ], globbuf[BUFSZ];
3508     /* Fruits may not mess up the ability to wish for real objects (since
3509      * you can leave a fruit in a bones file and it will be added to
3510      * another person's game), so they must be checked for last, after
3511      * stripping all the possible prefixes and seeing if there's a real
3512      * name in there.  So we have to save the full original name.  However,
3513      * it's still possible to do things like "uncursed burnt Alaska",
3514      * or worse yet, "2 burned 5 course meals", so we need to loop to
3515      * strip off the prefixes again, this time stripping only the ones
3516      * possible on food.
3517      * We could get even more detailed so as to allow food names with
3518      * prefixes that _are_ possible on food, so you could wish for
3519      * "2 3 alarm chilis".  Currently this isn't allowed; options.c
3520      * automatically sticks 'candied' in front of such names.
3521      */
3522     char oclass;
3523     char *un, *dn, *actualn, *origbp = bp;
3524     const char *name = 0;
3525
3526     cnt = spe = spesgn = typ = 0;
3527     very = rechrg = blessed = uncursed = iscursed = ispoisoned =
3528         isgreased = eroded = eroded2 = erodeproof = halfeaten =
3529         islit = unlabeled = ishistoric = isdiluted = trapped =
3530         locked = unlocked = broken = 0;
3531     tvariety = RANDOM_TIN;
3532     mntmp = NON_PM;
3533 #define UNDEFINED 0
3534 #define EMPTY 1
3535 #define SPINACH 2
3536     contents = UNDEFINED;
3537     oclass = 0;
3538     actualn = dn = un = 0;
3539     wetness = 0;
3540
3541     if (!bp)
3542         goto any;
3543     /* first, remove extra whitespace they may have typed */
3544     (void) mungspaces(bp);
3545     /* allow wishing for "nothing" to preserve wishless conduct...
3546        [now requires "wand of nothing" if that's what was really wanted] */
3547 #if 0 /*JP*/
3548     if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil")
3549         || !strcmpi(bp, "none"))
3550 #else
3551     if (!strcmpi(bp, "\82È\82µ") || !strcmpi(bp, "\96³\82µ"))
3552 #endif
3553         return no_wish;
3554     /* save the [nearly] unmodified choice string */
3555     Strcpy(fruitbuf, bp);
3556
3557     for (;;) {
3558         register int l;
3559
3560         if (!bp || !*bp)
3561             goto any;
3562         if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) {
3563             cnt = 1;
3564         } else if (!strncmpi(bp, "the ", l = 4)) {
3565             ; /* just increment `bp' by `l' below */
3566         } else if (!cnt && digit(*bp) && strcmp(bp, "0")) {
3567             cnt = atoi(bp);
3568             while (digit(*bp))
3569                 bp++;
3570             while (*bp == ' ')
3571                 bp++;
3572             l = 0;
3573 #if 1 /*JP*//* \8cã\82É\90\94\8e\8c\82ª\82 \82é\82Æ\82«\82Í\8dí\8f\9c */
3574             if(!strncmp(bp, "\8dû\82Ì", l = 4) ||
3575                !strncmp(bp, "\96{\82Ì", l = 4) ||
3576                !strncmp(bp, "\92\85\82Ì", l = 4) ||
3577                !strncmp(bp, "\8cÂ\82Ì", l = 4) ||
3578                !strncmp(bp, "\96\87\82Ì", l = 4) ||
3579                !strncmp(bp, "\82Â\82Ì", l = 4) ||
3580                !strncmp(bp, "\82Ì", l = 2))
3581               ;
3582             else
3583               l = 0;
3584 #endif
3585         } else if (*bp == '+' || *bp == '-') {
3586             spesgn = (*bp++ == '+') ? 1 : -1;
3587             spe = atoi(bp);
3588             while (digit(*bp))
3589                 bp++;
3590             while (*bp == ' ')
3591                 bp++;
3592             l = 0;
3593 #if 0 /*JP*/
3594         } else if (!strncmpi(bp, "blessed ", l = 8)
3595                    || !strncmpi(bp, "holy ", l = 5)) {
3596 #else
3597         } else if (!strncmpi(bp, "\8fj\95\9f\82³\82ê\82½", l = 10)) {
3598 #endif
3599             blessed = 1;
3600 #if 0 /*JP*/
3601         } else if (!strncmpi(bp, "moist ", l = 6)
3602                    || !strncmpi(bp, "wet ", l = 4)) {
3603 #else
3604         } else if (!strncmpi(bp, "\8e¼\82Á\82½", l = 6)
3605                    || !strncmpi(bp, "\94G\82ê\82½", l = 6)) {
3606 #endif
3607 #if 0 /*JP*/
3608             if (!strncmpi(bp, "wet ", 4))
3609 #else
3610             if (!strncmpi(bp, "\94G\82ê\82½", 6))
3611 #endif
3612                 wetness = rn2(3) + 3;
3613             else
3614                 wetness = rnd(2);
3615 #if 0 /*JP*/
3616         } else if (!strncmpi(bp, "cursed ", l = 7)
3617                    || !strncmpi(bp, "unholy ", l = 7)) {
3618 #else
3619         } else if (!strncmpi(bp, "\8eô\82í\82ê\82½", l = 8)) {
3620 #endif
3621             iscursed = 1;
3622 #if 0 /*JP*/
3623         } else if (!strncmpi(bp, "uncursed ", l = 9)) {
3624 #else
3625         } else if (!strncmpi(bp, "\8eô\82í\82ê\82Ä\82¢\82È\82¢", l = 14)) {
3626 #endif
3627             uncursed = 1;
3628 #if 0 /*JP*/
3629         } else if (!strncmpi(bp, "rustproof ", l = 10)
3630                    || !strncmpi(bp, "erodeproof ", l = 11)
3631                    || !strncmpi(bp, "corrodeproof ", l = 13)
3632                    || !strncmpi(bp, "fixed ", l = 6)
3633                    || !strncmpi(bp, "fireproof ", l = 10)
3634                    || !strncmpi(bp, "rotproof ", l = 9)) {
3635 #else
3636         } else if (!strncmpi(bp, "\8eK\82Ñ\82È\82¢", l = 8)
3637                    || !strncmpi(bp, "\95\85\90H\82µ\82È\82¢", l = 10)
3638                    || !strncmpi(bp, "\88À\92è\82µ\82½", l = 8)
3639                    || !strncmpi(bp, "\94R\82¦\82È\82¢", l = 8)) {
3640 #endif
3641             erodeproof = 1;
3642 #if 0 /*JP*/
3643         } else if (!strncmpi(bp, "lit ", l = 4)
3644                    || !strncmpi(bp, "burning ", l = 8)) {
3645 #else
3646         } else if (!strncmpi(bp, "\8cõ\82Á\82Ä\82¢\82é", l = 10)
3647                    || !strncmpi(bp, "\94R\82¦\82Ä\82¢\82é", l = 10)) {
3648 #endif
3649             islit = 1;
3650 #if 0 /*JP*/
3651         } else if (!strncmpi(bp, "unlit ", l = 6)
3652                    || !strncmpi(bp, "extinguished ", l = 13)) {
3653 #else
3654         } else if (!strncmpi(bp, "\8fÁ\82¦\82Ä\82¢\82é", l = 10)) {
3655 #endif
3656             islit = 0;
3657             /* "unlabeled" and "blank" are synonymous */
3658 #if 0 /*JP*/
3659         } else if (!strncmpi(bp, "unlabeled ", l = 10)
3660                    || !strncmpi(bp, "unlabelled ", l = 11)
3661                    || !strncmpi(bp, "blank ", l = 6)) {
3662 #else
3663         } else if (!strncmpi(bp, "\83\89\83x\83\8b\82Ì\82È\82¢", l = 12)
3664                    || !strncmpi(bp, "\90^\82Á\94\92\82È", l = 8)) {
3665 #endif
3666             unlabeled = 1;
3667 #if 0 /*JP*/
3668         } else if (!strncmpi(bp, "poisoned ", l = 9)) {
3669 #else
3670         } else if (!strncmpi(bp, "\93Å\82Ì\93h\82ç\82ê\82½", l = 12)) {
3671 #endif
3672             ispoisoned = 1;
3673             /* "trapped" recognized but not honored outside wizard mode */
3674         } else if (!strncmpi(bp, "trapped ", l = 8)) {
3675             trapped = 0; /* undo any previous "untrapped" */
3676             if (wizard)
3677                 trapped = 1;
3678         } else if (!strncmpi(bp, "untrapped ", l = 10)) {
3679             trapped = 2; /* not trapped */
3680         /* locked, unlocked, broken: box/chest lock states */
3681 #if 0 /*JP*/
3682         } else if (!strncmpi(bp, "locked ", l = 7)) {
3683 #else
3684         } else if (!strncmpi(bp, "\8c®\82Ì\8a|\82©\82Á\82½", l = 12)) {
3685 #endif
3686             locked = 1, unlocked = broken = 0;
3687 #if 0 /*JP*/
3688         } else if (!strncmpi(bp, "unlocked ", l = 9)) {
3689 #else
3690         } else if (!strncmpi(bp, "\8c®\82Ì\8a|\82©\82Á\82Ä\82¢\82È\82¢", l = 18)) {
3691 #endif
3692             unlocked = 1, locked = broken = 0;
3693 #if 0 /*JP*/
3694         } else if (!strncmpi(bp, "broken ", l = 7)) {
3695 #else
3696         } else if (!strncmpi(bp, "\8c®\82Ì\89ó\82ê\82½", l = 10)) {
3697 #endif
3698             broken = 1, locked = unlocked = 0;
3699 #if 0 /*JP*/
3700         } else if (!strncmpi(bp, "greased ", l = 8)) {
3701 #else
3702         } else if (!strncmpi(bp, "\96û\82Ì\93h\82ç\82ê\82½", l = 12)
3703                    || !strncmpi(bp, "\8e\89\82Ì\93h\82ç\82ê\82½", l = 12)) {
3704 #endif
3705             isgreased = 1;
3706 #if 0 /*JP*/
3707         } else if (!strncmpi(bp, "very ", l = 5)) {
3708 #else
3709         } else if (!strncmpi(bp, "\82Æ\82Ä\82à", l = 6)) {
3710 #endif
3711             /* very rusted very heavy iron ball */
3712             very = 1;
3713 #if 0 /*JP*/
3714         } else if (!strncmpi(bp, "thoroughly ", l = 11)) {
3715 #else
3716         } else if (!strncmpi(bp, "\82©\82È\82è", l = 6)) {
3717 #endif
3718             very = 2;
3719 #if 0 /*JP*/
3720         } else if (!strncmpi(bp, "rusty ", l = 6)
3721                    || !strncmpi(bp, "rusted ", l = 7)
3722                    || !strncmpi(bp, "burnt ", l = 6)
3723                    || !strncmpi(bp, "burned ", l = 7)) {
3724 #else
3725         } else if (!strncmpi(bp, "\8eK\82Ñ\82½", l = 6)
3726                    || !strncmpi(bp, "\94R\82¦\82½", l = 6)) {
3727 #endif
3728             eroded = 1 + very;
3729             very = 0;
3730 #if 0 /*JP*/
3731         } else if (!strncmpi(bp, "corroded ", l = 9)
3732                    || !strncmpi(bp, "rotted ", l = 7)) {
3733 #else
3734         } else if (!strncmpi(bp, "\95\85\90H\82µ\82½", l = 8)
3735                    || !strncmpi(bp, "\95\85\82Á\82½", l = 6)) {
3736 #endif
3737             eroded2 = 1 + very;
3738             very = 0;
3739 #if 0 /*JP*/
3740         } else if (!strncmpi(bp, "partly eaten ", l = 13)
3741                    || !strncmpi(bp, "partially eaten ", l = 16)) {
3742 #else
3743         } else if (!strncmpi(bp, "\90H\82×\82©\82¯\82Ì", l = 10)) {
3744 #endif
3745             halfeaten = 1;
3746 #if 0 /*JP*/
3747         } else if (!strncmpi(bp, "historic ", l = 9)) {
3748 #else
3749         } else if (!strncmpi(bp, "\97ð\8ej\93I\82È", l = 8)) {
3750 #endif
3751             ishistoric = 1;
3752 #if 0 /*JP*/
3753         } else if (!strncmpi(bp, "diluted ", l = 8)) {
3754 #else
3755         } else if (!strncmpi(bp, "\94\96\82Ü\82Á\82½", l = 8)) {
3756 #endif
3757             isdiluted = 1;
3758 #if 0 /*JP*/
3759         } else if (!strncmpi(bp, "empty ", l = 6)) {
3760 #else
3761         } else if (!strncmpi(bp, "\8bó\82Á\82Û\82Ì", l = 8)) {
3762 #endif
3763             contents = EMPTY;
3764 #if 0 /*JP*/
3765         } else if (!strncmpi(bp, "small ", l = 6)) { /* glob sizes */
3766 #else
3767         } else if (!strncmpi(bp, "\8f¬\82³\82¢", l = 6)) { /* glob sizes */
3768 #endif
3769             /* "small" might be part of monster name (mimic, if wishing
3770                for its corpse) rather than prefix for glob size; when
3771                used for globs, it might be either "small glob of <foo>" or
3772                "small <foo> glob" and user might add 's' even though plural
3773                doesn't accomplish anything because globs don't stack */
3774             if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob"))
3775                 break;
3776             gsize = 1;
3777 #if 0 /*JP*/
3778         } else if (!strncmpi(bp, "medium ", l = 7)) {
3779 #else
3780         } else if (!strncmpi(bp, "\92\86\82­\82ç\82¢\82Ì", l = 10)) {
3781 #endif
3782             /* xname() doesn't display "medium" but without this
3783                there'd be no way to ask for the intermediate size
3784                ("glob" without size prefix yields smallest one) */
3785             gsize = 2;
3786 #if 0 /*JP*/
3787         } else if (!strncmpi(bp, "large ", l = 6)) {
3788 #else
3789         } else if (!strncmpi(bp, "\91å\82«\82¢", l = 6)) {
3790 #endif
3791             /* "large" might be part of monster name (dog, cat, koboold,
3792                mimic) or object name (box, round shield) rather than
3793                prefix for glob size */
3794             if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob"))
3795                 break;
3796             /* "very large " had "very " peeled off on previous iteration */
3797             gsize = (very != 1) ? 3 : 4;
3798         } else
3799             break;
3800         bp += l;
3801     }
3802     if (!cnt)
3803         cnt = 1; /* will be changed to 2 if makesingular() changes string */
3804     if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) {
3805         boolean keeptrailingchars = TRUE;
3806
3807         p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */
3808         ++p; /* advance past '(' */
3809         if (!strncmpi(p, "lit)", 4)) {
3810             islit = 1;
3811             p += 4 - 1; /* point at ')' */
3812         } else {
3813             spe = atoi(p);
3814             while (digit(*p))
3815                 p++;
3816             if (*p == ':') {
3817                 p++;
3818                 rechrg = spe;
3819                 spe = atoi(p);
3820                 while (digit(*p))
3821                     p++;
3822             }
3823             if (*p != ')') {
3824                 spe = rechrg = 0;
3825                 /* mis-matched parentheses; rest of string will be ignored
3826                  * [probably we should restore everything back to '('
3827                  * instead since it might be part of "named ..."]
3828                  */
3829                 keeptrailingchars = FALSE;
3830             } else {
3831                 spesgn = 1;
3832             }
3833         }
3834         if (keeptrailingchars) {
3835             char *pp = eos(bp);
3836
3837             /* 'pp' points at 'pb's terminating '\0',
3838                'p' points at ')' and will be incremented past it */
3839             do {
3840                 *pp++ = *++p;
3841             } while (*p);
3842         }
3843     }
3844     /*
3845      * otmp->spe is type schar, so we don't want spe to be any bigger or
3846      * smaller.  Also, spe should always be positive --some cheaters may
3847      * try to confuse atoi().
3848      */
3849     if (spe < 0) {
3850         spesgn = -1; /* cheaters get what they deserve */
3851         spe = abs(spe);
3852     }
3853     if (spe > SCHAR_LIM)
3854         spe = SCHAR_LIM;
3855     if (rechrg < 0 || rechrg > 7)
3856         rechrg = 7; /* recharge_limit */
3857
3858     /* now we have the actual name, as delivered by xname, say
3859      *  green potions called whisky
3860      *  scrolls labeled "QWERTY"
3861      *  egg
3862      *  fortune cookies
3863      *  very heavy iron ball named hoei
3864      *  wand of wishing
3865      *  elven cloak
3866      */
3867     if ((p = strstri(bp, " named ")) != 0) {
3868         *p = 0;
3869         name = p + 7;
3870     }
3871     if ((p = strstri(bp, " called ")) != 0) {
3872         *p = 0;
3873         un = p + 8;
3874 #if 0 /*JP*//*\83^\83C\83v\95Ê\82Í\82Æ\82è\82 \82¦\82¸\82µ\82È\82¢*/
3875         /* "helmet called telepathy" is not "helmet" (a specific type)
3876          * "shield called reflection" is not "shield" (a general type)
3877          */
3878         for (i = 0; i < SIZE(o_ranges); i++)
3879             if (!strcmpi(bp, o_ranges[i].name)) {
3880                 oclass = o_ranges[i].oclass;
3881                 goto srch;
3882             }
3883 #endif
3884     }
3885     if ((p = strstri(bp, " labeled ")) != 0) {
3886         *p = 0;
3887         dn = p + 9;
3888     } else if ((p = strstri(bp, " labelled ")) != 0) {
3889         *p = 0;
3890         dn = p + 10;
3891     }
3892     if ((p = strstri(bp, " of spinach")) != 0) {
3893         *p = 0;
3894         contents = SPINACH;
3895     }
3896
3897 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\8f\88\97\9d\82µ\82È\82¢*/
3898     /*
3899      * Skip over "pair of ", "pairs of", "set of" and "sets of".
3900      *
3901      * Accept "3 pair of boots" as well as "3 pairs of boots".  It is
3902      * valid English either way.  See makeplural() for more on pair/pairs.
3903      *
3904      * We should only double count if the object in question is not
3905      * referred to as a "pair of".  E.g. We should double if the player
3906      * types "pair of spears", but not if the player types "pair of
3907      * lenses".  Luckily (?) all objects that are referred to as pairs
3908      * -- boots, gloves, and lenses -- are also not mergable, so cnt is
3909      * ignored anyway.
3910      */
3911     if (!strncmpi(bp, "pair of ", 8)) {
3912         bp += 8;
3913         cnt *= 2;
3914     } else if (!strncmpi(bp, "pairs of ", 9)) {
3915         bp += 9;
3916         if (cnt > 1)
3917             cnt *= 2;
3918     } else if (!strncmpi(bp, "set of ", 7)) {
3919         bp += 7;
3920     } else if (!strncmpi(bp, "sets of ", 8)) {
3921         bp += 8;
3922     }
3923 #endif
3924
3925 #if 0 /*JP*/
3926     /* intercept pudding globs here; they're a valid wish target,
3927      * but we need them to not get treated like a corpse.
3928      *
3929      * also don't let player wish for multiple globs.
3930      */
3931     i = (int) strlen(bp);
3932     p = (char *) 0;
3933     /* check for "glob", "<foo> glob", and "glob of <foo>" */
3934     if (!strcmpi(bp, "glob") || !BSTRCMPI(bp, bp + i - 5, " glob")
3935         || !strcmpi(bp, "globs") || !BSTRCMPI(bp, bp + i - 6, " globs")
3936         || (p = strstri(bp, "glob of ")) != 0
3937         || (p = strstri(bp, "globs of ")) != 0) {
3938         mntmp = name_to_mon(!p ? bp : (strstri(p, " of ") + 4));
3939         /* if we didn't recognize monster type, pick a valid one at random */
3940         if (mntmp == NON_PM)
3941             mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE);
3942         /* construct canonical spelling in case name_to_mon() recognized a
3943            variant (grey ooze) or player used inverted syntax (<foo> glob);
3944            if player has given a valid monster type but not valid glob type,
3945            object name lookup won't find it and wish attempt will fail */
3946         Sprintf(globbuf, "glob of %s", mons[mntmp].mname);
3947         bp = globbuf;
3948         mntmp = NON_PM; /* not useful for "glob of <foo>" object lookup */
3949         cnt = 0; /* globs don't stack */
3950         oclass = FOOD_CLASS;
3951         actualn = bp, dn = 0;
3952         goto srch;
3953     } else {
3954         /*
3955          * Find corpse type using "of" (figurine of an orc, tin of orc meat)
3956          * Don't check if it's a wand or spellbook.
3957          * (avoid "wand/finger of death" confusion).
3958          */
3959         if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ")
3960             && !strstri(bp, "finger ")) {
3961             if ((p = strstri(bp, "tin of ")) != 0) {
3962                 if (!strcmpi(p + 7, "spinach")) {
3963                     contents = SPINACH;
3964                     mntmp = NON_PM;
3965                 } else {
3966                     tmp = tin_variety_txt(p + 7, &tinv);
3967                     tvariety = tinv;
3968                     mntmp = name_to_mon(p + 7 + tmp);
3969                 }
3970                 typ = TIN;
3971                 goto typfnd;
3972             } else if ((p = strstri(bp, " of ")) != 0
3973                        && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
3974                 *p = 0;
3975         }
3976     }
3977     /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
3978     if (strncmpi(bp, "samurai sword", 13)  /* not the "samurai" monster! */
3979         && strncmpi(bp, "wizard lock", 11) /* not the "wizard" monster! */
3980         && strncmpi(bp, "ninja-to", 8)     /* not the "ninja" rank */
3981         && strncmpi(bp, "master key", 10)  /* not the "master" rank */
3982         && strncmpi(bp, "magenta", 7)) {   /* not the "mage" rank */
3983         if (mntmp < LOW_PM && strlen(bp) > 2
3984             && (mntmp = name_to_mon(bp)) >= LOW_PM) {
3985             int mntmptoo, mntmplen; /* double check for rank title */
3986             char *obp = bp;
3987
3988             mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
3989             bp += (mntmp != mntmptoo) ? (int) strlen(mons[mntmp].mname)
3990                                       : mntmplen;
3991             if (*bp == ' ') {
3992                 bp++;
3993             } else if (!strncmpi(bp, "s ", 2)) {
3994                 bp += 2;
3995             } else if (!strncmpi(bp, "es ", 3)) {
3996                 bp += 3;
3997             } else if (!*bp && !actualn && !dn && !un && !oclass) {
3998                 /* no referent; they don't really mean a monster type */
3999                 bp = obp;
4000                 mntmp = NON_PM;
4001             }
4002         }
4003     }
4004 #else
4005     {
4006         /*JP \81u(\89ö\95¨\96¼)\82Ì\89ò\81v\82Í\8cÂ\81X\82ÉID\82ª\82 \82é\82Ì\82Å\95Ê\88µ\82¢ */
4007         int l = strlen(bp);
4008         if (l > 4 && strncmp(bp + l - 4, "\82Ì\89ò", 4) == 0) {
4009             if ((mntmp = name_to_mon(bp)) >= PM_GRAY_OOZE
4010                 && mntmp <= PM_BLACK_PUDDING) {
4011                 mntmp = NON_PM; /* lie to ourselves */
4012                 cnt = 0;        /* force only one */
4013             }
4014         } else {
4015             /*JP:\81u(\89ö\95¨\96¼)\82Ì(\83A\83C\83e\83\80)\81v\91Î\89\9e */
4016             if ((mntmp = name_to_mon(bp)) >= LOW_PM) {
4017                 const char *mp = mons[mntmp].mname;
4018                 bp = strstri(bp, mp) + strlen(mp) + 2;
4019             }
4020         }
4021     }
4022 #endif
4023
4024 #if 0 /*JP*//*\92P\90\94\89»\82Í\82µ\82È\82¢*/
4025     /* first change to singular if necessary */
4026     if (*bp) {
4027         char *sng = makesingular(bp);
4028
4029         if (strcmp(bp, sng)) {
4030             if (cnt == 1)
4031                 cnt = 2;
4032             Strcpy(bp, sng);
4033         }
4034     }
4035 #endif
4036
4037 #if 0 /*JP*//*\83X\83y\83\8b\97h\82ê\8f\88\97\9d\82Í\82µ\82È\82¢*/
4038     /* Alternate spellings (pick-ax, silver sabre, &c) */
4039     {
4040         const struct alt_spellings *as = spellings;
4041
4042         while (as->sp) {
4043             if (fuzzymatch(bp, as->sp, " -", TRUE)) {
4044                 typ = as->ob;
4045                 goto typfnd;
4046             }
4047             as++;
4048         }
4049         /* can't use spellings list for this one due to shuffling */
4050         if (!strncmpi(bp, "grey spell", 10))
4051             *(bp + 2) = 'a';
4052
4053         if ((p = strstri(bp, "armour")) != 0) {
4054             /* skip past "armo", then copy remainder beyond "u" */
4055             p += 4;
4056             while ((*p = *(p + 1)) != '\0')
4057                 ++p; /* self terminating */
4058         }
4059     }
4060 #endif
4061
4062 #if 0 /*JP*/
4063     /* dragon scales - assumes order of dragons */
4064     if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON
4065         && mntmp <= PM_YELLOW_DRAGON) {
4066         typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
4067         mntmp = NON_PM; /* no monster */
4068         goto typfnd;
4069     }
4070 #else
4071     /*JP: \81u\97Ø\8aZ\81v\82ð\90æ\82É\8f\88\97\9d\82µ\82Ä\82¨\82­ */
4072     if (!strcmpi(bp, "\97Ø\8aZ") && mntmp >= PM_GRAY_DRAGON
4073         && mntmp <= PM_YELLOW_DRAGON) {
4074         typ = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4075         mntmp = NON_PM; /* no monster */
4076         goto typfnd;
4077     }
4078
4079     if (!strcmpi(bp, "\97Ø") && mntmp >= PM_GRAY_DRAGON
4080         && mntmp <= PM_YELLOW_DRAGON) {
4081         typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
4082         mntmp = NON_PM; /* no monster */
4083         goto typfnd;
4084     }
4085 #endif
4086
4087     p = eos(bp);
4088 #if 0 /*JP*/
4089     if (!BSTRCMPI(bp, p - 10, "holy water")) {
4090         typ = POT_WATER;
4091         if ((p - bp) >= 12 && *(p - 12) == 'u')
4092             iscursed = 1; /* unholy water */
4093         else
4094             blessed = 1;
4095         goto typfnd;
4096     }
4097 #else /*JP:\90¹\90\85\82Æ\95s\8fò\82È\90\85\82ð\95Ê\82É\94»\92è*/
4098     if (!BSTRCMPI(bp, p - 4, "\90¹\90\85")) {
4099         typ = POT_WATER;
4100         blessed = 1;
4101         goto typfnd;
4102     }
4103     if (!BSTRCMPI(bp, p - 8, "\95s\8fò\82È\90\85")) {
4104         typ = POT_WATER;
4105         iscursed = 1;
4106         goto typfnd;
4107     }
4108 #endif
4109 #if 0 /*JP*/
4110     if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
4111 #else
4112     if (unlabeled && !BSTRCMPI(bp, p - 4, "\8aª\95¨")) {
4113 #endif
4114         typ = SCR_BLANK_PAPER;
4115         goto typfnd;
4116     }
4117 #if 0 /*JP*/
4118     if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
4119 #else
4120     if (unlabeled && !BSTRCMPI(bp, p - 6, "\96\82\96@\8f\91")) {
4121 #endif
4122         typ = SPE_BLANK_PAPER;
4123         goto typfnd;
4124     }
4125     /* specific food rather than color of gem/potion/spellbook[/scales] */
4126     if (!BSTRCMPI(bp, p - 6, "orange") && mntmp == NON_PM) {
4127         typ = ORANGE;
4128         goto typfnd;
4129     }
4130     /*
4131      * NOTE: Gold pieces are handled as objects nowadays, and therefore
4132      * this section should probably be reconsidered as well as the entire
4133      * gold/money concept.  Maybe we want to add other monetary units as
4134      * well in the future. (TH)
4135      */
4136 #if 0 /*JP*/
4137     if (!BSTRCMPI(bp, p - 10, "gold piece")
4138         || !BSTRCMPI(bp, p - 7, "zorkmid")
4139         || !strcmpi(bp, "gold") || !strcmpi(bp, "money")
4140         || !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
4141 #else
4142     if (!BSTRCMPI(bp, p - 4, "\8bà\89Ý") || !BSTRCMPI(bp, p - 8, "\83S\81[\83\8b\83h")
4143         || *bp == GOLD_SYM) {
4144 #endif
4145         if (cnt > 5000 && !wizard)
4146             cnt = 5000;
4147         else if (cnt < 1)
4148             cnt = 1;
4149         otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
4150         otmp->quan = (long) cnt;
4151         otmp->owt = weight(otmp);
4152         context.botl = 1;
4153         return otmp;
4154     }
4155
4156     /* check for single character object class code ("/" for wand, &c) */
4157     if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES
4158         && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
4159         oclass = i;
4160         goto any;
4161     }
4162
4163 #if 0 /*JP*/
4164     /*JP
4165       \89p\8cê\82È\82ç XXXXX potion \82Í\95s\8am\92è\96¼\81Apotion of XXXXX \82Í\8am\92è\96¼\82Æ\82¢\82¤
4166       \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¢
4167       */
4168     /* Search for class names: XXXXX potion, scroll of XXXXX.  Avoid */
4169     /* false hits on, e.g., rings for "ring mail". */
4170     if (strncmpi(bp, "enchant ", 8)
4171         && strncmpi(bp, "destroy ", 8)
4172         && strncmpi(bp, "detect food", 11)
4173         && strncmpi(bp, "food detection", 14)
4174         && strncmpi(bp, "ring mail", 9)
4175         && strncmpi(bp, "studded leather armor", 21)
4176         && strncmpi(bp, "leather armor", 13)
4177         && strncmpi(bp, "tooled horn", 11)
4178         && strncmpi(bp, "food ration", 11)
4179         && strncmpi(bp, "meat ring", 9))
4180         for (i = 0; i < (int) (sizeof wrpsym); i++) {
4181             register int j = strlen(wrp[i]);
4182
4183             if (!strncmpi(bp, wrp[i], j)) {
4184                 oclass = wrpsym[i];
4185                 if (oclass != AMULET_CLASS) {
4186                     bp += j;
4187                     if (!strncmpi(bp, " of ", 4))
4188                         actualn = bp + 4;
4189                     /* else if(*bp) ?? */
4190                 } else
4191                     actualn = bp;
4192                 goto srch;
4193             }
4194             if (!BSTRCMPI(bp, p - j, wrp[i])) {
4195                 oclass = wrpsym[i];
4196                 p -= j;
4197                 *p = 0;
4198                 if (p > bp && p[-1] == ' ')
4199                     p[-1] = 0;
4200                 actualn = dn = bp;
4201                 goto srch;
4202             }
4203         }
4204 #endif
4205
4206     /* Wishing in wizard mode can create traps and furniture.
4207      * Part I:  distinguish between trap and object for the two
4208      * types of traps which have corresponding objects:  bear trap
4209      * and land mine.  "beartrap" (object) and "bear trap" (trap)
4210      * have a difference in spelling which we used to exploit by
4211      * adding a special case in wishymatch(), but "land mine" is
4212      * spelled the same either way so needs different handing.
4213      * Since we need something else for land mine, we've dropped
4214      * the bear trap hack so that both are handled exactly the
4215      * same.  To get an armed trap instead of a disarmed object,
4216      * the player can prefix either the object name or the trap
4217      * name with "trapped " (which ordinarily applies to chests
4218      * and tins), or append something--anything at all except for
4219      * " object", but " trap" is suggested--to either the trap
4220      * name or the object name.
4221      */
4222     if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
4223         boolean beartrap = (lowc(*bp) == 'b');
4224         char *zp = bp + 4; /* skip "bear"/"land" */
4225
4226         if (*zp == ' ')
4227             ++zp; /* embedded space is optional */
4228         if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
4229             zp += 4;
4230             if (trapped == 2 || !strcmpi(zp, " object")) {
4231                 /* "untrapped <foo>" or "<foo> object" */
4232                 typ = beartrap ? BEARTRAP : LAND_MINE;
4233                 goto typfnd;
4234             } else if (trapped == 1 || *zp != '\0') {
4235                 /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
4236                 int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
4237
4238                 /* use canonical trap spelling, skip object matching */
4239                 Strcpy(bp, defsyms[idx].explanation);
4240                 goto wiztrap;
4241             }
4242             /* [no prefix or suffix; we're going to end up matching
4243                the object name and getting a disarmed trap object] */
4244         }
4245     }
4246
4247 #if 0 /*JP*//* mail/armor\8aÖ\98A\82Å\82Ì\82Ý\8eg\82¤\83\89\83x\83\8b */
4248  retry:
4249 #endif
4250 #if 0 /*JP*//* \83^\83C\83v\95Ê\82Í\82Æ\82è\82 \82¦\82¸\82µ\82È\82¢ */
4251     /* "grey stone" check must be before general "stone" */
4252     for (i = 0; i < SIZE(o_ranges); i++)
4253         if (!strcmpi(bp, o_ranges[i].name)) {
4254             typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
4255             goto typfnd;
4256         }
4257 #endif
4258
4259 #if 0 /*JP*//* \90Î\82Ì\93Á\95Ê\8f\88\97\9d\82Í\95s\97v */
4260     if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) {
4261         p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0';
4262         oclass = GEM_CLASS;
4263         dn = actualn = bp;
4264         goto srch;
4265     } else if (!strcmpi(bp, "looking glass")) {
4266         ; /* avoid false hit on "* glass" */
4267     } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) {
4268         register char *g = bp;
4269
4270         /* treat "broken glass" as a non-existent item; since "broken" is
4271            also a chest/box prefix it might have been stripped off above */
4272         if (broken || strstri(g, "broken"))
4273             return (struct obj *) 0;
4274         if (!strncmpi(g, "worthless ", 10))
4275             g += 10;
4276         if (!strncmpi(g, "piece of ", 9))
4277             g += 9;
4278         if (!strncmpi(g, "colored ", 8))
4279             g += 8;
4280         else if (!strncmpi(g, "coloured ", 9))
4281             g += 9;
4282         if (!strcmpi(g, "glass")) { /* choose random color */
4283             /* 9 different kinds */
4284             typ = LAST_GEM + rnd(9);
4285             if (objects[typ].oc_class == GEM_CLASS)
4286                 goto typfnd;
4287             else
4288                 typ = 0; /* somebody changed objects[]? punt */
4289         } else { /* try to construct canonical form */
4290             char tbuf[BUFSZ];
4291
4292             Strcpy(tbuf, "worthless piece of ");
4293             Strcat(tbuf, g); /* assume it starts with the color */
4294             Strcpy(bp, tbuf);
4295         }
4296     }
4297 #endif
4298
4299     actualn = bp;
4300     if (!dn)
4301         dn = actualn; /* ex. "skull cap" */
4302 #if 0 /*JP*/
4303  srch:
4304 #endif
4305     /* check real names of gems first */
4306     if (!oclass && actualn) {
4307         for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
4308             register const char *zn;
4309
4310             if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(actualn, zn)) {
4311                 typ = i;
4312                 goto typfnd;
4313             }
4314         }
4315 #if 0 /*JP*//* \93ú\96{\8cê\82Í"tin"\82ð\96ó\82µ\95ª\82¯\82Ä\82¢\82é\82Ì\82Å\95s\97v */
4316         /* "tin of foo" would be caught above, but plain "tin" has
4317            a random chance of yielding "tin wand" unless we do this */
4318         if (!strcmpi(actualn, "tin")) {
4319             typ = TIN;
4320             goto typfnd;
4321         }
4322 #endif
4323     }
4324
4325     if (((typ = rnd_otyp_by_namedesc(actualn, oclass, 1)) != STRANGE_OBJECT)
4326         || ((typ = rnd_otyp_by_namedesc(dn, oclass, 1)) != STRANGE_OBJECT)
4327         || ((typ = rnd_otyp_by_namedesc(un, oclass, 1)) != STRANGE_OBJECT)
4328         || ((typ = rnd_otyp_by_namedesc(origbp, oclass, 1)) != STRANGE_OBJECT))
4329         goto typfnd;
4330     typ = 0;
4331
4332     if (actualn) {
4333         struct Jitem *j = Japanese_items;
4334
4335         while (j->item) {
4336             if (actualn && !strcmpi(actualn, j->name)) {
4337                 typ = j->item;
4338                 goto typfnd;
4339             }
4340             j++;
4341         }
4342     }
4343 #if 0 /*JP*//* mail/armor\82Ì\95\\8bL\97h\82ê\83`\83F\83b\83N\82Í\95s\97v */
4344     /* if we've stripped off "armor" and failed to match anything
4345        in objects[], append "mail" and try again to catch misnamed
4346        requests like "plate armor" and "yellow dragon scale armor" */
4347     if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
4348         /* modifying bp's string is ok; we're about to resort
4349            to random armor if this also fails to match anything */
4350         Strcat(bp, " mail");
4351         goto retry;
4352     }
4353 #endif
4354 #if 0 /*JP*/
4355     if (!strcmpi(bp, "spinach")) {
4356 #else
4357     if (!strcmp(bp, "\83z\83E\83\8c\83\93\91\90")) {
4358 #endif
4359         contents = SPINACH;
4360         typ = TIN;
4361         goto typfnd;
4362     }
4363     /* Note: not strcmpi.  2 fruits, one capital, one not, are possible.
4364        Also not strncmp.  We used to ignore trailing text with it, but
4365        that resulted in "grapefruit" matching "grape" if the latter came
4366        earlier than the former in the fruit list. */
4367     {
4368         char *fp;
4369         int l, cntf;
4370         int blessedf, iscursedf, uncursedf, halfeatenf;
4371
4372         blessedf = iscursedf = uncursedf = halfeatenf = 0;
4373         cntf = 0;
4374
4375         fp = fruitbuf;
4376         for (;;) {
4377             if (!fp || !*fp)
4378                 break;
4379             if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
4380                 cntf = 1;
4381             } else if (!cntf && digit(*fp)) {
4382                 cntf = atoi(fp);
4383                 while (digit(*fp))
4384                     fp++;
4385                 while (*fp == ' ')
4386                     fp++;
4387                 l = 0;
4388             } else if (!strncmpi(fp, "blessed ", l = 8)) {
4389                 blessedf = 1;
4390             } else if (!strncmpi(fp, "cursed ", l = 7)) {
4391                 iscursedf = 1;
4392             } else if (!strncmpi(fp, "uncursed ", l = 9)) {
4393                 uncursedf = 1;
4394             } else if (!strncmpi(fp, "partly eaten ", l = 13)
4395                        || !strncmpi(fp, "partially eaten ", l = 16)) {
4396                 halfeatenf = 1;
4397             } else
4398                 break;
4399             fp += l;
4400         }
4401
4402         for (f = ffruit; f; f = f->nextf) {
4403             /* match type: 0=none, 1=exact, 2=singular, 3=plural */
4404             int ftyp = 0;
4405
4406             if (!strcmp(fp, f->fname))
4407                 ftyp = 1;
4408             else if (!strcmp(fp, makesingular(f->fname)))
4409                 ftyp = 2;
4410             else if (!strcmp(fp, makeplural(f->fname)))
4411                 ftyp = 3;
4412             if (ftyp) {
4413                 typ = SLIME_MOLD;
4414                 blessed = blessedf;
4415                 iscursed = iscursedf;
4416                 uncursed = uncursedf;
4417                 halfeaten = halfeatenf;
4418                 /* adjust count if user explicitly asked for
4419                    singular amount (can't happen unless fruit
4420                    has been given an already pluralized name)
4421                    or for plural amount */
4422                 if (ftyp == 2 && !cntf)
4423                     cntf = 1;
4424                 else if (ftyp == 3 && !cntf)
4425                     cntf = 2;
4426                 cnt = cntf;
4427                 ftype = f->fid;
4428                 goto typfnd;
4429             }
4430         }
4431     }
4432
4433     if (!oclass && actualn) {
4434         short objtyp;
4435
4436         /* Perhaps it's an artifact specified by name, not type */
4437         name = artifact_name(actualn, &objtyp);
4438         if (name) {
4439             typ = objtyp;
4440             goto typfnd;
4441         }
4442     }
4443 /* Let wizards wish for traps and furniture.
4444  * Must come after objects check so wizards can still wish for
4445  * trap objects like beartraps.
4446  * Disallow such topology tweaks for WIZKIT startup wishes.
4447  */
4448  wiztrap:
4449     if (wizard && !program_state.wizkit_wishing) {
4450         struct rm *lev;
4451         int trap, x = u.ux, y = u.uy;
4452
4453         for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
4454             struct trap *t;
4455             const char *tname;
4456
4457             tname = defsyms[trap_to_defsym(trap)].explanation;
4458             if (strncmpi(tname, bp, strlen(tname)))
4459                 continue;
4460             /* found it; avoid stupid mistakes */
4461             if (is_hole(trap) && !Can_fall_thru(&u.uz))
4462                 trap = ROCKTRAP;
4463             if ((t = maketrap(x, y, trap)) != 0) {
4464                 trap = t->ttyp;
4465                 tname = defsyms[trap_to_defsym(trap)].explanation;
4466                 pline("%s%s.", An(tname),
4467                       (trap != MAGIC_PORTAL) ? "" : " to nowhere");
4468             } else
4469                 pline("Creation of %s failed.", an(tname));
4470             return (struct obj *) &zeroobj;
4471         }
4472
4473         /* furniture and terrain */
4474         lev = &levl[x][y];
4475         p = eos(bp);
4476         if (!BSTRCMPI(bp, p - 8, "fountain")) {
4477             lev->typ = FOUNTAIN;
4478             level.flags.nfountains++;
4479             if (!strncmpi(bp, "magic ", 6))
4480                 lev->blessedftn = 1;
4481             pline("A %sfountain.", lev->blessedftn ? "magic " : "");
4482             newsym(x, y);
4483             return (struct obj *) &zeroobj;
4484         }
4485         if (!BSTRCMPI(bp, p - 6, "throne")) {
4486             lev->typ = THRONE;
4487             pline("A throne.");
4488             newsym(x, y);
4489             return (struct obj *) &zeroobj;
4490         }
4491         if (!BSTRCMPI(bp, p - 4, "sink")) {
4492             lev->typ = SINK;
4493             level.flags.nsinks++;
4494             pline("A sink.");
4495             newsym(x, y);
4496             return (struct obj *) &zeroobj;
4497         }
4498         /* ("water" matches "potion of water" rather than terrain) */
4499         if (!BSTRCMPI(bp, p - 4, "pool") || !BSTRCMPI(bp, p - 4, "moat")) {
4500             lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
4501             del_engr_at(x, y);
4502             pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
4503             /* Must manually make kelp! */
4504             water_damage_chain(level.objects[x][y], TRUE);
4505             newsym(x, y);
4506             return (struct obj *) &zeroobj;
4507         }
4508         if (!BSTRCMPI(bp, p - 4, "lava")) { /* also matches "molten lava" */
4509             lev->typ = LAVAPOOL;
4510             del_engr_at(x, y);
4511             pline("A pool of molten lava.");
4512             if (!(Levitation || Flying))
4513                 (void) lava_effects();
4514             newsym(x, y);
4515             return (struct obj *) &zeroobj;
4516         }
4517
4518         if (!BSTRCMPI(bp, p - 5, "altar")) {
4519             aligntyp al;
4520
4521             lev->typ = ALTAR;
4522             if (!strncmpi(bp, "chaotic ", 8))
4523                 al = A_CHAOTIC;
4524             else if (!strncmpi(bp, "neutral ", 8))
4525                 al = A_NEUTRAL;
4526             else if (!strncmpi(bp, "lawful ", 7))
4527                 al = A_LAWFUL;
4528             else if (!strncmpi(bp, "unaligned ", 10))
4529                 al = A_NONE;
4530             else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
4531                 al = (!rn2(6)) ? A_NONE : rn2((int) A_LAWFUL + 2) - 1;
4532             lev->altarmask = Align2amask(al);
4533             pline("%s altar.", An(align_str(al)));
4534             newsym(x, y);
4535             return (struct obj *) &zeroobj;
4536         }
4537
4538         if (!BSTRCMPI(bp, p - 5, "grave")
4539             || !BSTRCMPI(bp, p - 9, "headstone")) {
4540             make_grave(x, y, (char *) 0);
4541             pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
4542                                             : "Can't place a grave here");
4543             newsym(x, y);
4544             return (struct obj *) &zeroobj;
4545         }
4546
4547         if (!BSTRCMPI(bp, p - 4, "tree")) {
4548             lev->typ = TREE;
4549             pline("A tree.");
4550             newsym(x, y);
4551             block_point(x, y);
4552             return (struct obj *) &zeroobj;
4553         }
4554
4555         if (!BSTRCMPI(bp, p - 4, "bars")) {
4556             lev->typ = IRONBARS;
4557             pline("Iron bars.");
4558             newsym(x, y);
4559             return (struct obj *) &zeroobj;
4560         }
4561     }
4562
4563 #if 0 /*JP*//* \83^\83C\83v\95Ê\82Í\82Æ\82è\82 \82¦\82¸\82µ\82È\82¢ */
4564     if (!oclass && !typ) {
4565         if (!strncmpi(bp, "polearm", 7)) {
4566             typ = rnd_otyp_by_wpnskill(P_POLEARMS);
4567             goto typfnd;
4568         } else if (!strncmpi(bp, "hammer", 6)) {
4569             typ = rnd_otyp_by_wpnskill(P_HAMMER);
4570             goto typfnd;
4571         }
4572     }
4573 #endif
4574
4575     if (!oclass)
4576         return ((struct obj *) 0);
4577  any:
4578     if (!oclass)
4579         oclass = wrpsym[rn2((int) sizeof wrpsym)];
4580  typfnd:
4581     if (typ)
4582         oclass = objects[typ].oc_class;
4583
4584     /* handle some objects that are only allowed in wizard mode */
4585     if (typ && !wizard) {
4586         switch (typ) {
4587         case AMULET_OF_YENDOR:
4588             typ = FAKE_AMULET_OF_YENDOR;
4589             break;
4590         case CANDELABRUM_OF_INVOCATION:
4591             typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
4592             break;
4593         case BELL_OF_OPENING:
4594             typ = BELL;
4595             break;
4596         case SPE_BOOK_OF_THE_DEAD:
4597             typ = SPE_BLANK_PAPER;
4598             break;
4599         case MAGIC_LAMP:
4600             typ = OIL_LAMP;
4601             break;
4602         default:
4603             /* catch any other non-wishable objects (venom) */
4604             if (objects[typ].oc_nowish)
4605                 return (struct obj *) 0;
4606             break;
4607         }
4608     }
4609
4610     /*
4611      * Create the object, then fine-tune it.
4612      */
4613     otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
4614     typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
4615
4616     if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN
4617                   || Is_candle(otmp) || typ == POT_OIL)) {
4618         place_object(otmp, u.ux, u.uy); /* make it viable light source */
4619         begin_burn(otmp, FALSE);
4620         obj_extract_self(otmp); /* now release it for caller's use */
4621     }
4622
4623     /* if player specified a reasonable count, maybe honor it */
4624     if (cnt > 0 && objects[typ].oc_merge
4625         && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp))
4626             || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp))
4627                               || typ == ROCK || is_missile(otmp)))))
4628         otmp->quan = (long) cnt;
4629
4630     if (oclass == VENOM_CLASS)
4631         otmp->spe = 1;
4632
4633     if (spesgn == 0) {
4634         spe = otmp->spe;
4635     } else if (wizard) {
4636         ; /* no alteration to spe */
4637     } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
4638                || is_weptool(otmp)
4639                || (oclass == RING_CLASS && objects[typ].oc_charged)) {
4640         if (spe > rnd(5) && spe > otmp->spe)
4641             spe = 0;
4642         if (spe > 2 && Luck < 0)
4643             spesgn = -1;
4644     } else {
4645         if (oclass == WAND_CLASS) {
4646             if (spe > 1 && spesgn == -1)
4647                 spe = 1;
4648         } else {
4649             if (spe > 0 && spesgn == -1)
4650                 spe = 0;
4651         }
4652         if (spe > otmp->spe)
4653             spe = otmp->spe;
4654     }
4655
4656     if (spesgn == -1)
4657         spe = -spe;
4658
4659     /* set otmp->spe.  This may, or may not, use spe... */
4660     switch (typ) {
4661     case TIN:
4662         if (contents == EMPTY) {
4663             otmp->corpsenm = NON_PM;
4664             otmp->spe = 0;
4665         } else if (contents == SPINACH) {
4666             otmp->corpsenm = NON_PM;
4667             otmp->spe = 1;
4668         }
4669         break;
4670     case TOWEL:
4671         if (wetness)
4672             otmp->spe = wetness;
4673         break;
4674     case SLIME_MOLD:
4675         otmp->spe = ftype;
4676     /* Fall through */
4677     case SKELETON_KEY:
4678     case CHEST:
4679     case LARGE_BOX:
4680     case HEAVY_IRON_BALL:
4681     case IRON_CHAIN:
4682     case STATUE:
4683         /* otmp->cobj already done in mksobj() */
4684         break;
4685 #ifdef MAIL
4686     case SCR_MAIL:
4687         /* 0: delivered in-game via external event (or randomly for fake mail);
4688            1: from bones or wishing; 2: written with marker */
4689         otmp->spe = 1;
4690         break;
4691 #endif
4692     case WAN_WISHING:
4693         if (!wizard) {
4694             otmp->spe = (rn2(10) ? -1 : 0);
4695             break;
4696         }
4697         /*FALLTHRU*/
4698     default:
4699         otmp->spe = spe;
4700     }
4701
4702     /* set otmp->corpsenm or dragon scale [mail] */
4703     if (mntmp >= LOW_PM) {
4704         if (mntmp == PM_LONG_WORM_TAIL)
4705             mntmp = PM_LONG_WORM;
4706
4707         switch (typ) {
4708         case TIN:
4709             otmp->spe = 0; /* No spinach */
4710             if (dead_species(mntmp, FALSE)) {
4711                 otmp->corpsenm = NON_PM; /* it's empty */
4712             } else if ((!(mons[mntmp].geno & G_UNIQ) || wizard)
4713                        && !(mvitals[mntmp].mvflags & G_NOCORPSE)
4714                        && mons[mntmp].cnutrit != 0) {
4715                 otmp->corpsenm = mntmp;
4716             }
4717             break;
4718         case CORPSE:
4719             if ((!(mons[mntmp].geno & G_UNIQ) || wizard)
4720                 && !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
4721                 if (mons[mntmp].msound == MS_GUARDIAN)
4722                     mntmp = genus(mntmp, 1);
4723                 set_corpsenm(otmp, mntmp);
4724             }
4725             break;
4726         case EGG:
4727             mntmp = can_be_hatched(mntmp);
4728             /* this also sets hatch timer if appropriate */
4729             set_corpsenm(otmp, mntmp);
4730             break;
4731         case FIGURINE:
4732             if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4733 #ifdef MAIL
4734                 && mntmp != PM_MAIL_DAEMON
4735 #endif
4736                 )
4737                 otmp->corpsenm = mntmp;
4738             break;
4739         case STATUE:
4740             otmp->corpsenm = mntmp;
4741             if (Has_contents(otmp) && verysmall(&mons[mntmp]))
4742                 delete_contents(otmp); /* no spellbook */
4743             otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
4744             break;
4745         case SCALE_MAIL:
4746             /* Dragon mail - depends on the order of objects & dragons. */
4747             if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON)
4748                 otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4749             break;
4750         }
4751     }
4752
4753     /* set blessed/cursed -- setting the fields directly is safe
4754      * since weight() is called below and addinv() will take care
4755      * of luck */
4756     if (iscursed) {
4757         curse(otmp);
4758     } else if (uncursed) {
4759         otmp->blessed = 0;
4760         otmp->cursed = (Luck < 0 && !wizard);
4761     } else if (blessed) {
4762         otmp->blessed = (Luck >= 0 || wizard);
4763         otmp->cursed = (Luck < 0 && !wizard);
4764     } else if (spesgn < 0) {
4765         curse(otmp);
4766     }
4767
4768     /* set eroded and erodeproof */
4769     if (erosion_matters(otmp)) {
4770         if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
4771             otmp->oeroded = eroded;
4772         if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
4773             otmp->oeroded2 = eroded2;
4774         /*
4775          * 3.6.1: earlier versions included `&& !eroded && !eroded2' here,
4776          * but damageproof combined with damaged is feasible (eroded
4777          * armor modified by confused reading of cursed destroy armor)
4778          * so don't prevent player from wishing for such a combination.
4779          */
4780         if (erodeproof && (is_damageable(otmp) || otmp->otyp == CRYSKNIFE))
4781             otmp->oerodeproof = (Luck >= 0 || wizard);
4782     }
4783
4784     /* set otmp->recharged */
4785     if (oclass == WAND_CLASS) {
4786         /* prevent wishing abuse */
4787         if (otmp->otyp == WAN_WISHING && !wizard)
4788             rechrg = 1;
4789         otmp->recharged = (unsigned) rechrg;
4790     }
4791
4792     /* set poisoned */
4793     if (ispoisoned) {
4794         if (is_poisonable(otmp))
4795             otmp->opoisoned = (Luck >= 0);
4796         else if (oclass == FOOD_CLASS)
4797             /* try to taint by making it as old as possible */
4798             otmp->age = 1L;
4799     }
4800     /* and [un]trapped */
4801     if (trapped) {
4802         if (Is_box(otmp) || typ == TIN)
4803             otmp->otrapped = (trapped == 1);
4804     }
4805     /* empty for containers rather than for tins */
4806     if (contents == EMPTY) {
4807         if (otmp->otyp == BAG_OF_TRICKS || otmp->otyp == HORN_OF_PLENTY) {
4808             if (otmp->spe > 0)
4809                 otmp->spe = 0;
4810         } else if (Has_contents(otmp)) {
4811             /* this assumes that artifacts can't be randomly generated
4812                inside containers */
4813             delete_contents(otmp);
4814             otmp->owt = weight(otmp);
4815         }
4816     }
4817     /* set locked/unlocked/broken */
4818     if (Is_box(otmp)) {
4819         if (locked) {
4820             otmp->olocked = 1, otmp->obroken = 0;
4821         } else if (unlocked) {
4822             otmp->olocked = 0, otmp->obroken = 0;
4823         } else if (broken) {
4824             otmp->olocked = 0, otmp->obroken = 1;
4825         }
4826     }
4827
4828     if (isgreased)
4829         otmp->greased = 1;
4830
4831     if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4832         otmp->odiluted = 1;
4833
4834     /* set tin variety */
4835     if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4836         set_tin_variety(otmp, tvariety);
4837
4838     if (name) {
4839         const char *aname;
4840         short objtyp;
4841
4842         /* an artifact name might need capitalization fixing */
4843         aname = artifact_name(name, &objtyp);
4844         if (aname && objtyp == otmp->otyp)
4845             name = aname;
4846
4847         /* 3.6 tribute - fix up novel */
4848         if (otmp->otyp == SPE_NOVEL) {
4849             const char *novelname;
4850
4851             novelname = lookup_novel(name, &otmp->novelidx);
4852             if (novelname)
4853                 name = novelname;
4854         }
4855
4856         otmp = oname(otmp, name);
4857         /* name==aname => wished for artifact (otmp->oartifact => got it) */
4858         if (otmp->oartifact || name == aname) {
4859             otmp->quan = 1L;
4860             u.uconduct.wisharti++; /* KMH, conduct */
4861         }
4862     }
4863
4864     /* more wishing abuse: don't allow wishing for certain artifacts */
4865     /* and make them pay; charge them for the wish anyway! */
4866     if ((is_quest_artifact(otmp)
4867          || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) {
4868         artifact_exists(otmp, safe_oname(otmp), FALSE);
4869         obfree(otmp, (struct obj *) 0);
4870         otmp = (struct obj *) &zeroobj;
4871 /*JP
4872         pline("For a moment, you feel %s in your %s, but it disappears!",
4873 */
4874         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",
4875               something, makeplural(body_part(HAND)));
4876         return otmp;
4877     }
4878
4879     if (halfeaten && otmp->oclass == FOOD_CLASS) {
4880         if (otmp->otyp == CORPSE)
4881             otmp->oeaten = mons[otmp->corpsenm].cnutrit;
4882         else
4883             otmp->oeaten = objects[otmp->otyp].oc_nutrition;
4884         /* (do this adjustment before setting up object's weight) */
4885         consume_oeaten(otmp, 1);
4886     }
4887     otmp->owt = weight(otmp);
4888     if (very && otmp->otyp == HEAVY_IRON_BALL)
4889         otmp->owt += IRON_BALL_W_INCR;
4890     else if (gsize > 1 && otmp->globby)
4891         /* 0: unspecified => small; 1: small => keep default owt of 20;
4892            2: medium => 120; 3: large => 320; 4: very large => 520 */
4893         otmp->owt += 100 + (gsize - 2) * 200;
4894
4895     return otmp;
4896 }
4897
4898 int
4899 rnd_class(first, last)
4900 int first, last;
4901 {
4902     int i, x, sum = 0;
4903
4904     if (first == last)
4905         return first;
4906     for (i = first; i <= last; i++)
4907         sum += objects[i].oc_prob;
4908     if (!sum) /* all zero */
4909         return first + rn2(last - first + 1);
4910     x = rnd(sum);
4911     for (i = first; i <= last; i++)
4912         if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
4913             return i;
4914     return 0;
4915 }
4916
4917 STATIC_OVL const char *
4918 Japanese_item_name(i)
4919 int i;
4920 {
4921     struct Jitem *j = Japanese_items;
4922
4923     while (j->item) {
4924         if (i == j->item)
4925             return j->name;
4926         j++;
4927     }
4928     return (const char *) 0;
4929 }
4930
4931 const char *
4932 suit_simple_name(suit)
4933 struct obj *suit;
4934 {
4935     const char *suitnm, *esuitp;
4936
4937     if (suit) {
4938         if (Is_dragon_mail(suit))
4939 #if 0 /*JP*/
4940             return "dragon mail"; /* <color> dragon scale mail */
4941 #else
4942             return "\97Ø\8aZ"; /* <color> dragon scale mail */
4943 #endif
4944         else if (Is_dragon_scales(suit))
4945 /*JP
4946         return "dragon scales";
4947 */
4948         return "\97Ø";
4949         suitnm = OBJ_NAME(objects[suit->otyp]);
4950         esuitp = eos((char *) suitnm);
4951 #if 0 /*JP*/
4952         if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
4953             return "mail"; /* most suits fall into this category */
4954 #else
4955         if (strlen(suitnm) > 2 && !strcmp(esuitp - 2, "\8aZ"))
4956             return "\8aZ"; /* most suits fall into this category */
4957 #endif
4958 #if 0 /*JP*/
4959         else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
4960             return "jacket"; /* leather jacket */
4961 #endif
4962     }
4963     /* "suit" is lame but "armor" is ambiguous and "body armor" is absurd */
4964 /*JP
4965     return "suit";
4966 */
4967     return "\95\9e";
4968 }
4969
4970 const char *
4971 cloak_simple_name(cloak)
4972 struct obj *cloak;
4973 {
4974     if (cloak) {
4975         switch (cloak->otyp) {
4976         case ROBE:
4977 /*JP
4978             return "robe";
4979 */
4980             return "\83\8d\81[\83u";
4981         case MUMMY_WRAPPING:
4982 /*JP
4983             return "wrapping";
4984 */
4985             return "\95ï\91Ñ";
4986         case ALCHEMY_SMOCK:
4987             return (objects[cloak->otyp].oc_name_known && cloak->dknown)
4988 /*JP
4989                        ? "smock"
4990 */
4991                        ? "\83X\83\82\83b\83N"
4992 /*JP
4993                        : "apron";
4994 */
4995                        : "\83G\83v\83\8d\83\93";
4996         default:
4997             break;
4998         }
4999     }
5000 /*JP
5001     return "cloak";
5002 */
5003     return "\83N\83\8d\81[\83N";
5004 }
5005
5006 /* helm vs hat for messages */
5007 const char *
5008 helm_simple_name(helmet)
5009 struct obj *helmet;
5010 {
5011     /*
5012      *  There is some wiggle room here; the result has been chosen
5013      *  for consistency with the "protected by hard helmet" messages
5014      *  given for various bonks on the head:  headgear that provides
5015      *  such protection is a "helm", that which doesn't is a "hat".
5016      *
5017      *      elven leather helm / leather hat    -> hat
5018      *      dwarvish iron helm / hard hat       -> helm
5019      *  The rest are completely straightforward:
5020      *      fedora, cornuthaum, dunce cap       -> hat
5021      *      all other types of helmets          -> helm
5022      */
5023 /*JP
5024     return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
5025 */
5026     return (helmet && !is_metallic(helmet)) ? "\96X\8eq" : "\8a\95";
5027 }
5028
5029 const char *
5030 mimic_obj_name(mtmp)
5031 struct monst *mtmp;
5032 {
5033     if (M_AP_TYPE(mtmp) == M_AP_OBJECT) {
5034         if (mtmp->mappearance == GOLD_PIECE)
5035 /*JP
5036             return "gold";
5037 */
5038             return "\8bà\89Ý";
5039         if (mtmp->mappearance != STRANGE_OBJECT)
5040             return simple_typename(mtmp->mappearance);
5041     }
5042 /*JP
5043     return "whatcha-may-callit";
5044 */
5045     return "\89½\82Æ\82©\82¢\82¤\82à\82Ì";
5046 }
5047
5048 /*
5049  * Construct a query prompt string, based around an object name, which is
5050  * guaranteed to fit within [QBUFSZ].  Takes an optional prefix, three
5051  * choices for filling in the middle (two object formatting functions and a
5052  * last resort literal which should be very short), and an optional suffix.
5053  */
5054 char *
5055 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
5056 char *qbuf; /* output buffer */
5057 const char *qprefix, *qsuffix;
5058 struct obj *obj;
5059 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
5060 const char *lastR;
5061 {
5062     char *bufp, *endp;
5063     /* convert size_t (or int for ancient systems) to ordinary unsigned */
5064     unsigned len, lenlimit,
5065         len_qpfx = (unsigned) (qprefix ? strlen(qprefix) : 0),
5066         len_qsfx = (unsigned) (qsuffix ? strlen(qsuffix) : 0),
5067         len_lastR = (unsigned) strlen(lastR);
5068
5069     lenlimit = QBUFSZ - 1;
5070     endp = qbuf + lenlimit;
5071     /* sanity check, aimed mainly at paniclog (it's conceivable for
5072        the result of short_oname() to be shorter than the length of
5073        the last resort string, but we ignore that possibility here) */
5074     if (len_qpfx > lenlimit)
5075         impossible("safe_qbuf: prefix too long (%u characters).", len_qpfx);
5076     else if (len_qpfx + len_qsfx > lenlimit)
5077         impossible("safe_qbuf: suffix too long (%u + %u characters).",
5078                    len_qpfx, len_qsfx);
5079     else if (len_qpfx + len_lastR + len_qsfx > lenlimit)
5080         impossible("safe_qbuf: filler too long (%u + %u + %u characters).",
5081                    len_qpfx, len_lastR, len_qsfx);
5082
5083     /* the output buffer might be the same as the prefix if caller
5084        has already partially filled it */
5085     if (qbuf == qprefix) {
5086         /* prefix is already in the buffer */
5087         *endp = '\0';
5088     } else if (qprefix) {
5089         /* put prefix into the buffer */
5090         (void) strncpy(qbuf, qprefix, lenlimit);
5091         *endp = '\0';
5092     } else {
5093         /* no prefix; output buffer starts out empty */
5094         qbuf[0] = '\0';
5095     }
5096     len = (unsigned) strlen(qbuf);
5097
5098     if (len + len_lastR + len_qsfx > lenlimit) {
5099         /* too long; skip formatting, last resort output is truncated */
5100         if (len < lenlimit) {
5101             (void) strncpy(&qbuf[len], lastR, lenlimit - len);
5102             *endp = '\0';
5103             len = (unsigned) strlen(qbuf);
5104             if (qsuffix && len < lenlimit) {
5105                 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
5106                 *endp = '\0';
5107                 /* len = (unsigned) strlen(qbuf); */
5108             }
5109         }
5110     } else {
5111         /* suffix and last resort are guaranteed to fit */
5112         len += len_qsfx; /* include the pending suffix */
5113         /* format the object */
5114         bufp = short_oname(obj, func, altfunc, lenlimit - len);
5115         if (len + strlen(bufp) <= lenlimit)
5116             Strcat(qbuf, bufp); /* formatted name fits */
5117         else
5118             Strcat(qbuf, lastR); /* use last resort */
5119         releaseobuf(bufp);
5120
5121         if (qsuffix)
5122             Strcat(qbuf, qsuffix);
5123     }
5124     /* assert( strlen(qbuf) < QBUFSZ ); */
5125     return qbuf;
5126 }
5127
5128 /*objnam.c*/