OSDN Git Service

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