From 013ac7742311556022304e8b30ca170d48b3a016 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 7 May 2015 16:32:32 -0400 Subject: initial commit --- hack/hack.objnam.c | 584 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 584 insertions(+) create mode 100644 hack/hack.objnam.c (limited to 'hack/hack.objnam.c') diff --git a/hack/hack.objnam.c b/hack/hack.objnam.c new file mode 100644 index 0000000..2dc2397 --- /dev/null +++ b/hack/hack.objnam.c @@ -0,0 +1,584 @@ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* hack.objnam.c - version 1.0.2 */ +/* $FreeBSD: src/games/hack/hack.objnam.c,v 1.3 1999/11/16 02:57:08 billf Exp $ */ + +#include "hack.h" +#define Sprintf (void) sprintf +#define Strcat (void) strcat +#define Strcpy (void) strcpy +#define PREFIX 15 +extern int bases[]; + +static char *strprepend(char *, char *); +static char *sitoa(int); + +static char * +strprepend(char *s, char *pref) +{ + int i = strlen(pref); + + if (i > PREFIX) { + pline("WARNING: prefix too short."); + return (s); + } + s -= i; + strncpy(s, pref, i); /* do not copy trailing 0 */ + return (s); +} + +static char * +sitoa(int a) +{ + static char buf[13]; + + Sprintf(buf, (a < 0) ? "%d" : "+%d", a); + return (buf); +} + +char * +typename(int otyp) +{ + static char buf[BUFSZ]; + struct objclass *ocl = &objects[otyp]; + const char *an = ocl->oc_name; + const char *dn = ocl->oc_descr; + char *un = ocl->oc_uname; + int nn = ocl->oc_name_known; + + switch (ocl->oc_olet) { + case POTION_SYM: + Strcpy(buf, "potion"); + break; + case SCROLL_SYM: + Strcpy(buf, "scroll"); + break; + case WAND_SYM: + Strcpy(buf, "wand"); + break; + case RING_SYM: + Strcpy(buf, "ring"); + break; + default: + if (nn) { + Strcpy(buf, an); + if (otyp >= TURQUOISE && otyp <= JADE) + Strcat(buf, " stone"); + if (un) + Sprintf(eos(buf), " called %s", un); + if (dn) + Sprintf(eos(buf), " (%s)", dn); + } else { + Strcpy(buf, dn ? dn : an); + if (ocl->oc_olet == GEM_SYM) + Strcat(buf, " gem"); + if (un) + Sprintf(eos(buf), " called %s", un); + } + return (buf); + } + /* here for ring/scroll/potion/wand */ + if (nn) + Sprintf(eos(buf), " of %s", an); + if (un) + Sprintf(eos(buf), " called %s", un); + if (dn) + Sprintf(eos(buf), " (%s)", dn); + return (buf); +} + +char * +xname(struct obj *obj) +{ + static char bufr[BUFSZ]; + /* caution: doname() and aobjnam() below "know" these sizes */ + char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */ + int nn = objects[obj->otyp].oc_name_known; + const char *an = objects[obj->otyp].oc_name; + const char *dn = objects[obj->otyp].oc_descr; + char *un = objects[obj->otyp].oc_uname; + int pl = (obj->quan != 1); + + if (!obj->dknown && !Blind) /* %% doesnt belong here */ + obj->dknown = 1; + switch (obj->olet) { + case AMULET_SYM: + Strcpy(buf, (obj->spe < 0 && obj->known) + ? "cheap plastic imitation of the " : ""); + Strcat(buf, "Amulet of Yendor"); + break; + case TOOL_SYM: + if (!nn) { + Strcpy(buf, dn); + break; + } + Strcpy(buf, an); + break; + case FOOD_SYM: + if (obj->otyp == DEAD_HOMUNCULUS && pl) { + pl = 0; + Strcpy(buf, "dead homunculi"); + break; + } + /* fungis ? */ + /* fall into next case */ + case WEAPON_SYM: + if (obj->otyp == WORM_TOOTH && pl) { + pl = 0; + Strcpy(buf, "worm teeth"); + break; + } + if (obj->otyp == CRYSKNIFE && pl) { + pl = 0; + Strcpy(buf, "crysknives"); + break; + } + /* fall into next case */ + case ARMOR_SYM: + case CHAIN_SYM: + case ROCK_SYM: + Strcpy(buf, an); + break; + case BALL_SYM: + Sprintf(buf, "%sheavy iron ball", + (obj->owt > objects[obj->otyp].oc_weight) ? "very " : ""); + break; + case POTION_SYM: + if (nn || un || !obj->dknown) { + Strcpy(buf, "potion"); + if (pl) { + pl = 0; + Strcat(buf, "s"); + } + if (!obj->dknown) + break; + if (un) { + Strcat(buf, " called "); + Strcat(buf, un); + } else { + Strcat(buf, " of "); + Strcat(buf, an); + } + } else { + Strcpy(buf, dn); + Strcat(buf, " potion"); + } + break; + case SCROLL_SYM: + Strcpy(buf, "scroll"); + if (pl) { + pl = 0; + Strcat(buf, "s"); + } + if (!obj->dknown) + break; + if (nn) { + Strcat(buf, " of "); + Strcat(buf, an); + } else if (un) { + Strcat(buf, " called "); + Strcat(buf, un); + } else { + Strcat(buf, " labeled "); + Strcat(buf, dn); + } + break; + case WAND_SYM: + if (!obj->dknown) + Sprintf(buf, "wand"); + else if (nn) + Sprintf(buf, "wand of %s", an); + else if (un) + Sprintf(buf, "wand called %s", un); + else + Sprintf(buf, "%s wand", dn); + break; + case RING_SYM: + if (!obj->dknown) + Sprintf(buf, "ring"); + else if (nn) + Sprintf(buf, "ring of %s", an); + else if (un) + Sprintf(buf, "ring called %s", un); + else + Sprintf(buf, "%s ring", dn); + break; + case GEM_SYM: + if (!obj->dknown) { + Strcpy(buf, "gem"); + break; + } + if (!nn) { + Sprintf(buf, "%s gem", dn); + break; + } + Strcpy(buf, an); + if (obj->otyp >= TURQUOISE && obj->otyp <= JADE) + Strcat(buf, " stone"); + break; + default: + Sprintf(buf, "glorkum %c (0%o) %u %d", + obj->olet, obj->olet, obj->otyp, obj->spe); + } + if (pl) { + char *p; + + for (p = buf; *p; p++) + if (!strncmp(" of ", p, 4)) { + /* pieces of, cloves of, lumps of */ + int c1, c2 = 's'; + + do { + c1 = c2; + c2 = *p; + *p++ = c1; + } while (c1); + goto nopl; + } + p = eos(buf) - 1; + if (*p == 's' || *p == 'z' || *p == 'x' || + (*p == 'h' && p[-1] == 's')) + Strcat(buf, "es"); /* boxes */ + else if (*p == 'y' && !strchr(vowels, p[-1])) + Strcpy(p, "ies"); /* rubies, zruties */ + else + Strcat(buf, "s"); + } +nopl: + if (obj->onamelth) { + Strcat(buf, " named "); + Strcat(buf, ONAME(obj)); + } + return (buf); +} + +char * +doname(struct obj *obj) +{ + char prefix[PREFIX]; + char *bp = xname(obj); + + if (obj->quan != 1) + Sprintf(prefix, "%u ", obj->quan); + else + Strcpy(prefix, "a "); + switch (obj->olet) { + case AMULET_SYM: + if (strncmp(bp, "cheap ", 6)) + Strcpy(prefix, "the "); + break; + case ARMOR_SYM: + if (obj->owornmask & W_ARMOR) + Strcat(bp, " (being worn)"); + /* fall into next case */ + case WEAPON_SYM: + if (obj->known) { + Strcat(prefix, sitoa(obj->spe)); + Strcat(prefix, " "); + } + break; + case WAND_SYM: + if (obj->known) + Sprintf(eos(bp), " (%d)", obj->spe); + break; + case RING_SYM: + if (obj->owornmask & W_RINGR) + Strcat(bp, " (on right hand)"); + if (obj->owornmask & W_RINGL) + Strcat(bp, " (on left hand)"); + if (obj->known && (objects[obj->otyp].bits & SPEC)) { + Strcat(prefix, sitoa(obj->spe)); + Strcat(prefix, " "); + } + break; + } + if (obj->owornmask & W_WEP) + Strcat(bp, " (weapon in hand)"); + if (obj->unpaid) + Strcat(bp, " (unpaid)"); + if (!strcmp(prefix, "a ") && strchr(vowels, *bp)) + Strcpy(prefix, "an "); + bp = strprepend(bp, prefix); + return (bp); +} + +/* used only in hack.fight.c (thitu) */ +void +setan(const char *str, char *buf) +{ + if (strchr(vowels, *str)) + Sprintf(buf, "an %s", str); + else + Sprintf(buf, "a %s", str); +} + +char * +aobjnam(struct obj *otmp, const char *verb) +{ + char *bp = xname(otmp); + char prefix[PREFIX]; + + if (otmp->quan != 1) { + Sprintf(prefix, "%u ", otmp->quan); + bp = strprepend(bp, prefix); + } + + if (verb) { + /* verb is given in plural (i.e., without trailing s) */ + Strcat(bp, " "); + if (otmp->quan != 1) + Strcat(bp, verb); + else if (!strcmp(verb, "are")) + Strcat(bp, "is"); + else { + Strcat(bp, verb); + Strcat(bp, "s"); + } + } + return (bp); +} + +char * +Doname(struct obj *obj) +{ + char *s = doname(obj); + + if ('a' <= *s && *s <= 'z') + *s -= ('a' - 'A'); + return (s); +} + +static const char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" }; +char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM }; + +struct obj * +readobjnam(char *bp) +{ + char *p; + int i; + int cnt, spe, spesgn, typ, heavy; + char let; + char *un, *dn, *an; + + cnt = spe = spesgn = typ = heavy = 0; + let = 0; + an = dn = un = NULL; + for (p = bp; *p; p++) + if ('A' <= *p && *p <= 'Z') + *p += 'a' - 'A'; + if (!strncmp(bp, "the ", 4)) + bp += 4; + else if (!strncmp(bp, "an ", 3)) { + cnt = 1; + bp += 3; + } else if (!strncmp(bp, "a ", 2)) { + cnt = 1; + bp += 2; + } + if (!cnt && digit(*bp)) { + cnt = atoi(bp); + while (digit(*bp)) + bp++; + while (*bp == ' ') + bp++; + } + if (!cnt) /* %% what with "gems" etc. ? */ + cnt = 1; + + if (*bp == '+' || *bp == '-') { + spesgn = (*bp++ == '+') ? 1 : -1; + spe = atoi(bp); + while (digit(*bp)) + bp++; + while (*bp == ' ') + bp++; + } else { + p = strrchr(bp, '('); + if (p) { + if (p > bp && p[-1] == ' ') + p[-1] = 0; + else + *p = 0; + p++; + spe = atoi(p); + while (digit(*p)) + p++; + if (strcmp(p, ")")) + spe = 0; + else + spesgn = 1; + } + } + /* + * now we have the actual name, as delivered by xname, say + * green potions called whisky + * scrolls labeled "QWERTY" + * egg + * dead zruties + * fortune cookies + * very heavy iron ball named hoei + * wand of wishing + * elven cloak + */ + for (p = bp; *p; p++) + if (!strncmp(p, " named ", 7)) + *p = 0; + + for (p = bp; *p; p++) + if (!strncmp(p, " called ", 8)) { + *p = 0; + un = p + 8; + } + for (p = bp; *p; p++) + if (!strncmp(p, " labeled ", 9)) { + *p = 0; + dn = p + 9; + } + + /* first change to singular if necessary */ + if (cnt != 1) { + /* find "cloves of garlic", "worthless pieces of blue glass" */ + for (p = bp; *p; p++) + if (!strncmp(p, "s of ", 5)) { + while ((*p = p[1])) + p++; + goto sing; + } + /* remove -s or -es (boxes) or -ies (rubies, zruties) */ + p = eos(bp); + if (p[-1] == 's') { + if (p[-2] == 'e') { + if (p[-3] == 'i') { + if (!strcmp(p - 7, "cookies")) + goto mins; + Strcpy(p - 3, "y"); + goto sing; + } + + /* note: cloves / knives from clove / knife */ + if (!strcmp(p - 6, "knives")) { + Strcpy(p - 3, "fe"); + goto sing; + } + + /* note: nurses, axes but boxes */ + if (!strcmp(p - 5, "boxes")) { + p[-2] = 0; + goto sing; + } + } +mins: + p[-1] = 0; + } else { + if (!strcmp(p - 9, "homunculi")) { + Strcpy(p - 1, "us"); /* !! makes string longer */ + goto sing; + } + if (!strcmp(p - 5, "teeth")) { + Strcpy(p - 5, "tooth"); + goto sing; + } + /* here we cannot find the plural suffix */ + } + } +sing: + if (!strcmp(bp, "amulet of yendor")) { + typ = AMULET_OF_YENDOR; + goto typfnd; + } + p = eos(bp); + if (!strcmp(p - 5, " mail")) { /* Note: ring mail is not a ring ! */ + let = ARMOR_SYM; + an = bp; + goto srch; + } + for (i = 0; (unsigned)i < sizeof(wrpsym); i++) { + int j = strlen(wrp[i]); + if (!strncmp(bp, wrp[i], j)) { + let = wrpsym[i]; + bp += j; + if (!strncmp(bp, " of ", 4)) + an = bp + 4; + /* else if (*bp) ?? */ + goto srch; + } + if (!strcmp(p - j, wrp[i])) { + let = wrpsym[i]; + p -= j; + *p = 0; + if (p[-1] == ' ') + p[-1] = 0; + dn = bp; + goto srch; + } + } + if (!strcmp(p - 6, " stone")) { + p[-6] = 0; + let = GEM_SYM; + an = bp; + goto srch; + } + if (!strcmp(bp, "very heavy iron ball")) { + heavy = 1; + typ = HEAVY_IRON_BALL; + goto typfnd; + } + an = bp; +srch: + if (!an && !dn && !un) + goto any; + i = 1; + if (let) + i = bases[letindex(let)]; + while (i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)) { + const char *zn = objects[i].oc_name; + + if (!zn) + goto nxti; + if (an && strcmp(an, zn)) + goto nxti; + if (dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn))) + goto nxti; + if (un && (!(zn = objects[i].oc_uname) || strcmp(un, zn))) + goto nxti; + typ = i; + goto typfnd; +nxti: + i++; + } +any: + if (!let) + let = wrpsym[rn2(sizeof(wrpsym))]; + typ = probtype(let); +typfnd: + { + struct obj *otmp; + let = objects[typ].oc_olet; + otmp = mksobj(typ); + if (heavy) + otmp->owt += 15; + if (cnt > 0 && strchr("%?!*)", let) && + (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20))) + otmp->quan = cnt; + + if (spe > 3 && spe > otmp->spe) + spe = 0; + else if (let == WAND_SYM) + spe = otmp->spe; + if (spe == 3 && u.uluck < 0) + spesgn = -1; + if (let != WAND_SYM && spesgn == -1) + spe = -spe; + if (let == BALL_SYM) + spe = 0; + else if (let == AMULET_SYM) + spe = -1; + else if (typ == WAN_WISHING && rn2(10)) + spe = (rn2(10) ? -1 : 0); + otmp->spe = spe; + + if (spesgn == -1) + otmp->cursed = 1; + + return (otmp); + } +} -- cgit v1.2.3