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 */
365 #if 1 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\82»
\82±
\82Ü
\82Å
\82µ
\82È
\82¢*/
366 char *buf = nextobuf();
367 Sprintf(buf, "%s%s", pl_fruit, juice ? "
\83W
\83\85\81[
\83X" : "");
370 char *buf = nextobuf();
371 const char *fruit_nam = strstri(pl_fruit, " of ");
374 fruit_nam += 4; /* skip past " of " */
376 fruit_nam = pl_fruit; /* use it as is */
378 Sprintf(buf, "%s%s", makesingular(fruit_nam), juice ? " juice" : "");
383 /* look up a named fruit by index (1..127) */
385 fruit_from_indx(indx)
390 for (f = ffruit; f; f = f->nextf)
396 /* look up a named fruit by name */
398 fruit_from_name(fname, exact, highest_fid)
400 boolean exact; /* False => prefix or exact match, True = exact match only */
401 int *highest_fid; /* optional output; only valid if 'fname' isn't found */
403 struct fruit *f, *tentativef;
407 * note: named fruits are case-senstive...
412 /* first try for an exact match */
413 for (f = ffruit; f; f = f->nextf)
414 if (!strcmp(f->fname, fname))
416 else if (highest_fid && f->fid > *highest_fid)
417 *highest_fid = f->fid;
419 /* didn't match as-is; if caller is willing to accept a prefix
420 match, try to find one; we want to find the longest prefix that
421 matches, not the first */
424 for (f = ffruit; f; f = f->nextf) {
425 k = strlen(f->fname);
426 if (!strncmp(f->fname, fname, k)
427 && (!fname[k] || fname[k] == ' ')
428 && (!tentativef || k > strlen(tentativef->fname)))
433 /* if we still don't have a match, try singularizing the target;
434 for exact match, that's trivial, but for prefix, it's hard */
436 altfname = makesingular(fname);
437 for (f = ffruit; f; f = f->nextf) {
438 if (!strcmp(f->fname, altfname))
441 releaseobuf(altfname);
444 char fnamebuf[BUFSZ], *p;
445 unsigned fname_k = strlen(fname); /* length of assumed plural fname */
448 for (f = ffruit; f; f = f->nextf) {
449 k = strlen(f->fname);
450 /* reload fnamebuf[] each iteration in case it gets modified;
451 there's no need to recalculate fname_k */
452 Strcpy(fnamebuf, fname);
453 /* bug? if singular of fname is longer than plural,
454 failing the 'fname_k > k' test could skip a viable
455 candidate; unfortunately, we can't singularize until
456 after stripping off trailing stuff and we can't get
457 accurate fname_k until fname has been singularized;
458 compromise and use 'fname_k >= k' instead of '>',
459 accepting 1 char length discrepancy without risking
460 false match (I hope...) */
461 if (fname_k >= k && (p = index(&fnamebuf[k], ' ')) != 0) {
462 *p = '\0'; /* truncate at 1st space past length of f->fname */
463 altfname = makesingular(fnamebuf);
464 k = strlen(altfname); /* actually revised 'fname_k' */
465 if (!strcmp(f->fname, altfname)
466 && (!tentativef || k > strlen(tentativef->fname)))
468 releaseobuf(altfname); /* avoid churning through all obufs */
476 /* sort the named-fruit linked list by fruit index number */
478 reorder_fruit(forward)
481 struct fruit *f, *allfr[1 + 127];
482 int i, j, k = SIZE(allfr);
484 for (i = 0; i < k; ++i)
485 allfr[i] = (struct fruit *) 0;
486 for (f = ffruit; f; f = f->nextf) {
487 /* without sanity checking, this would reduce to 'allfr[f->fid]=f' */
489 if (j < 1 || j >= k) {
490 impossible("reorder_fruit: fruit index (%d) out of range", j);
491 return; /* don't sort after all; should never happen... */
492 } else if (allfr[j]) {
493 impossible("reorder_fruit: duplicate fruit index (%d)", j);
498 ffruit = 0; /* reset linked list; we're rebuilding it from scratch */
499 /* slot [0] will always be empty; must start 'i' at 1 to avoid
500 [k - i] being out of bounds during first iteration */
501 for (i = 1; i < k; ++i) {
502 /* for forward ordering, go through indices from high to low;
503 for backward ordering, go from low to high */
504 j = forward ? (k - i) : i;
506 allfr[j]->nextf = ffruit;
516 return xname_flags(obj, CXN_NORMAL);
520 xname_flags(obj, cxn_flags)
521 register struct obj *obj;
522 unsigned cxn_flags; /* bitmask of CXN_xxx values */
525 register int typ = obj->otyp;
526 register struct objclass *ocl = &objects[typ];
527 int nn = ocl->oc_name_known, omndx = obj->corpsenm;
528 const char *actualn = OBJ_NAME(*ocl);
529 const char *dn = OBJ_DESCR(*ocl);
530 const char *un = ocl->oc_uname;
531 boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
532 boolean known, dknown, bknown;
534 buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
535 if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
536 actualn = Japanese_item_name(typ);
537 /* As of 3.6.2: this used to be part of 'dn's initialization, but it
538 needs to come after possibly overriding 'actualn' */
544 * clean up known when it's tied to oc_name_known, eg after AD_DRIN
545 * This is only required for unique objects since the article
546 * printed for the object is tied to the combination of the two
547 * and printing the wrong article gives away information.
549 if (!nn && ocl->oc_uses_known && ocl->oc_unique)
551 if (!Blind && !distantname)
553 if (Role_if(PM_PRIEST))
554 obj->bknown = 1; /* actively avoid set_bknown();
555 * we mustn't call update_inventory() now because
556 * it would call xname() (via doname()) recursively
557 * and could end up clobbering all the obufs... */
559 if (iflags.override_ID) {
560 known = dknown = bknown = TRUE;
564 dknown = obj->dknown;
565 bknown = obj->bknown;
568 if (obj_is_pname(obj))
573 Strcat(buf, ONAME(obj));
578 if (has_oname(obj) && dknown) {
579 Strcat(buf, ONAME(obj));
580 Strcat(buf, "
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½");
583 switch (obj->oclass) {
587 Strcpy(buf, "amulet");
589 Strcat(buf, "
\96\82\8f\9c\82¯");
590 else if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
591 /* each must be identified individually */
592 Strcpy(buf, known ? actualn : dn);
594 Strcpy(buf, actualn);
597 Sprintf(buf, "amulet called %s", un);
599 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\8f\9c\82¯", un);
602 Sprintf(buf, "%s amulet", dn);
604 Sprintf(eos(buf), "%s", dn);
607 if (is_poisonable(obj) && obj->opoisoned)
609 Strcpy(buf, "poisoned ");
611 Strcpy(buf, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
617 Sprintf(eos(buf), "%s
\82Ì", mons[obj->corpsenm].mname);
621 Strcpy(buf, "pair of ");
623 Strcpy(buf, "
\88ê
\91Î
\82Ì");
624 else if (is_wet_towel(obj))
626 Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
628 Strcpy(buf, (obj->spe < 3) ? "
\8e¼
\82Á
\82½" : "
\94G
\82ê
\82½");
633 Strcat(buf, actualn);
637 Strcat(buf, " called ");
641 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é");
647 #if 0 /*JP*/ /*
\82±
\82ê
\82Í
\8cê
\8f\87\82Ì
\8aÖ
\8cW
\82©
\82ç
\8fã
\82Ì
\95û
\82Å
\92è
\8b`*/
648 if (typ == FIGURINE && omndx != NON_PM) {
649 char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */
651 Sprintf(eos(buf), " of %s%s",
652 just_an(anbuf, mons[omndx].mname),
654 } else if (is_wet_towel(obj)) {
656 if (is_wet_towel(obj)) {
659 Sprintf(eos(buf), " (%d)", obj->spe);
663 /* depends on order of the dragon scales objects */
664 if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
666 Sprintf(buf, "set of %s", actualn);
668 Sprintf(buf, "%s
\88ê
\8e®", actualn);
671 if (is_boots(obj) || is_gloves(obj))
673 Strcpy(buf, "pair of ");
675 Strcat(buf,"
\88ê
\91Î
\82Ì");
677 if (obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
680 Strcpy(buf, "shield");
682 Strcat(buf, "
\8f\82");
685 if (obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
687 Strcpy(buf, "smooth shield");
689 Strcat(buf, "
\82·
\82×
\82·
\82×
\82µ
\82½
\8f\82");
694 Strcat(buf, actualn);
698 Strcat(buf, "boots");
699 else if (is_gloves(obj))
700 Strcat(buf, "gloves");
701 else if (is_cloak(obj))
702 Strcpy(buf, "cloak");
703 else if (is_helmet(obj))
704 Strcpy(buf, "helmet");
705 else if (is_shield(obj))
706 Strcpy(buf, "shield");
708 Strcpy(buf, "armor");
709 Strcat(buf, " called ");
715 else if (is_gloves(obj))
717 else if (is_cloak(obj))
718 p = "
\83N
\83\8d\81[
\83N";
719 else if (is_helmet(obj))
721 else if (is_shield(obj))
725 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, p);
731 if (typ == SLIME_MOLD) {
732 struct fruit *f = fruit_from_indx(obj->spe);
735 impossible("Bad fruit #%d?", obj->spe);
736 Strcpy(buf, "fruit");
738 Strcpy(buf, f->fname);
740 /* ick; already pluralized fruit names
741 are allowed--we want to try to avoid
742 adding a redundant plural suffix */
743 Strcpy(buf, makeplural(makesingular(buf)));
760 ? "
\82Æ
\82Ä
\82à
\91å
\82«
\82¢"
772 Strcpy(buf, actualn);
773 if (typ == TIN && known)
774 tin_details(obj, omndx, buf);
776 if (typ == TIN && known)
777 /*JP
\81u
\81`
\82Ì
\93÷
\82Ì
\81v*/
778 tin_details(obj, omndx, buf);
779 Strcat(buf, actualn);
785 Strcpy(buf, actualn);
787 Strcat(buf, actualn);
791 if (typ == STATUE && omndx != NON_PM) {
795 Sprintf(buf, "%s%s of %s%s",
796 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
800 type_is_pname(&mons[omndx])
802 : the_unique_pm(&mons[omndx])
804 : just_an(anbuf, mons[omndx].mname),
807 Sprintf(eos(buf), "%s%s
\82Ì%s",
808 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
811 mons[obj->corpsenm].mname, actualn);
815 Strcpy(buf, actualn);
817 Strcat(buf, actualn);
822 Sprintf(buf, "%sheavy iron ball",
823 (obj->owt > ocl->oc_weight) ? "very " : "");
825 Sprintf(eos(buf), "%s
\8fd
\82¢
\93S
\8b\85",
826 (obj->owt > ocl->oc_weight) ? "
\82Æ
\82Ä
\82à" : "");
830 if (dknown && obj->odiluted)
832 Strcpy(buf, "diluted ");
834 Strcat(buf, "
\94\96\82Ü
\82Á
\82½");
835 if (nn || un || !dknown) {
837 Strcat(buf, "potion");
850 if (typ == POT_WATER && bknown
851 && (obj->blessed || obj->cursed)) {
853 Strcat(buf, obj->blessed ? "holy " : "unholy ");
855 Strcat(buf, obj->blessed ? "
\90¹" : "
\95s
\8fò
\82È");
857 Strcat(buf, actualn);
860 Strcat(buf, " called ");
864 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96ò");
869 #if 0 /*JP*//*
\95s
\8am
\92è
\96¼
\82É
\81u
\96ò
\81v
\82Í
\95t
\82¢
\82Ä
\82¢
\82é*/
870 Strcat(buf, " potion");
876 Strcpy(buf, "scroll");
881 Strcat(buf,"
\8aª
\95¨");
889 Strcat(buf, actualn);
892 Strcat(buf, " called ");
896 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8aª
\95¨");
898 } else if (ocl->oc_magic) {
900 Strcat(buf, " labeled ");
906 Strcat(buf, " scroll");
920 Sprintf(buf, "wand of %s", actualn);
922 Strcat(buf, actualn);
925 Sprintf(buf, "wand called %s", un);
927 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8fñ", un);
930 Sprintf(buf, "%s wand", dn);
935 if (typ == SPE_NOVEL) { /* 3.6 tribute */
942 Strcpy(buf, actualn);
945 Sprintf(buf, "novel called %s", un);
947 Sprintf(buf, "%s
\82Æ
\82¢
\82¤
\8f¬
\90à", un);
950 Sprintf(buf, "%s book", dn);
952 Sprintf(buf, "%s
\96{", dn);
955 } else if (!dknown) {
957 Strcpy(buf, "spellbook");
959 Strcat(buf, "
\96\82\96@
\8f\91");
962 if (typ != SPE_BOOK_OF_THE_DEAD)
963 Strcpy(buf, "spellbook of ");
965 Strcat(buf, actualn);
968 Sprintf(buf, "spellbook called %s", un);
970 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\96@
\8f\91", un);
973 Sprintf(buf, "%s spellbook", dn);
975 Sprintf(eos(buf), "%s", dn);
982 Strcat(buf, "
\8ew
\97Ö");
985 Sprintf(buf, "ring of %s", actualn);
987 Strcat(buf, actualn);
990 Sprintf(buf, "ring called %s", un);
992 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8ew
\97Ö", un);
995 Sprintf(buf, "%s ring", dn);
1001 const char *rock = (ocl->oc_material == MINERAL) ? "stone" : "gem";
1003 const char *rock = (ocl->oc_material == MINERAL) ? "
\90Î" : "
\95ó
\90Î";
1014 Sprintf(buf, "%s called %s", rock, un);
1016 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, rock);
1019 Sprintf(buf, "%s %s", dn, rock);
1023 Strcpy(buf, actualn);
1026 Strcat(buf, " stone");
1032 Sprintf(buf, "glorkum %d %d %d", obj->oclass, typ, obj->spe);
1036 Strcpy(buf, makeplural(buf));
1039 if (obj->otyp == T_SHIRT && program_state.gameover) {
1043 Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
1045 Sprintf(eos(buf), "(
\81u%s
\81v
\82Æ
\8f\91\82¢
\82Ä
\82 \82é)", tshirt_text(obj, tmpbuf));
1049 if (has_oname(obj) && dknown) {
1050 Strcat(buf, " named ");
1052 Strcat(buf, ONAME(obj));
1055 if (!strncmpi(buf, "the ", 4))
1063 /* similar to simple_typename but minimal_xname operates on a particular
1064 object rather than its general type; it formats the most basic info:
1065 potion -- if description not known
1066 brown potion -- if oc_name_known not set
1067 potion of object detection -- if discovered
1075 struct objclass saveobcls;
1076 int otyp = obj->otyp;
1078 /* suppress user-supplied name */
1079 saveobcls.oc_uname = objects[otyp].oc_uname;
1080 objects[otyp].oc_uname = 0;
1081 /* suppress actual name if object's description is unknown */
1082 saveobcls.oc_name_known = objects[otyp].oc_name_known;
1084 objects[otyp].oc_name_known = 0;
1086 /* caveat: this makes a lot of assumptions about which fields
1087 are required in order for xname() to yield a sensible result */
1089 bareobj.otyp = otyp;
1090 bareobj.oclass = obj->oclass;
1091 bareobj.dknown = obj->dknown;
1092 /* suppress known except for amulets (needed for fakes and real A-of-Y) */
1093 bareobj.known = (obj->oclass == AMULET_CLASS)
1095 /* default is "on" for types which don't use it */
1096 : !objects[otyp].oc_uses_known;
1097 bareobj.quan = 1L; /* don't want plural */
1098 bareobj.corpsenm = NON_PM; /* suppress statue and figurine details */
1099 /* but suppressing fruit details leads to "bad fruit #0"
1100 [perhaps we should force "slime mold" rather than use xname?] */
1101 if (obj->otyp == SLIME_MOLD)
1102 bareobj.spe = obj->spe;
1104 bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
1106 if (!strncmp(bufp, "uncursed ", 9))
1107 bufp += 9; /* Role_if(PM_PRIEST) */
1109 if (!strncmp(bufp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", 14))
1110 bufp += 14; /* Role_if(PM_PRIEST) */
1113 objects[otyp].oc_uname = saveobcls.oc_uname;
1114 objects[otyp].oc_name_known = saveobcls.oc_name_known;
1118 /* xname() output augmented for multishot missile feedback */
1124 char *onm = xname(obj);
1126 if (m_shot.n > 1 && m_shot.o == obj->otyp) {
1127 /* "the Nth arrow"; value will eventually be passed to an() or
1128 The(), both of which correctly handle this "the " prefix */
1130 Sprintf(tmpbuf, "the %d%s ", m_shot.i, ordin(m_shot.i));
1132 Sprintf(tmpbuf, "%d%s
\96Ú
\82Ì", m_shot.i, numeral(obj));
1133 onm = strprepend(onm, tmpbuf);
1138 /* used for naming "the unique_item" instead of "a unique_item" */
1144 boolean known = (obj->known || iflags.override_ID);
1146 if (!obj->dknown && !iflags.override_ID)
1148 else if (obj->otyp == FAKE_AMULET_OF_YENDOR && !known)
1149 return TRUE; /* lie */
1151 return (boolean) (objects[obj->otyp].oc_unique
1152 && (known || obj->otyp == AMULET_OF_YENDOR));
1158 /* should monster type be prefixed with "the"? (mostly used for corpses) */
1161 struct permonst *ptr;
1165 /* even though monsters with personal names are unique, we want to
1166 describe them as "Name" rather than "the Name" */
1167 if (type_is_pname(ptr))
1170 uniq = (ptr->geno & G_UNIQ) ? TRUE : FALSE;
1171 /* high priest is unique if it includes "of <deity>", otherwise not
1172 (caller needs to handle the 1st possibility; we assume the 2nd);
1173 worm tail should be irrelevant but is included for completeness */
1174 if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
1176 /* Wizard no longer needs this; he's flagged as unique these days */
1177 if (ptr == &mons[PM_WIZARD_OF_YENDOR])
1183 add_erosion_words(obj, prefix)
1187 boolean iscrys = (obj->otyp == CRYSKNIFE);
1190 rknown = (iflags.override_ID == 0) ? obj->rknown : TRUE;
1192 if (!is_damageable(obj) && !iscrys)
1195 /* The only cases where any of these bits do double duty are for
1196 * rotted food and diluted potions, which are all not is_damageable().
1198 if (obj->oeroded && !iscrys) {
1199 switch (obj->oeroded) {
1202 Strcat(prefix, "very ");
1204 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1208 Strcat(prefix, "thoroughly ");
1210 Strcat(prefix, "
\82©
\82È
\82è");
1214 Strcat(prefix, is_rustprone(obj) ? "rusty " : "burnt ");
1216 Strcat(prefix, is_rustprone(obj) ? "
\8eK
\82Ñ
\82½" : "
\8f\9d\82Â
\82¢
\82½");
1218 if (obj->oeroded2 && !iscrys) {
1219 switch (obj->oeroded2) {
1222 Strcat(prefix, "very ");
1224 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1228 Strcat(prefix, "thoroughly ");
1230 Strcat(prefix, "
\82©
\82È
\82è");
1234 Strcat(prefix, is_corrodeable(obj) ? "corroded " : "rotted ");
1236 Strcat(prefix, is_corrodeable(obj) ? "
\95\85\90H
\82µ
\82½" : "
\95\85\82Á
\82½");
1238 if (rknown && obj->oerodeproof)
1240 Strcat(prefix, iscrys
1244 : is_corrodeable(obj)
1245 ? "corrodeproof " /* "stainless"? */
1250 Strcat(prefix, iscrys
1251 ? "
\88À
\92è
\82µ
\82½"
1253 ? "
\8eK
\82Ñ
\82È
\82¢"
1254 : is_corrodeable(obj)
1255 ? "
\95\85\90H
\82µ
\82È
\82¢" /* "stainless"? */
1257 ? "
\94R
\82¦
\82È
\82¢"
1262 /* used to prevent rust on items where rust makes no difference */
1264 erosion_matters(obj)
1267 switch (obj->oclass) {
1269 /* it's possible for a rusty weptool to be polymorphed into some
1270 non-weptool iron tool, in which case the rust implicitly goes
1271 away, but it's also possible for it to be polymorphed into a
1272 non-iron tool, in which case rust also implicitly goes away,
1273 so there's no particular reason to try to handle the first
1274 instance differently [this comment belongs in poly_obj()...] */
1275 return is_weptool(obj) ? TRUE : FALSE;
1287 #define DONAME_WITH_PRICE 1
1288 #define DONAME_VAGUE_QUAN 2
1291 doname_base(obj, doname_flags)
1293 unsigned doname_flags;
1295 boolean ispoisoned = FALSE,
1296 with_price = (doname_flags & DONAME_WITH_PRICE) != 0,
1297 vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0,
1298 weightshown = FALSE;
1299 boolean known, dknown, cknown, bknown, lknown;
1300 int omndx = obj->corpsenm;
1301 char prefix[PREFIX], globbuf[QBUFSZ];
1303 char tmpbuf[PREFIX + 1]; /* for when we have to add something at
1304 the start of prefix instead of the
1305 end (Strcat is used on the end) */
1307 register char *bp = xname(obj);
1308 #if 1 /*JP*//*
\8f\87\8f\98\93ü
\82ê
\91Ö
\82¦
\82É
\8eg
\82¤*/
1309 char preprefix[PREFIX];
1312 if (iflags.override_ID) {
1313 known = dknown = cknown = bknown = lknown = TRUE;
1316 dknown = obj->dknown;
1317 cknown = obj->cknown;
1318 bknown = obj->bknown;
1319 lknown = obj->lknown;
1322 /* When using xname, we want "poisoned arrow", and when using
1323 * doname, we want "poisoned +0 arrow". This kludge is about the only
1324 * way to do it, at least until someone overhauls xname() and doname(),
1325 * combining both into one function taking a parameter.
1327 /* must check opoisoned--someone can have a weirdly-named fruit */
1329 if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
1334 if (!strncmp(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", 12) && obj->opoisoned) {
1341 *
\81u
\8eq
\94L
\82Ì
\82½
\82Ü
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\8e\80\91Ì
\81v
\82æ
\82è
\81u
\82½
\82Ü
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\8eq
\94L
\82Ì
\8e\80\91Ì
\81v
1342 *
\82Ì
\82Ù
\82¤
\82ª
\8e©
\91R
\82Å
\82 \82é
\81D
1346 preprefix[0] = '\0';
1347 if((tp = strstri(bp, "
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½")) != NULL){
1348 tp += 12; /*
\81u
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\81v*/
1349 strncpy(preprefix, bp, tp - bp);
1350 preprefix[tp - bp] = '\0';
1357 if (obj->quan != 1L) {
1358 if (dknown || !vague_quan)
1360 Sprintf(prefix, "%ld ", obj->quan);
1361 #else /*
\93ú
\96{
\8cê
\82Æ
\82µ
\82Ä
\82Í
\90\94\8e\8c\82ª
\82È
\82¢
\82Ì
\82Í
\95s
\8e©
\91R */
1362 Sprintf(prefix, "%ld%s
\82Ì", obj->quan, numeral(obj));
1366 Strcpy(prefix, "some ");
1368 Strcpy(prefix, "
\82¢
\82
\82Â
\82©
\82Ì");
1369 } else if (obj->otyp == CORPSE) {
1370 /* skip article prefix for corpses [else corpse_xname()
1371 would have to be taught how to strip it off again] */
1373 #if 0 /*JP*/ /*
\8a¥
\8e\8c\82Í
\95s
\97v */
1374 } else if (obj_is_pname(obj) || the_unique_obj(obj)) {
1375 if (!strncmpi(bp, "the ", 4))
1377 Strcpy(prefix, "the ");
1379 Strcpy(prefix, "a ");
1380 #else /*prefix
\82Ì
\8f\89\8aú
\89»*/
1386 /* "empty" goes at the beginning, but item count goes at the end */
1388 /* bag of tricks: include "empty" prefix if it's known to
1389 be empty but its precise number of charges isn't known
1390 (when that is known, suffix of "(n:0)" will be appended,
1391 making the prefix be redundant; note that 'known' flag
1392 isn't set when emptiness gets discovered because then
1393 charging magic would yield known number of new charges) */
1394 && ((obj->otyp == BAG_OF_TRICKS)
1395 ? (obj->spe == 0 && !obj->known)
1396 /* not bag of tricks: empty if container which has no contents */
1397 : ((Is_container(obj) || obj->otyp == STATUE)
1398 && !Has_contents(obj))))
1400 Strcat(prefix, "empty ");
1402 Strcat(prefix, "
\8bó
\82Ì");
1404 if (bknown && obj->oclass != COIN_CLASS
1405 && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
1406 || (!obj->cursed && !obj->blessed))) {
1407 /* allow 'blessed clear potion' if we don't know it's holy water;
1408 * always allow "uncursed potion of water"
1412 Strcat(prefix, "cursed ");
1414 Strcat(prefix, "
\8eô
\82í
\82ê
\82½");
1415 else if (obj->blessed)
1417 Strcat(prefix, "blessed ");
1419 Strcat(prefix, "
\8fj
\95\9f\82³
\82ê
\82½");
1420 else if (!iflags.implicit_uncursed
1421 /* For most items with charges or +/-, if you know how many
1422 * charges are left or what the +/- is, then you must have
1423 * totally identified the item, so "uncursed" is unnecessary,
1424 * because an identified object not described as "blessed" or
1425 * "cursed" must be uncursed.
1427 * If the charges or +/- is not known, "uncursed" must be
1428 * printed to avoid ambiguity between an item whose curse
1429 * status is unknown, and an item known to be uncursed.
1431 || ((!known || !objects[obj->otyp].oc_charged
1432 || obj->oclass == ARMOR_CLASS
1433 || obj->oclass == RING_CLASS)
1435 && obj->otyp != SCR_MAIL
1437 && obj->otyp != FAKE_AMULET_OF_YENDOR
1438 && obj->otyp != AMULET_OF_YENDOR
1439 && !Role_if(PM_PRIEST)))
1441 Strcat(prefix, "uncursed ");
1443 Strcat(prefix, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢");
1446 if (lknown && Is_box(obj)) {
1448 /* 3.6.0 used "unlockable" here but that could be misunderstood
1449 to mean "capable of being unlocked" rather than the intended
1450 "not capable of being locked" */
1452 Strcat(prefix, "broken ");
1454 Strcat(prefix, "
\8c®
\82Ì
\89ó
\82ê
\82½");
1455 else if (obj->olocked)
1457 Strcat(prefix, "locked ");
1459 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½");
1462 Strcat(prefix, "unlocked ");
1464 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢");
1469 Strcat(prefix, "greased ");
1471 Strcat(prefix, "
\96û
\82Ì
\93h
\82ç
\82ê
\82½");
1473 if (cknown && Has_contents(obj)) {
1474 /* we count the number of separate stacks, which corresponds
1475 to the number of inventory slots needed to be able to take
1476 everything out if no merges occur */
1477 long itemcount = count_contents(obj, FALSE, FALSE, TRUE, FALSE);
1480 Sprintf(eos(bp), " containing %ld item%s", itemcount,
1483 Sprintf(eos(bp), "(%ld
\8cÂ
\93ü
\82Á
\82Ä
\82¢
\82é)", itemcount);
1487 switch (is_weptool(obj) ? WEAPON_CLASS : obj->oclass) {
1489 if (obj->owornmask & W_AMUL)
1491 Strcat(bp, " (being worn)");
1493 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1496 if (obj->owornmask & W_ARMOR) {
1498 Strcat(bp, (obj == uskin) ? " (embedded in your skin)"
1500 Strcat(bp, (obj == uskin) ? "(
\94§
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é)"
1501 /* in case of perm_invent update while Wear/Takeoff
1502 is in progress; check doffing() before donning()
1503 because donning() returns True for both cases */
1504 : doffing(obj) ? " (being doffed)"
1505 : donning(obj) ? " (being donned)"
1509 : "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1510 /* slippery fingers is an intrinsic condition of the hero
1511 rather than extrinsic condition of objects, but gloves
1512 are described as slippery when hero has slippery fingers */
1513 if (obj == uarmg && Glib) /* just appended "(something)",
1514 * change to "(something; slippery)" */
1515 Strcpy(rindex(bp, ')'), "; slippery)");
1521 Strcat(prefix, "poisoned ");
1523 Strcat(prefix, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
1524 add_erosion_words(obj, prefix);
1526 Strcat(prefix, sitoa(obj->spe));
1527 Strcat(prefix, " ");
1531 if (obj->owornmask & (W_TOOL | W_SADDLE)) { /* blindfold */
1533 Strcat(bp, " (being worn)");
1535 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1538 if (obj->otyp == LEASH && obj->leashmon != 0) {
1539 struct monst *mlsh = find_mid(obj->leashmon, FM_FMON);
1542 impossible("leashed monster not on this level");
1546 Sprintf(eos(bp), " (attached to %s)",
1547 noit_mon_nam(mlsh));
1549 Sprintf(eos(bp), " (%s
\82É
\8c\8b\82Ñ
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)",
1550 noit_mon_nam(mlsh));
1555 if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1558 Strcpy(tmpbuf, "no");
1560 Sprintf(tmpbuf, "%d", obj->spe);
1561 Sprintf(eos(bp), " (%s candle%s%s)", tmpbuf, plur(obj->spe),
1562 !obj->lamplit ? " attached" : ", lit");
1565 Sprintf(eos(bp), "(
\88ê
\96{
\82à
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢)");
1568 Sprintf(eos(bp), "(%d
\96{
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)", obj->spe);
1570 Sprintf(eos(bp), "(%d
\96{
\8cõ
\82Á
\82Ä
\82¢
\82é)", obj->spe);
1574 } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
1575 || obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
1577 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
1579 Strcat(prefix, "partly used ");
1581 Strcat(prefix, "
\8eg
\82¢
\82³
\82µ
\82Ì");
1584 Strcat(bp, " (lit)");
1586 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1589 if (objects[obj->otyp].oc_charged)
1596 Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe);
1598 Sprintf(eos(bp), "(%d:%d)", (int) obj->recharged, obj->spe);
1601 if (obj->otyp == POT_OIL && obj->lamplit)
1603 Strcat(bp, " (lit)");
1605 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1609 if (obj->owornmask & W_RINGR)
1611 Strcat(bp, " (on right ");
1613 Strcat(bp, "(
\89E");
1614 if (obj->owornmask & W_RINGL)
1616 Strcat(bp, " (on left ");
1618 Strcat(bp, "(
\8d¶");
1619 if (obj->owornmask & W_RING) {
1620 Strcat(bp, body_part(HAND));
1623 if (known && objects[obj->otyp].oc_charged) {
1625 Strcat(prefix, " ");
1627 Strcat(prefix, sitoa(obj->spe));
1628 Strcat(prefix, " ");
1634 Strcat(prefix, "partly eaten ");
1636 Strcat(prefix, "
\90H
\82×
\82©
\82¯
\82Ì");
1637 if (obj->otyp == CORPSE) {
1638 /* (quan == 1) => want corpse_xname() to supply article,
1639 (quan != 1) => already have count or "some" as prefix;
1640 "corpse" is already in the buffer returned by xname() */
1641 unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE)
1643 char *cxstr = corpse_xname(obj, prefix, cxarg);
1646 Sprintf(prefix, "%s ", cxstr);
1648 Sprintf(prefix, "%s
\82Ì", cxstr);
1650 /* avoid having doname(corpse) consume an extra obuf */
1652 } else if (obj->otyp == EGG) {
1653 #if 0 /* corpses don't tell if they're stale either */
1654 if (known && stale_egg(obj))
1655 Strcat(prefix, "stale ");
1658 && (known || (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
1660 Strcat(prefix, mons[omndx].mname);
1661 Strcat(prefix, " ");
1663 Strcat(prefix, mons[omndx].mname);
1664 Strcat(prefix, "
\82Ì");
1668 Strcat(bp, " (laid by you)");
1670 Strcat(bp, "(
\82 \82È
\82½
\82ª
\8eY
\82ñ
\82¾)");
1673 if (obj->otyp == MEAT_RING)
1678 add_erosion_words(obj, prefix);
1679 if (obj->owornmask & W_BALL)
1681 Strcat(bp, " (chained to you)");
1683 Strcat(bp, "(
\82 \82È
\82½
\82É
\8cq
\82ª
\82ê
\82Ä
\82¢
\82é)");
1687 if ((obj->owornmask & W_WEP) && !mrg_to_wielded) {
1688 if (obj->quan != 1L) {
1690 Strcat(bp, " (wielded)");
1692 Strcat(bp, "(
\91\95\94õ
\82µ
\82Ä
\82¢
\82é)");
1694 const char *hand_s = body_part(HAND);
1697 hand_s = makeplural(hand_s);
1698 /* note: Sting's glow message, if added, will insert text
1699 in front of "(weapon in hand)"'s closing paren */
1701 Sprintf(eos(bp), " (%sweapon in %s)",
1702 (obj->otyp == AKLYS) ? "tethered " : "", hand_s);
1703 #else /*
\83A
\83L
\83\8a\83X
\82ð
\93Á
\95Ê
\88µ
\82¢
\82µ
\82È
\82¢*/
1704 Sprintf(eos(bp), "(%s
\82É
\82µ
\82Ä
\82¢
\82é)", hand_s);
1707 if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
1708 if (!Blind) /* we know bp[] ends with ')'; overwrite that */
1710 Sprintf(eos(bp) - 1, ", %s %s)",
1711 glow_verb(warn_obj_cnt, TRUE),
1712 glow_color(obj->oartifact));
1714 Sprintf(eos(bp) - 1, ", %s%s
\82¢
\82é)",
1715 jconj_adj(glow_color(obj->oartifact)),
1716 jconj(glow_verb(warn_obj_cnt, TRUE), "
\82Ä"));
1721 if (obj->owornmask & W_SWAPWEP) {
1724 Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND));
1726 Sprintf(eos(bp), "(
\8d¶%s
\82É
\82µ
\82Ä
\82¢
\82é)", body_part(HAND));
1729 Strcat(bp, " (alternate weapon; not wielded)");
1731 Strcat(bp, "(
\97\
\94õ
\82Ì
\95\90\8aí;
\91\95\94õ
\82µ
\82Ä
\82¢
\82È
\82¢)");
1733 if (obj->owornmask & W_QUIVER) {
1734 switch (obj->oclass) {
1737 if (objects[obj->otyp].oc_skill == -P_BOW) {
1738 /* Ammo for a bow */
1740 Strcat(bp, " (in quiver)");
1742 Strcat(bp, "(
\96î
\93\9b\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1745 /* Ammo not for a bow */
1747 Strcat(bp, " (in quiver pouch)");
1749 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1753 /* Weapons not considered ammo */
1755 Strcat(bp, " (at the ready)");
1757 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1760 /* Small things and ammo not for a bow */
1767 Strcat(bp, " (in quiver pouch)");
1769 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1771 default: /* odd things */
1773 Strcat(bp, " (at the ready)");
1775 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1778 /* treat 'restoring' like suppress_price because shopkeeper and
1779 bill might not be available yet while restore is in progress
1780 (objects won't normally be formatted during that time, but if
1781 'perm_invent' is enabled then they might be) */
1782 if (iflags.suppress_price || restoring) {
1783 ; /* don't attempt to obtain any stop pricing, even if 'with_price' */
1784 } else if (is_unpaid(obj)) { /* in inventory or in container in invent */
1785 long quotedprice = unpaid_cost(obj, TRUE);
1788 Sprintf(eos(bp), " (%s, %s%ld %s)",
1789 obj->unpaid ? "unpaid" : "contents",
1790 globwt(obj, globbuf, &weightshown),
1791 quotedprice, currency(quotedprice));
1793 Sprintf(eos(bp), " (%s, %s%ld%s)",
1794 obj->unpaid ? "
\96¢
\95¥
\82¢" : "
\92\86\90g",
1795 globwt(obj, globbuf, &weightshown),
1796 quotedprice, currency(quotedprice));
1798 } else if (with_price) { /* on floor or in container on floor */
1800 long price = get_cost_of_shop_item(obj, &nochrg);
1803 Sprintf(eos(bp), " (%s, %s%ld %s)",
1804 nochrg ? "contents" : "for sale",
1805 globwt(obj, globbuf, &weightshown),
1806 price, currency(price));
1807 else if (nochrg > 0)
1808 Sprintf(eos(bp), " (%sno charge)",
1809 globwt(obj, globbuf, &weightshown));
1811 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1812 if (!strncmp(prefix, "a ", 2)) {
1813 /* save current prefix, without "a "; might be empty */
1814 Strcpy(tmpbuf, prefix + 2);
1815 /* set prefix[] to "", "a ", or "an " */
1816 (void) just_an(prefix, *tmpbuf ? tmpbuf : bp);
1817 /* append remainder of original prefix */
1818 Strcat(prefix, tmpbuf);
1822 /* show weight for items (debug tourist info);
1823 "aum" is stolen from Crawl's "Arbitrary Unit of Measure" */
1824 if (wizard && iflags.wizweight) {
1825 /* wizard mode user has asked to see object weights;
1826 globs with shop pricing attached already include it */
1828 Sprintf(eos(bp), " (%u aum)", obj->owt);
1831 bp = strprepend(bp, prefix);
1832 #else /*JP:
\81u
\96¼
\95t
\82¯
\82ç
\82ê
\82½
\81v
\82ð
\96ß
\82·*/
1833 Strcat(preprefix, prefix);
1834 bp = strprepend(bp, preprefix);
1843 return doname_base(obj, (unsigned) 0);
1846 /* Name of object including price. */
1848 doname_with_price(obj)
1851 return doname_base(obj, DONAME_WITH_PRICE);
1854 /* "some" instead of precise quantity if obj->dknown not set */
1856 doname_vague_quan(obj)
1860 * If it hasn't been seen up close and quantity is more than one,
1861 * use "some" instead of the quantity: "some gold pieces" rather
1862 * than "25 gold pieces". This is suboptimal, to put it mildly,
1863 * because lookhere and pickup report the precise amount.
1864 * Picking the item up while blind also shows the precise amount
1865 * for inventory display, then dropping it while still blind leaves
1866 * obj->dknown unset so the count reverts to "some" for farlook.
1868 * TODO: add obj->qknown flag for 'quantity known' on stackable
1869 * items; it could overlay obj->cknown since no containers stack.
1871 return doname_base(obj, DONAME_VAGUE_QUAN);
1874 /* used from invent.c */
1876 not_fully_identified(otmp)
1879 /* gold doesn't have any interesting attributes [yet?] */
1880 if (otmp->oclass == COIN_CLASS)
1881 return FALSE; /* always fully ID'd */
1882 /* check fundamental ID hallmarks first */
1883 if (!otmp->known || !otmp->dknown
1885 || (!otmp->bknown && otmp->otyp != SCR_MAIL)
1889 || !objects[otmp->otyp].oc_name_known)
1891 if ((!otmp->cknown && (Is_container(otmp) || otmp->otyp == STATUE))
1892 || (!otmp->lknown && Is_box(otmp)))
1894 if (otmp->oartifact && undiscovered_artifact(otmp->oartifact))
1896 /* otmp->rknown is the only item of interest if we reach here */
1898 * Note: if a revision ever allows scrolls to become fireproof or
1899 * rings to become shockproof, this checking will need to be revised.
1900 * `rknown' ID only matters if xname() will provide the info about it.
1903 || (otmp->oclass != ARMOR_CLASS && otmp->oclass != WEAPON_CLASS
1904 && !is_weptool(otmp) /* (redundant) */
1905 && otmp->oclass != BALL_CLASS)) /* (useless) */
1907 else /* lack of `rknown' only matters for vulnerable objects */
1908 return (boolean) (is_rustprone(otmp) || is_corrodeable(otmp)
1909 || is_flammable(otmp));
1912 /* format a corpse name (xname() omits monster type; doname() calls us);
1913 eatcorpse() also uses us for death reason when eating tainted glob */
1915 corpse_xname(otmp, adjective, cxn_flags)
1917 const char *adjective;
1918 unsigned cxn_flags; /* bitmask of CXN_xxx values */
1920 /* some callers [aobjnam()] rely on prefix area that xname() sets aside */
1921 char *nambuf = nextobuf() + PREFIX;
1922 int omndx = otmp->corpsenm;
1924 boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
1925 /* suppress "the" from "the unique monster corpse" */
1929 no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
1930 /* include "the" for "the woodchuck corpse */
1931 the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
1932 /* include "an" for "an ogre corpse */
1933 any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
1934 /* leave off suffix (do_name() appends "corpse" itself) */
1935 omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
1937 glob = (otmp->otyp != CORPSE && otmp->globby);
1941 mname = OBJ_NAME(objects[otmp->otyp]); /* "glob of <monster>" */
1942 } else if (omndx == NON_PM) { /* paranoia */
1947 /* [Possible enhancement: check whether corpse has monster traits
1948 attached in order to use priestname() for priests and minions.] */
1949 } else if (omndx == PM_ALIGNED_PRIEST) {
1950 /* avoid "aligned priest"; it just exposes internal details */
1956 mname = mons[omndx].mname;
1957 if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
1958 mname = s_suffix(mname);
1960 /* don't precede personal name like "Medusa" with an article */
1961 if (type_is_pname(&mons[omndx]))
1963 /* always precede non-personal unique monster name like
1964 "Oracle" with "the" unless explicitly overridden */
1965 else if (the_unique_pm(&mons[omndx]) && !no_prefix)
1970 the_prefix = any_prefix = FALSE;
1971 else if (the_prefix)
1972 any_prefix = FALSE; /* mutually exclusive */
1975 /* can't use the() the way we use an() below because any capitalized
1976 Name causes it to assume a personal name and return Name as-is;
1977 that's usually the behavior wanted, but here we need to force "the"
1978 to precede capitalized unique monsters (pnames are handled above) */
1979 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1981 Strcat(nambuf, "the ");
1984 if (!adjective || !*adjective) {
1985 /* normal case: newt corpse */
1986 Strcat(nambuf, mname);
1988 /* adjective positioning depends upon format of monster name */
1989 if (possessive) /* Medusa's cursed partly eaten corpse */
1991 Sprintf(eos(nambuf), "%s %s", mname, adjective);
1993 Sprintf(eos(nambuf), "%s%s", mname, adjective);
1994 else /* cursed partly eaten troll corpse */
1996 Sprintf(eos(nambuf), "%s %s", adjective, mname);
1998 Sprintf(eos(nambuf), "%s%s", adjective, mname);
1999 /* in case adjective has a trailing space, squeeze it out */
2001 /* doname() might include a count in the adjective argument;
2002 if so, don't prepend an article */
2003 if (digit(*adjective))
2008 ; /* omit_corpse doesn't apply; quantity is always 1 */
2009 } else if (!omit_corpse) {
2011 Strcat(nambuf, " corpse");
2012 /* makeplural(nambuf) => append "s" to "corpse" */
2013 if (otmp->quan > 1L && !ignore_quan) {
2014 Strcat(nambuf, "s");
2015 any_prefix = FALSE; /* avoid "a newt corpses" */
2018 Strcat(nambuf, "
\82Ì
\8e\80\91Ì");
2022 /* it's safe to overwrite our nambuf after an() has copied
2023 its old value into another buffer */
2025 Strcpy(nambuf, an(nambuf));
2030 /* xname doesn't include monster type for "corpse"; cxname does */
2035 if (obj->otyp == CORPSE)
2036 return corpse_xname(obj, (const char *) 0, CXN_NORMAL);
2040 /* like cxname, but ignores quantity */
2042 cxname_singular(obj)
2045 if (obj->otyp == CORPSE)
2046 return corpse_xname(obj, (const char *) 0, CXN_SINGULAR);
2047 return xname_flags(obj, CXN_SINGULAR);
2050 /* treat an object as fully ID'd when it might be used as reason for death */
2055 struct obj save_obj;
2056 unsigned save_ocknown;
2057 char *buf, *save_ocuname, *save_oname = (char *) 0;
2059 /* bypass object twiddling for artifacts */
2061 return bare_artifactname(obj);
2063 /* remember original settings for core of the object;
2064 oextra structs other than oname don't matter here--since they
2065 aren't modified they don't need to be saved and restored */
2068 save_oname = ONAME(obj);
2070 /* killer name should be more specific than general xname; however, exact
2071 info like blessed/cursed and rustproof makes things be too verbose */
2072 obj->known = obj->dknown = 1;
2073 obj->bknown = obj->rknown = obj->greased = 0;
2074 /* if character is a priest[ess], bknown will get toggled back on */
2075 if (obj->otyp != POT_WATER)
2076 obj->blessed = obj->cursed = 0;
2078 obj->bknown = 1; /* describe holy/unholy water as such */
2079 /* "killed by poisoned <obj>" would be misleading when poison is
2080 not the cause of death and "poisoned by poisoned <obj>" would
2081 be redundant when it is, so suppress "poisoned" prefix */
2083 /* strip user-supplied name; artifacts keep theirs */
2084 if (!obj->oartifact && save_oname)
2085 ONAME(obj) = (char *) 0;
2086 /* temporarily identify the type of object */
2087 save_ocknown = objects[obj->otyp].oc_name_known;
2088 objects[obj->otyp].oc_name_known = 1;
2089 save_ocuname = objects[obj->otyp].oc_uname;
2090 objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
2092 /* format the object */
2093 if (obj->otyp == CORPSE) {
2094 buf = corpse_xname(obj, (const char *) 0, CXN_NORMAL);
2095 } else if (obj->otyp == SLIME_MOLD) {
2096 /* concession to "most unique deaths competition" in the annual
2097 devnull tournament, suppress player supplied fruit names because
2098 those can be used to fake other objects and dungeon features */
2101 Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
2103 Strcpy(buf, "
\8aë
\8c¯
\82È
\82Ë
\82Î
\82Ë
\82Î
\83J
\83r");
2107 /* apply an article if appropriate; caller should always use KILLED_BY */
2108 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
2109 if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
2110 buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
2113 objects[obj->otyp].oc_name_known = save_ocknown;
2114 objects[obj->otyp].oc_uname = save_ocuname;
2115 *obj = save_obj; /* restore object's core settings */
2116 if (!obj->oartifact && save_oname)
2117 ONAME(obj) = save_oname;
2122 /* xname,doname,&c with long results reformatted to omit some stuff */
2124 short_oname(obj, func, altfunc, lenlimit)
2126 char *FDECL((*func), (OBJ_P)), /* main formatting routine */
2127 *FDECL((*altfunc), (OBJ_P)); /* alternate for shortest result */
2130 struct obj save_obj;
2131 char unamebuf[12], onamebuf[12], *save_oname, *save_uname, *outbuf;
2133 outbuf = (*func)(obj);
2134 if ((unsigned) strlen(outbuf) <= lenlimit)
2137 /* shorten called string to fairly small amount */
2138 save_uname = objects[obj->otyp].oc_uname;
2139 if (save_uname && strlen(save_uname) >= sizeof unamebuf) {
2140 (void) strncpy(unamebuf, save_uname, sizeof unamebuf - 4);
2141 Strcpy(unamebuf + sizeof unamebuf - 4, "...");
2142 objects[obj->otyp].oc_uname = unamebuf;
2143 releaseobuf(outbuf);
2144 outbuf = (*func)(obj);
2145 objects[obj->otyp].oc_uname = save_uname; /* restore called string */
2146 if ((unsigned) strlen(outbuf) <= lenlimit)
2150 /* shorten named string to fairly small amount */
2151 save_oname = has_oname(obj) ? ONAME(obj) : 0;
2152 if (save_oname && strlen(save_oname) >= sizeof onamebuf) {
2153 (void) strncpy(onamebuf, save_oname, sizeof onamebuf - 4);
2154 Strcpy(onamebuf + sizeof onamebuf - 4, "...");
2155 ONAME(obj) = onamebuf;
2156 releaseobuf(outbuf);
2157 outbuf = (*func)(obj);
2158 ONAME(obj) = save_oname; /* restore named string */
2159 if ((unsigned) strlen(outbuf) <= lenlimit)
2163 /* shorten both called and named strings;
2164 unamebuf and onamebuf have both already been populated */
2165 if (save_uname && strlen(save_uname) >= sizeof unamebuf && save_oname
2166 && strlen(save_oname) >= sizeof onamebuf) {
2167 objects[obj->otyp].oc_uname = unamebuf;
2168 ONAME(obj) = onamebuf;
2169 releaseobuf(outbuf);
2170 outbuf = (*func)(obj);
2171 if ((unsigned) strlen(outbuf) <= lenlimit) {
2172 objects[obj->otyp].oc_uname = save_uname;
2173 ONAME(obj) = save_oname;
2178 /* still long; strip several name-lengthening attributes;
2179 called and named strings are still in truncated form */
2181 obj->bknown = obj->rknown = obj->greased = 0;
2182 obj->oeroded = obj->oeroded2 = 0;
2183 releaseobuf(outbuf);
2184 outbuf = (*func)(obj);
2185 if (altfunc && (unsigned) strlen(outbuf) > lenlimit) {
2186 /* still long; use the alternate function (usually one of
2187 the jackets around minimal_xname()) */
2188 releaseobuf(outbuf);
2189 outbuf = (*altfunc)(obj);
2191 /* restore the object */
2194 ONAME(obj) = save_oname;
2196 objects[obj->otyp].oc_uname = save_uname;
2198 /* use whatever we've got, whether it's too long or not */
2203 * Used if only one of a collection of objects is named (e.g. in eat.c).
2206 singular(otmp, func)
2207 register struct obj *otmp;
2208 char *FDECL((*func), (OBJ_P));
2213 /* using xname for corpses does not give the monster type */
2214 if (otmp->otyp == CORPSE && func == xname)
2217 savequan = otmp->quan;
2219 nam = (*func)(otmp);
2220 otmp->quan = savequan;
2224 /* pick "", "a ", or "an " as article for 'str'; used by an() and doname() */
2226 just_an(outbuf, str)
2230 #if 0 /*JP*//*
\95s
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2236 /* single letter; might be used for named fruit */
2237 Strcpy(outbuf, index("aefhilmnosx", c0) ? "an " : "a ");
2238 } else if (!strncmpi(str, "the ", 4) || !strcmpi(str, "molten lava")
2239 || !strcmpi(str, "iron bars") || !strcmpi(str, "ice")) {
2242 if ((index(vowels, c0) && strncmpi(str, "one-", 4)
2243 && strncmpi(str, "eucalyptus", 10) && strncmpi(str, "unicorn", 7)
2244 && strncmpi(str, "uranium", 7) && strncmpi(str, "useful", 6))
2245 || (index("x", c0) && !index(vowels, lowc(str[1]))))
2246 Strcpy(outbuf, "an ");
2248 Strcpy(outbuf, "a ");
2260 char *buf = nextobuf();
2262 if (!str || !*str) {
2263 impossible("Alphabet soup: 'an(%s)'.", str ? "\"\"" : "<null>");
2264 return strcpy(buf, "an []");
2266 (void) just_an(buf, str);
2267 return strcat(buf, str);
2274 char *tmp = an(str);
2276 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2283 * Prepend "the" if necessary; assumes str is a subject derived from xname.
2284 * Use type_is_pname() for monster names, not the(). the() is idempotent.
2290 char *buf = nextobuf();
2291 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
2292 boolean insert_the = FALSE;
2294 if (!str || !*str) {
2295 impossible("Alphabet soup: 'the(%s)'.", str ? "\"\"" : "<null>");
2296 return strcpy(buf, "the []");
2298 if (!strncmpi(str, "the ", 4)) {
2299 buf[0] = lowc(*str);
2300 Strcpy(&buf[1], str + 1);
2302 } else if (*str < 'A' || *str > 'Z'
2303 /* treat named fruit as not a proper name, even if player
2304 has assigned a capitalized proper name as his/her fruit */
2305 || fruit_from_name(str, TRUE, (int *) 0)) {
2306 /* not a proper name, needs an article */
2309 /* Probably a proper name, might not need an article */
2310 register char *tmp, *named, *called;
2313 /* some objects have capitalized adjectives in their names */
2314 if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0)
2315 && (tmp[1] < 'A' || tmp[1] > 'Z')) {
2317 } else if (tmp && index(str, ' ') < tmp) { /* has spaces */
2318 /* it needs an article if the name contains "of" */
2319 tmp = strstri(str, " of ");
2320 named = strstri(str, " named ");
2321 called = strstri(str, " called ");
2322 if (called && (!named || called < named))
2325 if (tmp && (!named || tmp < named)) /* found an "of" */
2327 /* stupid special case: lacks "of" but needs "the" */
2328 else if (!named && (l = strlen(str)) >= 31
2329 && !strcmp(&str[l - 31],
2330 "Platinum Yendorian Express Card"))
2335 Strcpy(buf, "the ");
2340 #else /*
\92P
\82É
\83R
\83s
\81[*/
2350 char *tmp = the(str);
2352 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2361 register struct obj *otmp;
2362 register const char *verb;
2368 /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */
2374 char prefix[PREFIX];
2375 char *bp = cxname(otmp);
2377 if (otmp->quan != 1L) {
2378 Sprintf(prefix, "%ld ", otmp->quan);
2379 bp = strprepend(bp, prefix);
2383 Strcat(bp, otense(otmp, verb));
2389 /* combine yname and aobjnam eg "your count cxname(otmp)" */
2395 char *s = aobjnam(obj, verb);
2397 /* leave off "your" for most of your artifacts, but prepend
2398 * "your" for unique objects and "foo of bar" quest artifacts */
2399 if (!carried(obj) || !obj_is_pname(obj)
2400 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2401 char *outbuf = shk_your(nextobuf(), obj);
2402 int space_left = BUFSZ - 1 - strlen(outbuf);
2404 s = strncat(outbuf, s, space_left);
2409 /* combine Yname2 and aobjnam eg "Your count cxname(otmp)" */
2415 register char *s = yobjnam(obj, verb);
2423 /* like aobjnam, but prepend "The", not count, and use xname */
2429 char *bp = The(xname(otmp));
2431 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2434 Strcat(bp, otense(otmp, verb));
2440 /* capitalized variant of doname() */
2445 char *s = doname(obj);
2451 #if 0 /* stalled-out work in progress */
2452 /* Doname2() for itemized buying of 'obj' from a shop */
2457 static const char and_contents[] = " and its contents";
2458 char *p = doname(obj);
2460 if (Is_container(obj) && !obj->cknown) {
2462 if ((int) strlen(p) + sizeof and_contents - 1 < BUFSZ - PREFIX)
2463 Strcat(p, and_contents);
2466 p = strprepend(p, "Contents of ");
2475 /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */
2480 char *s = cxname(obj);
2482 /* leave off "your" for most of your artifacts, but prepend
2483 * "your" for unique objects and "foo of bar" quest artifacts */
2484 if (!carried(obj) || !obj_is_pname(obj)
2485 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2486 char *outbuf = shk_your(nextobuf(), obj);
2487 int space_left = BUFSZ - 1 - strlen(outbuf);
2489 s = strncat(outbuf, s, space_left);
2495 /* capitalized variant of yname() */
2500 char *s = yname(obj);
2508 /* returns "your minimal_xname(obj)"
2509 * or "Foobar's minimal_xname(obj)"
2510 * or "the minimal_xname(obj)"
2516 char *outbuf = nextobuf();
2517 char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */
2519 int space_left = BUFSZ - 1 - strlen(s);
2521 return strncat(s, minimal_xname(obj), space_left);
2523 int space_left = BUFSZ - strlen(s);
2525 return strncat(s, minimal_xname(obj), space_left);
2529 /* capitalized variant of ysimple_name() */
2534 char *s = ysimple_name(obj);
2542 /* "scroll" or "scrolls" */
2547 char *simpleoname = minimal_xname(obj);
2549 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2550 if (obj->quan != 1L)
2551 simpleoname = makeplural(simpleoname);
2556 /* "a scroll" or "scrolls"; "a silver bell" or "the Bell of Opening" */
2561 char *simpleoname = simpleonames(obj);
2562 int otyp = obj->otyp;
2564 /* prefix with "the" if a unique item, or a fake one imitating same,
2565 has been formatted with its actual name (we let typename() handle
2566 any `known' and `dknown' checking necessary) */
2567 if (otyp == FAKE_AMULET_OF_YENDOR)
2568 otyp = AMULET_OF_YENDOR;
2569 if (objects[otyp].oc_unique
2570 && !strcmp(simpleoname, OBJ_NAME(objects[otyp])))
2571 return the(simpleoname);
2573 /* simpleoname is singular if quan==1, plural otherwise */
2574 if (obj->quan == 1L)
2575 simpleoname = an(simpleoname);
2579 /* "the scroll" or "the scrolls" */
2584 char *simpleoname = simpleonames(obj);
2586 return the(simpleoname);
2589 /* artifact's name without any object type or known/dknown/&c feedback */
2591 bare_artifactname(obj)
2596 if (obj->oartifact) {
2597 outbuf = nextobuf();
2598 Strcpy(outbuf, artiname(obj->oartifact));
2600 if (!strncmp(outbuf, "The ", 4))
2601 outbuf[0] = lowc(outbuf[0]);
2604 outbuf = xname(obj);
2610 static const char *wrp[] = {
2611 "wand", "ring", "potion", "scroll", "gem",
2612 "amulet", "spellbook", "spell book",
2613 /* for non-specific wishes */
2614 "weapon", "armor", "tool", "food", "comestible",
2617 static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
2618 SCROLL_CLASS, GEM_CLASS, AMULET_CLASS,
2619 SPBOOK_CLASS, SPBOOK_CLASS, WEAPON_CLASS,
2620 ARMOR_CLASS, TOOL_CLASS, FOOD_CLASS,
2623 /* return form of the verb (input plural) if xname(otmp) were the subject */
2632 * verb is given in plural (without trailing s). Return as input
2633 * if the result of xname(otmp) would be plural. Don't bother
2634 * recomputing xname(otmp) at this time.
2636 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2637 if (!is_plural(otmp))
2638 return vtense((char *) 0, verb);
2646 /* various singular words that vtense would otherwise categorize as plural;
2647 also used by makesingular() to catch some special cases */
2648 static const char *const special_subjs[] = {
2649 "erinys", "manes", /* this one is ambiguous */
2650 "Cyclops", "Hippocrates", "Pelias", "aklys",
2651 "amnesia", "detect monsters", "paralysis", "shape changers",
2653 /* note: "detect monsters" and "shape changers" are normally
2654 caught via "<something>(s) of <whatever>", but they can be
2655 wished for using the shorter form, so we include them here
2656 to accommodate usage by makesingular during wishing */
2659 /* return form of the verb (input plural) for present tense 3rd person subj */
2662 register const char *subj;
2663 register const char *verb;
2665 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2666 char *buf = nextobuf(), *bspot;
2668 const char *sp, *spot;
2669 const char *const *spec;
2672 * verb is given in plural (without trailing s). Return as input
2673 * if subj appears to be plural. Add special cases as necessary.
2674 * Many hard cases can already be handled by using otense() instead.
2675 * If this gets much bigger, consider decomposing makeplural.
2676 * Note: monster names are not expected here (except before corpse).
2678 * Special case: allow null sobj to get the singular 3rd person
2679 * present tense form so we don't duplicate this code elsewhere.
2682 if (!strncmpi(subj, "a ", 2) || !strncmpi(subj, "an ", 3))
2684 spot = (const char *) 0;
2685 for (sp = subj; (sp = index(sp, ' ')) != 0; ++sp) {
2686 if (!strncmpi(sp, " of ", 4) || !strncmpi(sp, " from ", 6)
2687 || !strncmpi(sp, " called ", 8) || !strncmpi(sp, " named ", 7)
2688 || !strncmpi(sp, " labeled ", 9)) {
2694 len = (int) strlen(subj);
2696 spot = subj + len - 1;
2699 * plural: anything that ends in 's', but not '*us' or '*ss'.
2700 * Guess at a few other special cases that makeplural creates.
2702 if ((lowc(*spot) == 's' && spot != subj
2703 && !index("us", lowc(*(spot - 1))))
2704 || !BSTRNCMPI(subj, spot - 3, "eeth", 4)
2705 || !BSTRNCMPI(subj, spot - 3, "feet", 4)
2706 || !BSTRNCMPI(subj, spot - 1, "ia", 2)
2707 || !BSTRNCMPI(subj, spot - 1, "ae", 2)) {
2708 /* check for special cases to avoid false matches */
2709 len = (int) (spot - subj) + 1;
2710 for (spec = special_subjs; *spec; spec++) {
2711 ltmp = strlen(*spec);
2712 if (len == ltmp && !strncmpi(*spec, subj, len))
2714 /* also check for <prefix><space><special_subj>
2715 to catch things like "the invisible erinys" */
2716 if (len > ltmp && *(spot - ltmp) == ' '
2717 && !strncmpi(*spec, spot - ltmp + 1, ltmp))
2721 return strcpy(buf, verb);
2724 * 3rd person plural doesn't end in telltale 's';
2725 * 2nd person singular behaves as if plural.
2727 if (!strcmpi(subj, "they") || !strcmpi(subj, "you"))
2728 return strcpy(buf, verb);
2733 len = (int) strlen(buf);
2734 bspot = buf + len - 1;
2736 if (!strcmpi(buf, "are")) {
2737 Strcasecpy(buf, "is");
2738 } else if (!strcmpi(buf, "have")) {
2739 Strcasecpy(bspot - 1, "s");
2740 } else if (index("zxs", lowc(*bspot))
2741 || (len >= 2 && lowc(*bspot) == 'h'
2742 && index("cs", lowc(*(bspot - 1))))
2743 || (len == 2 && lowc(*bspot) == 'o')) {
2744 /* Ends in z, x, s, ch, sh; add an "es" */
2745 Strcasecpy(bspot + 1, "es");
2746 } else if (lowc(*bspot) == 'y' && !index(vowels, lowc(*(bspot - 1)))) {
2747 /* like "y" case in makeplural */
2748 Strcasecpy(bspot, "ies");
2750 Strcasecpy(bspot + 1, "s");
2753 #else /*
\90V
\82µ
\82¢
\83o
\83b
\83t
\83@
\82Í
\95K
\97v*/
2764 const char *sing, *plur;
2767 /* word pairs that don't fit into formula-based transformations;
2768 also some suffices which have very few--often one--matches or
2769 which aren't systematically reversible (knives, staves) */
2770 static struct sing_plur one_off[] = {
2772 "children" }, /* (for wise guys who give their food funny names) */
2773 { "cubus", "cubi" }, /* in-/suc-cubus */
2774 { "culus", "culi" }, /* homunculus */
2775 { "djinni", "djinn" },
2776 { "erinys", "erinyes" },
2778 { "fungus", "fungi" },
2779 { "goose", "geese" },
2780 { "knife", "knives" },
2781 { "labrum", "labra" }, /* candelabrum */
2782 { "louse", "lice" },
2783 { "mouse", "mice" },
2784 { "mumak", "mumakil" },
2785 { "nemesis", "nemeses" },
2788 { "passerby", "passersby" },
2789 { "rtex", "rtices" }, /* vortex */
2790 { "serum", "sera" },
2791 { "staff", "staves" },
2792 { "tooth", "teeth" },
2796 static const char *const as_is[] = {
2797 /* makesingular() leaves these plural due to how they're used */
2798 "boots", "shoes", "gloves", "lenses", "scales",
2799 "eyes", "gauntlets", "iron bars",
2800 /* both singular and plural are spelled the same */
2801 "bison", "deer", "elk", "fish", "fowl",
2802 "tuna", "yaki", "-hai", "krill", "manes",
2803 "moose", "ninja", "sheep", "ronin", "roshi",
2804 "shito", "tengu", "ki-rin", "Nazgul", "gunyoki",
2805 "piranha", "samurai", "shuriken", 0,
2806 /* Note: "fish" and "piranha" are collective plurals, suitable
2807 for "wiped out all <foo>". For "3 <foo>", they should be
2808 "fishes" and "piranhas" instead. We settle for collective
2809 variant instead of attempting to support both. */
2812 /* singularize/pluralize decisions common to both makesingular & makeplural */
2814 singplur_lookup(basestr, endstring, to_plural, alt_as_is)
2815 char *basestr, *endstring; /* base string, pointer to eos(string) */
2816 boolean to_plural; /* true => makeplural, false => makesingular */
2817 const char *const *alt_as_is; /* another set like as_is[] */
2819 const struct sing_plur *sp;
2820 const char *same, *other, *const *as;
2822 int baselen = strlen(basestr);
2824 for (as = as_is; *as; ++as) {
2825 al = (int) strlen(*as);
2826 if (!BSTRCMPI(basestr, endstring - al, *as))
2830 for (as = alt_as_is; *as; ++as) {
2831 al = (int) strlen(*as);
2832 if (!BSTRCMPI(basestr, endstring - al, *as))
2837 /* Leave "craft" as a suffix as-is (aircraft, hovercraft);
2838 "craft" itself is (arguably) not included in our likely context */
2839 if ((baselen > 5) && (!BSTRCMPI(basestr, endstring - 5, "craft")))
2841 /* avoid false hit on one_off[].plur == "lice" or .sing == "goose";
2842 if more of these turn up, one_off[] entries will need to flagged
2843 as to which are whole words and which are matchable as suffices
2844 then matching in the loop below will end up becoming more complex */
2845 if (!strcmpi(basestr, "slice")
2846 || !strcmpi(basestr, "mongoose")) {
2848 Strcasecpy(endstring, "s");
2851 /* skip "ox" -> "oxen" entry when pluralizing "<something>ox"
2852 unless it is muskox */
2853 if (to_plural && baselen > 2 && !strcmpi(endstring - 2, "ox")
2854 && !(baselen > 5 && !strcmpi(endstring - 6, "muskox"))) {
2855 /* "fox" -> "foxes" */
2856 Strcasecpy(endstring, "es");
2860 if (baselen > 2 && !strcmpi(endstring - 3, "man")
2861 && badman(basestr, to_plural)) {
2862 Strcasecpy(endstring, "s");
2866 if (baselen > 2 && !strcmpi(endstring - 3, "men")
2867 && badman(basestr, to_plural))
2870 for (sp = one_off; sp->sing; sp++) {
2871 /* check whether endstring already matches */
2872 same = to_plural ? sp->plur : sp->sing;
2873 al = (int) strlen(same);
2874 if (!BSTRCMPI(basestr, endstring - al, same))
2875 return TRUE; /* use as-is */
2876 /* check whether it matches the inverse; if so, transform it */
2877 other = to_plural ? sp->sing : sp->plur;
2878 al = (int) strlen(other);
2879 if (!BSTRCMPI(basestr, endstring - al, other)) {
2880 Strcasecpy(endstring - al, same);
2881 return TRUE; /* one_off[] transformation */
2887 /* searches for common compounds, ex. lump of royal jelly */
2889 singplur_compound(str)
2892 /* if new entries are added, be sure to keep compound_start[] in sync */
2893 static const char *const compounds[] =
2895 " of ", " labeled ", " called ",
2896 " named ", " above", /* lurkers above */
2897 " versus ", " from ", " in ",
2898 " on ", " a la ", " with", /* " with "? */
2899 " de ", " d'", " du ",
2901 }, /* list of first characters for all compounds[] entries */
2902 compound_start[] = " -";
2904 const char *const *cmpd;
2907 for (p = str; *p; ++p) {
2908 /* substring starting at p can only match if *p is found
2909 within compound_start[] */
2910 if (!index(compound_start, *p))
2913 /* check current substring against all words in the compound[] list */
2914 for (cmpd = compounds; *cmpd; ++cmpd)
2915 if (!strncmpi(p, *cmpd, (int) strlen(*cmpd)))
2918 /* wasn't recognized as a compound phrase */
2923 /* Plural routine; once upon a time it may have been chiefly used for
2924 * user-defined fruits, but it is now used extensively throughout the
2927 * For fruit, we have to try to account for everything reasonable the
2928 * player has; something unreasonable can still break the code.
2929 * However, it's still a lot more accurate than "just add an 's' at the
2930 * end", which Rogue uses...
2932 * Also used for plural monster names ("Wiped out all homunculi." or the
2933 * vanquished monsters list) and body parts. A lot of unique monsters have
2934 * names which get mangled by makeplural and/or makesingular. They're not
2935 * genocidable, and vanquished-mon handling does its own special casing
2936 * (for uniques who've been revived and re-killed), so we don't bother
2937 * trying to get those right here.
2939 * Also misused by muse.c to convert 1st person present verbs to 2nd person.
2940 * 3.6.0: made case-insensitive.
2946 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2947 register char *spot;
2948 char lo_c, *str = nextobuf();
2949 const char *excess = (char *) 0;
2953 while (*oldstr == ' ')
2955 if (!oldstr || !*oldstr) {
2956 impossible("plural of null?");
2960 Strcpy(str, oldstr);
2963 * Skip changing "pair of" to "pairs of". According to Webster, usual
2964 * English usage is use pairs for humans, e.g. 3 pairs of dancers,
2965 * and pair for objects and non-humans, e.g. 3 pair of boots. We don't
2966 * refer to pairs of humans in this game so just skip to the bottom.
2968 if (!strncmpi(str, "pair of ", 8))
2971 /* look for "foo of bar" so that we can focus on "foo" */
2972 if ((spot = singplur_compound(str)) != 0) {
2973 excess = oldstr + (int) (spot - str);
2979 while (spot > str && *spot == ' ')
2980 spot--; /* Strip blanks from end */
2982 /* Now spot is the last character of the string */
2986 /* Single letters */
2987 if (len == 1 || !letter(*spot)) {
2988 Strcpy(spot + 1, "'s");
2992 /* dispense with some words which don't need pluralization */
2994 static const char *const already_plural[] = {
2995 "ae", /* algae, larvae, &c */
2999 /* spot+1: synch up with makesingular's usage */
3000 if (singplur_lookup(str, spot + 1, TRUE, already_plural))
3003 /* more of same, but not suitable for blanket loop checking */
3004 if ((len == 2 && !strcmpi(str, "ya"))
3005 || (len >= 3 && !strcmpi(spot - 2, " ya")))
3009 /* man/men ("Wiped out all cavemen.") */
3010 if (len >= 3 && !strcmpi(spot - 2, "man")
3011 /* exclude shamans and humans etc */
3012 && !badman(str, TRUE)) {
3013 Strcasecpy(spot - 1, "en");
3016 if (lowc(*spot) == 'f') { /* (staff handled via one_off[]) */
3017 lo_c = lowc(*(spot - 1));
3018 if (len >= 3 && !strcmpi(spot - 2, "erf")) {
3019 /* avoid "nerf" -> "nerves", "serf" -> "serves" */
3020 ; /* fall through to default (append 's') */
3021 } else if (index("lr", lo_c) || index(vowels, lo_c)) {
3022 /* [aeioulr]f to [aeioulr]ves */
3023 Strcasecpy(spot, "ves");
3027 /* ium/ia (mycelia, baluchitheria) */
3028 if (len >= 3 && !strcmpi(spot - 2, "ium")) {
3029 Strcasecpy(spot - 2, "ia");
3032 /* algae, larvae, hyphae (another fungus part) */
3033 if ((len >= 4 && !strcmpi(spot - 3, "alga"))
3035 && (!strcmpi(spot - 4, "hypha") || !strcmpi(spot - 4, "larva")))
3036 || (len >= 6 && !strcmpi(spot - 5, "amoeba"))
3037 || (len >= 8 && (!strcmpi(spot - 7, "vertebra")))) {
3039 Strcasecpy(spot + 1, "e");
3042 /* fungus/fungi, homunculus/homunculi, but buses, lotuses, wumpuses */
3043 if (len > 3 && !strcmpi(spot - 1, "us")
3044 && !((len >= 5 && !strcmpi(spot - 4, "lotus"))
3045 || (len >= 6 && !strcmpi(spot - 5, "wumpus")))) {
3046 Strcasecpy(spot - 1, "i");
3049 /* sis/ses (nemesis) */
3050 if (len >= 3 && !strcmpi(spot - 2, "sis")) {
3051 Strcasecpy(spot - 1, "es");
3054 /* matzoh/matzot, possible food name */
3056 && (!strcmpi(spot - 5, "matzoh") || !strcmpi(spot - 5, "matzah"))) {
3057 Strcasecpy(spot - 1, "ot"); /* oh/ah -> ot */
3061 && (!strcmpi(spot - 4, "matzo") || !strcmpi(spot - 4, "matza"))) {
3062 Strcasecpy(spot, "ot"); /* o/a -> ot */
3066 /* note: -eau/-eaux (gateau, bordeau...) */
3067 /* note: ox/oxen, VAX/VAXen, goose/geese */
3071 /* codex/spadix/neocortex and the like */
3073 && (!strcmpi(spot - 2, "dex")
3074 ||!strcmpi(spot - 2, "dix")
3075 ||!strcmpi(spot - 2, "tex"))
3076 /* indices would have been ok too, but stick with indexes */
3077 && (strcmpi(spot - 4,"index") != 0)) {
3078 Strcasecpy(spot - 1, "ices"); /* ex|ix -> ices */
3081 /* Ends in z, x, s, ch, sh; add an "es" */
3082 if (index("zxs", lo_c)
3083 || (len >= 2 && lo_c == 'h' && index("cs", lowc(*(spot - 1)))
3084 /* 21st century k-sound */
3086 ((lowc(*(spot - 2)) == 'e'
3087 && index("mt", lowc(*(spot - 3)))) ||
3088 (lowc(*(spot - 2)) == 'o'
3089 && index("lp", lowc(*(spot - 3)))))))
3090 /* Kludge to get "tomatoes" and "potatoes" right */
3091 || (len >= 4 && !strcmpi(spot - 2, "ato"))
3092 || (len >= 5 && !strcmpi(spot - 4, "dingo"))) {
3093 Strcasecpy(spot + 1, "es"); /* append es */
3096 /* Ends in y preceded by consonant (note: also "qu") change to "ies" */
3097 if (lo_c == 'y' && !index(vowels, lowc(*(spot - 1)))) {
3098 Strcasecpy(spot, "ies"); /* y -> ies */
3101 /* Default: append an 's' */
3102 Strcasecpy(spot + 1, "s");
3106 Strcat(str, excess);
3107 #else /*JP*//*
\90V
\82µ
\82¢
\83o
\83b
\83t
\83@
\82Í
\95K
\97v*/
3108 char *str = nextobuf();
3109 Strcpy(str, oldstr);
3115 * Singularize a string the user typed in; this helps reduce the complexity
3116 * of readobjnam, and is also used in pager.c to singularize the string
3117 * for which help is sought.
3119 * "Manes" is ambiguous: monster type (keep s), or horse body part (drop s)?
3120 * Its inclusion in as_is[]/special_subj[] makes it get treated as the former.
3122 * A lot of unique monsters have names ending in s; plural, or singular
3123 * from plural, doesn't make much sense for them so we don't bother trying.
3124 * 3.6.0: made case-insensitive.
3127 makesingular(oldstr)
3130 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
3131 register char *p, *bp;
3132 const char *excess = 0;
3133 char *str = nextobuf();
3136 while (*oldstr == ' ')
3138 if (!oldstr || !*oldstr) {
3139 impossible("singular of null?");
3144 bp = strcpy(str, oldstr);
3146 /* check for "foo of bar" so that we can focus on "foo" */
3147 if ((p = singplur_compound(bp)) != 0) {
3148 excess = oldstr + (int) (p - bp);
3153 /* dispense with some words which don't need singularization */
3154 if (singplur_lookup(bp, p, FALSE, special_subjs))
3157 /* remove -s or -es (boxes) or -ies (rubies) */
3158 if (p >= bp + 1 && lowc(p[-1]) == 's') {
3159 if (p >= bp + 2 && lowc(p[-2]) == 'e') {
3160 if (p >= bp + 3 && lowc(p[-3]) == 'i') { /* "ies" */
3161 if (!BSTRCMPI(bp, p - 7, "cookies")
3162 || (!BSTRCMPI(bp, p - 4, "pies")
3163 /* avoid false match for "harpies" */
3164 && (p - 4 == bp || p[-5] == ' '))
3165 /* alternate djinni/djinn spelling; not really needed */
3166 || (!BSTRCMPI(bp, p - 6, "genies")
3167 /* avoid false match for "progenies" */
3168 && (p - 6 == bp || p[-7] == ' '))
3169 || !BSTRCMPI(bp, p - 5, "mbies") /* zombie */
3170 || !BSTRCMPI(bp, p - 5, "yries")) /* valkyrie */
3172 Strcasecpy(p - 3, "y"); /* ies -> y */
3175 /* wolves, but f to ves isn't fully reversible */
3176 if (p - 4 >= bp && (index("lr", lowc(*(p - 4)))
3177 || index(vowels, lowc(*(p - 4))))
3178 && !BSTRCMPI(bp, p - 3, "ves")) {
3179 if (!BSTRCMPI(bp, p - 6, "cloves")
3180 || !BSTRCMPI(bp, p - 6, "nerves"))
3182 Strcasecpy(p - 3, "f"); /* ves -> f */
3185 /* note: nurses, axes but boxes, wumpuses */
3186 if (!BSTRCMPI(bp, p - 4, "eses")
3187 || !BSTRCMPI(bp, p - 4, "oxes") /* boxes, foxes */
3188 || !BSTRCMPI(bp, p - 4, "nxes") /* lynxes */
3189 || !BSTRCMPI(bp, p - 4, "ches")
3190 || !BSTRCMPI(bp, p - 4, "uses") /* lotuses */
3191 || !BSTRCMPI(bp, p - 4, "sses") /* priestesses */
3192 || !BSTRCMPI(bp, p - 5, "atoes") /* tomatoes */
3193 || !BSTRCMPI(bp, p - 7, "dingoes")
3194 || !BSTRCMPI(bp, p - 7, "Aleaxes")) {
3195 *(p - 2) = '\0'; /* drop es */
3197 } /* else fall through to mins */
3199 /* ends in 's' but not 'es' */
3200 } else if (!BSTRCMPI(bp, p - 2, "us")) { /* lotus, fungus... */
3201 if (BSTRCMPI(bp, p - 6, "tengus") /* but not these... */
3202 && BSTRCMPI(bp, p - 7, "hezrous"))
3204 } else if (!BSTRCMPI(bp, p - 2, "ss")
3205 || !BSTRCMPI(bp, p - 5, " lens")
3206 || (p - 4 == bp && !strcmpi(p - 4, "lens"))) {
3210 *(p - 1) = '\0'; /* drop s */
3212 } else { /* input doesn't end in 's' */
3214 if (!BSTRCMPI(bp, p - 3, "men")
3215 && !badman(bp, FALSE)) {
3216 Strcasecpy(p - 2, "an");
3219 /* matzot -> matzo, algae -> alga */
3220 if (!BSTRCMPI(bp, p - 6, "matzot") || !BSTRCMPI(bp, p - 2, "ae")) {
3221 *(p - 1) = '\0'; /* drop t/e */
3224 /* balactheria -> balactherium */
3225 if (p - 4 >= bp && !strcmpi(p - 2, "ia")
3226 && index("lr", lowc(*(p - 3))) && lowc(*(p - 4)) == 'e') {
3227 Strcasecpy(p - 1, "um"); /* a -> um */
3230 /* here we cannot find the plural suffix */
3234 /* if we stripped off a suffix (" of bar" from "foo of bar"),
3235 put it back now [strcat() isn't actually 100% safe here...] */
3240 #else /*JP*//*
\90V
\82µ
\82¢
\83o
\83b
\83t
\83@
\82Í
\95K
\97v*/
3241 char *str = nextobuf();
3242 Strcpy(str, oldstr);
3249 badman(basestr, to_plural)
3250 const char *basestr;
3251 boolean to_plural; /* true => makeplural, false => makesingular */
3253 /* these are all the prefixes for *man that don't have a *men plural */
3254 static const char *no_men[] = {
3255 "albu", "antihu", "anti", "ata", "auto", "bildungsro", "cai", "cay",
3256 "ceru", "corner", "decu", "des", "dura", "fir", "hanu", "het",
3257 "infrahu", "inhu", "nonhu", "otto", "out", "prehu", "protohu",
3258 "subhu", "superhu", "talis", "unhu", "sha",
3259 "hu", "un", "le", "re", "so", "to", "at", "a",
3261 /* these are all the prefixes for *men that don't have a *man singular */
3262 static const char *no_man[] = {
3263 "abdo", "acu", "agno", "ceru", "cogno", "cycla", "fleh", "grava",
3264 "hegu", "preno", "sonar", "speci", "dai", "exa", "fla", "sta", "teg",
3265 "tegu", "vela", "da", "hy", "lu", "no", "nu", "ra", "ru", "se", "vi",
3269 const char *endstr, *spot;
3271 if (!basestr || strlen(basestr) < 4)
3274 endstr = eos((char *) basestr);
3277 for (i = 0; i < SIZE(no_men); i++) {
3278 al = (int) strlen(no_men[i]);
3279 spot = endstr - (al + 3);
3280 if (!BSTRNCMPI(basestr, spot, no_men[i], al)
3281 && (spot == basestr || *(spot - 1) == ' '))
3285 for (i = 0; i < SIZE(no_man); i++) {
3286 al = (int) strlen(no_man[i]);
3287 spot = endstr - (al + 3);
3288 if (!BSTRNCMPI(basestr, spot, no_man[i], al)
3289 && (spot == basestr || *(spot - 1) == ' '))
3297 /* compare user string against object name string using fuzzy matching */
3299 wishymatch(u_str, o_str, retry_inverted)
3300 const char *u_str; /* from user, so might be variant spelling */
3301 const char *o_str; /* from objects[], so is in canonical form */
3302 boolean retry_inverted; /* optional extra "of" handling */
3304 static NEARDATA const char detect_SP[] = "detect ",
3305 SP_detection[] = " detection";
3306 char *p, buf[BUFSZ];
3308 /* ignore spaces & hyphens and upper/lower case when comparing */
3309 if (fuzzymatch(u_str, o_str, " -", TRUE))
3312 if (retry_inverted) {
3313 const char *u_of, *o_of;
3315 /* when just one of the strings is in the form "foo of bar",
3316 convert it into "bar foo" and perform another comparison */
3317 u_of = strstri(u_str, " of ");
3318 o_of = strstri(o_str, " of ");
3319 if (u_of && !o_of) {
3320 Strcpy(buf, u_of + 4);
3321 p = eos(strcat(buf, " "));
3322 while (u_str < u_of)
3325 return fuzzymatch(buf, o_str, " -", TRUE);
3326 } else if (o_of && !u_of) {
3327 Strcpy(buf, o_of + 4);
3328 p = eos(strcat(buf, " "));
3329 while (o_str < o_of)
3332 return fuzzymatch(u_str, buf, " -", TRUE);
3336 /* [note: if something like "elven speed boots" ever gets added, these
3337 special cases should be changed to call wishymatch() recursively in
3338 order to get the "of" inversion handling] */
3339 if (!strncmp(o_str, "dwarvish ", 9)) {
3340 if (!strncmpi(u_str, "dwarven ", 8))
3341 return fuzzymatch(u_str + 8, o_str + 9, " -", TRUE);
3342 } else if (!strncmp(o_str, "elven ", 6)) {
3343 if (!strncmpi(u_str, "elvish ", 7))
3344 return fuzzymatch(u_str + 7, o_str + 6, " -", TRUE);
3345 else if (!strncmpi(u_str, "elfin ", 6))
3346 return fuzzymatch(u_str + 6, o_str + 6, " -", TRUE);
3347 } else if (!strncmp(o_str, detect_SP, sizeof detect_SP - 1)) {
3348 /* check for "detect <foo>" vs "<foo> detection" */
3349 if ((p = strstri(u_str, SP_detection)) != 0
3350 && !*(p + sizeof SP_detection - 1)) {
3351 /* convert "<foo> detection" into "detect <foo>" */
3353 Strcat(strcpy(buf, detect_SP), u_str);
3354 /* "detect monster" -> "detect monsters" */
3355 if (!strcmpi(u_str, "monster"))
3358 return fuzzymatch(buf, o_str, " -", TRUE);
3360 } else if (strstri(o_str, SP_detection)) {
3361 /* and the inverse, "<foo> detection" vs "detect <foo>" */
3362 if (!strncmpi(u_str, detect_SP, sizeof detect_SP - 1)) {
3363 /* convert "detect <foo>s" into "<foo> detection" */
3364 p = makesingular(u_str + sizeof detect_SP - 1);
3365 Strcat(strcpy(buf, p), SP_detection);
3366 /* caller may be looping through objects[], so avoid
3367 churning through all the obufs */
3369 return fuzzymatch(buf, o_str, " -", TRUE);
3371 } else if (strstri(o_str, "ability")) {
3372 /* when presented with "foo of bar", makesingular() used to
3373 singularize both foo & bar, but now only does so for foo */
3374 /* catch "{potion(s),ring} of {gain,restore,sustain} abilities" */
3375 if ((p = strstri(u_str, "abilities")) != 0
3376 && !*(p + sizeof "abilities" - 1)) {
3377 (void) strncpy(buf, u_str, (unsigned) (p - u_str));
3378 Strcpy(buf + (p - u_str), "ability");
3379 return fuzzymatch(buf, o_str, " -", TRUE);
3381 } else if (!strcmp(o_str, "aluminum")) {
3382 /* this special case doesn't really fit anywhere else... */
3383 /* (note that " wand" will have been stripped off by now) */
3384 if (!strcmpi(u_str, "aluminium"))
3385 return fuzzymatch(u_str + 9, o_str + 8, " -", TRUE);
3392 const char *name, oclass;
3393 int f_o_range, l_o_range;
3396 #if 0 /*JP*//*
\95\94\95ª
\93I
\82È
\83W
\83\83\83\93\83\8b\8ew
\92è
\82Å
\82Ì
\8aè
\82¢
\97p
\81B
\93ú
\96{
\8cê
\82Å
\82Í
\82Æ
\82è
\82 \82¦
\82¸
\82µ
\82È
\82¢*/
3397 /* wishable subranges of objects */
3398 STATIC_OVL NEARDATA const struct o_range o_ranges[] = {
3399 { "bag", TOOL_CLASS, SACK, BAG_OF_TRICKS },
3400 { "lamp", TOOL_CLASS, OIL_LAMP, MAGIC_LAMP },
3401 { "candle", TOOL_CLASS, TALLOW_CANDLE, WAX_CANDLE },
3402 { "horn", TOOL_CLASS, TOOLED_HORN, HORN_OF_PLENTY },
3403 { "shield", ARMOR_CLASS, SMALL_SHIELD, SHIELD_OF_REFLECTION },
3404 { "hat", ARMOR_CLASS, FEDORA, DUNCE_CAP },
3405 { "helm", ARMOR_CLASS, ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY },
3406 { "gloves", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
3407 { "gauntlets", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
3408 { "boots", ARMOR_CLASS, LOW_BOOTS, LEVITATION_BOOTS },
3409 { "shoes", ARMOR_CLASS, LOW_BOOTS, IRON_SHOES },
3410 { "cloak", ARMOR_CLASS, MUMMY_WRAPPING, CLOAK_OF_DISPLACEMENT },
3411 { "shirt", ARMOR_CLASS, HAWAIIAN_SHIRT, T_SHIRT },
3412 { "dragon scales", ARMOR_CLASS, GRAY_DRAGON_SCALES,
3413 YELLOW_DRAGON_SCALES },
3414 { "dragon scale mail", ARMOR_CLASS, GRAY_DRAGON_SCALE_MAIL,
3415 YELLOW_DRAGON_SCALE_MAIL },
3416 { "sword", WEAPON_CLASS, SHORT_SWORD, KATANA },
3417 { "venom", VENOM_CLASS, BLINDING_VENOM, ACID_VENOM },
3418 { "gray stone", GEM_CLASS, LUCKSTONE, FLINT },
3419 { "grey stone", GEM_CLASS, LUCKSTONE, FLINT },
3424 #if 0 /*JP*//*not used*/
3425 /* alternate spellings; if the difference is only the presence or
3426 absence of spaces and/or hyphens (such as "pickaxe" vs "pick axe"
3427 vs "pick-axe") then there is no need for inclusion in this list;
3428 likewise for ``"of" inversions'' ("boots of speed" vs "speed boots") */
3429 static const struct alt_spellings {
3433 { "pickax", PICK_AXE },
3434 { "whip", BULLWHIP },
3435 { "saber", SILVER_SABER },
3436 { "silver sabre", SILVER_SABER },
3437 { "smooth shield", SHIELD_OF_REFLECTION },
3438 { "grey dragon scale mail", GRAY_DRAGON_SCALE_MAIL },
3439 { "grey dragon scales", GRAY_DRAGON_SCALES },
3440 { "iron ball", HEAVY_IRON_BALL },
3441 { "lantern", BRASS_LANTERN },
3442 { "mattock", DWARVISH_MATTOCK },
3443 { "amulet of poison resistance", AMULET_VERSUS_POISON },
3444 { "potion of sleep", POT_SLEEPING },
3446 { "camera", EXPENSIVE_CAMERA },
3447 { "tee shirt", T_SHIRT },
3449 { "can opener", TIN_OPENER },
3450 { "kelp", KELP_FROND },
3451 { "eucalyptus", EUCALYPTUS_LEAF },
3452 { "royal jelly", LUMP_OF_ROYAL_JELLY },
3453 { "lembas", LEMBAS_WAFER },
3454 { "cookie", FORTUNE_COOKIE },
3455 { "pie", CREAM_PIE },
3456 { "marker", MAGIC_MARKER },
3457 { "hook", GRAPPLING_HOOK },
3458 { "grappling iron", GRAPPLING_HOOK },
3459 { "grapnel", GRAPPLING_HOOK },
3460 { "grapple", GRAPPLING_HOOK },
3461 { "protection from shape shifters", RIN_PROTECTION_FROM_SHAPE_CHAN },
3462 /* if we ever add other sizes, move this to o_ranges[] with "bag" */
3463 { "box", LARGE_BOX },
3464 /* normally we wouldn't have to worry about unnecessary <space>, but
3465 " stone" will get stripped off, preventing a wishymatch; that actually
3466 lets "flint stone" be a match, so we also accept bogus "flintstone" */
3467 { "luck stone", LUCKSTONE },
3468 { "load stone", LOADSTONE },
3469 { "touch stone", TOUCHSTONE },
3470 { "flintstone", FLINT },
3471 { (const char *) 0, 0 },
3476 rnd_otyp_by_wpnskill(skill)
3480 short otyp = STRANGE_OBJECT;
3482 for (i = bases[WEAPON_CLASS];
3483 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3484 if (objects[i].oc_skill == skill) {
3490 for (i = bases[WEAPON_CLASS];
3491 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3492 if (objects[i].oc_skill == skill)
3500 rnd_otyp_by_namedesc(name, oclass, xtra_prob)
3503 int xtra_prob; /* to force 0% random generation items to also be considered */
3506 short validobjs[NUM_OBJECTS];
3507 register const char *zn;
3508 int prob, maxprob = 0;
3510 if (!name || !*name)
3511 return STRANGE_OBJECT;
3513 memset((genericptr_t) validobjs, 0, sizeof validobjs);
3516 * When this spans classes (the !oclass case), the item
3517 * probabilities are not very useful because they don't take
3518 * the class generation probability into account. [If 10%
3519 * of spellbooks were blank and 1% of scrolls were blank,
3520 * "blank" would have 10/11 chance to yield a book even though
3521 * scrolls are supposed to be much more common than books.]
3523 for (i = oclass ? bases[(int) oclass] : STRANGE_OBJECT + 1;
3524 i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass);
3526 /* don't match extra descriptions (w/o real name) */
3527 if ((zn = OBJ_NAME(objects[i])) == 0)
3531 *
\81u
\83C
\83F
\83\93\83_
\81[
\82Ì
\96\82\8f\9c\82¯
\81v
\82ð
\8aè
\82Á
\82½
\82Æ
\82«
\82É
\82±
\82±
\82Å
\82Í
\8bU
\95¨
\82É
3532 *
\82È
\82ç
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\81B
3533 *
\94ñ
\83E
\83B
\83U
\81[
\83h
\83\82\81[
\83h
\82Å
\82Ì
\93ü
\82ê
\91Ö
\82¦
\8f\88\97\9d\82Í
\8cã
\82É
\82 \82é
\81B
3535 if (i == FAKE_AMULET_OF_YENDOR)
3538 if (wishymatch(name, zn, TRUE)
3539 || ((zn = OBJ_DESCR(objects[i])) != 0
3540 && wishymatch(name, zn, FALSE))
3541 || ((zn = objects[i].oc_uname) != 0
3542 && wishymatch(name, zn, FALSE))) {
3543 validobjs[n++] = (short) i;
3544 maxprob += (objects[i].oc_prob + xtra_prob);
3548 if (n > 0 && maxprob) {
3549 prob = rn2(maxprob);
3550 for (i = 0; i < n - 1; i++)
3551 if ((prob -= (objects[validobjs[i]].oc_prob + xtra_prob)) < 0)
3553 return validobjs[i];
3555 return STRANGE_OBJECT;
3562 return (int) rnd_otyp_by_namedesc("shiny", oclass, 0);
3566 * Return something wished for. Specifying a null pointer for
3567 * the user request string results in a random object. Otherwise,
3568 * if asking explicitly for "nothing" (or "nil") return no_wish;
3569 * if not an object return &zeroobj; if an error (no matching object),
3574 readobjnam(bp, no_wish)
3576 struct obj *no_wish;
3580 register struct obj *otmp;
3581 int cnt, spe, spesgn, typ, very, rechrg;
3582 int blessed, uncursed, iscursed, ispoisoned, isgreased;
3583 int eroded, eroded2, erodeproof, locked, unlocked, broken;
3584 int halfeaten, mntmp, contents;
3585 int islit, unlabeled, ishistoric, isdiluted, trapped;
3587 int tmp, tinv, tvariety;
3591 int wetness, gsize = 0;
3593 int ftype = context.current_fruit;
3595 char fruitbuf[BUFSZ], globbuf[BUFSZ];
3597 char fruitbuf[BUFSZ];
3599 /* Fruits may not mess up the ability to wish for real objects (since
3600 * you can leave a fruit in a bones file and it will be added to
3601 * another person's game), so they must be checked for last, after
3602 * stripping all the possible prefixes and seeing if there's a real
3603 * name in there. So we have to save the full original name. However,
3604 * it's still possible to do things like "uncursed burnt Alaska",
3605 * or worse yet, "2 burned 5 course meals", so we need to loop to
3606 * strip off the prefixes again, this time stripping only the ones
3608 * We could get even more detailed so as to allow food names with
3609 * prefixes that _are_ possible on food, so you could wish for
3610 * "2 3 alarm chilis". Currently this isn't allowed; options.c
3611 * automatically sticks 'candied' in front of such names.
3614 char *un, *dn, *actualn, *origbp = bp;
3615 const char *name = 0;
3617 cnt = spe = spesgn = typ = 0;
3618 very = rechrg = blessed = uncursed = iscursed = ispoisoned =
3619 isgreased = eroded = eroded2 = erodeproof = halfeaten =
3620 islit = unlabeled = ishistoric = isdiluted = trapped =
3621 locked = unlocked = broken = 0;
3622 tvariety = RANDOM_TIN;
3627 contents = UNDEFINED;
3629 actualn = dn = un = 0;
3634 /* first, remove extra whitespace they may have typed */
3635 (void) mungspaces(bp);
3636 /* allow wishing for "nothing" to preserve wishless conduct...
3637 [now requires "wand of nothing" if that's what was really wanted] */
3639 if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil")
3640 || !strcmpi(bp, "none"))
3642 if (!strcmpi(bp, "
\82È
\82µ") || !strcmpi(bp, "
\96³
\82µ"))
3645 /* save the [nearly] unmodified choice string */
3646 Strcpy(fruitbuf, bp);
3653 if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) {
3655 } else if (!strncmpi(bp, "the ", l = 4)) {
3656 ; /* just increment `bp' by `l' below */
3657 } else if (!cnt && digit(*bp) && strcmp(bp, "0")) {
3664 #if 1 /*JP*//*
\8cã
\82É
\90\94\8e\8c\82ª
\82 \82é
\82Æ
\82«
\82Í
\8dí
\8f\9c */
3665 if(!strncmp(bp, "
\8dû
\82Ì", l = 4) ||
3666 !strncmp(bp, "
\96{
\82Ì", l = 4) ||
3667 !strncmp(bp, "
\92\85\82Ì", l = 4) ||
3668 !strncmp(bp, "
\8cÂ
\82Ì", l = 4) ||
3669 !strncmp(bp, "
\96\87\82Ì", l = 4) ||
3670 !strncmp(bp, "
\82Â
\82Ì", l = 4) ||
3671 !strncmp(bp, "
\82Ì", l = 2))
3676 } else if (*bp == '+' || *bp == '-') {
3677 spesgn = (*bp++ == '+') ? 1 : -1;
3685 } else if (!strncmpi(bp, "blessed ", l = 8)
3686 || !strncmpi(bp, "holy ", l = 5)) {
3688 } else if (!strncmpi(bp, "
\8fj
\95\9f\82³
\82ê
\82½", l = 10)) {
3692 } else if (!strncmpi(bp, "moist ", l = 6)
3693 || !strncmpi(bp, "wet ", l = 4)) {
3695 } else if (!strncmpi(bp, "
\8e¼
\82Á
\82½", l = 6)
3696 || !strncmpi(bp, "
\94G
\82ê
\82½", l = 6)) {
3699 if (!strncmpi(bp, "wet ", 4))
3701 if (!strncmpi(bp, "
\94G
\82ê
\82½", 6))
3703 wetness = rn2(3) + 3;
3707 } else if (!strncmpi(bp, "cursed ", l = 7)
3708 || !strncmpi(bp, "unholy ", l = 7)) {
3710 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82½", l = 8)) {
3714 } else if (!strncmpi(bp, "uncursed ", l = 9)) {
3716 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", l = 14)) {
3720 } else if (!strncmpi(bp, "rustproof ", l = 10)
3721 || !strncmpi(bp, "erodeproof ", l = 11)
3722 || !strncmpi(bp, "corrodeproof ", l = 13)
3723 || !strncmpi(bp, "fixed ", l = 6)
3724 || !strncmpi(bp, "fireproof ", l = 10)
3725 || !strncmpi(bp, "rotproof ", l = 9)) {
3727 } else if (!strncmpi(bp, "
\8eK
\82Ñ
\82È
\82¢", l = 8)
3728 || !strncmpi(bp, "
\95\85\90H
\82µ
\82È
\82¢", l = 10)
3729 || !strncmpi(bp, "
\88À
\92è
\82µ
\82½", l = 8)
3730 || !strncmpi(bp, "
\94R
\82¦
\82È
\82¢", l = 8)) {
3734 } else if (!strncmpi(bp, "lit ", l = 4)
3735 || !strncmpi(bp, "burning ", l = 8)) {
3737 } else if (!strncmpi(bp, "
\8cõ
\82Á
\82Ä
\82¢
\82é", l = 10)
3738 || !strncmpi(bp, "
\94R
\82¦
\82Ä
\82¢
\82é", l = 10)) {
3742 } else if (!strncmpi(bp, "unlit ", l = 6)
3743 || !strncmpi(bp, "extinguished ", l = 13)) {
3745 } else if (!strncmpi(bp, "
\8fÁ
\82¦
\82Ä
\82¢
\82é", l = 10)) {
3748 /* "unlabeled" and "blank" are synonymous */
3750 } else if (!strncmpi(bp, "unlabeled ", l = 10)
3751 || !strncmpi(bp, "unlabelled ", l = 11)
3752 || !strncmpi(bp, "blank ", l = 6)) {
3754 } else if (!strncmpi(bp, "
\83\89\83x
\83\8b\82Ì
\82È
\82¢", l = 12)
3755 || !strncmpi(bp, "
\90^
\82Á
\94\92\82È", l = 8)) {
3759 } else if (!strncmpi(bp, "poisoned ", l = 9)) {
3761 } else if (!strncmpi(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", l = 12)) {
3764 /* "trapped" recognized but not honored outside wizard mode */
3765 } else if (!strncmpi(bp, "trapped ", l = 8)) {
3766 trapped = 0; /* undo any previous "untrapped" */
3769 } else if (!strncmpi(bp, "untrapped ", l = 10)) {
3770 trapped = 2; /* not trapped */
3771 /* locked, unlocked, broken: box/chest lock states */
3773 } else if (!strncmpi(bp, "locked ", l = 7)) {
3775 } else if (!strncmpi(bp, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½", l = 12)) {
3777 locked = 1, unlocked = broken = 0;
3779 } else if (!strncmpi(bp, "unlocked ", l = 9)) {
3781 } else if (!strncmpi(bp, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢", l = 18)) {
3783 unlocked = 1, locked = broken = 0;
3785 } else if (!strncmpi(bp, "broken ", l = 7)) {
3787 } else if (!strncmpi(bp, "
\8c®
\82Ì
\89ó
\82ê
\82½", l = 10)) {
3789 broken = 1, locked = unlocked = 0;
3791 } else if (!strncmpi(bp, "greased ", l = 8)) {
3793 } else if (!strncmpi(bp, "
\96û
\82Ì
\93h
\82ç
\82ê
\82½", l = 12)
3794 || !strncmpi(bp, "
\8e\89\82Ì
\93h
\82ç
\82ê
\82½", l = 12)) {
3798 } else if (!strncmpi(bp, "very ", l = 5)) {
3800 } else if (!strncmpi(bp, "
\82Æ
\82Ä
\82à", l = 6)) {
3802 /* very rusted very heavy iron ball */
3805 } else if (!strncmpi(bp, "thoroughly ", l = 11)) {
3807 } else if (!strncmpi(bp, "
\82©
\82È
\82è", l = 6)) {
3811 } else if (!strncmpi(bp, "rusty ", l = 6)
3812 || !strncmpi(bp, "rusted ", l = 7)
3813 || !strncmpi(bp, "burnt ", l = 6)
3814 || !strncmpi(bp, "burned ", l = 7)) {
3816 } else if (!strncmpi(bp, "
\8eK
\82Ñ
\82½", l = 6)
3817 || !strncmpi(bp, "
\94R
\82¦
\82½", l = 6)) {
3822 } else if (!strncmpi(bp, "corroded ", l = 9)
3823 || !strncmpi(bp, "rotted ", l = 7)) {
3825 } else if (!strncmpi(bp, "
\95\85\90H
\82µ
\82½", l = 8)
3826 || !strncmpi(bp, "
\95\85\82Á
\82½", l = 6)) {
3831 } else if (!strncmpi(bp, "partly eaten ", l = 13)
3832 || !strncmpi(bp, "partially eaten ", l = 16)) {
3834 } else if (!strncmpi(bp, "
\90H
\82×
\82©
\82¯
\82Ì", l = 10)) {
3838 } else if (!strncmpi(bp, "historic ", l = 9)) {
3840 } else if (!strncmpi(bp, "
\97ð
\8ej
\93I
\82È", l = 8)) {
3844 } else if (!strncmpi(bp, "diluted ", l = 8)) {
3846 } else if (!strncmpi(bp, "
\94\96\82Ü
\82Á
\82½", l = 8)) {
3850 } else if (!strncmpi(bp, "empty ", l = 6)) {
3852 } else if (!strncmpi(bp, "
\8bó
\82Á
\82Û
\82Ì", l = 8)) {
3856 } else if (!strncmpi(bp, "small ", l = 6)) { /* glob sizes */
3858 } else if (!strncmpi(bp, "
\8f¬
\82³
\82¢", l = 6)) { /* glob sizes */
3860 /* "small" might be part of monster name (mimic, if wishing
3861 for its corpse) rather than prefix for glob size; when
3862 used for globs, it might be either "small glob of <foo>" or
3863 "small <foo> glob" and user might add 's' even though plural
3864 doesn't accomplish anything because globs don't stack */
3865 if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob"))
3869 } else if (!strncmpi(bp, "medium ", l = 7)) {
3871 } else if (!strncmpi(bp, "
\92\86\82
\82ç
\82¢
\82Ì", l = 10)) {
3873 /* xname() doesn't display "medium" but without this
3874 there'd be no way to ask for the intermediate size
3875 ("glob" without size prefix yields smallest one) */
3878 } else if (!strncmpi(bp, "large ", l = 6)) {
3880 } else if (!strncmpi(bp, "
\91å
\82«
\82¢", l = 6)) {
3882 /* "large" might be part of monster name (dog, cat, koboold,
3883 mimic) or object name (box, round shield) rather than
3884 prefix for glob size */
3885 if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob"))
3887 /* "very large " had "very " peeled off on previous iteration */
3888 gsize = (very != 1) ? 3 : 4;
3894 cnt = 1; /* will be changed to 2 if makesingular() changes string */
3895 if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) {
3896 boolean keeptrailingchars = TRUE;
3898 p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */
3899 ++p; /* advance past '(' */
3900 if (!strncmpi(p, "lit)", 4)) {
3902 p += 4 - 1; /* point at ')' */
3916 /* mis-matched parentheses; rest of string will be ignored
3917 * [probably we should restore everything back to '('
3918 * instead since it might be part of "named ..."]
3920 keeptrailingchars = FALSE;
3925 if (keeptrailingchars) {
3928 /* 'pp' points at 'pb's terminating '\0',
3929 'p' points at ')' and will be incremented past it */
3936 * otmp->spe is type schar, so we don't want spe to be any bigger or
3937 * smaller. Also, spe should always be positive --some cheaters may
3938 * try to confuse atoi().
3941 spesgn = -1; /* cheaters get what they deserve */
3944 if (spe > SCHAR_LIM)
3946 if (rechrg < 0 || rechrg > 7)
3947 rechrg = 7; /* recharge_limit */
3949 /* now we have the actual name, as delivered by xname, say
3950 * green potions called whisky
3951 * scrolls labeled "QWERTY"
3954 * very heavy iron ball named hoei
3958 if ((p = strstri(bp, " named ")) != 0) {
3962 if ((p = strstri(bp, " called ")) != 0) {
3965 #if 0 /*JP*//*
\83^
\83C
\83v
\95Ê
\82Í
\82Æ
\82è
\82 \82¦
\82¸
\82µ
\82È
\82¢*/
3966 /* "helmet called telepathy" is not "helmet" (a specific type)
3967 * "shield called reflection" is not "shield" (a general type)
3969 for (i = 0; i < SIZE(o_ranges); i++)
3970 if (!strcmpi(bp, o_ranges[i].name)) {
3971 oclass = o_ranges[i].oclass;
3976 if ((p = strstri(bp, " labeled ")) != 0) {
3979 } else if ((p = strstri(bp, " labelled ")) != 0) {
3983 if ((p = strstri(bp, " of spinach")) != 0) {
3988 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82µ
\82È
\82¢*/
3990 * Skip over "pair of ", "pairs of", "set of" and "sets of".
3992 * Accept "3 pair of boots" as well as "3 pairs of boots". It is
3993 * valid English either way. See makeplural() for more on pair/pairs.
3995 * We should only double count if the object in question is not
3996 * referred to as a "pair of". E.g. We should double if the player
3997 * types "pair of spears", but not if the player types "pair of
3998 * lenses". Luckily (?) all objects that are referred to as pairs
3999 * -- boots, gloves, and lenses -- are also not mergable, so cnt is
4002 if (!strncmpi(bp, "pair of ", 8)) {
4005 } else if (!strncmpi(bp, "pairs of ", 9)) {
4009 } else if (!strncmpi(bp, "set of ", 7)) {
4011 } else if (!strncmpi(bp, "sets of ", 8)) {
4017 /* intercept pudding globs here; they're a valid wish target,
4018 * but we need them to not get treated like a corpse.
4020 * also don't let player wish for multiple globs.
4022 i = (int) strlen(bp);
4024 /* check for "glob", "<foo> glob", and "glob of <foo>" */
4025 if (!strcmpi(bp, "glob") || !BSTRCMPI(bp, bp + i - 5, " glob")
4026 || !strcmpi(bp, "globs") || !BSTRCMPI(bp, bp + i - 6, " globs")
4027 || (p = strstri(bp, "glob of ")) != 0
4028 || (p = strstri(bp, "globs of ")) != 0) {
4029 mntmp = name_to_mon(!p ? bp : (strstri(p, " of ") + 4));
4030 /* if we didn't recognize monster type, pick a valid one at random */
4031 if (mntmp == NON_PM)
4032 mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE);
4033 /* construct canonical spelling in case name_to_mon() recognized a
4034 variant (grey ooze) or player used inverted syntax (<foo> glob);
4035 if player has given a valid monster type but not valid glob type,
4036 object name lookup won't find it and wish attempt will fail */
4037 Sprintf(globbuf, "glob of %s", mons[mntmp].mname);
4039 mntmp = NON_PM; /* not useful for "glob of <foo>" object lookup */
4040 cnt = 0; /* globs don't stack */
4041 oclass = FOOD_CLASS;
4042 actualn = bp, dn = 0;
4046 * Find corpse type using "of" (figurine of an orc, tin of orc meat)
4047 * Don't check if it's a wand or spellbook.
4048 * (avoid "wand/finger of death" confusion).
4050 if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ")
4051 && !strstri(bp, "finger ")) {
4052 if ((p = strstri(bp, "tin of ")) != 0) {
4053 if (!strcmpi(p + 7, "spinach")) {
4057 tmp = tin_variety_txt(p + 7, &tinv);
4059 mntmp = name_to_mon(p + 7 + tmp);
4063 } else if ((p = strstri(bp, " of ")) != 0
4064 && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
4068 /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
4069 if (strncmpi(bp, "samurai sword", 13) /* not the "samurai" monster! */
4070 && strncmpi(bp, "wizard lock", 11) /* not the "wizard" monster! */
4071 && strncmpi(bp, "ninja-to", 8) /* not the "ninja" rank */
4072 && strncmpi(bp, "master key", 10) /* not the "master" rank */
4073 && strncmpi(bp, "magenta", 7)) { /* not the "mage" rank */
4074 if (mntmp < LOW_PM && strlen(bp) > 2
4075 && (mntmp = name_to_mon(bp)) >= LOW_PM) {
4076 int mntmptoo, mntmplen; /* double check for rank title */
4079 mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
4080 bp += (mntmp != mntmptoo) ? (int) strlen(mons[mntmp].mname)
4084 } else if (!strncmpi(bp, "s ", 2)) {
4086 } else if (!strncmpi(bp, "es ", 3)) {
4088 } else if (!*bp && !actualn && !dn && !un && !oclass) {
4089 /* no referent; they don't really mean a monster type */
4097 /*JP
\81u(
\89ö
\95¨
\96¼)
\82Ì
\89ò
\81v
\82Í
\8cÂ
\81X
\82ÉID
\82ª
\82 \82é
\82Ì
\82Å
\95Ê
\88µ
\82¢ */
4099 if (l > 4 && strncmp(bp + l - 4, "
\82Ì
\89ò", 4) == 0) {
4100 if ((mntmp = name_to_mon(bp)) >= PM_GRAY_OOZE
4101 && mntmp <= PM_BLACK_PUDDING) {
4102 mntmp = NON_PM; /* lie to ourselves */
4103 cnt = 0; /* force only one */
4106 /*JP:
\81u(
\89ö
\95¨
\96¼)
\82Ì(
\83A
\83C
\83e
\83\80)
\81v
\91Î
\89\9e */
4107 if ((mntmp = name_to_mon(bp)) >= LOW_PM) {
4108 const char *mp = mons[mntmp].mname;
4109 bp = strstri(bp, mp) + strlen(mp) + 2;
4115 #if 0 /*JP*//*
\92P
\90\94\89»
\82Í
\82µ
\82È
\82¢*/
4116 /* first change to singular if necessary */
4118 char *sng = makesingular(bp);
4120 if (strcmp(bp, sng)) {
4128 #if 0 /*JP*//*
\83X
\83y
\83\8b\97h
\82ê
\8f\88\97\9d\82Í
\82µ
\82È
\82¢*/
4129 /* Alternate spellings (pick-ax, silver sabre, &c) */
4131 const struct alt_spellings *as = spellings;
4134 if (fuzzymatch(bp, as->sp, " -", TRUE)) {
4140 /* can't use spellings list for this one due to shuffling */
4141 if (!strncmpi(bp, "grey spell", 10))
4144 if ((p = strstri(bp, "armour")) != 0) {
4145 /* skip past "armo", then copy remainder beyond "u" */
4147 while ((*p = *(p + 1)) != '\0')
4148 ++p; /* self terminating */
4154 /* dragon scales - assumes order of dragons */
4155 if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON
4156 && mntmp <= PM_YELLOW_DRAGON) {
4157 typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
4158 mntmp = NON_PM; /* no monster */
4162 /*JP:
\81u
\97Ø
\8aZ
\81v
\82ð
\90æ
\82É
\8f\88\97\9d\82µ
\82Ä
\82¨
\82 */
4163 if (!strcmpi(bp, "
\97Ø
\8aZ") && mntmp >= PM_GRAY_DRAGON
4164 && mntmp <= PM_YELLOW_DRAGON) {
4165 typ = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4166 mntmp = NON_PM; /* no monster */
4170 if (!strcmpi(bp, "
\97Ø") && mntmp >= PM_GRAY_DRAGON
4171 && mntmp <= PM_YELLOW_DRAGON) {
4172 typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
4173 mntmp = NON_PM; /* no monster */
4180 if (!BSTRCMPI(bp, p - 10, "holy water")) {
4182 if ((p - bp) >= 12 && *(p - 12) == 'u')
4183 iscursed = 1; /* unholy water */
4188 #else /*JP:
\90¹
\90\85\82Æ
\95s
\8fò
\82È
\90\85\82ð
\95Ê
\82É
\94»
\92è*/
4189 if (!BSTRCMPI(bp, p - 4, "
\90¹
\90\85")) {
4194 if (!BSTRCMPI(bp, p - 8, "
\95s
\8fò
\82È
\90\85")) {
4201 if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
4203 if (unlabeled && !BSTRCMPI(bp, p - 4, "
\8aª
\95¨")) {
4205 typ = SCR_BLANK_PAPER;
4209 if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
4211 if (unlabeled && !BSTRCMPI(bp, p - 6, "
\96\82\96@
\8f\91")) {
4213 typ = SPE_BLANK_PAPER;
4216 /* specific food rather than color of gem/potion/spellbook[/scales] */
4217 if (!BSTRCMPI(bp, p - 6, "orange") && mntmp == NON_PM) {
4222 * NOTE: Gold pieces are handled as objects nowadays, and therefore
4223 * this section should probably be reconsidered as well as the entire
4224 * gold/money concept. Maybe we want to add other monetary units as
4225 * well in the future. (TH)
4228 if (!BSTRCMPI(bp, p - 10, "gold piece")
4229 || !BSTRCMPI(bp, p - 7, "zorkmid")
4230 || !strcmpi(bp, "gold") || !strcmpi(bp, "money")
4231 || !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
4233 if (!BSTRCMPI(bp, p - 4, "
\8bà
\89Ý") || !BSTRCMPI(bp, p - 8, "
\83S
\81[
\83\8b\83h")
4234 || *bp == GOLD_SYM) {
4236 if (cnt > 5000 && !wizard)
4240 otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
4241 otmp->quan = (long) cnt;
4242 otmp->owt = weight(otmp);
4247 /* check for single character object class code ("/" for wand, &c) */
4248 if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES
4249 && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
4256 \89p
\8cê
\82È
\82ç XXXXX potion
\82Í
\95s
\8am
\92è
\96¼
\81Apotion of XXXXX
\82Í
\8am
\92è
\96¼
\82Æ
\82¢
\82¤
4257 \8bæ
\95Ê
\82ª
\95t
\82
\82ª
\81A
\93ú
\96{
\8cê
\82Å
\82Í
\82Ç
\82¿
\82ç
\82à
\81uXXXXX
\82Ì
\96ò
\81v
\82È
\82Ì
\82Å
\82±
\82±
\82Å
\82Í
\94»
\95Ê
\82µ
\82È
\82¢
4259 /* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */
4260 /* false hits on, e.g., rings for "ring mail". */
4261 if (strncmpi(bp, "enchant ", 8)
4262 && strncmpi(bp, "destroy ", 8)
4263 && strncmpi(bp, "detect food", 11)
4264 && strncmpi(bp, "food detection", 14)
4265 && strncmpi(bp, "ring mail", 9)
4266 && strncmpi(bp, "studded leather armor", 21)
4267 && strncmpi(bp, "leather armor", 13)
4268 && strncmpi(bp, "tooled horn", 11)
4269 && strncmpi(bp, "food ration", 11)
4270 && strncmpi(bp, "meat ring", 9))
4271 for (i = 0; i < (int) (sizeof wrpsym); i++) {
4272 register int j = strlen(wrp[i]);
4274 /* check for "<class> [ of ] something" */
4275 if (!strncmpi(bp, wrp[i], j)) {
4277 if (oclass != AMULET_CLASS) {
4279 if (!strncmpi(bp, " of ", 4))
4281 /* else if(*bp) ?? */
4286 /* check for "something <class>" */
4287 if (!BSTRCMPI(bp, p - j, wrp[i])) {
4289 /* for "foo amulet", leave the class name so that
4290 wishymatch() can do "of inversion" to try matching
4291 "amulet of foo"; other classes don't include their
4292 class name in their full object names (where
4293 "potion of healing" is just "healing", for instance) */
4294 if (oclass != AMULET_CLASS) {
4297 if (p > bp && p[-1] == ' ')
4300 /* amulet without "of"; convoluted wording but better a
4301 special case that's handled than one that's missing */
4302 if (!strncmpi(bp, "versus poison ", 14)) {
4303 typ = AMULET_VERSUS_POISON;
4313 /* Wishing in wizard mode can create traps and furniture.
4314 * Part I: distinguish between trap and object for the two
4315 * types of traps which have corresponding objects: bear trap
4316 * and land mine. "beartrap" (object) and "bear trap" (trap)
4317 * have a difference in spelling which we used to exploit by
4318 * adding a special case in wishymatch(), but "land mine" is
4319 * spelled the same either way so needs different handing.
4320 * Since we need something else for land mine, we've dropped
4321 * the bear trap hack so that both are handled exactly the
4322 * same. To get an armed trap instead of a disarmed object,
4323 * the player can prefix either the object name or the trap
4324 * name with "trapped " (which ordinarily applies to chests
4325 * and tins), or append something--anything at all except for
4326 * " object", but " trap" is suggested--to either the trap
4327 * name or the object name.
4329 if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
4330 boolean beartrap = (lowc(*bp) == 'b');
4331 char *zp = bp + 4; /* skip "bear"/"land" */
4334 ++zp; /* embedded space is optional */
4335 if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
4337 if (trapped == 2 || !strcmpi(zp, " object")) {
4338 /* "untrapped <foo>" or "<foo> object" */
4339 typ = beartrap ? BEARTRAP : LAND_MINE;
4341 } else if (trapped == 1 || *zp != '\0') {
4342 /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
4343 int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
4345 /* use canonical trap spelling, skip object matching */
4346 Strcpy(bp, defsyms[idx].explanation);
4349 /* [no prefix or suffix; we're going to end up matching
4350 the object name and getting a disarmed trap object] */
4354 #if 0 /*JP*//* mail/armor
\8aÖ
\98A
\82Å
\82Ì
\82Ý
\8eg
\82¤
\83\89\83x
\83\8b */
4357 #if 0 /*JP*//*
\83^
\83C
\83v
\95Ê
\82Í
\82Æ
\82è
\82 \82¦
\82¸
\82µ
\82È
\82¢ */
4358 /* "grey stone" check must be before general "stone" */
4359 for (i = 0; i < SIZE(o_ranges); i++)
4360 if (!strcmpi(bp, o_ranges[i].name)) {
4361 typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
4366 #if 0 /*JP*//*
\90Î
\82Ì
\93Á
\95Ê
\8f\88\97\9d\82Í
\95s
\97v */
4367 if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) {
4368 p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0';
4372 } else if (!strcmpi(bp, "looking glass")) {
4373 ; /* avoid false hit on "* glass" */
4374 } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) {
4375 register char *g = bp;
4377 /* treat "broken glass" as a non-existent item; since "broken" is
4378 also a chest/box prefix it might have been stripped off above */
4379 if (broken || strstri(g, "broken"))
4380 return (struct obj *) 0;
4381 if (!strncmpi(g, "worthless ", 10))
4383 if (!strncmpi(g, "piece of ", 9))
4385 if (!strncmpi(g, "colored ", 8))
4387 else if (!strncmpi(g, "coloured ", 9))
4389 if (!strcmpi(g, "glass")) { /* choose random color */
4390 /* 9 different kinds */
4391 typ = LAST_GEM + rnd(9);
4392 if (objects[typ].oc_class == GEM_CLASS)
4395 typ = 0; /* somebody changed objects[]? punt */
4396 } else { /* try to construct canonical form */
4399 Strcpy(tbuf, "worthless piece of ");
4400 Strcat(tbuf, g); /* assume it starts with the color */
4408 dn = actualn; /* ex. "skull cap" */
4412 /* check real names of gems first */
4413 if (!oclass && actualn) {
4414 for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
4415 register const char *zn;
4417 if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(actualn, zn)) {
4422 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í"tin"
\82ð
\96ó
\82µ
\95ª
\82¯
\82Ä
\82¢
\82é
\82Ì
\82Å
\95s
\97v */
4423 /* "tin of foo" would be caught above, but plain "tin" has
4424 a random chance of yielding "tin wand" unless we do this */
4425 if (!strcmpi(actualn, "tin")) {
4432 if (((typ = rnd_otyp_by_namedesc(actualn, oclass, 1)) != STRANGE_OBJECT)
4433 || ((typ = rnd_otyp_by_namedesc(dn, oclass, 1)) != STRANGE_OBJECT)
4434 || ((typ = rnd_otyp_by_namedesc(un, oclass, 1)) != STRANGE_OBJECT)
4435 || ((typ = rnd_otyp_by_namedesc(origbp, oclass, 1)) != STRANGE_OBJECT))
4440 struct Jitem *j = Japanese_items;
4443 if (actualn && !strcmpi(actualn, j->name)) {
4450 #if 0 /*JP*//* mail/armor
\82Ì
\95\
\8bL
\97h
\82ê
\83`
\83F
\83b
\83N
\82Í
\95s
\97v */
4451 /* if we've stripped off "armor" and failed to match anything
4452 in objects[], append "mail" and try again to catch misnamed
4453 requests like "plate armor" and "yellow dragon scale armor" */
4454 if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
4455 /* modifying bp's string is ok; we're about to resort
4456 to random armor if this also fails to match anything */
4457 Strcat(bp, " mail");
4462 if (!strcmpi(bp, "spinach")) {
4464 if (!strcmp(bp, "
\83z
\83E
\83\8c\83\93\91\90")) {
4470 /* Note: not strcmpi. 2 fruits, one capital, one not, are possible.
4471 Also not strncmp. We used to ignore trailing text with it, but
4472 that resulted in "grapefruit" matching "grape" if the latter came
4473 earlier than the former in the fruit list. */
4477 int blessedf, iscursedf, uncursedf, halfeatenf;
4479 blessedf = iscursedf = uncursedf = halfeatenf = 0;
4486 if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
4488 } else if (!cntf && digit(*fp)) {
4495 } else if (!strncmpi(fp, "blessed ", l = 8)) {
4497 } else if (!strncmpi(fp, "cursed ", l = 7)) {
4499 } else if (!strncmpi(fp, "uncursed ", l = 9)) {
4501 } else if (!strncmpi(fp, "partly eaten ", l = 13)
4502 || !strncmpi(fp, "partially eaten ", l = 16)) {
4509 for (f = ffruit; f; f = f->nextf) {
4510 /* match type: 0=none, 1=exact, 2=singular, 3=plural */
4513 if (!strcmp(fp, f->fname))
4515 else if (!strcmp(fp, makesingular(f->fname)))
4517 else if (!strcmp(fp, makeplural(f->fname)))
4522 iscursed = iscursedf;
4523 uncursed = uncursedf;
4524 halfeaten = halfeatenf;
4525 /* adjust count if user explicitly asked for
4526 singular amount (can't happen unless fruit
4527 has been given an already pluralized name)
4528 or for plural amount */
4529 if (ftyp == 2 && !cntf)
4531 else if (ftyp == 3 && !cntf)
4540 if (!oclass && actualn) {
4543 /* Perhaps it's an artifact specified by name, not type */
4544 name = artifact_name(actualn, &objtyp);
4552 * Let wizards wish for traps and furniture.
4553 * Must come after objects check so wizards can still wish for
4554 * trap objects like beartraps.
4555 * Disallow such topology tweaks for WIZKIT startup wishes.
4558 if (wizard && !program_state.wizkit_wishing) {
4560 boolean madeterrain = FALSE;
4561 int trap, x = u.ux, y = u.uy;
4563 for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
4567 tname = defsyms[trap_to_defsym(trap)].explanation;
4568 if (strncmpi(tname, bp, strlen(tname)))
4570 /* found it; avoid stupid mistakes */
4571 if (is_hole(trap) && !Can_fall_thru(&u.uz))
4573 if ((t = maketrap(x, y, trap)) != 0) {
4575 tname = defsyms[trap_to_defsym(trap)].explanation;
4576 pline("%s%s.", An(tname),
4577 (trap != MAGIC_PORTAL) ? "" : " to nowhere");
4579 pline("Creation of %s failed.", an(tname));
4580 return (struct obj *) &zeroobj;
4583 /* furniture and terrain (use at your own risk; can clobber stairs
4584 or place furniture on existing traps which shouldn't be allowed) */
4587 if (!BSTRCMPI(bp, p - 8, "fountain")) {
4588 lev->typ = FOUNTAIN;
4589 level.flags.nfountains++;
4590 if (!strncmpi(bp, "magic ", 6))
4591 lev->blessedftn = 1;
4592 pline("A %sfountain.", lev->blessedftn ? "magic " : "");
4594 } else if (!BSTRCMPI(bp, p - 6, "throne")) {
4598 } else if (!BSTRCMPI(bp, p - 4, "sink")) {
4600 level.flags.nsinks++;
4604 /* ("water" matches "potion of water" rather than terrain) */
4605 } else if (!BSTRCMPI(bp, p - 4, "pool")
4606 || !BSTRCMPI(bp, p - 4, "moat")) {
4607 lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
4609 pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
4610 /* Must manually make kelp! */
4611 water_damage_chain(level.objects[x][y], TRUE);
4614 /* also matches "molten lava" */
4615 } else if (!BSTRCMPI(bp, p - 4, "lava")) {
4616 lev->typ = LAVAPOOL;
4618 pline("A pool of molten lava.");
4619 if (!(Levitation || Flying))
4622 } else if (!BSTRCMPI(bp, p - 5, "altar")) {
4626 if (!strncmpi(bp, "chaotic ", 8))
4628 else if (!strncmpi(bp, "neutral ", 8))
4630 else if (!strncmpi(bp, "lawful ", 7))
4632 else if (!strncmpi(bp, "unaligned ", 10))
4634 else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
4635 al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1);
4636 lev->altarmask = Align2amask(al);
4637 pline("%s altar.", An(align_str(al)));
4639 } else if (!BSTRCMPI(bp, p - 5, "grave")
4640 || !BSTRCMPI(bp, p - 9, "headstone")) {
4641 make_grave(x, y, (char *) 0);
4642 pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
4643 : "Can't place a grave here");
4645 } else if (!BSTRCMPI(bp, p - 4, "tree")) {
4650 } else if (!BSTRCMPI(bp, p - 4, "bars")) {
4651 lev->typ = IRONBARS;
4652 pline("Iron bars.");
4657 feel_newsym(x, y); /* map the spot where the wish occurred */
4658 /* hero started at <x,y> but might not be there anymore (create
4659 lava, decline to die, and get teleported away to safety) */
4660 if (u.uinwater && !is_pool(u.ux, u.uy)) {
4661 u.uinwater = 0; /* leave the water */
4663 vision_full_recalc = 1;
4664 } else if (u.utrap && u.utraptype == TT_LAVA
4665 && !is_lava(u.ux, u.uy)) {
4668 /* cast 'const' away; caller won't modify this */
4669 return (struct obj *) &zeroobj;
4671 } /* end of wizard mode traps and terrain */
4673 #if 0 /*JP*//*
\83^
\83C
\83v
\95Ê
\82Í
\82Æ
\82è
\82 \82¦
\82¸
\82µ
\82È
\82¢ */
4674 if (!oclass && !typ) {
4675 if (!strncmpi(bp, "polearm", 7)) {
4676 typ = rnd_otyp_by_wpnskill(P_POLEARMS);
4678 } else if (!strncmpi(bp, "hammer", 6)) {
4679 typ = rnd_otyp_by_wpnskill(P_HAMMER);
4686 return ((struct obj *) 0);
4689 oclass = wrpsym[rn2((int) sizeof wrpsym)];
4692 oclass = objects[typ].oc_class;
4694 /* handle some objects that are only allowed in wizard mode */
4695 if (typ && !wizard) {
4697 case AMULET_OF_YENDOR:
4698 typ = FAKE_AMULET_OF_YENDOR;
4700 case CANDELABRUM_OF_INVOCATION:
4701 typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
4703 case BELL_OF_OPENING:
4706 case SPE_BOOK_OF_THE_DEAD:
4707 typ = SPE_BLANK_PAPER;
4713 /* catch any other non-wishable objects (venom) */
4714 if (objects[typ].oc_nowish)
4715 return (struct obj *) 0;
4721 * Create the object, then fine-tune it.
4723 otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
4724 typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
4726 if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN
4727 || Is_candle(otmp) || typ == POT_OIL)) {
4728 place_object(otmp, u.ux, u.uy); /* make it viable light source */
4729 begin_burn(otmp, FALSE);
4730 obj_extract_self(otmp); /* now release it for caller's use */
4733 /* if player specified a reasonable count, maybe honor it */
4734 if (cnt > 0 && objects[typ].oc_merge
4735 && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp))
4736 || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp))
4737 || typ == ROCK || is_missile(otmp)))))
4738 otmp->quan = (long) cnt;
4740 if (oclass == VENOM_CLASS)
4745 } else if (wizard) {
4746 ; /* no alteration to spe */
4747 } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
4749 || (oclass == RING_CLASS && objects[typ].oc_charged)) {
4750 if (spe > rnd(5) && spe > otmp->spe)
4752 if (spe > 2 && Luck < 0)
4755 if (oclass == WAND_CLASS) {
4756 if (spe > 1 && spesgn == -1)
4759 if (spe > 0 && spesgn == -1)
4762 if (spe > otmp->spe)
4769 /* set otmp->spe. This may, or may not, use spe... */
4772 if (contents == EMPTY) {
4773 otmp->corpsenm = NON_PM;
4775 } else if (contents == SPINACH) {
4776 otmp->corpsenm = NON_PM;
4782 otmp->spe = wetness;
4790 case HEAVY_IRON_BALL:
4793 /* otmp->cobj already done in mksobj() */
4797 /* 0: delivered in-game via external event (or randomly for fake mail);
4798 1: from bones or wishing; 2: written with marker */
4804 otmp->spe = (rn2(10) ? -1 : 0);
4812 /* set otmp->corpsenm or dragon scale [mail] */
4813 if (mntmp >= LOW_PM) {
4814 if (mntmp == PM_LONG_WORM_TAIL)
4815 mntmp = PM_LONG_WORM;
4819 otmp->spe = 0; /* No spinach */
4820 if (dead_species(mntmp, FALSE)) {
4821 otmp->corpsenm = NON_PM; /* it's empty */
4822 } else if ((!(mons[mntmp].geno & G_UNIQ) || wizard)
4823 && !(mvitals[mntmp].mvflags & G_NOCORPSE)
4824 && mons[mntmp].cnutrit != 0) {
4825 otmp->corpsenm = mntmp;
4829 if ((!(mons[mntmp].geno & G_UNIQ) || wizard)
4830 && !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
4831 if (mons[mntmp].msound == MS_GUARDIAN)
4832 mntmp = genus(mntmp, 1);
4833 set_corpsenm(otmp, mntmp);
4837 mntmp = can_be_hatched(mntmp);
4838 /* this also sets hatch timer if appropriate */
4839 set_corpsenm(otmp, mntmp);
4842 if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4844 && mntmp != PM_MAIL_DAEMON
4847 otmp->corpsenm = mntmp;
4850 otmp->corpsenm = mntmp;
4851 if (Has_contents(otmp) && verysmall(&mons[mntmp]))
4852 delete_contents(otmp); /* no spellbook */
4853 otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
4856 /* Dragon mail - depends on the order of objects & dragons. */
4857 if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON)
4858 otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4863 /* set blessed/cursed -- setting the fields directly is safe
4864 * since weight() is called below and addinv() will take care
4868 } else if (uncursed) {
4870 otmp->cursed = (Luck < 0 && !wizard);
4871 } else if (blessed) {
4872 otmp->blessed = (Luck >= 0 || wizard);
4873 otmp->cursed = (Luck < 0 && !wizard);
4874 } else if (spesgn < 0) {
4878 /* set eroded and erodeproof */
4879 if (erosion_matters(otmp)) {
4880 if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
4881 otmp->oeroded = eroded;
4882 if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
4883 otmp->oeroded2 = eroded2;
4885 * 3.6.1: earlier versions included `&& !eroded && !eroded2' here,
4886 * but damageproof combined with damaged is feasible (eroded
4887 * armor modified by confused reading of cursed destroy armor)
4888 * so don't prevent player from wishing for such a combination.
4890 if (erodeproof && (is_damageable(otmp) || otmp->otyp == CRYSKNIFE))
4891 otmp->oerodeproof = (Luck >= 0 || wizard);
4894 /* set otmp->recharged */
4895 if (oclass == WAND_CLASS) {
4896 /* prevent wishing abuse */
4897 if (otmp->otyp == WAN_WISHING && !wizard)
4899 otmp->recharged = (unsigned) rechrg;
4904 if (is_poisonable(otmp))
4905 otmp->opoisoned = (Luck >= 0);
4906 else if (oclass == FOOD_CLASS)
4907 /* try to taint by making it as old as possible */
4910 /* and [un]trapped */
4912 if (Is_box(otmp) || typ == TIN)
4913 otmp->otrapped = (trapped == 1);
4915 /* empty for containers rather than for tins */
4916 if (contents == EMPTY) {
4917 if (otmp->otyp == BAG_OF_TRICKS || otmp->otyp == HORN_OF_PLENTY) {
4920 } else if (Has_contents(otmp)) {
4921 /* this assumes that artifacts can't be randomly generated
4922 inside containers */
4923 delete_contents(otmp);
4924 otmp->owt = weight(otmp);
4927 /* set locked/unlocked/broken */
4930 otmp->olocked = 1, otmp->obroken = 0;
4931 } else if (unlocked) {
4932 otmp->olocked = 0, otmp->obroken = 0;
4933 } else if (broken) {
4934 otmp->olocked = 0, otmp->obroken = 1;
4941 if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4944 /* set tin variety */
4945 if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4946 set_tin_variety(otmp, tvariety);
4952 /* an artifact name might need capitalization fixing */
4953 aname = artifact_name(name, &objtyp);
4954 if (aname && objtyp == otmp->otyp)
4957 /* 3.6 tribute - fix up novel */
4958 if (otmp->otyp == SPE_NOVEL) {
4959 const char *novelname;
4961 novelname = lookup_novel(name, &otmp->novelidx);
4966 otmp = oname(otmp, name);
4967 /* name==aname => wished for artifact (otmp->oartifact => got it) */
4968 if (otmp->oartifact || name == aname) {
4970 u.uconduct.wisharti++; /* KMH, conduct */
4974 /* more wishing abuse: don't allow wishing for certain artifacts */
4975 /* and make them pay; charge them for the wish anyway! */
4976 if ((is_quest_artifact(otmp)
4977 || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) {
4978 artifact_exists(otmp, safe_oname(otmp), FALSE);
4979 obfree(otmp, (struct obj *) 0);
4980 otmp = (struct obj *) &zeroobj;
4982 pline("For a moment, you feel %s in your %s, but it disappears!",
4984 pline("
\88ê
\8fu%s
\82ª%s
\82Ì
\92\86\82É
\82 \82é
\82æ
\82¤
\82È
\8a´
\82¶
\82ª
\82µ
\82½
\82ª
\81C
\82·
\82®
\82É
\8fÁ
\82¦
\82³
\82Á
\82½
\81I",
4985 something, makeplural(body_part(HAND)));
4989 if (halfeaten && otmp->oclass == FOOD_CLASS) {
4990 if (otmp->otyp == CORPSE)
4991 otmp->oeaten = mons[otmp->corpsenm].cnutrit;
4993 otmp->oeaten = objects[otmp->otyp].oc_nutrition;
4994 /* (do this adjustment before setting up object's weight) */
4995 consume_oeaten(otmp, 1);
4997 otmp->owt = weight(otmp);
4998 if (very && otmp->otyp == HEAVY_IRON_BALL)
4999 otmp->owt += IRON_BALL_W_INCR;
5000 else if (gsize > 1 && otmp->globby)
5001 /* 0: unspecified => small; 1: small => keep default owt of 20;
5002 2: medium => 120; 3: large => 320; 4: very large => 520 */
5003 otmp->owt += 100 + (gsize - 2) * 200;
5009 rnd_class(first, last)
5016 for (i = first; i <= last; i++)
5017 sum += objects[i].oc_prob;
5018 if (!sum) /* all zero */
5019 return first + rn2(last - first + 1);
5021 for (i = first; i <= last; i++)
5022 if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
5027 STATIC_OVL const char *
5028 Japanese_item_name(i)
5031 struct Jitem *j = Japanese_items;
5038 return (const char *) 0;
5042 suit_simple_name(suit)
5045 const char *suitnm, *esuitp;
5048 if (Is_dragon_mail(suit))
5050 return "dragon mail"; /* <color> dragon scale mail */
5052 return "
\97Ø
\8aZ"; /* <color> dragon scale mail */
5054 else if (Is_dragon_scales(suit))
5056 return "dragon scales";
5059 suitnm = OBJ_NAME(objects[suit->otyp]);
5060 esuitp = eos((char *) suitnm);
5062 if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
5063 return "mail"; /* most suits fall into this category */
5065 if (strlen(suitnm) > 2 && !strcmp(esuitp - 2, "
\8aZ"))
5066 return "
\8aZ"; /* most suits fall into this category */
5069 else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
5070 return "jacket"; /* leather jacket */
5073 /* "suit" is lame but "armor" is ambiguous and "body armor" is absurd */
5081 cloak_simple_name(cloak)
5085 switch (cloak->otyp) {
5090 return "
\83\8d\81[
\83u";
5091 case MUMMY_WRAPPING:
5097 return (objects[cloak->otyp].oc_name_known && cloak->dknown)
5101 ? "
\83X
\83\82\83b
\83N"
5105 : "
\83G
\83v
\83\8d\83\93";
5113 return "
\83N
\83\8d\81[
\83N";
5116 /* helm vs hat for messages */
5118 helm_simple_name(helmet)
5122 * There is some wiggle room here; the result has been chosen
5123 * for consistency with the "protected by hard helmet" messages
5124 * given for various bonks on the head: headgear that provides
5125 * such protection is a "helm", that which doesn't is a "hat".
5127 * elven leather helm / leather hat -> hat
5128 * dwarvish iron helm / hard hat -> helm
5129 * The rest are completely straightforward:
5130 * fedora, cornuthaum, dunce cap -> hat
5131 * all other types of helmets -> helm
5134 return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
5136 return (helmet && !is_metallic(helmet)) ? "
\96X
\8eq" : "
\8a\95";
5139 /* gloves vs gauntlets; depends upon discovery state */
5141 gloves_simple_name(gloves)
5144 static const char gauntlets[] = "gauntlets";
5146 if (gloves && gloves->dknown) {
5147 int otyp = gloves->otyp;
5148 struct objclass *ocl = &objects[otyp];
5149 const char *actualn = OBJ_NAME(*ocl),
5150 *descrpn = OBJ_DESCR(*ocl);
5152 if (strstri(objects[otyp].oc_name_known ? actualn : descrpn,
5160 mimic_obj_name(mtmp)
5163 if (M_AP_TYPE(mtmp) == M_AP_OBJECT) {
5164 if (mtmp->mappearance == GOLD_PIECE)
5169 if (mtmp->mappearance != STRANGE_OBJECT)
5170 return simple_typename(mtmp->mappearance);
5173 return "whatcha-may-callit";
5175 return "
\89½
\82Æ
\82©
\82¢
\82¤
\82à
\82Ì";
5179 * Construct a query prompt string, based around an object name, which is
5180 * guaranteed to fit within [QBUFSZ]. Takes an optional prefix, three
5181 * choices for filling in the middle (two object formatting functions and a
5182 * last resort literal which should be very short), and an optional suffix.
5185 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
5186 char *qbuf; /* output buffer */
5187 const char *qprefix, *qsuffix;
5189 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
5193 /* convert size_t (or int for ancient systems) to ordinary unsigned */
5194 unsigned len, lenlimit,
5195 len_qpfx = (unsigned) (qprefix ? strlen(qprefix) : 0),
5196 len_qsfx = (unsigned) (qsuffix ? strlen(qsuffix) : 0),
5197 len_lastR = (unsigned) strlen(lastR);
5199 lenlimit = QBUFSZ - 1;
5200 endp = qbuf + lenlimit;
5201 /* sanity check, aimed mainly at paniclog (it's conceivable for
5202 the result of short_oname() to be shorter than the length of
5203 the last resort string, but we ignore that possibility here) */
5204 if (len_qpfx > lenlimit)
5205 impossible("safe_qbuf: prefix too long (%u characters).", len_qpfx);
5206 else if (len_qpfx + len_qsfx > lenlimit)
5207 impossible("safe_qbuf: suffix too long (%u + %u characters).",
5208 len_qpfx, len_qsfx);
5209 else if (len_qpfx + len_lastR + len_qsfx > lenlimit)
5210 impossible("safe_qbuf: filler too long (%u + %u + %u characters).",
5211 len_qpfx, len_lastR, len_qsfx);
5213 /* the output buffer might be the same as the prefix if caller
5214 has already partially filled it */
5215 if (qbuf == qprefix) {
5216 /* prefix is already in the buffer */
5218 } else if (qprefix) {
5219 /* put prefix into the buffer */
5220 (void) strncpy(qbuf, qprefix, lenlimit);
5223 /* no prefix; output buffer starts out empty */
5226 len = (unsigned) strlen(qbuf);
5228 if (len + len_lastR + len_qsfx > lenlimit) {
5229 /* too long; skip formatting, last resort output is truncated */
5230 if (len < lenlimit) {
5231 (void) strncpy(&qbuf[len], lastR, lenlimit - len);
5233 len = (unsigned) strlen(qbuf);
5234 if (qsuffix && len < lenlimit) {
5235 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
5237 /* len = (unsigned) strlen(qbuf); */
5241 /* suffix and last resort are guaranteed to fit */
5242 len += len_qsfx; /* include the pending suffix */
5243 /* format the object */
5244 bufp = short_oname(obj, func, altfunc, lenlimit - len);
5245 if (len + strlen(bufp) <= lenlimit)
5246 Strcat(qbuf, bufp); /* formatted name fits */
5248 Strcat(qbuf, lastR); /* use last resort */
5252 Strcat(qbuf, qsuffix);
5254 /* assert( strlen(qbuf) < QBUFSZ ); */
5259 globwt(otmp, buf, weightformatted_p)
5262 boolean *weightformatted_p;
5266 Sprintf(buf, "%u aum, ", otmp->owt);
5267 *weightformatted_p = TRUE;
5269 *weightformatted_p = FALSE;