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-2019 */
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 *));
24 STATIC_DCL short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P));
25 STATIC_DCL short FDECL(rnd_otyp_by_namedesc, (const char *, CHAR_P, int));
26 STATIC_DCL boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P));
27 STATIC_DCL char *NDECL(nextobuf);
28 STATIC_DCL void FDECL(releaseobuf, (char *));
29 STATIC_DCL char *FDECL(minimal_xname, (struct obj *));
30 STATIC_DCL void FDECL(add_erosion_words, (struct obj *, char *));
31 STATIC_DCL char *FDECL(doname_base, (struct obj *obj, unsigned));
32 STATIC_DCL char *FDECL(just_an, (char *str, const char *));
34 STATIC_DCL boolean FDECL(singplur_lookup, (char *, char *, BOOLEAN_P,
35 const char *const *));
37 STATIC_DCL char *FDECL(singplur_compound, (char *));
38 STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned));
40 STATIC_DCL boolean FDECL(badman, (const char *, BOOLEAN_P));
42 STATIC_DCL char *FDECL(globwt, (struct obj *, char *, boolean *));
49 #define BSTRCMPI(base, ptr, str) ((ptr) < base || strcmpi((ptr), str))
50 #define BSTRNCMPI(base, ptr, str, num) \
51 ((ptr) < base || strncmpi((ptr), str, num))
52 #define Strcasecpy(dst, src) (void) strcasecpy(dst, src)
54 /* true for gems/rocks that should have " stone" appended to their names */
55 #define GemStone(typ) \
57 || (objects[typ].oc_material == GEMSTONE \
58 && (typ != DILITHIUM_CRYSTAL && typ != RUBY && typ != DIAMOND \
59 && typ != SAPPHIRE && typ != BLACK_OPAL && typ != EMERALD \
63 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "wakizashi" },
64 { BROADSWORD, "ninja-to" },
65 { FLAIL, "nunchaku" },
66 { GLAIVE, "naginata" },
67 { LOCK_PICK, "osaku" },
68 { WOODEN_HARP, "koto" },
70 { PLATE_MAIL, "tanko" },
72 { LEATHER_GLOVES, "yugake" },
73 { FOOD_RATION, "gunyoki" },
74 { POT_BOOZE, "sake" },
77 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "
\98e
\8d·
\82µ" },
78 { BROADSWORD, "
\94E
\8eÒ
\93\81" },
79 { FLAIL, "
\83k
\83\93\83`
\83\83\83N" },
80 { GLAIVE, "
\82È
\82¬
\82È
\82½" },
81 { LOCK_PICK, "
\82¨
\82³
\82" },
82 { WOODEN_HARP, "
\8bÕ" },
83 { KNIFE, "
\8eh
\93\81" },
84 { PLATE_MAIL, "
\92Z
\8db" },
86 { LEATHER_GLOVES, "
\8b|
\8c\9c" },
87 { FOOD_RATION, "
\8aÛ
\96ò" },
88 { POT_BOOZE, "
\8eð" },
92 STATIC_DCL const char *FDECL(Japanese_item_name, (int i));
97 register const char *pref;
99 register int i = (int) strlen(pref);
102 impossible("PREFIX too short (for %d).", i);
106 (void) strncpy(s, pref, i); /* do not copy trailing 0 */
110 /* manage a pool of BUFSZ buffers, so callers don't have to */
111 static char NEARDATA obufs[NUMOBUF][BUFSZ];
112 static int obufidx = 0;
117 obufidx = (obufidx + 1) % NUMOBUF;
118 return obufs[obufidx];
121 /* put the most recently allocated buffer back if possible */
126 /* caller may not know whether bufp is the most recently allocated
127 buffer; if it isn't, do nothing; note that because of the somewhat
128 obscure PREFIX handling for object name formatting by xname(),
129 the pointer our caller has and is passing to us might be into the
130 middle of an obuf rather than the address returned by nextobuf() */
131 if (bufp >= obufs[obufidx]
132 && bufp < obufs[obufidx] + sizeof obufs[obufidx]) /* obufs[][BUFSZ] */
133 obufidx = (obufidx - 1 + NUMOBUF) % NUMOBUF;
140 char *buf = nextobuf();
141 struct objclass *ocl = &objects[otyp];
142 const char *actualn = OBJ_NAME(*ocl);
143 const char *dn = OBJ_DESCR(*ocl);
144 const char *un = ocl->oc_uname;
145 int nn = ocl->oc_name_known;
147 if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
148 actualn = Japanese_item_name(otyp);
151 Sprintf(buf, "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é", un);
153 switch (ocl->oc_class) {
158 Strcat(buf, "
\8bà
\89Ý");
162 Strcpy(buf, "potion");
168 Strcpy(buf, "scroll");
170 Strcat(buf, "
\8aª
\95¨");
179 if (otyp != SPE_NOVEL) {
181 Strcpy(buf, "spellbook");
183 Strcat(buf, "
\96\82\96@
\8f\91");
186 Strcpy(buf, !nn ? "book" : "novel");
188 Strcpy(buf, !nn ? "
\96{" : "
\8f¬
\90à");
196 Strcat(buf, "
\8ew
\97Ö");
201 Strcpy(buf, actualn);
203 Strcpy(buf, "amulet");
205 Sprintf(eos(buf), " called %s", un);
207 Sprintf(eos(buf), " (%s)", dn);
211 Strcat(buf, actualn);
213 Strcat(buf, "
\96\82\8f\9c\82¯");
219 Strcat(buf, actualn);
221 Strcat(buf, "
\95ó
\90Î");
227 Strcpy(buf, actualn);
229 Strcat(buf, " stone");
231 Sprintf(eos(buf), " called %s", un);
233 Sprintf(eos(buf), " (%s)", dn);
235 Strcat(buf, actualn);
239 Strcpy(buf, dn ? dn : actualn);
240 if (ocl->oc_class == GEM_CLASS)
242 (ocl->oc_material == MINERAL) ? " stone" : " gem");
244 Sprintf(eos(buf), " called %s", un);
246 Strcat(buf, dn ? dn : actualn);
255 /* here for ring/scroll/potion/wand */
259 Strcpy(buf, actualn); /* avoid spellbook of Book of the Dead */
261 Sprintf(eos(buf), " of %s", actualn);
263 Strcpy(buf, actualn);
268 Sprintf(eos(buf), " called %s", un);
272 Sprintf(eos(buf), " (%s)", dn);
274 Sprintf(eos(buf), "(%s)", dn);
279 /* less verbose result than obj_typename(); either the actual name
280 or the description (but not both); user-assigned name is ignored */
282 simple_typename(otyp)
285 char *bufp, *pp, *save_uname = objects[otyp].oc_uname;
287 objects[otyp].oc_uname = 0; /* suppress any name given by user */
288 bufp = obj_typename(otyp);
289 objects[otyp].oc_uname = save_uname;
290 if ((pp = strstri(bufp, " (")) != 0)
291 *pp = '\0'; /* strip the appended description */
295 /* typename for debugging feedback where data involved might be suspect */
300 unsigned save_nameknown;
303 if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
304 || !OBJ_NAME(objects[otyp])) {
306 Sprintf(res, "glorkum[%d]", otyp);
308 /* force it to be treated as fully discovered */
309 save_nameknown = objects[otyp].oc_name_known;
310 objects[otyp].oc_name_known = 1;
311 res = simple_typename(otyp);
312 objects[otyp].oc_name_known = save_nameknown;
321 if (!obj->oartifact || !has_oname(obj))
323 if (!program_state.gameover && !iflags.override_ID) {
324 if (not_fully_identified(obj))
330 /* used by distant_name() to pass extra information to xname_flags();
331 it would be much cleaner if this were a parameter, but that would
332 require all of the xname() and doname() calls to be modified */
333 static int distantname = 0;
335 /* Give the name of an object seen at a distance. Unlike xname/doname,
336 * we don't want to set dknown if it's not set already.
339 distant_name(obj, func)
341 char *FDECL((*func), (OBJ_P));
345 /* 3.6.1: this used to save Blind, set it, make the call, then restore
346 * the saved value; but the Eyes of the Overworld override blindness
347 * and let characters wearing them get dknown set for distant items.
349 * TODO? if the hero is wearing those Eyes, figure out whether the
350 * object is within X-ray radius and only treat it as distant when
351 * beyond that radius. Logic is iffy but result might be interesting.
359 /* convert player specified fruit name into corresponding fruit juice name
360 ("slice of pizza" -> "pizza juice" rather than "slice of pizza juice") */
363 boolean juice; /* whether or not to append " juice" to the name */
366 char *buf = nextobuf();
367 const char *fruit_nam = strstri(pl_fruit, " of ");
370 fruit_nam += 4; /* skip past " of " */
372 fruit_nam = pl_fruit; /* use it as is */
374 Sprintf(buf, "%s%s", makesingular(fruit_nam), juice ? " juice" : "");
377 /*
\93ú
\96{
\8cê
\82Å
\82Í
\82»
\82±
\82Ü
\82Å
\82µ
\82È
\82¢*/
378 char *buf = nextobuf();
379 Sprintf(buf, "%s%s", pl_fruit, juice ? "
\83W
\83\85\81[
\83X" : "");
384 /* look up a named fruit by index (1..127) */
386 fruit_from_indx(indx)
391 for (f = ffruit; f; f = f->nextf)
397 /* look up a named fruit by name */
399 fruit_from_name(fname, exact, highest_fid)
401 boolean exact; /* False => prefix or exact match, True = exact match only */
402 int *highest_fid; /* optional output; only valid if 'fname' isn't found */
404 struct fruit *f, *tentativef;
408 * note: named fruits are case-senstive...
413 /* first try for an exact match */
414 for (f = ffruit; f; f = f->nextf)
415 if (!strcmp(f->fname, fname))
417 else if (highest_fid && f->fid > *highest_fid)
418 *highest_fid = f->fid;
420 /* didn't match as-is; if caller is willing to accept a prefix
421 match, try to find one; we want to find the longest prefix that
422 matches, not the first */
425 for (f = ffruit; f; f = f->nextf) {
426 k = strlen(f->fname);
427 if (!strncmp(f->fname, fname, k)
428 && (!fname[k] || fname[k] == ' ')
429 && (!tentativef || k > strlen(tentativef->fname)))
434 /* if we still don't have a match, try singularizing the target;
435 for exact match, that's trivial, but for prefix, it's hard */
437 altfname = makesingular(fname);
438 for (f = ffruit; f; f = f->nextf) {
439 if (!strcmp(f->fname, altfname))
442 releaseobuf(altfname);
445 char fnamebuf[BUFSZ], *p;
446 unsigned fname_k = strlen(fname); /* length of assumed plural fname */
449 for (f = ffruit; f; f = f->nextf) {
450 k = strlen(f->fname);
451 /* reload fnamebuf[] each iteration in case it gets modified;
452 there's no need to recalculate fname_k */
453 Strcpy(fnamebuf, fname);
454 /* bug? if singular of fname is longer than plural,
455 failing the 'fname_k > k' test could skip a viable
456 candidate; unfortunately, we can't singularize until
457 after stripping off trailing stuff and we can't get
458 accurate fname_k until fname has been singularized;
459 compromise and use 'fname_k >= k' instead of '>',
460 accepting 1 char length discrepancy without risking
461 false match (I hope...) */
462 if (fname_k >= k && (p = index(&fnamebuf[k], ' ')) != 0) {
463 *p = '\0'; /* truncate at 1st space past length of f->fname */
464 altfname = makesingular(fnamebuf);
465 k = strlen(altfname); /* actually revised 'fname_k' */
466 if (!strcmp(f->fname, altfname)
467 && (!tentativef || k > strlen(tentativef->fname)))
469 releaseobuf(altfname); /* avoid churning through all obufs */
477 /* sort the named-fruit linked list by fruit index number */
479 reorder_fruit(forward)
482 struct fruit *f, *allfr[1 + 127];
483 int i, j, k = SIZE(allfr);
485 for (i = 0; i < k; ++i)
486 allfr[i] = (struct fruit *) 0;
487 for (f = ffruit; f; f = f->nextf) {
488 /* without sanity checking, this would reduce to 'allfr[f->fid]=f' */
490 if (j < 1 || j >= k) {
491 impossible("reorder_fruit: fruit index (%d) out of range", j);
492 return; /* don't sort after all; should never happen... */
493 } else if (allfr[j]) {
494 impossible("reorder_fruit: duplicate fruit index (%d)", j);
499 ffruit = 0; /* reset linked list; we're rebuilding it from scratch */
500 /* slot [0] will always be empty; must start 'i' at 1 to avoid
501 [k - i] being out of bounds during first iteration */
502 for (i = 1; i < k; ++i) {
503 /* for forward ordering, go through indices from high to low;
504 for backward ordering, go from low to high */
505 j = forward ? (k - i) : i;
507 allfr[j]->nextf = ffruit;
517 return xname_flags(obj, CXN_NORMAL);
521 xname_flags(obj, cxn_flags)
522 register struct obj *obj;
523 unsigned cxn_flags; /* bitmask of CXN_xxx values */
526 register int typ = obj->otyp;
527 register struct objclass *ocl = &objects[typ];
528 int nn = ocl->oc_name_known, omndx = obj->corpsenm;
529 const char *actualn = OBJ_NAME(*ocl);
530 const char *dn = OBJ_DESCR(*ocl);
531 const char *un = ocl->oc_uname;
532 boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
533 boolean known, dknown, bknown;
535 buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
536 if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
537 actualn = Japanese_item_name(typ);
538 /* As of 3.6.2: this used to be part of 'dn's initialization, but it
539 needs to come after possibly overriding 'actualn' */
545 * clean up known when it's tied to oc_name_known, eg after AD_DRIN
546 * This is only required for unique objects since the article
547 * printed for the object is tied to the combination of the two
548 * and printing the wrong article gives away information.
550 if (!nn && ocl->oc_uses_known && ocl->oc_unique)
552 if (!Blind && !distantname)
554 if (Role_if(PM_PRIEST))
555 obj->bknown = 1; /* actively avoid set_bknown();
556 * we mustn't call update_inventory() now because
557 * it would call xname() (via doname()) recursively
558 * and could end up clobbering all the obufs... */
560 if (iflags.override_ID) {
561 known = dknown = bknown = TRUE;
565 dknown = obj->dknown;
566 bknown = obj->bknown;
569 if (obj_is_pname(obj))
574 Strcat(buf, ONAME(obj));
579 if (has_oname(obj) && dknown) {
580 Strcat(buf, ONAME(obj));
581 Strcat(buf, "
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½");
584 switch (obj->oclass) {
588 Strcpy(buf, "amulet");
590 Strcat(buf, "
\96\82\8f\9c\82¯");
591 else if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
592 /* each must be identified individually */
593 Strcpy(buf, known ? actualn : dn);
595 Strcpy(buf, actualn);
598 Sprintf(buf, "amulet called %s", un);
600 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\8f\9c\82¯", un);
603 Sprintf(buf, "%s amulet", dn);
605 Sprintf(eos(buf), "%s", dn);
608 if (is_poisonable(obj) && obj->opoisoned)
610 Strcpy(buf, "poisoned ");
612 Strcpy(buf, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
618 Sprintf(eos(buf), "%s
\82Ì", mons[obj->corpsenm].mname);
622 Strcpy(buf, "pair of ");
624 Strcpy(buf, "
\88ê
\91Î
\82Ì");
625 else if (is_wet_towel(obj))
627 Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
629 Strcpy(buf, (obj->spe < 3) ? "
\8e¼
\82Á
\82½" : "
\94G
\82ê
\82½");
634 Strcat(buf, actualn);
638 Strcat(buf, " called ");
642 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é");
648 #if 0 /*JP*/ /*
\82±
\82ê
\82Í
\8cê
\8f\87\82Ì
\8aÖ
\8cW
\82©
\82ç
\8fã
\82Ì
\95û
\82Å
\92è
\8b`*/
649 if (typ == FIGURINE && omndx != NON_PM) {
650 char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */
652 Sprintf(eos(buf), " of %s%s",
653 just_an(anbuf, mons[omndx].mname),
655 } else if (is_wet_towel(obj)) {
657 if (is_wet_towel(obj)) {
660 Sprintf(eos(buf), " (%d)", obj->spe);
664 /* depends on order of the dragon scales objects */
665 if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
667 Sprintf(buf, "set of %s", actualn);
669 Sprintf(buf, "%s
\88ê
\8e®", actualn);
672 if (is_boots(obj) || is_gloves(obj))
674 Strcpy(buf, "pair of ");
676 Strcat(buf,"
\88ê
\91Î
\82Ì");
678 if (obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
681 Strcpy(buf, "shield");
683 Strcat(buf, "
\8f\82");
686 if (obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
688 Strcpy(buf, "smooth shield");
690 Strcat(buf, "
\82·
\82×
\82·
\82×
\82µ
\82½
\8f\82");
695 Strcat(buf, actualn);
699 Strcat(buf, "boots");
700 else if (is_gloves(obj))
701 Strcat(buf, "gloves");
702 else if (is_cloak(obj))
703 Strcpy(buf, "cloak");
704 else if (is_helmet(obj))
705 Strcpy(buf, "helmet");
706 else if (is_shield(obj))
707 Strcpy(buf, "shield");
709 Strcpy(buf, "armor");
710 Strcat(buf, " called ");
716 else if (is_gloves(obj))
718 else if (is_cloak(obj))
719 p = "
\83N
\83\8d\81[
\83N";
720 else if (is_helmet(obj))
722 else if (is_shield(obj))
726 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, p);
732 if (typ == SLIME_MOLD) {
733 struct fruit *f = fruit_from_indx(obj->spe);
736 impossible("Bad fruit #%d?", obj->spe);
737 Strcpy(buf, "fruit");
739 Strcpy(buf, f->fname);
741 /* ick; already pluralized fruit names
742 are allowed--we want to try to avoid
743 adding a redundant plural suffix */
744 Strcpy(buf, makeplural(makesingular(buf)));
761 ? "
\82Æ
\82Ä
\82à
\91å
\82«
\82¢"
773 Strcpy(buf, actualn);
774 if (typ == TIN && known)
775 tin_details(obj, omndx, buf);
777 if (typ == TIN && known)
778 /*JP
\81u
\81`
\82Ì
\93÷
\82Ì
\81v*/
779 tin_details(obj, omndx, buf);
780 Strcat(buf, actualn);
786 Strcpy(buf, actualn);
788 Strcat(buf, actualn);
792 if (typ == STATUE && omndx != NON_PM) {
796 Sprintf(buf, "%s%s of %s%s",
797 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
801 type_is_pname(&mons[omndx])
803 : the_unique_pm(&mons[omndx])
805 : just_an(anbuf, mons[omndx].mname),
808 Sprintf(eos(buf), "%s%s
\82Ì%s",
809 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
812 mons[obj->corpsenm].mname, actualn);
816 Strcpy(buf, actualn);
818 Strcat(buf, actualn);
823 Sprintf(buf, "%sheavy iron ball",
824 (obj->owt > ocl->oc_weight) ? "very " : "");
826 Sprintf(eos(buf), "%s
\8fd
\82¢
\93S
\8b\85",
827 (obj->owt > ocl->oc_weight) ? "
\82Æ
\82Ä
\82à" : "");
831 if (dknown && obj->odiluted)
833 Strcpy(buf, "diluted ");
835 Strcat(buf, "
\94\96\82Ü
\82Á
\82½");
836 if (nn || un || !dknown) {
838 Strcat(buf, "potion");
851 if (typ == POT_WATER && bknown
852 && (obj->blessed || obj->cursed)) {
854 Strcat(buf, obj->blessed ? "holy " : "unholy ");
856 Strcat(buf, obj->blessed ? "
\90¹" : "
\95s
\8fò
\82È");
858 Strcat(buf, actualn);
861 Strcat(buf, " called ");
865 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96ò");
870 #if 0 /*JP*//*
\95s
\8am
\92è
\96¼
\82É
\81u
\96ò
\81v
\82Í
\95t
\82¢
\82Ä
\82¢
\82é*/
871 Strcat(buf, " potion");
877 Strcpy(buf, "scroll");
882 Strcat(buf,"
\8aª
\95¨");
890 Strcat(buf, actualn);
893 Strcat(buf, " called ");
897 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8aª
\95¨");
899 } else if (ocl->oc_magic) {
901 Strcat(buf, " labeled ");
907 Strcat(buf, " scroll");
921 Sprintf(buf, "wand of %s", actualn);
923 Strcat(buf, actualn);
926 Sprintf(buf, "wand called %s", un);
928 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8fñ", un);
931 Sprintf(buf, "%s wand", dn);
936 if (typ == SPE_NOVEL) { /* 3.6 tribute */
943 Strcpy(buf, actualn);
946 Sprintf(buf, "novel called %s", un);
948 Sprintf(buf, "%s
\82Æ
\82¢
\82¤
\8f¬
\90à", un);
951 Sprintf(buf, "%s book", dn);
953 Sprintf(buf, "%s
\96{", dn);
956 } else if (!dknown) {
958 Strcpy(buf, "spellbook");
960 Strcat(buf, "
\96\82\96@
\8f\91");
963 if (typ != SPE_BOOK_OF_THE_DEAD)
964 Strcpy(buf, "spellbook of ");
966 Strcat(buf, actualn);
969 Sprintf(buf, "spellbook called %s", un);
971 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\96@
\8f\91", un);
974 Sprintf(buf, "%s spellbook", dn);
976 Sprintf(eos(buf), "%s", dn);
983 Strcat(buf, "
\8ew
\97Ö");
986 Sprintf(buf, "ring of %s", actualn);
988 Strcat(buf, actualn);
991 Sprintf(buf, "ring called %s", un);
993 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8ew
\97Ö", un);
996 Sprintf(buf, "%s ring", dn);
1002 const char *rock = (ocl->oc_material == MINERAL) ? "stone" : "gem";
1004 const char *rock = (ocl->oc_material == MINERAL) ? "
\90Î" : "
\95ó
\90Î";
1015 Sprintf(buf, "%s called %s", rock, un);
1017 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, rock);
1020 Sprintf(buf, "%s %s", dn, rock);
1024 Strcpy(buf, actualn);
1027 Strcat(buf, " stone");
1033 Sprintf(buf, "glorkum %d %d %d", obj->oclass, typ, obj->spe);
1037 Strcpy(buf, makeplural(buf));
1040 if (obj->otyp == T_SHIRT && program_state.gameover) {
1044 Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
1046 Sprintf(eos(buf), "(
\81u%s
\81v
\82Æ
\8f\91\82¢
\82Ä
\82 \82é)", tshirt_text(obj, tmpbuf));
1050 if (has_oname(obj) && dknown) {
1051 Strcat(buf, " named ");
1053 Strcat(buf, ONAME(obj));
1056 if (!strncmpi(buf, "the ", 4))
1064 /* similar to simple_typename but minimal_xname operates on a particular
1065 object rather than its general type; it formats the most basic info:
1066 potion -- if description not known
1067 brown potion -- if oc_name_known not set
1068 potion of object detection -- if discovered
1076 struct objclass saveobcls;
1077 int otyp = obj->otyp;
1079 /* suppress user-supplied name */
1080 saveobcls.oc_uname = objects[otyp].oc_uname;
1081 objects[otyp].oc_uname = 0;
1082 /* suppress actual name if object's description is unknown */
1083 saveobcls.oc_name_known = objects[otyp].oc_name_known;
1085 objects[otyp].oc_name_known = 0;
1087 /* caveat: this makes a lot of assumptions about which fields
1088 are required in order for xname() to yield a sensible result */
1090 bareobj.otyp = otyp;
1091 bareobj.oclass = obj->oclass;
1092 bareobj.dknown = obj->dknown;
1093 /* suppress known except for amulets (needed for fakes and real A-of-Y) */
1094 bareobj.known = (obj->oclass == AMULET_CLASS)
1096 /* default is "on" for types which don't use it */
1097 : !objects[otyp].oc_uses_known;
1098 bareobj.quan = 1L; /* don't want plural */
1099 bareobj.corpsenm = NON_PM; /* suppress statue and figurine details */
1100 /* but suppressing fruit details leads to "bad fruit #0"
1101 [perhaps we should force "slime mold" rather than use xname?] */
1102 if (obj->otyp == SLIME_MOLD)
1103 bareobj.spe = obj->spe;
1105 bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
1107 if (!strncmp(bufp, "uncursed ", 9))
1108 bufp += 9; /* Role_if(PM_PRIEST) */
1110 if (!strncmp(bufp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", 14))
1111 bufp += 14; /* Role_if(PM_PRIEST) */
1114 objects[otyp].oc_uname = saveobcls.oc_uname;
1115 objects[otyp].oc_name_known = saveobcls.oc_name_known;
1119 /* xname() output augmented for multishot missile feedback */
1125 char *onm = xname(obj);
1127 if (m_shot.n > 1 && m_shot.o == obj->otyp) {
1128 /* "the Nth arrow"; value will eventually be passed to an() or
1129 The(), both of which correctly handle this "the " prefix */
1131 Sprintf(tmpbuf, "the %d%s ", m_shot.i, ordin(m_shot.i));
1133 Sprintf(tmpbuf, "%d%s
\96Ú
\82Ì", m_shot.i, numeral(obj));
1134 onm = strprepend(onm, tmpbuf);
1139 /* used for naming "the unique_item" instead of "a unique_item" */
1145 boolean known = (obj->known || iflags.override_ID);
1147 if (!obj->dknown && !iflags.override_ID)
1149 else if (obj->otyp == FAKE_AMULET_OF_YENDOR && !known)
1150 return TRUE; /* lie */
1152 return (boolean) (objects[obj->otyp].oc_unique
1153 && (known || obj->otyp == AMULET_OF_YENDOR));
1159 /* should monster type be prefixed with "the"? (mostly used for corpses) */
1162 struct permonst *ptr;
1166 /* even though monsters with personal names are unique, we want to
1167 describe them as "Name" rather than "the Name" */
1168 if (type_is_pname(ptr))
1171 uniq = (ptr->geno & G_UNIQ) ? TRUE : FALSE;
1172 /* high priest is unique if it includes "of <deity>", otherwise not
1173 (caller needs to handle the 1st possibility; we assume the 2nd);
1174 worm tail should be irrelevant but is included for completeness */
1175 if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
1177 /* Wizard no longer needs this; he's flagged as unique these days */
1178 if (ptr == &mons[PM_WIZARD_OF_YENDOR])
1184 add_erosion_words(obj, prefix)
1188 boolean iscrys = (obj->otyp == CRYSKNIFE);
1191 rknown = (iflags.override_ID == 0) ? obj->rknown : TRUE;
1193 if (!is_damageable(obj) && !iscrys)
1196 /* The only cases where any of these bits do double duty are for
1197 * rotted food and diluted potions, which are all not is_damageable().
1199 if (obj->oeroded && !iscrys) {
1200 switch (obj->oeroded) {
1203 Strcat(prefix, "very ");
1205 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1209 Strcat(prefix, "thoroughly ");
1211 Strcat(prefix, "
\82©
\82È
\82è");
1215 Strcat(prefix, is_rustprone(obj) ? "rusty " : "burnt ");
1217 Strcat(prefix, is_rustprone(obj) ? "
\8eK
\82Ñ
\82½" : "
\8f\9d\82Â
\82¢
\82½");
1219 if (obj->oeroded2 && !iscrys) {
1220 switch (obj->oeroded2) {
1223 Strcat(prefix, "very ");
1225 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1229 Strcat(prefix, "thoroughly ");
1231 Strcat(prefix, "
\82©
\82È
\82è");
1235 Strcat(prefix, is_corrodeable(obj) ? "corroded " : "rotted ");
1237 Strcat(prefix, is_corrodeable(obj) ? "
\95\85\90H
\82µ
\82½" : "
\95\85\82Á
\82½");
1239 if (rknown && obj->oerodeproof)
1241 Strcat(prefix, iscrys
1245 : is_corrodeable(obj)
1246 ? "corrodeproof " /* "stainless"? */
1251 Strcat(prefix, iscrys
1252 ? "
\88À
\92è
\82µ
\82½"
1254 ? "
\8eK
\82Ñ
\82È
\82¢"
1255 : is_corrodeable(obj)
1256 ? "
\95\85\90H
\82µ
\82È
\82¢" /* "stainless"? */
1258 ? "
\94R
\82¦
\82È
\82¢"
1263 /* used to prevent rust on items where rust makes no difference */
1265 erosion_matters(obj)
1268 switch (obj->oclass) {
1270 /* it's possible for a rusty weptool to be polymorphed into some
1271 non-weptool iron tool, in which case the rust implicitly goes
1272 away, but it's also possible for it to be polymorphed into a
1273 non-iron tool, in which case rust also implicitly goes away,
1274 so there's no particular reason to try to handle the first
1275 instance differently [this comment belongs in poly_obj()...] */
1276 return is_weptool(obj) ? TRUE : FALSE;
1288 #define DONAME_WITH_PRICE 1
1289 #define DONAME_VAGUE_QUAN 2
1292 doname_base(obj, doname_flags)
1294 unsigned doname_flags;
1296 boolean ispoisoned = FALSE,
1297 with_price = (doname_flags & DONAME_WITH_PRICE) != 0,
1298 vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0,
1299 weightshown = FALSE;
1300 boolean known, dknown, cknown, bknown, lknown;
1301 int omndx = obj->corpsenm;
1302 char prefix[PREFIX], globbuf[QBUFSZ];
1304 char tmpbuf[PREFIX + 1]; /* for when we have to add something at
1305 the start of prefix instead of the
1306 end (Strcat is used on the end) */
1308 register char *bp = xname(obj);
1309 #if 1 /*JP*//*
\8f\87\8f\98\93ü
\82ê
\91Ö
\82¦
\82É
\8eg
\82¤*/
1310 char preprefix[PREFIX];
1313 if (iflags.override_ID) {
1314 known = dknown = cknown = bknown = lknown = TRUE;
1317 dknown = obj->dknown;
1318 cknown = obj->cknown;
1319 bknown = obj->bknown;
1320 lknown = obj->lknown;
1323 /* When using xname, we want "poisoned arrow", and when using
1324 * doname, we want "poisoned +0 arrow". This kludge is about the only
1325 * way to do it, at least until someone overhauls xname() and doname(),
1326 * combining both into one function taking a parameter.
1328 /* must check opoisoned--someone can have a weirdly-named fruit */
1330 if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
1335 if (!strncmp(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", 12) && obj->opoisoned) {
1342 *
\81u
\8eq
\94L
\82Ì
\82½
\82Ü
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\8e\80\91Ì
\81v
\82æ
\82è
\81u
\82½
\82Ü
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\8eq
\94L
\82Ì
\8e\80\91Ì
\81v
1343 *
\82Ì
\82Ù
\82¤
\82ª
\8e©
\91R
\82Å
\82 \82é
\81D
1347 preprefix[0] = '\0';
1348 if((tp = strstri(bp, "
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½")) != NULL){
1349 tp += 12; /*
\81u
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\81v*/
1350 strncpy(preprefix, bp, tp - bp);
1351 preprefix[tp - bp] = '\0';
1358 if (obj->quan != 1L) {
1359 if (dknown || !vague_quan)
1361 Sprintf(prefix, "%ld ", obj->quan);
1362 #else /*
\93ú
\96{
\8cê
\82Æ
\82µ
\82Ä
\82Í
\90\94\8e\8c\82ª
\82È
\82¢
\82Ì
\82Í
\95s
\8e©
\91R */
1363 Sprintf(prefix, "%ld%s
\82Ì", obj->quan, numeral(obj));
1367 Strcpy(prefix, "some ");
1369 Strcpy(prefix, "
\82¢
\82
\82Â
\82©
\82Ì");
1370 } else if (obj->otyp == CORPSE) {
1371 /* skip article prefix for corpses [else corpse_xname()
1372 would have to be taught how to strip it off again] */
1374 #if 0 /*JP*/ /*
\8a¥
\8e\8c\82Í
\95s
\97v */
1375 } else if (obj_is_pname(obj) || the_unique_obj(obj)) {
1376 if (!strncmpi(bp, "the ", 4))
1378 Strcpy(prefix, "the ");
1380 Strcpy(prefix, "a ");
1381 #else /*prefix
\82Ì
\8f\89\8aú
\89»*/
1387 /* "empty" goes at the beginning, but item count goes at the end */
1389 /* bag of tricks: include "empty" prefix if it's known to
1390 be empty but its precise number of charges isn't known
1391 (when that is known, suffix of "(n:0)" will be appended,
1392 making the prefix be redundant; note that 'known' flag
1393 isn't set when emptiness gets discovered because then
1394 charging magic would yield known number of new charges) */
1395 && ((obj->otyp == BAG_OF_TRICKS)
1396 ? (obj->spe == 0 && !obj->known)
1397 /* not bag of tricks: empty if container which has no contents */
1398 : ((Is_container(obj) || obj->otyp == STATUE)
1399 && !Has_contents(obj))))
1401 Strcat(prefix, "empty ");
1403 Strcat(prefix, "
\8bó
\82Ì");
1405 if (bknown && obj->oclass != COIN_CLASS
1406 && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
1407 || (!obj->cursed && !obj->blessed))) {
1408 /* allow 'blessed clear potion' if we don't know it's holy water;
1409 * always allow "uncursed potion of water"
1413 Strcat(prefix, "cursed ");
1415 Strcat(prefix, "
\8eô
\82í
\82ê
\82½");
1416 else if (obj->blessed)
1418 Strcat(prefix, "blessed ");
1420 Strcat(prefix, "
\8fj
\95\9f\82³
\82ê
\82½");
1421 else if (!iflags.implicit_uncursed
1422 /* For most items with charges or +/-, if you know how many
1423 * charges are left or what the +/- is, then you must have
1424 * totally identified the item, so "uncursed" is unnecessary,
1425 * because an identified object not described as "blessed" or
1426 * "cursed" must be uncursed.
1428 * If the charges or +/- is not known, "uncursed" must be
1429 * printed to avoid ambiguity between an item whose curse
1430 * status is unknown, and an item known to be uncursed.
1432 || ((!known || !objects[obj->otyp].oc_charged
1433 || obj->oclass == ARMOR_CLASS
1434 || obj->oclass == RING_CLASS)
1436 && obj->otyp != SCR_MAIL
1438 && obj->otyp != FAKE_AMULET_OF_YENDOR
1439 && obj->otyp != AMULET_OF_YENDOR
1440 && !Role_if(PM_PRIEST)))
1442 Strcat(prefix, "uncursed ");
1444 Strcat(prefix, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢");
1447 if (lknown && Is_box(obj)) {
1449 /* 3.6.0 used "unlockable" here but that could be misunderstood
1450 to mean "capable of being unlocked" rather than the intended
1451 "not capable of being locked" */
1453 Strcat(prefix, "broken ");
1455 Strcat(prefix, "
\8c®
\82Ì
\89ó
\82ê
\82½");
1456 else if (obj->olocked)
1458 Strcat(prefix, "locked ");
1460 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½");
1463 Strcat(prefix, "unlocked ");
1465 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢");
1470 Strcat(prefix, "greased ");
1472 Strcat(prefix, "
\96û
\82Ì
\93h
\82ç
\82ê
\82½");
1474 if (cknown && Has_contents(obj)) {
1475 /* we count the number of separate stacks, which corresponds
1476 to the number of inventory slots needed to be able to take
1477 everything out if no merges occur */
1478 long itemcount = count_contents(obj, FALSE, FALSE, TRUE, FALSE);
1481 Sprintf(eos(bp), " containing %ld item%s", itemcount,
1484 Sprintf(eos(bp), "(%ld
\8cÂ
\93ü
\82Á
\82Ä
\82¢
\82é)", itemcount);
1488 switch (is_weptool(obj) ? WEAPON_CLASS : obj->oclass) {
1490 if (obj->owornmask & W_AMUL)
1492 Strcat(bp, " (being worn)");
1494 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1497 if (obj->owornmask & W_ARMOR) {
1499 Strcat(bp, (obj == uskin) ? " (embedded in your skin)"
1501 Strcat(bp, (obj == uskin) ? "(
\94§
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é)"
1502 /* in case of perm_invent update while Wear/Takeoff
1503 is in progress; check doffing() before donning()
1504 because donning() returns True for both cases */
1506 : doffing(obj) ? " (being doffed)"
1508 : doffing(obj) ? " (
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\93r
\92\86)"
1510 : donning(obj) ? " (being donned)"
1512 : donning(obj) ? " (
\92E
\82¢
\82Å
\82¢
\82é
\93r
\92\86)"
1516 : "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1517 /* slippery fingers is an intrinsic condition of the hero
1518 rather than extrinsic condition of objects, but gloves
1519 are described as slippery when hero has slippery fingers */
1520 if (obj == uarmg && Glib) /* just appended "(something)",
1521 * change to "(something; slippery)" */
1523 Strcpy(rindex(bp, ')'), "; slippery)");
1525 Strcpy(rindex(bp, ')'), ";
\82Ê
\82é
\82Ê
\82é)");
1531 Strcat(prefix, "poisoned ");
1533 Strcat(prefix, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
1534 add_erosion_words(obj, prefix);
1536 Strcat(prefix, sitoa(obj->spe));
1537 Strcat(prefix, " ");
1541 if (obj->owornmask & (W_TOOL | W_SADDLE)) { /* blindfold */
1543 Strcat(bp, " (being worn)");
1545 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1548 if (obj->otyp == LEASH && obj->leashmon != 0) {
1549 struct monst *mlsh = find_mid(obj->leashmon, FM_FMON);
1552 impossible("leashed monster not on this level");
1556 Sprintf(eos(bp), " (attached to %s)",
1557 noit_mon_nam(mlsh));
1559 Sprintf(eos(bp), " (%s
\82É
\8c\8b\82Ñ
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)",
1560 noit_mon_nam(mlsh));
1565 if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1568 Strcpy(tmpbuf, "no");
1570 Sprintf(tmpbuf, "%d", obj->spe);
1571 Sprintf(eos(bp), " (%s candle%s%s)", tmpbuf, plur(obj->spe),
1572 !obj->lamplit ? " attached" : ", lit");
1575 Sprintf(eos(bp), "(
\88ê
\96{
\82à
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢)");
1578 Sprintf(eos(bp), "(%d
\96{
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)", obj->spe);
1580 Sprintf(eos(bp), "(%d
\96{
\8cõ
\82Á
\82Ä
\82¢
\82é)", obj->spe);
1584 } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
1585 || obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
1587 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
1589 Strcat(prefix, "partly used ");
1591 Strcat(prefix, "
\8eg
\82¢
\82³
\82µ
\82Ì");
1594 Strcat(bp, " (lit)");
1596 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1599 if (objects[obj->otyp].oc_charged)
1606 Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe);
1608 Sprintf(eos(bp), "(%d:%d)", (int) obj->recharged, obj->spe);
1611 if (obj->otyp == POT_OIL && obj->lamplit)
1613 Strcat(bp, " (lit)");
1615 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1619 if (obj->owornmask & W_RINGR)
1621 Strcat(bp, " (on right ");
1623 Strcat(bp, "(
\89E");
1624 if (obj->owornmask & W_RINGL)
1626 Strcat(bp, " (on left ");
1628 Strcat(bp, "(
\8d¶");
1629 if (obj->owornmask & W_RING) {
1630 Strcat(bp, body_part(HAND));
1633 if (known && objects[obj->otyp].oc_charged) {
1635 Strcat(prefix, " ");
1637 Strcat(prefix, sitoa(obj->spe));
1638 Strcat(prefix, " ");
1644 Strcat(prefix, "partly eaten ");
1646 Strcat(prefix, "
\90H
\82×
\82©
\82¯
\82Ì");
1647 if (obj->otyp == CORPSE) {
1648 /* (quan == 1) => want corpse_xname() to supply article,
1649 (quan != 1) => already have count or "some" as prefix;
1650 "corpse" is already in the buffer returned by xname() */
1651 unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE)
1653 char *cxstr = corpse_xname(obj, prefix, cxarg);
1656 Sprintf(prefix, "%s ", cxstr);
1658 Sprintf(prefix, "%s
\82Ì", cxstr);
1660 /* avoid having doname(corpse) consume an extra obuf */
1662 } else if (obj->otyp == EGG) {
1663 #if 0 /* corpses don't tell if they're stale either */
1664 if (known && stale_egg(obj))
1665 Strcat(prefix, "stale ");
1668 && (known || (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
1670 Strcat(prefix, mons[omndx].mname);
1671 Strcat(prefix, " ");
1673 Strcat(prefix, mons[omndx].mname);
1674 Strcat(prefix, "
\82Ì");
1678 Strcat(bp, " (laid by you)");
1680 Strcat(bp, "(
\82 \82È
\82½
\82ª
\8eY
\82ñ
\82¾)");
1683 if (obj->otyp == MEAT_RING)
1688 add_erosion_words(obj, prefix);
1689 if (obj->owornmask & W_BALL)
1691 Strcat(bp, " (chained to you)");
1693 Strcat(bp, "(
\82 \82È
\82½
\82É
\8cq
\82ª
\82ê
\82Ä
\82¢
\82é)");
1697 if ((obj->owornmask & W_WEP) && !mrg_to_wielded) {
1698 if (obj->quan != 1L) {
1700 Strcat(bp, " (wielded)");
1702 Strcat(bp, "(
\91\95\94õ
\82µ
\82Ä
\82¢
\82é)");
1704 const char *hand_s = body_part(HAND);
1707 hand_s = makeplural(hand_s);
1708 /* note: Sting's glow message, if added, will insert text
1709 in front of "(weapon in hand)"'s closing paren */
1711 Sprintf(eos(bp), " (%sweapon in %s)",
1712 (obj->otyp == AKLYS) ? "tethered " : "", hand_s);
1713 #else /*
\83A
\83L
\83\8a\83X
\82ð
\93Á
\95Ê
\88µ
\82¢
\82µ
\82È
\82¢*/
1714 Sprintf(eos(bp), "(%s
\82É
\82µ
\82Ä
\82¢
\82é)", hand_s);
1717 if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
1718 if (!Blind) /* we know bp[] ends with ')'; overwrite that */
1720 Sprintf(eos(bp) - 1, ", %s %s)",
1721 glow_verb(warn_obj_cnt, TRUE),
1722 glow_color(obj->oartifact));
1724 Sprintf(eos(bp) - 1, ", %s%s
\82¢
\82é)",
1725 jconj_adj(glow_color(obj->oartifact)),
1726 jconj(glow_verb(warn_obj_cnt, TRUE), "
\82Ä"));
1731 if (obj->owornmask & W_SWAPWEP) {
1734 Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND));
1736 Sprintf(eos(bp), "(
\8d¶%s
\82É
\82µ
\82Ä
\82¢
\82é)", body_part(HAND));
1739 Strcat(bp, " (alternate weapon; not wielded)");
1741 Strcat(bp, "(
\97\
\94õ
\82Ì
\95\90\8aí;
\91\95\94õ
\82µ
\82Ä
\82¢
\82È
\82¢)");
1743 if (obj->owornmask & W_QUIVER) {
1744 switch (obj->oclass) {
1747 if (objects[obj->otyp].oc_skill == -P_BOW) {
1748 /* Ammo for a bow */
1750 Strcat(bp, " (in quiver)");
1752 Strcat(bp, "(
\96î
\93\9b\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1755 /* Ammo not for a bow */
1757 Strcat(bp, " (in quiver pouch)");
1759 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1763 /* Weapons not considered ammo */
1765 Strcat(bp, " (at the ready)");
1767 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1770 /* Small things and ammo not for a bow */
1777 Strcat(bp, " (in quiver pouch)");
1779 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1781 default: /* odd things */
1783 Strcat(bp, " (at the ready)");
1785 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1788 /* treat 'restoring' like suppress_price because shopkeeper and
1789 bill might not be available yet while restore is in progress
1790 (objects won't normally be formatted during that time, but if
1791 'perm_invent' is enabled then they might be) */
1792 if (iflags.suppress_price || restoring) {
1793 ; /* don't attempt to obtain any stop pricing, even if 'with_price' */
1794 } else if (is_unpaid(obj)) { /* in inventory or in container in invent */
1795 long quotedprice = unpaid_cost(obj, TRUE);
1798 Sprintf(eos(bp), " (%s, %s%ld %s)",
1799 obj->unpaid ? "unpaid" : "contents",
1800 globwt(obj, globbuf, &weightshown),
1801 quotedprice, currency(quotedprice));
1803 Sprintf(eos(bp), " (%s, %s%ld%s)",
1804 obj->unpaid ? "
\96¢
\95¥
\82¢" : "
\92\86\90g",
1805 globwt(obj, globbuf, &weightshown),
1806 quotedprice, currency(quotedprice));
1808 } else if (with_price) { /* on floor or in container on floor */
1810 long price = get_cost_of_shop_item(obj, &nochrg);
1814 Sprintf(eos(bp), " (%s, %s%ld %s)",
1815 nochrg ? "contents" : "for sale",
1816 globwt(obj, globbuf, &weightshown),
1817 price, currency(price));
1819 Sprintf(eos(bp), " (%s, %s%ld%s)",
1820 nochrg ? "
\92\86\90g" : "
\8f¤
\95i",
1821 globwt(obj, globbuf, &weightshown),
1822 price, currency(price));
1824 else if (nochrg > 0)
1826 Sprintf(eos(bp), " (%sno charge)",
1827 globwt(obj, globbuf, &weightshown));
1829 Sprintf(eos(bp), " (%s
\96³
\97¿)",
1830 globwt(obj, globbuf, &weightshown));
1833 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1834 if (!strncmp(prefix, "a ", 2)) {
1835 /* save current prefix, without "a "; might be empty */
1836 Strcpy(tmpbuf, prefix + 2);
1837 /* set prefix[] to "", "a ", or "an " */
1838 (void) just_an(prefix, *tmpbuf ? tmpbuf : bp);
1839 /* append remainder of original prefix */
1840 Strcat(prefix, tmpbuf);
1844 /* show weight for items (debug tourist info);
1845 "aum" is stolen from Crawl's "Arbitrary Unit of Measure" */
1846 if (wizard && iflags.wizweight) {
1847 /* wizard mode user has asked to see object weights;
1848 globs with shop pricing attached already include it */
1850 Sprintf(eos(bp), " (%u aum)", obj->owt);
1853 bp = strprepend(bp, prefix);
1854 #else /*JP:
\81u
\96¼
\95t
\82¯
\82ç
\82ê
\82½
\81v
\82ð
\96ß
\82·*/
1855 Strcat(preprefix, prefix);
1856 bp = strprepend(bp, preprefix);
1865 return doname_base(obj, (unsigned) 0);
1868 /* Name of object including price. */
1870 doname_with_price(obj)
1873 return doname_base(obj, DONAME_WITH_PRICE);
1876 /* "some" instead of precise quantity if obj->dknown not set */
1878 doname_vague_quan(obj)
1882 * If it hasn't been seen up close and quantity is more than one,
1883 * use "some" instead of the quantity: "some gold pieces" rather
1884 * than "25 gold pieces". This is suboptimal, to put it mildly,
1885 * because lookhere and pickup report the precise amount.
1886 * Picking the item up while blind also shows the precise amount
1887 * for inventory display, then dropping it while still blind leaves
1888 * obj->dknown unset so the count reverts to "some" for farlook.
1890 * TODO: add obj->qknown flag for 'quantity known' on stackable
1891 * items; it could overlay obj->cknown since no containers stack.
1893 return doname_base(obj, DONAME_VAGUE_QUAN);
1896 /* used from invent.c */
1898 not_fully_identified(otmp)
1901 /* gold doesn't have any interesting attributes [yet?] */
1902 if (otmp->oclass == COIN_CLASS)
1903 return FALSE; /* always fully ID'd */
1904 /* check fundamental ID hallmarks first */
1905 if (!otmp->known || !otmp->dknown
1907 || (!otmp->bknown && otmp->otyp != SCR_MAIL)
1911 || !objects[otmp->otyp].oc_name_known)
1913 if ((!otmp->cknown && (Is_container(otmp) || otmp->otyp == STATUE))
1914 || (!otmp->lknown && Is_box(otmp)))
1916 if (otmp->oartifact && undiscovered_artifact(otmp->oartifact))
1918 /* otmp->rknown is the only item of interest if we reach here */
1920 * Note: if a revision ever allows scrolls to become fireproof or
1921 * rings to become shockproof, this checking will need to be revised.
1922 * `rknown' ID only matters if xname() will provide the info about it.
1925 || (otmp->oclass != ARMOR_CLASS && otmp->oclass != WEAPON_CLASS
1926 && !is_weptool(otmp) /* (redundant) */
1927 && otmp->oclass != BALL_CLASS)) /* (useless) */
1929 else /* lack of `rknown' only matters for vulnerable objects */
1930 return (boolean) (is_rustprone(otmp) || is_corrodeable(otmp)
1931 || is_flammable(otmp));
1934 /* format a corpse name (xname() omits monster type; doname() calls us);
1935 eatcorpse() also uses us for death reason when eating tainted glob */
1937 corpse_xname(otmp, adjective, cxn_flags)
1939 const char *adjective;
1940 unsigned cxn_flags; /* bitmask of CXN_xxx values */
1942 /* some callers [aobjnam()] rely on prefix area that xname() sets aside */
1943 char *nambuf = nextobuf() + PREFIX;
1944 int omndx = otmp->corpsenm;
1946 boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
1947 /* suppress "the" from "the unique monster corpse" */
1951 no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
1952 /* include "the" for "the woodchuck corpse */
1953 the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
1954 /* include "an" for "an ogre corpse */
1955 any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
1956 /* leave off suffix (do_name() appends "corpse" itself) */
1957 omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
1959 glob = (otmp->otyp != CORPSE && otmp->globby);
1963 mname = OBJ_NAME(objects[otmp->otyp]); /* "glob of <monster>" */
1964 } else if (omndx == NON_PM) { /* paranoia */
1969 /* [Possible enhancement: check whether corpse has monster traits
1970 attached in order to use priestname() for priests and minions.] */
1971 } else if (omndx == PM_ALIGNED_PRIEST) {
1972 /* avoid "aligned priest"; it just exposes internal details */
1978 mname = mons[omndx].mname;
1979 if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
1980 mname = s_suffix(mname);
1982 /* don't precede personal name like "Medusa" with an article */
1983 if (type_is_pname(&mons[omndx]))
1985 /* always precede non-personal unique monster name like
1986 "Oracle" with "the" unless explicitly overridden */
1987 else if (the_unique_pm(&mons[omndx]) && !no_prefix)
1992 the_prefix = any_prefix = FALSE;
1993 else if (the_prefix)
1994 any_prefix = FALSE; /* mutually exclusive */
1997 /* can't use the() the way we use an() below because any capitalized
1998 Name causes it to assume a personal name and return Name as-is;
1999 that's usually the behavior wanted, but here we need to force "the"
2000 to precede capitalized unique monsters (pnames are handled above) */
2001 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2003 Strcat(nambuf, "the ");
2006 if (!adjective || !*adjective) {
2007 /* normal case: newt corpse */
2008 Strcat(nambuf, mname);
2010 /* adjective positioning depends upon format of monster name */
2011 if (possessive) /* Medusa's cursed partly eaten corpse */
2013 Sprintf(eos(nambuf), "%s %s", mname, adjective);
2015 Sprintf(eos(nambuf), "%s%s", mname, adjective);
2016 else /* cursed partly eaten troll corpse */
2018 Sprintf(eos(nambuf), "%s %s", adjective, mname);
2020 Sprintf(eos(nambuf), "%s%s", adjective, mname);
2021 /* in case adjective has a trailing space, squeeze it out */
2023 /* doname() might include a count in the adjective argument;
2024 if so, don't prepend an article */
2025 if (digit(*adjective))
2030 ; /* omit_corpse doesn't apply; quantity is always 1 */
2031 } else if (!omit_corpse) {
2033 Strcat(nambuf, " corpse");
2034 /* makeplural(nambuf) => append "s" to "corpse" */
2035 if (otmp->quan > 1L && !ignore_quan) {
2036 Strcat(nambuf, "s");
2037 any_prefix = FALSE; /* avoid "a newt corpses" */
2040 Strcat(nambuf, "
\82Ì
\8e\80\91Ì");
2044 /* it's safe to overwrite our nambuf after an() has copied
2045 its old value into another buffer */
2047 Strcpy(nambuf, an(nambuf));
2052 /* xname doesn't include monster type for "corpse"; cxname does */
2057 if (obj->otyp == CORPSE)
2058 return corpse_xname(obj, (const char *) 0, CXN_NORMAL);
2062 /* like cxname, but ignores quantity */
2064 cxname_singular(obj)
2067 if (obj->otyp == CORPSE)
2068 return corpse_xname(obj, (const char *) 0, CXN_SINGULAR);
2069 return xname_flags(obj, CXN_SINGULAR);
2072 /* treat an object as fully ID'd when it might be used as reason for death */
2077 struct obj save_obj;
2078 unsigned save_ocknown;
2079 char *buf, *save_ocuname, *save_oname = (char *) 0;
2081 /* bypass object twiddling for artifacts */
2083 return bare_artifactname(obj);
2085 /* remember original settings for core of the object;
2086 oextra structs other than oname don't matter here--since they
2087 aren't modified they don't need to be saved and restored */
2090 save_oname = ONAME(obj);
2092 /* killer name should be more specific than general xname; however, exact
2093 info like blessed/cursed and rustproof makes things be too verbose */
2094 obj->known = obj->dknown = 1;
2095 obj->bknown = obj->rknown = obj->greased = 0;
2096 /* if character is a priest[ess], bknown will get toggled back on */
2097 if (obj->otyp != POT_WATER)
2098 obj->blessed = obj->cursed = 0;
2100 obj->bknown = 1; /* describe holy/unholy water as such */
2101 /* "killed by poisoned <obj>" would be misleading when poison is
2102 not the cause of death and "poisoned by poisoned <obj>" would
2103 be redundant when it is, so suppress "poisoned" prefix */
2105 /* strip user-supplied name; artifacts keep theirs */
2106 if (!obj->oartifact && save_oname)
2107 ONAME(obj) = (char *) 0;
2108 /* temporarily identify the type of object */
2109 save_ocknown = objects[obj->otyp].oc_name_known;
2110 objects[obj->otyp].oc_name_known = 1;
2111 save_ocuname = objects[obj->otyp].oc_uname;
2112 objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
2114 /* format the object */
2115 if (obj->otyp == CORPSE) {
2116 buf = corpse_xname(obj, (const char *) 0, CXN_NORMAL);
2117 } else if (obj->otyp == SLIME_MOLD) {
2118 /* concession to "most unique deaths competition" in the annual
2119 devnull tournament, suppress player supplied fruit names because
2120 those can be used to fake other objects and dungeon features */
2123 Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
2125 Strcpy(buf, "
\8aë
\8c¯
\82È
\82Ë
\82Î
\82Ë
\82Î
\83J
\83r");
2129 /* apply an article if appropriate; caller should always use KILLED_BY */
2130 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
2131 if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
2132 buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
2135 objects[obj->otyp].oc_name_known = save_ocknown;
2136 objects[obj->otyp].oc_uname = save_ocuname;
2137 *obj = save_obj; /* restore object's core settings */
2138 if (!obj->oartifact && save_oname)
2139 ONAME(obj) = save_oname;
2144 /* xname,doname,&c with long results reformatted to omit some stuff */
2146 short_oname(obj, func, altfunc, lenlimit)
2148 char *FDECL((*func), (OBJ_P)), /* main formatting routine */
2149 *FDECL((*altfunc), (OBJ_P)); /* alternate for shortest result */
2152 struct obj save_obj;
2153 char unamebuf[12], onamebuf[12], *save_oname, *save_uname, *outbuf;
2155 outbuf = (*func)(obj);
2156 if ((unsigned) strlen(outbuf) <= lenlimit)
2159 /* shorten called string to fairly small amount */
2160 save_uname = objects[obj->otyp].oc_uname;
2161 if (save_uname && strlen(save_uname) >= sizeof unamebuf) {
2162 (void) strncpy(unamebuf, save_uname, sizeof unamebuf - 4);
2163 Strcpy(unamebuf + sizeof unamebuf - 4, "...");
2164 objects[obj->otyp].oc_uname = unamebuf;
2165 releaseobuf(outbuf);
2166 outbuf = (*func)(obj);
2167 objects[obj->otyp].oc_uname = save_uname; /* restore called string */
2168 if ((unsigned) strlen(outbuf) <= lenlimit)
2172 /* shorten named string to fairly small amount */
2173 save_oname = has_oname(obj) ? ONAME(obj) : 0;
2174 if (save_oname && strlen(save_oname) >= sizeof onamebuf) {
2175 (void) strncpy(onamebuf, save_oname, sizeof onamebuf - 4);
2176 Strcpy(onamebuf + sizeof onamebuf - 4, "...");
2177 ONAME(obj) = onamebuf;
2178 releaseobuf(outbuf);
2179 outbuf = (*func)(obj);
2180 ONAME(obj) = save_oname; /* restore named string */
2181 if ((unsigned) strlen(outbuf) <= lenlimit)
2185 /* shorten both called and named strings;
2186 unamebuf and onamebuf have both already been populated */
2187 if (save_uname && strlen(save_uname) >= sizeof unamebuf && save_oname
2188 && strlen(save_oname) >= sizeof onamebuf) {
2189 objects[obj->otyp].oc_uname = unamebuf;
2190 ONAME(obj) = onamebuf;
2191 releaseobuf(outbuf);
2192 outbuf = (*func)(obj);
2193 if ((unsigned) strlen(outbuf) <= lenlimit) {
2194 objects[obj->otyp].oc_uname = save_uname;
2195 ONAME(obj) = save_oname;
2200 /* still long; strip several name-lengthening attributes;
2201 called and named strings are still in truncated form */
2203 obj->bknown = obj->rknown = obj->greased = 0;
2204 obj->oeroded = obj->oeroded2 = 0;
2205 releaseobuf(outbuf);
2206 outbuf = (*func)(obj);
2207 if (altfunc && (unsigned) strlen(outbuf) > lenlimit) {
2208 /* still long; use the alternate function (usually one of
2209 the jackets around minimal_xname()) */
2210 releaseobuf(outbuf);
2211 outbuf = (*altfunc)(obj);
2213 /* restore the object */
2216 ONAME(obj) = save_oname;
2218 objects[obj->otyp].oc_uname = save_uname;
2220 /* use whatever we've got, whether it's too long or not */
2225 * Used if only one of a collection of objects is named (e.g. in eat.c).
2228 singular(otmp, func)
2229 register struct obj *otmp;
2230 char *FDECL((*func), (OBJ_P));
2235 /* using xname for corpses does not give the monster type */
2236 if (otmp->otyp == CORPSE && func == xname)
2239 savequan = otmp->quan;
2241 nam = (*func)(otmp);
2242 otmp->quan = savequan;
2246 /* pick "", "a ", or "an " as article for 'str'; used by an() and doname() */
2248 just_an(outbuf, str)
2252 #if 0 /*JP*//*
\95s
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2258 /* single letter; might be used for named fruit */
2259 Strcpy(outbuf, index("aefhilmnosx", c0) ? "an " : "a ");
2260 } else if (!strncmpi(str, "the ", 4) || !strcmpi(str, "molten lava")
2261 || !strcmpi(str, "iron bars") || !strcmpi(str, "ice")) {
2264 if ((index(vowels, c0) && strncmpi(str, "one-", 4)
2265 && strncmpi(str, "eucalyptus", 10) && strncmpi(str, "unicorn", 7)
2266 && strncmpi(str, "uranium", 7) && strncmpi(str, "useful", 6))
2267 || (index("x", c0) && !index(vowels, lowc(str[1]))))
2268 Strcpy(outbuf, "an ");
2270 Strcpy(outbuf, "a ");
2282 char *buf = nextobuf();
2284 if (!str || !*str) {
2285 impossible("Alphabet soup: 'an(%s)'.", str ? "\"\"" : "<null>");
2286 return strcpy(buf, "an []");
2288 (void) just_an(buf, str);
2289 return strcat(buf, str);
2296 char *tmp = an(str);
2298 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2305 * Prepend "the" if necessary; assumes str is a subject derived from xname.
2306 * Use type_is_pname() for monster names, not the(). the() is idempotent.
2312 char *buf = nextobuf();
2313 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2314 boolean insert_the = FALSE;
2316 if (!str || !*str) {
2317 impossible("Alphabet soup: 'the(%s)'.", str ? "\"\"" : "<null>");
2318 return strcpy(buf, "the []");
2320 if (!strncmpi(str, "the ", 4)) {
2321 buf[0] = lowc(*str);
2322 Strcpy(&buf[1], str + 1);
2324 } else if (*str < 'A' || *str > 'Z'
2325 /* treat named fruit as not a proper name, even if player
2326 has assigned a capitalized proper name as his/her fruit */
2327 || fruit_from_name(str, TRUE, (int *) 0)) {
2328 /* not a proper name, needs an article */
2331 /* Probably a proper name, might not need an article */
2332 register char *tmp, *named, *called;
2335 /* some objects have capitalized adjectives in their names */
2336 if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0)
2337 && (tmp[1] < 'A' || tmp[1] > 'Z')) {
2339 } else if (tmp && index(str, ' ') < tmp) { /* has spaces */
2340 /* it needs an article if the name contains "of" */
2341 tmp = strstri(str, " of ");
2342 named = strstri(str, " named ");
2343 called = strstri(str, " called ");
2344 if (called && (!named || called < named))
2347 if (tmp && (!named || tmp < named)) /* found an "of" */
2349 /* stupid special case: lacks "of" but needs "the" */
2350 else if (!named && (l = strlen(str)) >= 31
2351 && !strcmp(&str[l - 31],
2352 "Platinum Yendorian Express Card"))
2357 Strcpy(buf, "the ");
2362 #else /*
\92P
\82É
\83R
\83s
\81[*/
2372 char *tmp = the(str);
2374 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2383 register struct obj *otmp;
2384 register const char *verb;
2390 /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */
2396 char prefix[PREFIX];
2397 char *bp = cxname(otmp);
2399 if (otmp->quan != 1L) {
2400 Sprintf(prefix, "%ld ", otmp->quan);
2401 bp = strprepend(bp, prefix);
2405 Strcat(bp, otense(otmp, verb));
2411 /* combine yname and aobjnam eg "your count cxname(otmp)" */
2417 char *s = aobjnam(obj, verb);
2419 /* leave off "your" for most of your artifacts, but prepend
2420 * "your" for unique objects and "foo of bar" quest artifacts */
2421 if (!carried(obj) || !obj_is_pname(obj)
2422 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2423 char *outbuf = shk_your(nextobuf(), obj);
2424 int space_left = BUFSZ - 1 - strlen(outbuf);
2426 s = strncat(outbuf, s, space_left);
2431 /* combine Yname2 and aobjnam eg "Your count cxname(otmp)" */
2437 register char *s = yobjnam(obj, verb);
2445 /* like aobjnam, but prepend "The", not count, and use xname */
2451 char *bp = The(xname(otmp));
2453 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2456 Strcat(bp, otense(otmp, verb));
2462 /* capitalized variant of doname() */
2467 char *s = doname(obj);
2473 #if 0 /* stalled-out work in progress */
2474 /* Doname2() for itemized buying of 'obj' from a shop */
2479 static const char and_contents[] = " and its contents";
2480 char *p = doname(obj);
2482 if (Is_container(obj) && !obj->cknown) {
2484 if ((int) strlen(p) + sizeof and_contents - 1 < BUFSZ - PREFIX)
2485 Strcat(p, and_contents);
2488 p = strprepend(p, "Contents of ");
2497 /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */
2502 char *s = cxname(obj);
2504 /* leave off "your" for most of your artifacts, but prepend
2505 * "your" for unique objects and "foo of bar" quest artifacts */
2506 if (!carried(obj) || !obj_is_pname(obj)
2507 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2508 char *outbuf = shk_your(nextobuf(), obj);
2509 int space_left = BUFSZ - 1 - strlen(outbuf);
2511 s = strncat(outbuf, s, space_left);
2517 /* capitalized variant of yname() */
2522 char *s = yname(obj);
2530 /* returns "your minimal_xname(obj)"
2531 * or "Foobar's minimal_xname(obj)"
2532 * or "the minimal_xname(obj)"
2538 char *outbuf = nextobuf();
2539 char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */
2541 int space_left = BUFSZ - 1 - strlen(s);
2543 return strncat(s, minimal_xname(obj), space_left);
2545 int space_left = BUFSZ - strlen(s);
2547 return strncat(s, minimal_xname(obj), space_left);
2551 /* capitalized variant of ysimple_name() */
2556 char *s = ysimple_name(obj);
2564 /* "scroll" or "scrolls" */
2569 char *simpleoname = minimal_xname(obj);
2571 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2572 if (obj->quan != 1L)
2573 simpleoname = makeplural(simpleoname);
2578 /* "a scroll" or "scrolls"; "a silver bell" or "the Bell of Opening" */
2583 char *simpleoname = simpleonames(obj);
2584 int otyp = obj->otyp;
2586 /* prefix with "the" if a unique item, or a fake one imitating same,
2587 has been formatted with its actual name (we let typename() handle
2588 any `known' and `dknown' checking necessary) */
2589 if (otyp == FAKE_AMULET_OF_YENDOR)
2590 otyp = AMULET_OF_YENDOR;
2591 if (objects[otyp].oc_unique
2592 && !strcmp(simpleoname, OBJ_NAME(objects[otyp])))
2593 return the(simpleoname);
2595 /* simpleoname is singular if quan==1, plural otherwise */
2596 if (obj->quan == 1L)
2597 simpleoname = an(simpleoname);
2601 /* "the scroll" or "the scrolls" */
2606 char *simpleoname = simpleonames(obj);
2608 return the(simpleoname);
2611 /* artifact's name without any object type or known/dknown/&c feedback */
2613 bare_artifactname(obj)
2618 if (obj->oartifact) {
2619 outbuf = nextobuf();
2620 Strcpy(outbuf, artiname(obj->oartifact));
2622 if (!strncmp(outbuf, "The ", 4))
2623 outbuf[0] = lowc(outbuf[0]);
2626 outbuf = xname(obj);
2632 static const char *wrp[] = {
2633 "wand", "ring", "potion", "scroll", "gem",
2634 "amulet", "spellbook", "spell book",
2635 /* for non-specific wishes */
2636 "weapon", "armor", "tool", "food", "comestible",
2639 static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
2640 SCROLL_CLASS, GEM_CLASS, AMULET_CLASS,
2641 SPBOOK_CLASS, SPBOOK_CLASS, WEAPON_CLASS,
2642 ARMOR_CLASS, TOOL_CLASS, FOOD_CLASS,
2645 /* return form of the verb (input plural) if xname(otmp) were the subject */
2646 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2655 * verb is given in plural (without trailing s). Return as input
2656 * if the result of xname(otmp) would be plural. Don't bother
2657 * recomputing xname(otmp) at this time.
2659 if (!is_plural(otmp))
2660 return vtense((char *) 0, verb);
2668 /* various singular words that vtense would otherwise categorize as plural;
2669 also used by makesingular() to catch some special cases */
2670 static const char *const special_subjs[] = {
2671 "erinys", "manes", /* this one is ambiguous */
2672 "Cyclops", "Hippocrates", "Pelias", "aklys",
2673 "amnesia", "detect monsters", "paralysis", "shape changers",
2675 /* note: "detect monsters" and "shape changers" are normally
2676 caught via "<something>(s) of <whatever>", but they can be
2677 wished for using the shorter form, so we include them here
2678 to accommodate usage by makesingular during wishing */
2681 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2682 /* return form of the verb (input plural) for present tense 3rd person subj */
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 },
3493 rnd_otyp_by_wpnskill(skill)
3497 short otyp = STRANGE_OBJECT;
3499 for (i = bases[WEAPON_CLASS];
3500 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3501 if (objects[i].oc_skill == skill) {
3507 for (i = bases[WEAPON_CLASS];
3508 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3509 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;