OSDN Git Service

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