1 /* NetHack 3.6 objnam.c $NHDT-Date: 1447490776 2015/11/14 08:46:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.154 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */
14 #define PREFIX 80 /* (56) */
16 /*
\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*/
22 STATIC_DCL char *FDECL(strprepend, (char *, const char *));
23 STATIC_DCL short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P));
24 STATIC_DCL boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P));
25 STATIC_DCL char *NDECL(nextobuf);
26 STATIC_DCL void FDECL(releaseobuf, (char *));
27 STATIC_DCL char *FDECL(minimal_xname, (struct obj *));
28 STATIC_DCL void FDECL(add_erosion_words, (struct obj *, char *));
30 FDECL(singplur_lookup, (char *, char *, BOOLEAN_P, const char *const *));
31 STATIC_DCL char *FDECL(singplur_compound, (char *));
32 STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned));
34 static char *FDECL(substitute, (char *, char *, char *));
35 static char *FDECL(transpose, (char *buf,char *));
36 static char *FDECL(delete, (char *, char *str));
37 static int FDECL(digit_8, (int));
38 static int FDECL(atoi_8, (const char *));
46 #define BSTRCMPI(base, ptr, str) ((ptr) < base || strcmpi((ptr), str))
47 #define BSTRNCMPI(base, ptr, str, num) \
48 ((ptr) < base || strncmpi((ptr), str, num))
49 #define Strcasecpy(dst, src) (void) strcasecpy(dst, src)
51 /* true for gems/rocks that should have " stone" appended to their names */
52 #define GemStone(typ) \
54 || (objects[typ].oc_material == GEMSTONE \
55 && (typ != DILITHIUM_CRYSTAL && typ != RUBY && typ != DIAMOND \
56 && typ != SAPPHIRE && typ != BLACK_OPAL && typ != EMERALD \
60 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "wakizashi" },
61 { BROADSWORD, "ninja-to" },
62 { FLAIL, "nunchaku" },
63 { GLAIVE, "naginata" },
64 { LOCK_PICK, "osaku" },
65 { WOODEN_HARP, "koto" },
67 { PLATE_MAIL, "tanko" },
69 { LEATHER_GLOVES, "yugake" },
70 { FOOD_RATION, "gunyoki" },
71 { POT_BOOZE, "sake" },
74 STATIC_OVL struct Jitem Japanese_items[] = { { SHORT_SWORD, "
\98e
\8d·
\82µ" },
75 { BROADSWORD, "
\94E
\8eÒ
\93\81" },
76 { FLAIL, "
\83k
\83\93\83`
\83\83\83N" },
77 { GLAIVE, "
\82È
\82¬
\82È
\82½" },
78 { LOCK_PICK, "
\82¨
\82³
\82" },
79 { WOODEN_HARP, "
\8bÕ" },
80 { KNIFE, "
\8eh
\93\81" },
81 { PLATE_MAIL, "
\92Z
\8db" },
83 { LEATHER_GLOVES, "
\8b|
\8c\9c" },
84 { FOOD_RATION, "
\8aÛ
\96ò" },
85 { POT_BOOZE, "
\8eð" },
89 STATIC_DCL const char *FDECL(Japanese_item_name, (int i));
94 register const char *pref;
96 register int i = (int) strlen(pref);
99 impossible("PREFIX too short (for %d).", i);
103 (void) strncpy(s, pref, i); /* do not copy trailing 0 */
107 /* manage a pool of BUFSZ buffers, so callers don't have to */
108 static char NEARDATA obufs[NUMOBUF][BUFSZ];
109 static int obufidx = 0;
114 obufidx = (obufidx + 1) % NUMOBUF;
115 return obufs[obufidx];
118 /* put the most recently allocated buffer back if possible */
123 /* caller may not know whether bufp is the most recently allocated
124 buffer; if it isn't, do nothing */
125 if (bufp == obufs[obufidx])
126 obufidx = (obufidx - 1 + NUMOBUF) % NUMOBUF;
133 char *buf = nextobuf();
134 register struct objclass *ocl = &objects[otyp];
135 register const char *actualn = OBJ_NAME(*ocl);
136 register const char *dn = OBJ_DESCR(*ocl);
137 register const char *un = ocl->oc_uname;
138 register int nn = ocl->oc_name_known;
140 if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
141 actualn = Japanese_item_name(otyp);
144 Sprintf(buf, "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é", un);
146 switch (ocl->oc_class) {
151 Strcat(buf, "
\8bà
\89Ý");
155 Strcpy(buf, "potion");
161 Strcpy(buf, "scroll");
163 Strcat(buf, "
\8aª
\95¨");
173 Strcpy(buf, "spellbook");
175 Strcat(buf, "
\96\82\96@
\8f\91");
181 Strcat(buf, "
\8ew
\97Ö");
186 Strcpy(buf, actualn);
188 Strcpy(buf, "amulet");
190 Sprintf(eos(buf), " called %s", un);
192 Sprintf(eos(buf), " (%s)", dn);
196 Strcat(buf, actualn);
198 Strcat(buf, "
\96\82\8f\9c\82¯");
204 Strcat(buf, actualn);
206 Strcat(buf, "
\95ó
\90Î");
212 Strcpy(buf, actualn);
214 Strcat(buf, " stone");
216 Sprintf(eos(buf), " called %s", un);
218 Sprintf(eos(buf), " (%s)", dn);
220 Strcat(buf, actualn);
224 Strcpy(buf, dn ? dn : actualn);
225 if (ocl->oc_class == GEM_CLASS)
227 (ocl->oc_material == MINERAL) ? " stone" : " gem");
229 Sprintf(eos(buf), " called %s", un);
231 Strcat(buf, dn ? dn : actualn);
240 /* here for ring/scroll/potion/wand */
244 Strcpy(buf, actualn); /* avoid spellbook of Book of the Dead */
246 Sprintf(eos(buf), " of %s", actualn);
248 Strcpy(buf, actualn);
253 Sprintf(eos(buf), " called %s", un);
257 Sprintf(eos(buf), " (%s)", dn);
259 Sprintf(eos(buf), "(%s)", dn);
264 /* less verbose result than obj_typename(); either the actual name
265 or the description (but not both); user-assigned name is ignored */
267 simple_typename(otyp)
270 char *bufp, *pp, *save_uname = objects[otyp].oc_uname;
272 objects[otyp].oc_uname = 0; /* suppress any name given by user */
273 bufp = obj_typename(otyp);
274 objects[otyp].oc_uname = save_uname;
275 if ((pp = strstri(bufp, " (")) != 0)
276 *pp = '\0'; /* strip the appended description */
284 if (!obj->oartifact || !has_oname(obj))
286 if (!program_state.gameover && !iflags.override_ID) {
287 if (not_fully_identified(obj))
293 /* Give the name of an object seen at a distance. Unlike xname/doname,
294 * we don't want to set dknown if it's not set already. The kludge used is
295 * to temporarily set Blind so that xname() skips the dknown setting. This
296 * assumes that we don't want to do this too often; if this function becomes
297 * frequently used, it'd probably be better to pass a parameter to xname()
298 * or doname() instead.
301 distant_name(obj, func)
303 char *FDECL((*func), (OBJ_P));
307 long save_Blinded = Blinded;
310 Blinded = save_Blinded;
314 /* convert player specified fruit name into corresponding fruit juice name
315 ("slice of pizza" -> "pizza juice" rather than "slice of pizza juice") */
318 boolean juice; /* whether or not to append " juice" to the name */
320 #if 1 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\82»
\82±
\82Ü
\82Å
\82µ
\82È
\82¢*/
321 char *buf = nextobuf();
322 Sprintf(buf, "%s%s", pl_fruit, juice ? "
\83W
\83\85\81[
\83X" : "");
325 char *buf = nextobuf();
326 const char *fruit_nam = strstri(pl_fruit, " of ");
329 fruit_nam += 4; /* skip past " of " */
331 fruit_nam = pl_fruit; /* use it as is */
333 Sprintf(buf, "%s%s", makesingular(fruit_nam), juice ? " juice" : "");
342 return xname_flags(obj, CXN_NORMAL);
346 xname_flags(obj, cxn_flags)
347 register struct obj *obj;
348 unsigned cxn_flags; /* bitmask of CXN_xxx values */
351 register int typ = obj->otyp;
352 register struct objclass *ocl = &objects[typ];
353 int nn = ocl->oc_name_known, omndx = obj->corpsenm;
354 const char *actualn = OBJ_NAME(*ocl);
355 const char *dn = OBJ_DESCR(*ocl);
356 const char *un = ocl->oc_uname;
357 boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
358 boolean known, dknown, bknown;
360 buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
361 if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
362 actualn = Japanese_item_name(typ);
366 * clean up known when it's tied to oc_name_known, eg after AD_DRIN
367 * This is only required for unique objects since the article
368 * printed for the object is tied to the combination of the two
369 * and printing the wrong article gives away information.
371 if (!nn && ocl->oc_uses_known && ocl->oc_unique)
375 if (Role_if(PM_PRIEST))
378 if (iflags.override_ID) {
379 known = dknown = bknown = TRUE;
383 dknown = obj->dknown;
384 bknown = obj->bknown;
387 if (obj_is_pname(obj))
392 Strcat(buf, ONAME(obj));
397 if (has_oname(obj) && dknown) {
398 Strcat(buf, ONAME(obj));
399 Strcat(buf, "
\82Æ
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½");
402 switch (obj->oclass) {
406 Strcpy(buf, "amulet");
408 Strcat(buf, "
\96\82\8f\9c\82¯");
409 else if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
410 /* each must be identified individually */
411 Strcpy(buf, known ? actualn : dn);
413 Strcpy(buf, actualn);
416 Sprintf(buf, "amulet called %s", un);
418 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\8f\9c\82¯", un);
421 Sprintf(buf, "%s amulet", dn);
423 Sprintf(eos(buf), "%s", dn);
426 if (is_poisonable(obj) && obj->opoisoned)
428 Strcpy(buf, "poisoned ");
430 Strcpy(buf, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
435 Sprintf(eos(buf), "%s
\82Ì", mons[obj->corpsenm].mname);
439 Strcpy(buf, "pair of ");
441 Strcpy(buf, "
\88ê
\91Î
\82Ì");
442 else if (is_wet_towel(obj))
444 Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
446 Strcpy(buf, (obj->spe < 3) ? "
\8e¼
\82Á
\82½" : "
\94G
\82ê
\82½");
449 Strcat(buf, dn ? dn : actualn);
451 Strcat(buf, actualn);
454 Strcat(buf, dn ? dn : actualn);
455 Strcat(buf, " called ");
459 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é");
460 Strcat(buf, dn ? dn : actualn);
463 Strcat(buf, dn ? dn : actualn);
464 #if 0 /*JP*/ /*
\82±
\82ê
\82Í
\8cê
\8f\87\82Ì
\8aÖ
\8cW
\82©
\82ç
\8fã
\82Ì
\95û
\82Å
\92è
\8b`*/
465 /* If we use an() here we'd have to remember never to use */
466 /* it whenever calling doname() or xname(). */
467 if (typ == FIGURINE && omndx != NON_PM) {
468 Sprintf(eos(buf), " of a%s %s",
469 index(vowels, *mons[omndx].mname) ? "n" : "",
471 } else if (is_wet_towel(obj)) {
473 if (is_wet_towel(obj)) {
476 Sprintf(eos(buf), " (%d)", obj->spe);
480 /* depends on order of the dragon scales objects */
481 if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
483 Sprintf(buf, "set of %s", actualn);
485 Sprintf(buf, "%s
\88ê
\8e®", actualn);
488 if (is_boots(obj) || is_gloves(obj))
490 Strcpy(buf, "pair of ");
492 Strcat(buf,"
\88ê
\91Î
\82Ì");
494 if (obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
497 Strcpy(buf, "shield");
499 Strcat(buf, "
\8f\82");
502 if (obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
504 Strcpy(buf, "smooth shield");
506 Strcat(buf, "
\82·
\82×
\82·
\82×
\82µ
\82½
\8f\82");
511 Strcat(buf, actualn);
515 Strcat(buf, "boots");
516 else if (is_gloves(obj))
517 Strcat(buf, "gloves");
518 else if (is_cloak(obj))
519 Strcpy(buf, "cloak");
520 else if (is_helmet(obj))
521 Strcpy(buf, "helmet");
522 else if (is_shield(obj))
523 Strcpy(buf, "shield");
525 Strcpy(buf, "armor");
526 Strcat(buf, " called ");
532 else if (is_gloves(obj))
534 else if (is_cloak(obj))
535 p = "
\83N
\83\8d\81[
\83N";
536 else if (is_helmet(obj))
538 else if (is_shield(obj))
542 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, p);
548 if (typ == SLIME_MOLD) {
549 register struct fruit *f;
551 for (f = ffruit; f; f = f->nextf) {
552 if (f->fid == obj->spe) {
553 Strcpy(buf, f->fname);
558 impossible("Bad fruit #%d?", obj->spe);
559 Strcpy(buf, "fruit");
560 } else if (pluralize) {
561 /* ick; already pluralized fruit names
562 are allowed--we want to try to avoid
563 adding a redundant plural suffix */
564 Strcpy(buf, makeplural(makesingular(buf)));
569 if (Is_pudding(obj)) {
580 ? "
\82Æ
\82Ä
\82à
\91å
\82«
\82¢"
592 Strcpy(buf, actualn);
593 if (typ == TIN && known)
594 tin_details(obj, omndx, buf);
596 if (typ == TIN && known)
597 /*JP
\81u
\81`
\82Ì
\93÷
\82Ì
\81v*/
598 tin_details(obj, omndx, buf);
599 Strcat(buf, actualn);
605 Strcpy(buf, actualn);
607 Strcat(buf, actualn);
611 if (typ == STATUE && omndx != NON_PM)
613 Sprintf(buf, "%s%s of %s%s",
614 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
618 type_is_pname(&mons[omndx])
620 : the_unique_pm(&mons[omndx])
622 : index(vowels, *mons[omndx].mname)
627 Sprintf(eos(buf), "%s%s
\82Ì%s",
628 (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
631 mons[obj->corpsenm].mname, actualn);
635 Strcpy(buf, actualn);
637 Strcat(buf, actualn);
642 Sprintf(buf, "%sheavy iron ball",
643 (obj->owt > ocl->oc_weight) ? "very " : "");
645 Sprintf(eos(buf), "%s
\8fd
\82¢
\93S
\8b\85",
646 (obj->owt > ocl->oc_weight) ? "
\82Æ
\82Ä
\82à" : "");
650 if (dknown && obj->odiluted)
652 Strcpy(buf, "diluted ");
654 Strcat(buf, "
\94\96\82Ü
\82Á
\82½");
655 if (nn || un || !dknown) {
657 Strcat(buf, "potion");
670 if (typ == POT_WATER && bknown
671 && (obj->blessed || obj->cursed)) {
673 Strcat(buf, obj->blessed ? "holy " : "unholy ");
675 Strcat(buf, obj->blessed ? "
\90¹" : "
\95s
\8fò
\82È");
677 Strcat(buf, actualn);
680 Strcat(buf, " called ");
684 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96ò");
689 #if 0 /*JP*//*
\95s
\8am
\92è
\96¼
\82É
\81u
\96ò
\81v
\82Í
\95t
\82¢
\82Ä
\82¢
\82é*/
690 Strcat(buf, " potion");
696 Strcpy(buf, "scroll");
701 Strcat(buf,"
\8aª
\95¨");
709 Strcat(buf, actualn);
712 Strcat(buf, " called ");
716 Strcat(buf, "
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8aª
\95¨");
718 } else if (ocl->oc_magic) {
720 Strcat(buf, " labeled ");
726 Strcat(buf, " scroll");
740 Sprintf(buf, "wand of %s", actualn);
742 Strcat(buf, actualn);
745 Sprintf(buf, "wand called %s", un);
747 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8fñ", un);
750 Sprintf(buf, "%s wand", dn);
755 if (typ == SPE_NOVEL) { /* 3.6 tribute */
759 Strcpy(buf, actualn);
761 Sprintf(buf, "novel called %s", un);
763 Sprintf(buf, "%s book", dn);
766 } else if (!dknown) {
768 Strcpy(buf, "spellbook");
770 Strcat(buf, "
\96\82\96@
\8f\91");
773 if (typ != SPE_BOOK_OF_THE_DEAD)
774 Strcpy(buf, "spellbook of ");
776 Strcat(buf, actualn);
779 Sprintf(buf, "spellbook called %s", un);
781 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\96\82\96@
\8f\91", un);
784 Sprintf(buf, "%s spellbook", dn);
786 Sprintf(eos(buf), "%s", dn);
793 Strcat(buf, "
\8ew
\97Ö");
796 Sprintf(buf, "ring of %s", actualn);
798 Strcat(buf, actualn);
801 Sprintf(buf, "ring called %s", un);
803 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é
\8ew
\97Ö", un);
806 Sprintf(buf, "%s ring", dn);
812 const char *rock = (ocl->oc_material == MINERAL) ? "stone" : "gem";
814 const char *rock = (ocl->oc_material == MINERAL) ? "
\90Î" : "
\95ó
\90Î";
825 Sprintf(buf, "%s called %s", rock, un);
827 Sprintf(eos(buf), "%s
\82Æ
\8cÄ
\82Î
\82ê
\82é%s", un, rock);
830 Sprintf(buf, "%s %s", dn, rock);
834 Strcpy(buf, actualn);
837 Strcat(buf, " stone");
843 Sprintf(buf, "glorkum %d %d %d", obj->oclass, typ, obj->spe);
847 Strcpy(buf, makeplural(buf));
850 if (obj->otyp == T_SHIRT && program_state.gameover) {
854 Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf));
856 Sprintf(eos(buf), "(
\81u%s
\81v
\82Æ
\8f\91\82¢
\82Ä
\82 \82é)", tshirt_text(obj, tmpbuf));
860 if (has_oname(obj) && dknown) {
861 Strcat(buf, " named ");
863 Strcat(buf, ONAME(obj));
866 if (!strncmpi(buf, "the ", 4))
874 /* similar to simple_typename but minimal_xname operates on a particular
875 object rather than its general type; it formats the most basic info:
876 potion -- if description not known
877 brown potion -- if oc_name_known not set
878 potion of object detection -- if discovered
886 struct objclass saveobcls;
887 int otyp = obj->otyp;
889 /* suppress user-supplied name */
890 saveobcls.oc_uname = objects[otyp].oc_uname;
891 objects[otyp].oc_uname = 0;
892 /* suppress actual name if object's description is unknown */
893 saveobcls.oc_name_known = objects[otyp].oc_name_known;
895 objects[otyp].oc_name_known = 0;
897 /* caveat: this makes a lot of assumptions about which fields
898 are required in order for xname() to yield a sensible result */
901 bareobj.oclass = obj->oclass;
902 bareobj.dknown = obj->dknown;
903 /* suppress known except for amulets (needed for fakes and real A-of-Y) */
904 bareobj.known = (obj->oclass == AMULET_CLASS)
906 /* default is "on" for types which don't use it */
907 : !objects[otyp].oc_uses_known;
908 bareobj.quan = 1L; /* don't want plural */
909 bareobj.corpsenm = NON_PM; /* suppress statue and figurine details */
910 /* but suppressing fruit details leads to "bad fruit #0"
911 [perhaps we should force "slime mold" rather than use xname?] */
912 if (obj->otyp == SLIME_MOLD)
913 bareobj.spe = obj->spe;
915 bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
917 if (!strncmp(bufp, "uncursed ", 9))
918 bufp += 9; /* Role_if(PM_PRIEST) */
920 if (!strncmp(bufp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", 14))
921 bufp += 14; /* Role_if(PM_PRIEST) */
924 objects[otyp].oc_uname = saveobcls.oc_uname;
925 objects[otyp].oc_name_known = saveobcls.oc_name_known;
929 /* xname() output augmented for multishot missile feedback */
935 char *onm = xname(obj);
937 if (m_shot.n > 1 && m_shot.o == obj->otyp) {
938 /* "the Nth arrow"; value will eventually be passed to an() or
939 The(), both of which correctly handle this "the " prefix */
941 Sprintf(tmpbuf, "the %d%s ", m_shot.i, ordin(m_shot.i));
943 Sprintf(tmpbuf, "%d%s
\96Ú
\82Ì", m_shot.i, numeral(obj));
944 onm = strprepend(onm, tmpbuf);
949 /* used for naming "the unique_item" instead of "a unique_item" */
955 boolean known = (obj->known || iflags.override_ID);
957 if (!obj->dknown && !iflags.override_ID)
959 else if (obj->otyp == FAKE_AMULET_OF_YENDOR && !known)
960 return TRUE; /* lie */
962 return (boolean) (objects[obj->otyp].oc_unique
963 && (known || obj->otyp == AMULET_OF_YENDOR));
969 /* should monster type be prefixed with "the"? (mostly used for corpses) */
972 struct permonst *ptr;
976 /* even though monsters with personal names are unique, we want to
977 describe them as "Name" rather than "the Name" */
978 if (type_is_pname(ptr))
981 uniq = (ptr->geno & G_UNIQ) ? TRUE : FALSE;
982 /* high priest is unique if it includes "of <deity>", otherwise not
983 (caller needs to handle the 1st possibility; we assume the 2nd);
984 worm tail should be irrelevant but is included for completeness */
985 if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
987 /* Wizard no longer needs this; he's flagged as unique these days */
988 if (ptr == &mons[PM_WIZARD_OF_YENDOR])
994 add_erosion_words(obj, prefix)
998 boolean iscrys = (obj->otyp == CRYSKNIFE);
1001 rknown = (iflags.override_ID == 0) ? obj->rknown : TRUE;
1003 if (!is_damageable(obj) && !iscrys)
1006 /* The only cases where any of these bits do double duty are for
1007 * rotted food and diluted potions, which are all not is_damageable().
1009 if (obj->oeroded && !iscrys) {
1010 switch (obj->oeroded) {
1013 Strcat(prefix, "very ");
1015 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1019 Strcat(prefix, "thoroughly ");
1021 Strcat(prefix, "
\82©
\82È
\82è");
1025 Strcat(prefix, is_rustprone(obj) ? "rusty " : "burnt ");
1027 Strcat(prefix, is_rustprone(obj) ? "
\8eK
\82Ñ
\82½" : "
\8f\9d\82Â
\82¢
\82½");
1029 if (obj->oeroded2 && !iscrys) {
1030 switch (obj->oeroded2) {
1033 Strcat(prefix, "very ");
1035 Strcat(prefix, "
\82Æ
\82Ä
\82à");
1039 Strcat(prefix, "thoroughly ");
1041 Strcat(prefix, "
\82©
\82È
\82è");
1045 Strcat(prefix, is_corrodeable(obj) ? "corroded " : "rotted ");
1047 Strcat(prefix, is_corrodeable(obj) ? "
\95\85\90H
\82µ
\82½" : "
\95\85\82Á
\82½");
1049 if (rknown && obj->oerodeproof)
1050 Strcat(prefix, iscrys
1054 ? "
\88À
\92è
\82µ
\82½"
1059 ? "
\8eK
\82Ñ
\82È
\82¢"
1060 : is_corrodeable(obj)
1062 ? "corrodeproof " /* "stainless"? */
1064 ? "
\95\85\90H
\82µ
\82È
\82¢" /* "stainless"? */
1070 ? "
\94R
\82¦
\82È
\82¢"
1075 doname_base(obj, with_price)
1076 register struct obj *obj;
1079 boolean ispoisoned = FALSE;
1080 boolean known, cknown, bknown, lknown;
1081 int omndx = obj->corpsenm;
1082 char prefix[PREFIX];
1084 char tmpbuf[PREFIX + 1]; /* for when we have to add something at
1085 the start of prefix instead of the
1086 end (Strcat is used on the end) */
1088 register char *bp = xname(obj);
1089 #if 1 /*JP*//*
\8f\87\8f\98\93ü
\82ê
\91Ö
\82¦
\82É
\8eg
\82¤*/
1090 char preprefix[PREFIX];
1093 if (iflags.override_ID) {
1094 known = cknown = bknown = lknown = TRUE;
1097 cknown = obj->cknown;
1098 bknown = obj->bknown;
1099 lknown = obj->lknown;
1102 /* When using xname, we want "poisoned arrow", and when using
1103 * doname, we want "poisoned +0 arrow". This kludge is about the only
1104 * way to do it, at least until someone overhauls xname() and doname(),
1105 * combining both into one function taking a parameter.
1107 /* must check opoisoned--someone can have a weirdly-named fruit */
1109 if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
1114 if (!strncmp(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", 12) && obj->opoisoned) {
1121 *
\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
1122 *
\82Ì
\82Ù
\82¤
\82ª
\8e©
\91R
\82Å
\82 \82é
\81D
1126 preprefix[0] = '\0';
1127 if((tp = strstri(bp, "
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½")) != NULL){
1128 tp += 12; /*
\81u
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\81v*/
1129 strncpy(preprefix, bp, tp - bp);
1130 preprefix[tp - bp] = '\0';
1137 if (obj->quan != 1L) {
1139 Sprintf(prefix, "%ld ", obj->quan);
1140 #else /*
\93ú
\96{
\8cê
\82Æ
\82µ
\82Ä
\82Í
\90\94\8e\8c\82ª
\82È
\82¢
\82Ì
\82Í
\95s
\8e©
\91R */
1141 Sprintf(prefix, "%ld%s
\82Ì", obj->quan, numeral(obj));
1143 } else if (obj->otyp == CORPSE) {
1144 /* skip article prefix for corpses [else corpse_xname()
1145 would have to be taught how to strip it off again] */
1147 #if 0 /*JP*/ /*
\8a¥
\8e\8c\82Í
\95s
\97v */
1148 } else if (obj_is_pname(obj) || the_unique_obj(obj)) {
1149 if (!strncmpi(bp, "the ", 4))
1151 Strcpy(prefix, "the ");
1153 Strcpy(prefix, "a ");
1154 #else /*prefix
\82Ì
\8f\89\8aú
\89»*/
1160 /* "empty" goes at the beginning, but item count goes at the end */
1162 /* bag of tricks: include "empty" prefix if it's known to
1163 be empty but its precise number of charges isn't known
1164 (when that is known, suffix of "(n:0)" will be appended,
1165 making the prefix be redundant; note that 'known' flag
1166 isn't set when emptiness gets discovered because then
1167 charging magic would yield known number of new charges) */
1168 && (obj->otyp == BAG_OF_TRICKS
1169 ? (obj->spe == 0 && !obj->known)
1170 /* not bag of tricks: empty if container which has no contents */
1171 : (Is_container(obj) || obj->otyp == STATUE)
1172 && !Has_contents(obj)))
1174 Strcat(prefix, "empty ");
1176 Strcat(prefix, "
\8bó
\82Ì");
1178 if (bknown && obj->oclass != COIN_CLASS
1179 && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
1180 || (!obj->cursed && !obj->blessed))) {
1181 /* allow 'blessed clear potion' if we don't know it's holy water;
1182 * always allow "uncursed potion of water"
1186 Strcat(prefix, "cursed ");
1188 Strcat(prefix, "
\8eô
\82í
\82ê
\82½");
1189 else if (obj->blessed)
1191 Strcat(prefix, "blessed ");
1193 Strcat(prefix, "
\8fj
\95\9f\82³
\82ê
\82½");
1194 else if (!iflags.implicit_uncursed
1195 /* For most items with charges or +/-, if you know how many
1196 * charges are left or what the +/- is, then you must have
1197 * totally identified the item, so "uncursed" is unnecessary,
1198 * because an identified object not described as "blessed" or
1199 * "cursed" must be uncursed.
1201 * If the charges or +/- is not known, "uncursed" must be
1202 * printed to avoid ambiguity between an item whose curse
1203 * status is unknown, and an item known to be uncursed.
1205 || ((!known || !objects[obj->otyp].oc_charged
1206 || obj->oclass == ARMOR_CLASS
1207 || obj->oclass == RING_CLASS)
1209 && obj->otyp != SCR_MAIL
1211 && obj->otyp != FAKE_AMULET_OF_YENDOR
1212 && obj->otyp != AMULET_OF_YENDOR
1213 && !Role_if(PM_PRIEST)))
1215 Strcat(prefix, "uncursed ");
1217 Strcat(prefix, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢");
1220 if (lknown && Is_box(obj)) {
1223 Strcat(prefix, "unlockable ");
1225 Strcat(prefix, "
\8c®
\82Ì
\89ó
\82ê
\82½");
1226 else if (obj->olocked)
1228 Strcat(prefix, "locked ");
1230 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½");
1233 Strcat(prefix, "unlocked ");
1235 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢");
1240 Strcat(prefix, "greased ");
1242 Strcat(prefix, "
\96û
\82Ì
\93h
\82ç
\82ê
\82½");
1244 if (cknown && Has_contents(obj)) {
1245 /* we count all objects (obj->quantity); perhaps we should
1246 count separate stacks instead (or even introduce a user
1247 preference option to choose between the two alternatives)
1248 since it's somewhat odd so see "containing 1002 items"
1249 when there are 2 scrolls plus 1000 gold pieces */
1250 long itemcount = count_contents(obj, FALSE, FALSE, TRUE);
1253 Sprintf(eos(bp), " containing %ld item%s", itemcount,
1256 Sprintf(eos(bp), "(%ld
\8cÂ
\93ü
\82Á
\82Ä
\82¢
\82é)", itemcount);
1260 switch (obj->oclass) {
1262 if (obj->owornmask & W_AMUL)
1264 Strcat(bp, " (being worn)");
1266 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1271 Strcat(prefix, "poisoned ");
1273 Strcat(prefix, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
1275 add_erosion_words(obj, prefix);
1277 Strcat(prefix, sitoa(obj->spe));
1278 Strcat(prefix, " ");
1282 if (obj->owornmask & W_ARMOR)
1284 Strcat(bp, (obj == uskin) ? " (embedded in your skin)"
1286 Strcat(bp, (obj == uskin) ? "(
\94§
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é)"
1290 : "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1293 /* weptools already get this done when we go to the +n code */
1294 if (!is_weptool(obj))
1295 add_erosion_words(obj, prefix);
1296 if (obj->owornmask & (W_TOOL /* blindfold */ | W_SADDLE)) {
1298 Strcat(bp, " (being worn)");
1300 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1303 if (obj->otyp == LEASH && obj->leashmon != 0) {
1305 Strcat(bp, " (in use)");
1307 Strcat(bp, "(
\8c\8b\82Ñ
\82Â
\82¯
\82Ä
\82¢
\82é)");
1310 if (is_weptool(obj))
1312 if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1315 Strcpy(tmpbuf, "no");
1317 Sprintf(tmpbuf, "%d", obj->spe);
1318 Sprintf(eos(bp), " (%s candle%s%s)", tmpbuf, plur(obj->spe),
1319 !obj->lamplit ? " attached" : ", lit");
1322 Sprintf(eos(bp), "(
\88ê
\96{
\82à
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢)");
1325 Sprintf(eos(bp), "(%d
\96{
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)", obj->spe);
1327 Sprintf(eos(bp), "(%d
\96{
\8cõ
\82Á
\82Ä
\82¢
\82é)", obj->spe);
1331 } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
1332 || obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
1334 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
1336 Strcat(prefix, "partly used ");
1338 Strcat(prefix, "
\8eg
\82¢
\82³
\82µ
\82Ì");
1341 Strcat(bp, " (lit)");
1343 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1346 if (objects[obj->otyp].oc_charged)
1350 add_erosion_words(obj, prefix);
1354 Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe);
1356 Sprintf(eos(bp), "(%d:%d)", (int) obj->recharged, obj->spe);
1359 if (obj->otyp == POT_OIL && obj->lamplit)
1361 Strcat(bp, " (lit)");
1363 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1366 add_erosion_words(obj, prefix);
1368 if (obj->owornmask & W_RINGR)
1370 Strcat(bp, " (on right ");
1372 Strcat(bp, "(
\89E");
1373 if (obj->owornmask & W_RINGL)
1375 Strcat(bp, " (on left ");
1377 Strcat(bp, "(
\8d¶");
1378 if (obj->owornmask & W_RING) {
1379 Strcat(bp, body_part(HAND));
1382 if (known && objects[obj->otyp].oc_charged) {
1384 Strcat(prefix, " ");
1386 Strcat(prefix, sitoa(obj->spe));
1387 Strcat(prefix, " ");
1393 Strcat(prefix, "partly eaten ");
1395 Strcat(prefix, "
\90H
\82×
\82©
\82¯
\82Ì");
1396 if (obj->otyp == CORPSE) {
1398 Sprintf(prefix, "%s ",
1399 corpse_xname(obj, prefix, CXN_ARTICLE | CXN_NOCORPSE));
1401 Sprintf(prefix, "%s
\82Ì",
1402 corpse_xname(obj, prefix, CXN_ARTICLE | CXN_NOCORPSE));
1404 } else if (obj->otyp == EGG) {
1405 #if 0 /* corpses don't tell if they're stale either */
1406 if (known && stale_egg(obj))
1407 Strcat(prefix, "stale ");
1410 && (known || (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
1412 Strcat(prefix, mons[omndx].mname);
1413 Strcat(prefix, " ");
1415 Strcat(prefix, mons[omndx].mname);
1416 Strcat(prefix, "
\82Ì");
1420 Strcat(bp, " (laid by you)");
1422 Strcat(bp, "(
\82 \82È
\82½
\82ª
\8eY
\82ñ
\82¾)");
1425 if (obj->otyp == MEAT_RING)
1430 add_erosion_words(obj, prefix);
1431 if (obj->owornmask & W_BALL)
1433 Strcat(bp, " (chained to you)");
1435 Strcat(bp, "(
\82 \82È
\82½
\82É
\8cq
\82ª
\82ê
\82Ä
\82¢
\82é)");
1439 if ((obj->owornmask & W_WEP) && !mrg_to_wielded) {
1440 if (obj->quan != 1L) {
1442 Strcat(bp, " (wielded)");
1444 Strcat(bp, "(
\91\95\94õ
\82µ
\82Ä
\82¢
\82é)");
1446 const char *hand_s = body_part(HAND);
1449 hand_s = makeplural(hand_s);
1451 Sprintf(eos(bp), " (weapon in %s)", hand_s);
1453 Sprintf(eos(bp), "(%s
\82É
\82µ
\82Ä
\82¢
\82é)", hand_s);
1455 if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
1456 /* presumably can be felt when blind */
1458 Strcat(bp, " (glowing");
1460 Sprintf(eos(bp), " %s", glow_color(obj->oartifact));
1464 Strcat(bp, " (
\94M
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82é)");
1466 Sprintf(eos(bp), " (%s
\8bP
\82¢
\82Ä
\82¢
\82é)",
1467 glow_color(obj->oartifact));
1472 if (obj->owornmask & W_SWAPWEP) {
1475 Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND));
1477 Sprintf(eos(bp), "(
\8d¶%s
\82É
\82µ
\82Ä
\82¢
\82é)", body_part(HAND));
1480 Strcat(bp, " (alternate weapon; not wielded)");
1482 Strcat(bp, "(
\97\
\94õ
\82Ì
\95\90\8aí;
\91\95\94õ
\82µ
\82Ä
\82¢
\82È
\82¢)");
1484 if (obj->owornmask & W_QUIVER) {
1485 switch (obj->oclass) {
1488 if (objects[obj->otyp].oc_skill == -P_BOW) {
1489 /* Ammo for a bow */
1491 Strcat(bp, " (in quiver)");
1493 Strcat(bp, "(
\96î
\93\9b\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1496 /* Ammo not for a bow */
1498 Strcat(bp, " (in quiver pouch)");
1500 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1504 /* Weapons not considered ammo */
1506 Strcat(bp, " (at the ready)");
1508 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1511 /* Small things and ammo not for a bow */
1518 Strcat(bp, " (in quiver pouch)");
1520 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1522 default: /* odd things */
1524 Strcat(bp, " (at the ready)");
1526 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1529 if (!iflags.suppress_price && is_unpaid(obj)) {
1530 long quotedprice = unpaid_cost(obj, TRUE);
1532 Sprintf(eos(bp), " (%s, %ld %s)",
1533 obj->unpaid ? "unpaid" : "contents",
1534 quotedprice, currency(quotedprice));
1535 } else if (with_price) {
1536 long price = get_cost_of_shop_item(obj);
1539 Sprintf(eos(bp), " (%ld %s)", price, currency(price));
1541 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1542 if (!strncmp(prefix, "a ", 2)
1543 && index(vowels, *(prefix + 2) ? *(prefix + 2) : *bp)
1545 || (strncmp(bp, "uranium", 7) && strncmp(bp, "unicorn", 7)
1546 && strncmp(bp, "eucalyptus", 10)))) {
1547 Strcpy(tmpbuf, prefix);
1548 Strcpy(prefix, "an ");
1549 Strcpy(prefix + 3, tmpbuf + 2);
1553 /* show weight for items (debug tourist info)
1554 * aum is stolen from Crawl's "Arbitrary Unit of Measure" */
1556 Sprintf(eos(bp), " (%d aum)", obj->owt);
1559 bp = strprepend(bp, prefix);
1560 #else /*JP:
\81u
\96¼
\95t
\82¯
\82ç
\82ê
\82½
\81v
\82ð
\96ß
\82·*/
1561 Strcat(preprefix, prefix);
1562 bp = strprepend(bp, preprefix);
1569 register struct obj *obj;
1571 return doname_base(obj, FALSE);
1574 /* Name of object including price. */
1576 doname_with_price(obj)
1577 register struct obj *obj;
1579 return doname_base(obj, TRUE);
1582 /* used from invent.c */
1584 not_fully_identified(otmp)
1585 register struct obj *otmp;
1587 /* gold doesn't have any interesting attributes [yet?] */
1588 if (otmp->oclass == COIN_CLASS)
1589 return FALSE; /* always fully ID'd */
1590 /* check fundamental ID hallmarks first */
1591 if (!otmp->known || !otmp->dknown
1593 || (!otmp->bknown && otmp->otyp != SCR_MAIL)
1597 || !objects[otmp->otyp].oc_name_known)
1599 if ((!otmp->cknown && (Is_container(otmp) || otmp->otyp == STATUE))
1600 || (!otmp->lknown && Is_box(otmp)))
1602 if (otmp->oartifact && undiscovered_artifact(otmp->oartifact))
1604 /* otmp->rknown is the only item of interest if we reach here */
1606 * Note: if a revision ever allows scrolls to become fireproof or
1607 * rings to become shockproof, this checking will need to be revised.
1608 * `rknown' ID only matters if xname() will provide the info about it.
1611 || (otmp->oclass != ARMOR_CLASS && otmp->oclass != WEAPON_CLASS
1612 && !is_weptool(otmp) /* (redundant) */
1613 && otmp->oclass != BALL_CLASS)) /* (useless) */
1615 else /* lack of `rknown' only matters for vulnerable objects */
1616 return (boolean) (is_rustprone(otmp) || is_corrodeable(otmp)
1617 || is_flammable(otmp));
1621 corpse_xname(otmp, adjective, cxn_flags)
1623 const char *adjective;
1624 unsigned cxn_flags; /* bitmask of CXN_xxx values */
1626 char *nambuf = nextobuf();
1627 int omndx = otmp->corpsenm;
1628 boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
1629 /* suppress "the" from "the unique monster corpse" */
1630 no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
1631 /* include "the" for "the woodchuck corpse */
1632 the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
1633 /* include "an" for "an ogre corpse */
1634 any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
1635 /* leave off suffix (do_name() appends "corpse" itself) */
1636 omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, possessive = FALSE;
1639 if (omndx == NON_PM) { /* paranoia */
1644 /* [Possible enhancement: check whether corpse has monster traits
1645 attached in order to use priestname() for priests and minions.] */
1646 } else if (omndx == PM_ALIGNED_PRIEST) {
1647 /* avoid "aligned priest"; it just exposes internal details */
1653 mname = mons[omndx].mname;
1654 if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
1655 mname = s_suffix(mname);
1657 /* don't precede personal name like "Medusa" with an article */
1658 if (type_is_pname(&mons[omndx]))
1660 /* always precede non-personal unique monster name like
1661 "Oracle" with "the" unless explicitly overridden */
1662 else if (the_unique_pm(&mons[omndx]) && !no_prefix)
1667 the_prefix = any_prefix = FALSE;
1668 else if (the_prefix)
1669 any_prefix = FALSE; /* mutually exclusive */
1672 /* can't use the() the way we use an() below because any capitalized
1673 Name causes it to assume a personal name and return Name as-is;
1674 that's usually the behavior wanted, but here we need to force "the"
1675 to precede capitalized unique monsters (pnames are handled above) */
1676 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1678 Strcat(nambuf, "the ");
1681 if (!adjective || !*adjective) {
1682 /* normal case: newt corpse */
1683 Strcat(nambuf, mname);
1685 /* adjective positioning depends upon format of monster name */
1686 if (possessive) /* Medusa's cursed partly eaten corpse */
1688 Sprintf(eos(nambuf), "%s %s", mname, adjective);
1690 Sprintf(eos(nambuf), "%s%s", mname, adjective);
1691 else /* cursed partly eaten troll corpse */
1693 Sprintf(eos(nambuf), "%s %s", adjective, mname);
1695 Sprintf(eos(nambuf), "%s%s", adjective, mname);
1696 /* in case adjective has a trailing space, squeeze it out */
1698 /* doname() might include a count in the adjective argument;
1699 if so, don't prepend an article */
1700 if (digit(*adjective))
1706 Strcat(nambuf, " corpse");
1707 /* makeplural(nambuf) => append "s" to "corpse" */
1708 if (otmp->quan > 1L && !ignore_quan) {
1709 Strcat(nambuf, "s");
1710 any_prefix = FALSE; /* avoid "a newt corpses" */
1713 Strcat(nambuf, "
\82Ì
\8e\80\91Ì");
1717 /* it's safe to overwrite our nambuf after an() has copied
1718 its old value into another buffer */
1720 Strcpy(nambuf, an(nambuf));
1725 /* xname doesn't include monster type for "corpse"; cxname does */
1730 if (obj->otyp == CORPSE)
1731 return corpse_xname(obj, (const char *) 0, CXN_NORMAL);
1735 /* like cxname, but ignores quantity */
1737 cxname_singular(obj)
1740 if (obj->otyp == CORPSE)
1741 return corpse_xname(obj, (const char *) 0, CXN_SINGULAR);
1742 return xname_flags(obj, CXN_SINGULAR);
1745 /* treat an object as fully ID'd when it might be used as reason for death */
1750 struct obj save_obj;
1751 unsigned save_ocknown;
1752 char *buf, *save_ocuname, *save_oname = (char *) 0;
1754 /* bypass object twiddling for artifacts */
1756 return bare_artifactname(obj);
1758 /* remember original settings for core of the object;
1759 oextra structs other than oname don't matter here--since they
1760 aren't modified they don't need to be saved and restored */
1763 save_oname = ONAME(obj);
1765 /* killer name should be more specific than general xname; however, exact
1766 info like blessed/cursed and rustproof makes things be too verbose */
1767 obj->known = obj->dknown = 1;
1768 obj->bknown = obj->rknown = obj->greased = 0;
1769 /* if character is a priest[ess], bknown will get toggled back on */
1770 if (obj->otyp != POT_WATER)
1771 obj->blessed = obj->cursed = 0;
1773 obj->bknown = 1; /* describe holy/unholy water as such */
1774 /* "killed by poisoned <obj>" would be misleading when poison is
1775 not the cause of death and "poisoned by poisoned <obj>" would
1776 be redundant when it is, so suppress "poisoned" prefix */
1778 /* strip user-supplied name; artifacts keep theirs */
1779 if (!obj->oartifact && save_oname)
1780 ONAME(obj) = (char *) 0;
1781 /* temporarily identify the type of object */
1782 save_ocknown = objects[obj->otyp].oc_name_known;
1783 objects[obj->otyp].oc_name_known = 1;
1784 save_ocuname = objects[obj->otyp].oc_uname;
1785 objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
1787 /* format the object */
1788 if (obj->otyp == CORPSE) {
1790 Strcpy(buf, corpse_xname(obj, (const char *) 0, CXN_NORMAL));
1791 } else if (obj->otyp == SLIME_MOLD) {
1792 /* concession to "most unique deaths competition" in the annual
1793 devnull tournament, suppress player supplied fruit names because
1794 those can be used to fake other objects and dungeon features */
1797 Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
1799 Strcpy(buf, "
\8aë
\8c¯
\82È
\82Ë
\82Î
\82Ë
\82Î
\83J
\83r");
1803 /* apply an article if appropriate; caller should always use KILLED_BY */
1804 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1805 if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
1806 buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
1809 objects[obj->otyp].oc_name_known = save_ocknown;
1810 objects[obj->otyp].oc_uname = save_ocuname;
1811 *obj = save_obj; /* restore object's core settings */
1812 if (!obj->oartifact && save_oname)
1813 ONAME(obj) = save_oname;
1818 /* xname,doname,&c with long results reformatted to omit some stuff */
1820 short_oname(obj, func, altfunc, lenlimit)
1822 char *FDECL((*func), (OBJ_P)), /* main formatting routine */
1823 *FDECL((*altfunc), (OBJ_P)); /* alternate for shortest result */
1826 struct obj save_obj;
1827 char unamebuf[12], onamebuf[12], *save_oname, *save_uname, *outbuf;
1829 outbuf = (*func)(obj);
1830 if ((unsigned) strlen(outbuf) <= lenlimit)
1833 /* shorten called string to fairly small amount */
1834 save_uname = objects[obj->otyp].oc_uname;
1835 if (save_uname && strlen(save_uname) >= sizeof unamebuf) {
1836 (void) strncpy(unamebuf, save_uname, sizeof unamebuf - 4);
1837 Strcpy(unamebuf + sizeof unamebuf - 4, "...");
1838 objects[obj->otyp].oc_uname = unamebuf;
1839 releaseobuf(outbuf);
1840 outbuf = (*func)(obj);
1841 objects[obj->otyp].oc_uname = save_uname; /* restore called string */
1842 if ((unsigned) strlen(outbuf) <= lenlimit)
1846 /* shorten named string to fairly small amount */
1847 save_oname = has_oname(obj) ? ONAME(obj) : 0;
1848 if (save_oname && strlen(save_oname) >= sizeof onamebuf) {
1849 (void) strncpy(onamebuf, save_oname, sizeof onamebuf - 4);
1850 Strcpy(onamebuf + sizeof onamebuf - 4, "...");
1851 ONAME(obj) = onamebuf;
1852 releaseobuf(outbuf);
1853 outbuf = (*func)(obj);
1854 ONAME(obj) = save_oname; /* restore named string */
1855 if ((unsigned) strlen(outbuf) <= lenlimit)
1859 /* shorten both called and named strings;
1860 unamebuf and onamebuf have both already been populated */
1861 if (save_uname && strlen(save_uname) >= sizeof unamebuf && save_oname
1862 && strlen(save_oname) >= sizeof onamebuf) {
1863 objects[obj->otyp].oc_uname = unamebuf;
1864 ONAME(obj) = onamebuf;
1865 releaseobuf(outbuf);
1866 outbuf = (*func)(obj);
1867 if ((unsigned) strlen(outbuf) <= lenlimit) {
1868 objects[obj->otyp].oc_uname = save_uname;
1869 ONAME(obj) = save_oname;
1874 /* still long; strip several name-lengthening attributes;
1875 called and named strings are still in truncated form */
1877 obj->bknown = obj->rknown = obj->greased = 0;
1878 obj->oeroded = obj->oeroded2 = 0;
1879 releaseobuf(outbuf);
1880 outbuf = (*func)(obj);
1881 if (altfunc && (unsigned) strlen(outbuf) > lenlimit) {
1882 /* still long; use the alternate function (usually one of
1883 the jackets around minimal_xname()) */
1884 releaseobuf(outbuf);
1885 outbuf = (*altfunc)(obj);
1887 /* restore the object */
1890 ONAME(obj) = save_oname;
1892 objects[obj->otyp].oc_uname = save_uname;
1894 /* use whatever we've got, whether it's too long or not */
1899 * Used if only one of a collection of objects is named (e.g. in eat.c).
1902 singular(otmp, func)
1903 register struct obj *otmp;
1904 char *FDECL((*func), (OBJ_P));
1909 /* using xname for corpses does not give the monster type */
1910 if (otmp->otyp == CORPSE && func == xname)
1913 savequan = otmp->quan;
1915 nam = (*func)(otmp);
1916 otmp->quan = savequan;
1922 register const char *str;
1924 char *buf = nextobuf();
1926 #if 0 /*JP*//*
\95s
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1929 if (strncmpi(str, "the ", 4) && strcmp(str, "molten lava")
1930 && strcmp(str, "iron bars") && strcmp(str, "ice")) {
1931 if (index(vowels, *str) && strncmp(str, "one-", 4)
1932 && strncmp(str, "useful", 6) && strncmp(str, "unicorn", 7)
1933 && strncmp(str, "uranium", 7) && strncmp(str, "eucalyptus", 10))
1940 #else /*
\92P
\82É
\83R
\83s
\81[*/
1950 char *tmp = an(str);
1952 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
1959 * Prepend "the" if necessary; assumes str is a subject derived from xname.
1960 * Use type_is_pname() for monster names, not the(). the() is idempotent.
1966 char *buf = nextobuf();
1967 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1968 boolean insert_the = FALSE;
1970 if (!strncmpi(str, "the ", 4)) {
1971 buf[0] = lowc(*str);
1972 Strcpy(&buf[1], str + 1);
1974 } else if (*str < 'A' || *str > 'Z') {
1975 /* not a proper name, needs an article */
1978 /* Probably a proper name, might not need an article */
1979 register char *tmp, *named, *called;
1982 /* some objects have capitalized adjectives in their names */
1983 if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0)
1984 && (tmp[1] < 'A' || tmp[1] > 'Z')) {
1986 } else if (tmp && index(str, ' ') < tmp) { /* has spaces */
1987 /* it needs an article if the name contains "of" */
1988 tmp = strstri(str, " of ");
1989 named = strstri(str, " named ");
1990 called = strstri(str, " called ");
1991 if (called && (!named || called < named))
1994 if (tmp && (!named || tmp < named)) /* found an "of" */
1996 /* stupid special case: lacks "of" but needs "the" */
1997 else if (!named && (l = strlen(str)) >= 31
1998 && !strcmp(&str[l - 31],
1999 "Platinum Yendorian Express Card"))
2004 Strcpy(buf, "the ");
2009 #else /*
\92P
\82É
\83R
\83s
\81[*/
2019 char *tmp = the(str);
2021 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2030 register struct obj *otmp;
2031 register const char *verb;
2037 /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */
2043 char prefix[PREFIX];
2044 char *bp = cxname(otmp);
2046 if (otmp->quan != 1L) {
2047 Sprintf(prefix, "%ld ", otmp->quan);
2048 bp = strprepend(bp, prefix);
2052 Strcat(bp, otense(otmp, verb));
2058 /* combine yname and aobjnam eg "your count cxname(otmp)" */
2064 char *s = aobjnam(obj, verb);
2066 /* leave off "your" for most of your artifacts, but prepend
2067 * "your" for unique objects and "foo of bar" quest artifacts */
2068 if (!carried(obj) || !obj_is_pname(obj)
2069 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2070 char *outbuf = shk_your(nextobuf(), obj);
2071 int space_left = BUFSZ - 1 - strlen(outbuf);
2073 s = strncat(outbuf, s, space_left);
2078 /* combine Yname2 and aobjnam eg "Your count cxname(otmp)" */
2084 register char *s = yobjnam(obj, verb);
2092 /* like aobjnam, but prepend "The", not count, and use xname */
2098 char *bp = The(xname(otmp));
2100 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2103 Strcat(bp, otense(otmp, verb));
2109 /* capitalized variant of doname() */
2114 char *s = doname(obj);
2120 /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */
2125 char *s = cxname(obj);
2127 /* leave off "your" for most of your artifacts, but prepend
2128 * "your" for unique objects and "foo of bar" quest artifacts */
2129 if (!carried(obj) || !obj_is_pname(obj)
2130 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2131 char *outbuf = shk_your(nextobuf(), obj);
2132 int space_left = BUFSZ - 1 - strlen(outbuf);
2134 s = strncat(outbuf, s, space_left);
2140 /* capitalized variant of yname() */
2145 char *s = yname(obj);
2153 /* returns "your minimal_xname(obj)"
2154 * or "Foobar's minimal_xname(obj)"
2155 * or "the minimal_xname(obj)"
2161 char *outbuf = nextobuf();
2162 char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */
2164 int space_left = BUFSZ - 1 - strlen(s);
2166 return strncat(s, minimal_xname(obj), space_left);
2168 int space_left = BUFSZ - strlen(s);
2170 return strncat(s, minimal_xname(obj), space_left);
2174 /* capitalized variant of ysimple_name() */
2179 char *s = ysimple_name(obj);
2187 /* "scroll" or "scrolls" */
2192 char *simpleoname = minimal_xname(obj);
2194 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2195 if (obj->quan != 1L)
2196 simpleoname = makeplural(simpleoname);
2201 /* "a scroll" or "scrolls"; "a silver bell" or "the Bell of Opening" */
2206 char *simpleoname = simpleonames(obj);
2207 int otyp = obj->otyp;
2209 /* prefix with "the" if a unique item, or a fake one imitating same,
2210 has been formatted with its actual name (we let typename() handle
2211 any `known' and `dknown' checking necessary) */
2212 if (otyp == FAKE_AMULET_OF_YENDOR)
2213 otyp = AMULET_OF_YENDOR;
2214 if (objects[otyp].oc_unique
2215 && !strcmp(simpleoname, OBJ_NAME(objects[otyp])))
2216 return the(simpleoname);
2218 /* simpleoname is singular if quan==1, plural otherwise */
2219 if (obj->quan == 1L)
2220 simpleoname = an(simpleoname);
2224 /* "the scroll" or "the scrolls" */
2229 char *simpleoname = simpleonames(obj);
2231 return the(simpleoname);
2234 /* artifact's name without any object type or known/dknown/&c feedback */
2236 bare_artifactname(obj)
2241 if (obj->oartifact) {
2242 outbuf = nextobuf();
2243 Strcpy(outbuf, artiname(obj->oartifact));
2245 if (!strncmp(outbuf, "The ", 4))
2246 outbuf[0] = lowc(outbuf[0]);
2249 outbuf = xname(obj);
2254 static const char *wrp[] = {
2255 "wand", "ring", "potion", "scroll", "gem",
2256 "amulet", "spellbook", "spell book",
2257 /* for non-specific wishes */
2258 "weapon", "armor", "tool", "food", "comestible",
2260 static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
2261 SCROLL_CLASS, GEM_CLASS, AMULET_CLASS,
2262 SPBOOK_CLASS, SPBOOK_CLASS, WEAPON_CLASS,
2263 ARMOR_CLASS, TOOL_CLASS, FOOD_CLASS,
2266 /* return form of the verb (input plural) if xname(otmp) were the subject */
2275 * verb is given in plural (without trailing s). Return as input
2276 * if the result of xname(otmp) would be plural. Don't bother
2277 * recomputing xname(otmp) at this time.
2279 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2280 if (!is_plural(otmp))
2281 return vtense((char *) 0, verb);
2289 /* various singular words that vtense would otherwise categorize as plural;
2290 also used by makesingular() to catch some special cases */
2291 static const char *const special_subjs[] = {
2292 "erinys", "manes", /* this one is ambiguous */
2293 "Cyclops", "Hippocrates", "Pelias", "aklys",
2294 "amnesia", "detect monsters", "paralysis", "shape changers",
2296 /* note: "detect monsters" and "shape changers" are normally
2297 caught via "<something>(s) of <whatever>", but they can be
2298 wished for using the shorter form, so we include them here
2299 to accommodate usage by makesingular during wishing */
2302 /* return form of the verb (input plural) for present tense 3rd person subj */
2305 register const char *subj;
2306 register const char *verb;
2308 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2309 char *buf = nextobuf(), *bspot;
2311 const char *sp, *spot;
2312 const char *const *spec;
2315 * verb is given in plural (without trailing s). Return as input
2316 * if subj appears to be plural. Add special cases as necessary.
2317 * Many hard cases can already be handled by using otense() instead.
2318 * If this gets much bigger, consider decomposing makeplural.
2319 * Note: monster names are not expected here (except before corpse).
2321 * Special case: allow null sobj to get the singular 3rd person
2322 * present tense form so we don't duplicate this code elsewhere.
2325 if (!strncmpi(subj, "a ", 2) || !strncmpi(subj, "an ", 3))
2327 spot = (const char *) 0;
2328 for (sp = subj; (sp = index(sp, ' ')) != 0; ++sp) {
2329 if (!strncmpi(sp, " of ", 4) || !strncmpi(sp, " from ", 6)
2330 || !strncmpi(sp, " called ", 8) || !strncmpi(sp, " named ", 7)
2331 || !strncmpi(sp, " labeled ", 9)) {
2337 len = (int) strlen(subj);
2339 spot = subj + len - 1;
2342 * plural: anything that ends in 's', but not '*us' or '*ss'.
2343 * Guess at a few other special cases that makeplural creates.
2345 if ((lowc(*spot) == 's' && spot != subj
2346 && !index("us", lowc(*(spot - 1))))
2347 || !BSTRNCMPI(subj, spot - 3, "eeth", 4)
2348 || !BSTRNCMPI(subj, spot - 3, "feet", 4)
2349 || !BSTRNCMPI(subj, spot - 1, "ia", 2)
2350 || !BSTRNCMPI(subj, spot - 1, "ae", 2)) {
2351 /* check for special cases to avoid false matches */
2352 len = (int) (spot - subj) + 1;
2353 for (spec = special_subjs; *spec; spec++) {
2354 ltmp = strlen(*spec);
2355 if (len == ltmp && !strncmpi(*spec, subj, len))
2357 /* also check for <prefix><space><special_subj>
2358 to catch things like "the invisible erinys" */
2359 if (len > ltmp && *(spot - ltmp) == ' '
2360 && !strncmpi(*spec, spot - ltmp + 1, ltmp))
2364 return strcpy(buf, verb);
2367 * 3rd person plural doesn't end in telltale 's';
2368 * 2nd person singular behaves as if plural.
2370 if (!strcmpi(subj, "they") || !strcmpi(subj, "you"))
2371 return strcpy(buf, verb);
2376 len = (int) strlen(buf);
2377 bspot = buf + len - 1;
2379 if (!strcmpi(buf, "are")) {
2380 Strcasecpy(buf, "is");
2381 } else if (!strcmpi(buf, "have")) {
2382 Strcasecpy(bspot - 1, "s");
2383 } else if (index("zxs", lowc(*bspot))
2384 || (len >= 2 && lowc(*bspot) == 'h'
2385 && index("cs", lowc(*(bspot - 1))))
2386 || (len == 2 && lowc(*bspot) == 'o')) {
2387 /* Ends in z, x, s, ch, sh; add an "es" */
2388 Strcasecpy(bspot + 1, "es");
2389 } else if (lowc(*bspot) == 'y' && !index(vowels, lowc(*(bspot - 1)))) {
2390 /* like "y" case in makeplural */
2391 Strcasecpy(bspot, "ies");
2393 Strcasecpy(bspot + 1, "s");
2406 const char *sing, *plur;
2409 /* word pairs that don't fit into formula-based transformations;
2410 also some suffices which have very few--often one--matches or
2411 which aren't systematically reversible (knives, staves) */
2412 static struct sing_plur one_off[] = {
2414 "children" }, /* (for wise guys who give their food funny names) */
2415 { "cubus", "cubi" }, /* in-/suc-cubus */
2416 { "culus", "culi" }, /* homunculus */
2417 { "djinni", "djinn" },
2418 { "erinys", "erinyes" },
2420 { "fungus", "fungi" },
2421 { "knife", "knives" },
2422 { "labrum", "labra" }, /* candelabrum */
2423 { "louse", "lice" },
2424 { "mouse", "mice" },
2425 { "mumak", "mumakil" },
2426 { "nemesis", "nemeses" },
2427 { "rtex", "rtices" }, /* vortex */
2428 { "tooth", "teeth" },
2429 { "staff", "staves" },
2433 static const char *const as_is[] = {
2434 /* makesingular() leaves these plural due to how they're used */
2435 "boots", "shoes", "gloves", "lenses", "scales",
2436 "eyes", "gauntlets", "iron bars",
2437 /* both singular and plural are spelled the same */
2438 "deer", "fish", "tuna", "yaki", "-hai",
2439 "krill", "manes", "ninja", "sheep", "ronin",
2440 "roshi", "shito", "tengu", "ki-rin", "Nazgul",
2441 "gunyoki", "piranha", "samurai", "shuriken", 0,
2442 /* Note: "fish" and "piranha" are collective plurals, suitable
2443 for "wiped out all <foo>". For "3 <foo>", they should be
2444 "fishes" and "piranhas" instead. We settle for collective
2445 variant instead of attempting to support both. */
2448 /* singularize/pluralize decisions common to both makesingular & makeplural
2451 singplur_lookup(basestr, endstring, to_plural, alt_as_is)
2452 char *basestr, *endstring; /* base string, pointer to eos(string) */
2453 boolean to_plural; /* true => makeplural, false => makesingular */
2454 const char *const *alt_as_is; /* another set like as_is[] */
2456 const struct sing_plur *sp;
2457 const char *same, *other, *const *as;
2460 for (as = as_is; *as; ++as) {
2461 al = (int) strlen(*as);
2462 if (!BSTRCMPI(basestr, endstring - al, *as))
2466 for (as = alt_as_is; *as; ++as) {
2467 al = (int) strlen(*as);
2468 if (!BSTRCMPI(basestr, endstring - al, *as))
2473 for (sp = one_off; sp->sing; sp++) {
2474 /* check whether endstring already matches */
2475 same = to_plural ? sp->plur : sp->sing;
2476 al = (int) strlen(same);
2477 if (!BSTRCMPI(basestr, endstring - al, same))
2478 return TRUE; /* use as-is */
2479 /* check whether it matches the inverse; if so, transform it */
2480 other = to_plural ? sp->sing : sp->plur;
2481 al = (int) strlen(other);
2482 if (!BSTRCMPI(basestr, endstring - al, other)) {
2483 Strcasecpy(endstring - al, same);
2484 return TRUE; /* one_off[] transformation */
2490 /* searches for common compounds, ex. lump of royal jelly */
2492 singplur_compound(str)
2495 /* if new entries are added, be sure to keep compound_start[] in sync */
2496 static const char *const compounds[] =
2498 " of ", " labeled ", " called ",
2499 " named ", " above", /* lurkers above */
2500 " versus ", " from ", " in ",
2501 " on ", " a la ", " with", /* " with "? */
2502 " de ", " d'", " du ",
2504 }, /* list of first characters for all compounds[] entries */
2505 compound_start[] = " -";
2507 const char *const *cmpd;
2510 for (p = str; *p; ++p) {
2511 /* substring starting at p can only match if *p is found
2512 within compound_start[] */
2513 if (!index(compound_start, *p))
2516 /* check current substring against all words in the compound[] list */
2517 for (cmpd = compounds; *cmpd; ++cmpd)
2518 if (!strncmpi(p, *cmpd, (int) strlen(*cmpd)))
2521 /* wasn't recognized as a compound phrase */
2525 /* Plural routine; chiefly used for user-defined fruits. We have to try to
2526 * account for everything reasonable the player has; something unreasonable
2527 * can still break the code. However, it's still a lot more accurate than
2528 * "just add an s at the end", which Rogue uses...
2530 * Also used for plural monster names ("Wiped out all homunculi." or the
2531 * vanquished monsters list) and body parts. A lot of unique monsters have
2532 * names which get mangled by makeplural and/or makesingular. They're not
2533 * genocidable, and vanquished-mon handling does its own special casing
2534 * (for uniques who've been revived and re-killed), so we don't bother
2535 * trying to get those right here.
2537 * Also misused by muse.c to convert 1st person present verbs to 2nd person.
2538 * 3.6.0: made case-insensitive.
2544 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2545 register char *spot;
2546 char lo_c, *str = nextobuf();
2547 const char *excess = (char *) 0;
2551 while (*oldstr == ' ')
2553 if (!oldstr || !*oldstr) {
2554 impossible("plural of null?");
2558 Strcpy(str, oldstr);
2561 * Skip changing "pair of" to "pairs of". According to Webster, usual
2562 * English usage is use pairs for humans, e.g. 3 pairs of dancers,
2563 * and pair for objects and non-humans, e.g. 3 pair of boots. We don't
2564 * refer to pairs of humans in this game so just skip to the bottom.
2566 if (!strncmpi(str, "pair of ", 8))
2569 /* look for "foo of bar" so that we can focus on "foo" */
2570 if ((spot = singplur_compound(str)) != 0) {
2571 excess = oldstr + (int) (spot - str);
2577 while (spot > str && *spot == ' ')
2578 spot--; /* Strip blanks from end */
2580 /* Now spot is the last character of the string */
2584 /* Single letters */
2585 if (len == 1 || !letter(*spot)) {
2586 Strcpy(spot + 1, "'s");
2590 /* dispense with some words which don't need pluralization */
2592 static const char *const already_plural[] = {
2593 "ae", /* algae, larvae, &c */
2594 "men", /* also catches women, watchmen */
2598 /* spot+1: synch up with makesingular's usage */
2599 if (singplur_lookup(str, spot + 1, TRUE, already_plural))
2602 /* more of same, but not suitable for blanket loop checking */
2603 if ((len == 2 && !strcmpi(str, "ya"))
2604 || (len >= 3 && !strcmpi(spot - 2, " ya")))
2608 /* man/men ("Wiped out all cavemen.") */
2609 if (len >= 3 && !strcmpi(spot - 2, "man")
2610 /* exclude shamans and humans */
2611 && (len < 6 || strcmpi(spot - 5, "shaman"))
2612 && (len < 5 || strcmpi(spot - 4, "human"))) {
2613 Strcasecpy(spot - 1, "en");
2616 if (lowc(*spot) == 'f') { /* (staff handled via one_off[]) */
2617 lo_c = lowc(*(spot - 1));
2618 if (len >= 3 && !strcmpi(spot - 2, "erf")) {
2619 /* avoid "nerf" -> "nerves", "serf" -> "serves" */
2620 ; /* fall through to default (append 's') */
2621 } else if (index("lr", lo_c) || index(vowels, lo_c)) {
2622 /* [aeioulr]f to [aeioulr]ves */
2623 Strcasecpy(spot, "ves");
2627 /* ium/ia (mycelia, baluchitheria) */
2628 if (len >= 3 && !strcmpi(spot - 2, "ium")) {
2629 Strcasecpy(spot - 2, "ia");
2632 /* algae, larvae, hyphae (another fungus part) */
2633 if ((len >= 4 && !strcmpi(spot - 3, "alga"))
2635 && (!strcmpi(spot - 4, "hypha") || !strcmpi(spot - 4, "larva")))
2636 || (len >= 6 && !strcmpi(spot - 5, "amoeba"))
2637 || (len >= 8 && (!strcmpi(spot - 7, "vertebra")))) {
2639 Strcasecpy(spot + 1, "e");
2642 /* fungus/fungi, homunculus/homunculi, but buses, lotuses, wumpuses */
2643 if (len > 3 && !strcmpi(spot - 1, "us")
2644 && !((len >= 5 && !strcmpi(spot - 4, "lotus"))
2645 || (len >= 6 && !strcmpi(spot - 5, "wumpus")))) {
2646 Strcasecpy(spot - 1, "i");
2649 /* sis/ses (nemesis) */
2650 if (len >= 3 && !strcmpi(spot - 2, "sis")) {
2651 Strcasecpy(spot - 1, "es");
2654 /* matzoh/matzot, possible food name */
2656 && (!strcmpi(spot - 5, "matzoh") || !strcmpi(spot - 5, "matzah"))) {
2657 Strcasecpy(spot - 1, "ot"); /* oh/ah -> ot */
2661 && (!strcmpi(spot - 4, "matzo") || !strcmpi(spot - 4, "matza"))) {
2662 Strcasecpy(spot, "ot"); /* o/a -> ot */
2666 /* note: -eau/-eaux (gateau, bordeau...) */
2667 /* note: ox/oxen, VAX/VAXen, goose/geese */
2671 /* Ends in z, x, s, ch, sh; add an "es" */
2672 if (index("zxs", lo_c)
2673 || (len >= 2 && lo_c == 'h' && index("cs", lowc(*(spot - 1))))
2674 /* Kludge to get "tomatoes" and "potatoes" right */
2675 || (len >= 4 && !strcmpi(spot - 2, "ato"))
2676 || (len >= 5 && !strcmpi(spot - 4, "dingo"))) {
2677 Strcasecpy(spot + 1, "es"); /* append es */
2680 /* Ends in y preceded by consonant (note: also "qu") change to "ies" */
2681 if (lo_c == 'y' && !index(vowels, lowc(*(spot - 1)))) {
2682 Strcasecpy(spot, "ies"); /* y -> ies */
2685 /* Default: append an 's' */
2686 Strcasecpy(spot + 1, "s");
2690 Strcat(str, excess);
2692 char *str = nextobuf();
2693 Strcpy(str, oldstr);
2699 * Singularize a string the user typed in; this helps reduce the complexity
2700 * of readobjnam, and is also used in pager.c to singularize the string
2701 * for which help is sought.
2703 * "Manes" is ambiguous: monster type (keep s), or horse body part (drop s)?
2704 * Its inclusion in as_is[]/special_subj[] makes it get treated as the former.
2706 * A lot of unique monsters have names ending in s; plural, or singular
2707 * from plural, doesn't make much sense for them so we don't bother trying.
2708 * 3.6.0: made case-insensitive.
2711 makesingular(oldstr)
2714 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2715 register char *p, *bp;
2716 const char *excess = 0;
2717 char *str = nextobuf();
2720 while (*oldstr == ' ')
2722 if (!oldstr || !*oldstr) {
2723 impossible("singular of null?");
2728 bp = strcpy(str, oldstr);
2730 /* check for "foo of bar" so that we can focus on "foo" */
2731 if ((p = singplur_compound(bp)) != 0) {
2732 excess = oldstr + (int) (p - bp);
2737 /* dispense with some words which don't need singularization */
2738 if (singplur_lookup(bp, p, FALSE, special_subjs))
2741 /* remove -s or -es (boxes) or -ies (rubies) */
2742 if (p >= bp + 1 && lowc(p[-1]) == 's') {
2743 if (p >= bp + 2 && lowc(p[-2]) == 'e') {
2744 if (p >= bp + 3 && lowc(p[-3]) == 'i') { /* "ies" */
2745 if (!BSTRCMPI(bp, p - 7, "cookies")
2746 || !BSTRCMPI(bp, p - 4, "pies")
2747 || !BSTRCMPI(bp, p - 5, "mbies") /* zombie */
2748 || !BSTRCMPI(bp, p - 5, "yries")) /* valkyrie */
2750 Strcasecpy(p - 3, "y"); /* ies -> y */
2753 /* wolves, but f to ves isn't fully reversible */
2754 if (p - 4 >= bp && (index("lr", lowc(*(p - 4)))
2755 || index(vowels, lowc(*(p - 4))))
2756 && !BSTRCMPI(bp, p - 3, "ves")) {
2757 if (!BSTRCMPI(bp, p - 6, "cloves")
2758 || !BSTRCMPI(bp, p - 6, "nerves"))
2760 Strcasecpy(p - 3, "f"); /* ves -> f */
2763 /* note: nurses, axes but boxes, wumpuses */
2764 if (!BSTRCMPI(bp, p - 4, "eses")
2765 || !BSTRCMPI(bp, p - 4, "oxes") /* boxes, foxes */
2766 || !BSTRCMPI(bp, p - 4, "nxes") /* lynxes */
2767 || !BSTRCMPI(bp, p - 4, "ches")
2768 || !BSTRCMPI(bp, p - 4, "uses") /* lotuses */
2769 || !BSTRCMPI(bp, p - 4, "sses") /* priestesses */
2770 || !BSTRCMPI(bp, p - 5, "atoes") /* tomatoes */
2771 || !BSTRCMPI(bp, p - 7, "dingoes")
2772 || !BSTRCMPI(bp, p - 7, "Aleaxes")) {
2773 *(p - 2) = '\0'; /* drop es */
2775 } /* else fall through to mins */
2777 /* ends in 's' but not 'es' */
2778 } else if (!BSTRCMPI(bp, p - 2, "us")) { /* lotus, fungus... */
2779 if (BSTRCMPI(bp, p - 6, "tengus") /* but not these... */
2780 && BSTRCMPI(bp, p - 7, "hezrous"))
2782 } else if (!BSTRCMPI(bp, p - 2, "ss")
2783 || !BSTRCMPI(bp, p - 5, " lens")
2784 || (p - 4 == bp && !strcmpi(p - 4, "lens"))) {
2788 *(p - 1) = '\0'; /* drop s */
2790 } else { /* input doesn't end in 's' */
2792 if (!BSTRCMPI(bp, p - 3, "men")) {
2793 Strcasecpy(p - 2, "an");
2796 /* matzot -> matzo, algae -> alga */
2797 if (!BSTRCMPI(bp, p - 6, "matzot") || !BSTRCMPI(bp, p - 2, "ae")) {
2798 *(p - 1) = '\0'; /* drop t/e */
2801 /* balactheria -> balactherium */
2802 if (p - 4 >= bp && !strcmpi(p - 2, "ia")
2803 && index("lr", lowc(*(p - 3))) && lowc(*(p - 4)) == 'e') {
2804 Strcasecpy(p - 1, "um"); /* a -> um */
2807 /* here we cannot find the plural suffix */
2811 /* if we stripped off a suffix (" of bar" from "foo of bar"),
2812 put it back now [strcat() isn't actually 100% safe here...] */
2818 char *str = nextobuf();
2819 Strcpy(str, oldstr);
2824 /* compare user string against object name string using fuzzy matching */
2826 wishymatch(u_str, o_str, retry_inverted)
2827 const char *u_str; /* from user, so might be variant spelling */
2828 const char *o_str; /* from objects[], so is in canonical form */
2829 boolean retry_inverted; /* optional extra "of" handling */
2831 static NEARDATA const char detect_SP[] = "detect ",
2832 SP_detection[] = " detection";
2833 char *p, buf[BUFSZ];
2835 /* ignore spaces & hyphens and upper/lower case when comparing */
2836 if (fuzzymatch(u_str, o_str, " -", TRUE))
2839 if (retry_inverted) {
2840 const char *u_of, *o_of;
2842 /* when just one of the strings is in the form "foo of bar",
2843 convert it into "bar foo" and perform another comparison */
2844 u_of = strstri(u_str, " of ");
2845 o_of = strstri(o_str, " of ");
2846 if (u_of && !o_of) {
2847 Strcpy(buf, u_of + 4);
2848 p = eos(strcat(buf, " "));
2849 while (u_str < u_of)
2852 return fuzzymatch(buf, o_str, " -", TRUE);
2853 } else if (o_of && !u_of) {
2854 Strcpy(buf, o_of + 4);
2855 p = eos(strcat(buf, " "));
2856 while (o_str < o_of)
2859 return fuzzymatch(u_str, buf, " -", TRUE);
2863 /* [note: if something like "elven speed boots" ever gets added, these
2864 special cases should be changed to call wishymatch() recursively in
2865 order to get the "of" inversion handling] */
2866 if (!strncmp(o_str, "dwarvish ", 9)) {
2867 if (!strncmpi(u_str, "dwarven ", 8))
2868 return fuzzymatch(u_str + 8, o_str + 9, " -", TRUE);
2869 } else if (!strncmp(o_str, "elven ", 6)) {
2870 if (!strncmpi(u_str, "elvish ", 7))
2871 return fuzzymatch(u_str + 7, o_str + 6, " -", TRUE);
2872 else if (!strncmpi(u_str, "elfin ", 6))
2873 return fuzzymatch(u_str + 6, o_str + 6, " -", TRUE);
2874 } else if (!strncmp(o_str, detect_SP, sizeof detect_SP - 1)) {
2875 /* check for "detect <foo>" vs "<foo> detection" */
2876 if ((p = strstri(u_str, SP_detection)) != 0
2877 && !*(p + sizeof SP_detection - 1)) {
2878 /* convert "<foo> detection" into "detect <foo>" */
2880 Strcat(strcpy(buf, detect_SP), u_str);
2881 /* "detect monster" -> "detect monsters" */
2882 if (!strcmpi(u_str, "monster"))
2885 return fuzzymatch(buf, o_str, " -", TRUE);
2887 } else if (strstri(o_str, SP_detection)) {
2888 /* and the inverse, "<foo> detection" vs "detect <foo>" */
2889 if (!strncmpi(u_str, detect_SP, sizeof detect_SP - 1)) {
2890 /* convert "detect <foo>s" into "<foo> detection" */
2891 p = makesingular(u_str + sizeof detect_SP - 1);
2892 Strcat(strcpy(buf, p), SP_detection);
2893 /* caller may be looping through objects[], so avoid
2894 churning through all the obufs */
2896 return fuzzymatch(buf, o_str, " -", TRUE);
2898 } else if (strstri(o_str, "ability")) {
2899 /* when presented with "foo of bar", makesingular() used to
2900 singularize both foo & bar, but now only does so for foo */
2901 /* catch "{potion(s),ring} of {gain,restore,sustain} abilities" */
2902 if ((p = strstri(u_str, "abilities")) != 0
2903 && !*(p + sizeof "abilities" - 1)) {
2904 (void) strncpy(buf, u_str, (unsigned) (p - u_str));
2905 Strcpy(buf + (p - u_str), "ability");
2906 return fuzzymatch(buf, o_str, " -", TRUE);
2908 } else if (!strcmp(o_str, "aluminum")) {
2909 /* this special case doesn't really fit anywhere else... */
2910 /* (note that " wand" will have been stripped off by now) */
2911 if (!strcmpi(u_str, "aluminium"))
2912 return fuzzymatch(u_str + 9, o_str + 8, " -", TRUE);
2919 const char *name, oclass;
2920 int f_o_range, l_o_range;
2923 /* wishable subranges of objects */
2924 STATIC_OVL NEARDATA const struct o_range o_ranges[] = {
2925 { "bag", TOOL_CLASS, SACK, BAG_OF_TRICKS },
2926 { "lamp", TOOL_CLASS, OIL_LAMP, MAGIC_LAMP },
2927 { "candle", TOOL_CLASS, TALLOW_CANDLE, WAX_CANDLE },
2928 { "horn", TOOL_CLASS, TOOLED_HORN, HORN_OF_PLENTY },
2929 { "shield", ARMOR_CLASS, SMALL_SHIELD, SHIELD_OF_REFLECTION },
2930 { "hat", ARMOR_CLASS, FEDORA, DUNCE_CAP },
2931 { "helm", ARMOR_CLASS, ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY },
2932 { "gloves", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
2933 { "gauntlets", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
2934 { "boots", ARMOR_CLASS, LOW_BOOTS, LEVITATION_BOOTS },
2935 { "shoes", ARMOR_CLASS, LOW_BOOTS, IRON_SHOES },
2936 { "cloak", ARMOR_CLASS, MUMMY_WRAPPING, CLOAK_OF_DISPLACEMENT },
2937 { "shirt", ARMOR_CLASS, HAWAIIAN_SHIRT, T_SHIRT },
2938 { "dragon scales", ARMOR_CLASS, GRAY_DRAGON_SCALES,
2939 YELLOW_DRAGON_SCALES },
2940 { "dragon scale mail", ARMOR_CLASS, GRAY_DRAGON_SCALE_MAIL,
2941 YELLOW_DRAGON_SCALE_MAIL },
2942 { "sword", WEAPON_CLASS, SHORT_SWORD, KATANA },
2943 { "venom", VENOM_CLASS, BLINDING_VENOM, ACID_VENOM },
2944 { "gray stone", GEM_CLASS, LUCKSTONE, FLINT },
2945 { "grey stone", GEM_CLASS, LUCKSTONE, FLINT },
2949 #if 0 /*JP*//*not used*/
2950 /* alternate spellings; if the difference is only the presence or
2951 absence of spaces and/or hyphens (such as "pickaxe" vs "pick axe"
2952 vs "pick-axe") then there is no need for inclusion in this list;
2953 likewise for ``"of" inversions'' ("boots of speed" vs "speed boots") */
2954 struct alt_spellings {
2958 { "pickax", PICK_AXE },
2959 { "whip", BULLWHIP },
2960 { "saber", SILVER_SABER },
2961 { "silver sabre", SILVER_SABER },
2962 { "smooth shield", SHIELD_OF_REFLECTION },
2963 { "grey dragon scale mail", GRAY_DRAGON_SCALE_MAIL },
2964 { "grey dragon scales", GRAY_DRAGON_SCALES },
2965 { "iron ball", HEAVY_IRON_BALL },
2966 { "lantern", BRASS_LANTERN },
2967 { "mattock", DWARVISH_MATTOCK },
2968 { "amulet of poison resistance", AMULET_VERSUS_POISON },
2969 { "potion of sleep", POT_SLEEPING },
2971 { "camera", EXPENSIVE_CAMERA },
2972 { "tee shirt", T_SHIRT },
2974 { "can opener", TIN_OPENER },
2975 { "kelp", KELP_FROND },
2976 { "eucalyptus", EUCALYPTUS_LEAF },
2977 { "royal jelly", LUMP_OF_ROYAL_JELLY },
2978 { "lembas", LEMBAS_WAFER },
2979 { "marker", MAGIC_MARKER },
2980 { "hook", GRAPPLING_HOOK },
2981 { "grappling iron", GRAPPLING_HOOK },
2982 { "grapnel", GRAPPLING_HOOK },
2983 { "grapple", GRAPPLING_HOOK },
2984 /* normally we wouldn't have to worry about unnecessary <space>, but
2985 " stone" will get stripped off, preventing a wishymatch; that actually
2986 lets "flint stone" be a match, so we also accept bogus "flintstone" */
2987 { "luck stone", LUCKSTONE },
2988 { "load stone", LOADSTONE },
2989 { "touch stone", TOUCHSTONE },
2990 { "flintstone", FLINT },
2991 { (const char *) 0, 0 },
2996 rnd_otyp_by_wpnskill(skill)
3000 short otyp = STRANGE_OBJECT;
3001 for (i = bases[WEAPON_CLASS];
3002 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3003 if (objects[i].oc_skill == skill) {
3009 for (i = bases[WEAPON_CLASS];
3010 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3011 if (objects[i].oc_skill == skill)
3019 * Return something wished for. Specifying a null pointer for
3020 * the user request string results in a random object. Otherwise,
3021 * if asking explicitly for "nothing" (or "nil") return no_wish;
3022 * if not an object return &zeroobj; if an error (no matching object),
3027 readobjnam(bp, no_wish)
3029 struct obj *no_wish;
3033 register struct obj *otmp;
3034 int cnt, spe, spesgn, typ, very, rechrg;
3035 int blessed, uncursed, iscursed, ispoisoned, isgreased;
3036 int eroded, eroded2, erodeproof;
3037 int halfeaten, mntmp, contents;
3038 int islit, unlabeled, ishistoric, isdiluted, trapped;
3040 int tmp, tinv, tvariety;
3046 int ftype = context.current_fruit;
3047 char fruitbuf[BUFSZ];
3048 /* Fruits may not mess up the ability to wish for real objects (since
3049 * you can leave a fruit in a bones file and it will be added to
3050 * another person's game), so they must be checked for last, after
3051 * stripping all the possible prefixes and seeing if there's a real
3052 * name in there. So we have to save the full original name. However,
3053 * it's still possible to do things like "uncursed burnt Alaska",
3054 * or worse yet, "2 burned 5 course meals", so we need to loop to
3055 * strip off the prefixes again, this time stripping only the ones
3057 * We could get even more detailed so as to allow food names with
3058 * prefixes that _are_ possible on food, so you could wish for
3059 * "2 3 alarm chilis". Currently this isn't allowed; options.c
3060 * automatically sticks 'candied' in front of such names.
3063 char *un, *dn, *actualn;
3064 const char *name = 0;
3066 cnt = spe = spesgn = typ = very = rechrg = blessed = uncursed = iscursed =
3067 ispoisoned = isgreased = eroded = eroded2 = erodeproof = halfeaten =
3068 islit = unlabeled = ishistoric = isdiluted = trapped = 0;
3069 tvariety = RANDOM_TIN;
3074 contents = UNDEFINED;
3076 actualn = dn = un = 0;
3081 /* first, remove extra whitespace they may have typed */
3082 (void) mungspaces(bp);
3083 /* allow wishing for "nothing" to preserve wishless conduct...
3084 [now requires "wand of nothing" if that's what was really wanted] */
3086 if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil")
3087 || !strcmpi(bp, "none"))
3089 if (!strcmpi(bp, "
\82È
\82µ") || !strcmpi(bp, "
\96³
\82µ"))
3092 /* save the [nearly] unmodified choice string */
3093 Strcpy(fruitbuf, bp);
3100 if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) {
3102 } else if (!strncmpi(bp, "the ", l = 4)) {
3103 ; /* just increment `bp' by `l' below */
3104 } else if (!cnt && digit(*bp) && strcmp(bp, "0")) {
3111 } else if (*bp == '+' || *bp == '-') {
3112 spesgn = (*bp++ == '+') ? 1 : -1;
3120 } else if (!strncmpi(bp, "blessed ", l = 8)
3121 || !strncmpi(bp, "holy ", l = 5)) {
3123 } else if (!strncmpi(bp, "
\8fj
\95\9f\82³
\82ê
\82½", l = 10)) {
3127 } else if (!strncmpi(bp, "moist ", l = 6)
3128 || !strncmpi(bp, "wet ", l = 4)) {
3130 } else if (!strncmpi(bp, "
\8e¼
\82Á
\82½", l = 6)
3131 || !strncmpi(bp, "
\94G
\82ê
\82½", l = 6)) {
3134 if (!strncmpi(bp, "wet ", 4))
3136 if (!strncmpi(bp, "
\94G
\82ê
\82½", 4))
3138 wetness = rn2(3) + 3;
3142 } else if (!strncmpi(bp, "cursed ", l = 7)
3143 || !strncmpi(bp, "unholy ", l = 7)) {
3145 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82½", l = 8)) {
3149 } else if (!strncmpi(bp, "uncursed ", l = 9)) {
3151 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", l = 9)) {
3155 } else if (!strncmpi(bp, "rustproof ", l = 10)
3156 || !strncmpi(bp, "erodeproof ", l = 11)
3157 || !strncmpi(bp, "corrodeproof ", l = 13)
3158 || !strncmpi(bp, "fixed ", l = 6)
3159 || !strncmpi(bp, "fireproof ", l = 10)
3160 || !strncmpi(bp, "rotproof ", l = 9)) {
3162 } else if (!strncmpi(bp, "
\8eK
\82Ñ
\82È
\82¢", l = 8)
3163 || !strncmpi(bp, "
\95\85\90H
\82µ
\82È
\82¢", l = 10)
3164 || !strncmpi(bp, "
\88À
\92è
\82µ
\82½", l = 8)
3165 || !strncmpi(bp, "
\94R
\82¦
\82È
\82¢", l = 8)) {
3168 } else if (!strncmpi(bp, "lit ", l = 4)
3169 || !strncmpi(bp, "burning ", l = 8)) {
3171 } else if (!strncmpi(bp, "unlit ", l = 6)
3172 || !strncmpi(bp, "extinguished ", l = 13)) {
3174 /* "unlabeled" and "blank" are synonymous */
3175 } else if (!strncmpi(bp, "unlabeled ", l = 10)
3176 || !strncmpi(bp, "unlabelled ", l = 11)
3177 || !strncmpi(bp, "blank ", l = 6)) {
3179 } else if (!strncmpi(bp, "poisoned ", l = 9)) {
3181 /* "trapped" recognized but not honored outside wizard mode */
3182 } else if (!strncmpi(bp, "trapped ", l = 8)) {
3183 trapped = 0; /* undo any previous "untrapped" */
3186 } else if (!strncmpi(bp, "untrapped ", l = 10)) {
3187 trapped = 2; /* not trapped */
3188 } else if (!strncmpi(bp, "greased ", l = 8)) {
3190 } else if (!strncmpi(bp, "very ", l = 5)) {
3191 /* very rusted very heavy iron ball */
3193 } else if (!strncmpi(bp, "thoroughly ", l = 11)) {
3195 } else if (!strncmpi(bp, "rusty ", l = 6)
3196 || !strncmpi(bp, "rusted ", l = 7)
3197 || !strncmpi(bp, "burnt ", l = 6)
3198 || !strncmpi(bp, "burned ", l = 7)) {
3201 } else if (!strncmpi(bp, "corroded ", l = 9)
3202 || !strncmpi(bp, "rotted ", l = 7)) {
3205 } else if (!strncmpi(bp, "partly eaten ", l = 13)
3206 || !strncmpi(bp, "partially eaten ", l = 16)) {
3208 } else if (!strncmpi(bp, "historic ", l = 9)) {
3210 } else if (!strncmpi(bp, "diluted ", l = 8)) {
3212 } else if (!strncmpi(bp, "empty ", l = 6)) {
3219 cnt = 1; /* %% what with "gems" etc. ? */
3220 if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) {
3221 boolean keeptrailingchars = TRUE;
3223 p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */
3224 ++p; /* advance past '(' */
3225 if (!strncmpi(p, "lit)", 4)) {
3227 p += 4 - 1; /* point at ')' */
3241 /* mis-matched parentheses; rest of string will be ignored
3242 * [probably we should restore everything back to '('
3243 * instead since it might be part of "named ..."]
3245 keeptrailingchars = FALSE;
3250 if (keeptrailingchars) {
3253 /* 'pp' points at 'pb's terminating '\0',
3254 'p' points at ')' and will be incremented past it */
3261 * otmp->spe is type schar, so we don't want spe to be any bigger or
3262 * smaller. Also, spe should always be positive --some cheaters may
3263 * try to confuse atoi().
3266 spesgn = -1; /* cheaters get what they deserve */
3269 if (spe > SCHAR_LIM)
3271 if (rechrg < 0 || rechrg > 7)
3272 rechrg = 7; /* recharge_limit */
3274 /* now we have the actual name, as delivered by xname, say
3275 * green potions called whisky
3276 * scrolls labeled "QWERTY"
3279 * very heavy iron ball named hoei
3283 if ((p = strstri(bp, " named ")) != 0) {
3287 if ((p = strstri(bp, " called ")) != 0) {
3290 /* "helmet called telepathy" is not "helmet" (a specific type)
3291 * "shield called reflection" is not "shield" (a general type)
3293 for (i = 0; i < SIZE(o_ranges); i++)
3294 if (!strcmpi(bp, o_ranges[i].name)) {
3295 oclass = o_ranges[i].oclass;
3299 if ((p = strstri(bp, " labeled ")) != 0) {
3302 } else if ((p = strstri(bp, " labelled ")) != 0) {
3306 if ((p = strstri(bp, " of spinach")) != 0) {
3311 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82µ
\82È
\82¢*/
3313 Skip over "pair of ", "pairs of", "set of" and "sets of".
3315 Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
3316 English either way. See makeplural() for more on pair/pairs.
3318 We should only double count if the object in question is not
3319 referred to as a "pair of". E.g. We should double if the player
3320 types "pair of spears", but not if the player types "pair of
3321 lenses". Luckily (?) all objects that are referred to as pairs
3322 -- boots, gloves, and lenses -- are also not mergable, so cnt is
3325 if (!strncmpi(bp, "pair of ", 8)) {
3328 } else if (cnt > 1 && !strncmpi(bp, "pairs of ", 9)) {
3331 } else if (!strncmpi(bp, "set of ", 7)) {
3333 } else if (!strncmpi(bp, "sets of ", 8)) {
3339 /* intercept pudding globs here; they're a valid wish target,
3340 * but we need them to not get treated like a corpse.
3342 * also don't let player wish for multiple globs.
3344 if ((p = strstri(bp, "glob of ")) != 0
3345 || (p = strstri(bp, "globs of ")) != 0) {
3346 int globoffset = (*(p + 4) == 's') ? 9 : 8;
3347 if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE
3348 && mntmp <= PM_BLACK_PUDDING) {
3349 mntmp = NON_PM; /* lie to ourselves */
3350 cnt = 0; /* force only one */
3354 * Find corpse type using "of" (figurine of an orc, tin of orc meat)
3355 * Don't check if it's a wand or spellbook.
3356 * (avoid "wand/finger of death" confusion).
3358 if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ")
3359 && !strstri(bp, "finger ")) {
3360 if (((p = strstri(bp, "tin of ")) != 0)
3361 && (tmp = tin_variety_txt(p + 7, &tinv))
3362 && (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) {
3365 } else if ((p = strstri(bp, " of ")) != 0
3366 && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
3370 /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
3371 if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
3372 if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
3373 if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
3374 if (strncmpi(bp, "master key",
3375 10)) /* not the "master" rank */
3376 if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
3377 if (mntmp < LOW_PM && strlen(bp) > 2
3378 && (mntmp = name_to_mon(bp)) >= LOW_PM) {
3380 mntmplen; /* double check for rank title */
3382 mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
3383 bp += mntmp != mntmptoo
3384 ? (int) strlen(mons[mntmp].mname)
3388 else if (!strncmpi(bp, "s ", 2))
3390 else if (!strncmpi(bp, "es ", 3))
3392 else if (!*bp && !actualn && !dn && !un
3394 /* no referent; they don't really mean a
3400 #else /*JP:
\81u(
\89ö
\95¨
\96¼)
\82Ì(
\83A
\83C
\83e
\83\80)
\81v
\91Î
\89\9e */
3402 if ((mntmp = name_to_mon(bp)) >= LOW_PM) {
3403 const char *mp = mons[mntmp].mname;
3404 bp = strstri(bp, mp) + strlen(mp) + 2;
3409 #if 0 /*JP*//*
\92P
\90\94\89»
\82Í
\82µ
\82È
\82¢*/
3410 /* first change to singular if necessary */
3412 char *sng = makesingular(bp);
3413 if (strcmp(bp, sng)) {
3421 #if 0 /*JP*//*
\83X
\83y
\83\8b\97h
\82ê
\8f\88\97\9d\82Í
\82µ
\82È
\82¢*/
3422 /* Alternate spellings (pick-ax, silver sabre, &c) */
3424 struct alt_spellings *as = spellings;
3427 if (fuzzymatch(bp, as->sp, " -", TRUE)) {
3433 /* can't use spellings list for this one due to shuffling */
3434 if (!strncmpi(bp, "grey spell", 10))
3437 if ((p = strstri(bp, "armour")) != 0) {
3438 /* skip past "armo", then copy remainder beyond "u" */
3440 while ((*p = *(p + 1)) != '\0')
3441 ++p; /* self terminating */
3447 /* dragon scales - assumes order of dragons */
3448 if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON
3449 && mntmp <= PM_YELLOW_DRAGON) {
3450 typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3451 mntmp = NON_PM; /* no monster */
3455 /*JP:
\81u
\97Ø
\8aZ
\81v
\82ð
\90æ
\82É
\8f\88\97\9d\82µ
\82Ä
\82¨
\82 */
3456 if (!strcmpi(bp, "
\97Ø
\8aZ") && mntmp >= PM_GRAY_DRAGON
3457 && mntmp <= PM_YELLOW_DRAGON) {
3458 typ = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
3459 mntmp = NON_PM; /* no monster */
3463 if (!strcmpi(bp, "
\97Ø") && mntmp >= PM_GRAY_DRAGON
3464 && mntmp <= PM_YELLOW_DRAGON) {
3465 typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3466 mntmp = NON_PM; /* no monster */
3473 if (!BSTRCMPI(bp, p - 10, "holy water")) {
3475 if ((p - bp) >= 12 && *(p - 12) == 'u')
3476 iscursed = 1; /* unholy water */
3481 #else /*JP:
\90¹
\90\85\82Æ
\95s
\8fò
\82È
\90\85\82ð
\95Ê
\82É
\94»
\92è*/
3482 if (!BSTRCMPI(bp, p - 4, "
\90¹
\90\85")) {
3487 if (!BSTRCMPI(bp, p - 4, "
\95s
\8fò
\82È
\90\85")) {
3494 if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
3496 if (unlabeled && !BSTRCMPI(bp, p - 4, "
\8aª
\95¨")) {
3498 typ = SCR_BLANK_PAPER;
3502 if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
3504 if (unlabeled && !BSTRCMPI(bp, p - 6, "
\96\82\96@
\8f\91")) {
3506 typ = SPE_BLANK_PAPER;
3510 * NOTE: Gold pieces are handled as objects nowadays, and therefore
3511 * this section should probably be reconsidered as well as the entire
3512 * gold/money concept. Maybe we want to add other monetary units as
3513 * well in the future. (TH)
3516 if (!BSTRCMPI(bp, p - 10, "gold piece") || !BSTRCMPI(bp, p - 7, "zorkmid")
3517 || !strcmpi(bp, "gold") || !strcmpi(bp, "money")
3518 || !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
3520 if (!BSTRCMPI(bp, p - 4, "
\8bà
\89Ý") || !BSTRCMPI(bp, p - 8, "
\83S
\81[
\83\8b\83h")
3521 || *bp == GOLD_SYM) {
3523 if (cnt > 5000 && !wizard)
3527 otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
3528 otmp->quan = (long) cnt;
3529 otmp->owt = weight(otmp);
3534 /* check for single character object class code ("/" for wand, &c) */
3535 if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES
3536 && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
3543 \89p
\8cê
\82È
\82ç XXXXX potion
\82Í
\95s
\8am
\92è
\96¼
\81Apotion of XXXXX
\82Í
\8am
\92è
\96¼
\82Æ
\82¢
\82¤
3544 \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¢
3546 /* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */
3547 /* false hits on, e.g., rings for "ring mail". */
3548 if (strncmpi(bp, "enchant ", 8) && strncmpi(bp, "destroy ", 8)
3549 && strncmpi(bp, "detect food", 11)
3550 && strncmpi(bp, "food detection", 14) && strncmpi(bp, "ring mail", 9)
3551 && strncmpi(bp, "studded leather armor", 21)
3552 && strncmpi(bp, "leather armor", 13)
3553 && strncmpi(bp, "tooled horn", 11) && strncmpi(bp, "food ration", 11)
3554 && strncmpi(bp, "meat ring", 9))
3555 for (i = 0; i < (int) (sizeof wrpsym); i++) {
3556 register int j = strlen(wrp[i]);
3557 if (!strncmpi(bp, wrp[i], j)) {
3559 if (oclass != AMULET_CLASS) {
3561 if (!strncmpi(bp, " of ", 4))
3563 /* else if(*bp) ?? */
3568 if (!BSTRCMPI(bp, p - j, wrp[i])) {
3572 if (p > bp && p[-1] == ' ')
3580 /* Wishing in wizard mode can create traps and furniture.
3581 * Part I: distinguish between trap and object for the two
3582 * types of traps which have corresponding objects: bear trap
3583 * and land mine. "beartrap" (object) and "bear trap" (trap)
3584 * have a difference in spelling which we used to exploit by
3585 * adding a special case in wishymatch(), but "land mine" is
3586 * spelled the same either way so needs different handing.
3587 * Since we need something else for land mine, we've dropped
3588 * the bear trap hack so that both are handled exactly the
3589 * same. To get an armed trap instead of a disarmed object,
3590 * the player can prefix either the object name or the trap
3591 * name with "trapped " (which ordinarily applies to chests
3592 * and tins), or append something--anything at all except for
3593 * " object", but " trap" is suggested--to either the trap
3594 * name or the object name.
3596 if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
3597 boolean beartrap = (lowc(*bp) == 'b');
3598 char *zp = bp + 4; /* skip "bear"/"land" */
3601 ++zp; /* embedded space is optional */
3602 if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
3604 if (trapped == 2 || !strcmpi(zp, " object")) {
3605 /* "untrapped <foo>" or "<foo> object" */
3606 typ = beartrap ? BEARTRAP : LAND_MINE;
3608 } else if (trapped == 1 || *zp != '\0') {
3609 /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
3610 int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
3612 /* use canonical trap spelling, skip object matching */
3613 Strcpy(bp, defsyms[idx].explanation);
3616 /* [no prefix or suffix; we're going to end up matching
3617 the object name and getting a disarmed trap object] */
3622 /* "grey stone" check must be before general "stone" */
3623 for (i = 0; i < SIZE(o_ranges); i++)
3624 if (!strcmpi(bp, o_ranges[i].name)) {
3625 typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
3629 if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) {
3630 p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0';
3634 } else if (!strcmpi(bp, "looking glass")) {
3635 ; /* avoid false hit on "* glass" */
3636 } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) {
3637 register char *g = bp;
3638 if (strstri(g, "broken"))
3639 return (struct obj *) 0;
3640 if (!strncmpi(g, "worthless ", 10))
3642 if (!strncmpi(g, "piece of ", 9))
3644 if (!strncmpi(g, "colored ", 8))
3646 else if (!strncmpi(g, "coloured ", 9))
3648 if (!strcmpi(g, "glass")) { /* choose random color */
3649 /* 9 different kinds */
3650 typ = LAST_GEM + rnd(9);
3651 if (objects[typ].oc_class == GEM_CLASS)
3654 typ = 0; /* somebody changed objects[]? punt */
3655 } else { /* try to construct canonical form */
3658 Strcpy(tbuf, "worthless piece of ");
3659 Strcat(tbuf, g); /* assume it starts with the color */
3666 dn = actualn; /* ex. "skull cap" */
3668 /* check real names of gems first */
3669 if (!oclass && actualn) {
3670 for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
3671 register const char *zn;
3673 if ((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
3679 i = oclass ? bases[(int) oclass] : 1;
3680 while (i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)) {
3681 register const char *zn;
3683 if (actualn && (zn = OBJ_NAME(objects[i])) != 0
3684 && wishymatch(actualn, zn, TRUE)) {
3689 if (dn && (zn = OBJ_DESCR(objects[i])) != 0
3690 && wishymatch(dn, zn, FALSE)) {
3692 *
\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É
3693 *
\82È
\82ç
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\81B
3694 *
\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
3696 if (i != FAKE_AMULET_OF_YENDOR &&
3697 dn && (zn = OBJ_DESCR(objects[i])) != 0
3698 && wishymatch(dn, zn, FALSE)) {
3700 /* don't match extra descriptions (w/o real name) */
3701 if (!OBJ_NAME(objects[i]))
3702 return (struct obj *) 0;
3706 if (un && (zn = objects[i].oc_uname) != 0
3707 && wishymatch(un, zn, FALSE)) {
3714 struct Jitem *j = Japanese_items;
3717 if (actualn && !strcmpi(actualn, j->name)) {
3724 /* if we've stripped off "armor" and failed to match anything
3725 in objects[], append "mail" and try again to catch misnamed
3726 requests like "plate armor" and "yellow dragon scale armor" */
3727 if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
3728 /* modifying bp's string is ok; we're about to resort
3729 to random armor if this also fails to match anything */
3730 Strcat(bp, " mail");
3734 if (!strcmpi(bp, "spinach")) {
3736 if (!strcmp(bp, "
\83z
\83E
\83\8c\83\93\91\90")) {
3742 /* Note: not strcmpi. 2 fruits, one capital, one not, are possible.
3743 Also not strncmp. We used to ignore trailing text with it, but
3744 that resulted in "grapefruit" matching "grape" if the latter came
3745 earlier than the former in the fruit list. */
3749 int blessedf, iscursedf, uncursedf, halfeatenf;
3751 blessedf = iscursedf = uncursedf = halfeatenf = 0;
3758 if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
3760 } else if (!cntf && digit(*fp)) {
3767 } else if (!strncmpi(fp, "blessed ", l = 8)) {
3769 } else if (!strncmpi(fp, "cursed ", l = 7)) {
3771 } else if (!strncmpi(fp, "uncursed ", l = 9)) {
3773 } else if (!strncmpi(fp, "partly eaten ", l = 13)
3774 || !strncmpi(fp, "partially eaten ", l = 16)) {
3781 for (f = ffruit; f; f = f->nextf) {
3782 /* match type: 0=none, 1=exact, 2=singular, 3=plural */
3785 if (!strcmp(fp, f->fname))
3787 else if (!strcmp(fp, makesingular(f->fname)))
3789 else if (!strcmp(fp, makeplural(f->fname)))
3794 iscursed = iscursedf;
3795 uncursed = uncursedf;
3796 halfeaten = halfeatenf;
3797 /* adjust count if user explicitly asked for
3798 singular amount (can't happen unless fruit
3799 has been given an already pluralized name)
3800 or for plural amount */
3801 if (ftyp == 2 && !cntf)
3803 else if (ftyp == 3 && !cntf)
3812 if (!oclass && actualn) {
3815 /* Perhaps it's an artifact specified by name, not type */
3816 name = artifact_name(actualn, &objtyp);
3822 /* Let wizards wish for traps and furniture.
3823 * Must come after objects check so wizards can still wish for
3824 * trap objects like beartraps.
3825 * Disallow such topology tweaks for WIZKIT startup wishes.
3828 if (wizard && !program_state.wizkit_wishing) {
3830 int trap, x = u.ux, y = u.uy;
3832 for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
3836 tname = defsyms[trap_to_defsym(trap)].explanation;
3837 if (strncmpi(tname, bp, strlen(tname)))
3839 /* found it; avoid stupid mistakes */
3840 if ((trap == TRAPDOOR || trap == HOLE) && !Can_fall_thru(&u.uz))
3842 if ((t = maketrap(x, y, trap)) != 0) {
3844 tname = defsyms[trap_to_defsym(trap)].explanation;
3845 pline("%s%s.", An(tname),
3846 (trap != MAGIC_PORTAL) ? "" : " to nowhere");
3848 pline("Creation of %s failed.", an(tname));
3852 /* furniture and terrain */
3855 if (!BSTRCMPI(bp, p - 8, "fountain")) {
3856 lev->typ = FOUNTAIN;
3857 level.flags.nfountains++;
3858 if (!strncmpi(bp, "magic ", 6))
3859 lev->blessedftn = 1;
3860 pline("A %sfountain.", lev->blessedftn ? "magic " : "");
3864 if (!BSTRCMPI(bp, p - 6, "throne")) {
3870 if (!BSTRCMPI(bp, p - 4, "sink")) {
3872 level.flags.nsinks++;
3877 /* ("water" matches "potion of water" rather than terrain) */
3878 if (!BSTRCMPI(bp, p - 4, "pool") || !BSTRCMPI(bp, p - 4, "moat")) {
3879 lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
3881 pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
3882 /* Must manually make kelp! */
3883 water_damage_chain(level.objects[x][y], TRUE);
3887 if (!BSTRCMPI(bp, p - 4, "lava")) { /* also matches "molten lava" */
3888 lev->typ = LAVAPOOL;
3890 pline("A pool of molten lava.");
3891 if (!(Levitation || Flying))
3892 (void) lava_effects();
3897 if (!BSTRCMPI(bp, p - 5, "altar")) {
3901 if (!strncmpi(bp, "chaotic ", 8))
3903 else if (!strncmpi(bp, "neutral ", 8))
3905 else if (!strncmpi(bp, "lawful ", 7))
3907 else if (!strncmpi(bp, "unaligned ", 10))
3909 else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
3910 al = (!rn2(6)) ? A_NONE : rn2((int) A_LAWFUL + 2) - 1;
3911 lev->altarmask = Align2amask(al);
3912 pline("%s altar.", An(align_str(al)));
3917 if (!BSTRCMPI(bp, p - 5, "grave")
3918 || !BSTRCMPI(bp, p - 9, "headstone")) {
3919 make_grave(x, y, (char *) 0);
3920 pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
3921 : "Can't place a grave here");
3926 if (!BSTRCMPI(bp, p - 4, "tree")) {
3934 if (!BSTRCMPI(bp, p - 4, "bars")) {
3935 lev->typ = IRONBARS;
3936 pline("Iron bars.");
3942 if (!oclass && !typ) {
3943 if (!strncmpi(bp, "polearm", 7)) {
3944 typ = rnd_otyp_by_wpnskill(P_POLEARMS);
3946 } else if (!strncmpi(bp, "hammer", 6)) {
3947 typ = rnd_otyp_by_wpnskill(P_HAMMER);
3953 return ((struct obj *) 0);
3956 oclass = wrpsym[rn2((int) sizeof(wrpsym))];
3959 oclass = objects[typ].oc_class;
3961 /* handle some objects that are only allowed in wizard mode */
3962 if (typ && !wizard) {
3964 case AMULET_OF_YENDOR:
3965 typ = FAKE_AMULET_OF_YENDOR;
3967 case CANDELABRUM_OF_INVOCATION:
3968 typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
3970 case BELL_OF_OPENING:
3973 case SPE_BOOK_OF_THE_DEAD:
3974 typ = SPE_BLANK_PAPER;
3980 /* catch any other non-wishable objects (venom) */
3981 if (objects[typ].oc_nowish)
3982 return (struct obj *) 0;
3988 * Create the object, then fine-tune it.
3990 otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
3991 typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
3993 if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN
3994 || Is_candle(otmp) || typ == POT_OIL)) {
3995 place_object(otmp, u.ux, u.uy); /* make it viable light source */
3996 begin_burn(otmp, FALSE);
3997 obj_extract_self(otmp); /* now release it for caller's use */
4000 /* if player specified a reasonable count, maybe honor it */
4001 if (cnt > 0 && objects[typ].oc_merge
4002 && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp))
4003 || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp))
4004 || typ == ROCK || is_missile(otmp)))))
4005 otmp->quan = (long) cnt;
4007 if (oclass == VENOM_CLASS)
4012 } else if (wizard) {
4013 ; /* no alteration to spe */
4014 } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
4016 || (oclass == RING_CLASS && objects[typ].oc_charged)) {
4017 if (spe > rnd(5) && spe > otmp->spe)
4019 if (spe > 2 && Luck < 0)
4022 if (oclass == WAND_CLASS) {
4023 if (spe > 1 && spesgn == -1)
4026 if (spe > 0 && spesgn == -1)
4029 if (spe > otmp->spe)
4036 /* set otmp->spe. This may, or may not, use spe... */
4039 if (contents == EMPTY) {
4040 otmp->corpsenm = NON_PM;
4042 } else if (contents == SPINACH) {
4043 otmp->corpsenm = NON_PM;
4049 otmp->spe = wetness;
4057 case HEAVY_IRON_BALL:
4060 /* otmp->cobj already done in mksobj() */
4069 otmp->spe = (rn2(10) ? -1 : 0);
4072 /* fall through, if wizard */
4077 /* set otmp->corpsenm or dragon scale [mail] */
4078 if (mntmp >= LOW_PM) {
4079 if (mntmp == PM_LONG_WORM_TAIL)
4080 mntmp = PM_LONG_WORM;
4084 otmp->spe = 0; /* No spinach */
4085 if (dead_species(mntmp, FALSE)) {
4086 otmp->corpsenm = NON_PM; /* it's empty */
4087 } else if (!(mons[mntmp].geno & G_UNIQ)
4088 && !(mvitals[mntmp].mvflags & G_NOCORPSE)
4089 && mons[mntmp].cnutrit != 0) {
4090 otmp->corpsenm = mntmp;
4094 if (!(mons[mntmp].geno & G_UNIQ)
4095 && !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
4096 if (mons[mntmp].msound == MS_GUARDIAN)
4097 mntmp = genus(mntmp, 1);
4098 set_corpsenm(otmp, mntmp);
4102 if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4104 && mntmp != PM_MAIL_DAEMON
4107 otmp->corpsenm = mntmp;
4110 mntmp = can_be_hatched(mntmp);
4111 /* this also sets hatch timer if appropriate */
4112 set_corpsenm(otmp, mntmp);
4115 otmp->corpsenm = mntmp;
4116 if (Has_contents(otmp) && verysmall(&mons[mntmp]))
4117 delete_contents(otmp); /* no spellbook */
4118 otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
4121 /* Dragon mail - depends on the order of objects & dragons. */
4122 if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON)
4123 otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4128 /* set blessed/cursed -- setting the fields directly is safe
4129 * since weight() is called below and addinv() will take care
4133 } else if (uncursed) {
4135 otmp->cursed = (Luck < 0 && !wizard);
4136 } else if (blessed) {
4137 otmp->blessed = (Luck >= 0 || wizard);
4138 otmp->cursed = (Luck < 0 && !wizard);
4139 } else if (spesgn < 0) {
4144 if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
4145 if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
4146 otmp->oeroded = eroded;
4147 if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
4148 otmp->oeroded2 = eroded2;
4150 /* set erodeproof */
4151 if (erodeproof && !eroded && !eroded2)
4152 otmp->oerodeproof = (Luck >= 0 || wizard);
4155 /* set otmp->recharged */
4156 if (oclass == WAND_CLASS) {
4157 /* prevent wishing abuse */
4158 if (otmp->otyp == WAN_WISHING && !wizard)
4160 otmp->recharged = (unsigned) rechrg;
4165 if (is_poisonable(otmp))
4166 otmp->opoisoned = (Luck >= 0);
4167 else if (oclass == FOOD_CLASS)
4168 /* try to taint by making it as old as possible */
4171 /* and [un]trapped */
4173 if (Is_box(otmp) || typ == TIN)
4174 otmp->otrapped = (trapped == 1);
4180 if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4183 /* set tin variety */
4184 if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4185 set_tin_variety(otmp, tvariety);
4191 /* an artifact name might need capitalization fixing */
4192 aname = artifact_name(name, &objtyp);
4193 if (aname && objtyp == otmp->otyp)
4196 /* 3.6.0 tribute - fix up novel */
4197 if (otmp->otyp == SPE_NOVEL) {
4198 const char *novelname;
4200 novelname = lookup_novel(name, &otmp->novelidx);
4205 otmp = oname(otmp, name);
4206 if (otmp->oartifact) {
4208 u.uconduct.wisharti++; /* KMH, conduct */
4212 /* more wishing abuse: don't allow wishing for certain artifacts */
4213 /* and make them pay; charge them for the wish anyway! */
4214 if ((is_quest_artifact(otmp)
4215 || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) {
4216 artifact_exists(otmp, safe_oname(otmp), FALSE);
4217 obfree(otmp, (struct obj *) 0);
4220 pline("For a moment, you feel %s in your %s, but it disappears!",
4222 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",
4223 something, makeplural(body_part(HAND)));
4226 if (halfeaten && otmp->oclass == FOOD_CLASS) {
4227 if (otmp->otyp == CORPSE)
4228 otmp->oeaten = mons[otmp->corpsenm].cnutrit;
4230 otmp->oeaten = objects[otmp->otyp].oc_nutrition;
4231 /* (do this adjustment before setting up object's weight) */
4232 consume_oeaten(otmp, 1);
4234 otmp->owt = weight(otmp);
4235 if (very && otmp->otyp == HEAVY_IRON_BALL)
4242 rnd_class(first, last)
4249 for (i = first; i <= last; i++)
4250 sum += objects[i].oc_prob;
4251 if (!sum) /* all zero */
4252 return first + rn2(last - first + 1);
4254 for (i = first; i <= last; i++)
4255 if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
4260 STATIC_OVL const char *
4261 Japanese_item_name(i)
4264 struct Jitem *j = Japanese_items;
4271 return (const char *) 0;
4275 suit_simple_name(suit)
4278 const char *suitnm, *esuitp;
4280 if (Is_dragon_mail(suit))
4281 return "dragon mail"; /* <color> dragon scale mail */
4282 else if (Is_dragon_scales(suit))
4283 return "dragon scales";
4284 suitnm = OBJ_NAME(objects[suit->otyp]);
4285 esuitp = eos((char *) suitnm);
4286 if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
4287 return "mail"; /* most suits fall into this category */
4288 else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
4289 return "jacket"; /* leather jacket */
4290 /* suit is lame but armor is ambiguous and body armor is absurd */
4295 cloak_simple_name(cloak)
4299 switch (cloak->otyp) {
4304 return "
\83\8d\81[
\83u";
4305 case MUMMY_WRAPPING:
4311 return (objects[cloak->otyp].oc_name_known && cloak->dknown)
4315 ? "
\83X
\83\82\83b
\83N"
4319 : "
\83G
\83v
\83\8d\83\93";
4327 return "
\83N
\83\8d\81[
\83N";
4330 /* helm vs hat for messages */
4332 helm_simple_name(helmet)
4336 * There is some wiggle room here; the result has been chosen
4337 * for consistency with the "protected by hard helmet" messages
4338 * given for various bonks on the head: headgear that provides
4339 * such protection is a "helm", that which doesn't is a "hat".
4341 * elven leather helm / leather hat -> hat
4342 * dwarvish iron helm / hard hat -> helm
4343 * The rest are completely straightforward:
4344 * fedora, cornuthaum, dunce cap -> hat
4345 * all other types of helmets -> helm
4348 return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
4350 return (helmet && !is_metallic(helmet)) ? "
\96X
\8eq" : "
\8a\95";
4354 mimic_obj_name(mtmp)
4357 if (mtmp->m_ap_type == M_AP_OBJECT
4358 && mtmp->mappearance != STRANGE_OBJECT) {
4359 int idx = objects[mtmp->mappearance].oc_descr_idx;
4360 if (mtmp->mappearance == GOLD_PIECE)
4365 return obj_descr[idx].oc_name;
4368 return "whatcha-may-callit";
4370 return "
\89½
\82Æ
\82©
\82¢
\82¤
\82à
\82Ì";
4374 * Construct a query prompt string, based around an object name, which is
4375 * guaranteed to fit within [QBUFSZ]. Takes an optional prefix, three
4376 * choices for filling in the middle (two object formatting functions and a
4377 * last resort literal which should be very short), and an optional suffix.
4380 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
4381 char *qbuf; /* output buffer */
4382 const char *qprefix, *qsuffix;
4384 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
4388 /* convert size_t (or int for ancient systems) to ordinary unsigned */
4389 unsigned len, lenlimit,
4390 len_qpfx = (unsigned) (qprefix ? strlen(qprefix) : 0),
4391 len_qsfx = (unsigned) (qsuffix ? strlen(qsuffix) : 0),
4392 len_lastR = (unsigned) strlen(lastR);
4394 lenlimit = QBUFSZ - 1;
4395 endp = qbuf + lenlimit;
4396 /* sanity check, aimed mainly at paniclog (it's conceivable for
4397 the result of short_oname() to be shorter than the length of
4398 the last resort string, but we ignore that possibility here) */
4399 if (len_qpfx > lenlimit)
4400 impossible("safe_qbuf: prefix too long (%u characters).", len_qpfx);
4401 else if (len_qpfx + len_qsfx > lenlimit)
4402 impossible("safe_qbuf: suffix too long (%u + %u characters).",
4403 len_qpfx, len_qsfx);
4404 else if (len_qpfx + len_lastR + len_qsfx > lenlimit)
4405 impossible("safe_qbuf: filler too long (%u + %u + %u characters).",
4406 len_qpfx, len_lastR, len_qsfx);
4408 /* the output buffer might be the same as the prefix if caller
4409 has already partially filled it */
4410 if (qbuf == qprefix) {
4411 /* prefix is already in the buffer */
4413 } else if (qprefix) {
4414 /* put prefix into the buffer */
4415 (void) strncpy(qbuf, qprefix, lenlimit);
4418 /* no prefix; output buffer starts out empty */
4421 len = (unsigned) strlen(qbuf);
4423 if (len + len_lastR + len_qsfx > lenlimit) {
4424 /* too long; skip formatting, last resort output is truncated */
4425 if (len < lenlimit) {
4426 (void) strncpy(&qbuf[len], lastR, lenlimit - len);
4428 len = (unsigned) strlen(qbuf);
4429 if (qsuffix && len < lenlimit) {
4430 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
4432 /* len = (unsigned) strlen(qbuf); */
4436 /* suffix and last resort are guaranteed to fit */
4437 len += len_qsfx; /* include the pending suffix */
4438 /* format the object */
4439 bufp = short_oname(obj, func, altfunc, lenlimit - len);
4440 if (len + strlen(bufp) <= lenlimit)
4441 Strcat(qbuf, bufp); /* formatted name fits */
4443 Strcat(qbuf, lastR); /* use last resort */
4447 Strcat(qbuf, qsuffix);
4449 /* assert( strlen(qbuf) < QBUFSZ ); */