billr@saab.CNA.TEK.COM (Bill Randle) (07/24/89)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 64
Archive-name: NetHack3/Part09
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 9 (of 38)."
# Contents: src/objnam.c src/u_init.c
# Wrapped by billr@saab on Sun Jul 23 21:32:52 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/objnam.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/objnam.c'\"
else
echo shar: Extracting \"'src/objnam.c'\" \(33829 characters\)
sed "s/^X//" >'src/objnam.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)objnam.c 3.0 88/11/30
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
X#define PREFIX 30
X
X/* We want the player to be able to learn what key goes in what lock. */
Xconst char *keystr[N_LOX] = { "round", "square", "triangular", "oval",
X "octagonal", "hexagonal", "cylindrical",
X "irregular", "conical", "wedge-shaped" },
X *lockstr[N_LOX] = { "round", "square", "triangular", "oval",
X "octagonal", "hexagonal", "wide",
X "notched", "large round", "large square" };
X
Xstatic int rnd_class P((int,int));
X
Xstatic int
Xnamed_key(s) register char *s; {
X char tc[BUFSZ];
X register int i;
X
X for(i=0; i<10; i++) {
X Strcpy(tc, keystr[i]);
X Strcat(tc, " key");
X if(!strcmp(s,tc)) return(i+1);
X }
X return(0);
X}
X
Xstatic int
Xnamed_box(s)
Xregister char *s;
X{
X char tc[BUFSZ];
X register int i;
X
X for(i=0; i<10; i++) {
X Strcpy(tc, lockstr[i]);
X Strcat(tc, " keyhole)");
X if(!strcmp(s,tc)) return(i+1);
X }
X return(0);
X}
X
Xstatic char *
Xstrprepend(s,pref) register char *s, *pref; {
Xregister int i = strlen(pref);
X if(i > PREFIX) {
X pline("WARNING: prefix too short.");
X return(s);
X }
X s -= i;
X (void) strncpy(s, pref, i); /* do not copy trailing 0 */
X return(s);
X}
X
Xstatic char *
Xsitoa(a) int a; {
X#ifdef LINT /* static char buf[13]; */
X char buf[13];
X#else
X static char buf[13];
X#endif
X Sprintf(buf, (a < 0) ? "%d" : "+%d", a);
X return(buf);
X}
X
Xchar *
Xtypename(otyp)
Xregister int otyp;
X{
X#ifdef LINT /* static char buf[BUFSZ]; */
Xchar buf[BUFSZ];
X#else
Xstatic char buf[BUFSZ];
X#endif
Xregister struct objclass *ocl = &objects[otyp];
Xregister char *an = ocl->oc_name;
Xregister char *dn = ocl->oc_descr;
Xregister char *un = ocl->oc_uname;
Xregister int nn = ocl->oc_name_known;
X switch(ocl->oc_olet) {
X case POTION_SYM:
X Strcpy(buf, "potion");
X break;
X case SCROLL_SYM:
X Strcpy(buf, "scroll");
X break;
X case WAND_SYM:
X Strcpy(buf, "wand");
X break;
X#ifdef SPELLS
X case SPBOOK_SYM:
X Strcpy(buf, "spellbook");
X break;
X#endif
X case RING_SYM:
X Strcpy(buf, "ring");
X break;
X case AMULET_SYM:
X if(nn)
X Strcpy(buf,an);
X else
X Strcpy(buf,"amulet");
X if(un)
X Sprintf(eos(buf)," called %s",un);
X if(dn)
X Sprintf(eos(buf)," (%s)",dn);
X return(buf);
X default:
X if(nn) {
X Strcpy(buf, an);
X if(otyp >= TURQUOISE && otyp <= JADE)
X Strcat(buf, " stone");
X if(un)
X Sprintf(eos(buf), " called %s", un);
X if(dn)
X Sprintf(eos(buf), " (%s)", dn);
X } else {
X Strcpy(buf, dn ? dn : an);
X if(ocl->oc_olet == GEM_SYM) {
X if (otyp == LOADSTONE || otyp == LUCKSTONE)
X Strcat(buf, " stone");
X else
X Strcat(buf, " gem");
X }
X if(un)
X Sprintf(eos(buf), " called %s", un);
X }
X return(buf);
X }
X /* here for ring/scroll/potion/wand */
X if(nn)
X Sprintf(eos(buf), " of %s", an);
X if(un)
X Sprintf(eos(buf), " called %s", un);
X if(dn)
X Sprintf(eos(buf), " (%s)", dn);
X return(buf);
X}
X
X/* Give the name of an object seen at a distance. Unlike xname/doname,
X * we don't want to set dknown if it's not set already. The kludge used is
X * to temporarily set Blind so that xname() skips the dknown setting. This
X * assumes that we don't want to do this too often; if this function becomes
X * frequently used, it'd probably be better to pass a parameter to xname()
X * or doname() instead.
X */
Xchar *
Xdistant_name(obj, func)
Xregister struct obj *obj;
Xchar *(*func) P((struct obj *));
X{
X char *str;
X
X long save_Blinded = Blinded;
X Blinded = 1;
X str = func(obj);
X Blinded = save_Blinded;
X return str;
X}
X
Xchar *
Xxname(obj)
Xregister struct obj *obj;
X{
X#ifdef LINT /* lint may handle static decl poorly -- static char bufr[]; */
Xchar bufr[BUFSZ];
X#else
Xstatic char bufr[BUFSZ];
X#endif
Xregister char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */
Xregister int nn = objects[obj->otyp].oc_name_known;
Xregister char *an = objects[obj->otyp].oc_name;
Xregister char *dn = objects[obj->otyp].oc_descr;
Xregister char *un = objects[obj->otyp].oc_uname;
X
X buf[0] = 0;
X if(!Blind) obj->dknown=1;
X switch(obj->olet) {
X case AMULET_SYM:
X if(obj->otyp == AMULET_OF_YENDOR) {
X Strcpy(buf, (obj->spe < 0 && obj->known) ?
X "cheap plastic imitation of the " : "");
X Strcat(buf, an);
X } else if (!obj->dknown)
X Strcpy(buf, "amulet");
X else if (nn)
X Strcpy(buf, an);
X else if (un)
X Sprintf(buf,"amulet called %s", un);
X else
X Sprintf(buf,"%s amulet", dn);
X break;
X case WEAPON_SYM:
X if(obj->otyp <= SHURIKEN && obj->opoisoned)
X Strcpy(buf, "poisoned ");
X case VENOM_SYM:
X case TOOL_SYM:
X if(nn) Strcat(buf, an);
X else Strcat(buf, dn);
X if(obj->otyp == FIGURINE && obj->known) {
X Sprintf(eos(buf), " of a%s %s",
X index(vowels, *mons[obj->corpsenm].mname)
X ? "n" : "",
X mons[obj->corpsenm].mname);
X break;
X }
X break;
X case ARMOR_SYM:
X if(obj->otyp==DRAGON_SCALE_MAIL) {
X Sprintf(buf, "%s scale mail",
X mons[obj->corpsenm].mname);
X break;
X }
X
X if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
X
X if(nn) Strcat(buf, an);
X else if(un) {
X if(is_boots(obj))
X Strcat(buf,"boots");
X else if(is_gloves(obj))
X Strcat(buf,"gloves");
X else if(is_cloak(obj))
X Strcpy(buf,"cloak");
X else if(is_helmet(obj))
X Strcpy(buf,"helmet");
X else if(is_shield(obj))
X Strcpy(buf,"shield");
X else
X Strcpy(buf,"armor");
X Strcat(buf, " called ");
X Strcat(buf, un);
X } else Strcat(buf, dn);
X break;
X case FOOD_SYM:
X if (obj->otyp == SLIME_MOLD) {
X register struct fruit *f;
X
X for(f=ffruit; f; f = f->nextf) {
X if(f->fid == obj->spe) {
X Strcpy(buf, f->fname);
X break;
X }
X }
X if (!f) impossible("Bad fruit #%d?", obj->spe);
X break;
X }
X Strcpy(buf, an);
X if(obj->otyp == TIN && obj->known) {
X if(obj->spe > 0)
X Strcat(buf, " of spinach");
X else if (mons[obj->corpsenm].mlet == S_FUNGUS)
X Sprintf(eos(buf), " of %s", mons[obj->corpsenm].mname);
X else if(obj->corpsenm >= 0)
X Sprintf(eos(buf), " of %s meat", mons[obj->corpsenm].mname);
X else Strcpy(buf, "empty tin");
X }
X break;
X case CHAIN_SYM:
X Strcpy(buf, an);
X break;
X case ROCK_SYM:
X if(obj->otyp == STATUE)
X Sprintf(buf, "%s of a%s %s", an,
X (index(vowels, *(mons[obj->corpsenm].mname))) ? "n" : "",
X mons[obj->corpsenm].mname);
X else Strcpy(buf, an);
X break;
X case BALL_SYM:
X Sprintf(buf, "%sheavy iron ball",
X (obj->owt > objects[obj->otyp].oc_weight) ? "very " : "");
X break;
X case POTION_SYM:
X if(nn || un || !obj->dknown) {
X Strcpy(buf, "potion");
X if(!obj->dknown) break;
X if(nn) {
X Strcat(buf, " of ");
X if(obj->otyp == POT_WATER &&
X objects[POT_WATER].oc_name_known &&
X (obj->bknown || pl_character[0] == 'P') &&
X (obj->blessed || obj->cursed)) {
X Strcat(buf, obj->blessed ? "holy " : "unholy ");
X }
X Strcat(buf, an);
X } else {
X Strcat(buf, " called ");
X Strcat(buf, un);
X }
X } else {
X Strcpy(buf, dn);
X Strcat(buf, " potion");
X }
X break;
X case SCROLL_SYM:
X Strcpy(buf, "scroll");
X if(!obj->dknown) break;
X if(nn) {
X Strcat(buf, " of ");
X Strcat(buf, an);
X } else if(un) {
X Strcat(buf, " called ");
X Strcat(buf, un);
X } else {
X Strcat(buf, " labeled ");
X Strcat(buf, dn);
X }
X break;
X case WAND_SYM:
X if(!obj->dknown)
X Sprintf(buf, "wand");
X else if(nn)
X Sprintf(buf, "wand of %s", an);
X else if(un)
X Sprintf(buf, "wand called %s", un);
X else
X Sprintf(buf, "%s wand", dn);
X break;
X#ifdef SPELLS
X case SPBOOK_SYM:
X if(!obj->dknown)
X Sprintf(buf, "spellbook");
X else if(nn)
X Sprintf(buf, "spellbook of %s", an);
X else if(un)
X Sprintf(buf, "spellbook called %s", un);
X else
X Sprintf(buf, "%s spellbook", dn);
X break;
X#endif
X case RING_SYM:
X if(!obj->dknown)
X Sprintf(buf, "ring");
X else if(nn)
X Sprintf(buf, "ring of %s", an);
X else if(un)
X Sprintf(buf, "ring called %s", un);
X else
X Sprintf(buf, "%s ring", dn);
X break;
X case GEM_SYM:
X if(!obj->dknown) {
X if (obj->otyp == ROCK || obj->otyp == LOADSTONE
X || obj->otyp == LUCKSTONE)
X Strcpy(buf, "stone");
X else
X Strcpy(buf, "gem");
X break;
X }
X if(!nn) {
X char *rock=(obj->otyp==LOADSTONE||obj->otyp==LUCKSTONE)
X ? "stone" : "gem";
X if(un) Sprintf(buf,"%s called %s", rock, un);
X else Sprintf(buf, "%s %s", dn, rock);
X break;
X }
X Strcpy(buf, an);
X if(obj->otyp >= TURQUOISE && obj->otyp <= JADE)
X Strcat(buf, " stone");
X break;
X default:
X Sprintf(buf,"glorkum %c (0%o) %u %d",
X obj->olet,obj->olet,obj->otyp,obj->spe);
X }
X if(obj->quan != 1) Strcpy(buf, makeplural(buf));
X
X if(obj->onamelth) {
X Strcat(buf, " named ");
X Strcat(buf, ONAME(obj));
X }
X return(buf);
X}
X
Xchar *
Xdoname(obj)
Xregister struct obj *obj;
X{
X boolean ispoisoned = FALSE;
X char prefix[PREFIX];
X char tmpbuf[PREFIX+1];
X /* when we have to add something at the start of prefix instead of the
X * end (Strcat is used on the end)
X */
X register char *bp = xname(obj);
X /* When using xname, we want "poisoned arrow", and when using
X * doname, we want "poisoned +0 arrow". This kludge is about the only
X * way to do it, at least until someone overhauls xname() and doname(),
X * combining both into one function taking a parameter.
X */
X if (!strncmp(bp, "poisoned ", 9)) {
X bp += 9;
X ispoisoned = TRUE;
X }
X
X if(obj->quan != 1)
X Sprintf(prefix, "%u ", obj->quan);
X else
X Strcpy(prefix, "a ");
X if((obj->bknown || pl_character[0] == 'P') &&
X (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
X || (!obj->cursed && !obj->blessed))) {
X /* allow 'blessed clear potion' if we don't know it's holy water;
X * always allow "uncursed potion of water"
X */
X if(obj->cursed)
X Strcat(prefix, "cursed ");
X else if(obj->blessed)
X Strcat(prefix, "blessed ");
X else if (((obj->olet != ARMOR_SYM
X && obj->olet != WAND_SYM
X && obj->olet != WEAPON_SYM
X && ((obj->olet != TOOL_SYM &&
X obj->olet != RING_SYM) ||
X !objects[obj->otyp].oc_charged))
X || !obj->known)
X /* For items with charges or +/-, knowing the +/- means that
X * the item has been totally identified, and therefore there
X * is no doubt as to the object being uncursed if it's
X * not described as "blessed" or "cursed".
X *
X * If the +/- isn't known, "uncursed" must be printed to
X * avoid ambiguity between an item whose curse status is
X * unknown, and an item known to be uncursed.
X */
X#ifdef MAIL
X && obj->otyp != SCR_MAIL
X#endif
X && obj->otyp != AMULET_OF_YENDOR &&
X pl_character[0] != 'P')
X Strcat(prefix, "uncursed ");
X }
X switch(obj->olet) {
X case AMULET_SYM:
X if(obj->otyp == AMULET_OF_YENDOR)
X if(strncmp(bp, "cheap ", 6)) {
X Strcpy(tmpbuf, "the ");
X Strcat(tmpbuf, prefix+2); /* skip the "a " */
X Strcpy(prefix, tmpbuf);
X }
X if(obj->owornmask & W_AMUL)
X Strcat(bp, " (being worn)");
X break;
X case WEAPON_SYM:
X if(ispoisoned)
X Strcat(prefix, "poisoned ");
Xplus:
X if(obj->known) {
X Strcat(prefix, sitoa(obj->spe));
X Strcat(prefix, " ");
X }
X break;
X case ARMOR_SYM:
X if(obj->owornmask & W_ARMOR)
X Strcat(bp, " (being worn)");
X goto plus;
X case TOOL_SYM: /* temp. hack by GAN 11/18/86 */
X if(obj->owornmask & W_TOOL) { /* blindfold */
X Strcat(bp, " (being worn)");
X break;
X }
X#ifdef WALKIES
X if(obj->otyp == LEASH && obj->leashmon != 0) {
X Strcat(bp, " (in use)");
X break;
X }
X#endif
X if(obj->otyp == KEY ||
X (obj->otyp == SKELETON_KEY &&
X !objects[obj->otyp].oc_name_known)) {
X Strcat(prefix, keystr[obj->spe]);
X Strcat(prefix, " ");
X break;
X }
X if(obj->otyp == LARGE_BOX || obj->otyp == CHEST) {
X Sprintf(eos(bp), " (%s keyhole)", lockstr[obj->spe]);
X break;
X }
X if(obj->otyp == PICK_AXE) goto plus;
X if(!objects[obj->otyp].oc_charged) break;
X /* if special tool, fall through to show charges */
X case WAND_SYM:
X if(obj->known)
X Sprintf(eos(bp), " (%d)", obj->spe);
X break;
X case RING_SYM:
X if(obj->owornmask & W_RINGR) Strcat(bp, " (on right ");
X if(obj->owornmask & W_RINGL) Strcat(bp, " (on left ");
X if(obj->owornmask & W_RING) {
X Strcat(bp, body_part(HAND));
X Strcat(bp, ")");
X }
X if(obj->known && objects[obj->otyp].oc_charged) {
X Strcat(prefix, sitoa(obj->spe));
X Strcat(prefix, " ");
X }
X break;
X case FOOD_SYM:
X if(obj->otyp == CORPSE) {
X Strcat(prefix, mons[obj->corpsenm].mname);
X Strcat(prefix, " ");
X } else if(obj->otyp == EGG && obj->known) {
X if(obj->corpsenm >= 0) {
X Strcat(prefix, mons[obj->corpsenm].mname);
X Strcat(prefix, " ");
X#ifdef POLYSELF
X if (obj->spe)
X Strcat(bp, " (laid by you)");
X#endif
X }
X }
X break;
X case BALL_SYM:
X if(obj->owornmask & W_BALL)
X Strcat(bp, " (chained to you)");
X break;
X }
X
X if(obj->owornmask & W_WEP) {
X Strcat(bp, " (weapon in ");
X Strcat(bp, body_part(HAND));
X Strcat(bp, ")");
X }
X if(obj->unpaid)
X Strcat(bp, " (unpaid)");
X if (!strncmp(prefix, "a ", 2) &&
X index(vowels, *(prefix+2) ? *(prefix+2) : *bp)
X && (*(prefix+2) || strncmp(bp, "uranium", 7))) {
X Strcpy(tmpbuf, prefix);
X Strcpy(prefix, "an ");
X Strcpy(prefix+3, tmpbuf+2);
X }
X bp = strprepend(bp, prefix);
X return(bp);
X}
X
X/* used only in fight.c (thitu) */
Xvoid
Xsetan(str,buf)
Xregister char *str,*buf;
X{
X if(index(vowels,*str))
X Sprintf(buf, "an %s", str);
X else
X Sprintf(buf, "a %s", str);
X}
X
Xchar *
Xaobjnam(otmp,verb) register struct obj *otmp; register char *verb; {
Xregister char *bp = xname(otmp);
Xchar prefix[PREFIX];
X if(otmp->quan != 1) {
X Sprintf(prefix, "%u ", otmp->quan);
X bp = strprepend(bp, prefix);
X }
X
X if(verb) {
X /* verb is given in plural (i.e., without trailing s) */
X Strcat(bp, " ");
X if(otmp->quan != 1)
X Strcat(bp, verb);
X else if(!strcmp(verb, "are"))
X Strcat(bp, "is");
X else {
X Strcat(bp, verb);
X Strcat(bp, "s");
X }
X }
X return(bp);
X}
X
Xchar *
XDoname2(obj)
Xregister struct obj *obj;
X{
X register char *s = doname(obj);
X
X if('a' <= *s && *s <= 'z') *s -= ('a' - 'A');
X return(s);
X}
X
Xconst char *wrp[] = { "wand", "ring", "potion", "scroll", "gem", "amulet",
X#ifdef SPELLS
X "spellbook",
X#endif
X /* for non-specific wishes */
X "weapon", "armor", "tool", "food", "comestible",
X };
Xconst char wrpsym[] = {WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM, AMULET_SYM,
X#ifdef SPELLS
X SPBOOK_SYM,
X#endif
X WEAPON_SYM, ARMOR_SYM, TOOL_SYM, FOOD_SYM, FOOD_SYM
X };
X
Xvoid
Xlcase(str)
Xregister char *str;
X{
X register char *p;
X for (p = str; *p; p++)
X if('A' <= *p && *p <= 'Z') *p += 'a'-'A';
X}
X
X/* Plural routine; chiefly used for user-defined fruits. We have to try to
X * account for everything reasonable the player has; something unreasonable
X * can still break the code. However, it's still a lot more accurate than
X * "just add an s at the end", which Rogue uses...
X *
X * Also used for plural monster names ("Wiped out all homunculi.")
X * and body parts.
X */
Xchar *
Xmakeplural(oldstr)
Xchar *oldstr;
X{
X register char *spot;
X static char str[BUFSZ];
X static char *excess;
X int len;
X
X while (*oldstr==' ') oldstr++;
X if (!oldstr || !*oldstr) {
X impossible("plural of null?");
X return("s");
X }
X Strcpy(str, oldstr);
X
X /* Search for common compounds, i.e. lump of royal jelly */
X for(excess=0, spot=str; *spot; spot++) {
X if (!strncmp(spot, " of ", 4) || !strncmp(spot, " with ", 6)
X || !strncmp(spot, " a la ", 6)
X || !strncmp(spot, " from ", 6)
X || !strncmp(spot, " in ", 4)
X || !strncmp(spot, " labeled ", 9)
X || !strncmp(spot, " called ", 8)
X || !strncmp(spot, " named ", 7)
X || !strncmp(spot, " on ", 4)
X || !strcmp(spot, " above") /* lurkers above */
X || !strncmp(spot, " versus ", 8)
X || !strncmp(spot, " de ", 4)
X || !strncmp(spot, " d'", 3)
X || !strncmp(spot, " du ", 4)) {
X excess = oldstr + (spot - str);
X *spot = 0;
X break;
X }
X }
X spot--;
X while (*spot==' ') spot--; /* Strip blanks from end */
X *(spot+1) = 0;
X /* Now spot is the last character of the string */
X
X /* Single letters */
X len = strlen(str);
X if (len==1) {
X Strcpy(spot+1, "'s");
X goto bottom;
X }
X
X /* man/men ("Wiped out all cavemen.") */
X if (len >= 3 && !strcmp(spot-2, "man") &&
X (len<6 || strcmp(spot-5, "shaman")) &&
X (len<5 || strcmp(spot-4, "human"))) {
X *(spot-1) = 'e';
X goto bottom;
X }
X
X /* mouse/mice,louse/lice (not a monster, but possible in a food name) */
X if (len >= 5 && !strcmp(spot-3, "ouse") && index("MmLl", *(spot-4))) {
X Strcpy(spot-3, "ice");
X goto bottom;
X }
X
X /* matzoh/matzot, possible food name */
X if (len >= 6 && !strcmp(spot-5, "matzoh")) {
X *(spot) = 't';
X goto bottom;
X }
X
X /* child/children (for the wise guys who give their food funny names) */
X if (len >= 5 && !strcmp(spot-4, "child")) {
X Strcpy(spot, "dren");
X goto bottom;
X }
X
X /* tooth/teeth */
X if (len >= 5 && !strcmp(spot-4, "tooth")) {
X Strcpy(spot-3, "eeth");
X goto bottom;
X }
X
X /* knife/knives, etc... */
X if (!strcmp(spot-1, "fe"))
X *(spot-1) = 'v';
X else if (*spot == 'f')
X if (index("lr", *(spot-1)) || index(vowels, *(spot-1)))
X *spot = 'v';
X else if (!strncmp(spot-4, "staf", 4))
X Strcpy(spot-1, "ve");
X
X /* foot/feet (body part) */
X if (len >= 4 && !strcmp(spot-3, "foot")) {
X Strcpy(spot-2, "eet");
X goto bottom;
X }
X
X /* ium/ia (mycelia, baluchitheria) */
X if (len >= 3 && !strcmp(spot-2, "ium")) {
X *(spot--) = (char)0;
X *spot = 'a';
X goto bottom;
X }
X
X /* algae, larvae, hyphae (another fungus part) */
X if ((len >= 4 && !strcmp(spot-3, "alga")) ||
X (len >= 5 &&
X (!strcmp(spot-4, "hypha") || !strcmp(spot-4, "larva")))) {
X Strcpy(spot, "ae");
X goto bottom;
X }
X
X /* fungus/fungi, homunculus/homunculi */
X if (!strcmp(spot-1, "us")) {
X *(spot--) = (char)0;
X *spot = 'i';
X goto bottom;
X }
X
X /* vortex/vortices */
X if (len >= 6 && !strcmp(spot-3, "rtex")) {
X Strcpy(spot-1, "ices");
X goto bottom;
X }
X
X /* djinni/djinn (note: also efreeti/efreet) */
X if (len >= 6 && !strcmp(spot-5, "djinni")) {
X *(spot--) = (char)0;
X goto bottom;
X }
X
X /* same singular and plural */
X /* note: also swine, trout, grouse */
X if ((len >= 7 && !strcmp(spot-6, "samurai")) ||
X (len >= 5 &&
X (!strcmp(spot-4, "manes") || !strcmp(spot-4, "sheep"))) ||
X (len >= 4 &&
X (!strcmp(spot-3, "fish") || !strcmp(spot-3, "tuna") ||
X !strcmp(spot-3, "deer"))))
X goto bottom;
X
X /* Aren't the following two going a bit far? --KAA */
X /* eau/eaux (gateau) */
X if (len >= 3 && !strcmp(spot-2, "eau")) {
X Strcpy(spot, "ux");
X goto bottom;
X }
X
X /* sis/ses (oasis, nemesis) */
X if (len >= 3 && !strcmp(spot-2, "sis")) {
X *(spot-1) = 'e';
X goto bottom;
X }
X
X /* note: ox/oxen, VAX/VAXen, goose/geese */
X
X /* Ends in z, x, s, ch, sh; add an "es" */
X if (index("zxsv", *spot) || (*spot=='h' && index("cs", *(spot-1))) ||
X /* Kludge to get "tomatoes" and "potatoes" right */
X (len >= 4 && !strcmp(spot-2, "ato"))) {
X Strcpy(spot+1, "es");
X goto bottom;
X }
X
X /* Ends in y preceded by consonant or "qu"; change to "ies" */
X if (*spot == 'y' &&
X (!index(vowels, *(spot-1)) || !strncmp("qu", spot-2, 2))) {
X Strcpy(spot, "ies");
X goto bottom;
X }
X
X /* Default: append an 's' */
X Strcpy(spot+1, "s");
X
Xbottom: if (excess) Strcpy(str+strlen(str), excess);
X return str;
X}
X
Xstatic const char *armor_classes[] = {
X /* "shield called reflection" gives a specific type of shield.
X * "shield" gives a random type of shield--but not of all armor.
X */
X "gloves", "boots", "cloak", "shield", "helmet"
X};
X#define ARMOR_CLASSES 5
X
X/* Return something wished for. If not an object, return &zeroobj; if an error
X * (no matching object), return (struct obj *)0. Giving readobjnam() a null
X * pointer skips the error return and creates a random object instead.
X */
Xstruct obj *
Xreadobjnam(bp)
Xregister char *bp;
X{
X register char *p;
X register int i;
X register struct obj *otmp;
X struct fruit *f;
X int cnt, spe, spesgn, typ, heavy, blessed, uncursed;
X int iscursed, ispoisoned, mntmp, contents, iskey=0;
X int isnamedbox=0, ftype = current_fruit;
X char let;
X char *un, *dn, *an;
X char *name=0;
X char fruitbuf[BUFSZ];
X /* We want to check for fruits last so that, for example, someone
X * who names their fruit "katana" and wishes for a katana gets a real
X * one. But, we have to keep around the old buf since in the meantime
X * we have deleted "empty", "+6", etc...
X */
X#ifdef WIZARD
X int fake=0;
X#endif
X
X cnt = spe = spesgn = typ = heavy =
X blessed = uncursed = iscursed = ispoisoned = 0;
X mntmp = -1;
X#define UNDEFINED 0
X#define EMPTY 1
X#define SPINACH 2
X contents = UNDEFINED;
X let = 0;
X an = dn = un = 0;
X
X for(;;) {
X if (!bp) goto any;
X if(!strncmp(bp, "an ", 3)) {
X cnt = 1;
X bp += 3;
X } else if(!strncmp(bp, "a ", 2)) {
X cnt = 1;
X bp += 2;
X } else if(!strncmp(bp, "cheap plastic imitation of ", 27)) {
X#ifdef WIZARD
X fake = 1;
X#endif
X bp += 27;
X } else if(!strncmp(bp, "the ", 4)){
X /* the = 1; */
X bp += 4;
X } else if(!cnt && digit(*bp)){
X cnt = atoi(bp);
X while(digit(*bp)) bp++;
X while(*bp == ' ') bp++;
X } else if(!strncmp(bp,"blessed ",8) || !strncmp(bp,"holy ",5)) {
X blessed=1;
X bp += 8;
X } else if(!strncmp(bp,"cursed ",7) || !strncmp(bp,"unholy ",7)){
X iscursed=1;
X bp += 7;
X } else if(!strncmp(bp, "uncursed ",9)) {
X uncursed=1;
X bp += 9;
X } else break;
X }
X if(!cnt) cnt = 1; /* %% what with "gems" etc. ? */
X Strcpy(fruitbuf, bp);
X if(!strncmp(bp, "empty ", 6)) {
X contents = EMPTY;
X bp += 6;
X } else if(!strncmp(bp, "poisoned ",9)) {
X ispoisoned=1;
X bp += 9;
X#ifdef WIZARD
X } else if(wizard && !strncmp(bp, "trapped ",8)) {
X ispoisoned=1;
X bp += 8;
X#endif
X }
X if(*bp == '+' || *bp == '-'){
X spesgn = (*bp++ == '+') ? 1 : -1;
X spe = atoi(bp);
X while(digit(*bp)) bp++;
X while(*bp == ' ') bp++;
X } else {
X p = rindex(bp, '(');
X if(p) {
X if(p > bp && p[-1] == ' ') p[-1] = 0;
X else *p = 0;
X p++;
X if (!(isnamedbox = named_box(p))) {
X spe = atoi(p);
X while(digit(*p)) p++;
X if (*p != ')') spe = 0;
X else {
X spesgn = 1;
X p++;
X if (*p) Strcat(bp, p);
X }
X }
X }
X }
X /* now we have the actual name, as delivered by xname, say
X green potions called whisky
X scrolls labeled "QWERTY"
X egg
X fortune cookies
X very heavy iron ball named hoei
X wand of wishing
X elven cloak
X */
X for(p = bp; *p; p++) if(!strncmp(p, " named ", 7)) {
X *p = 0;
X name = p+7;
X }
X for(p = bp; *p; p++) if(!strncmp(p, " called ", 8)) {
X *p = 0;
X un = p+8;
X /* "helmet called telepathy" is not "helmet" (a specific type)
X * "shield called reflection" is not "shield" (a general type)
X */
X for(i=0; i<ARMOR_CLASSES; i++)
X if(!strncmp(bp,armor_classes[i], strlen(armor_classes[i]))){
X let = ARMOR_SYM;
X goto srch;
X }
X }
X for(p = bp; *p; p++) if(!strncmp(p, " labeled ", 9)) {
X *p = 0;
X dn = p+9;
X }
X for(p = bp; *p; p++) if(!strncmp(p, " labelled ", 10)) {
X *p = 0;
X dn = p+10;
X }
X for(p = bp; *p; p++) if(!strncmp(p, " of spinach", 11)) {
X *p = 0;
X contents = SPINACH;
X }
X
X /* Skip over "pair of ", then jump to the singular so we don't
X try to convert "gloves" or "boots". */
X if(cnt == 1 && !strncmp(bp, "pair of ",8)) {
X bp += 8;
X cnt = 2;
X /* cnt is ignored for armor and other non-stackable objects;
X DTRT for stackable objects */
X } else if(cnt > 1 && !strncmp(bp, "pairs of ",9)) {
X bp += 9;
X cnt *= 2;
X }
X
X /* Find corpse type using "of" (figurine of an orc, tin of orc meat) */
X for(p = bp; *p; p++)
X if (!strncmp(p, " of ", 4) && (mntmp = name_to_mon(p+4)) >= 0) {
X *p = 0;
X break;
X }
X /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
X if (strncmp(bp, "samurai sword", 13)) /* not the "samurai" monster! */
X if (strncmp(bp, "orcish", 6)) /* not the "orc" monster! */
X if (mntmp < 0) if ((mntmp = name_to_mon(bp)) >= 0) {
X bp += strlen(mons[mntmp].mname);
X if (*bp==' ') bp++;
X }
X
X /* first change to singular if necessary */
X if(cnt != 1) {
X /* find "cloves of garlic", "worthless pieces of blue glass" */
X for(p = bp; *p; p++)
X if(!strncmp(p, "s of ", 5)){
X /* but don't singularize "gauntlets" */
X if(strncmp(p-8, "gauntlet", 8))
X while(*p = p[1]) p++;
X goto sing;
X }
X /* remove -s or -es (boxes) or -ies (rubies) */
X p = eos(bp);
X if(p[-1] == 's') {
X if(p[-2] == 'e') {
X if(p[-3] == 'i') {
X
X if(!strcmp(p-7, "cookies") ||
X !strcmp(p-4, "pies"))
X goto mins;
X Strcpy(p-3, "y");
X goto sing;
X }
X
X /* note: cloves / knives from clove / knife */
X if(!strcmp(p-6, "knives")) {
X Strcpy(p-3, "fe");
X goto sing;
X }
X
X /* note: nurses, axes but boxes */
X if(!strcmp(p-5, "boxes")) {
X p[-2] = 0;
X goto sing;
X }
X }
X /* but don't singularize boots or gloves */
X else if(!strcmp(p-5, "boots") ||
X !strcmp(p-6, "gloves"))
X goto sing;
X mins:
X p[-1] = 0;
X } else {
X if(!strcmp(p-5, "teeth")) {
X Strcpy(p-5, "tooth");
X goto sing;
X }
X /* here we cannot find the plural suffix */
X }
X }
Xsing:
X /* Maybe we need a special strcmp() which ignores capitalization and
X * dashes/spaces/underscores, so the below 3 special cases would be
X * unnecessary.
X */
X /* Alternate spellings (two-handed sword vs. two handed sword) */
X if(!strcmp(bp, "two handed sword")) {
X typ = TWO_HANDED_SWORD;
X goto typfnd;
X }
X /* pick-axe vs. pick axe */
X if(!strcmp(bp, "pick axe")) {
X typ = PICK_AXE;
X goto typfnd;
X }
X if(!strcmp(bp, "luck stone")){
X typ = LUCKSTONE;
X goto typfnd;
X }
X if(!strcmp(bp, "load stone")){
X typ = LOADSTONE;
X goto typfnd;
X }
X /* Alternate capitalizations (Amulet of Yendor, amulet of esp) */
X if(!strcmp(bp, "amulet of Yendor")) {
X typ = AMULET_OF_YENDOR;
X goto typfnd;
X }
X if(!strcmp(bp, "amulet of ESP")) {
X typ = AMULET_OF_ESP;
X goto typfnd;
X }
X if(!strcmp(bp, "ring mail") || /* Note: ring mail is not a ring ! */
X !strcmp(bp, "leather armor") || /* Prevent falling to 'armor'. */
X !strcmp(bp, "studded leather armor")) {
X let = ARMOR_SYM;
X an = bp;
X goto srch;
X }
X if(!strcmp(bp, "food ration")){
X let = FOOD_SYM;
X an = bp;
X goto srch;
X }
X if((iskey = named_key(bp)) > 0) {
X typ = KEY;
X goto typfnd;
X }
X p = eos(bp);
X if(!strcmp(p-10, "holy water")) {
X typ = POT_WATER;
X if (*(p-12) == 'u') iscursed = 1; /* unholy water */
X else blessed = 1;
X goto typfnd;
X }
X#ifdef SHIRT
X if (!strcmp(p-5, "shirt")) {
X typ = HAWAIIAN_SHIRT;
X goto typfnd;
X }
X#endif
X if (strlen(bp) == 1 && index(obj_symbols, *bp)) {
X let = *bp;
X goto any;
X }
X if(strncmp(bp, "enchant ", 8) &&
X strncmp(bp, "destroy ", 8) &&
X strncmp(bp, "food detection", 14))
X /* allow wishes for "enchant weapon" and "food detection" */
X for(i = 0; i < sizeof(wrpsym); i++) {
X register int j = strlen(wrp[i]);
X if(!strncmp(bp, wrp[i], j)){
X let = wrpsym[i];
X if(let != AMULET_SYM) {
X bp += j;
X if(!strncmp(bp, " of ", 4)) an = bp+4;
X /* else if(*bp) ?? */
X } else
X an = bp;
X goto srch;
X }
X if(!strcmp(p-j, wrp[i])){
X let = wrpsym[i];
X p -= j;
X *p = 0;
X if(p[-1] == ' ') p[-1] = 0;
X dn = bp;
X goto srch;
X }
X }
X if(!strcmp(p-6, " stone")){
X p[-6] = 0;
X let = GEM_SYM;
X dn = an = bp;
X goto srch;
X }
X if(!strcmp(p-10, "gold piece") || !strcmp(p-7, "zorkmid") ||
X !strcmp(bp, "Zorkmid") ||
X !strcmp(bp, "gold") || !strcmp(bp, "money") || *bp == GOLD_SYM) {
X if (cnt > 5000
X#ifdef WIZARD
X && !wizard
X#endif
X ) cnt=5000;
X if (cnt < 1) cnt=1;
X pline("%d gold piece%s.", cnt, cnt==1 ? "" : "s");
X u.ugold += cnt;
X flags.botl=1;
X return (&zeroobj);
X }
X#ifdef WIZARD
X /* Let wizards wish for traps --KAA */
X if (wizard) {
X int trap;
X char *tname;
X
X for (trap = NO_TRAP+1; trap < TRAPNUM; trap++) {
X tname = index(traps[trap], ' ');
X if (tname) {
X if (!strncmp(tname+1, bp, strlen(tname+1))) {
X (void) maketrap(u.ux, u.uy, trap);
X pline("A%s.", traps[trap]);
X if (Invisible) newsym(u.ux,u.uy);
X return(&zeroobj);
X }
X }
X }
X }
X#endif
X if(!strcmp(bp, "very heavy iron ball")) {
X heavy = 1;
X typ = HEAVY_IRON_BALL;
X goto typfnd;
X }
X if(!strcmp(bp, "bag")) {
X typ = rnd_class(SACK, BAG_OF_TRICKS);
X goto typfnd;
X }
X if(!strcmp(bp, armor_classes[0])){ /* pair of gloves */
X typ = rnd_class(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY);
X goto typfnd;
X }
X if(!strcmp(bp, armor_classes[1])){ /* pair of boots */
X typ = rnd_class(LOW_BOOTS, LEVITATION_BOOTS);
X goto typfnd;
X }
X if(!strcmp(bp, armor_classes[2])){ /* cloak */
X typ = rnd_class(MUMMY_WRAPPING, CLOAK_OF_DISPLACEMENT);
X goto typfnd;
X }
X if(!strcmp(bp, armor_classes[3])){ /* shield */
X typ = rnd_class(SMALL_SHIELD, SHIELD_OF_REFLECTION);
X goto typfnd;
X }
X /* helmet is not generic */
X
X an = bp;
X if (!dn) dn = an; /* i.e., "black cap" */
Xsrch:
X i = 1;
X if(let) i = bases[letindex(let)];
X while(i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)){
X register char *zn;
X
X if(an && (zn = objects[i].oc_name) && !strcmp(an, zn)) {
X typ = i;
X goto typfnd;
X }
X if(dn && (zn = objects[i].oc_descr) && !strcmp(dn, zn)) {
X typ = i;
X goto typfnd;
X }
X if(un && (zn = objects[i].oc_uname) && !strcmp(un, zn)) {
X typ = i;
X goto typfnd;
X }
X i++;
X }
X for(f=ffruit; f; f = f->nextf) {
X char *f1 = f->fname, *f2 = makeplural(f->fname);
X
X if(!strncmp(fruitbuf, f1, strlen(f1)) ||
X !strncmp(fruitbuf, f2, strlen(f2))) {
X typ = SLIME_MOLD;
X ftype = f->fid;
X goto typfnd;
X }
X }
X if(!let) return((struct obj *)0);
Xany:
X if(!let) let = wrpsym[rn2(sizeof(wrpsym))];
Xtypfnd:
X if(typ) {
X let = objects[typ].oc_olet;
X otmp = mksobj(typ,FALSE);
X } else {
X otmp = mkobj(let,FALSE);
X typ = otmp->otyp;
X }
X
X /* venom isn't really an object and can't be wished for; but allow
X * wizards to wish for it since it's faster than polymorphing and
X * spitting.
X */
X if(otmp->olet==VENOM_SYM
X#ifdef WIZARD
X && !wizard
X#endif
X ) {
X free((genericptr_t) otmp);
X return((struct obj *)0);
X }
X if(iskey) otmp->spe = (iskey-1);
X if(isnamedbox && (otmp->otyp==LARGE_BOX || otmp->otyp==CHEST))
X otmp->spe = (isnamedbox-1);
X
X if(cnt > 0 && objects[typ].oc_merge &&
X#ifdef SPELLS
X let != SPBOOK_SYM &&
X#endif
X (cnt < rnd(6) ||
X#ifdef WIZARD
X wizard ||
X#endif
X (cnt <= 20 &&
X (let == WEAPON_SYM && typ <= SHURIKEN) || (typ == ROCK))))
X otmp->quan = cnt;
X
X if (spesgn == 0) spe = otmp->spe;
X#ifdef WIZARD
X else if (wizard) /* no alteration to spe */ ;
X#endif
X else if (let == ARMOR_SYM || let == WEAPON_SYM || typ == PICK_AXE ||
X (let==RING_SYM && objects[typ].oc_charged)) {
X if(spe > rnd(5) && spe > otmp->spe) spe = 0;
X if(spe > 2 && u.uluck < 0) spesgn = -1;
X } else {
X if (let == WAND_SYM) {
X if (spe > 1 && spesgn == -1) spe = 1;
X } else {
X if (spe > 0 && spesgn == -1) spe = 0;
X }
X if (spe > otmp->spe) spe = otmp->spe;
X }
X
X if (spesgn == -1) spe = -spe;
X
X /* set otmp->spe. This may, or may not, use spe... */
X switch (typ) {
X case TIN: if (contents==EMPTY) {
X otmp->corpsenm = -1;
X otmp->spe = 0;
X } else if (contents==SPINACH) {
X otmp->corpsenm = -1;
X otmp->spe = 1;
X }
X break;
X case SLIME_MOLD: otmp->spe = ftype;
X /* Fall through */
X case SKELETON_KEY: case KEY: case CHEST: case LARGE_BOX:
X case HEAVY_IRON_BALL: case IRON_CHAIN: case STATUE:
X /* otmp->spe already done in mksobj() */
X break;
X#ifdef MAIL
X case SCR_MAIL: otmp->spe = 1; break;
X#endif
X case AMULET_OF_YENDOR:
X#ifdef WIZARD
X if (fake || !wizard)
X#endif
X otmp->spe = -1;
X#ifdef WIZARD
X else otmp->spe = 0;
X#endif
X break;
X case WAN_WISHING:
X#ifdef WIZARD
X if (!wizard)
X#endif
X otmp->spe = (rn2(10) ? -1 : 0); break;
X /* fall through, if wizard */
X default: otmp->spe = spe;
X }
X
X /* set otmp->corpsenm */
X if (mntmp > -1) switch(typ) {
X case TIN:
X otmp->spe = 0; /* No spinach */
X case CORPSE:
X if (!(mons[mntmp].geno & G_NOCORPSE))
X otmp->corpsenm = mntmp;
X break;
X case FIGURINE:
X if (!is_dlord(&mons[mntmp]) && !is_dprince(&mons[mntmp])
X && !is_human(&mons[mntmp])
X#ifdef WORM
X && mntmp != PM_LONG_WORM
X#endif
X )
X otmp->corpsenm = mntmp;
X break;
X case EGG: if (lays_eggs(&mons[mntmp]) || mntmp==PM_KILLER_BEE)
X otmp->corpsenm = mntmp;
X break;
X case STATUE: otmp->corpsenm = mntmp;
X break;
X case DRAGON_SCALE_MAIL: /* Not actually possible unless they
X typed "red dragon dragon scale mail" */
X case SCALE_MAIL:
X if (mntmp >= PM_GREY_DRAGON &&
X mntmp <= PM_YELLOW_DRAGON)
X otmp->corpsenm = mntmp;
X if (otmp->corpsenm >= 0)
X otmp->otyp = DRAGON_SCALE_MAIL;
X break;
X }
X
X /* set blessed/cursed */
X if (iscursed) {
X curse(otmp);
X } else if (uncursed) {
X otmp->blessed = 0;
X otmp->cursed = (u.uluck < 0);
X } else if (blessed) {
X otmp->blessed = (u.uluck >= 0);
X otmp->cursed = (u.uluck < 0);
X } else if (spesgn < 0) {
X curse(otmp);
X }
X
X /* set poisoned */
X if (ispoisoned) {
X if (let == WEAPON_SYM && typ <= SHURIKEN)
X otmp->opoisoned = (u.uluck >= 0);
X#ifdef WIZARD
X else if (Is_box(otmp))
X otmp->otrapped = 1;
X else if (let == FOOD_SYM)
X /* try to taint by making it as old as possible */
X otmp->age = 1L;
X#endif
X }
X
X if (name) otmp = oname(otmp, name, 0);
X otmp->owt = weight(otmp);
X if (heavy) otmp->owt += 15;
X return(otmp);
X}
X
Xboolean
Xuses_known(otmp)
Xregister struct obj *otmp;
X/* returns TRUE if otmp->known would be used to affect the full description
X * of the item
X * if not, otmp->dknown and otmp->bknown give all the information of otmp->known
X * and otmp->known should always be set to avoid problems with items not
X * merging due to different values of otmp->known
X */
X{
X return (otmp->olet == ARMOR_SYM ||
X otmp->olet == WAND_SYM ||
X otmp->olet == WEAPON_SYM ||
X ((otmp->olet == TOOL_SYM || otmp->olet == RING_SYM) &&
X objects[otmp->otyp].oc_charged) ||
X otmp->otyp == FIGURINE ||
X otmp->otyp == EGG ||
X otmp->otyp == TIN ||
X otmp->otyp == AMULET_OF_YENDOR);
X}
X
Xstatic int
Xrnd_class(first,last)
Xint first,last;
X{
X int i, x, sum=0;
X for(i=first; i<=last; i++)
X sum += objects[i].oc_prob;
X x = rnd(sum);
X for(i=first; i<=last; i++)
X if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
X return i;
X return 0;
X}
END_OF_FILE
if test 33829 -ne `wc -c <'src/objnam.c'`; then
echo shar: \"'src/objnam.c'\" unpacked with wrong size!
fi
# end of 'src/objnam.c'
fi
if test -f 'src/u_init.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/u_init.c'\"
else
echo shar: Extracting \"'src/u_init.c'\" \(17550 characters\)
sed "s/^X//" >'src/u_init.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)u_init.c 3.0 88/04/13
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
Xstruct trobj {
X unsigned short int trotyp;
X schar trspe;
X char trolet;
X Bitfield(trquan,6);
X Bitfield(trknown,1);
X Bitfield(trbless,2);
X};
X
Xstatic void ini_inv P((struct trobj *));
X
X#define UNDEF_TYP 0
X#define UNDEF_SPE '\177'
X#define UNDEF_BLESS 2
X
Xchar *(roles[]) = { /* must all have distinct first letter */
X /* roles[2] and [6] are changed for females */
X /* in all cases, the corresponding male and female */
X /* roles must start with the same letter */
X "Archeologist", "Barbarian", "Cave-man", "Elf", "Healer", "Knight",
X "Priest", "Rogue", "Samurai", "Tourist", "Valkyrie", "Wizard"
X};
X
Xstruct you zerou;
X
X#define NR_OF_ROLES SIZE(roles)
Xchar rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */
X
Xstruct trobj Cave_man[] = {
X#define C_ARROWS 2
X { CLUB, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { BOW, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS }, /* quan is variable */
X { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Barbarian[] = {
X { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { AXE, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { RING_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { FOOD_RATION, 0, FOOD_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Knight[] = {
X { LONG_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { SPEAR, 2, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { RING_MAIL, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { HELMET, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { SMALL_SHIELD, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { LEATHER_GLOVES, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Elf[] = {
X#define E_ARROWS 2
X#define E_ARMOR 3
X#ifdef TOLKIEN
X { ELVEN_SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { ELVEN_BOW, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { ELVEN_ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS },
X { UNDEF_TYP, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { LEMBAS_WAFER, 0, FOOD_SYM, 2, 1, 0 },
X#else
X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { BOW, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS },
X { ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { FOOD_RATION, 0, FOOD_SYM, 2, 1, 0 },
X#endif
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Valkyrie[] = {
X { LONG_SWORD, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { DAGGER, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { SMALL_SHIELD, 3, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { FOOD_RATION, 0, FOOD_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Healer[] = {
X { SCALPEL, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { LEATHER_GLOVES, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { STETHOSCOPE, 0, TOOL_SYM, 1, 1, 0 },
X { POT_HEALING, 0, POTION_SYM, 4, 1, UNDEF_BLESS },
X { POT_EXTRA_HEALING, 0, POTION_SYM, 4, 1, UNDEF_BLESS },
X { WAN_SLEEP, UNDEF_SPE, WAND_SYM, 1, 1, UNDEF_BLESS },
X { APPLE, 0, FOOD_SYM, 5, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Archeologist[] = {
X /* if adventure has a name... idea from tan@uvm-gen */
X { BULLWHIP, 2, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { FEDORA, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { FOOD_RATION, 0, FOOD_SYM, 3, 1, 0 },
X { PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 1, UNDEF_BLESS },
X { TINNING_KIT, 0, TOOL_SYM, 1, 1, UNDEF_BLESS },
X { SACK, 0, TOOL_SYM, 1, 0, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Tinopener[] = {
X { TIN_OPENER, 0, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Magicmarker[] = {
X { MAGIC_MARKER, UNDEF_SPE, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Lamp[] = {
X { LAMP, 5, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
X#ifndef HARD
Xstruct trobj Saving[] = {
X { AMULET_OF_LIFE_SAVING, 0, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X#endif
X
X#ifdef EXPLORE_MODE
Xstruct trobj Wishing[] = {
X { WAN_WISHING, 3, WAND_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X#endif
X
X#ifdef WALKIES
Xstruct trobj Leash[] = {
X { LEASH, 0, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X#endif
X
Xstruct trobj Blindfold[] = {
X { BLINDFOLD, 0, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Tourist[] = {
X#define T_DARTS 0
X { DART, 2, WEAPON_SYM, 25, 1, UNDEF_BLESS }, /* quan is variable */
X { UNDEF_TYP, UNDEF_SPE, FOOD_SYM, 10, 1, 0 },
X { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 1, UNDEF_BLESS },
X { SCR_MAGIC_MAPPING, 0, SCROLL_SYM, 4, 1, UNDEF_BLESS },
X { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1, 0 },
X#ifdef SHIRT
X { HAWAIIAN_SHIRT, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X#endif
X { CREDIT_CARD, 0, TOOL_SYM, 1, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Rogue[] = {
X#define R_DAGGERS 1
X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { DAGGER, 0, WEAPON_SYM, 10, 1, 0 }, /* quan is variable */
X { LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { POT_SICKNESS, 0, POTION_SYM, 1, 1, 0 },
X { LOCK_PICK, 9, TOOL_SYM, 1, 1, 0 },
X { SACK, 0, TOOL_SYM, 1, 0, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Wizard[] = {
X#define W_MULTSTART 2
X#ifdef SPELLS
X# define W_MULTEND 6
X#else
X# define W_MULTEND 5
X#endif
X { DAGGER, 0, WEAPON_SYM, 1, 1, 1 }, /* for dealing with ghosts */
X { CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 1, 1, UNDEF_BLESS },
X { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 1, UNDEF_BLESS },
X { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 3, 1, UNDEF_BLESS },
X { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 1, UNDEF_BLESS },
X#ifdef SPELLS
X { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 1, 1, UNDEF_BLESS },
X#endif
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Samurai[] = {
X { KATANA, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS },
X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, /* the wakizashi */
X { SHURIKEN, 0, WEAPON_SYM, 9, 1, UNDEF_BLESS }, /* quan is variable */
X { SPLINT_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { FORTUNE_COOKIE, 0, FOOD_SYM, 3, 1, 0 },
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Priest[] = {
X { MACE, 1, WEAPON_SYM, 1, 1, 1 },
X { CHAIN_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { SMALL_SHIELD, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS },
X { POT_WATER, 0, POTION_SYM, 4, 1, 1 }, /* holy water */
X { CLOVE_OF_GARLIC, 0, FOOD_SYM, 1, 1, 0 },
X#ifdef SPELLS
X { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 1, UNDEF_BLESS },
X#endif
X { 0, 0, 0, 0, 0, 0 }
X};
X
Xstatic void
Xknows_class(sym)
Xregister char sym;
X{
X register unsigned ct;
X for (ct = 1; ct <= NROFOBJECTS; ct++)
X if (objects[ct].oc_olet == sym) {
X makeknown(ct);
X objects[ct].oc_descr = NULL; /* not a "discovery" */
X }
X}
X
Xstatic int
Xrole_index(pc)
Xchar pc;
X{ /* must be called only from u_init() */
X /* so that rolesyms[] is defined */
X register char *cp;
X
X if(cp = index(rolesyms, pc))
X return(cp - rolesyms);
X return(-1);
X}
X
Xvoid
Xu_init()
X{
X register int i;
X char pick, pc;
X
X Printf("\nNetHack, Copyright 1985, 1986, 1987, 1988, 1989.");
X Printf("\n By Stichting Mathematisch Centrum and M. Stephenson.");
X Printf("\n See license for details.\n\n");
X
X if(flags.female) { /* should have been set in NETHACKOPTIONS */
X roles[2] = "Cave-woman";
X roles[6] = "Priestess";
X }
X for(i = 0; i < NR_OF_ROLES; i++)
X rolesyms[i] = roles[i][0];
X rolesyms[i] = 0;
X
X if(pc = pl_character[0]) {
X if('a' <= pc && pc <= 'z') pc += 'A'-'a';
X if((i = role_index(pc)) >= 0)
X goto got_suffix;
X Printf("\nUnknown role: %c\n", pc);
X pl_character[0] = pc = 0;
X }
X
X Printf("\nShall I pick a character for you? [Y,N, or Q(quit)] ");
X
X while(!index("yYnNqQ", (pick = readchar())) && !index(quitchars, pick))
X bell();
X
X if(index(quitchars, pick)) pick = 'Y';
X else if('a' <= pick && pick <= 'z') pick += 'A'-'a';
X
X Printf("%c\n", pick); /* echo */
X
X if (pick == 'Q') {
X clearlocks();
X settty(NULL);
X exit(0);
X }
X
X if (pick == 'Y')
X goto beginner;
X
X Printf("\nWhat kind of character are you:\n\n");
X Printf(" An");
X Printf(" %s,",roles[0]);
X for(i = 1; i < NR_OF_ROLES; i++) {
X Printf(" a%s %s", index(vowels,roles[i][0]) ? "n" : "", roles[i]);
X if((((i + 1) % 4) == 0) && (i != NR_OF_ROLES -1)) Printf(",\n ");
X else if(i < NR_OF_ROLES - 2) Printf(",");
X if(i == NR_OF_ROLES - 2) Printf(" or");
X }
X Printf("?\n [");
X for(i = 0; i < NR_OF_ROLES; i++) Printf("%c,", rolesyms[i]);
X Printf(" or Q] ");
X
X while(pc = readchar()) {
X if('a' <= pc && pc <= 'z') pc += 'A'-'a';
X if (pc == 'Q') {
X clearlocks();
X settty(NULL);
X exit(0);
X }
X if((i = role_index(pc)) >= 0) {
X Printf("%c\n", pc); /* echo */
X (void) fflush(stdout); /* should be seen */
X break;
X }
X if(pc == '\n') break;
X bell();
X }
X if(pc == '\n') pc = 0;
X
Xbeginner:
X if(!pc) {
X i = rn2(NR_OF_ROLES);
X pc = rolesyms[i];
X Printf("\nThis game you will be %s %s.\n",
X index("AEIOU", roles[i][0]) ? "an" : "a",
X roles[i]);
X getret();
X /* give him some feedback in case mklev takes much time */
X (void) putchar('\n');
X (void) fflush(stdout);
X }
X
Xgot_suffix:
X
X (void) strncpy(pl_character, roles[i], PL_CSIZ-1);
X pl_character[PL_CSIZ-1] = 0;
X flags.beginner = 1;
X u = zerou;
X u.usym = S_HUMAN;
X u.umoved = FALSE;
X u.ugrave_arise = -1;
X
X u.ulevel = 0; /* set up some of the initial attributes */
X u.uhp = u.uhpmax = newhp();
X adjabil(1);
X u.ulevel = 1;
X
X u.uluck = u.moreluck = 0;
X init_uhunger();
X uarm = uarmc = uarmh = uarms = uarmg = uarmf =
X#ifdef SHIRT
X uarmu =
X#endif
X uwep = uball = uchain = uleft = uright = 0;
X
X#ifdef SPELLS
X u.uen = u.uenmax = 1;
X for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL;
X#endif
X#ifdef THEOLOGY
X u.ublesscnt = 300; /* no prayers just yet */
X u.ublessed = 0; /* not worthy yet */
X u.ugangr = 0; /* gods not angry */
X#endif
X#if defined(THEOLOGY) && defined(ELBERETH)
X u.uhand_of_elbereth = 0;
X#endif
X#ifdef MEDUSA
X u.ukilled_medusa = 0;
X#endif
X#ifdef HARD
X u.udemigod = u.udg_cnt = 0; /* not a demi-god yet... */
X#endif
X#ifdef POLYSELF
X u.umonnum = u.ulycn = -1;
X u.mh = u.mhmax = u.mtimedone = 0;
X set_uasmon();
X#endif
X switch(pc) {
X /* pc will always be in uppercase by this point */
X case 'C':
X Cave_man[C_ARROWS].trquan = 12 + rnd(30);
X ini_inv(Cave_man);
X break;
X case 'T':
X Tourist[T_DARTS].trquan = 20 + rnd(20);
X u.ugold = u.ugold0 = rnd(1000);
X ini_inv(Tourist);
X if(!rn2(25)) ini_inv(Tinopener);
X else if(!rn2(25)) ini_inv(Magicmarker);
X#ifdef WALKIES
X else if(!rn2(25)) ini_inv(Leash);
X#endif
X break;
X case 'R':
X Rogue[R_DAGGERS].trquan = 5 + rnd(10);
X u.ugold = u.ugold0 = 0;
X ini_inv(Rogue);
X if(!rn2(5)) ini_inv(Blindfold);
X makeknown(SACK);
X break;
X case 'W':
X#ifdef SPELLS
X u.uen = u.uenmax += rn2(4);
X#endif
X ini_inv(Wizard);
X if(!rn2(5)) ini_inv(Magicmarker);
X if(!rn2(5)) ini_inv(Blindfold);
X break;
X case 'A':
X ini_inv(Archeologist);
X if(!rn2(10)) ini_inv(Tinopener);
X else if(!rn2(4)) ini_inv(Lamp);
X else if(!rn2(10)) ini_inv(Magicmarker);
X knows_class(GEM_SYM);
X makeknown(SACK);
X /* We can't set trknown for it, then it'd be "uncursed"
X * sack...
X */
X break;
X case 'E':
X Elf[E_ARROWS].trquan = 15+rnd(20);
X#ifdef TOLKIEN
X Elf[E_ARMOR].trotyp = ((rn2(100) >= 50)
X ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
X /* rn2(100) > 50 necessary because some random number
X * generators are bad enough to seriously skew the
X * results if we use rn2(2)... --KAA
X */
X#endif
X ini_inv(Elf);
X if(!rn2(5)) ini_inv(Blindfold);
X else if(!rn2(6)) ini_inv(Lamp);
X#ifdef TOLKIEN
X /* makeknown(ELVEN_SHORT_SWORD);
X * no need to do this since the initial inventory contains one,
X * so ini_inv already did it for us
X */
X objects[ELVEN_SHORT_SWORD].oc_descr = NULL;
X /* makeknown(ELVEN_ARROW); */
X objects[ELVEN_ARROW].oc_descr = NULL;
X /* makeknown(ELVEN_BOW); */
X objects[ELVEN_BOW].oc_descr = NULL;
X makeknown(ELVEN_SPEAR);
X objects[ELVEN_SPEAR].oc_descr = NULL;
X makeknown(ELVEN_DAGGER);
X objects[ELVEN_DAGGER].oc_descr = NULL;
X makeknown(ELVEN_BROADSWORD);
X objects[ELVEN_BROADSWORD].oc_descr = NULL;
X#endif
X makeknown(ELVEN_CLOAK);
X objects[ELVEN_CLOAK].oc_descr = NULL;
X break;
X case 'V':
X flags.female = TRUE;
X ini_inv(Valkyrie);
X if(!rn2(6)) ini_inv(Lamp);
X knows_class(WEAPON_SYM);
X break;
X case 'H':
X u.ugold = u.ugold0 = rnd(1000)+1000;
X ini_inv(Healer);
X if(!rn2(25)) ini_inv(Lamp);
X break;
X case 'K':
X ini_inv(Knight);
X knows_class(WEAPON_SYM);
X break;
X case 'B':
X ini_inv(Barbarian);
X if(!rn2(6)) ini_inv(Lamp);
X knows_class(WEAPON_SYM);
X break;
X case 'S':
X ini_inv(Samurai);
X if(!rn2(5)) ini_inv(Blindfold);
X objects[SHORT_SWORD].oc_name = "wakizashi";
X objects[BROADSWORD].oc_name = "ninja-to";
X objects[GLAIVE].oc_name = "naginata";
X /* objects[BOW].oc_name = "yumi"; */
X objects[LOCK_PICK].oc_name = "osaku";
X knows_class(WEAPON_SYM);
X break;
X case 'P':
X#ifdef SPELLS
X u.uen = u.uenmax += rn2(4);
X#endif
X ini_inv(Priest);
X if(!rn2(10)) ini_inv(Magicmarker);
X else if(!rn2(10)) ini_inv(Lamp);
X break;
X
X default: /* impossible */
X break;
X }
X#ifndef HARD
X ini_inv(Saving); /* give beginners an extra chance */
X#endif
X#ifdef EXPLORE_MODE
X if (discover)
X ini_inv(Wishing);
X#endif
X find_ac(); /* get initial ac value */
X init_attr((pick != 'y') ? 69 : 72); /* init attribute values */
X max_rank_sz(); /* set max str size for class ranks */
X/*
X * Do we really need this?
X */
X for(i = 0; i < A_MAX; i++)
X if(!rn2(20)) {
X register int xd = rn2(7) - 2; /* biased variation */
X adjattrib(i, xd, TRUE);
X }
X
X /* make sure he can carry all he has - especially for T's */
X while(inv_weight() > 0)
X adjattrib(A_STR, 1, TRUE);
X
X#ifdef THEOLOGY
X u.ualignbase[0] = u.ualignbase[1] = u.ualigntyp;
X#endif
X}
X
Xstatic void
Xini_inv(trop)
Xregister struct trobj *trop;
X{
X struct obj *obj;
X while(trop->trolet) {
X boolean undefined = (trop->trotyp == UNDEF_TYP);
X
X if (!undefined)
X obj = mksobj((int)trop->trotyp,FALSE);
X else obj = mkobj(trop->trolet,FALSE);
X
X /* For random objects, do not create certain overly powerful
X * items: wand of wishing, ring of levitation, or the
X * polymorph/polymorph control combination. Specific objects,
X * i.e. the discovery wishing, are still OK.
X */
X if (undefined) {
X#ifdef POLYSELF
X static int nocreate = STRANGE_OBJECT;
X# ifdef SPELLS
X static int nocreate2 = STRANGE_OBJECT;
X# endif
X#endif
X
X while(obj->otyp == WAN_WISHING
X#ifdef POLYSELF
X || obj->otyp == nocreate
X# ifdef SPELLS
X || obj->otyp == nocreate2
X# endif
X#endif
X#ifdef ELBERETH
X || obj->otyp == RIN_LEVITATION
X#endif
X ) {
X free((genericptr_t) obj);
X obj = mkobj(trop->trolet, FALSE);
X }
X
X /* Don't start with +0 or negative rings */
X if(objects[obj->otyp].oc_charged && obj->spe <= 0)
X obj->spe = rne(3);
X
X /* Heavily relies on the fact that 1) we create wands
X * before rings, 2) that we create rings before
X * spellbooks, and that 3) not more than 1 object of a
X * particular symbol is to be prohibited.
X */
X#ifdef POLYSELF
X if (obj->otyp == WAN_POLYMORPH)
X nocreate = RIN_POLYMORPH_CONTROL;
X if (obj->otyp == RIN_POLYMORPH)
X nocreate = RIN_POLYMORPH_CONTROL;
X if (obj->otyp == RIN_POLYMORPH_CONTROL) {
X nocreate = RIN_POLYMORPH;
X# ifdef SPELLS
X nocreate2 = SPE_POLYMORPH;
X# endif /* SPELLS */
X }
X#endif /* POLYSELF */
X }
X
X obj->bknown = trop->trknown;
X if(uses_known(obj)) obj->known = trop->trknown;
X /* not obj->dknown = 1; - let him look at it at least once */
X obj->cursed = 0;
X if(obj->olet == TOOL_SYM){ /* problem with multiple tools */
X obj->quan = 1; /* might be > because of grenades */
X }
X if(obj->olet == WEAPON_SYM) {
X obj->quan = trop->trquan;
X trop->trquan = 1;
X }
X if(obj->olet == FOOD_SYM && undefined) {
X obj->known = 1;
X /* needed for tins and eggs; harmless otherwise */
X obj->bknown = (obj->otyp != DEAD_LIZARD);
X /* only for dead lizards does the blessing not matter */
X }
X /*
X * The below lines not needed because they don't correspond
X * to any actual inventory; nobody gets random tools.
X else if(obj->olet == TOOL_SYM && undefined) {
X obj->bknown = (obj->otyp != BAG_OF_TRICKS
X && obj->otyp != SACK
X && obj->otyp != CHEST
X && obj->otyp != LARGE_BOX
X && obj->otyp != ICE_BOX)
X }
X */
X if(trop->trspe != UNDEF_SPE)
X obj->spe = trop->trspe;
X if(trop->trbless != UNDEF_BLESS)
X obj->blessed = trop->trbless;
X
X if (!Is_container(obj))
X obj->owt = weight(obj);
X /* defined after setting otyp+quan */
X obj = addinv(obj);
X
X /* Make the type known if necessary */
X if (objects[obj->otyp].oc_descr && obj->known)
X makeknown(obj->otyp);
X
X if(obj->olet == ARMOR_SYM){
X if (is_shield(obj) && !uarms)
X setworn(obj, W_ARMS);
X else if (is_helmet(obj) && !uarmh)
X setworn(obj, W_ARMH);
X else if (is_gloves(obj) && !uarmg)
X setworn(obj, W_ARMG);
X#ifdef SHIRT
X else if (obj->otyp == HAWAIIAN_SHIRT && !uarmu)
X setworn(obj, W_ARMU);
X#endif
X else if (is_cloak(obj) && !uarmc)
X setworn(obj, W_ARMC);
X else if (is_boots(obj) && !uarmf)
X setworn(obj, W_ARMF);
X else if (!uarm)
X setworn(obj, W_ARM);
X }
X /* below changed by GAN 01/09/87 to allow wielding of
X * pick-axe or can-opener if there is no weapon
X */
X if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
X obj->otyp == TIN_OPENER)
X if(!uwep) setuwep(obj);
X#ifndef PYRAMID_BUG
X if(--trop->trquan) continue; /* make a similar object */
X#else
X if(trop->trquan) { /* check if zero first */
X --trop->trquan;
X if(trop->trquan)
X continue; /* make a similar object */
X }
X#endif
X trop++;
X }
X}
X
Xvoid
Xplnamesuffix() {
X register char *p;
X if(p = rindex(plname, '-')) {
X *p = 0;
X pl_character[0] = p[1];
X pl_character[1] = 0;
X if(!plname[0]) {
X askname();
X plnamesuffix();
X }
X }
X}
END_OF_FILE
if test 17550 -ne `wc -c <'src/u_init.c'`; then
echo shar: \"'src/u_init.c'\" unpacked with wrong size!
fi
# end of 'src/u_init.c'
fi
echo shar: End of archive 9 \(of 38\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 38 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0