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];
1083 char tmpbuf[PREFIX + 1]; /* for when we have to add something at
1084 the start of prefix instead of the
1085 end (Strcat is used on the end) */
1086 register char *bp = xname(obj);
1087 #if 1 /*JP*//*
\8f\87\8f\98\93ü
\82ê
\91Ö
\82¦
\82É
\8eg
\82¤*/
1088 char preprefix[PREFIX];
1091 if (iflags.override_ID) {
1092 known = cknown = bknown = lknown = TRUE;
1095 cknown = obj->cknown;
1096 bknown = obj->bknown;
1097 lknown = obj->lknown;
1100 /* When using xname, we want "poisoned arrow", and when using
1101 * doname, we want "poisoned +0 arrow". This kludge is about the only
1102 * way to do it, at least until someone overhauls xname() and doname(),
1103 * combining both into one function taking a parameter.
1105 /* must check opoisoned--someone can have a weirdly-named fruit */
1107 if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) {
1112 if (!strncmp(bp, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½", 12) && obj->opoisoned) {
1119 *
\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
1120 *
\82Ì
\82Ù
\82¤
\82ª
\8e©
\91R
\82Å
\82 \82é
\81D
1124 preprefix[0] = '\0';
1125 if((tp = strstri(bp, "
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½")) != NULL){
1126 tp += 12; /*
\81u
\96¼
\82Ã
\82¯
\82ç
\82ê
\82½
\81v*/
1127 strncpy(preprefix, bp, tp - bp);
1128 preprefix[tp - bp] = '\0';
1135 if (obj->quan != 1L) {
1137 Sprintf(prefix, "%ld ", obj->quan);
1138 #else /*
\93ú
\96{
\8cê
\82Æ
\82µ
\82Ä
\82Í
\90\94\8e\8c\82ª
\82È
\82¢
\82Ì
\82Í
\95s
\8e©
\91R */
1139 Sprintf(prefix, "%ld%s
\82Ì", obj->quan, numeral(obj));
1141 } else if (obj->otyp == CORPSE) {
1142 /* skip article prefix for corpses [else corpse_xname()
1143 would have to be taught how to strip it off again] */
1145 #if 0 /*JP*/ /*
\8a¥
\8e\8c\82Í
\95s
\97v */
1146 } else if (obj_is_pname(obj) || the_unique_obj(obj)) {
1147 if (!strncmpi(bp, "the ", 4))
1149 Strcpy(prefix, "the ");
1151 Strcpy(prefix, "a ");
1152 #else /*prefix
\82Ì
\8f\89\8aú
\89»*/
1158 /* "empty" goes at the beginning, but item count goes at the end */
1160 /* bag of tricks: include "empty" prefix if it's known to
1161 be empty but its precise number of charges isn't known
1162 (when that is known, suffix of "(n:0)" will be appended,
1163 making the prefix be redundant; note that 'known' flag
1164 isn't set when emptiness gets discovered because then
1165 charging magic would yield known number of new charges) */
1166 && (obj->otyp == BAG_OF_TRICKS
1167 ? (obj->spe == 0 && !obj->known)
1168 /* not bag of tricks: empty if container which has no contents */
1169 : (Is_container(obj) || obj->otyp == STATUE)
1170 && !Has_contents(obj)))
1172 Strcat(prefix, "empty ");
1174 Strcat(prefix, "
\8bó
\82Ì");
1176 if (bknown && obj->oclass != COIN_CLASS
1177 && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
1178 || (!obj->cursed && !obj->blessed))) {
1179 /* allow 'blessed clear potion' if we don't know it's holy water;
1180 * always allow "uncursed potion of water"
1184 Strcat(prefix, "cursed ");
1186 Strcat(prefix, "
\8eô
\82í
\82ê
\82½");
1187 else if (obj->blessed)
1189 Strcat(prefix, "blessed ");
1191 Strcat(prefix, "
\8fj
\95\9f\82³
\82ê
\82½");
1192 else if (!iflags.implicit_uncursed
1193 /* For most items with charges or +/-, if you know how many
1194 * charges are left or what the +/- is, then you must have
1195 * totally identified the item, so "uncursed" is unnecessary,
1196 * because an identified object not described as "blessed" or
1197 * "cursed" must be uncursed.
1199 * If the charges or +/- is not known, "uncursed" must be
1200 * printed to avoid ambiguity between an item whose curse
1201 * status is unknown, and an item known to be uncursed.
1203 || ((!known || !objects[obj->otyp].oc_charged
1204 || obj->oclass == ARMOR_CLASS
1205 || obj->oclass == RING_CLASS)
1207 && obj->otyp != SCR_MAIL
1209 && obj->otyp != FAKE_AMULET_OF_YENDOR
1210 && obj->otyp != AMULET_OF_YENDOR
1211 && !Role_if(PM_PRIEST)))
1213 Strcat(prefix, "uncursed ");
1215 Strcat(prefix, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢");
1218 if (lknown && Is_box(obj)) {
1221 Strcat(prefix, "unlockable ");
1223 Strcat(prefix, "
\8c®
\82Ì
\89ó
\82ê
\82½");
1224 else if (obj->olocked)
1226 Strcat(prefix, "locked ");
1228 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82½");
1231 Strcat(prefix, "unlocked ");
1233 Strcat(prefix, "
\8c®
\82Ì
\8a|
\82©
\82Á
\82Ä
\82¢
\82È
\82¢");
1238 Strcat(prefix, "greased ");
1240 Strcat(prefix, "
\96û
\82Ì
\93h
\82ç
\82ê
\82½");
1242 if (cknown && Has_contents(obj)) {
1243 /* we count all objects (obj->quantity); perhaps we should
1244 count separate stacks instead (or even introduce a user
1245 preference option to choose between the two alternatives)
1246 since it's somewhat odd so see "containing 1002 items"
1247 when there are 2 scrolls plus 1000 gold pieces */
1248 long itemcount = count_contents(obj, FALSE, FALSE, TRUE);
1251 Sprintf(eos(bp), " containing %ld item%s", itemcount,
1254 Sprintf(eos(bp), "(%ld
\8cÂ
\93ü
\82Á
\82Ä
\82¢
\82é)", itemcount);
1258 switch (obj->oclass) {
1260 if (obj->owornmask & W_AMUL)
1262 Strcat(bp, " (being worn)");
1264 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1269 Strcat(prefix, "poisoned ");
1271 Strcat(prefix, "
\93Å
\82Ì
\93h
\82ç
\82ê
\82½");
1273 add_erosion_words(obj, prefix);
1275 Strcat(prefix, sitoa(obj->spe));
1276 Strcat(prefix, " ");
1280 if (obj->owornmask & W_ARMOR)
1282 Strcat(bp, (obj == uskin) ? " (embedded in your skin)"
1284 Strcat(bp, (obj == uskin) ? "(
\94§
\82É
\96\84\82ß
\82±
\82Ü
\82ê
\82Ä
\82¢
\82é)"
1288 : "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1291 /* weptools already get this done when we go to the +n code */
1292 if (!is_weptool(obj))
1293 add_erosion_words(obj, prefix);
1294 if (obj->owornmask & (W_TOOL /* blindfold */ | W_SADDLE)) {
1296 Strcat(bp, " (being worn)");
1298 Strcat(bp, "(
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é)");
1301 if (obj->otyp == LEASH && obj->leashmon != 0) {
1303 Strcat(bp, " (in use)");
1305 Strcat(bp, "(
\8c\8b\82Ñ
\82Â
\82¯
\82Ä
\82¢
\82é)");
1308 if (is_weptool(obj))
1310 if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1313 Strcpy(tmpbuf, "no");
1315 Sprintf(tmpbuf, "%d", obj->spe);
1316 Sprintf(eos(bp), " (%s candle%s%s)", tmpbuf, plur(obj->spe),
1317 !obj->lamplit ? " attached" : ", lit");
1320 Sprintf(eos(bp), "(
\88ê
\96{
\82à
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢)");
1323 Sprintf(eos(bp), "(%d
\96{
\8eæ
\82è
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é)", obj->spe);
1325 Sprintf(eos(bp), "(%d
\96{
\8cõ
\82Á
\82Ä
\82¢
\82é)", obj->spe);
1329 } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
1330 || obj->otyp == BRASS_LANTERN || Is_candle(obj)) {
1332 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
1334 Strcat(prefix, "partly used ");
1336 Strcat(prefix, "
\8eg
\82¢
\82³
\82µ
\82Ì");
1339 Strcat(bp, " (lit)");
1341 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1344 if (objects[obj->otyp].oc_charged)
1348 add_erosion_words(obj, prefix);
1352 Sprintf(eos(bp), " (%d:%d)", (int) obj->recharged, obj->spe);
1354 Sprintf(eos(bp), "(%d:%d)", (int) obj->recharged, obj->spe);
1357 if (obj->otyp == POT_OIL && obj->lamplit)
1359 Strcat(bp, " (lit)");
1361 Strcat(bp, "(
\8cõ
\82Á
\82Ä
\82¢
\82é)");
1364 add_erosion_words(obj, prefix);
1366 if (obj->owornmask & W_RINGR)
1368 Strcat(bp, " (on right ");
1370 Strcat(bp, "(
\89E");
1371 if (obj->owornmask & W_RINGL)
1373 Strcat(bp, " (on left ");
1375 Strcat(bp, "(
\8d¶");
1376 if (obj->owornmask & W_RING) {
1377 Strcat(bp, body_part(HAND));
1380 if (known && objects[obj->otyp].oc_charged) {
1382 Strcat(prefix, " ");
1384 Strcat(prefix, sitoa(obj->spe));
1385 Strcat(prefix, " ");
1391 Strcat(prefix, "partly eaten ");
1393 Strcat(prefix, "
\90H
\82×
\82©
\82¯
\82Ì");
1394 if (obj->otyp == CORPSE) {
1396 Sprintf(prefix, "%s ",
1397 corpse_xname(obj, prefix, CXN_ARTICLE | CXN_NOCORPSE));
1399 Sprintf(prefix, "%s
\82Ì",
1400 corpse_xname(obj, prefix, CXN_ARTICLE | CXN_NOCORPSE));
1402 } else if (obj->otyp == EGG) {
1403 #if 0 /* corpses don't tell if they're stale either */
1404 if (known && stale_egg(obj))
1405 Strcat(prefix, "stale ");
1408 && (known || (mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
1410 Strcat(prefix, mons[omndx].mname);
1411 Strcat(prefix, " ");
1413 Strcat(prefix, mons[omndx].mname);
1414 Strcat(prefix, "
\82Ì");
1418 Strcat(bp, " (laid by you)");
1420 Strcat(bp, "(
\82 \82È
\82½
\82ª
\8eY
\82ñ
\82¾)");
1423 if (obj->otyp == MEAT_RING)
1428 add_erosion_words(obj, prefix);
1429 if (obj->owornmask & W_BALL)
1431 Strcat(bp, " (chained to you)");
1433 Strcat(bp, "(
\82 \82È
\82½
\82É
\8cq
\82ª
\82ê
\82Ä
\82¢
\82é)");
1437 if ((obj->owornmask & W_WEP) && !mrg_to_wielded) {
1438 if (obj->quan != 1L) {
1440 Strcat(bp, " (wielded)");
1442 Strcat(bp, "(
\91\95\94õ
\82µ
\82Ä
\82¢
\82é)");
1444 const char *hand_s = body_part(HAND);
1447 hand_s = makeplural(hand_s);
1449 Sprintf(eos(bp), " (weapon in %s)", hand_s);
1451 Sprintf(eos(bp), "(%s
\82É
\82µ
\82Ä
\82¢
\82é)", hand_s);
1453 if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) {
1454 /* presumably can be felt when blind */
1456 Strcat(bp, " (glowing");
1458 Sprintf(eos(bp), " %s", glow_color(obj->oartifact));
1462 Strcat(bp, " (
\94M
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82é)");
1464 Sprintf(eos(bp), " (%s
\8bP
\82¢
\82Ä
\82¢
\82é)",
1465 glow_color(obj->oartifact));
1470 if (obj->owornmask & W_SWAPWEP) {
1473 Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND));
1475 Sprintf(eos(bp), "(
\8d¶%s
\82É
\82µ
\82Ä
\82¢
\82é)", body_part(HAND));
1478 Strcat(bp, " (alternate weapon; not wielded)");
1480 Strcat(bp, "(
\97\
\94õ
\82Ì
\95\90\8aí;
\91\95\94õ
\82µ
\82Ä
\82¢
\82È
\82¢)");
1482 if (obj->owornmask & W_QUIVER) {
1483 switch (obj->oclass) {
1486 if (objects[obj->otyp].oc_skill == -P_BOW) {
1487 /* Ammo for a bow */
1489 Strcat(bp, " (in quiver)");
1491 Strcat(bp, "(
\96î
\93\9b\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1494 /* Ammo not for a bow */
1496 Strcat(bp, " (in quiver pouch)");
1498 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1502 /* Weapons not considered ammo */
1504 Strcat(bp, " (at the ready)");
1506 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1509 /* Small things and ammo not for a bow */
1516 Strcat(bp, " (in quiver pouch)");
1518 Strcat(bp, "(
\92e
\93ü
\82ê
\82É
\93ü
\82Á
\82Ä
\82¢
\82é)");
1520 default: /* odd things */
1522 Strcat(bp, " (at the ready)");
1524 Strcat(bp, "(
\8f\80\94õ
\82µ
\82Ä
\82¢
\82é)");
1527 if (!iflags.suppress_price && is_unpaid(obj)) {
1528 long quotedprice = unpaid_cost(obj, TRUE);
1530 Sprintf(eos(bp), " (%s, %ld %s)",
1531 obj->unpaid ? "unpaid" : "contents",
1532 quotedprice, currency(quotedprice));
1533 } else if (with_price) {
1534 long price = get_cost_of_shop_item(obj);
1537 Sprintf(eos(bp), " (%ld %s)", price, currency(price));
1539 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1540 if (!strncmp(prefix, "a ", 2)
1541 && index(vowels, *(prefix + 2) ? *(prefix + 2) : *bp)
1543 || (strncmp(bp, "uranium", 7) && strncmp(bp, "unicorn", 7)
1544 && strncmp(bp, "eucalyptus", 10)))) {
1545 Strcpy(tmpbuf, prefix);
1546 Strcpy(prefix, "an ");
1547 Strcpy(prefix + 3, tmpbuf + 2);
1551 /* show weight for items (debug tourist info)
1552 * aum is stolen from Crawl's "Arbitrary Unit of Measure" */
1554 Sprintf(eos(bp), " (%d aum)", obj->owt);
1557 bp = strprepend(bp, prefix);
1558 #else /*JP:
\81u
\96¼
\95t
\82¯
\82ç
\82ê
\82½
\81v
\82ð
\96ß
\82·*/
1559 Strcat(preprefix, prefix);
1560 bp = strprepend(bp, preprefix);
1567 register struct obj *obj;
1569 return doname_base(obj, FALSE);
1572 /* Name of object including price. */
1574 doname_with_price(obj)
1575 register struct obj *obj;
1577 return doname_base(obj, TRUE);
1580 /* used from invent.c */
1582 not_fully_identified(otmp)
1583 register struct obj *otmp;
1585 /* gold doesn't have any interesting attributes [yet?] */
1586 if (otmp->oclass == COIN_CLASS)
1587 return FALSE; /* always fully ID'd */
1588 /* check fundamental ID hallmarks first */
1589 if (!otmp->known || !otmp->dknown
1591 || (!otmp->bknown && otmp->otyp != SCR_MAIL)
1595 || !objects[otmp->otyp].oc_name_known)
1597 if ((!otmp->cknown && (Is_container(otmp) || otmp->otyp == STATUE))
1598 || (!otmp->lknown && Is_box(otmp)))
1600 if (otmp->oartifact && undiscovered_artifact(otmp->oartifact))
1602 /* otmp->rknown is the only item of interest if we reach here */
1604 * Note: if a revision ever allows scrolls to become fireproof or
1605 * rings to become shockproof, this checking will need to be revised.
1606 * `rknown' ID only matters if xname() will provide the info about it.
1609 || (otmp->oclass != ARMOR_CLASS && otmp->oclass != WEAPON_CLASS
1610 && !is_weptool(otmp) /* (redundant) */
1611 && otmp->oclass != BALL_CLASS)) /* (useless) */
1613 else /* lack of `rknown' only matters for vulnerable objects */
1614 return (boolean) (is_rustprone(otmp) || is_corrodeable(otmp)
1615 || is_flammable(otmp));
1619 corpse_xname(otmp, adjective, cxn_flags)
1621 const char *adjective;
1622 unsigned cxn_flags; /* bitmask of CXN_xxx values */
1624 char *nambuf = nextobuf();
1625 int omndx = otmp->corpsenm;
1626 boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
1627 /* suppress "the" from "the unique monster corpse" */
1628 no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
1629 /* include "the" for "the woodchuck corpse */
1630 the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
1631 /* include "an" for "an ogre corpse */
1632 any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
1633 /* leave off suffix (do_name() appends "corpse" itself) */
1634 omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, possessive = FALSE;
1637 if (omndx == NON_PM) { /* paranoia */
1642 /* [Possible enhancement: check whether corpse has monster traits
1643 attached in order to use priestname() for priests and minions.] */
1644 } else if (omndx == PM_ALIGNED_PRIEST) {
1645 /* avoid "aligned priest"; it just exposes internal details */
1651 mname = mons[omndx].mname;
1652 if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
1653 mname = s_suffix(mname);
1655 /* don't precede personal name like "Medusa" with an article */
1656 if (type_is_pname(&mons[omndx]))
1658 /* always precede non-personal unique monster name like
1659 "Oracle" with "the" unless explicitly overridden */
1660 else if (the_unique_pm(&mons[omndx]) && !no_prefix)
1665 the_prefix = any_prefix = FALSE;
1666 else if (the_prefix)
1667 any_prefix = FALSE; /* mutually exclusive */
1670 /* can't use the() the way we use an() below because any capitalized
1671 Name causes it to assume a personal name and return Name as-is;
1672 that's usually the behavior wanted, but here we need to force "the"
1673 to precede capitalized unique monsters (pnames are handled above) */
1674 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1676 Strcat(nambuf, "the ");
1679 if (!adjective || !*adjective) {
1680 /* normal case: newt corpse */
1681 Strcat(nambuf, mname);
1683 /* adjective positioning depends upon format of monster name */
1684 if (possessive) /* Medusa's cursed partly eaten corpse */
1686 Sprintf(eos(nambuf), "%s %s", mname, adjective);
1688 Sprintf(eos(nambuf), "%s%s", mname, adjective);
1689 else /* cursed partly eaten troll corpse */
1691 Sprintf(eos(nambuf), "%s %s", adjective, mname);
1693 Sprintf(eos(nambuf), "%s%s", adjective, mname);
1694 /* in case adjective has a trailing space, squeeze it out */
1696 /* doname() might include a count in the adjective argument;
1697 if so, don't prepend an article */
1698 if (digit(*adjective))
1704 Strcat(nambuf, " corpse");
1705 /* makeplural(nambuf) => append "s" to "corpse" */
1706 if (otmp->quan > 1L && !ignore_quan) {
1707 Strcat(nambuf, "s");
1708 any_prefix = FALSE; /* avoid "a newt corpses" */
1711 Strcat(nambuf, "
\82Ì
\8e\80\91Ì");
1715 /* it's safe to overwrite our nambuf after an() has copied
1716 its old value into another buffer */
1718 Strcpy(nambuf, an(nambuf));
1723 /* xname doesn't include monster type for "corpse"; cxname does */
1728 if (obj->otyp == CORPSE)
1729 return corpse_xname(obj, (const char *) 0, CXN_NORMAL);
1733 /* like cxname, but ignores quantity */
1735 cxname_singular(obj)
1738 if (obj->otyp == CORPSE)
1739 return corpse_xname(obj, (const char *) 0, CXN_SINGULAR);
1740 return xname_flags(obj, CXN_SINGULAR);
1743 /* treat an object as fully ID'd when it might be used as reason for death */
1748 struct obj save_obj;
1749 unsigned save_ocknown;
1750 char *buf, *save_ocuname, *save_oname = (char *) 0;
1752 /* bypass object twiddling for artifacts */
1754 return bare_artifactname(obj);
1756 /* remember original settings for core of the object;
1757 oextra structs other than oname don't matter here--since they
1758 aren't modified they don't need to be saved and restored */
1761 save_oname = ONAME(obj);
1763 /* killer name should be more specific than general xname; however, exact
1764 info like blessed/cursed and rustproof makes things be too verbose */
1765 obj->known = obj->dknown = 1;
1766 obj->bknown = obj->rknown = obj->greased = 0;
1767 /* if character is a priest[ess], bknown will get toggled back on */
1768 if (obj->otyp != POT_WATER)
1769 obj->blessed = obj->cursed = 0;
1771 obj->bknown = 1; /* describe holy/unholy water as such */
1772 /* "killed by poisoned <obj>" would be misleading when poison is
1773 not the cause of death and "poisoned by poisoned <obj>" would
1774 be redundant when it is, so suppress "poisoned" prefix */
1776 /* strip user-supplied name; artifacts keep theirs */
1777 if (!obj->oartifact && save_oname)
1778 ONAME(obj) = (char *) 0;
1779 /* temporarily identify the type of object */
1780 save_ocknown = objects[obj->otyp].oc_name_known;
1781 objects[obj->otyp].oc_name_known = 1;
1782 save_ocuname = objects[obj->otyp].oc_uname;
1783 objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
1785 /* format the object */
1786 if (obj->otyp == CORPSE) {
1788 Strcpy(buf, corpse_xname(obj, (const char *) 0, CXN_NORMAL));
1789 } else if (obj->otyp == SLIME_MOLD) {
1790 /* concession to "most unique deaths competition" in the annual
1791 devnull tournament, suppress player supplied fruit names because
1792 those can be used to fake other objects and dungeon features */
1795 Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
1797 Strcpy(buf, "
\8aë
\8c¯
\82È
\82Ë
\82Î
\82Ë
\82Î
\83J
\83r");
1801 /* apply an article if appropriate; caller should always use KILLED_BY */
1802 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\95s
\97v*/
1803 if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
1804 buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
1807 objects[obj->otyp].oc_name_known = save_ocknown;
1808 objects[obj->otyp].oc_uname = save_ocuname;
1809 *obj = save_obj; /* restore object's core settings */
1810 if (!obj->oartifact && save_oname)
1811 ONAME(obj) = save_oname;
1816 /* xname,doname,&c with long results reformatted to omit some stuff */
1818 short_oname(obj, func, altfunc, lenlimit)
1820 char *FDECL((*func), (OBJ_P)), /* main formatting routine */
1821 *FDECL((*altfunc), (OBJ_P)); /* alternate for shortest result */
1824 struct obj save_obj;
1825 char unamebuf[12], onamebuf[12], *save_oname, *save_uname, *outbuf;
1827 outbuf = (*func)(obj);
1828 if ((unsigned) strlen(outbuf) <= lenlimit)
1831 /* shorten called string to fairly small amount */
1832 save_uname = objects[obj->otyp].oc_uname;
1833 if (save_uname && strlen(save_uname) >= sizeof unamebuf) {
1834 (void) strncpy(unamebuf, save_uname, sizeof unamebuf - 4);
1835 Strcpy(unamebuf + sizeof unamebuf - 4, "...");
1836 objects[obj->otyp].oc_uname = unamebuf;
1837 releaseobuf(outbuf);
1838 outbuf = (*func)(obj);
1839 objects[obj->otyp].oc_uname = save_uname; /* restore called string */
1840 if ((unsigned) strlen(outbuf) <= lenlimit)
1844 /* shorten named string to fairly small amount */
1845 save_oname = has_oname(obj) ? ONAME(obj) : 0;
1846 if (save_oname && strlen(save_oname) >= sizeof onamebuf) {
1847 (void) strncpy(onamebuf, save_oname, sizeof onamebuf - 4);
1848 Strcpy(onamebuf + sizeof onamebuf - 4, "...");
1849 ONAME(obj) = onamebuf;
1850 releaseobuf(outbuf);
1851 outbuf = (*func)(obj);
1852 ONAME(obj) = save_oname; /* restore named string */
1853 if ((unsigned) strlen(outbuf) <= lenlimit)
1857 /* shorten both called and named strings;
1858 unamebuf and onamebuf have both already been populated */
1859 if (save_uname && strlen(save_uname) >= sizeof unamebuf && save_oname
1860 && strlen(save_oname) >= sizeof onamebuf) {
1861 objects[obj->otyp].oc_uname = unamebuf;
1862 ONAME(obj) = onamebuf;
1863 releaseobuf(outbuf);
1864 outbuf = (*func)(obj);
1865 if ((unsigned) strlen(outbuf) <= lenlimit) {
1866 objects[obj->otyp].oc_uname = save_uname;
1867 ONAME(obj) = save_oname;
1872 /* still long; strip several name-lengthening attributes;
1873 called and named strings are still in truncated form */
1875 obj->bknown = obj->rknown = obj->greased = 0;
1876 obj->oeroded = obj->oeroded2 = 0;
1877 releaseobuf(outbuf);
1878 outbuf = (*func)(obj);
1879 if (altfunc && (unsigned) strlen(outbuf) > lenlimit) {
1880 /* still long; use the alternate function (usually one of
1881 the jackets around minimal_xname()) */
1882 releaseobuf(outbuf);
1883 outbuf = (*altfunc)(obj);
1885 /* restore the object */
1888 ONAME(obj) = save_oname;
1890 objects[obj->otyp].oc_uname = save_uname;
1892 /* use whatever we've got, whether it's too long or not */
1897 * Used if only one of a collection of objects is named (e.g. in eat.c).
1900 singular(otmp, func)
1901 register struct obj *otmp;
1902 char *FDECL((*func), (OBJ_P));
1907 /* using xname for corpses does not give the monster type */
1908 if (otmp->otyp == CORPSE && func == xname)
1911 savequan = otmp->quan;
1913 nam = (*func)(otmp);
1914 otmp->quan = savequan;
1920 register const char *str;
1922 char *buf = nextobuf();
1924 #if 0 /*JP*//*
\95s
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1927 if (strncmpi(str, "the ", 4) && strcmp(str, "molten lava")
1928 && strcmp(str, "iron bars") && strcmp(str, "ice")) {
1929 if (index(vowels, *str) && strncmp(str, "one-", 4)
1930 && strncmp(str, "useful", 6) && strncmp(str, "unicorn", 7)
1931 && strncmp(str, "uranium", 7) && strncmp(str, "eucalyptus", 10))
1938 #else /*
\92P
\82É
\83R
\83s
\81[*/
1948 char *tmp = an(str);
1950 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
1957 * Prepend "the" if necessary; assumes str is a subject derived from xname.
1958 * Use type_is_pname() for monster names, not the(). the() is idempotent.
1964 char *buf = nextobuf();
1965 #if 0 /*JP*//*
\92è
\8a¥
\8e\8c\82Í
\95s
\97v*/
1966 boolean insert_the = FALSE;
1968 if (!strncmpi(str, "the ", 4)) {
1969 buf[0] = lowc(*str);
1970 Strcpy(&buf[1], str + 1);
1972 } else if (*str < 'A' || *str > 'Z') {
1973 /* not a proper name, needs an article */
1976 /* Probably a proper name, might not need an article */
1977 register char *tmp, *named, *called;
1980 /* some objects have capitalized adjectives in their names */
1981 if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0)
1982 && (tmp[1] < 'A' || tmp[1] > 'Z')) {
1984 } else if (tmp && index(str, ' ') < tmp) { /* has spaces */
1985 /* it needs an article if the name contains "of" */
1986 tmp = strstri(str, " of ");
1987 named = strstri(str, " named ");
1988 called = strstri(str, " called ");
1989 if (called && (!named || called < named))
1992 if (tmp && (!named || tmp < named)) /* found an "of" */
1994 /* stupid special case: lacks "of" but needs "the" */
1995 else if (!named && (l = strlen(str)) >= 31
1996 && !strcmp(&str[l - 31],
1997 "Platinum Yendorian Express Card"))
2002 Strcpy(buf, "the ");
2007 #else /*
\92P
\82É
\83R
\83s
\81[*/
2017 char *tmp = the(str);
2019 #if 0 /*JP*//*
\91å
\95¶
\8e\9a\89»
\82µ
\82È
\82¢*/
2028 register struct obj *otmp;
2029 register const char *verb;
2035 /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */
2041 char prefix[PREFIX];
2042 char *bp = cxname(otmp);
2044 if (otmp->quan != 1L) {
2045 Sprintf(prefix, "%ld ", otmp->quan);
2046 bp = strprepend(bp, prefix);
2050 Strcat(bp, otense(otmp, verb));
2056 /* combine yname and aobjnam eg "your count cxname(otmp)" */
2062 char *s = aobjnam(obj, verb);
2064 /* leave off "your" for most of your artifacts, but prepend
2065 * "your" for unique objects and "foo of bar" quest artifacts */
2066 if (!carried(obj) || !obj_is_pname(obj)
2067 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2068 char *outbuf = shk_your(nextobuf(), obj);
2069 int space_left = BUFSZ - 1 - strlen(outbuf);
2071 s = strncat(outbuf, s, space_left);
2076 /* combine Yname2 and aobjnam eg "Your count cxname(otmp)" */
2082 register char *s = yobjnam(obj, verb);
2090 /* like aobjnam, but prepend "The", not count, and use xname */
2096 char *bp = The(xname(otmp));
2098 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2101 Strcat(bp, otense(otmp, verb));
2107 /* capitalized variant of doname() */
2112 char *s = doname(obj);
2118 /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */
2123 char *s = cxname(obj);
2125 /* leave off "your" for most of your artifacts, but prepend
2126 * "your" for unique objects and "foo of bar" quest artifacts */
2127 if (!carried(obj) || !obj_is_pname(obj)
2128 || obj->oartifact >= ART_ORB_OF_DETECTION) {
2129 char *outbuf = shk_your(nextobuf(), obj);
2130 int space_left = BUFSZ - 1 - strlen(outbuf);
2132 s = strncat(outbuf, s, space_left);
2138 /* capitalized variant of yname() */
2143 char *s = yname(obj);
2151 /* returns "your minimal_xname(obj)"
2152 * or "Foobar's minimal_xname(obj)"
2153 * or "the minimal_xname(obj)"
2159 char *outbuf = nextobuf();
2160 char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */
2162 int space_left = BUFSZ - 1 - strlen(s);
2164 return strncat(s, minimal_xname(obj), space_left);
2166 int space_left = BUFSZ - strlen(s);
2168 return strncat(s, minimal_xname(obj), space_left);
2172 /* capitalized variant of ysimple_name() */
2177 char *s = ysimple_name(obj);
2185 /* "scroll" or "scrolls" */
2190 char *simpleoname = minimal_xname(obj);
2192 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2193 if (obj->quan != 1L)
2194 simpleoname = makeplural(simpleoname);
2199 /* "a scroll" or "scrolls"; "a silver bell" or "the Bell of Opening" */
2204 char *simpleoname = simpleonames(obj);
2205 int otyp = obj->otyp;
2207 /* prefix with "the" if a unique item, or a fake one imitating same,
2208 has been formatted with its actual name (we let typename() handle
2209 any `known' and `dknown' checking necessary) */
2210 if (otyp == FAKE_AMULET_OF_YENDOR)
2211 otyp = AMULET_OF_YENDOR;
2212 if (objects[otyp].oc_unique
2213 && !strcmp(simpleoname, OBJ_NAME(objects[otyp])))
2214 return the(simpleoname);
2216 /* simpleoname is singular if quan==1, plural otherwise */
2217 if (obj->quan == 1L)
2218 simpleoname = an(simpleoname);
2222 /* "the scroll" or "the scrolls" */
2227 char *simpleoname = simpleonames(obj);
2229 return the(simpleoname);
2232 /* artifact's name without any object type or known/dknown/&c feedback */
2234 bare_artifactname(obj)
2239 if (obj->oartifact) {
2240 outbuf = nextobuf();
2241 Strcpy(outbuf, artiname(obj->oartifact));
2243 if (!strncmp(outbuf, "The ", 4))
2244 outbuf[0] = lowc(outbuf[0]);
2247 outbuf = xname(obj);
2252 static const char *wrp[] = {
2253 "wand", "ring", "potion", "scroll", "gem",
2254 "amulet", "spellbook", "spell book",
2255 /* for non-specific wishes */
2256 "weapon", "armor", "tool", "food", "comestible",
2258 static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
2259 SCROLL_CLASS, GEM_CLASS, AMULET_CLASS,
2260 SPBOOK_CLASS, SPBOOK_CLASS, WEAPON_CLASS,
2261 ARMOR_CLASS, TOOL_CLASS, FOOD_CLASS,
2264 /* return form of the verb (input plural) if xname(otmp) were the subject */
2273 * verb is given in plural (without trailing s). Return as input
2274 * if the result of xname(otmp) would be plural. Don't bother
2275 * recomputing xname(otmp) at this time.
2277 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2278 if (!is_plural(otmp))
2279 return vtense((char *) 0, verb);
2287 /* various singular words that vtense would otherwise categorize as plural;
2288 also used by makesingular() to catch some special cases */
2289 static const char *const special_subjs[] = {
2290 "erinys", "manes", /* this one is ambiguous */
2291 "Cyclops", "Hippocrates", "Pelias", "aklys",
2292 "amnesia", "detect monsters", "paralysis", "shape changers",
2294 /* note: "detect monsters" and "shape changers" are normally
2295 caught via "<something>(s) of <whatever>", but they can be
2296 wished for using the shorter form, so we include them here
2297 to accommodate usage by makesingular during wishing */
2300 /* return form of the verb (input plural) for present tense 3rd person subj */
2303 register const char *subj;
2304 register const char *verb;
2306 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82É
\82Í
\8eO
\92P
\8c»
\82Ìs
\82Í
\82È
\82¢*/
2307 char *buf = nextobuf(), *bspot;
2309 const char *sp, *spot;
2310 const char *const *spec;
2313 * verb is given in plural (without trailing s). Return as input
2314 * if subj appears to be plural. Add special cases as necessary.
2315 * Many hard cases can already be handled by using otense() instead.
2316 * If this gets much bigger, consider decomposing makeplural.
2317 * Note: monster names are not expected here (except before corpse).
2319 * Special case: allow null sobj to get the singular 3rd person
2320 * present tense form so we don't duplicate this code elsewhere.
2323 if (!strncmpi(subj, "a ", 2) || !strncmpi(subj, "an ", 3))
2325 spot = (const char *) 0;
2326 for (sp = subj; (sp = index(sp, ' ')) != 0; ++sp) {
2327 if (!strncmpi(sp, " of ", 4) || !strncmpi(sp, " from ", 6)
2328 || !strncmpi(sp, " called ", 8) || !strncmpi(sp, " named ", 7)
2329 || !strncmpi(sp, " labeled ", 9)) {
2335 len = (int) strlen(subj);
2337 spot = subj + len - 1;
2340 * plural: anything that ends in 's', but not '*us' or '*ss'.
2341 * Guess at a few other special cases that makeplural creates.
2343 if ((lowc(*spot) == 's' && spot != subj
2344 && !index("us", lowc(*(spot - 1))))
2345 || !BSTRNCMPI(subj, spot - 3, "eeth", 4)
2346 || !BSTRNCMPI(subj, spot - 3, "feet", 4)
2347 || !BSTRNCMPI(subj, spot - 1, "ia", 2)
2348 || !BSTRNCMPI(subj, spot - 1, "ae", 2)) {
2349 /* check for special cases to avoid false matches */
2350 len = (int) (spot - subj) + 1;
2351 for (spec = special_subjs; *spec; spec++) {
2352 ltmp = strlen(*spec);
2353 if (len == ltmp && !strncmpi(*spec, subj, len))
2355 /* also check for <prefix><space><special_subj>
2356 to catch things like "the invisible erinys" */
2357 if (len > ltmp && *(spot - ltmp) == ' '
2358 && !strncmpi(*spec, spot - ltmp + 1, ltmp))
2362 return strcpy(buf, verb);
2365 * 3rd person plural doesn't end in telltale 's';
2366 * 2nd person singular behaves as if plural.
2368 if (!strcmpi(subj, "they") || !strcmpi(subj, "you"))
2369 return strcpy(buf, verb);
2374 len = (int) strlen(buf);
2375 bspot = buf + len - 1;
2377 if (!strcmpi(buf, "are")) {
2378 Strcasecpy(buf, "is");
2379 } else if (!strcmpi(buf, "have")) {
2380 Strcasecpy(bspot - 1, "s");
2381 } else if (index("zxs", lowc(*bspot))
2382 || (len >= 2 && lowc(*bspot) == 'h'
2383 && index("cs", lowc(*(bspot - 1))))
2384 || (len == 2 && lowc(*bspot) == 'o')) {
2385 /* Ends in z, x, s, ch, sh; add an "es" */
2386 Strcasecpy(bspot + 1, "es");
2387 } else if (lowc(*bspot) == 'y' && !index(vowels, lowc(*(bspot - 1)))) {
2388 /* like "y" case in makeplural */
2389 Strcasecpy(bspot, "ies");
2391 Strcasecpy(bspot + 1, "s");
2404 const char *sing, *plur;
2407 /* word pairs that don't fit into formula-based transformations;
2408 also some suffices which have very few--often one--matches or
2409 which aren't systematically reversible (knives, staves) */
2410 static struct sing_plur one_off[] = {
2412 "children" }, /* (for wise guys who give their food funny names) */
2413 { "cubus", "cubi" }, /* in-/suc-cubus */
2414 { "culus", "culi" }, /* homunculus */
2415 { "djinni", "djinn" },
2416 { "erinys", "erinyes" },
2418 { "fungus", "fungi" },
2419 { "knife", "knives" },
2420 { "labrum", "labra" }, /* candelabrum */
2421 { "louse", "lice" },
2422 { "mouse", "mice" },
2423 { "mumak", "mumakil" },
2424 { "nemesis", "nemeses" },
2425 { "rtex", "rtices" }, /* vortex */
2426 { "tooth", "teeth" },
2427 { "staff", "staves" },
2431 static const char *const as_is[] = {
2432 /* makesingular() leaves these plural due to how they're used */
2433 "boots", "shoes", "gloves", "lenses", "scales",
2434 "eyes", "gauntlets", "iron bars",
2435 /* both singular and plural are spelled the same */
2436 "deer", "fish", "tuna", "yaki", "-hai",
2437 "krill", "manes", "ninja", "sheep", "ronin",
2438 "roshi", "shito", "tengu", "ki-rin", "Nazgul",
2439 "gunyoki", "piranha", "samurai", "shuriken", 0,
2440 /* Note: "fish" and "piranha" are collective plurals, suitable
2441 for "wiped out all <foo>". For "3 <foo>", they should be
2442 "fishes" and "piranhas" instead. We settle for collective
2443 variant instead of attempting to support both. */
2446 /* singularize/pluralize decisions common to both makesingular & makeplural
2449 singplur_lookup(basestr, endstring, to_plural, alt_as_is)
2450 char *basestr, *endstring; /* base string, pointer to eos(string) */
2451 boolean to_plural; /* true => makeplural, false => makesingular */
2452 const char *const *alt_as_is; /* another set like as_is[] */
2454 const struct sing_plur *sp;
2455 const char *same, *other, *const *as;
2458 for (as = as_is; *as; ++as) {
2459 al = (int) strlen(*as);
2460 if (!BSTRCMPI(basestr, endstring - al, *as))
2464 for (as = alt_as_is; *as; ++as) {
2465 al = (int) strlen(*as);
2466 if (!BSTRCMPI(basestr, endstring - al, *as))
2471 for (sp = one_off; sp->sing; sp++) {
2472 /* check whether endstring already matches */
2473 same = to_plural ? sp->plur : sp->sing;
2474 al = (int) strlen(same);
2475 if (!BSTRCMPI(basestr, endstring - al, same))
2476 return TRUE; /* use as-is */
2477 /* check whether it matches the inverse; if so, transform it */
2478 other = to_plural ? sp->sing : sp->plur;
2479 al = (int) strlen(other);
2480 if (!BSTRCMPI(basestr, endstring - al, other)) {
2481 Strcasecpy(endstring - al, same);
2482 return TRUE; /* one_off[] transformation */
2488 /* searches for common compounds, ex. lump of royal jelly */
2490 singplur_compound(str)
2493 /* if new entries are added, be sure to keep compound_start[] in sync */
2494 static const char *const compounds[] =
2496 " of ", " labeled ", " called ",
2497 " named ", " above", /* lurkers above */
2498 " versus ", " from ", " in ",
2499 " on ", " a la ", " with", /* " with "? */
2500 " de ", " d'", " du ",
2502 }, /* list of first characters for all compounds[] entries */
2503 compound_start[] = " -";
2505 const char *const *cmpd;
2508 for (p = str; *p; ++p) {
2509 /* substring starting at p can only match if *p is found
2510 within compound_start[] */
2511 if (!index(compound_start, *p))
2514 /* check current substring against all words in the compound[] list */
2515 for (cmpd = compounds; *cmpd; ++cmpd)
2516 if (!strncmpi(p, *cmpd, (int) strlen(*cmpd)))
2519 /* wasn't recognized as a compound phrase */
2523 /* Plural routine; chiefly used for user-defined fruits. We have to try to
2524 * account for everything reasonable the player has; something unreasonable
2525 * can still break the code. However, it's still a lot more accurate than
2526 * "just add an s at the end", which Rogue uses...
2528 * Also used for plural monster names ("Wiped out all homunculi." or the
2529 * vanquished monsters list) and body parts. A lot of unique monsters have
2530 * names which get mangled by makeplural and/or makesingular. They're not
2531 * genocidable, and vanquished-mon handling does its own special casing
2532 * (for uniques who've been revived and re-killed), so we don't bother
2533 * trying to get those right here.
2535 * Also misused by muse.c to convert 1st person present verbs to 2nd person.
2536 * 3.6.0: made case-insensitive.
2542 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2543 register char *spot;
2544 char lo_c, *str = nextobuf();
2545 const char *excess = (char *) 0;
2549 while (*oldstr == ' ')
2551 if (!oldstr || !*oldstr) {
2552 impossible("plural of null?");
2556 Strcpy(str, oldstr);
2559 * Skip changing "pair of" to "pairs of". According to Webster, usual
2560 * English usage is use pairs for humans, e.g. 3 pairs of dancers,
2561 * and pair for objects and non-humans, e.g. 3 pair of boots. We don't
2562 * refer to pairs of humans in this game so just skip to the bottom.
2564 if (!strncmpi(str, "pair of ", 8))
2567 /* look for "foo of bar" so that we can focus on "foo" */
2568 if ((spot = singplur_compound(str)) != 0) {
2569 excess = oldstr + (int) (spot - str);
2575 while (spot > str && *spot == ' ')
2576 spot--; /* Strip blanks from end */
2578 /* Now spot is the last character of the string */
2582 /* Single letters */
2583 if (len == 1 || !letter(*spot)) {
2584 Strcpy(spot + 1, "'s");
2588 /* dispense with some words which don't need pluralization */
2590 static const char *const already_plural[] = {
2591 "ae", /* algae, larvae, &c */
2592 "men", /* also catches women, watchmen */
2596 /* spot+1: synch up with makesingular's usage */
2597 if (singplur_lookup(str, spot + 1, TRUE, already_plural))
2600 /* more of same, but not suitable for blanket loop checking */
2601 if ((len == 2 && !strcmpi(str, "ya"))
2602 || (len >= 3 && !strcmpi(spot - 2, " ya")))
2606 /* man/men ("Wiped out all cavemen.") */
2607 if (len >= 3 && !strcmpi(spot - 2, "man")
2608 /* exclude shamans and humans */
2609 && (len < 6 || strcmpi(spot - 5, "shaman"))
2610 && (len < 5 || strcmpi(spot - 4, "human"))) {
2611 Strcasecpy(spot - 1, "en");
2614 if (lowc(*spot) == 'f') { /* (staff handled via one_off[]) */
2615 lo_c = lowc(*(spot - 1));
2616 if (len >= 3 && !strcmpi(spot - 2, "erf")) {
2617 /* avoid "nerf" -> "nerves", "serf" -> "serves" */
2618 ; /* fall through to default (append 's') */
2619 } else if (index("lr", lo_c) || index(vowels, lo_c)) {
2620 /* [aeioulr]f to [aeioulr]ves */
2621 Strcasecpy(spot, "ves");
2625 /* ium/ia (mycelia, baluchitheria) */
2626 if (len >= 3 && !strcmpi(spot - 2, "ium")) {
2627 Strcasecpy(spot - 2, "ia");
2630 /* algae, larvae, hyphae (another fungus part) */
2631 if ((len >= 4 && !strcmpi(spot - 3, "alga"))
2633 && (!strcmpi(spot - 4, "hypha") || !strcmpi(spot - 4, "larva")))
2634 || (len >= 6 && !strcmpi(spot - 5, "amoeba"))
2635 || (len >= 8 && (!strcmpi(spot - 7, "vertebra")))) {
2637 Strcasecpy(spot + 1, "e");
2640 /* fungus/fungi, homunculus/homunculi, but buses, lotuses, wumpuses */
2641 if (len > 3 && !strcmpi(spot - 1, "us")
2642 && !((len >= 5 && !strcmpi(spot - 4, "lotus"))
2643 || (len >= 6 && !strcmpi(spot - 5, "wumpus")))) {
2644 Strcasecpy(spot - 1, "i");
2647 /* sis/ses (nemesis) */
2648 if (len >= 3 && !strcmpi(spot - 2, "sis")) {
2649 Strcasecpy(spot - 1, "es");
2652 /* matzoh/matzot, possible food name */
2654 && (!strcmpi(spot - 5, "matzoh") || !strcmpi(spot - 5, "matzah"))) {
2655 Strcasecpy(spot - 1, "ot"); /* oh/ah -> ot */
2659 && (!strcmpi(spot - 4, "matzo") || !strcmpi(spot - 4, "matza"))) {
2660 Strcasecpy(spot, "ot"); /* o/a -> ot */
2664 /* note: -eau/-eaux (gateau, bordeau...) */
2665 /* note: ox/oxen, VAX/VAXen, goose/geese */
2669 /* Ends in z, x, s, ch, sh; add an "es" */
2670 if (index("zxs", lo_c)
2671 || (len >= 2 && lo_c == 'h' && index("cs", lowc(*(spot - 1))))
2672 /* Kludge to get "tomatoes" and "potatoes" right */
2673 || (len >= 4 && !strcmpi(spot - 2, "ato"))
2674 || (len >= 5 && !strcmpi(spot - 4, "dingo"))) {
2675 Strcasecpy(spot + 1, "es"); /* append es */
2678 /* Ends in y preceded by consonant (note: also "qu") change to "ies" */
2679 if (lo_c == 'y' && !index(vowels, lowc(*(spot - 1)))) {
2680 Strcasecpy(spot, "ies"); /* y -> ies */
2683 /* Default: append an 's' */
2684 Strcasecpy(spot + 1, "s");
2688 Strcat(str, excess);
2690 char *str = nextobuf();
2691 Strcpy(str, oldstr);
2697 * Singularize a string the user typed in; this helps reduce the complexity
2698 * of readobjnam, and is also used in pager.c to singularize the string
2699 * for which help is sought.
2701 * "Manes" is ambiguous: monster type (keep s), or horse body part (drop s)?
2702 * Its inclusion in as_is[]/special_subj[] makes it get treated as the former.
2704 * A lot of unique monsters have names ending in s; plural, or singular
2705 * from plural, doesn't make much sense for them so we don't bother trying.
2706 * 3.6.0: made case-insensitive.
2709 makesingular(oldstr)
2712 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Í
\92P
\95¡
\93¯
\8c^*/
2713 register char *p, *bp;
2714 const char *excess = 0;
2715 char *str = nextobuf();
2718 while (*oldstr == ' ')
2720 if (!oldstr || !*oldstr) {
2721 impossible("singular of null?");
2726 bp = strcpy(str, oldstr);
2728 /* check for "foo of bar" so that we can focus on "foo" */
2729 if ((p = singplur_compound(bp)) != 0) {
2730 excess = oldstr + (int) (p - bp);
2735 /* dispense with some words which don't need singularization */
2736 if (singplur_lookup(bp, p, FALSE, special_subjs))
2739 /* remove -s or -es (boxes) or -ies (rubies) */
2740 if (p >= bp + 1 && lowc(p[-1]) == 's') {
2741 if (p >= bp + 2 && lowc(p[-2]) == 'e') {
2742 if (p >= bp + 3 && lowc(p[-3]) == 'i') { /* "ies" */
2743 if (!BSTRCMPI(bp, p - 7, "cookies")
2744 || !BSTRCMPI(bp, p - 4, "pies")
2745 || !BSTRCMPI(bp, p - 5, "mbies") /* zombie */
2746 || !BSTRCMPI(bp, p - 5, "yries")) /* valkyrie */
2748 Strcasecpy(p - 3, "y"); /* ies -> y */
2751 /* wolves, but f to ves isn't fully reversible */
2752 if (p - 4 >= bp && (index("lr", lowc(*(p - 4)))
2753 || index(vowels, lowc(*(p - 4))))
2754 && !BSTRCMPI(bp, p - 3, "ves")) {
2755 if (!BSTRCMPI(bp, p - 6, "cloves")
2756 || !BSTRCMPI(bp, p - 6, "nerves"))
2758 Strcasecpy(p - 3, "f"); /* ves -> f */
2761 /* note: nurses, axes but boxes, wumpuses */
2762 if (!BSTRCMPI(bp, p - 4, "eses")
2763 || !BSTRCMPI(bp, p - 4, "oxes") /* boxes, foxes */
2764 || !BSTRCMPI(bp, p - 4, "nxes") /* lynxes */
2765 || !BSTRCMPI(bp, p - 4, "ches")
2766 || !BSTRCMPI(bp, p - 4, "uses") /* lotuses */
2767 || !BSTRCMPI(bp, p - 4, "sses") /* priestesses */
2768 || !BSTRCMPI(bp, p - 5, "atoes") /* tomatoes */
2769 || !BSTRCMPI(bp, p - 7, "dingoes")
2770 || !BSTRCMPI(bp, p - 7, "Aleaxes")) {
2771 *(p - 2) = '\0'; /* drop es */
2773 } /* else fall through to mins */
2775 /* ends in 's' but not 'es' */
2776 } else if (!BSTRCMPI(bp, p - 2, "us")) { /* lotus, fungus... */
2777 if (BSTRCMPI(bp, p - 6, "tengus") /* but not these... */
2778 && BSTRCMPI(bp, p - 7, "hezrous"))
2780 } else if (!BSTRCMPI(bp, p - 2, "ss")
2781 || !BSTRCMPI(bp, p - 5, " lens")
2782 || (p - 4 == bp && !strcmpi(p - 4, "lens"))) {
2786 *(p - 1) = '\0'; /* drop s */
2788 } else { /* input doesn't end in 's' */
2790 if (!BSTRCMPI(bp, p - 3, "men")) {
2791 Strcasecpy(p - 2, "an");
2794 /* matzot -> matzo, algae -> alga */
2795 if (!BSTRCMPI(bp, p - 6, "matzot") || !BSTRCMPI(bp, p - 2, "ae")) {
2796 *(p - 1) = '\0'; /* drop t/e */
2799 /* balactheria -> balactherium */
2800 if (p - 4 >= bp && !strcmpi(p - 2, "ia")
2801 && index("lr", lowc(*(p - 3))) && lowc(*(p - 4)) == 'e') {
2802 Strcasecpy(p - 1, "um"); /* a -> um */
2805 /* here we cannot find the plural suffix */
2809 /* if we stripped off a suffix (" of bar" from "foo of bar"),
2810 put it back now [strcat() isn't actually 100% safe here...] */
2816 char *str = nextobuf();
2817 Strcpy(str, oldstr);
2822 /* compare user string against object name string using fuzzy matching */
2824 wishymatch(u_str, o_str, retry_inverted)
2825 const char *u_str; /* from user, so might be variant spelling */
2826 const char *o_str; /* from objects[], so is in canonical form */
2827 boolean retry_inverted; /* optional extra "of" handling */
2829 static NEARDATA const char detect_SP[] = "detect ",
2830 SP_detection[] = " detection";
2831 char *p, buf[BUFSZ];
2833 /* ignore spaces & hyphens and upper/lower case when comparing */
2834 if (fuzzymatch(u_str, o_str, " -", TRUE))
2837 if (retry_inverted) {
2838 const char *u_of, *o_of;
2840 /* when just one of the strings is in the form "foo of bar",
2841 convert it into "bar foo" and perform another comparison */
2842 u_of = strstri(u_str, " of ");
2843 o_of = strstri(o_str, " of ");
2844 if (u_of && !o_of) {
2845 Strcpy(buf, u_of + 4);
2846 p = eos(strcat(buf, " "));
2847 while (u_str < u_of)
2850 return fuzzymatch(buf, o_str, " -", TRUE);
2851 } else if (o_of && !u_of) {
2852 Strcpy(buf, o_of + 4);
2853 p = eos(strcat(buf, " "));
2854 while (o_str < o_of)
2857 return fuzzymatch(u_str, buf, " -", TRUE);
2861 /* [note: if something like "elven speed boots" ever gets added, these
2862 special cases should be changed to call wishymatch() recursively in
2863 order to get the "of" inversion handling] */
2864 if (!strncmp(o_str, "dwarvish ", 9)) {
2865 if (!strncmpi(u_str, "dwarven ", 8))
2866 return fuzzymatch(u_str + 8, o_str + 9, " -", TRUE);
2867 } else if (!strncmp(o_str, "elven ", 6)) {
2868 if (!strncmpi(u_str, "elvish ", 7))
2869 return fuzzymatch(u_str + 7, o_str + 6, " -", TRUE);
2870 else if (!strncmpi(u_str, "elfin ", 6))
2871 return fuzzymatch(u_str + 6, o_str + 6, " -", TRUE);
2872 } else if (!strncmp(o_str, detect_SP, sizeof detect_SP - 1)) {
2873 /* check for "detect <foo>" vs "<foo> detection" */
2874 if ((p = strstri(u_str, SP_detection)) != 0
2875 && !*(p + sizeof SP_detection - 1)) {
2876 /* convert "<foo> detection" into "detect <foo>" */
2878 Strcat(strcpy(buf, detect_SP), u_str);
2879 /* "detect monster" -> "detect monsters" */
2880 if (!strcmpi(u_str, "monster"))
2883 return fuzzymatch(buf, o_str, " -", TRUE);
2885 } else if (strstri(o_str, SP_detection)) {
2886 /* and the inverse, "<foo> detection" vs "detect <foo>" */
2887 if (!strncmpi(u_str, detect_SP, sizeof detect_SP - 1)) {
2888 /* convert "detect <foo>s" into "<foo> detection" */
2889 p = makesingular(u_str + sizeof detect_SP - 1);
2890 Strcat(strcpy(buf, p), SP_detection);
2891 /* caller may be looping through objects[], so avoid
2892 churning through all the obufs */
2894 return fuzzymatch(buf, o_str, " -", TRUE);
2896 } else if (strstri(o_str, "ability")) {
2897 /* when presented with "foo of bar", makesingular() used to
2898 singularize both foo & bar, but now only does so for foo */
2899 /* catch "{potion(s),ring} of {gain,restore,sustain} abilities" */
2900 if ((p = strstri(u_str, "abilities")) != 0
2901 && !*(p + sizeof "abilities" - 1)) {
2902 (void) strncpy(buf, u_str, (unsigned) (p - u_str));
2903 Strcpy(buf + (p - u_str), "ability");
2904 return fuzzymatch(buf, o_str, " -", TRUE);
2906 } else if (!strcmp(o_str, "aluminum")) {
2907 /* this special case doesn't really fit anywhere else... */
2908 /* (note that " wand" will have been stripped off by now) */
2909 if (!strcmpi(u_str, "aluminium"))
2910 return fuzzymatch(u_str + 9, o_str + 8, " -", TRUE);
2917 const char *name, oclass;
2918 int f_o_range, l_o_range;
2921 /* wishable subranges of objects */
2922 STATIC_OVL NEARDATA const struct o_range o_ranges[] = {
2923 { "bag", TOOL_CLASS, SACK, BAG_OF_TRICKS },
2924 { "lamp", TOOL_CLASS, OIL_LAMP, MAGIC_LAMP },
2925 { "candle", TOOL_CLASS, TALLOW_CANDLE, WAX_CANDLE },
2926 { "horn", TOOL_CLASS, TOOLED_HORN, HORN_OF_PLENTY },
2927 { "shield", ARMOR_CLASS, SMALL_SHIELD, SHIELD_OF_REFLECTION },
2928 { "hat", ARMOR_CLASS, FEDORA, DUNCE_CAP },
2929 { "helm", ARMOR_CLASS, ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY },
2930 { "gloves", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
2931 { "gauntlets", ARMOR_CLASS, LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
2932 { "boots", ARMOR_CLASS, LOW_BOOTS, LEVITATION_BOOTS },
2933 { "shoes", ARMOR_CLASS, LOW_BOOTS, IRON_SHOES },
2934 { "cloak", ARMOR_CLASS, MUMMY_WRAPPING, CLOAK_OF_DISPLACEMENT },
2935 { "shirt", ARMOR_CLASS, HAWAIIAN_SHIRT, T_SHIRT },
2936 { "dragon scales", ARMOR_CLASS, GRAY_DRAGON_SCALES,
2937 YELLOW_DRAGON_SCALES },
2938 { "dragon scale mail", ARMOR_CLASS, GRAY_DRAGON_SCALE_MAIL,
2939 YELLOW_DRAGON_SCALE_MAIL },
2940 { "sword", WEAPON_CLASS, SHORT_SWORD, KATANA },
2941 { "venom", VENOM_CLASS, BLINDING_VENOM, ACID_VENOM },
2942 { "gray stone", GEM_CLASS, LUCKSTONE, FLINT },
2943 { "grey stone", GEM_CLASS, LUCKSTONE, FLINT },
2947 #if 0 /*JP*//*not used*/
2948 /* alternate spellings; if the difference is only the presence or
2949 absence of spaces and/or hyphens (such as "pickaxe" vs "pick axe"
2950 vs "pick-axe") then there is no need for inclusion in this list;
2951 likewise for ``"of" inversions'' ("boots of speed" vs "speed boots") */
2952 struct alt_spellings {
2956 { "pickax", PICK_AXE },
2957 { "whip", BULLWHIP },
2958 { "saber", SILVER_SABER },
2959 { "silver sabre", SILVER_SABER },
2960 { "smooth shield", SHIELD_OF_REFLECTION },
2961 { "grey dragon scale mail", GRAY_DRAGON_SCALE_MAIL },
2962 { "grey dragon scales", GRAY_DRAGON_SCALES },
2963 { "iron ball", HEAVY_IRON_BALL },
2964 { "lantern", BRASS_LANTERN },
2965 { "mattock", DWARVISH_MATTOCK },
2966 { "amulet of poison resistance", AMULET_VERSUS_POISON },
2967 { "potion of sleep", POT_SLEEPING },
2969 { "camera", EXPENSIVE_CAMERA },
2970 { "tee shirt", T_SHIRT },
2972 { "can opener", TIN_OPENER },
2973 { "kelp", KELP_FROND },
2974 { "eucalyptus", EUCALYPTUS_LEAF },
2975 { "royal jelly", LUMP_OF_ROYAL_JELLY },
2976 { "lembas", LEMBAS_WAFER },
2977 { "marker", MAGIC_MARKER },
2978 { "hook", GRAPPLING_HOOK },
2979 { "grappling iron", GRAPPLING_HOOK },
2980 { "grapnel", GRAPPLING_HOOK },
2981 { "grapple", GRAPPLING_HOOK },
2982 /* normally we wouldn't have to worry about unnecessary <space>, but
2983 " stone" will get stripped off, preventing a wishymatch; that actually
2984 lets "flint stone" be a match, so we also accept bogus "flintstone" */
2985 { "luck stone", LUCKSTONE },
2986 { "load stone", LOADSTONE },
2987 { "touch stone", TOUCHSTONE },
2988 { "flintstone", FLINT },
2989 { (const char *) 0, 0 },
2994 rnd_otyp_by_wpnskill(skill)
2998 short otyp = STRANGE_OBJECT;
2999 for (i = bases[WEAPON_CLASS];
3000 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3001 if (objects[i].oc_skill == skill) {
3007 for (i = bases[WEAPON_CLASS];
3008 i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++)
3009 if (objects[i].oc_skill == skill)
3017 * Return something wished for. Specifying a null pointer for
3018 * the user request string results in a random object. Otherwise,
3019 * if asking explicitly for "nothing" (or "nil") return no_wish;
3020 * if not an object return &zeroobj; if an error (no matching object),
3025 readobjnam(bp, no_wish)
3027 struct obj *no_wish;
3031 register struct obj *otmp;
3032 int cnt, spe, spesgn, typ, very, rechrg;
3033 int blessed, uncursed, iscursed, ispoisoned, isgreased;
3034 int eroded, eroded2, erodeproof;
3035 int halfeaten, mntmp, contents;
3036 int islit, unlabeled, ishistoric, isdiluted, trapped;
3037 int tmp, tinv, tvariety;
3040 int ftype = context.current_fruit;
3041 char fruitbuf[BUFSZ];
3046 /* Fruits may not mess up the ability to wish for real objects (since
3047 * you can leave a fruit in a bones file and it will be added to
3048 * another person's game), so they must be checked for last, after
3049 * stripping all the possible prefixes and seeing if there's a real
3050 * name in there. So we have to save the full original name. However,
3051 * it's still possible to do things like "uncursed burnt Alaska",
3052 * or worse yet, "2 burned 5 course meals", so we need to loop to
3053 * strip off the prefixes again, this time stripping only the ones
3055 * We could get even more detailed so as to allow food names with
3056 * prefixes that _are_ possible on food, so you could wish for
3057 * "2 3 alarm chilis". Currently this isn't allowed; options.c
3058 * automatically sticks 'candied' in front of such names.
3061 char *un, *dn, *actualn;
3062 const char *name = 0;
3064 cnt = spe = spesgn = typ = very = rechrg = blessed = uncursed = iscursed =
3065 ispoisoned = isgreased = eroded = eroded2 = erodeproof = halfeaten =
3066 islit = unlabeled = ishistoric = isdiluted = trapped = 0;
3067 tvariety = RANDOM_TIN;
3072 contents = UNDEFINED;
3074 actualn = dn = un = 0;
3079 /* first, remove extra whitespace they may have typed */
3080 (void) mungspaces(bp);
3081 /* allow wishing for "nothing" to preserve wishless conduct...
3082 [now requires "wand of nothing" if that's what was really wanted] */
3084 if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil")
3085 || !strcmpi(bp, "none"))
3087 if (!strcmpi(bp, "
\82È
\82µ") || !strcmpi(bp, "
\96³
\82µ"))
3090 /* save the [nearly] unmodified choice string */
3091 Strcpy(fruitbuf, bp);
3098 if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) {
3100 } else if (!strncmpi(bp, "the ", l = 4)) {
3101 ; /* just increment `bp' by `l' below */
3102 } else if (!cnt && digit(*bp) && strcmp(bp, "0")) {
3109 } else if (*bp == '+' || *bp == '-') {
3110 spesgn = (*bp++ == '+') ? 1 : -1;
3118 } else if (!strncmpi(bp, "blessed ", l = 8)
3119 || !strncmpi(bp, "holy ", l = 5)) {
3121 } else if (!strncmpi(bp, "
\8fj
\95\9f\82³
\82ê
\82½", l = 10)) {
3125 } else if (!strncmpi(bp, "moist ", l = 6)
3126 || !strncmpi(bp, "wet ", l = 4)) {
3128 } else if (!strncmpi(bp, "
\8e¼
\82Á
\82½", l = 6)
3129 || !strncmpi(bp, "
\94G
\82ê
\82½", l = 6)) {
3132 if (!strncmpi(bp, "wet ", 4))
3134 if (!strncmpi(bp, "
\94G
\82ê
\82½", 4))
3136 wetness = rn2(3) + 3;
3140 } else if (!strncmpi(bp, "cursed ", l = 7)
3141 || !strncmpi(bp, "unholy ", l = 7)) {
3143 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82½", l = 8)) {
3147 } else if (!strncmpi(bp, "uncursed ", l = 9)) {
3149 } else if (!strncmpi(bp, "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢", l = 9)) {
3153 } else if (!strncmpi(bp, "rustproof ", l = 10)
3154 || !strncmpi(bp, "erodeproof ", l = 11)
3155 || !strncmpi(bp, "corrodeproof ", l = 13)
3156 || !strncmpi(bp, "fixed ", l = 6)
3157 || !strncmpi(bp, "fireproof ", l = 10)
3158 || !strncmpi(bp, "rotproof ", l = 9)) {
3160 } else if (!strncmpi(bp, "
\8eK
\82Ñ
\82È
\82¢", l = 8)
3161 || !strncmpi(bp, "
\95\85\90H
\82µ
\82È
\82¢", l = 10)
3162 || !strncmpi(bp, "
\88À
\92è
\82µ
\82½", l = 8)
3163 || !strncmpi(bp, "
\94R
\82¦
\82È
\82¢", l = 8)) {
3166 } else if (!strncmpi(bp, "lit ", l = 4)
3167 || !strncmpi(bp, "burning ", l = 8)) {
3169 } else if (!strncmpi(bp, "unlit ", l = 6)
3170 || !strncmpi(bp, "extinguished ", l = 13)) {
3172 /* "unlabeled" and "blank" are synonymous */
3173 } else if (!strncmpi(bp, "unlabeled ", l = 10)
3174 || !strncmpi(bp, "unlabelled ", l = 11)
3175 || !strncmpi(bp, "blank ", l = 6)) {
3177 } else if (!strncmpi(bp, "poisoned ", l = 9)) {
3179 /* "trapped" recognized but not honored outside wizard mode */
3180 } else if (!strncmpi(bp, "trapped ", l = 8)) {
3181 trapped = 0; /* undo any previous "untrapped" */
3184 } else if (!strncmpi(bp, "untrapped ", l = 10)) {
3185 trapped = 2; /* not trapped */
3186 } else if (!strncmpi(bp, "greased ", l = 8)) {
3188 } else if (!strncmpi(bp, "very ", l = 5)) {
3189 /* very rusted very heavy iron ball */
3191 } else if (!strncmpi(bp, "thoroughly ", l = 11)) {
3193 } else if (!strncmpi(bp, "rusty ", l = 6)
3194 || !strncmpi(bp, "rusted ", l = 7)
3195 || !strncmpi(bp, "burnt ", l = 6)
3196 || !strncmpi(bp, "burned ", l = 7)) {
3199 } else if (!strncmpi(bp, "corroded ", l = 9)
3200 || !strncmpi(bp, "rotted ", l = 7)) {
3203 } else if (!strncmpi(bp, "partly eaten ", l = 13)
3204 || !strncmpi(bp, "partially eaten ", l = 16)) {
3206 } else if (!strncmpi(bp, "historic ", l = 9)) {
3208 } else if (!strncmpi(bp, "diluted ", l = 8)) {
3210 } else if (!strncmpi(bp, "empty ", l = 6)) {
3217 cnt = 1; /* %% what with "gems" etc. ? */
3218 if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) {
3219 boolean keeptrailingchars = TRUE;
3221 p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */
3222 ++p; /* advance past '(' */
3223 if (!strncmpi(p, "lit)", 4)) {
3225 p += 4 - 1; /* point at ')' */
3239 /* mis-matched parentheses; rest of string will be ignored
3240 * [probably we should restore everything back to '('
3241 * instead since it might be part of "named ..."]
3243 keeptrailingchars = FALSE;
3248 if (keeptrailingchars) {
3251 /* 'pp' points at 'pb's terminating '\0',
3252 'p' points at ')' and will be incremented past it */
3259 * otmp->spe is type schar, so we don't want spe to be any bigger or
3260 * smaller. Also, spe should always be positive --some cheaters may
3261 * try to confuse atoi().
3264 spesgn = -1; /* cheaters get what they deserve */
3267 if (spe > SCHAR_LIM)
3269 if (rechrg < 0 || rechrg > 7)
3270 rechrg = 7; /* recharge_limit */
3272 /* now we have the actual name, as delivered by xname, say
3273 * green potions called whisky
3274 * scrolls labeled "QWERTY"
3277 * very heavy iron ball named hoei
3281 if ((p = strstri(bp, " named ")) != 0) {
3285 if ((p = strstri(bp, " called ")) != 0) {
3288 /* "helmet called telepathy" is not "helmet" (a specific type)
3289 * "shield called reflection" is not "shield" (a general type)
3291 for (i = 0; i < SIZE(o_ranges); i++)
3292 if (!strcmpi(bp, o_ranges[i].name)) {
3293 oclass = o_ranges[i].oclass;
3297 if ((p = strstri(bp, " labeled ")) != 0) {
3300 } else if ((p = strstri(bp, " labelled ")) != 0) {
3304 if ((p = strstri(bp, " of spinach")) != 0) {
3309 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82µ
\82È
\82¢*/
3311 Skip over "pair of ", "pairs of", "set of" and "sets of".
3313 Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
3314 English either way. See makeplural() for more on pair/pairs.
3316 We should only double count if the object in question is not
3317 referred to as a "pair of". E.g. We should double if the player
3318 types "pair of spears", but not if the player types "pair of
3319 lenses". Luckily (?) all objects that are referred to as pairs
3320 -- boots, gloves, and lenses -- are also not mergable, so cnt is
3323 if (!strncmpi(bp, "pair of ", 8)) {
3326 } else if (cnt > 1 && !strncmpi(bp, "pairs of ", 9)) {
3329 } else if (!strncmpi(bp, "set of ", 7)) {
3331 } else if (!strncmpi(bp, "sets of ", 8)) {
3337 /* intercept pudding globs here; they're a valid wish target,
3338 * but we need them to not get treated like a corpse.
3340 * also don't let player wish for multiple globs.
3342 if ((p = strstri(bp, "glob of ")) != 0
3343 || (p = strstri(bp, "globs of ")) != 0) {
3344 int globoffset = (*(p + 4) == 's') ? 9 : 8;
3345 if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE
3346 && mntmp <= PM_BLACK_PUDDING) {
3347 mntmp = NON_PM; /* lie to ourselves */
3348 cnt = 0; /* force only one */
3352 * Find corpse type using "of" (figurine of an orc, tin of orc meat)
3353 * Don't check if it's a wand or spellbook.
3354 * (avoid "wand/finger of death" confusion).
3356 if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ")
3357 && !strstri(bp, "finger ")) {
3358 if (((p = strstri(bp, "tin of ")) != 0)
3359 && (tmp = tin_variety_txt(p + 7, &tinv))
3360 && (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) {
3363 } else if ((p = strstri(bp, " of ")) != 0
3364 && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
3368 /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
3369 if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
3370 if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
3371 if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
3372 if (strncmpi(bp, "master key",
3373 10)) /* not the "master" rank */
3374 if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
3375 if (mntmp < LOW_PM && strlen(bp) > 2
3376 && (mntmp = name_to_mon(bp)) >= LOW_PM) {
3378 mntmplen; /* double check for rank title */
3380 mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
3381 bp += mntmp != mntmptoo
3382 ? (int) strlen(mons[mntmp].mname)
3386 else if (!strncmpi(bp, "s ", 2))
3388 else if (!strncmpi(bp, "es ", 3))
3390 else if (!*bp && !actualn && !dn && !un
3392 /* no referent; they don't really mean a
3398 #else /*JP:
\81u(
\89ö
\95¨
\96¼)
\82Ì(
\83A
\83C
\83e
\83\80)
\81v
\91Î
\89\9e */
3400 if ((mntmp = name_to_mon(bp)) >= LOW_PM) {
3401 char *mp = mons[mntmp].mname;
3402 bp = strstri(bp, mp) + strlen(mp) + 2;
3407 #if 0 /*JP*//*
\92P
\90\94\89»
\82Í
\82µ
\82È
\82¢*/
3408 /* first change to singular if necessary */
3410 char *sng = makesingular(bp);
3411 if (strcmp(bp, sng)) {
3419 #if 0 /*JP*//*
\83X
\83y
\83\8b\97h
\82ê
\8f\88\97\9d\82Í
\82µ
\82È
\82¢*/
3420 /* Alternate spellings (pick-ax, silver sabre, &c) */
3422 struct alt_spellings *as = spellings;
3425 if (fuzzymatch(bp, as->sp, " -", TRUE)) {
3431 /* can't use spellings list for this one due to shuffling */
3432 if (!strncmpi(bp, "grey spell", 10))
3435 if ((p = strstri(bp, "armour")) != 0) {
3436 /* skip past "armo", then copy remainder beyond "u" */
3438 while ((*p = *(p + 1)) != '\0')
3439 ++p; /* self terminating */
3445 /* dragon scales - assumes order of dragons */
3446 if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON
3447 && mntmp <= PM_YELLOW_DRAGON) {
3448 typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3449 mntmp = NON_PM; /* no monster */
3453 /*JP:
\81u
\97Ø
\8aZ
\81v
\82ð
\90æ
\82É
\8f\88\97\9d\82µ
\82Ä
\82¨
\82 */
3454 if (!strcmpi(bp, "
\97Ø
\8aZ") && mntmp >= PM_GRAY_DRAGON
3455 && mntmp <= PM_YELLOW_DRAGON) {
3456 typ = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
3457 mntmp = NON_PM; /* no monster */
3461 if (!strcmpi(bp, "
\97Ø") && mntmp >= PM_GRAY_DRAGON
3462 && mntmp <= PM_YELLOW_DRAGON) {
3463 typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
3464 mntmp = NON_PM; /* no monster */
3471 if (!BSTRCMPI(bp, p - 10, "holy water")) {
3473 if ((p - bp) >= 12 && *(p - 12) == 'u')
3474 iscursed = 1; /* unholy water */
3479 #else /*JP:
\90¹
\90\85\82Æ
\95s
\8fò
\82È
\90\85\82ð
\95Ê
\82É
\94»
\92è*/
3480 if (!BSTRCMPI(bp, p - 4, "
\90¹
\90\85")) {
3485 if (!BSTRCMPI(bp, p - 4, "
\95s
\8fò
\82È
\90\85")) {
3492 if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) {
3494 if (unlabeled && !BSTRCMPI(bp, p - 4, "
\8aª
\95¨")) {
3496 typ = SCR_BLANK_PAPER;
3500 if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) {
3502 if (unlabeled && !BSTRCMPI(bp, p - 6, "
\96\82\96@
\8f\91")) {
3504 typ = SPE_BLANK_PAPER;
3508 * NOTE: Gold pieces are handled as objects nowadays, and therefore
3509 * this section should probably be reconsidered as well as the entire
3510 * gold/money concept. Maybe we want to add other monetary units as
3511 * well in the future. (TH)
3514 if (!BSTRCMPI(bp, p - 10, "gold piece") || !BSTRCMPI(bp, p - 7, "zorkmid")
3515 || !strcmpi(bp, "gold") || !strcmpi(bp, "money")
3516 || !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
3518 if (!BSTRCMPI(bp, p - 4, "
\8bà
\89Ý") || !BSTRCMPI(bp, p - 8, "
\83S
\81[
\83\8b\83h")
3519 || *bp == GOLD_SYM) {
3521 if (cnt > 5000 && !wizard)
3525 otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
3526 otmp->quan = (long) cnt;
3527 otmp->owt = weight(otmp);
3532 /* check for single character object class code ("/" for wand, &c) */
3533 if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES
3534 && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
3541 \89p
\8cê
\82È
\82ç XXXXX potion
\82Í
\95s
\8am
\92è
\96¼
\81Apotion of XXXXX
\82Í
\8am
\92è
\96¼
\82Æ
\82¢
\82¤
3542 \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¢
3544 /* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */
3545 /* false hits on, e.g., rings for "ring mail". */
3546 if (strncmpi(bp, "enchant ", 8) && strncmpi(bp, "destroy ", 8)
3547 && strncmpi(bp, "detect food", 11)
3548 && strncmpi(bp, "food detection", 14) && strncmpi(bp, "ring mail", 9)
3549 && strncmpi(bp, "studded leather armor", 21)
3550 && strncmpi(bp, "leather armor", 13)
3551 && strncmpi(bp, "tooled horn", 11) && strncmpi(bp, "food ration", 11)
3552 && strncmpi(bp, "meat ring", 9))
3553 for (i = 0; i < (int) (sizeof wrpsym); i++) {
3554 register int j = strlen(wrp[i]);
3555 if (!strncmpi(bp, wrp[i], j)) {
3557 if (oclass != AMULET_CLASS) {
3559 if (!strncmpi(bp, " of ", 4))
3561 /* else if(*bp) ?? */
3566 if (!BSTRCMPI(bp, p - j, wrp[i])) {
3570 if (p > bp && p[-1] == ' ')
3578 /* Wishing in wizard mode can create traps and furniture.
3579 * Part I: distinguish between trap and object for the two
3580 * types of traps which have corresponding objects: bear trap
3581 * and land mine. "beartrap" (object) and "bear trap" (trap)
3582 * have a difference in spelling which we used to exploit by
3583 * adding a special case in wishymatch(), but "land mine" is
3584 * spelled the same either way so needs different handing.
3585 * Since we need something else for land mine, we've dropped
3586 * the bear trap hack so that both are handled exactly the
3587 * same. To get an armed trap instead of a disarmed object,
3588 * the player can prefix either the object name or the trap
3589 * name with "trapped " (which ordinarily applies to chests
3590 * and tins), or append something--anything at all except for
3591 * " object", but " trap" is suggested--to either the trap
3592 * name or the object name.
3594 if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
3595 boolean beartrap = (lowc(*bp) == 'b');
3596 char *zp = bp + 4; /* skip "bear"/"land" */
3599 ++zp; /* embedded space is optional */
3600 if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
3602 if (trapped == 2 || !strcmpi(zp, " object")) {
3603 /* "untrapped <foo>" or "<foo> object" */
3604 typ = beartrap ? BEARTRAP : LAND_MINE;
3606 } else if (trapped == 1 || *zp != '\0') {
3607 /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
3608 int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
3610 /* use canonical trap spelling, skip object matching */
3611 Strcpy(bp, defsyms[idx].explanation);
3614 /* [no prefix or suffix; we're going to end up matching
3615 the object name and getting a disarmed trap object] */
3620 /* "grey stone" check must be before general "stone" */
3621 for (i = 0; i < SIZE(o_ranges); i++)
3622 if (!strcmpi(bp, o_ranges[i].name)) {
3623 typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
3627 if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) {
3628 p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0';
3632 } else if (!strcmpi(bp, "looking glass")) {
3633 ; /* avoid false hit on "* glass" */
3634 } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) {
3635 register char *g = bp;
3636 if (strstri(g, "broken"))
3637 return (struct obj *) 0;
3638 if (!strncmpi(g, "worthless ", 10))
3640 if (!strncmpi(g, "piece of ", 9))
3642 if (!strncmpi(g, "colored ", 8))
3644 else if (!strncmpi(g, "coloured ", 9))
3646 if (!strcmpi(g, "glass")) { /* choose random color */
3647 /* 9 different kinds */
3648 typ = LAST_GEM + rnd(9);
3649 if (objects[typ].oc_class == GEM_CLASS)
3652 typ = 0; /* somebody changed objects[]? punt */
3653 } else { /* try to construct canonical form */
3656 Strcpy(tbuf, "worthless piece of ");
3657 Strcat(tbuf, g); /* assume it starts with the color */
3664 dn = actualn; /* ex. "skull cap" */
3666 /* check real names of gems first */
3667 if (!oclass && actualn) {
3668 for (i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
3669 register const char *zn;
3671 if ((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
3677 i = oclass ? bases[(int) oclass] : 1;
3678 while (i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)) {
3679 register const char *zn;
3681 if (actualn && (zn = OBJ_NAME(objects[i])) != 0
3682 && wishymatch(actualn, zn, TRUE)) {
3687 if (dn && (zn = OBJ_DESCR(objects[i])) != 0
3688 && wishymatch(dn, zn, FALSE)) {
3690 *
\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É
3691 *
\82È
\82ç
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\81B
3692 *
\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
3694 if (i != FAKE_AMULET_OF_YENDOR &&
3695 dn && (zn = OBJ_DESCR(objects[i])) != 0
3696 && wishymatch(dn, zn, FALSE)) {
3698 /* don't match extra descriptions (w/o real name) */
3699 if (!OBJ_NAME(objects[i]))
3700 return (struct obj *) 0;
3704 if (un && (zn = objects[i].oc_uname) != 0
3705 && wishymatch(un, zn, FALSE)) {
3712 struct Jitem *j = Japanese_items;
3715 if (actualn && !strcmpi(actualn, j->name)) {
3722 /* if we've stripped off "armor" and failed to match anything
3723 in objects[], append "mail" and try again to catch misnamed
3724 requests like "plate armor" and "yellow dragon scale armor" */
3725 if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
3726 /* modifying bp's string is ok; we're about to resort
3727 to random armor if this also fails to match anything */
3728 Strcat(bp, " mail");
3732 if (!strcmpi(bp, "spinach")) {
3734 if (!strcmp(bp, "
\83z
\83E
\83\8c\83\93\91\90")) {
3740 /* Note: not strcmpi. 2 fruits, one capital, one not, are possible.
3741 Also not strncmp. We used to ignore trailing text with it, but
3742 that resulted in "grapefruit" matching "grape" if the latter came
3743 earlier than the former in the fruit list. */
3747 int blessedf, iscursedf, uncursedf, halfeatenf;
3749 blessedf = iscursedf = uncursedf = halfeatenf = 0;
3756 if (!strncmpi(fp, "an ", l = 3) || !strncmpi(fp, "a ", l = 2)) {
3758 } else if (!cntf && digit(*fp)) {
3765 } else if (!strncmpi(fp, "blessed ", l = 8)) {
3767 } else if (!strncmpi(fp, "cursed ", l = 7)) {
3769 } else if (!strncmpi(fp, "uncursed ", l = 9)) {
3771 } else if (!strncmpi(fp, "partly eaten ", l = 13)
3772 || !strncmpi(fp, "partially eaten ", l = 16)) {
3779 for (f = ffruit; f; f = f->nextf) {
3780 /* match type: 0=none, 1=exact, 2=singular, 3=plural */
3783 if (!strcmp(fp, f->fname))
3785 else if (!strcmp(fp, makesingular(f->fname)))
3787 else if (!strcmp(fp, makeplural(f->fname)))
3792 iscursed = iscursedf;
3793 uncursed = uncursedf;
3794 halfeaten = halfeatenf;
3795 /* adjust count if user explicitly asked for
3796 singular amount (can't happen unless fruit
3797 has been given an already pluralized name)
3798 or for plural amount */
3799 if (ftyp == 2 && !cntf)
3801 else if (ftyp == 3 && !cntf)
3810 if (!oclass && actualn) {
3813 /* Perhaps it's an artifact specified by name, not type */
3814 name = artifact_name(actualn, &objtyp);
3820 /* Let wizards wish for traps and furniture.
3821 * Must come after objects check so wizards can still wish for
3822 * trap objects like beartraps.
3823 * Disallow such topology tweaks for WIZKIT startup wishes.
3826 if (wizard && !program_state.wizkit_wishing) {
3828 int trap, x = u.ux, y = u.uy;
3830 for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
3834 tname = defsyms[trap_to_defsym(trap)].explanation;
3835 if (strncmpi(tname, bp, strlen(tname)))
3837 /* found it; avoid stupid mistakes */
3838 if ((trap == TRAPDOOR || trap == HOLE) && !Can_fall_thru(&u.uz))
3840 if ((t = maketrap(x, y, trap)) != 0) {
3842 tname = defsyms[trap_to_defsym(trap)].explanation;
3843 pline("%s%s.", An(tname),
3844 (trap != MAGIC_PORTAL) ? "" : " to nowhere");
3846 pline("Creation of %s failed.", an(tname));
3850 /* furniture and terrain */
3853 if (!BSTRCMPI(bp, p - 8, "fountain")) {
3854 lev->typ = FOUNTAIN;
3855 level.flags.nfountains++;
3856 if (!strncmpi(bp, "magic ", 6))
3857 lev->blessedftn = 1;
3858 pline("A %sfountain.", lev->blessedftn ? "magic " : "");
3862 if (!BSTRCMPI(bp, p - 6, "throne")) {
3868 if (!BSTRCMPI(bp, p - 4, "sink")) {
3870 level.flags.nsinks++;
3875 /* ("water" matches "potion of water" rather than terrain) */
3876 if (!BSTRCMPI(bp, p - 4, "pool") || !BSTRCMPI(bp, p - 4, "moat")) {
3877 lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
3879 pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
3880 /* Must manually make kelp! */
3881 water_damage_chain(level.objects[x][y], TRUE);
3885 if (!BSTRCMPI(bp, p - 4, "lava")) { /* also matches "molten lava" */
3886 lev->typ = LAVAPOOL;
3888 pline("A pool of molten lava.");
3889 if (!(Levitation || Flying))
3890 (void) lava_effects();
3895 if (!BSTRCMPI(bp, p - 5, "altar")) {
3899 if (!strncmpi(bp, "chaotic ", 8))
3901 else if (!strncmpi(bp, "neutral ", 8))
3903 else if (!strncmpi(bp, "lawful ", 7))
3905 else if (!strncmpi(bp, "unaligned ", 10))
3907 else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
3908 al = (!rn2(6)) ? A_NONE : rn2((int) A_LAWFUL + 2) - 1;
3909 lev->altarmask = Align2amask(al);
3910 pline("%s altar.", An(align_str(al)));
3915 if (!BSTRCMPI(bp, p - 5, "grave")
3916 || !BSTRCMPI(bp, p - 9, "headstone")) {
3917 make_grave(x, y, (char *) 0);
3918 pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
3919 : "Can't place a grave here");
3924 if (!BSTRCMPI(bp, p - 4, "tree")) {
3932 if (!BSTRCMPI(bp, p - 4, "bars")) {
3933 lev->typ = IRONBARS;
3934 pline("Iron bars.");
3940 if (!oclass && !typ) {
3941 if (!strncmpi(bp, "polearm", 7)) {
3942 typ = rnd_otyp_by_wpnskill(P_POLEARMS);
3944 } else if (!strncmpi(bp, "hammer", 6)) {
3945 typ = rnd_otyp_by_wpnskill(P_HAMMER);
3951 return ((struct obj *) 0);
3954 oclass = wrpsym[rn2((int) sizeof(wrpsym))];
3957 oclass = objects[typ].oc_class;
3959 /* handle some objects that are only allowed in wizard mode */
3960 if (typ && !wizard) {
3962 case AMULET_OF_YENDOR:
3963 typ = FAKE_AMULET_OF_YENDOR;
3965 case CANDELABRUM_OF_INVOCATION:
3966 typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
3968 case BELL_OF_OPENING:
3971 case SPE_BOOK_OF_THE_DEAD:
3972 typ = SPE_BLANK_PAPER;
3978 /* catch any other non-wishable objects (venom) */
3979 if (objects[typ].oc_nowish)
3980 return (struct obj *) 0;
3986 * Create the object, then fine-tune it.
3988 otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
3989 typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
3991 if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN
3992 || Is_candle(otmp) || typ == POT_OIL)) {
3993 place_object(otmp, u.ux, u.uy); /* make it viable light source */
3994 begin_burn(otmp, FALSE);
3995 obj_extract_self(otmp); /* now release it for caller's use */
3998 /* if player specified a reasonable count, maybe honor it */
3999 if (cnt > 0 && objects[typ].oc_merge
4000 && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp))
4001 || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp))
4002 || typ == ROCK || is_missile(otmp)))))
4003 otmp->quan = (long) cnt;
4005 if (oclass == VENOM_CLASS)
4010 } else if (wizard) {
4011 ; /* no alteration to spe */
4012 } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS
4014 || (oclass == RING_CLASS && objects[typ].oc_charged)) {
4015 if (spe > rnd(5) && spe > otmp->spe)
4017 if (spe > 2 && Luck < 0)
4020 if (oclass == WAND_CLASS) {
4021 if (spe > 1 && spesgn == -1)
4024 if (spe > 0 && spesgn == -1)
4027 if (spe > otmp->spe)
4034 /* set otmp->spe. This may, or may not, use spe... */
4037 if (contents == EMPTY) {
4038 otmp->corpsenm = NON_PM;
4040 } else if (contents == SPINACH) {
4041 otmp->corpsenm = NON_PM;
4047 otmp->spe = wetness;
4055 case HEAVY_IRON_BALL:
4058 /* otmp->cobj already done in mksobj() */
4067 otmp->spe = (rn2(10) ? -1 : 0);
4070 /* fall through, if wizard */
4075 /* set otmp->corpsenm or dragon scale [mail] */
4076 if (mntmp >= LOW_PM) {
4077 if (mntmp == PM_LONG_WORM_TAIL)
4078 mntmp = PM_LONG_WORM;
4082 otmp->spe = 0; /* No spinach */
4083 if (dead_species(mntmp, FALSE)) {
4084 otmp->corpsenm = NON_PM; /* it's empty */
4085 } else if (!(mons[mntmp].geno & G_UNIQ)
4086 && !(mvitals[mntmp].mvflags & G_NOCORPSE)
4087 && mons[mntmp].cnutrit != 0) {
4088 otmp->corpsenm = mntmp;
4092 if (!(mons[mntmp].geno & G_UNIQ)
4093 && !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
4094 if (mons[mntmp].msound == MS_GUARDIAN)
4095 mntmp = genus(mntmp, 1);
4096 set_corpsenm(otmp, mntmp);
4100 if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp])
4102 && mntmp != PM_MAIL_DAEMON
4105 otmp->corpsenm = mntmp;
4108 mntmp = can_be_hatched(mntmp);
4109 /* this also sets hatch timer if appropriate */
4110 set_corpsenm(otmp, mntmp);
4113 otmp->corpsenm = mntmp;
4114 if (Has_contents(otmp) && verysmall(&mons[mntmp]))
4115 delete_contents(otmp); /* no spellbook */
4116 otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
4119 /* Dragon mail - depends on the order of objects & dragons. */
4120 if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON)
4121 otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON;
4126 /* set blessed/cursed -- setting the fields directly is safe
4127 * since weight() is called below and addinv() will take care
4131 } else if (uncursed) {
4133 otmp->cursed = (Luck < 0 && !wizard);
4134 } else if (blessed) {
4135 otmp->blessed = (Luck >= 0 || wizard);
4136 otmp->cursed = (Luck < 0 && !wizard);
4137 } else if (spesgn < 0) {
4142 if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
4143 if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
4144 otmp->oeroded = eroded;
4145 if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
4146 otmp->oeroded2 = eroded2;
4148 /* set erodeproof */
4149 if (erodeproof && !eroded && !eroded2)
4150 otmp->oerodeproof = (Luck >= 0 || wizard);
4153 /* set otmp->recharged */
4154 if (oclass == WAND_CLASS) {
4155 /* prevent wishing abuse */
4156 if (otmp->otyp == WAN_WISHING && !wizard)
4158 otmp->recharged = (unsigned) rechrg;
4163 if (is_poisonable(otmp))
4164 otmp->opoisoned = (Luck >= 0);
4165 else if (oclass == FOOD_CLASS)
4166 /* try to taint by making it as old as possible */
4169 /* and [un]trapped */
4171 if (Is_box(otmp) || typ == TIN)
4172 otmp->otrapped = (trapped == 1);
4178 if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER)
4181 /* set tin variety */
4182 if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
4183 set_tin_variety(otmp, tvariety);
4189 /* an artifact name might need capitalization fixing */
4190 aname = artifact_name(name, &objtyp);
4191 if (aname && objtyp == otmp->otyp)
4194 /* 3.6.0 tribute - fix up novel */
4195 if (otmp->otyp == SPE_NOVEL) {
4196 const char *novelname;
4198 novelname = lookup_novel(name, &otmp->novelidx);
4203 otmp = oname(otmp, name);
4204 if (otmp->oartifact) {
4206 u.uconduct.wisharti++; /* KMH, conduct */
4210 /* more wishing abuse: don't allow wishing for certain artifacts */
4211 /* and make them pay; charge them for the wish anyway! */
4212 if ((is_quest_artifact(otmp)
4213 || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) {
4214 artifact_exists(otmp, safe_oname(otmp), FALSE);
4215 obfree(otmp, (struct obj *) 0);
4218 pline("For a moment, you feel %s in your %s, but it disappears!",
4220 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",
4221 something, makeplural(body_part(HAND)));
4224 if (halfeaten && otmp->oclass == FOOD_CLASS) {
4225 if (otmp->otyp == CORPSE)
4226 otmp->oeaten = mons[otmp->corpsenm].cnutrit;
4228 otmp->oeaten = objects[otmp->otyp].oc_nutrition;
4229 /* (do this adjustment before setting up object's weight) */
4230 consume_oeaten(otmp, 1);
4232 otmp->owt = weight(otmp);
4233 if (very && otmp->otyp == HEAVY_IRON_BALL)
4240 rnd_class(first, last)
4247 for (i = first; i <= last; i++)
4248 sum += objects[i].oc_prob;
4249 if (!sum) /* all zero */
4250 return first + rn2(last - first + 1);
4252 for (i = first; i <= last; i++)
4253 if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
4258 STATIC_OVL const char *
4259 Japanese_item_name(i)
4262 struct Jitem *j = Japanese_items;
4269 return (const char *) 0;
4273 suit_simple_name(suit)
4276 const char *suitnm, *esuitp;
4278 if (Is_dragon_mail(suit))
4279 return "dragon mail"; /* <color> dragon scale mail */
4280 else if (Is_dragon_scales(suit))
4281 return "dragon scales";
4282 suitnm = OBJ_NAME(objects[suit->otyp]);
4283 esuitp = eos((char *) suitnm);
4284 if (strlen(suitnm) > 5 && !strcmp(esuitp - 5, " mail"))
4285 return "mail"; /* most suits fall into this category */
4286 else if (strlen(suitnm) > 7 && !strcmp(esuitp - 7, " jacket"))
4287 return "jacket"; /* leather jacket */
4288 /* suit is lame but armor is ambiguous and body armor is absurd */
4293 cloak_simple_name(cloak)
4297 switch (cloak->otyp) {
4302 return "
\83\8d\81[
\83u";
4303 case MUMMY_WRAPPING:
4309 return (objects[cloak->otyp].oc_name_known && cloak->dknown)
4313 ? "
\83X
\83\82\83b
\83N"
4317 : "
\83G
\83v
\83\8d\83\93";
4325 return "
\83N
\83\8d\81[
\83N";
4328 /* helm vs hat for messages */
4330 helm_simple_name(helmet)
4334 * There is some wiggle room here; the result has been chosen
4335 * for consistency with the "protected by hard helmet" messages
4336 * given for various bonks on the head: headgear that provides
4337 * such protection is a "helm", that which doesn't is a "hat".
4339 * elven leather helm / leather hat -> hat
4340 * dwarvish iron helm / hard hat -> helm
4341 * The rest are completely straightforward:
4342 * fedora, cornuthaum, dunce cap -> hat
4343 * all other types of helmets -> helm
4346 return (helmet && !is_metallic(helmet)) ? "hat" : "helm";
4348 return (helmet && !is_metallic(helmet)) ? "
\96X
\8eq" : "
\8a\95";
4352 mimic_obj_name(mtmp)
4355 if (mtmp->m_ap_type == M_AP_OBJECT
4356 && mtmp->mappearance != STRANGE_OBJECT) {
4357 int idx = objects[mtmp->mappearance].oc_descr_idx;
4358 if (mtmp->mappearance == GOLD_PIECE)
4363 return obj_descr[idx].oc_name;
4366 return "whatcha-may-callit";
4368 return "
\89½
\82Æ
\82©
\82¢
\82¤
\82à
\82Ì";
4372 * Construct a query prompt string, based around an object name, which is
4373 * guaranteed to fit within [QBUFSZ]. Takes an optional prefix, three
4374 * choices for filling in the middle (two object formatting functions and a
4375 * last resort literal which should be very short), and an optional suffix.
4378 safe_qbuf(qbuf, qprefix, qsuffix, obj, func, altfunc, lastR)
4379 char *qbuf; /* output buffer */
4380 const char *qprefix, *qsuffix;
4382 char *FDECL((*func), (OBJ_P)), *FDECL((*altfunc), (OBJ_P));
4386 /* convert size_t (or int for ancient systems) to ordinary unsigned */
4387 unsigned len, lenlimit,
4388 len_qpfx = (unsigned) (qprefix ? strlen(qprefix) : 0),
4389 len_qsfx = (unsigned) (qsuffix ? strlen(qsuffix) : 0),
4390 len_lastR = (unsigned) strlen(lastR);
4392 lenlimit = QBUFSZ - 1;
4393 endp = qbuf + lenlimit;
4394 /* sanity check, aimed mainly at paniclog (it's conceivable for
4395 the result of short_oname() to be shorter than the length of
4396 the last resort string, but we ignore that possibility here) */
4397 if (len_qpfx > lenlimit)
4398 impossible("safe_qbuf: prefix too long (%u characters).", len_qpfx);
4399 else if (len_qpfx + len_qsfx > lenlimit)
4400 impossible("safe_qbuf: suffix too long (%u + %u characters).",
4401 len_qpfx, len_qsfx);
4402 else if (len_qpfx + len_lastR + len_qsfx > lenlimit)
4403 impossible("safe_qbuf: filler too long (%u + %u + %u characters).",
4404 len_qpfx, len_lastR, len_qsfx);
4406 /* the output buffer might be the same as the prefix if caller
4407 has already partially filled it */
4408 if (qbuf == qprefix) {
4409 /* prefix is already in the buffer */
4411 } else if (qprefix) {
4412 /* put prefix into the buffer */
4413 (void) strncpy(qbuf, qprefix, lenlimit);
4416 /* no prefix; output buffer starts out empty */
4419 len = (unsigned) strlen(qbuf);
4421 if (len + len_lastR + len_qsfx > lenlimit) {
4422 /* too long; skip formatting, last resort output is truncated */
4423 if (len < lenlimit) {
4424 (void) strncpy(&qbuf[len], lastR, lenlimit - len);
4426 len = (unsigned) strlen(qbuf);
4427 if (qsuffix && len < lenlimit) {
4428 (void) strncpy(&qbuf[len], qsuffix, lenlimit - len);
4430 /* len = (unsigned) strlen(qbuf); */
4434 /* suffix and last resort are guaranteed to fit */
4435 len += len_qsfx; /* include the pending suffix */
4436 /* format the object */
4437 bufp = short_oname(obj, func, altfunc, lenlimit - len);
4438 if (len + strlen(bufp) <= lenlimit)
4439 Strcat(qbuf, bufp); /* formatted name fits */
4441 Strcat(qbuf, lastR); /* use last resort */
4445 Strcat(qbuf, qsuffix);
4447 /* assert( strlen(qbuf) < QBUFSZ ); */