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. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 /* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */
15 #define PREFIX 80 /* (56) */
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*/
23 STATIC_DCL char *FDECL(strprepend, (char *, const char *));
25 STATIC_DCL short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P));
27 STATIC_DCL short FDECL(rnd_otyp_by_namedesc, (const char *, CHAR_P, int));
28 STATIC_DCL boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P));
29 STATIC_DCL char *NDECL(nextobuf);
30 STATIC_DCL void FDECL(releaseobuf, (char *));
31 STATIC_DCL char *FDECL(minimal_xname, (struct obj *));
32 STATIC_DCL void FDECL(add_erosion_words, (struct obj *, char *));
33 STATIC_DCL char *FDECL(doname_base, (struct obj *obj, unsigned));
34 STATIC_DCL char *FDECL(just_an, (char *str, const char *));
36 STATIC_DCL boolean FDECL(singplur_lookup, (char *, char *, BOOLEAN_P,
37 const char *const *));
38 STATIC_DCL char *FDECL(singplur_compound, (char *));
40 STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned));
42 STATIC_DCL boolean FDECL(badman, (const char *, BOOLEAN_P));
44 STATIC_DCL char *FDECL(globwt, (struct obj *, char *, boolean *));
51 #define BSTRCMPI(base, ptr, str) ((ptr) < base || strcmpi((ptr), str))
52 #define BSTRNCMPI(base, ptr, str, num) \
53 ((ptr) < base || strncmpi((ptr), str, num))
54 #define Strcasecpy(dst, src) (void) strcasecpy(dst, src)
56 /* true for gems/rocks that should have " stone" appended to their names */
57 #define GemStone(typ) \
59 || (objects[typ].oc_material == GEMSTONE \
60 && (typ != DILITHIUM_CRYSTAL && typ != RUBY && typ != DIAMOND \
61 && typ != SAPPHIRE && typ != BLACK_OPAL && typ != EMERALD \
65 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "wakizashi" },
66 { BROADSWORD, "ninja-to" },
67 { FLAIL, "nunchaku" },
68 { GLAIVE, "naginata" },
69 { LOCK_PICK, "osaku" },
70 { WOODEN_HARP, "koto" },
72 { PLATE_MAIL, "tanko" },
74 { LEATHER_GLOVES, "yugake" },
75 { FOOD_RATION, "gunyoki" },
76 { POT_BOOZE, "sake" },
79 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "
\98e
\8d·
\82µ" },
80 { BROADSWORD, "
\94E
\8eÒ
\93\81" },
81 { FLAIL, "
\83k
\83\93\83`
\83\83\83N" },
82 { GLAIVE, "
\82È
\82¬
\82È
\82½" },
83 { LOCK_PICK, "
\82¨
\82³
\82" },
84 { WOODEN_HARP, "
\8bÕ" },
85 { KNIFE, "
\8eh
\93\81" },
86 { PLATE_MAIL, "
\92Z
\8db" },
88 { LEATHER_GLOVES, "
\8b|
\8c\9c" },
89 { FOOD_RATION, "
\8aÛ
\96ò" },
90 { POT_BOOZE, "
\8eð" },
94 STATIC_DCL const char *FDECL(Japanese_item_name, (int i));
99 register const char *pref;
101 register int i = (int) strlen(pref);
104 impossible("PREFIX too short (for %d).", i);
108 (void) strncpy(s, pref, i); /* do not copy trailing 0 */
112 /* manage a pool of BUFSZ buffers, so callers don't have to */
113 static char NEARDATA obufs[NUMOBUF][BUFSZ];
114 static int obufidx = 0;
119 obufidx = (obufidx + 1) % NUMOBUF;
120 return obufs[obufidx];
123 /* put the most recently allocated buffer back if possible */
128 /* caller may not know whether bufp is the most recently allocated
129 buffer; if it isn't, do nothing; note that because of the somewhat
130 obscure PREFIX handling for object name formatting by xname(),
131 the pointer our caller has and is passing to us might be into the
132 middle of an obuf rather than the address returned by nextobuf() */
133 if (bufp >= obufs[obufidx]
134 && bufp < obufs[obufidx] + sizeof obufs[obufidx]) /* obufs[][BUFSZ] */
135 obufidx = (obufidx - 1 + NUMOBUF) % NUMOBUF;
142 char *buf = nextobuf();
143 struct objclass *ocl = &objects[otyp];
144 const char *actualn = OBJ_NAME(*ocl);
145 const char *dn = OBJ_DESCR(*ocl);
146 const char *un = ocl->oc_uname;
147 int nn = ocl->oc_name_known;
149 if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
150 actualn = Japanese_item_name(otyp);
153 Sprintf(buf, "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é", un);
155 switch (ocl->oc_class) {
160 Strcat(buf, "
\8bà
\89Ý");
164 Strcpy(buf, "potion");
170 Strcpy(buf, "scroll");
172 Strcat(buf, "
\8aª
\95¨");
181 if (otyp != SPE_NOVEL) {
183 Strcpy(buf, "spellbook");
185 Strcat(buf, "
\96\82\96@
\8f\91");
188 Strcpy(buf, !nn ? "book" : "novel");
190 Strcpy(buf, !nn ? "
\96{" : "
\8f¬
\90à");
198 Strcat(buf, "
\8ew
\97Ö");
203 Strcpy(buf, actualn);
205 Strcpy(buf, "amulet");
207 Sprintf(eos(buf), " called %s", un);
209 Sprintf(eos(buf), " (%s)", dn);
213 Strcat(buf, actualn);
215 Strcat(buf, "
\96\82\8f\9c\82¯");
221 Strcat(buf, actualn);
223 Strcat(buf, "
\95ó
\90Î");
229 Strcpy(buf, actualn);
231 Strcat(buf, " stone");
233 Sprintf(eos(buf), " called %s", un);
235 Sprintf(eos(buf), " (%s)", dn);
237 Strcat(buf, actualn);
241 Strcpy(buf, dn ? dn : actualn);
242 if (ocl->oc_class == GEM_CLASS)
244 (ocl->oc_material == MINERAL) ? " stone" : " gem");
246 Sprintf(eos(buf), " called %s", un);
248 Strcat(buf, dn ? dn : actualn);
257 /* here for ring/scroll/potion/wand */
261 Strcpy(buf, actualn); /* avoid spellbook of Book of the Dead */
263 Sprintf(eos(buf), " of %s", actualn);
265 Strcpy(buf, actualn);
270 Sprintf(eos(buf), " called %s", un);
274 Sprintf(eos(buf), " (%s)", dn);
276 Sprintf(eos(buf), "(%s)", dn);
281 /* less verbose result than obj_typename(); either the actual name
282 or the description (but not both); user-assigned name is ignored */
284 simple_typename(otyp)
287 char *bufp, *pp, *save_uname = objects[otyp].oc_uname;
289 objects[otyp].oc_uname = 0; /* suppress any name given by user */
290 bufp = obj_typename(otyp);
291 objects[otyp].oc_uname = save_uname;
292 if ((pp = strstri(bufp, " (")) != 0)
293 *pp = '\0'; /* strip the appended description */
297 /* typename for debugging feedback where data involved might be suspect */
302 unsigned save_nameknown;
305 if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
306 || !OBJ_NAME(objects[otyp])) {
308 Sprintf(res, "glorkum[%d]", otyp);
310 /* force it to be treated as fully discovered */
311 save_nameknown = objects[otyp].oc_name_known;
312 objects[otyp].oc_name_known = 1;
313 res = simple_typename(otyp);
314 objects[otyp].oc_name_known = save_nameknown;
323 if (!obj->oartifact || !has_oname(obj))
325 if (!program_state.gameover && !iflags.override_ID) {
326 if (not_fully_identified(obj))
332 /* used by distant_name() to pass extra information to xname_flags();
333 it would be much cleaner if this were a parameter, but that would
334 require all of the xname() and doname() calls to be modified */
335 static int distantname = 0;
337 /* Give the name of an object seen at a distance. Unlike xname/doname,
338 * we don't want to set dknown if it's not set already.
341 distant_name(obj, func)
343 char *FDECL((*func), (OBJ_P));
347 /* 3.6.1: this used to save Blind, set it, make the call, then restore
348 * the saved value; but the Eyes of the Overworld override blindness
349 * and let characters wearing them get dknown set for distant items.
351 * TODO? if the hero is wearing those Eyes, figure out whether the
352 * object is within X-ray radius and only treat it as distant when
353 * beyond that radius. Logic is iffy but result might be interesting.
361 /* convert player specified fruit name into corresponding fruit juice name
362 ("slice of pizza" -> "pizza juice" rather than "slice of pizza juice") */
365 boolean juice; /* whether or not to append " juice" to the name */
368 char *buf = nextobuf();
369 const char *fruit_nam = strstri(pl_fruit, " of ");
372 fruit_nam += 4; /* skip past " of " */
374 fruit_nam = pl_fruit; /* use it as is */
376 Sprintf(buf, "%s%s", makesingular(fruit_nam), juice ? " juice" : "");
379 /*
\93ú
\96{
\8cê
\82Å
\82Í
\82»
\82±
\82Ü
\82Å
\82µ
\82È
\82¢*/
380 char *buf = nextobuf();
381 Sprintf(buf, "%s%s", pl_fruit, juice ? "
\83W
\83\85\81[
\83X" : "");
386 /* look up a named fruit by index (1..127) */
388 fruit_from_indx(indx)
393 for (f = ffruit; f; f = f->nextf)
399 /* look up a named fruit by name */
401 fruit_from_name(fname, exact, highest_fid)
403 boolean exact; /* False => prefix or exact match, True = exact match only */
404 int *highest_fid; /* optional output; only valid if 'fname' isn't found */
406 struct fruit *f, *tentativef;
410 * note: named fruits are case-senstive...
415 /* first try for an exact match */
416 for (f = ffruit; f; f = f->nextf)
417 if (!strcmp(f->fname, fname))
419 else if (highest_fid && f->fid > *highest_fid)
420 *highest_fid = f->fid;
422 /* didn't match as-is; if caller is willing to accept a prefix
423 match, try to find one; we want to find the longest prefix that
424 matches, not the first */
427 for (f = ffruit; f; f = f->nextf) {
428 k = strlen(f->fname);
429 if (!strncmp(f->fname, fname, k)
430 && (!fname[k] || fname[k] == ' ')
431 && (!tentativef || k > strlen(tentativef->fname)))
436 /* if we still don't have a match, try singularizing the target;
437 for exact match, that's trivial, but for prefix, it's hard */
439 altfname = makesingular(fname);
440 for (f = ffruit; f; f = f->nextf) {
441 if (!strcmp(f->fname, altfname))
444 releaseobuf(altfname);
447 char fnamebuf[BUFSZ], *p;
448 unsigned fname_k = strlen(fname); /* length of assumed plural fname */
451 for (f = ffruit; f; f = f->nextf) {
452 k = strlen(f->fname);
453 /* reload fnamebuf[] each iteration in case it gets modified;
454 there's no need to recalculate fname_k */
455 Strcpy(fnamebuf, fname);
456 /* bug? if singular of fname is longer than plural,
457 failing the 'fname_k > k' test could skip a viable
458 candidate; unfortunately, we can't singularize until
459 after stripping off trailing stuff and we can't get
460 accurate fname_k until fname has been singularized;
461 compromise and use 'fname_k >= k' instead of '>',
462 accepting 1 char length discrepancy without risking
463 false match (I hope...) */
464 if (fname_k >= k && (p = index(&fnamebuf[k], ' ')) != 0) {
465 *p = '\0'; /* truncate at 1st space past length of f->fname */
466 altfname = makesingular(fnamebuf);
467 k = strlen(altfname); /* actually revised 'fname_k' */
468 if (!strcmp(f->fname, altfname)
469 && (!tentativef || k > strlen(tentativef->fname)))
471 releaseobuf(altfname); /* avoid churning through all obufs */
479 /* sort the named-fruit linked list by fruit index number */
481 reorder_fruit(forward)
484 struct fruit *f, *allfr[1 + 127];
485 int i, j, k = SIZE(allfr);
487 for (i = 0; i < k; ++i)
488 allfr[i] = (struct fruit *) 0;
489 for (f = ffruit; f; f = f->nextf) {
490 /* without sanity checking, this would reduce to 'allfr[f->fid]=f' */
492 if (j < 1 || j >= k) {
493 impossible("reorder_fruit: fruit index (%d) out of range", j);
494 return; /* don't sort after all; should never happen... */
495 } else if (allfr[j]) {
496 impossible("reorder_fruit: duplicate fruit index (%d)", j);
501 ffruit = 0; /* reset linked list; we're rebuilding it from scratch */
502 /* slot [0] will always be empty; must start 'i' at 1 to avoid
503 [k - i] being out of bounds during first iteration */
504 for (i = 1; i < k; ++i) {
505 /* for forward ordering, go through indices from high to low;
506 for backward ordering, go from low to high */
507 j = forward ? (k - i) : i;
509 allfr[j]->nextf = ffruit;
519 return xname_flags(obj, CXN_NORMAL);
523 xname_flags(obj, cxn_flags)
524 register struct obj *obj;
525 unsigned cxn_flags; /* bitmask of CXN_xxx values */
528 register int typ = obj->otyp;
529 register struct objclass *ocl = &objects[typ];
530 int nn = ocl->oc_name_known, omndx = obj->corpsenm;
531 const char *actualn = OBJ_NAME(*ocl);
532 const char *dn = OBJ_DESCR(*ocl);
533 const char *un = ocl->oc_uname;
534 boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
535 boolean known, dknown, bknown;
537 buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
538 if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
539 actualn = Japanese_item_name(typ);
540 /* As of 3.6.2: this used to be part of 'dn's initialization, but it
541 needs to come after possibly overriding 'actualn' */
547 * clean up known when it's tied to oc_name_known, eg after AD_DRIN
548 * This is only required for unique objects since the article
549 * printed for the object is tied to the combination of the two
550 * and printing the wrong article gives away information.
552 if (!nn && ocl->oc_uses_known && ocl->oc_unique)
554 if (!Blind && !distantname)
556 if (Role_if(PM_PRIEST))
557 obj->bknown = 1; /* actively avoid set_bknown();
558 * we mustn't call update_inventory() now because
559 * it would call xname() (via doname()) recursively
560 * and could end up clobbering all the obufs... */
562 if (iflags.override_ID) {
563 known = dknown = bknown = TRUE;
567 dknown = obj->dknown;
568 bknown = obj->bknown;
571 if (obj_is_pname(obj))
576 Strcat(buf, ONAME(obj));
581 if (has_oname(obj) && dknown) {
582 Strcat(buf, ONAME(obj));
583 Strcat(buf, "
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½");
586 switch (obj->oclass) {
590 Strcpy(buf, "amulet");
592 Strcat(buf, "
\96\82\8f\9c\82¯");
593 else if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
594 /* each must be identified individually */
595 Strcpy(buf, known ? actualn : dn);
597 Strcpy(buf, actualn);
600 Sprintf(buf, "amulet called %s", un);
602 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\8f\9c\82¯", un);
605 Sprintf(buf, "%s amulet", dn);
607 Sprintf(eos(buf), "%s", dn);
610 if (is_poisonable(obj) && obj->opoisoned)
612 Strcpy(buf, "poisoned ");
614 Strcpy(buf, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
620 Sprintf(eos(buf), "%s
\82Ì", mons[obj->corpsenm].mname);
624 Strcpy(buf, "pair of ");
626 Strcpy(buf, "
\88ê
\91Î
\82Ì");
627 else if (is_wet_towel(obj))
629 Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
631 Strcpy(buf, (obj->spe < 3) ? "
\8e¼
\82Á
\82½" : "
\94G
\82ê
\82½");
636 Strcat(buf, actualn);
640 Strcat(buf, " called ");
644 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é");
650 #if 0 /*JP*/ /*
\82±
\82ê
\82Í
\8cê
\8f\87\82Ì
\8aÖ
\8cW
\82©
\82ç
\8fã
\82Ì
\95û
\82Å
\92è
\8b`*/
651 if (typ == FIGURINE && omndx != NON_PM) {
652 char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */
654 Sprintf(eos(buf), " of %s%s",
655 just_an(anbuf, mons[omndx].mname),
657 } else if (is_wet_towel(obj)) {
659 if (is_wet_towel(obj)) {
662 Sprintf(eos(buf), " (%d)", obj->spe);
666 /* depends on order of the dragon scales objects */
667 if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
669 Sprintf(buf, "set of %s", actualn);
671 Sprintf(buf, "%s
\88ê
\8e®", actualn);
674 if (is_boots(obj) || is_gloves(obj))
676 Strcpy(buf, "pair of ");
678 Strcat(buf,"
\88ê
\91Î
\82Ì");
680 if (obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
683 Strcpy(buf, "shield");
685 Strcat(buf, "
\8f\82");
688 if (obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
690 Strcpy(buf, "smooth shield");
692 Strcat(buf, "
\82·
\82×
\82·
\82×
\82µ
\82½
\8f\82");
697 Strcat(buf, actualn);
701 Strcat(buf, "boots");
702 else if (is_gloves(obj))
703 Strcat(buf, "gloves");
704 else if (is_cloak(obj))
705 Strcpy(buf, "cloak");
706 else if (is_helmet(obj))
707 Strcpy(buf, "helmet");
708 else if (is_shield(obj))
709 Strcpy(buf, "shield");
711 Strcpy(buf, "armor");
712 Strcat(buf, " called ");
718 else if (is_gloves(obj))
720 else if (is_cloak(obj))
721 p = "
\83N
\83\8d\81[
\83N";
722 else if (is_helmet(obj))
724 else if (is_shield(obj))
728 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, p);
734 if (typ == SLIME_MOLD) {
735 struct fruit *f = fruit_from_indx(obj->spe);
738 impossible("Bad fruit #%d?", obj->spe);
739 Strcpy(buf, "fruit");
741 Strcpy(buf, f->fname);
743 /* ick; already pluralized fruit names
744 are allowed--we want to try to avoid
745 adding a redundant plural suffix */
746 Strcpy(buf, makeplural(makesingular(buf)));
763 ? "
\82Æ
\82Ä
\82à
\91å
\82«
\82¢"
775 Strcpy(buf, actualn);
776 if (typ == TIN && known)
777 tin_details(obj, omndx, buf);
779 if (typ == TIN && known)
780 /*JP
\81u
\81`
\82Ì
\93÷
\82Ì
\81v*/
781 tin_details(obj, omndx, buf);
782 Strcat(buf, actualn);
788 Strcpy(buf, actualn);
790 Strcat(buf, actualn);
794 if (typ == STATUE && omndx != NON_PM) {
798 Sprintf(buf, "%s%s of %s%s",
799 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
803 type_is_pname(&mons[omndx])
805 : the_unique_pm(&mons[omndx])
807 : just_an(anbuf, mons[omndx].mname),
810 Sprintf(eos(buf), "%s%s
\82Ì%s",
811 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
814 mons[obj->corpsenm].mname, actualn);
818 Strcpy(buf, actualn);
820 Strcat(buf, actualn);
825 Sprintf(buf, "%sheavy iron ball",
826 (obj->owt > ocl->oc_weight) ? "very " : "");
828 Sprintf(eos(buf), "%s
\8fd
\82¢
\93S
\8b\85",
829 (obj->owt > ocl->oc_weight) ? "
\82Æ
\82Ä
\82à" : "");
833 if (dknown && obj->odiluted)
835 Strcpy(buf, "diluted ");
837 Strcat(buf, "
\94\96\82Ü
\82Á
\82½");
838 if (nn || un || !dknown) {
840 Strcat(buf, "potion");
853 if (typ == POT_WATER && bknown
854 && (obj->blessed || obj->cursed)) {
856 Strcat(buf, obj->blessed ? "holy " : "unholy ");
858 Strcat(buf, obj->blessed ? "
\90¹" : "
\95s
\8fò
\82È");
860 Strcat(buf, actualn);
863 Strcat(buf, " called ");
867 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96ò");
872 #if 0 /*JP*//*
\95s
\8am
\92è
\96¼
\82É
\81u
\96ò
\81v
\82Í
\95t
\82¢
\82Ä
\82¢
\82é*/
873 Strcat(buf, " potion");
879 Strcpy(buf, "scroll");
884 Strcat(buf,"
\8aª
\95¨");
892 Strcat(buf, actualn);
895 Strcat(buf, " called ");
899 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8aª
\95¨");
901 } else if (ocl->oc_magic) {
903 Strcat(buf, " labeled ");
909 Strcat(buf, " scroll");
923 Sprintf(buf, "wand of %s", actualn);
925 Strcat(buf, actualn);
928 Sprintf(buf, "wand called %s", un);
930 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8fñ", un);
933 Sprintf(buf, "%s wand", dn);
938 if (typ == SPE_NOVEL) { /* 3.6 tribute */
945 Strcpy(buf, actualn);
948 Sprintf(buf, "novel called %s", un);
950 Sprintf(buf, "%s
\82Æ
\82¢
\82¤
\8f¬
\90à", un);
953 Sprintf(buf, "%s book", dn);
955 Sprintf(buf, "%s
\96{", dn);
958 } else if (!dknown) {
960 Strcpy(buf, "spellbook");
962 Strcat(buf, "
\96\82\96@
\8f\91");
965 if (typ != SPE_BOOK_OF_THE_DEAD)
966 Strcpy(buf, "spellbook of ");
968 Strcat(buf, actualn);
971 Sprintf(buf, "spellbook called %s", un);
973 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\96@
\8f\91", un);
976 Sprintf(buf, "%s spellbook", dn);
978 Sprintf(eos(buf), "%s", dn);
985 Strcat(buf, "
\8ew
\97Ö");
988 Sprintf(buf, "ring of %s", actualn);
990 Strcat(buf, actualn);
993 Sprintf(buf, "ring called %s", un);
995 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8ew
\97Ö", un);
998 Sprintf(buf, "%s ring", dn);
1004 const char *rock = (ocl->oc_material == MINERAL) ? "stone" : "gem";
1006 const char *rock = (ocl->oc_material == MINERAL) ? "
\90Î" : "
\95ó
\90Î";
1017 Sprintf(buf, "%s called %s", rock, un);
1019 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, rock);
1022 Sprintf(buf, "%s %s", dn, rock);
1026 Strcpy(buf, actualn);
1029 Strcat(buf, " stone");
1035 Sprintf(buf, "glorkum %d %d %d", obj->oclass, typ, obj->spe);
1039 Strcpy(buf, makeplural(buf));
1042 if (obj->otyp == T_SHIRT && program_state.gameover) {
1046 Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
1048 Sprintf(eos(buf), "(
\81u%s
\81v
\82Æ
\8f\91\82¢
\82Ä
\82 \82é)", tshirt_text(obj, tmpbuf));
1052 if (has_oname(obj) && dknown) {
1053 Strcat(buf, " named ");
1055 Strcat(buf, ONAME(obj));
1058 if (!strncmpi(buf, "the ", 4))
1066 /* similar to simple_typename but minimal_xname operates on a particular
1067 object rather than its general type; it formats the most basic info:
1068 potion -- if description not known
1069 brown potion -- if oc_name_known not set
1070 potion of object detection -- if discovered
1078 struct objclass saveobcls;
1079 int otyp = obj->otyp;
1081 /* suppress user-supplied name */
1082 saveobcls.oc_uname = objects[otyp].oc_uname;
1083 objects[otyp].oc_uname = 0;
1084 /* suppress actual name if object's description is unknown */
1085 saveobcls.oc_name_known = objects[otyp].oc_name_known;
1087 objects[otyp].oc_name_known = 0;
1089 /* caveat: this makes a lot of assumptions about which fields
1090 are required in order for xname() to yield a sensible result */
1092 bareobj.otyp = otyp;
1093 bareobj.oclass = obj->oclass;
1094 bareobj.dknown = obj->dknown;
1095 /* suppress known except for amulets (needed for fakes and real A-of-Y) */
1096 bareobj.known = (obj->oclass == AMULET_CLASS)
1098 /* default is "on" for types which don't use it */
1099 : !objects[otyp].oc_uses_known;
1100 bareobj.quan = 1L; /* don't want plural */
1101 bareobj.corpsenm = NON_PM; /* suppress statue and figurine details */
1102 /* but suppressing fruit details leads to "bad fruit #0"
1103 [perhaps we should force "slime mold" rather than use xname?] */
1104 if (obj->otyp == SLIME_MOLD)
1105 bareobj.spe = obj->spe;
1107 bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
1109 if (!strncmp(bufp, "uncursed ", 9))
1110 bufp += 9; /* Role_if(PM_PRIEST) */
1112 if (!strncmp(bufp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", 14))
1113 bufp += 14; /* Role_if(PM_PRIEST) */
1116 objects[otyp].oc_uname = saveobcls.oc_uname;
1117 objects[otyp].oc_name_known = saveobcls.oc_name_known;
1121 /* xname() output augmented for multishot missile feedback */
1127 char *onm = xname(obj);
1129 if (m_shot.n > 1 && m_shot.o == obj->otyp) {
1130 /* "the Nth arrow"; value will eventually be passed to an() or
1131 The(), both of which correctly handle this "the " prefix */
1133 Sprintf(tmpbuf, "the %d%s ", m_shot.i, ordin(m_shot.i));
1135 Sprintf(tmpbuf, "%d%s
\96Ú
\82Ì", m_shot.i, numeral(obj));
1136 onm = strprepend(onm, tmpbuf);
1141 /* used for naming "the unique_item" instead of "a unique_item" */
1147 boolean known = (obj->known || iflags.override_ID);
1149 if (!obj->dknown && !iflags.override_ID)
1151 else if (obj->otyp == FAKE_AMULET_OF_YENDOR && !known)
1152 return TRUE; /* lie */
1154 return (boolean) (objects[obj->otyp].oc_unique
1155 && (known || obj->otyp == AMULET_OF_YENDOR));
1161 /* should monster type be prefixed with "the"? (mostly used for corpses) */
1164 struct permonst *ptr;
1168 /* even though monsters with personal names are unique, we want to
1169 describe them as "Name" rather than "the Name" */
1170 if (type_is_pname(ptr))
1173 uniq = (ptr->geno & G_UNIQ) ? TRUE : FALSE;
1174 /* high priest is unique if it includes "of <deity>", otherwise not
1175 (caller needs to handle the 1st possibility; we assume the 2nd);
1176 worm tail should be irrelevant but is included for completeness */
1177 if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
1179 /* Wizard no longer needs this; he's flagged as unique these days */
1180 if (ptr == &mons[PM_WIZARD_OF_YENDOR])
1186 add_erosion_words(obj, prefix)
1190 boolean iscrys = (obj->otyp == CRYSKNIFE);
1193 rknown = (iflags.override_ID == 0) ? obj->rknown : TRUE;
1195 if (!is_damageable(obj) && !iscrys)
1198 /* The only cases where any of these bits do double duty are for
1199 * rotted food and diluted potions, which are all not is_damageable().
1201 if (obj->oeroded && !iscrys) {
1202 switch (obj->oeroded) {
1205 Strcat(prefix, "very ");
1207 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1211 Strcat(prefix, "thoroughly ");
1213 Strcat(prefix, "
\82©
\82È
\82è");
1217 Strcat(prefix, is_rustprone(obj) ? "rusty " : "burnt ");
1219 Strcat(prefix, is_rustprone(obj) ? "
\8eK
\82Ñ
\82½" : "
\8f\9d\82Â
\82¢
\82½");
1221 if (obj->oeroded2 && !iscrys) {
1222 switch (obj->oeroded2) {
1225 Strcat(prefix, "very ");
1227 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1231 Strcat(prefix, "thoroughly ");
1233 Strcat(prefix, "
\82©
\82È
\82è");
1237 Strcat(prefix, is_corrodeable(obj) ? "corroded " : "rotted ");
1239 Strcat(prefix, is_corrodeable(obj) ? "
\95\85\90H
\82µ
\82½" : "
\95\85\82Á
\82½");
1241 if (rknown && obj->oerodeproof)
1243 Strcat(prefix, iscrys
1247 : is_corrodeable(obj)
1248 ? "corrodeproof " /* "stainless"? */
1253 Strcat(prefix, iscrys
1254 ? "
\88À
\92è
\82µ
\82½"
1256 ? "
\8eK
\82Ñ
\82È
\82¢"
1257 : is_corrodeable(obj)
1258 ? "
\95\85\90H
\82µ
\82È
\82¢" /* "stainless"? */
1260 ? "
\94R
\82¦
\82È
\82¢"
1265 /* used to prevent rust on items where rust makes no difference */
1267 erosion_matters(obj)
1270 switch (obj->oclass) {
1272 /* it's possible for a rusty weptool to be polymorphed into some
1273 non-weptool iron tool, in which case the rust implicitly goes
1274 away, but it's also possible for it to be polymorphed into a
1275 non-iron tool, in which case rust also implicitly goes away,
1276 so there's no particular reason to try to handle the first
1277 instance differently [this comment belongs in poly_obj()...] */
1278 return is_weptool(obj) ? TRUE : FALSE;
1290 #define DONAME_WITH_PRICE 1
1291 #define DONAME_VAGUE_QUAN 2
1294 doname_base(obj, doname_flags)
1296 unsigned doname_flags;
1298 boolean ispoisoned = FALSE,
1299 with_price = (doname_flags & DONAME_WITH_PRICE) != 0,
1300 vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0,
1301 weightshown = FALSE;
1302 boolean known, dknown, cknown, bknown, lknown;
1303 int omndx = obj->corpsenm;
1304 char prefix[PREFIX], globbuf[QBUFSZ];
1306 char tmpbuf[PREFIX + 1]; /* for when we have to add something at
1307 the start of prefix instead of the
1308 end (Strcat is used on the end) */
1310 register char *bp = xname(obj);
1311 #if 1 /*JP*//*
\8f\87\8f\98\93ü
\82ê
\91Ö
\82¦
\82É
\8eg
\82¤*/
1312 char preprefix[PREFIX];
1315 if (iflags.override_ID) {
1316 known = dknown = cknown = bknown = lknown = TRUE;
1319 dknown = obj->dknown;
1320 cknown = obj->cknown;
1321 bknown = obj->bknown;
1322 lknown = obj->lknown;
1325 /* When using xname, we want "poisoned arrow", and when using
1326 * doname, we want "poisoned +0 arrow". This kludge is about the only
1327 * way to do it, at least until someone overhauls xname() and doname(),
1328 * combining both into one function taking a parameter.
1330 /* must check opoisoned--someone can have a weirdly-named fruit */
1332 if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
1337 if (!strncmp(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", 12) && obj->opoisoned) {
1344 *
\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
1345 *
\82Ì
\82Ù
\82¤
\82ª
\8e©
\91R
\82Å
\82 \82é
\81D
1349 preprefix[0] = '\0';
1350 if((tp = strstri(bp, "
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½")) != NULL){
1351 tp += 12; /*
\81u
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\81v*/
1352 strncpy(preprefix, bp, tp - bp);
1353 preprefix[tp - bp] = '\0';
1360 if (obj->quan != 1L) {
1361 if (dknown || !vague_quan)
1363 Sprintf(prefix, "%ld ", obj->quan);
1364 #else /*
\93ú
\96{
\8cê
\82Æ
\82µ
\82Ä
\82Í
\90\94\8e\8c\82ª
\82È
\82¢
\82Ì
\82Í
\95s
\8e©
\91R */
1365 Sprintf(prefix, "%ld%s
\82Ì", obj->quan, numeral(obj));
1369 Strcpy(prefix, "some ");
1371 Strcpy(prefix, "
\82¢
\82
\82Â
\82©
\82Ì");
1372 } else if (obj->otyp == CORPSE) {
1373 /* skip article prefix for corpses [else corpse_xname()
1374 would have to be taught how to strip it off again] */
1376 #if 0 /*JP*/ /*
\8a¥
\8e\8c\82Í
\95s
\97v */
1377 } else if (obj_is_pname(obj) || the_unique_obj(obj)) {
1378 if (!strncmpi(bp, "the ", 4))
1380 Strcpy(prefix, "the ");
1382 Strcpy(prefix, "a ");
1383 #else /*prefix
\82Ì
\8f\89\8aú
\89»*/
1389 /* "empty" goes at the beginning, but item count goes at the end */
1391 /* bag of tricks: include "empty" prefix if it's known to
1392 be empty but its precise number of charges isn't known
1393 (when that is known, suffix of "(n:0)" will be appended,
1394 making the prefix be redundant; note that 'known' flag
1395 isn't set when emptiness gets discovered because then
1396 charging magic would yield known number of new charges) */
1397 && ((obj->otyp == BAG_OF_TRICKS)
1398 ? (obj->spe == 0 && !obj->known)
1399 /* not bag of tricks: empty if container which has no contents */
1400 : ((Is_container(obj) || obj->otyp == STATUE)
1401 && !Has_contents(obj))))
1403 Strcat(prefix, "empty ");
1405 Strcat(prefix, "
\8bó
\82Ì");
1407 if (bknown && obj->oclass != COIN_CLASS
1408 && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
1409 || (!obj->cursed && !obj->blessed))) {
1410 /* allow 'blessed clear potion' if we don't know it's holy water;
1411 * always allow "uncursed potion of water"
1415 Strcat(prefix, "cursed ");
1417 Strcat(prefix, "
\8eô
\82í
\82ê
\82½");
1418 else if (obj->blessed)
1420 Strcat(prefix, "blessed ");
1422 Strcat(prefix, "
\8fj
\95\9f\82³
\82ê
\82½");
1423 else if (!iflags.implicit_uncursed
1424 /* For most items with charges or +/-, if you know how many
1425 * charges are left or what the +/- is, then you must have
1426 * totally identified the item, so "uncursed" is unnecessary,
1427 * because an identified object not described as "blessed" or
1428 * "cursed" must be uncursed.
1430 * If the charges or +/- is not known, "uncursed" must be
1431 * printed to avoid ambiguity between an item whose curse
1432 * status is unknown, and an item known to be uncursed.
1434 || ((!known || !objects[obj->otyp].oc_charged
1435 || obj->oclass == ARMOR_CLASS
1436 || obj->oclass == RING_CLASS)
1438 && obj->otyp != SCR_MAIL
1440 && obj->otyp != FAKE_AMULET_OF_YENDOR
1441 && obj->otyp != AMULET_OF_YENDOR
1442 && !Role_if(PM_PRIEST)))
1444 Strcat(prefix, "uncursed ");
1446 Strcat(prefix, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢");
1449 if (lknown && Is_box(obj)) {
1451 /* 3.6.0 used "unlockable" here but that could be misunderstood
1452 to mean "capable of being unlocked" rather than the intended
1453 "not capable of being locked" */
1455 Strcat(prefix, "broken ");
1457 Strcat(prefix, "
\8c®
\82Ì
\89ó
\82ê
\82½");
1458 else if (obj->olocked)
1460 Strcat(prefix, "locked ");
1462 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½");
1465 Strcat(prefix, "unlocked ");
1467 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢");
1472 Strcat(prefix, "greased ");
1474 Strcat(prefix, "
\96û
\82Ì
\93h
\82ç
\82ê
\82½");
1476 if (cknown && Has_contents(obj)) {
1477 /* we count the number of separate stacks, which corresponds
1478 to the number of inventory slots needed to be able to take
1479 everything out if no merges occur */
1480 long itemcount = count_contents(obj, FALSE, FALSE, TRUE, FALSE);
1483 Sprintf(eos(bp), " containing %ld item%s", itemcount,
1486 Sprintf(eos(bp), "(%ld
\8cÂ
\93ü
\82Á
\82Ä
\82¢
\82é)", itemcount);
1490 switch (is_weptool(obj) ? WEAPON_CLASS : obj->oclass) {
1492 if (obj->owornmask & W_AMUL)
1494 Strcat(bp, " (being worn)");
1496 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1499 if (obj->owornmask & W_ARMOR) {
1501 Strcat(bp, (obj == uskin) ? " (embedded in your skin)"
1503 Strcat(bp, (obj == uskin) ? "(
\94§
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é)"
1504 /* in case of perm_invent update while Wear/Takeoff
1505 is in progress; check doffing() before donning()
1506 because donning() returns True for both cases */
1508 : doffing(obj) ? " (being doffed)"
1510 : doffing(obj) ? " (
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\93r
\92\86)"
1512 : donning(obj) ? " (being donned)"
1514 : donning(obj) ? " (
\92E
\82¢
\82Å
\82¢
\82é
\93r
\92\86)"
1518 : "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1519 /* slippery fingers is an intrinsic condition of the hero
1520 rather than extrinsic condition of objects, but gloves
1521 are described as slippery when hero has slippery fingers */
1522 if (obj == uarmg && Glib) /* just appended "(something)",
1523 * change to "(something; slippery)" */
1525 Strcpy(rindex(bp, ')'), "; slippery)");
1527 Strcpy(rindex(bp, ')'), ";
\82Ê
\82é
\82Ê
\82é)");
1533 Strcat(prefix, "poisoned ");
1535 Strcat(prefix, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
1536 add_erosion_words(obj, prefix);
1538 Strcat(prefix, sitoa(obj->spe));
1539 Strcat(prefix, " ");
1543 if (obj->owornmask & (W_TOOL | W_SADDLE)) { /* blindfold */
1545 Strcat(bp, " (being worn)");
1547 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1550 if (obj->otyp == LEASH && obj->leashmon != 0) {
1551 struct monst *mlsh = find_mid(obj->leashmon, FM_FMON);
1554 impossible("leashed monster not on this level");
1558 Sprintf(eos(bp), " (attached to %s)",
1559 noit_mon_nam(mlsh));
1561 Sprintf(eos(bp), " (%s
\82É
\8c\8b\82Ñ
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)",
1562 noit_mon_nam(mlsh));
1567 if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1570 Strcpy(tmpbuf, "no");
1572 Sprintf(tmpbuf, "%d", obj->spe);
1573 Sprintf(eos(bp), " (%s candle%s%s)", tmpbuf, plur(obj->spe),
1574 !obj->lamplit ? " attached" : ", lit");
1577 Sprintf(eos(bp), "(
\88ê
\96{
\82à
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢)");
1580 Sprintf(eos(bp), "(%d
\96{
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)", obj->spe);
1582 Sprintf(eos(bp), "(%d
\96{
\8cõ
\82Á
\82Ä
\82¢
\82é)", obj->spe);
1586 } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
1587 || obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
1589 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
1591 Strcat(prefix, "partly used ");
1593 Strcat(prefix, "
\8eg
\82¢
\82³
\82µ
\82Ì");
1596 Strcat(bp, " (lit)");
1598 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1601 if (objects[obj->otyp].oc_charged)
1608 Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe);
1610 Sprintf(eos(bp), "(%d:%d)", (int) obj->recharged, obj->spe);
1613 if (obj->otyp == POT_OIL && obj->lamplit)
1615 Strcat(bp, " (lit)");
1617 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1621 if (obj->owornmask & W_RINGR)
1623 Strcat(bp, " (on right ");
1625 Strcat(bp, "(
\89E");
1626 if (obj->owornmask & W_RINGL)
1628 Strcat(bp, " (on left ");
1630 Strcat(bp, "(
\8d¶");
1631 if (obj->owornmask & W_RING) {
1632 Strcat(bp, body_part(HAND));
1635 if (known && objects[obj->otyp].oc_charged) {
1637 Strcat(prefix, " ");
1639 Strcat(prefix, sitoa(obj->spe));
1640 Strcat(prefix, " ");
1646 Strcat(prefix, "partly eaten ");
1648 Strcat(prefix, "
\90H
\82×
\82©
\82¯
\82Ì");
1649 if (obj->otyp == CORPSE) {
1650 /* (quan == 1) => want corpse_xname() to supply article,
1651 (quan != 1) => already have count or "some" as prefix;
1652 "corpse" is already in the buffer returned by xname() */
1653 unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE)
1655 char *cxstr = corpse_xname(obj, prefix, cxarg);
1658 Sprintf(prefix, "%s ", cxstr);
1660 Sprintf(prefix, "%s
\82Ì", cxstr);
1662 /* avoid having doname(corpse) consume an extra obuf */
1664 } else if (obj->otyp == EGG) {
1665 #if 0 /* corpses don't tell if they're stale either */
1666 if (known && stale_egg(obj))
1667 Strcat(prefix, "stale ");
1670 && (known || (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
1672 Strcat(prefix, mons[omndx].mname);
1673 Strcat(prefix, " ");
1675 Strcat(prefix, mons[omndx].mname);
1676 Strcat(prefix, "
\82Ì");
1680 Strcat(bp, " (laid by you)");
1682 Strcat(bp, "(
\82 \82È
\82½
\82ª
\8eY
\82ñ
\82¾)");
1685 if (obj->otyp == MEAT_RING)
1690 add_erosion_words(obj, prefix);
1691 if (obj->owornmask & W_BALL)
1693 Strcat(bp, " (chained to you)");
1695 Strcat(bp, "(
\82 \82È
\82½
\82É
\8cq
\82ª
\82ê
\82Ä
\82¢
\82é)");
1699 if ((obj->owornmask & W_WEP) && !mrg_to_wielded) {
1700 if (obj->quan != 1L) {
1702 Strcat(bp, " (wielded)");
1704 Strcat(bp, "(
\91\95\94õ
\82µ
\82Ä
\82¢
\82é)");
1706 const char *hand_s = body_part(HAND);
1709 hand_s = makeplural(hand_s);
1710 /* note: Sting's glow message, if added, will insert text
1711 in front of "(weapon in hand)"'s closing paren */
1713 Sprintf(eos(bp), " (%sweapon in %s)",
1714 (obj->otyp == AKLYS) ? "tethered " : "", hand_s);
1715 #else /*
\83A
\83L
\83\8a\83X
\82ð
\93Á
\95Ê
\88µ
\82¢
\82µ
\82È
\82¢*/
1716 Sprintf(eos(bp), "(%s
\82É
\82µ
\82Ä
\82¢
\82é)", hand_s);
1719 if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
1720 if (!Blind) /* we know bp[] ends with ')'; overwrite that */
1722 Sprintf(eos(bp) - 1, ", %s %s)",
1723 glow_verb(warn_obj_cnt, TRUE),
1724 glow_color(obj->oartifact));
1726 Sprintf(eos(bp) - 1, ", %s%s
\82¢
\82é)",
1727 jconj_adj(glow_color(obj->oartifact)),
1728 jconj(glow_verb(warn_obj_cnt, TRUE), "
\82Ä"));
1733 if (obj->owornmask & W_SWAPWEP) {
1736 Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND));
1738 Sprintf(eos(bp), "(
\8d¶%s
\82É
\82µ
\82Ä
\82¢
\82é)", body_part(HAND));
1741 Strcat(bp, " (alternate weapon; not wielded)");
1743 Strcat(bp, "(
\97\
\94õ
\82Ì
\95\90\8aí;
\91\95\94õ
\82µ
\82Ä
\82¢
\82È
\82¢)");
1745 if (obj->owornmask & W_QUIVER) {
1746 switch (obj->oclass) {
1749 if (objects[obj->otyp].oc_skill == -P_BOW) {
1750 /* Ammo for a bow */
1752 Strcat(bp, " (in quiver)");
1754 Strcat(bp, "(
\96î
\93\9b\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1757 /* Ammo not for a bow */
1759 Strcat(bp, " (in quiver pouch)");
1761 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1765 /* Weapons not considered ammo */
1767 Strcat(bp, " (at the ready)");
1769 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1772 /* Small things and ammo not for a bow */
1779 Strcat(bp, " (in quiver pouch)");
1781 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1783 default: /* odd things */
1785 Strcat(bp, " (at the ready)");
1787 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1790 /* treat 'restoring' like suppress_price because shopkeeper and
1791 bill might not be available yet while restore is in progress
1792 (objects won't normally be formatted during that time, but if
1793 'perm_invent' is enabled then they might be) */
1794 if (iflags.suppress_price || restoring) {
1795 ; /* don't attempt to obtain any stop pricing, even if 'with_price' */
1796 } else if (is_unpaid(obj)) { /* in inventory or in container in invent */
1797 long quotedprice = unpaid_cost(obj, TRUE);
1800 Sprintf(eos(bp), " (%s, %s%ld %s)",
1801 obj->unpaid ? "unpaid" : "contents",
1802 globwt(obj, globbuf, &weightshown),
1803 quotedprice, currency(quotedprice));
1805 Sprintf(eos(bp), " (%s, %s%ld%s)",
1806 obj->unpaid ? "
\96¢
\95¥
\82¢" : "
\92\86\90g",
1807 globwt(obj, globbuf, &weightshown),
1808 quotedprice, currency(quotedprice));
1810 } else if (with_price) { /* on floor or in container on floor */
1812 long price = get_cost_of_shop_item(obj, &nochrg);
1816 Sprintf(eos(bp), " (%s, %s%ld %s)",
1817 nochrg ? "contents" : "for sale",
1818 globwt(obj, globbuf, &weightshown),
1819 price, currency(price));
1821 Sprintf(eos(bp), " (%s, %s%ld%s)",
1822 nochrg ? "
\92\86\90g" : "
\8f¤
\95i",
1823 globwt(obj, globbuf, &weightshown),
1824 price, currency(price));
1826 else if (nochrg > 0)
1828 Sprintf(eos(bp), " (%sno charge)",
1829 globwt(obj, globbuf, &weightshown));
1831 Sprintf(eos(bp), " (%s
\96³
\97¿)",
1832 globwt(obj, globbuf, &weightshown));
1835 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1836 if (!strncmp(prefix, "a ", 2)) {
1837 /* save current prefix, without "a "; might be empty */
1838 Strcpy(tmpbuf, prefix + 2);
1839 /* set prefix[] to "", "a ", or "an " */
1840 (void) just_an(prefix, *tmpbuf ? tmpbuf : bp);
1841 /* append remainder of original prefix */
1842 Strcat(prefix, tmpbuf);
1846 /* show weight for items (debug tourist info);
1847 "aum" is stolen from Crawl's "Arbitrary Unit of Measure" */
1848 if (wizard && iflags.wizweight) {
1849 /* wizard mode user has asked to see object weights;
1850 globs with shop pricing attached already include it */
1852 Sprintf(eos(bp), " (%u aum)", obj->owt);
1855 bp = strprepend(bp, prefix);
1856 #else /*JP:
\81u
\96¼
\95t
\82¯
\82ç
\82ê
\82½
\81v
\82ð
\96ß
\82·*/
1857 Strcat(preprefix, prefix);
1858 bp = strprepend(bp, preprefix);
1867 return doname_base(obj, (unsigned) 0);
1870 /* Name of object including price. */
1872 doname_with_price(obj)
1875 return doname_base(obj, DONAME_WITH_PRICE);
1878 /* "some" instead of precise quantity if obj->dknown not set */
1880 doname_vague_quan(obj)
1884 * If it hasn't been seen up close and quantity is more than one,
1885 * use "some" instead of the quantity: "some gold pieces" rather
1886 * than "25 gold pieces". This is suboptimal, to put it mildly,
1887 * because lookhere and pickup report the precise amount.
1888 * Picking the item up while blind also shows the precise amount
1889 * for inventory display, then dropping it while still blind leaves
1890 * obj->dknown unset so the count reverts to "some" for farlook.
1892 * TODO: add obj->qknown flag for 'quantity known' on stackable
1893 * items; it could overlay obj->cknown since no containers stack.
1895 return doname_base(obj, DONAME_VAGUE_QUAN);
1898 /* used from invent.c */
1900 not_fully_identified(otmp)
1903 /* gold doesn't have any interesting attributes [yet?] */
1904 if (otmp->oclass == COIN_CLASS)
1905 return FALSE; /* always fully ID'd */
1906 /* check fundamental ID hallmarks first */
1907 if (!otmp->known || !otmp->dknown
1909 || (!otmp->bknown && otmp->otyp != SCR_MAIL)
1913 || !objects[otmp->otyp].oc_name_known)
1915 if ((!otmp->cknown && (Is_container(otmp) || otmp->otyp == STATUE))
1916 || (!otmp->lknown && Is_box(otmp)))
1918 if (otmp->oartifact && undiscovered_artifact(otmp->oartifact))
1920 /* otmp->rknown is the only item of interest if we reach here */
1922 * Note: if a revision ever allows scrolls to become fireproof or
1923 * rings to become shockproof, this checking will need to be revised.
1924 * `rknown' ID only matters if xname() will provide the info about it.
1927 || (otmp->oclass != ARMOR_CLASS && otmp->oclass != WEAPON_CLASS
1928 && !is_weptool(otmp) /* (redundant) */
1929 && otmp->oclass != BALL_CLASS)) /* (useless) */
1931 else /* lack of `rknown' only matters for vulnerable objects */
1932 return (boolean) (is_rustprone(otmp) || is_corrodeable(otmp)
1933 || is_flammable(otmp));
1936 /* format a corpse name (xname() omits monster type; doname() calls us);
1937 eatcorpse() also uses us for death reason when eating tainted glob */
1939 corpse_xname(otmp, adjective, cxn_flags)
1941 const char *adjective;
1942 unsigned cxn_flags; /* bitmask of CXN_xxx values */
1944 /* some callers [aobjnam()] rely on prefix area that xname() sets aside */
1945 char *nambuf = nextobuf() + PREFIX;
1946 int omndx = otmp->corpsenm;
1948 boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
1949 /* suppress "the" from "the unique monster corpse" */
1953 no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
1954 /* include "the" for "the woodchuck corpse */
1955 the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
1956 /* include "an" for "an ogre corpse */
1957 any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
1958 /* leave off suffix (do_name() appends "corpse" itself) */
1959 omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
1961 glob = (otmp->otyp != CORPSE && otmp->globby);
1965 mname = OBJ_NAME(objects[otmp->otyp]); /* "glob of <monster>" */
1966 } else if (omndx == NON_PM) { /* paranoia */
1971 /* [Possible enhancement: check whether corpse has monster traits
1972 attached in order to use priestname() for priests and minions.] */
1973 } else if (omndx == PM_ALIGNED_PRIEST) {
1974 /* avoid "aligned priest"; it just exposes internal details */
1980 mname = mons[omndx].mname;
1981 if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
1982 mname = s_suffix(mname);
1984 /* don't precede personal name like "Medusa" with an article */
1985 if (type_is_pname(&mons[omndx]))
1987 /* always precede non-personal unique monster name like
1988 "Oracle" with "the" unless explicitly overridden */
1989 else if (the_unique_pm(&mons[omndx]) && !no_prefix)
1994 the_prefix = any_prefix = FALSE;
1995 else if (the_prefix)
1996 any_prefix = FALSE; /* mutually exclusive */
1999 /* can't use the() the way we use an() below because any capitalized
2000 Name causes it to assume a personal name and return Name as-is;
2001 that's usually the behavior wanted, but here we need to force "the"
2002 to precede capitalized unique monsters (pnames are handled above) */
2003 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2005 Strcat(nambuf, "the ");
2008 if (!adjective || !*adjective) {
2009 /* normal case: newt corpse */
2010 Strcat(nambuf, mname);
2012 /* adjective positioning depends upon format of monster name */
2013 if (possessive) /* Medusa's cursed partly eaten corpse */
2015 Sprintf(eos(nambuf), "%s %s", mname, adjective);
2017 Sprintf(eos(nambuf), "%s%s", mname, adjective);
2018 else /* cursed partly eaten troll corpse */
2020 Sprintf(eos(nambuf), "%s %s", adjective, mname);
2022 Sprintf(eos(nambuf), "%s%s", adjective, mname);
2023 /* in case adjective has a trailing space, squeeze it out */
2025 /* doname() might include a count in the adjective argument;
2026 if so, don't prepend an article */
2027 if (digit(*adjective))
2032 ; /* omit_corpse doesn't apply; quantity is always 1 */
2033 } else if (!omit_corpse) {
2035 Strcat(nambuf, " corpse");
2036 /* makeplural(nambuf) => append "s" to "corpse" */
2037 if (otmp->quan > 1L && !ignore_quan) {
2038 Strcat(nambuf, "s");
2039 any_prefix = FALSE; /* avoid "a newt corpses" */
2042 Strcat(nambuf, "
\82Ì
\8e\80\91Ì");
2046 /* it's safe to overwrite our nambuf after an() has copied
2047 its old value into another buffer */
2049 Strcpy(nambuf, an(nambuf));
2054 /* xname doesn't include monster type for "corpse"; cxname does */
2059 if (obj->otyp == CORPSE)
2060 return corpse_xname(obj, (const char *) 0, CXN_NORMAL);
2064 /* like cxname, but ignores quantity */
2066 cxname_singular(obj)
2069 if (obj->otyp == CORPSE)
2070 return corpse_xname(obj, (const char *) 0, CXN_SINGULAR);
2071 return xname_flags(obj, CXN_SINGULAR);
2074 /* treat an object as fully ID'd when it might be used as reason for death */
2079 struct obj save_obj;
2080 unsigned save_ocknown;
2081 char *buf, *save_ocuname, *save_oname = (char *) 0;
2083 /* bypass object twiddling for artifacts */
2085 return bare_artifactname(obj);
2087 /* remember original settings for core of the object;
2088 oextra structs other than oname don't matter here--since they
2089 aren't modified they don't need to be saved and restored */
2092 save_oname = ONAME(obj);
2094 /* killer name should be more specific than general xname; however, exact
2095 info like blessed/cursed and rustproof makes things be too verbose */
2096 obj->known = obj->dknown = 1;
2097 obj->bknown = obj->rknown = obj->greased = 0;
2098 /* if character is a priest[ess], bknown will get toggled back on */
2099 if (obj->otyp != POT_WATER)
2100 obj->blessed = obj->cursed = 0;
2102 obj->bknown = 1; /* describe holy/unholy water as such */
2103 /* "killed by poisoned <obj>" would be misleading when poison is
2104 not the cause of death and "poisoned by poisoned <obj>" would
2105 be redundant when it is, so suppress "poisoned" prefix */
2107 /* strip user-supplied name; artifacts keep theirs */
2108 if (!obj->oartifact && save_oname)
2109 ONAME(obj) = (char *) 0;
2110 /* temporarily identify the type of object */
2111 save_ocknown = objects[obj->otyp].oc_name_known;
2112 objects[obj->otyp].oc_name_known = 1;
2113 save_ocuname = objects[obj->otyp].oc_uname;
2114 objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
2116 /* format the object */
2117 if (obj->otyp == CORPSE) {
2118 buf = corpse_xname(obj, (const char *) 0, CXN_NORMAL);
2119 } else if (obj->otyp == SLIME_MOLD) {
2120 /* concession to "most unique deaths competition" in the annual
2121 devnull tournament, suppress player supplied fruit names because
2122 those can be used to fake other objects and dungeon features */
2125 Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
2127 Strcpy(buf, "
\8aë
\8c¯
\82È
\82Ë
\82Î
\82Ë
\82Î
\83J
\83r");
2131 /* apply an article if appropriate; caller should always use KILLED_BY */
2132 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
2133 if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
2134 buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
2137 objects[obj->otyp].oc_name_known = save_ocknown;
2138 objects[obj->otyp].oc_uname = save_ocuname;
2139 *obj = save_obj; /* restore object's core settings */
2140 if (!obj->oartifact && save_oname)
2141 ONAME(obj) = save_oname;
2146 /* xname,doname,&c with long results reformatted to omit some stuff */
2148 short_oname(obj, func, altfunc, lenlimit)
2150 char *FDECL((*func), (OBJ_P)), /* main formatting routine */
2151 *FDECL((*altfunc), (OBJ_P)); /* alternate for shortest result */
2154 struct obj save_obj;
2155 char unamebuf[12], onamebuf[12], *save_oname, *save_uname, *outbuf;
2157 outbuf = (*func)(obj);
2158 if ((unsigned) strlen(outbuf) <= lenlimit)
2161 /* shorten called string to fairly small amount */
2162 save_uname = objects[obj->otyp].oc_uname;
2163 if (save_uname && strlen(save_uname) >= sizeof unamebuf) {
2164 (void) strncpy(unamebuf, save_uname, sizeof unamebuf - 4);
2165 Strcpy(unamebuf + sizeof unamebuf - 4, "...");
2166 objects[obj->otyp].oc_uname = unamebuf;
2167 releaseobuf(outbuf);
2168 outbuf = (*func)(obj);
2169 objects[obj->otyp].oc_uname = save_uname; /* restore called string */
2170 if ((unsigned) strlen(outbuf) <= lenlimit)
2174 /* shorten named string to fairly small amount */
2175 save_oname = has_oname(obj) ? ONAME(obj) : 0;
2176 if (save_oname && strlen(save_oname) >= sizeof onamebuf) {
2177 (void) strncpy(onamebuf, save_oname, sizeof onamebuf - 4);
2178 Strcpy(onamebuf + sizeof onamebuf - 4, "...");
2179 ONAME(obj) = onamebuf;
2180 releaseobuf(outbuf);
2181 outbuf = (*func)(obj);
2182 ONAME(obj) = save_oname; /* restore named string */
2183 if ((unsigned) strlen(outbuf) <= lenlimit)
2187 /* shorten both called and named strings;
2188 unamebuf and onamebuf have both already been populated */
2189 if (save_uname && strlen(save_uname) >= sizeof unamebuf && save_oname
2190 && strlen(save_oname) >= sizeof onamebuf) {
2191 objects[obj->otyp].oc_uname = unamebuf;
2192 ONAME(obj) = onamebuf;
2193 releaseobuf(outbuf);
2194 outbuf = (*func)(obj);
2195 if ((unsigned) strlen(outbuf) <= lenlimit) {
2196 objects[obj->otyp].oc_uname = save_uname;
2197 ONAME(obj) = save_oname;
2202 /* still long; strip several name-lengthening attributes;
2203 called and named strings are still in truncated form */
2205 obj->bknown = obj->rknown = obj->greased = 0;
2206 obj->oeroded = obj->oeroded2 = 0;
2207 releaseobuf(outbuf);
2208 outbuf = (*func)(obj);
2209 if (altfunc && (unsigned) strlen(outbuf) > lenlimit) {
2210 /* still long; use the alternate function (usually one of
2211 the jackets around minimal_xname()) */
2212 releaseobuf(outbuf);
2213 outbuf = (*altfunc)(obj);
2215 /* restore the object */
2218 ONAME(obj) = save_oname;
2220 objects[obj->otyp].oc_uname = save_uname;
2222 /* use whatever we've got, whether it's too long or not */
2227 * Used if only one of a collection of objects is named (e.g. in eat.c).
2230 singular(otmp, func)
2231 register struct obj *otmp;
2232 char *FDECL((*func), (OBJ_P));
2237 /* using xname for corpses does not give the monster type */
2238 if (otmp->otyp == CORPSE && func == xname)
2241 savequan = otmp->quan;
2243 nam = (*func)(otmp);
2244 otmp->quan = savequan;
2248 /* pick "", "a ", or "an " as article for 'str'; used by an() and doname() */
2250 just_an(outbuf, str)
2254 #if 0 /*JP*//*
\95s
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2260 /* single letter; might be used for named fruit */
2261 Strcpy(outbuf, index("aefhilmnosx", c0) ? "an " : "a ");
2262 } else if (!strncmpi(str, "the ", 4) || !strcmpi(str, "molten lava")
2263 || !strcmpi(str, "iron bars") || !strcmpi(str, "ice")) {
2266 if ((index(vowels, c0) && strncmpi(str, "one-", 4)
2267 && strncmpi(str, "eucalyptus", 10) && strncmpi(str, "unicorn", 7)
2268 && strncmpi(str, "uranium", 7) && strncmpi(str, "useful", 6))
2269 || (index("x", c0) && !index(vowels, lowc(str[1]))))
2270 Strcpy(outbuf, "an ");
2272 Strcpy(outbuf, "a ");
2284 char *buf = nextobuf();
2286 if (!str || !*str) {
2287 impossible("Alphabet soup: 'an(%s)'.", str ? "\"\"" : "<null>");
2288 return strcpy(buf, "an []");
2290 (void) just_an(buf, str);
2291 return strcat(buf, str);
2298 char *tmp = an(str);
2300 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2307 * Prepend "the" if necessary; assumes str is a subject derived from xname.
2308 * Use type_is_pname() for monster names, not the(). the() is idempotent.
2314 char *buf = nextobuf();
2315 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2316 boolean insert_the = FALSE;
2318 if (!str || !*str) {
2319 impossible("Alphabet soup: 'the(%s)'.", str ? "\"\"" : "<null>");
2320 return strcpy(buf, "the []");
2322 if (!strncmpi(str, "the ", 4)) {
2323 buf[0] = lowc(*str);
2324 Strcpy(&buf[1], str + 1);
2326 } else if (*str < 'A' || *str > 'Z'
2327 /* treat named fruit as not a proper name, even if player
2328 has assigned a capitalized proper name as his/her fruit */
2329 || fruit_from_name(str, TRUE, (int *) 0)) {
2330 /* not a proper name, needs an article */
2333 /* Probably a proper name, might not need an article */
2334 register char *tmp, *named, *called;
2337 /* some objects have capitalized adjectives in their names */
2338 if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0)
2339 && (tmp[1] < 'A' || tmp[1] > 'Z')) {
2341 } else if (tmp && index(str, ' ') < tmp) { /* has spaces */
2342 /* it needs an article if the name contains "of" */
2343 tmp = strstri(str, " of ");
2344 named = strstri(str, " named ");
2345 called = strstri(str, " called ");
2346 if (called && (!named || called < named))
2349 if (tmp && (!named || tmp < named)) /* found an "of" */
2351 /* stupid special case: lacks "of" but needs "the" */
2352 else if (!named && (l = strlen(str)) >= 31
2353 && !strcmp(&str[l - 31],
2354 "Platinum Yendorian Express Card"))
2359 Strcpy(buf, "the ");
2364 #else /*
\92P
\82É
\83R
\83s
\81[*/
2374 char *tmp = the(str);
2376 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2385 register struct obj *otmp;
2386 register const char *verb;
2392 /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */
2398 char prefix[PREFIX];
2399 char *bp = cxname(otmp);
2401 if (otmp->quan != 1L) {
2402 Sprintf(prefix, "%ld ", otmp->quan);
2403 bp = strprepend(bp, prefix);
2407 Strcat(bp, otense(otmp, verb));
2413 /* combine yname and aobjnam eg "your count cxname(otmp)" */
2419 char *s = aobjnam(obj, verb);
2421 /* leave off "your" for most of your artifacts, but prepend
2422 * "your" for unique objects and "foo of bar" quest artifacts */
2423 if (!carried(obj) || !obj_is_pname(obj)
2424 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2425 char *outbuf = shk_your(nextobuf(), obj);
2426 int space_left = BUFSZ - 1 - strlen(outbuf);
2428 s = strncat(outbuf, s, space_left);
2433 /* combine Yname2 and aobjnam eg "Your count cxname(otmp)" */
2439 register char *s = yobjnam(obj, verb);
2447 /* like aobjnam, but prepend "The", not count, and use xname */
2453 char *bp = The(xname(otmp));
2455 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2458 Strcat(bp, otense(otmp, verb));
2464 /* capitalized variant of doname() */
2469 char *s = doname(obj);
2475 #if 0 /* stalled-out work in progress */
2476 /* Doname2() for itemized buying of 'obj' from a shop */
2481 static const char and_contents[] = " and its contents";
2482 char *p = doname(obj);
2484 if (Is_container(obj) && !obj->cknown) {
2486 if ((int) strlen(p) + sizeof and_contents - 1 < BUFSZ - PREFIX)
2487 Strcat(p, and_contents);
2490 p = strprepend(p, "Contents of ");
2499 /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */
2504 char *s = cxname(obj);
2506 /* leave off "your" for most of your artifacts, but prepend
2507 * "your" for unique objects and "foo of bar" quest artifacts */
2508 if (!carried(obj) || !obj_is_pname(obj)
2509 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2510 char *outbuf = shk_your(nextobuf(), obj);
2511 int space_left = BUFSZ - 1 - strlen(outbuf);
2513 s = strncat(outbuf, s, space_left);
2519 /* capitalized variant of yname() */
2524 char *s = yname(obj);
2532 /* returns "your minimal_xname(obj)"
2533 * or "Foobar's minimal_xname(obj)"
2534 * or "the minimal_xname(obj)"
2540 char *outbuf = nextobuf();
2541 char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */
2543 int space_left = BUFSZ - 1 - strlen(s);
2545 return strncat(s, minimal_xname(obj), space_left);
2547 int space_left = BUFSZ - strlen(s);
2549 return strncat(s, minimal_xname(obj), space_left);
2553 /* capitalized variant of ysimple_name() */
2558 char *s = ysimple_name(obj);
2566 /* "scroll" or "scrolls" */
2571 char *simpleoname = minimal_xname(obj);
2573 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2574 if (obj->quan != 1L)
2575 simpleoname = makeplural(simpleoname);
2580 /* "a scroll" or "scrolls"; "a silver bell" or "the Bell of Opening" */
2585 char *simpleoname = simpleonames(obj);
2586 int otyp = obj->otyp;
2588 /* prefix with "the" if a unique item, or a fake one imitating same,
2589 has been formatted with its actual name (we let typename() handle
2590 any `known' and `dknown' checking necessary) */
2591 if (otyp == FAKE_AMULET_OF_YENDOR)
2592 otyp = AMULET_OF_YENDOR;
2593 if (objects[otyp].oc_unique
2594 && !strcmp(simpleoname, OBJ_NAME(objects[otyp])))
2595 return the(simpleoname);
2597 /* simpleoname is singular if quan==1, plural otherwise */
2598 if (obj->quan == 1L)
2599 simpleoname = an(simpleoname);
2603 /* "the scroll" or "the scrolls" */
2608 char *simpleoname = simpleonames(obj);
2610 return the(simpleoname);
2613 /* artifact's name without any object type or known/dknown/&c feedback */
2615 bare_artifactname(obj)
2620 if (obj->oartifact) {
2621 outbuf = nextobuf();
2622 Strcpy(outbuf, artiname(obj->oartifact));
2624 if (!strncmp(outbuf, "The ", 4))
2625 outbuf[0] = lowc(outbuf[0]);
2628 outbuf = xname(obj);
2634 static const char *wrp[] = {
2635 "wand", "ring", "potion", "scroll", "gem",
2636 "amulet", "spellbook", "spell book",
2637 /* for non-specific wishes */
2638 "weapon", "armor", "tool", "food", "comestible",
2641 static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
2642 SCROLL_CLASS, GEM_CLASS, AMULET_CLASS,
2643 SPBOOK_CLASS, SPBOOK_CLASS, WEAPON_CLASS,
2644 ARMOR_CLASS, TOOL_CLASS, FOOD_CLASS,
2647 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2648 /* return form of the verb (input plural) if xname(otmp) were the subject */
2657 * verb is given in plural (without trailing s). Return as input
2658 * if the result of xname(otmp) would be plural. Don't bother
2659 * recomputing xname(otmp) at this time.
2661 if (!is_plural(otmp))
2662 return vtense((char *) 0, verb);
2669 /* various singular words that vtense would otherwise categorize as plural;
2670 also used by makesingular() to catch some special cases */
2671 static const char *const special_subjs[] = {
2672 "erinys", "manes", /* this one is ambiguous */
2673 "Cyclops", "Hippocrates", "Pelias", "aklys",
2674 "amnesia", "detect monsters", "paralysis", "shape changers",
2676 /* note: "detect monsters" and "shape changers" are normally
2677 caught via "<something>(s) of <whatever>", but they can be
2678 wished for using the shorter form, so we include them here
2679 to accommodate usage by makesingular during wishing */
2682 /* return form of the verb (input plural) for present tense 3rd person subj */
2685 register const char *subj;
2686 register const char *verb;
2688 char *buf = nextobuf(), *bspot;
2690 const char *sp, *spot;
2691 const char *const *spec;
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).
2700 * Special case: allow null sobj to get the singular 3rd person
2701 * present tense form so we don't duplicate this code elsewhere.
2704 if (!strncmpi(subj, "a ", 2) || !strncmpi(subj, "an ", 3))
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)) {
2716 len = (int) strlen(subj);
2718 spot = subj + len - 1;
2721 * plural: anything that ends in 's', but not '*us' or '*ss'.
2722 * Guess at a few other special cases that makeplural creates.
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))
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))
2743 return strcpy(buf, verb);
2746 * 3rd person plural doesn't end in telltale 's';
2747 * 2nd person singular behaves as if plural.
2749 if (!strcmpi(subj, "they") || !strcmpi(subj, "you"))
2750 return strcpy(buf, verb);
2755 len = (int) strlen(buf);
2756 bspot = buf + len - 1;
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");
2772 Strcasecpy(bspot + 1, "s");
2781 const char *sing, *plur;
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[] = {
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" },
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" },
2805 { "passerby", "passersby" },
2806 { "rtex", "rtices" }, /* vortex */
2807 { "serum", "sera" },
2808 { "staff", "staves" },
2809 { "tooth", "teeth" },
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. */
2829 /* singularize/pluralize decisions common to both makesingular & makeplural */
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[] */
2836 const struct sing_plur *sp;
2837 const char *same, *other, *const *as;
2839 int baselen = strlen(basestr);
2841 for (as = as_is; *as; ++as) {
2842 al = (int) strlen(*as);
2843 if (!BSTRCMPI(basestr, endstring - al, *as))
2847 for (as = alt_as_is; *as; ++as) {
2848 al = (int) strlen(*as);
2849 if (!BSTRCMPI(basestr, endstring - al, *as))
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")))
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")) {
2865 Strcasecpy(endstring, "s");
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");
2877 if (baselen > 2 && !strcmpi(endstring - 3, "man")
2878 && badman(basestr, to_plural)) {
2879 Strcasecpy(endstring, "s");
2883 if (baselen > 2 && !strcmpi(endstring - 3, "men")
2884 && badman(basestr, to_plural))
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 */
2904 /* searches for common compounds, ex. lump of royal jelly */
2906 singplur_compound(str)
2909 /* if new entries are added, be sure to keep compound_start[] in sync */
2910 static const char *const compounds[] =
2912 " of ", " labeled ", " called ",
2913 " named ", " above", /* lurkers above */
2914 " versus ", " from ", " in ",
2915 " on ", " a la ", " with", /* " with "? */
2916 " de ", " d'", " du ",
2918 }, /* list of first characters for all compounds[] entries */
2919 compound_start[] = " -";
2921 const char *const *cmpd;
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))
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)))
2935 /* wasn't recognized as a compound phrase */
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
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...
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.
2956 * Also misused by muse.c to convert 1st person present verbs to 2nd person.
2957 * 3.6.0: made case-insensitive.
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;
2970 while (*oldstr == ' ')
2972 if (!oldstr || !*oldstr) {
2973 impossible("plural of null?");
2977 Strcpy(str, oldstr);
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.
2985 if (!strncmpi(str, "pair of ", 8))
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);
2996 while (spot > str && *spot == ' ')
2997 spot--; /* Strip blanks from end */
2999 /* Now spot is the last character of the string */
3003 /* Single letters */
3004 if (len == 1 || !letter(*spot)) {
3005 Strcpy(spot + 1, "'s");
3009 /* dispense with some words which don't need pluralization */
3011 static const char *const already_plural[] = {
3012 "ae", /* algae, larvae, &c */
3016 /* spot+1: synch up with makesingular's usage */
3017 if (singplur_lookup(str, spot + 1, TRUE, already_plural))
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")))
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");
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");
3044 /* ium/ia (mycelia, baluchitheria) */
3045 if (len >= 3 && !strcmpi(spot - 2, "ium")) {
3046 Strcasecpy(spot - 2, "ia");
3049 /* algae, larvae, hyphae (another fungus part) */
3050 if ((len >= 4 && !strcmpi(spot - 3, "alga"))
3052 && (!strcmpi(spot - 4, "hypha") || !strcmpi(spot - 4, "larva")))
3053 || (len >= 6 && !strcmpi(spot - 5, "amoeba"))
3054 || (len >= 8 && (!strcmpi(spot - 7, "vertebra")))) {
3056 Strcasecpy(spot + 1, "e");
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");
3066 /* sis/ses (nemesis) */
3067 if (len >= 3 && !strcmpi(spot - 2, "sis")) {
3068 Strcasecpy(spot - 1, "es");
3071 /* matzoh/matzot, possible food name */
3073 && (!strcmpi(spot - 5, "matzoh") || !strcmpi(spot - 5, "matzah"))) {
3074 Strcasecpy(spot - 1, "ot"); /* oh/ah -> ot */
3078 && (!strcmpi(spot - 4, "matzo") || !strcmpi(spot - 4, "matza"))) {
3079 Strcasecpy(spot, "ot"); /* o/a -> ot */
3083 /* note: -eau/-eaux (gateau, bordeau...) */
3084 /* note: ox/oxen, VAX/VAXen, goose/geese */
3088 /* codex/spadix/neocortex and the like */
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 */
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 */
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 */
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 */
3118 /* Default: append an 's' */
3119 Strcasecpy(spot + 1, "s");
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);
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.
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.
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.
3144 makesingular(oldstr)
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();
3153 while (*oldstr == ' ')
3155 if (!oldstr || !*oldstr) {
3156 impossible("singular of null?");
3161 bp = strcpy(str, oldstr);
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);
3170 /* dispense with some words which don't need singularization */
3171 if (singplur_lookup(bp, p, FALSE, special_subjs))
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 */
3189 Strcasecpy(p - 3, "y"); /* ies -> y */
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"))
3199 Strcasecpy(p - 3, "f"); /* ves -> f */
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 */
3214 } /* else fall through to mins */
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"))
3221 } else if (!BSTRCMPI(bp, p - 2, "ss")
3222 || !BSTRCMPI(bp, p - 5, " lens")
3223 || (p - 4 == bp && !strcmpi(p - 4, "lens"))) {
3227 *(p - 1) = '\0'; /* drop s */
3229 } else { /* input doesn't end in 's' */
3231 if (!BSTRCMPI(bp, p - 3, "men")
3232 && !badman(bp, FALSE)) {
3233 Strcasecpy(p - 2, "an");
3236 /* matzot -> matzo, algae -> alga */
3237 if (!BSTRCMPI(bp, p - 6, "matzot") || !BSTRCMPI(bp, p - 2, "ae")) {
3238 *(p - 1) = '\0'; /* drop t/e */
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 */
3247 /* here we cannot find the plural suffix */
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...] */
3257 #else /*JP*//*
\90V
\82µ
\82¢
\83o
\83b
\83t
\83@
\82Í
\95K
\97v*/
3258 char *str = nextobuf();
3259 Strcpy(str, oldstr);
3266 badman(basestr, to_plural)
3267 const char *basestr;
3268 boolean to_plural; /* true => makeplural, false => makesingular */
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",
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",
3286 const char *endstr, *spot;
3288 if (!basestr || strlen(basestr) < 4)
3291 endstr = eos((char *) basestr);
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) == ' '))
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) == ' '))
3314 /* compare user string against object name string using fuzzy matching */
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 */
3321 static NEARDATA const char detect_SP[] = "detect ",
3322 SP_detection[] = " detection";
3323 char *p, buf[BUFSZ];
3325 /* ignore spaces & hyphens and upper/lower case when comparing */
3326 if (fuzzymatch(u_str, o_str, " -", TRUE))
3329 if (retry_inverted) {
3330 const char *u_of, *o_of;
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)
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)
3349 return fuzzymatch(u_str, buf, " -", TRUE);
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>" */
3370 Strcat(strcpy(buf, detect_SP), u_str);
3371 /* "detect monster" -> "detect monsters" */
3372 if (!strcmpi(u_str, "monster"))
3375 return fuzzymatch(buf, o_str, " -", TRUE);
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 */
3386 return fuzzymatch(buf, o_str, " -", TRUE);
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);
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);
3409 const char *name, oclass;
3410 int f_o_range, l_o_range;
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 },
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 {
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 },
3463 { "camera", EXPENSIVE_CAMERA },
3464 { "tee shirt", T_SHIRT },
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 },
3492 rnd_otyp_by_wpnskill(skill)
3496 short otyp = STRANGE_OBJECT;
3498 for (i = bases[WEAPON_CLASS];
3499 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3500 if (objects[i].oc_skill == skill) {
3506 for (i = bases[WEAPON_CLASS];
3507 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3508 if (objects[i].oc_skill == skill)
3517 rnd_otyp_by_namedesc(name, oclass, xtra_prob)
3520 int xtra_prob; /* to force 0% random generation items to also be considered */
3523 short validobjs[NUM_OBJECTS];
3524 register const char *zn;
3525 int prob, maxprob = 0;
3527 if (!name || !*name)
3528 return STRANGE_OBJECT;
3530 memset((genericptr_t) validobjs, 0, sizeof validobjs);
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.]
3540 for (i = oclass ? bases[(int) oclass] : STRANGE_OBJECT + 1;
3541 i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass);
3543 /* don't match extra descriptions (w/o real name) */
3544 if ((zn = OBJ_NAME(objects[i])) == 0)
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
3552 if (i == FAKE_AMULET_OF_YENDOR)
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);
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)
3570 return validobjs[i];
3572 return STRANGE_OBJECT;
3579 return (int) rnd_otyp_by_namedesc("shiny", oclass, 0);
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),
3591 readobjnam(bp, no_wish)
3593 struct obj *no_wish;
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;
3604 int tmp, tinv, tvariety;
3608 int wetness, gsize = 0;
3610 int ftype = context.current_fruit;
3612 char fruitbuf[BUFSZ], globbuf[BUFSZ];
3614 char fruitbuf[BUFSZ];
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
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.
3631 char *un, *dn, *actualn, *origbp = bp;
3632 const char *name = 0;
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;
3644 contents = UNDEFINED;
3646 actualn = dn = un = 0;
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] */
3656 if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil")
3657 || !strcmpi(bp, "none"))
3659 if (!strcmpi(bp, "
\82È
\82µ") || !strcmpi(bp, "
\96³
\82µ"))
3662 /* save the [nearly] unmodified choice string */
3663 Strcpy(fruitbuf, bp);
3670 if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) {
3672 } else if (!strncmpi(bp, "the ", l = 4)) {
3673 ; /* just increment `bp' by `l' below */
3674 } else if (!cnt && digit(*bp) && strcmp(bp, "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))
3693 } else if (*bp == '+' || *bp == '-') {
3694 spesgn = (*bp++ == '+') ? 1 : -1;
3702 } else if (!strncmpi(bp, "blessed ", l = 8)
3703 || !strncmpi(bp, "holy ", l = 5)) {
3705 } else if (!strncmpi(bp, "
\8fj
\95\9f\82³
\82ê
\82½", l = 10)) {
3709 } else if (!strncmpi(bp, "moist ", l = 6)
3710 || !strncmpi(bp, "wet ", l = 4)) {
3712 } else if (!strncmpi(bp, "
\8e¼
\82Á
\82½", l = 6)
3713 || !strncmpi(bp, "
\94G
\82ê
\82½", l = 6)) {
3716 if (!strncmpi(bp, "wet ", 4))
3718 if (!strncmpi(bp, "
\94G
\82ê
\82½", 6))
3720 wetness = rn2(3) + 3;
3724 } else if (!strncmpi(bp, "cursed ", l = 7)
3725 || !strncmpi(bp, "unholy ", l = 7)) {
3727 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82½", l = 8)) {
3731 } else if (!strncmpi(bp, "uncursed ", l = 9)) {
3733 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", l = 14)) {
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)) {
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)) {
3751 } else if (!strncmpi(bp, "lit ", l = 4)
3752 || !strncmpi(bp, "burning ", l = 8)) {
3754 } else if (!strncmpi(bp, "
\8cõ
\82Á
\82Ä
\82¢
\82é", l = 10)
3755 || !strncmpi(bp, "
\94R
\82¦
\82Ä
\82¢
\82é", l = 10)) {
3759 } else if (!strncmpi(bp, "unlit ", l = 6)
3760 || !strncmpi(bp, "extinguished ", l = 13)) {
3762 } else if (!strncmpi(bp, "
\8fÁ
\82¦
\82Ä
\82¢
\82é", l = 10)) {
3765 /* "unlabeled" and "blank" are synonymous */
3767 } else if (!strncmpi(bp, "unlabeled ", l = 10)
3768 || !strncmpi(bp, "unlabelled ", l = 11)
3769 || !strncmpi(bp, "blank ", l = 6)) {
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)) {
3776 } else if (!strncmpi(bp, "poisoned ", l = 9)) {
3778 } else if (!strncmpi(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", l = 12)) {
3781 /* "trapped" recognized but not honored outside wizard mode */
3782 } else if (!strncmpi(bp, "trapped ", l = 8)) {
3783 trapped = 0; /* undo any previous "untrapped" */
3786 } else if (!strncmpi(bp, "untrapped ", l = 10)) {
3787 trapped = 2; /* not trapped */
3788 /* locked, unlocked, broken: box/chest lock states */
3790 } else if (!strncmpi(bp, "locked ", l = 7)) {
3792 } else if (!strncmpi(bp, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½", l = 12)) {
3794 locked = 1, unlocked = broken = 0;
3796 } else if (!strncmpi(bp, "unlocked ", l = 9)) {
3798 } else if (!strncmpi(bp, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢", l = 18)) {
3800 unlocked = 1, locked = broken = 0;
3802 } else if (!strncmpi(bp, "broken ", l = 7)) {
3804 } else if (!strncmpi(bp, "
\8c®
\82Ì
\89ó
\82ê
\82½", l = 10)) {
3806 broken = 1, locked = unlocked = 0;
3808 } else if (!strncmpi(bp, "greased ", l = 8)) {
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)) {
3815 } else if (!strncmpi(bp, "very ", l = 5)) {
3817 } else if (!strncmpi(bp, "
\82Æ
\82Ä
\82à", l = 6)) {
3819 /* very rusted very heavy iron ball */
3822 } else if (!strncmpi(bp, "thoroughly ", l = 11)) {
3824 } else if (!strncmpi(bp, "
\82©
\82È
\82è", l = 6)) {
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)) {
3833 } else if (!strncmpi(bp, "
\8eK
\82Ñ
\82½", l = 6)
3834 || !strncmpi(bp, "
\94R
\82¦
\82½", l = 6)) {
3839 } else if (!strncmpi(bp, "corroded ", l = 9)
3840 || !strncmpi(bp, "rotted ", l = 7)) {
3842 } else if (!strncmpi(bp, "
\95\85\90H
\82µ
\82½", l = 8)
3843 || !strncmpi(bp, "
\95\85\82Á
\82½", l = 6)) {
3848 } else if (!strncmpi(bp, "partly eaten ", l = 13)
3849 || !strncmpi(bp, "partially eaten ", l = 16)) {
3851 } else if (!strncmpi(bp, "
\90H
\82×
\82©
\82¯
\82Ì", l = 10)) {
3855 } else if (!strncmpi(bp, "historic ", l = 9)) {
3857 } else if (!strncmpi(bp, "
\97ð
\8ej
\93I
\82È", l = 8)) {
3861 } else if (!strncmpi(bp, "diluted ", l = 8)) {
3863 } else if (!strncmpi(bp, "
\94\96\82Ü
\82Á
\82½", l = 8)) {
3867 } else if (!strncmpi(bp, "empty ", l = 6)) {
3869 } else if (!strncmpi(bp, "
\8bó
\82Á
\82Û
\82Ì", l = 8)) {
3873 } else if (!strncmpi(bp, "small ", l = 6)) { /* glob sizes */
3875 } else if (!strncmpi(bp, "
\8f¬
\82³
\82¢", l = 6)) { /* glob sizes */
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"))
3886 } else if (!strncmpi(bp, "medium ", l = 7)) {
3888 } else if (!strncmpi(bp, "
\92\86\82
\82ç
\82¢
\82Ì", l = 10)) {
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) */
3895 } else if (!strncmpi(bp, "large ", l = 6)) {
3897 } else if (!strncmpi(bp, "
\91å
\82«
\82¢", l = 6)) {
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"))
3904 /* "very large " had "very " peeled off on previous iteration */
3905 gsize = (very != 1) ? 3 : 4;
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;
3915 p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */
3916 ++p; /* advance past '(' */
3917 if (!strncmpi(p, "lit)", 4)) {
3919 p += 4 - 1; /* point at ')' */
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 ..."]
3937 keeptrailingchars = FALSE;
3942 if (keeptrailingchars) {
3945 /* 'pp' points at 'pb's terminating '\0',
3946 'p' points at ')' and will be incremented past it */
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().
3958 spesgn = -1; /* cheaters get what they deserve */
3961 if (spe > SCHAR_LIM)
3963 if (rechrg < 0 || rechrg > 7)
3964 rechrg = 7; /* recharge_limit */
3966 /* now we have the actual name, as delivered by xname, say
3967 * green potions called whisky
3968 * scrolls labeled "QWERTY"
3971 * very heavy iron ball named hoei
3975 if ((p = strstri(bp, " named ")) != 0) {
3979 if ((p = strstri(bp, " called ")) != 0) {
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)
3986 for (i = 0; i < SIZE(o_ranges); i++)
3987 if (!strcmpi(bp, o_ranges[i].name)) {
3988 oclass = o_ranges[i].oclass;
3993 if ((p = strstri(bp, " labeled ")) != 0) {
3996 } else if ((p = strstri(bp, " labelled ")) != 0) {
4000 if ((p = strstri(bp, " of spinach")) != 0) {
4005 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82µ
\82È
\82¢*/
4007 * Skip over "pair of ", "pairs of", "set of" and "sets of".
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.
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
4019 if (!strncmpi(bp, "pair of ", 8)) {
4022 } else if (!strncmpi(bp, "pairs of ", 9)) {
4026 } else if (!strncmpi(bp, "set of ", 7)) {
4028 } else if (!strncmpi(bp, "sets of ", 8)) {
4034 /* intercept pudding globs here; they're a valid wish target,
4035 * but we need them to not get treated like a corpse.
4037 * also don't let player wish for multiple globs.
4039 i = (int) strlen(bp);
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);
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;
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).
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")) {
4074 tmp = tin_variety_txt(p + 7, &tinv);
4076 mntmp = name_to_mon(p + 7 + tmp);
4080 } else if ((p = strstri(bp, " of ")) != 0
4081 && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
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 */
4096 mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
4097 bp += (mntmp != mntmptoo) ? (int) strlen(mons[mntmp].mname)
4101 } else if (!strncmpi(bp, "s ", 2)) {
4103 } else if (!strncmpi(bp, "es ", 3)) {
4105 } else if (!*bp && !actualn && !dn && !un && !oclass) {
4106 /* no referent; they don't really mean a monster type */
4114 /*JP
\81u(
\89ö
\95¨
\96¼)
\82Ì
\89ò
\81v
\82Í
\8cÂ
\81X
\82ÉID
\82ª
\82 \82é
\82Ì
\82Å
\95Ê
\88µ
\82¢ */
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 */
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;
4132 #if 0 /*JP*//*
\92P
\90\94\89»
\82Í
\82µ
\82È
\82¢*/
4133 /* first change to singular if necessary */
4135 char *sng = makesingular(bp);
4137 if (strcmp(bp, sng)) {
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) */
4148 const struct alt_spellings *as = spellings;
4151 if (fuzzymatch(bp, as->sp, " -", TRUE)) {
4157 /* can't use spellings list for this one due to shuffling */
4158 if (!strncmpi(bp, "grey spell", 10))
4161 if ((p = strstri(bp, "armour")) != 0) {
4162 /* skip past "armo", then copy remainder beyond "u" */
4164 while ((*p = *(p + 1)) != '\0')
4165 ++p; /* self terminating */
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 */
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 */
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 */
4197 if (!BSTRCMPI(bp, p - 10, "holy water")) {
4199 if ((p - bp) >= 12 && *(p - 12) == 'u')
4200 iscursed = 1; /* unholy water */
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")) {
4211 if (!BSTRCMPI(bp, p - 8, "
\95s
\8fò
\82È
\90\85")) {
4218 if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
4220 if (unlabeled && !BSTRCMPI(bp, p - 4, "
\8aª
\95¨")) {
4222 typ = SCR_BLANK_PAPER;
4226 if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
4228 if (unlabeled && !BSTRCMPI(bp, p - 6, "
\96\82\96@
\8f\91")) {
4230 typ = SPE_BLANK_PAPER;
4233 /* specific food rather than color of gem/potion/spellbook[/scales] */
4234 if (!BSTRCMPI(bp, p - 6, "orange") && mntmp == NON_PM) {
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)
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) {
4250 if (!BSTRCMPI(bp, p - 4, "
\8bà
\89Ý") || !BSTRCMPI(bp, p - 8, "
\83S
\81[
\83\8b\83h")
4251 || *bp == GOLD_SYM) {
4253 if (cnt > 5000 && !wizard)
4257 otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
4258 otmp->quan = (long) cnt;
4259 otmp->owt = weight(otmp);
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)) {
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¢
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]);
4291 /* check for "<class> [ of ] something" */
4292 if (!strncmpi(bp, wrp[i], j)) {
4294 if (oclass != AMULET_CLASS) {
4296 if (!strncmpi(bp, " of ", 4))
4298 /* else if(*bp) ?? */
4303 /* check for "something <class>" */
4304 if (!BSTRCMPI(bp, p - j, wrp[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) {
4314 if (p > bp && p[-1] == ' ')
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;
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.
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" */
4351 ++zp; /* embedded space is optional */
4352 if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
4354 if (trapped == 2 || !strcmpi(zp, " object")) {
4355 /* "untrapped <foo>" or "<foo> object" */
4356 typ = beartrap ? BEARTRAP : LAND_MINE;
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);
4362 /* use canonical trap spelling, skip object matching */
4363 Strcpy(bp, defsyms[idx].explanation);
4366 /* [no prefix or suffix; we're going to end up matching
4367 the object name and getting a disarmed trap object] */
4371 #if 0 /*JP*//* mail/armor
\8aÖ
\98A
\82Å
\82Ì
\82Ý
\8eg
\82¤
\83\89\83x
\83\8b */
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);
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';
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;
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))
4400 if (!strncmpi(g, "piece of ", 9))
4402 if (!strncmpi(g, "colored ", 8))
4404 else if (!strncmpi(g, "coloured ", 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)
4412 typ = 0; /* somebody changed objects[]? punt */
4413 } else { /* try to construct canonical form */
4416 Strcpy(tbuf, "worthless piece of ");
4417 Strcat(tbuf, g); /* assume it starts with the color */
4425 dn = actualn; /* ex. "skull cap" */
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;
4434 if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(actualn, zn)) {
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")) {
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))
4457 struct Jitem *j = Japanese_items;
4460 if (actualn && !strcmpi(actualn, j->name)) {
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");
4479 if (!strcmpi(bp, "spinach")) {
4481 if (!strcmp(bp, "
\83z
\83E
\83\8c\83\93\91\90")) {
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. */
4494 int blessedf, iscursedf, uncursedf, halfeatenf;
4496 blessedf = iscursedf = uncursedf = halfeatenf = 0;
4503 if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
4505 } else if (!cntf && digit(*fp)) {
4512 } else if (!strncmpi(fp, "blessed ", l = 8)) {
4514 } else if (!strncmpi(fp, "cursed ", l = 7)) {
4516 } else if (!strncmpi(fp, "uncursed ", l = 9)) {
4518 } else if (!strncmpi(fp, "partly eaten ", l = 13)
4519 || !strncmpi(fp, "partially eaten ", l = 16)) {
4526 for (f = ffruit; f; f = f->nextf) {
4527 /* match type: 0=none, 1=exact, 2=singular, 3=plural */
4530 if (!strcmp(fp, f->fname))
4532 else if (!strcmp(fp, makesingular(f->fname)))
4534 else if (!strcmp(fp, makeplural(f->fname)))
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)
4548 else if (ftyp == 3 && !cntf)
4557 if (!oclass && actualn) {
4560 /* Perhaps it's an artifact specified by name, not type */
4561 name = artifact_name(actualn, &objtyp);
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.
4575 if (wizard && !program_state.wizkit_wishing) {
4577 boolean madeterrain = FALSE;
4578 int trap, x = u.ux, y = u.uy;
4580 for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
4584 tname = defsyms[trap_to_defsym(trap)].explanation;
4585 if (strncmpi(tname, bp, strlen(tname)))
4587 /* found it; avoid stupid mistakes */
4588 if (is_hole(trap) && !Can_fall_thru(&u.uz))
4590 if ((t = maketrap(x, y, trap)) != 0) {
4592 tname = defsyms[trap_to_defsym(trap)].explanation;
4593 pline("%s%s.", An(tname),
4594 (trap != MAGIC_PORTAL) ? "" : " to nowhere");
4596 pline("Creation of %s failed.", an(tname));
4597 return (struct obj *) &zeroobj;
4600 /* furniture and terrain (use at your own risk; can clobber stairs
4601 or place furniture on existing traps which shouldn't be allowed) */
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 " : "");
4611 } else if (!BSTRCMPI(bp, p - 6, "throne")) {
4615 } else if (!BSTRCMPI(bp, p - 4, "sink")) {
4617 level.flags.nsinks++;
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;
4626 pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
4627 /* Must manually make kelp! */
4628 water_damage_chain(level.objects[x][y], TRUE);
4631 /* also matches "molten lava" */
4632 } else if (!BSTRCMPI(bp, p - 4, "lava")) {
4633 lev->typ = LAVAPOOL;
4635 pline("A pool of molten lava.");
4636 if (!(Levitation || Flying))
4639 } else if (!BSTRCMPI(bp, p - 5, "altar")) {
4643 if (!strncmpi(bp, "chaotic ", 8))
4645 else if (!strncmpi(bp, "neutral ", 8))
4647 else if (!strncmpi(bp, "lawful ", 7))
4649 else if (!strncmpi(bp, "unaligned ", 10))
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)));
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");
4662 } else if (!BSTRCMPI(bp, p - 4, "tree")) {
4667 } else if (!BSTRCMPI(bp, p - 4, "bars")) {
4668 lev->typ = IRONBARS;
4669 pline("Iron bars.");
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 */
4680 vision_full_recalc = 1;
4681 } else if (u.utrap && u.utraptype == TT_LAVA
4682 && !is_lava(u.ux, u.uy)) {
4685 /* cast 'const' away; caller won't modify this */
4686 return (struct obj *) &zeroobj;
4688 } /* end of wizard mode traps and terrain */
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);
4695 } else if (!strncmpi(bp, "hammer", 6)) {
4696 typ = rnd_otyp_by_wpnskill(P_HAMMER);
4703 return ((struct obj *) 0);
4706 oclass = wrpsym[rn2((int) sizeof wrpsym)];
4709 oclass = objects[typ].oc_class;
4711 /* handle some objects that are only allowed in wizard mode */
4712 if (typ && !wizard) {
4714 case AMULET_OF_YENDOR:
4715 typ = FAKE_AMULET_OF_YENDOR;
4717 case CANDELABRUM_OF_INVOCATION:
4718 typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
4720 case BELL_OF_OPENING:
4723 case SPE_BOOK_OF_THE_DEAD:
4724 typ = SPE_BLANK_PAPER;
4730 /* catch any other non-wishable objects (venom) */
4731 if (objects[typ].oc_nowish)
4732 return (struct obj *) 0;
4738 * Create the object, then fine-tune it.
4740 otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
4741 typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
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 */
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;
4757 if (oclass == VENOM_CLASS)
4762 } else if (wizard) {
4763 ; /* no alteration to spe */
4764 } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
4766 || (oclass == RING_CLASS && objects[typ].oc_charged)) {
4767 if (spe > rnd(5) && spe > otmp->spe)
4769 if (spe > 2 && Luck < 0)
4772 if (oclass == WAND_CLASS) {
4773 if (spe > 1 && spesgn == -1)
4776 if (spe > 0 && spesgn == -1)
4779 if (spe > otmp->spe)
4786 /* set otmp->spe. This may, or may not, use spe... */
4789 if (contents == EMPTY) {
4790 otmp->corpsenm = NON_PM;
4792 } else if (contents == SPINACH) {
4793 otmp->corpsenm = NON_PM;
4799 otmp->spe = wetness;
4807 case HEAVY_IRON_BALL:
4810 /* otmp->cobj already done in mksobj() */
4814 /* 0: delivered in-game via external event (or randomly for fake mail);
4815 1: from bones or wishing; 2: written with marker */
4821 otmp->spe = (rn2(10) ? -1 : 0);
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;
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;
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);
4854 mntmp = can_be_hatched(mntmp);
4855 /* this also sets hatch timer if appropriate */
4856 set_corpsenm(otmp, mntmp);
4859 if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4861 && mntmp != PM_MAIL_DAEMON
4864 otmp->corpsenm = mntmp;
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;
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;
4880 /* set blessed/cursed -- setting the fields directly is safe
4881 * since weight() is called below and addinv() will take care
4885 } else if (uncursed) {
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) {
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;
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.
4907 if (erodeproof && (is_damageable(otmp) || otmp->otyp == CRYSKNIFE))
4908 otmp->oerodeproof = (Luck >= 0 || wizard);
4911 /* set otmp->recharged */
4912 if (oclass == WAND_CLASS) {
4913 /* prevent wishing abuse */
4914 if (otmp->otyp == WAN_WISHING && !wizard)
4916 otmp->recharged = (unsigned) rechrg;
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 */
4927 /* and [un]trapped */
4929 if (Is_box(otmp) || typ == TIN)
4930 otmp->otrapped = (trapped == 1);
4932 /* empty for containers rather than for tins */
4933 if (contents == EMPTY) {
4934 if (otmp->otyp == BAG_OF_TRICKS || otmp->otyp == HORN_OF_PLENTY) {
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);
4944 /* set locked/unlocked/broken */
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;
4958 if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4961 /* set tin variety */
4962 if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4963 set_tin_variety(otmp, tvariety);
4969 /* an artifact name might need capitalization fixing */
4970 aname = artifact_name(name, &objtyp);
4971 if (aname && objtyp == otmp->otyp)
4974 /* 3.6 tribute - fix up novel */
4975 if (otmp->otyp == SPE_NOVEL) {
4976 const char *novelname;
4978 novelname = lookup_novel(name, &otmp->novelidx);
4983 otmp = oname(otmp, name);
4984 /* name==aname => wished for artifact (otmp->oartifact => got it) */
4985 if (otmp->oartifact || name == aname) {
4987 u.uconduct.wisharti++; /* KMH, conduct */
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;
4999 pline("For a moment, you feel %s in your %s, but it disappears!",
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)));
5006 if (halfeaten && otmp->oclass == FOOD_CLASS) {
5007 if (otmp->otyp == CORPSE)
5008 otmp->oeaten = mons[otmp->corpsenm].cnutrit;
5010 otmp->oeaten = objects[otmp->otyp].oc_nutrition;
5011 /* (do this adjustment before setting up object's weight) */
5012 consume_oeaten(otmp, 1);
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;
5026 rnd_class(first, last)
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);
5038 for (i = first; i <= last; i++)
5039 if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
5044 STATIC_OVL const char *
5045 Japanese_item_name(i)
5048 struct Jitem *j = Japanese_items;
5055 return (const char *) 0;
5059 suit_simple_name(suit)
5062 const char *suitnm, *esuitp;
5065 if (Is_dragon_mail(suit))
5067 return "dragon mail"; /* <color> dragon scale mail */
5069 return "
\97Ø
\8aZ"; /* <color> dragon scale mail */
5071 else if (Is_dragon_scales(suit))
5073 return "dragon scales";
5076 suitnm = OBJ_NAME(objects[suit->otyp]);
5077 esuitp = eos((char *) suitnm);
5079 if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
5080 return "mail"; /* most suits fall into this category */
5082 if (strlen(suitnm) > 2 && !strcmp(esuitp - 2, "
\8aZ"))
5083 return "
\8aZ"; /* most suits fall into this category */
5086 else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
5087 return "jacket"; /* leather jacket */
5090 /* "suit" is lame but "armor" is ambiguous and "body armor" is absurd */
5098 cloak_simple_name(cloak)
5102 switch (cloak->otyp) {
5107 return "
\83\8d\81[
\83u";
5108 case MUMMY_WRAPPING:
5114 return (objects[cloak->otyp].oc_name_known && cloak->dknown)
5118 ? "
\83X
\83\82\83b
\83N"
5122 : "
\83G
\83v
\83\8d\83\93";
5130 return "
\83N
\83\8d\81[
\83N";
5133 /* helm vs hat for messages */
5135 helm_simple_name(helmet)
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".
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
5151 return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
5153 return (helmet && !is_metallic(helmet)) ? "
\96X
\8eq" : "
\8a\95";
5156 /* gloves vs gauntlets; depends upon discovery state */
5158 gloves_simple_name(gloves)
5161 static const char gauntlets[] = "gauntlets";
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);
5169 if (strstri(objects[otyp].oc_name_known ? actualn : descrpn,
5177 mimic_obj_name(mtmp)
5180 if (M_AP_TYPE(mtmp) == M_AP_OBJECT) {
5181 if (mtmp->mappearance == GOLD_PIECE)
5186 if (mtmp->mappearance != STRANGE_OBJECT)
5187 return simple_typename(mtmp->mappearance);
5190 return "whatcha-may-callit";
5192 return "
\89½
\82Æ
\82©
\82¢
\82¤
\82à
\82Ì";
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.
5202 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
5203 char *qbuf; /* output buffer */
5204 const char *qprefix, *qsuffix;
5206 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
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);
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);
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 */
5235 } else if (qprefix) {
5236 /* put prefix into the buffer */
5237 (void) strncpy(qbuf, qprefix, lenlimit);
5240 /* no prefix; output buffer starts out empty */
5243 len = (unsigned) strlen(qbuf);
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);
5250 len = (unsigned) strlen(qbuf);
5251 if (qsuffix && len < lenlimit) {
5252 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
5254 /* len = (unsigned) strlen(qbuf); */
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 */
5265 Strcat(qbuf, lastR); /* use last resort */
5269 Strcat(qbuf, qsuffix);
5271 /* assert( strlen(qbuf) < QBUFSZ ); */
5276 globwt(otmp, buf, weightformatted_p)
5279 boolean *weightformatted_p;
5283 Sprintf(buf, "%u aum, ", otmp->owt);
5284 *weightformatted_p = TRUE;
5286 *weightformatted_p = FALSE;