[comp.sources.games] v07i064: NetHack3 - display oriented dungeons & dragons

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