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 $ */
6 #define Sprintf (void) sprintf
7 #define Strcat (void) strcat
8 #define Strcpy (void) strcpy
12 static char *strprepend(char *, char *);
13 static char *sitoa(int);
16 strprepend(char *s, char *pref)
21 pline("WARNING: prefix too short.");
25 strncpy(s, pref, i); /* do not copy trailing 0 */
34 Sprintf(buf, (a < 0) ? "%d" : "+%d", a);
41 static char buf[BUFSZ];
42 struct objclass *ocl = &objects[otyp];
43 const char *an = ocl->oc_name;
44 const char *dn = ocl->oc_descr;
45 char *un = ocl->oc_uname;
46 int nn = ocl->oc_name_known;
48 switch (ocl->oc_olet) {
50 Strcpy(buf, "potion");
53 Strcpy(buf, "scroll");
64 if (otyp >= TURQUOISE && otyp <= JADE)
65 Strcat(buf, " stone");
67 Sprintf(eos(buf), " called %s", un);
69 Sprintf(eos(buf), " (%s)", dn);
71 Strcpy(buf, dn ? dn : an);
72 if (ocl->oc_olet == GEM_SYM)
75 Sprintf(eos(buf), " called %s", un);
79 /* here for ring/scroll/potion/wand */
81 Sprintf(eos(buf), " of %s", an);
83 Sprintf(eos(buf), " called %s", un);
85 Sprintf(eos(buf), " (%s)", dn);
90 xname(struct obj *obj)
92 static char bufr[BUFSZ];
93 /* caution: doname() and aobjnam() below "know" these sizes */
94 char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */
95 int nn = objects[obj->otyp].oc_name_known;
96 const char *an = objects[obj->otyp].oc_name;
97 const char *dn = objects[obj->otyp].oc_descr;
98 char *un = objects[obj->otyp].oc_uname;
99 int pl = (obj->quan != 1);
101 if (!obj->dknown && !Blind) /* %% doesnt belong here */
105 Strcpy(buf, (obj->spe < 0 && obj->known)
106 ? "cheap plastic imitation of the " : "");
107 Strcat(buf, "Amulet of Yendor");
117 if (obj->otyp == DEAD_HOMUNCULUS && pl) {
119 Strcpy(buf, "dead homunculi");
123 /* fall into next case */
125 if (obj->otyp == WORM_TOOTH && pl) {
127 Strcpy(buf, "worm teeth");
130 if (obj->otyp == CRYSKNIFE && pl) {
132 Strcpy(buf, "crysknives");
135 /* fall into next case */
142 Sprintf(buf, "%sheavy iron ball",
143 (obj->owt > objects[obj->otyp].oc_weight) ? "very " : "");
146 if (nn || un || !obj->dknown) {
147 Strcpy(buf, "potion");
155 Strcat(buf, " called ");
163 Strcat(buf, " potion");
167 Strcpy(buf, "scroll");
178 Strcat(buf, " called ");
181 Strcat(buf, " labeled ");
187 Sprintf(buf, "wand");
189 Sprintf(buf, "wand of %s", an);
191 Sprintf(buf, "wand called %s", un);
193 Sprintf(buf, "%s wand", dn);
197 Sprintf(buf, "ring");
199 Sprintf(buf, "ring of %s", an);
201 Sprintf(buf, "ring called %s", un);
203 Sprintf(buf, "%s ring", dn);
211 Sprintf(buf, "%s gem", dn);
215 if (obj->otyp >= TURQUOISE && obj->otyp <= JADE)
216 Strcat(buf, " stone");
219 Sprintf(buf, "glorkum %c (0%o) %u %d",
220 obj->olet, obj->olet, obj->otyp, obj->spe);
225 for (p = buf; *p; p++)
226 if (!strncmp(" of ", p, 4)) {
227 /* pieces of, cloves of, lumps of */
238 if (*p == 's' || *p == 'z' || *p == 'x' ||
239 (*p == 'h' && p[-1] == 's'))
240 Strcat(buf, "es"); /* boxes */
241 else if (*p == 'y' && !strchr(vowels, p[-1]))
242 Strcpy(p, "ies"); /* rubies, zruties */
248 Strcat(buf, " named ");
249 Strcat(buf, ONAME(obj));
255 doname(struct obj *obj)
258 char *bp = xname(obj);
261 Sprintf(prefix, "%u ", obj->quan);
263 Strcpy(prefix, "a ");
266 if (strncmp(bp, "cheap ", 6))
267 Strcpy(prefix, "the ");
270 if (obj->owornmask & W_ARMOR)
271 Strcat(bp, " (being worn)");
272 /* fall into next case */
275 Strcat(prefix, sitoa(obj->spe));
281 Sprintf(eos(bp), " (%d)", obj->spe);
284 if (obj->owornmask & W_RINGR)
285 Strcat(bp, " (on right hand)");
286 if (obj->owornmask & W_RINGL)
287 Strcat(bp, " (on left hand)");
288 if (obj->known && (objects[obj->otyp].bits & SPEC)) {
289 Strcat(prefix, sitoa(obj->spe));
294 if (obj->owornmask & W_WEP)
295 Strcat(bp, " (weapon in hand)");
297 Strcat(bp, " (unpaid)");
298 if (!strcmp(prefix, "a ") && strchr(vowels, *bp))
299 Strcpy(prefix, "an ");
300 bp = strprepend(bp, prefix);
304 /* used only in hack.fight.c (thitu) */
306 setan(const char *str, char *buf)
308 if (strchr(vowels, *str))
309 Sprintf(buf, "an %s", str);
311 Sprintf(buf, "a %s", str);
315 aobjnam(struct obj *otmp, const char *verb)
317 char *bp = xname(otmp);
320 if (otmp->quan != 1) {
321 Sprintf(prefix, "%u ", otmp->quan);
322 bp = strprepend(bp, prefix);
326 /* verb is given in plural (i.e., without trailing s) */
330 else if (!strcmp(verb, "are"))
341 Doname(struct obj *obj)
343 char *s = doname(obj);
345 if ('a' <= *s && *s <= 'z')
350 static const char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" };
351 char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM };
358 int cnt, spe, spesgn, typ, heavy;
362 cnt = spe = spesgn = typ = heavy = 0;
365 for (p = bp; *p; p++)
366 if ('A' <= *p && *p <= 'Z')
368 if (!strncmp(bp, "the ", 4))
370 else if (!strncmp(bp, "an ", 3)) {
373 } else if (!strncmp(bp, "a ", 2)) {
377 if (!cnt && digit(*bp)) {
384 if (!cnt) /* %% what with "gems" etc. ? */
387 if (*bp == '+' || *bp == '-') {
388 spesgn = (*bp++ == '+') ? 1 : -1;
395 p = strrchr(bp, '(');
397 if (p > bp && p[-1] == ' ')
412 * now we have the actual name, as delivered by xname, say
413 * green potions called whisky
414 * scrolls labeled "QWERTY"
418 * very heavy iron ball named hoei
422 for (p = bp; *p; p++)
423 if (!strncmp(p, " named ", 7))
426 for (p = bp; *p; p++)
427 if (!strncmp(p, " called ", 8)) {
431 for (p = bp; *p; p++)
432 if (!strncmp(p, " labeled ", 9)) {
437 /* first change to singular if necessary */
439 /* find "cloves of garlic", "worthless pieces of blue glass" */
440 for (p = bp; *p; p++)
441 if (!strncmp(p, "s of ", 5)) {
446 /* remove -s or -es (boxes) or -ies (rubies, zruties) */
451 if (!strcmp(p - 7, "cookies"))
457 /* note: cloves / knives from clove / knife */
458 if (!strcmp(p - 6, "knives")) {
463 /* note: nurses, axes but boxes */
464 if (!strcmp(p - 5, "boxes")) {
472 if (!strcmp(p - 9, "homunculi")) {
473 Strcpy(p - 1, "us"); /* !! makes string longer */
476 if (!strcmp(p - 5, "teeth")) {
477 Strcpy(p - 5, "tooth");
480 /* here we cannot find the plural suffix */
484 if (!strcmp(bp, "amulet of yendor")) {
485 typ = AMULET_OF_YENDOR;
489 if (!strcmp(p - 5, " mail")) { /* Note: ring mail is not a ring ! */
494 for (i = 0; (unsigned)i < sizeof(wrpsym); i++) {
495 int j = strlen(wrp[i]);
496 if (!strncmp(bp, wrp[i], j)) {
499 if (!strncmp(bp, " of ", 4))
501 /* else if (*bp) ?? */
504 if (!strcmp(p - j, wrp[i])) {
514 if (!strcmp(p - 6, " stone")) {
520 if (!strcmp(bp, "very heavy iron ball")) {
522 typ = HEAVY_IRON_BALL;
527 if (!an && !dn && !un)
531 i = bases[letindex(let)];
532 while (i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)) {
533 const char *zn = objects[i].oc_name;
537 if (an && strcmp(an, zn))
539 if (dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn)))
541 if (un && (!(zn = objects[i].oc_uname) || strcmp(un, zn)))
550 let = wrpsym[rn2(sizeof(wrpsym))];
555 let = objects[typ].oc_olet;
559 if (cnt > 0 && strchr("%?!*)", let) &&
560 (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20)))
563 if (spe > 3 && spe > otmp->spe)
565 else if (let == WAND_SYM)
567 if (spe == 3 && u.uluck < 0)
569 if (let != WAND_SYM && spesgn == -1)
573 else if (let == AMULET_SYM)
575 else if (typ == WAN_WISHING && rn2(10))
576 spe = (rn2(10) ? -1 : 0);