1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.objnam.c - version 1.0.2 */
3 /* $FreeBSD: src/games/hack/hack.objnam.c,v 1.3 1999/11/16 02:57:08 billf Exp $ */
4 /* $DragonFly: src/games/hack/hack.objnam.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
7 #define Sprintf (void) sprintf
8 #define Strcat (void) strcat
9 #define Strcpy (void) strcpy
13 static char *strprepend(char *, char *);
14 static char *sitoa(int);
17 strprepend(char *s, char *pref)
22 pline("WARNING: prefix too short.");
26 strncpy(s, pref, i); /* do not copy trailing 0 */
35 Sprintf(buf, (a < 0) ? "%d" : "+%d", a);
42 static char buf[BUFSZ];
43 struct objclass *ocl = &objects[otyp];
44 const char *an = ocl->oc_name;
45 const char *dn = ocl->oc_descr;
46 char *un = ocl->oc_uname;
47 int nn = ocl->oc_name_known;
49 switch (ocl->oc_olet) {
51 Strcpy(buf, "potion");
54 Strcpy(buf, "scroll");
65 if (otyp >= TURQUOISE && otyp <= JADE)
66 Strcat(buf, " stone");
68 Sprintf(eos(buf), " called %s", un);
70 Sprintf(eos(buf), " (%s)", dn);
72 Strcpy(buf, dn ? dn : an);
73 if (ocl->oc_olet == GEM_SYM)
76 Sprintf(eos(buf), " called %s", un);
80 /* here for ring/scroll/potion/wand */
82 Sprintf(eos(buf), " of %s", an);
84 Sprintf(eos(buf), " called %s", un);
86 Sprintf(eos(buf), " (%s)", dn);
91 xname(struct obj *obj)
93 static char bufr[BUFSZ];
94 /* caution: doname() and aobjnam() below "know" these sizes */
95 char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */
96 int nn = objects[obj->otyp].oc_name_known;
97 const char *an = objects[obj->otyp].oc_name;
98 const char *dn = objects[obj->otyp].oc_descr;
99 char *un = objects[obj->otyp].oc_uname;
100 int pl = (obj->quan != 1);
102 if (!obj->dknown && !Blind) /* %% doesnt belong here */
106 Strcpy(buf, (obj->spe < 0 && obj->known)
107 ? "cheap plastic imitation of the " : "");
108 Strcat(buf, "Amulet of Yendor");
118 if (obj->otyp == DEAD_HOMUNCULUS && pl) {
120 Strcpy(buf, "dead homunculi");
124 /* fall into next case */
126 if (obj->otyp == WORM_TOOTH && pl) {
128 Strcpy(buf, "worm teeth");
131 if (obj->otyp == CRYSKNIFE && pl) {
133 Strcpy(buf, "crysknives");
136 /* fall into next case */
143 Sprintf(buf, "%sheavy iron ball",
144 (obj->owt > objects[obj->otyp].oc_weight) ? "very " : "");
147 if (nn || un || !obj->dknown) {
148 Strcpy(buf, "potion");
156 Strcat(buf, " called ");
164 Strcat(buf, " potion");
168 Strcpy(buf, "scroll");
179 Strcat(buf, " called ");
182 Strcat(buf, " labeled ");
188 Sprintf(buf, "wand");
190 Sprintf(buf, "wand of %s", an);
192 Sprintf(buf, "wand called %s", un);
194 Sprintf(buf, "%s wand", dn);
198 Sprintf(buf, "ring");
200 Sprintf(buf, "ring of %s", an);
202 Sprintf(buf, "ring called %s", un);
204 Sprintf(buf, "%s ring", dn);
212 Sprintf(buf, "%s gem", dn);
216 if (obj->otyp >= TURQUOISE && obj->otyp <= JADE)
217 Strcat(buf, " stone");
220 Sprintf(buf, "glorkum %c (0%o) %u %d",
221 obj->olet, obj->olet, obj->otyp, obj->spe);
226 for (p = buf; *p; p++)
227 if (!strncmp(" of ", p, 4)) {
228 /* pieces of, cloves of, lumps of */
239 if (*p == 's' || *p == 'z' || *p == 'x' ||
240 (*p == 'h' && p[-1] == 's'))
241 Strcat(buf, "es"); /* boxes */
242 else if (*p == 'y' && !strchr(vowels, p[-1]))
243 Strcpy(p, "ies"); /* rubies, zruties */
249 Strcat(buf, " named ");
250 Strcat(buf, ONAME(obj));
256 doname(struct obj *obj)
259 char *bp = xname(obj);
262 Sprintf(prefix, "%u ", obj->quan);
264 Strcpy(prefix, "a ");
267 if (strncmp(bp, "cheap ", 6))
268 Strcpy(prefix, "the ");
271 if (obj->owornmask & W_ARMOR)
272 Strcat(bp, " (being worn)");
273 /* fall into next case */
276 Strcat(prefix, sitoa(obj->spe));
282 Sprintf(eos(bp), " (%d)", obj->spe);
285 if (obj->owornmask & W_RINGR)
286 Strcat(bp, " (on right hand)");
287 if (obj->owornmask & W_RINGL)
288 Strcat(bp, " (on left hand)");
289 if (obj->known && (objects[obj->otyp].bits & SPEC)) {
290 Strcat(prefix, sitoa(obj->spe));
295 if (obj->owornmask & W_WEP)
296 Strcat(bp, " (weapon in hand)");
298 Strcat(bp, " (unpaid)");
299 if (!strcmp(prefix, "a ") && strchr(vowels, *bp))
300 Strcpy(prefix, "an ");
301 bp = strprepend(bp, prefix);
305 /* used only in hack.fight.c (thitu) */
307 setan(const char *str, char *buf)
309 if (strchr(vowels, *str))
310 Sprintf(buf, "an %s", str);
312 Sprintf(buf, "a %s", str);
316 aobjnam(struct obj *otmp, const char *verb)
318 char *bp = xname(otmp);
321 if (otmp->quan != 1) {
322 Sprintf(prefix, "%u ", otmp->quan);
323 bp = strprepend(bp, prefix);
327 /* verb is given in plural (i.e., without trailing s) */
331 else if (!strcmp(verb, "are"))
342 Doname(struct obj *obj)
344 char *s = doname(obj);
346 if ('a' <= *s && *s <= 'z')
351 static const char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" };
352 char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM };
359 int cnt, spe, spesgn, typ, heavy;
363 cnt = spe = spesgn = typ = heavy = 0;
366 for (p = bp; *p; p++)
367 if ('A' <= *p && *p <= 'Z')
369 if (!strncmp(bp, "the ", 4))
371 else if (!strncmp(bp, "an ", 3)) {
374 } else if (!strncmp(bp, "a ", 2)) {
378 if (!cnt && digit(*bp)) {
385 if (!cnt) /* %% what with "gems" etc. ? */
388 if (*bp == '+' || *bp == '-') {
389 spesgn = (*bp++ == '+') ? 1 : -1;
396 p = strrchr(bp, '(');
398 if (p > bp && p[-1] == ' ')
413 * now we have the actual name, as delivered by xname, say
414 * green potions called whisky
415 * scrolls labeled "QWERTY"
419 * very heavy iron ball named hoei
423 for (p = bp; *p; p++)
424 if (!strncmp(p, " named ", 7))
427 for (p = bp; *p; p++)
428 if (!strncmp(p, " called ", 8)) {
432 for (p = bp; *p; p++)
433 if (!strncmp(p, " labeled ", 9)) {
438 /* first change to singular if necessary */
440 /* find "cloves of garlic", "worthless pieces of blue glass" */
441 for (p = bp; *p; p++)
442 if (!strncmp(p, "s of ", 5)) {
447 /* remove -s or -es (boxes) or -ies (rubies, zruties) */
452 if (!strcmp(p - 7, "cookies"))
458 /* note: cloves / knives from clove / knife */
459 if (!strcmp(p - 6, "knives")) {
464 /* note: nurses, axes but boxes */
465 if (!strcmp(p - 5, "boxes")) {
473 if (!strcmp(p - 9, "homunculi")) {
474 Strcpy(p - 1, "us"); /* !! makes string longer */
477 if (!strcmp(p - 5, "teeth")) {
478 Strcpy(p - 5, "tooth");
481 /* here we cannot find the plural suffix */
485 if (!strcmp(bp, "amulet of yendor")) {
486 typ = AMULET_OF_YENDOR;
490 if (!strcmp(p - 5, " mail")) { /* Note: ring mail is not a ring ! */
495 for (i = 0; (unsigned)i < sizeof(wrpsym); i++) {
496 int j = strlen(wrp[i]);
497 if (!strncmp(bp, wrp[i], j)) {
500 if (!strncmp(bp, " of ", 4))
502 /* else if (*bp) ?? */
505 if (!strcmp(p - j, wrp[i])) {
515 if (!strcmp(p - 6, " stone")) {
521 if (!strcmp(bp, "very heavy iron ball")) {
523 typ = HEAVY_IRON_BALL;
528 if (!an && !dn && !un)
532 i = bases[letindex(let)];
533 while (i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)) {
534 const char *zn = objects[i].oc_name;
538 if (an && strcmp(an, zn))
540 if (dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn)))
542 if (un && (!(zn = objects[i].oc_uname) || strcmp(un, zn)))
551 let = wrpsym[rn2(sizeof(wrpsym))];
556 let = objects[typ].oc_olet;
560 if (cnt > 0 && strchr("%?!*)", let) &&
561 (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20)))
564 if (spe > 3 && spe > otmp->spe)
566 else if (let == WAND_SYM)
568 if (spe == 3 && u.uluck < 0)
570 if (let != WAND_SYM && spesgn == -1)
574 else if (let == AMULET_SYM)
576 else if (typ == WAN_WISHING && rn2(10))
577 spe = (rn2(10) ? -1 : 0);