[comp.sources.games.bugs] NetHack 2.3 Update Pt. 12a of 12

mike@genpyr.UUCP (Mike Stephenson) (04/15/88)

	This shar contains all of the files on which "diff" produced a
patch listing larger than the original file.  They are included in full.

	The shell script "Update.sh" will automatically move all of the
files these are intended to replace to a "filename.orig" format name.
Please be careful if you are on a USG system, as some of the filenames are
very long, and Update.sh may actually end up clobbering things.

	MAKE A BACKUP BEFORE YOU DO ANYTHING!!!!!!!!!!

	README BEFORE YOU LEAP!!!!!!

-------------------------------cut here---------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	decl.c.new
#	extern.h.new
#	mkroom.h.new
#	nethack.cnf.new
#	o_init.c.new
#	obj.h.new
#	permonst.h.new
#	rnd.c.new
#	termcap.c.new
#	topten.c.new
# This archive created: Mon Apr  4 08:52:41 1988
export PATH; PATH=/bin:$PATH
echo shar: extracting "'decl.c.new'" '(2357 characters)'
if test -f 'decl.c.new'
then
	echo shar: will not over-write existing file "'decl.c.new'"
else
cat << \SHAR_EOF > 'decl.c.new'
/*	SCCS Id: @(#)decl.c	2.3	87/12/16
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#include	"hack.h"
char nul[40];			/* contains zeros */
char plname[PL_NSIZ];		/* player name */

#ifdef GRAPHICS
struct symbols defsyms = {
    ' ', '|', '-', '-', '-', '-', '-', '+', '.', '#', '<', '>', '^',
# ifdef FOUNTAINS
    '}', '{',
# endif
# ifdef NEWCLASS
    '\\',
# endif
# ifdef SPIDERS
    '"',
# endif
#ifdef SINKS
    '#',
#endif
};

struct symbols showsyms;	/* will contain the symbols actually used */

#endif	/* GRAPHICS /**/

#ifdef DGK
char hackdir[PATHLEN];		/* where rumors, help, record are */
char levels[PATHLEN];		/* where levels are */
char lock[FILENAME];		/* pathname of level files */
char permbones[PATHLEN];	/* where permanent copy of bones go */
int ramdisk = FALSE;		/* whether to copy bones to levels or not */
int saveprompt = TRUE;
char *alllevels = "levels.*";
char *allbones = "bones.*";
char *configfile = "NetHack.cnf";	/* read by read_config_file() */
#else
char lock[PL_NSIZ+4] = "1lock";		/* long enough for login name .99 */
#endif

boolean in_mklev, restoring;
struct rm levl[COLNO][ROWNO];		/* level map */

#ifndef QUEST
#include "mkroom.h"
struct mkroom rooms[MAXNROFROOMS+1];
coord doors[DOORMAX];
#endif

struct monst *fmon = 0;
struct trap *ftrap = 0;
struct gold *fgold = 0;
struct obj *fobj = 0, *fcobj = 0, *invent = 0, *uwep = 0, *uarm = 0,
#ifdef SHIRT
        *uarmu = 0,		/* under-wear, so to speak */
#endif
	*uarm2 = 0, *uarmh = 0, *uarms = 0, *uarmg = 0, *uright = 0,
	*uleft = 0, *uchain = 0, *uball = 0;
struct flag flags;
struct you u;

#ifdef SPELLS
struct spell spl_book[MAXSPELL + 1];
#endif

struct monst youmonst;	/* dummy; used as return value for boomhit */

xchar dlevel = 1;
xchar xupstair, yupstair, xdnstair, ydnstair;
char *save_cm = 0, *killer, *nomovemsg;

long moves = 1;
long wailmsg = 0;
int multi = 0;
char	*occtxt;
#ifdef DGKMOD
int	occtime;
#endif
#ifdef REDO
int	in_doagain = FALSE;
#endif

char *HI, *HE;		/* set up in termcap.c */
#ifdef MSDOSCOLOR
char *HI_MON, *HI_OBJ;	/* set up in termcap.c */
#endif

char genocided[60];
char fut_geno[60];
#ifdef KAA
boolean	stoned;				/* done to monsters hit by 'c' */
boolean	unweapon;
#endif
 
xchar curx,cury;
xchar seelx, seehx, seely, seehy;	/* corners of lit room */

coord bhitpos;

char quitchars[] = " \r\n\033";
SHAR_EOF
if test 2357 -ne "`wc -c < 'decl.c.new'`"
then
	echo shar: error transmitting "'decl.c.new'" '(should have been 2357 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'extern.h.new'" '(1501 characters)'
if test -f 'extern.h.new'
then
	echo shar: will not over-write existing file "'extern.h.new'"
else
cat << \SHAR_EOF > 'extern.h.new'
/*	SCCS Id: @(#)extern.h	2.3	87/12/12
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#include "config.h"

/*
 *	I have been told, that in Sys V R3.1, this has to be commented out.
 */
#ifndef MSDOS
extern char *sprintf();
#endif

extern long *alloc();

extern xchar xdnstair, ydnstair, xupstair, yupstair; /* stairs up and down. */

extern xchar dlevel;

#ifdef SPELLS
#include "spell.h"
extern	struct spell spl_book[];	/* sized in decl.c */
#endif

extern int occtime;
extern char *occtxt;		/* defined when occupation != NULL */

#ifdef REDO
extern int in_doagain;
#endif

extern char *HI, *HE;		/* set up in termcap.c */
#ifdef MSDOSCOLOR
extern char *HI_MON, *HI_OBJ;	/* set up in termcap.c */
#endif

#include "obj.h"
extern struct obj *invent, *uwep, *uarm, *uarm2, *uarmh, *uarms, *uarmg, 
#ifdef SHIRT
	*uarmu, /* under-wear, so to speak */
#endif
	*uleft, *uright, *fcobj;
extern struct obj *uchain;	/* defined iff PUNISHED */
extern struct obj *uball;	/* defined if PUNISHED */
struct obj *o_at(), *getobj(), *sobj_at();

extern char *traps[];
extern char *monnam(), *Monnam(), *amonnam(), *Amonnam(),
	*doname(), *aobjnam();
extern char readchar();
extern char vowels[];

#include "you.h"

extern struct you u;

extern xchar curx,cury;	/* cursor location on screen */

extern xchar seehx,seelx,seehy,seely; /* where to see*/
extern char *save_cm,*killer;

extern xchar dlevel, maxdlevel; /* dungeon level */

extern long moves;

extern int multi;

extern char lock[];
SHAR_EOF
if test 1501 -ne "`wc -c < 'extern.h.new'`"
then
	echo shar: error transmitting "'extern.h.new'" '(should have been 1501 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mkroom.h.new'" '(2085 characters)'
if test -f 'mkroom.h.new'
then
	echo shar: will not over-write existing file "'mkroom.h.new'"
else
cat << \SHAR_EOF > 'mkroom.h.new'
/*	SCCS Id: @(#)mkroom.h	2.3	87/12/12
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

/* mkroom.h - types and structures for room and shop initialization */

struct mkroom {
	schar lx,hx,ly,hy;	/* usually xchar, but hx may be -1 */
	schar rtype,rlit,doorct,fdoor;
};

struct shclass {
	char	*name;	/* name of the shop type */
	char	symb;	/* this identifies the shop type */
    	int	prob;	/* the shop type probability in % */
	schar	dist;	/* artifact placement type */
#define D_SCATTER	0	/* normal placement */
#define D_SHOP		1	/* shop-like placement */
#define D_TEMPLE	2	/* temple-like placement */
	struct itp {
	    int	iprob;	/* probability of an item type */
	    int itype;	/* item type: if >=0 a class, if < 0 a specific item */
	} iprobs[5];
	char **shknms;	/* string list of shopkeeper names for this type */
};
extern struct shclass shtypes[];	/* defined in shknam.c */

#define	MAXNROFROOMS	15
extern struct mkroom rooms[MAXNROFROOMS+1];

#define	DOORMAX	100
extern coord doors[DOORMAX];

/* values for rtype in the room definition structure */
#define OROOM		 0	/* ordinary room */
#define COURT		 2	/* contains a throne */
#define	SWAMP		 3	/* contains pools */
#define	VAULT		 4	/* contains piles of gold */
#define	BEEHIVE		 5	/* contains killer bees and royal jelly */
#define	MORGUE		 6	/* contains corpses, undead and ghosts */
#define BARRACKS	 7	/* contains soldiers and their gear */
#define	ZOO		 8	/* floor covered with treasure and monsters */
#define	SHOPBASE	 9	/* everything above this is a shop */

#define IS_SHOP(x)	((x).rtype >= SHOPBASE)

/* mkshop.c entry points (should become mkroom.c in next major release) */
extern void mkroom();		/* make and stock a room of a given type */
extern boolean nexttodoor();	/* TRUE if adjacent to a door */
extern boolean has_dnstairs();	/* TRUE if given room has a down staircase */
extern boolean has_upstairs();	/* TRUE if given room has an up staircase */
extern int dist2();		/* Euclidean square-of-distance function */
extern struct permonst *courtmon();	/* generate a court monster */
SHAR_EOF
if test 2085 -ne "`wc -c < 'mkroom.h.new'`"
then
	echo shar: error transmitting "'mkroom.h.new'" '(should have been 2085 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'nethack.cnf.new'" '(618 characters)'
if test -f 'nethack.cnf.new'
then
	echo shar: will not over-write existing file "'nethack.cnf.new'"
else
cat << \SHAR_EOF > 'nethack.cnf.new'
#
#	nethack.cnf	for NetHack release 2.3
#
HACKDIR=c:\games\nethack
SAVE=c:\games\nethack\save
LEVELS=c:\games\nethack\save
OPTIONS=male,rawio,IBMBIOS,no rest_on_space,time,packorder:"/!?=)[%(*0
OPTIONS=silent,endgame:10t/0a
# The 9 GRAPHICS characters are:
# vertical wall, horizontal wall, top left corner, top right corner
# bottom left corner, bottom right corner, door, floor, corridor
# An example using the IBM graphics character set.
# from hack.35: GRAPHICS = 186 205 201 187 200 188 206 249 177
# from hack.36: GRAPHICS = 179 196 218 191 192 217 206 250 176
GRAPHICS = 032 186 205 201 187 200 188 206 249 177
SHAR_EOF
if test 618 -ne "`wc -c < 'nethack.cnf.new'`"
then
	echo shar: error transmitting "'nethack.cnf.new'" '(should have been 618 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'o_init.c.new'" '(6079 characters)'
if test -f 'o_init.c.new'
then
	echo shar: will not over-write existing file "'o_init.c.new'"
else
cat << \SHAR_EOF > 'o_init.c.new'
/*	SCCS Id: @(#)o_init.c	2.3	88/01/24
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#include	"config.h"		/* for typedefs */
#include	"objects.h"
#include	"onames.h"		/* for LAST_GEM */
extern char *index();

int
letindex(let) register char let; {
register int i = 0;
register char ch;
	while((ch = obj_symbols[i++]) != 0)
		if(ch == let) return(i);
	return(0);
}

init_objects(){
register int i, j, first, last, sum, end;
register char let, *tmp;

	/* bug fix to prevent "initialization error" abort on Intel Xenix.
	 * reported by mikew@semike
	 */
        for(i = 0; i != sizeof(obj_symbols); i++)
                bases[i] = 0;

	/* init base; if probs given check that they add up to 100, 
	   otherwise compute probs; shuffle descriptions */
	end = SIZE(objects);
	first = 0;
	while( first < end ) {
		let = objects[first].oc_olet;
		last = first+1;
		while(last < end && objects[last].oc_olet == let
				 && objects[last].oc_name != NULL) last++;
		i = letindex(let);
		if((!i && let != ILLOBJ_SYM) || bases[i] != 0)
			error("initialization error");
		bases[i] = first;

		if(let == GEM_SYM) setgemprobs();
	check:
		sum = 0;
		for(j = first; j < last; j++) sum += objects[j].oc_prob;
		if(sum == 0) {
			for(j = first; j < last; j++)
			    objects[j].oc_prob = (100+j-first)/(last-first);
			goto check;
		}
		if(sum != 100)
			error("init-prob error for %c (%d%%)", let, sum);

		if(objects[first].oc_descr != NULL && let != TOOL_SYM){
			/* shuffle, also some additional descriptions */
			while(last < end && objects[last].oc_olet == let)
				last++;
			j = last;
			if (let == GEM_SYM) {
			    while(--j > first)
				/* NOTE:  longest color name must be default */
				if(!strcmp(objects[j].oc_name,"turquoise")) {
				    if(rn2(2)) /* change from green? */
					strcpy(objects[j].oc_descr,"blue");
				} else if (!strcmp(objects[j].oc_name,"aquamarine")) {
				    if(rn2(2)) /* change from green? */
					strcpy(objects[j].oc_descr,"blue");
				} else if (!strcmp(objects[j].oc_name,"fluorite")) {
				    switch (rn2(4)) { /* change from violet? */
					case 0:  break;
					case 1:
					    strcpy(objects[j].oc_descr,"blue");
					    break;
					case 2:
					    strcpy(objects[j].oc_descr,"white");
					    break;
					case 3:
					    strcpy(objects[j].oc_descr,"green");
					    break;
					}
				}
			} else
			    while(--j > first) {
				i = first + rn2(j+1-first);
				tmp = objects[j].oc_descr;
				objects[j].oc_descr = objects[i].oc_descr;
				objects[i].oc_descr = tmp;
			    }
		}
		first = last;
	}
}

probtype(let) register char let; {
register int i = bases[letindex(let)];
register int prob = rn2(100);
	while((prob -= objects[i].oc_prob) >= 0) i++;
	if(objects[i].oc_olet != let || !objects[i].oc_name)
		panic("probtype(%c) error, i=%d", let, i);
	return(i);
}

setgemprobs()
{
	register int j,first;
	extern xchar dlevel;

	first = bases[letindex(GEM_SYM)];

	for(j = 0; j < 9-dlevel/3; j++)
		objects[first+j].oc_prob = 0;
	first += j;
	if(first >= LAST_GEM || first >= SIZE(objects) ||
	    objects[first].oc_olet != GEM_SYM ||
	    objects[first].oc_name == NULL)
		printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
			first, j, LAST_GEM);
	for(j = first; j < LAST_GEM; j++)
		objects[j].oc_prob = (18+j-first)/(LAST_GEM-first);
}

oinit()			/* level dependent initialization */
{
	setgemprobs();
}

extern long *alloc();

savenames(fd) register fd; {
register int i;
unsigned len;
struct objclass *now = &objects[0];
	bwrite(fd, (char *) &now, sizeof now);
	bwrite(fd, (char *) bases, sizeof bases);
	bwrite(fd, (char *) objects, sizeof objects);
	/* as long as we use only one version of Hack/Quest we
	   need not save oc_name and oc_descr, but we must save
	   oc_uname for all objects */
	for(i=0; i < SIZE(objects); i++) {
		if(objects[i].oc_uname) {
			len = strlen(objects[i].oc_uname)+1;
			bwrite(fd, (char *) &len, sizeof len);
			bwrite(fd, objects[i].oc_uname, len);
		}
	}
}

restnames(fd) register fd; {
register int i;
unsigned len;
struct objclass *then;
long differ;
	mread(fd, (char *) &then, sizeof then);
	mread(fd, (char *) bases, sizeof bases);
	mread(fd, (char *) objects, sizeof objects);
#ifndef MSDOS
	differ = (char *)&objects[0] - (char *)then;
#else
	differ = (long)&objects[0] - (long)then;
#endif
	for(i=0; i < SIZE(objects); i++) {
		if (objects[i].oc_name) {
#ifndef MSDOS
			objects[i].oc_name += differ;
#else
			objects[i].oc_name =
			    (char *)((long)(objects[i].oc_name) + differ);
#endif
		}
		if (objects[i].oc_descr) {
#ifndef MSDOS
			objects[i].oc_descr += differ;
#else
			objects[i].oc_descr =
			    (char *)((long)(objects[i].oc_descr) + differ);
#endif
		}
		if (objects[i].oc_uname) {
			mread(fd, (char *) &len, sizeof len);
			objects[i].oc_uname = (char *) alloc(len);
			mread(fd, objects[i].oc_uname, len);
		}
	}
}

dodiscovered()				/* free after Robert Viduya */
{
    extern char *typename();
    register int i, end;
    int	ct = 0;
#ifdef DGKMOD
    char class = -1;
    extern char *let_to_name();
#endif

    cornline(0, "Discoveries");

    end = SIZE(objects);
    for (i = 0; i < end; i++) {
	if (interesting_to_discover (i)) {
	    ct++;
#ifdef DGKMOD
	    if (objects[i].oc_olet != class) {
		class = objects[i].oc_olet;
		cornline(1, let_to_name(class));
	    }
#endif
	    cornline(1, typename(i));
	}
    }
    if (ct == 0) {
	pline ("You haven't discovered anything yet...");
	cornline(3, (char *) 0);
    } else
	cornline(2, (char *) 0);

    return(0);
}

interesting_to_discover(i)
register int i;
{
    return(
	objects[i].oc_uname != NULL ||
	 (objects[i].oc_name_known && objects[i].oc_descr != NULL)
    );
}

init_corpses() {

#ifdef SPIDERS
	strcpy(objects[DEAD_GIANT_SPIDER].oc_name, "dead giant spider");
#endif

#ifdef KOPS
	strcpy(objects[DEAD_KOP].oc_name, "dead Kop");
# endif

#ifdef ROCKMOLE
	strcpy(objects[DEAD_ROCKMOLE].oc_name, "dead rockmole");
#endif

#ifndef KAA
	strcpy(objects[DEAD_QUASIT].oc_name, "dead quasit");
	strcpy(objects[DEAD_VIOLET_FUNGI].oc_name, "dead violet fungi");
#endif
	return(0);
}
SHAR_EOF
if test 6079 -ne "`wc -c < 'o_init.c.new'`"
then
	echo shar: error transmitting "'o_init.c.new'" '(should have been 6079 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'obj.h.new'" '(1800 characters)'
if test -f 'obj.h.new'
then
	echo shar: will not over-write existing file "'obj.h.new'"
else
cat << \SHAR_EOF > 'obj.h.new'
/*	SCCS Id: @(#)obj.h	2.3	88/01/21
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#ifndef OBJ_H
#define OBJ_H

struct obj {
	struct obj *nobj;
	unsigned o_id;
	unsigned o_cnt_id;		/* id of container object is in */
	xchar ox,oy;
	xchar odx,ody;
	unsigned otyp;
#ifdef DGK
	unsigned int	owt;
	unsigned int	quan;
#else
	uchar owt;
	uchar quan;		/* use oextra for tmp gold objects */
#endif
	schar spe;		/* quality of weapon, armor or ring (+ or -)
				   number of charges for wand ( >= -1 )
				   special for uball and amulet %% BAH */
	char olet;
	char invlet;
	Bitfield(oinvis,1);	/* not yet implemented */
	Bitfield(odispl,1);
	Bitfield(known,1);	/* exact nature known */
	Bitfield(dknown,1);	/* color or text known */
	Bitfield(cursed,1);
	Bitfield(unpaid,1);	/* on some bill */
	Bitfield(rustfree,1);
	Bitfield(no_charge, 1);	/* if shk shouldn't charge for this */
	Bitfield(onamelth,6);
	long age;		/* creation date */
	long owornmask;
#define	W_ARM	01L
#define	W_ARM2	02L
#define	W_ARMH	04L
#define	W_ARMS	010L
#define	W_ARMG	020L
#define	W_TOOL	040L	/* wearing a blindfold or badge */
#ifdef SHIRT
#define W_ARMU  0100L
#define W_ARMOR		(W_ARM | W_ARM2 | W_ARMH | W_ARMS | W_ARMG | W_ARMU)
#else
#define	W_ARMOR		(W_ARM | W_ARM2 | W_ARMH | W_ARMS | W_ARMG)
#endif
#define	W_RINGL	010000L	/* make W_RINGL = RING_LEFT (see uprop) */
#define	W_RINGR	020000L
#define	W_RING		(W_RINGL | W_RINGR)
#define	W_WEP	01000L
#define	W_BALL	02000L
#define	W_CHAIN	04000L
	long oextra[1];		/* used for name of ordinary objects - length
				   is flexible; amount for tmp gold objects */
};

extern struct obj *fobj;

#define newobj(xl)	(struct obj *) alloc((unsigned)(xl) + sizeof(struct obj))
#define	ONAME(otmp)	((char *) otmp->oextra)
#define	OGOLD(otmp)	(otmp->oextra[0])

#endif
SHAR_EOF
if test 1800 -ne "`wc -c < 'obj.h.new'`"
then
	echo shar: error transmitting "'obj.h.new'" '(should have been 1800 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'permonst.h.new'" '(1431 characters)'
if test -f 'permonst.h.new'
then
	echo shar: will not over-write existing file "'permonst.h.new'"
else
cat << \SHAR_EOF > 'permonst.h.new'
/*	SCCS Id: @(#)permonst.h	2.3	87/12/16
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

struct permonst {
	char *mname,mlet;
	schar mlevel,mmove,ac,mr,damn,damd;
	unsigned pxlth;
};

extern struct permonst mons[];
#define PM_GNOME	&mons[1]
#define PM_HOBGOBLIN	&mons[2]
#ifndef KOPS
#define PM_KOBOLD	&mons[4]
#endif
#define PM_ACID_BLOB	&mons[7]
#ifdef ROCKMOLE
#define PM_ORC		&mons[10]
#define	PM_ZOMBIE	&mons[12]
#else
#define PM_ORC		&mons[11]
#define	PM_ZOMBIE	&mons[13]
#endif
#define	PM_PIERCER	&mons[17]
#define PM_CENTAUR	&mons[22]
#define	PM_KILLER_BEE	&mons[26]
#ifdef SPIDERS
#define PM_SPIDER	&mons[31]
#endif
#define	PM_WRAITH	&mons[33]
#define	PM_MIMIC	&mons[37]
#define PM_TROLL	&mons[38]
#define	PM_VAMPIRE	&mons[43]
#define PM_XORN		&mons[44]
#define	PM_CHAMELEON	&mons[47]
#define PM_DRAGON	&mons[48]
#define PM_ETTIN	&mons[49]
/* The ones below changed to include giants. */
#define	PM_DEMON	&mons[55]

#define	PM_MINOTAUR	&mons[56]	/* last in mons array */
#define	PM_SHK		&mons[57]	/* very last */

#define	PM_GHOST	&pm_ghost
#define	PM_EEL		&pm_eel
#define	PM_WIZARD	&pm_wizard
#ifdef RPH
#define PM_MEDUSA	&pm_medusa
#endif
#ifdef SAC
#define PM_SOLDIER	&pm_soldier
#endif
#define	CMNUM		56		/* number of common monsters */
#ifdef STOOGES
#define PM_LARRY	&pm_larry
#define PM_CURLY	&pm_curly
#define PM_MOE		&pm_moe
#endif
#define PM_DJINNI	&pm_djinni
#define PM_GREMLIN	&pm_gremlin
SHAR_EOF
if test 1431 -ne "`wc -c < 'permonst.h.new'`"
then
	echo shar: error transmitting "'permonst.h.new'" '(should have been 1431 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rnd.c.new'" '(897 characters)'
if test -f 'rnd.c.new'
then
	echo shar: will not over-write existing file "'rnd.c.new'"
else
cat << \SHAR_EOF > 'rnd.c.new'
/*	SCCS Id: @(#)rnd.c	2.3	87/12/12
 */
#include	"config.h"
/* rand() is either random() or lrand48() - see config.h. */
#ifdef UNIX
#define RND(x)	(rand() % (x))
#else
/* Good luck: the bottom order bits are cyclic. */
#define RND(x)	((rand()>>3) % (x))
#endif

rn1(x,y)	/* y <= rn1(x,y) < (y+x) */ 
register x,y;
{
	return(RND(x)+y);
}

rn2(x)		/* 0 <= rn2(x) < x */
register x;
{
	return(RND(x));
}

rnd(x)		/* 1 <= rnd(x) <= x */
register x;
{
	return(RND(x)+1);
}

d(n,x)		/* n <= d(n,x) <= (n*x) */
register n,x;
{
	register tmp = n;

	while(n--) tmp += RND(x);
	return(tmp);
}

rne(x)          /* by stewr 870807 */
register x;
{
        register tmp = 1;
	while(!rn2(x)) tmp++;
	return(tmp);
}

rnz(i)
int i;
{
	register long x = i;
        register long tmp = 1000;
	tmp += rn2(1000);
	tmp *= rne(4);
	if (rn2(2)) { x *= tmp; x /= 1000; }
	else { x *= 1000; x /= tmp; }
	return((int)x);
}
SHAR_EOF
if test 897 -ne "`wc -c < 'rnd.c.new'`"
then
	echo shar: error transmitting "'rnd.c.new'" '(should have been 897 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'termcap.c.new'" '(8638 characters)'
if test -f 'termcap.c.new'
then
	echo shar: will not over-write existing file "'termcap.c.new'"
else
cat << \SHAR_EOF > 'termcap.c.new'
/*	SCCS Id: @(#)termcap.c	2.3	87/12/12
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#include <stdio.h>
#include <ctype.h>	/* for isdigit() */
#include "hack.h"	/* for ROWNO, COLNO, *HI, *HE */
#ifdef GENIX
#define	void	int	/* jhn - mod to prevent compiler from bombing */
#endif

extern char *tgetstr(), *tgoto(), *getenv();
extern long *alloc();

#ifndef SYSV
# ifndef LINT
extern			/* it is defined in libtermlib (libtermcap) */
# endif
	short ospeed;	/* terminal baudrate; used by tputs */
#else
short	ospeed = 0;	/* gets around "not defined" error message */
#endif

static char tbuf[512];
static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
static char *VS, *VE, *US, *UE;
static int SG;
static char PC = '\0';
char *CD;		/* tested in pri.c: docorner() */
int CO, LI;		/* used in pri.c and whatis.c */

#if defined(MSDOS) && !defined(TERMLIB)
static char tgotobuf[20];
#define tgoto(fmt, x, y)	(sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
#endif /* MSDOS /**/

startup()
{
	register char *term;
	register char *tptr;
	char *tbufptr, *pc;
	register int i;

	tptr = (char *) alloc(1024);

	tbufptr = tbuf;
	if(!(term = getenv("TERM")))
		error("Can't get TERM.");
	if(!strncmp(term, "5620", 4))
		flags.nonull = 1;	/* this should be a termcap flag */
	if(tgetent(tptr, term) < 1)
		error("Unknown terminal type: %s.", term);
	if(pc = tgetstr("pc", &tbufptr))
		PC = *pc;
	if(!(BC = tgetstr("bc", &tbufptr))) {	
		if(!tgetflag("bs"))
			error("Terminal must backspace.");
		BC = tbufptr;
		tbufptr += 2;
		*BC = '\b';
	}
	HO = tgetstr("ho", &tbufptr);
	CO = tgetnum("co");
	LI = tgetnum("li");
	if(CO < COLNO || LI < ROWNO+2)
		setclipped();
	if(!(CL = tgetstr("cl", &tbufptr)))
		error("Hack needs CL.");
	ND = tgetstr("nd", &tbufptr);
	if(tgetflag("os"))
		error("Hack can't have OS.");
	CE = tgetstr("ce", &tbufptr);
	UP = tgetstr("up", &tbufptr);
	/* It seems that xd is no longer supported, and we should use
	   a linefeed instead; unfortunately this requires resetting
	   CRMOD, and many output routines will have to be modified
	   slightly. Let's leave that till the next release. */
	XD = tgetstr("xd", &tbufptr);
/* not: 		XD = tgetstr("do", &tbufptr); */
	if(!(CM = tgetstr("cm", &tbufptr))) {
		if(!UP && !HO)
			error("Hack needs CM or UP or HO.");
		printf("Playing hack on terminals without cm is suspect...\n");
		getret();
	}
	SO = tgetstr("so", &tbufptr);
	SE = tgetstr("se", &tbufptr);
	US = tgetstr("us", &tbufptr);
	UE = tgetstr("ue", &tbufptr);
	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */
	if(!SO || !SE || (SG > 0)) SO = SE = US = UE = "";
	TI = tgetstr("ti", &tbufptr);
	TE = tgetstr("te", &tbufptr);
	VS = VE = "";
#if defined(SORTING) || defined(MSDOSCOLOR)
	/* Get rid of padding numbers for HI and HE.  Hope they
	 * aren't really needed!!!  HI and HE are ouputted to the
	 * pager as a string - so how can you send it NULLS???
	 *  -jsb
	 */
	    HI = (char *) alloc((unsigned)(strlen(SO)+1));
	    HE = (char *) alloc((unsigned)(strlen(SE)+1));
	    i = 0;
	    while(isdigit(SO[i])) i++;
	    strcpy(HI, &SO[i]);
	    i = 0;
	    while(isdigit(SE[i])) i++;
	    strcpy(HE, &SE[i]);
#endif
	CD = tgetstr("cd", &tbufptr);
	set_whole_screen();		/* uses LI and CD */
	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
	free(tptr);
#ifdef MSDOSCOLOR
	init_hilite();
#endif
}

start_screen()
{
	xputs(TI);
	xputs(VS);
#ifdef DGK
	/* Select normal ASCII and line drawing character sets.
	 */
	if (flags.DECRainbow)
		xputs("\033(B\033)0");
#endif
}

end_screen()
{
	clear_screen();
	xputs(VE);
	xputs(TE);
}

/* Cursor movements */
extern xchar curx, cury;

curs(x, y)
register int x, y;	/* not xchar: perhaps xchar is unsigned and
			   curx-x would be unsigned as well */
{

	if (y == cury && x == curx)
		return;
	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */
		cmov(x, y);			/* bunker!wtm */
		return;
	}
	if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
		nocmov(x, y);
	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
		(void) putchar('\r');
		curx = 1;
		nocmov(x, y);
	} else if(!CM) {
		nocmov(x, y);
	} else
		cmov(x, y);
}

nocmov(x, y)
{
	if (cury > y) {
		if(UP) {
			while (cury > y) {	/* Go up. */
				xputs(UP);
				cury--;
			}
		} else if(CM) {
			cmov(x, y);
		} else if(HO) {
			home();
			curs(x, y);
		} /* else impossible("..."); */
	} else if (cury < y) {
		if(XD) {
			while(cury < y) {
				xputs(XD);
				cury++;
			}
		} else if(CM) {
			cmov(x, y);
		} else {
			while(cury < y) {
				xputc('\n');
				curx = 1;
				cury++;
			}
		}
	}
	if (curx < x) {		/* Go to the right. */
		if(!ND) cmov(x, y); else	/* bah */
			/* should instead print what is there already */
		while (curx < x) {
			xputs(ND);
			curx++;
		}
	} else if (curx > x) {
		while (curx > x) {	/* Go to the left. */
			xputs(BC);
			curx--;
		}
	}
}

cmov(x, y)
register x, y;
{
	xputs(tgoto(CM, x-1, y-1));
	cury = y;
	curx = x;
}

xputc(c) char c; {
	(void) fputc(c, stdout);
}

xputs(s) char *s; {
#if defined(MSDOS) && !defined(TERMLIB)
	fputs(s, stdout);
#else
	tputs(s, 1, xputc);
#endif
}

cl_end() {
	if(CE)
		xputs(CE);
	else {	/* no-CE fix - free after Harold Rynes */
		/* this looks terrible, especially on a slow terminal
		   but is better than nothing */
		register cx = curx, cy = cury;

		while(curx < COLNO) {
			xputc(' ');
			curx++;
		}
		curs(cx, cy);
	}
}

clear_screen() {
	xputs(CL);
	home();
}

home()
{
	if(HO)
		xputs(HO);
	else if(CM)
		xputs(tgoto(CM, 0, 0));
	else
		curs(1, 1);	/* using UP ... */
	curx = cury = 1;
}

standoutbeg()
{
	if(SO) xputs(SO);
}

standoutend()
{
	if(SE) xputs(SE);
}

backsp()
{
	xputs(BC);
	curx--;
}

bell()
{
#ifdef DGKMOD
	if (flags.silent) return;
#endif /* DGKMOD /**/
	(void) putchar('\007');		/* curx does not change */
	(void) fflush(stdout);
}

static short tmspc10[] = {		/* from termcap */
	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
};

delay_output() {
	/* delay 50 ms - could also use a 'nap'-system call */
	/* BUG: if the padding character is visible, as it is on the 5620
	   then this looks terrible. */
#ifdef MSDOS
	/* simulate the delay with "cursor here" */
	register i;
	for (i = 0; i < 3; i++) {
		cmov(curx, cury);
		(void) fflush(stdout);
	}
#else /* MSDOS /**/
	if(!flags.nonull)
#ifdef TERMINFO
		tputs("$<50>", 1, xputs);
#else
		tputs("50", 1, xputs);
#endif
		/* cbosgd!cbcephus!pds for SYS V R2 */
		/* is this terminfo, or what? */
		/* tputs("$<50>", 1, xputc); */

	else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
		/* delay by sending cm(here) an appropriate number of times */
		register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
		register int i = 500 + tmspc10[ospeed]/2;

		while(i > 0) {
			cmov(curx, cury);
			i -= cmlen*tmspc10[ospeed];
		}
	}
#endif /* MSDOS /**/
}

cl_eos()			/* free after Robert Viduya */
{				/* must only be called with curx = 1 */

	if(CD)
		xputs(CD);
	else {
		register int cx = curx, cy = cury;
		while(cury <= LI-2) {
			cl_end();
			xputc('\n');
			curx = 1;
			cury++;
		}
		cl_end();
		curs(cx, cy);
	}
}

#ifdef MSDOSCOLOR
/* Sets up highlighting, using ANSI escape sequences, for monsters and 
 * objects (highlight code found in pri.c). 
 * The termcap entry for HI (from SO) is scanned to find the background 
 * color. If everything is o.k., monsters are displayed in the color 
 * used to define HILITE_MONSTER and objects are displayed in the color 
 * used to define HILITE_OBJECT. */

#define ESC		0x1b
#define NONE		0
#define HIGH_INTENSITY	1
#define BLACK		0
#define RED		1
#define GREEN		2
#define YELLOW		3
#define BLUE		4
#define MAGENTA		5
#define CYAN		6
#define WHITE		7

#define HILITE_ATTRIB	NONE
#define HILITE_MONSTER	RED
#define HILITE_OBJECT	YELLOW

init_hilite()
{
	register int backg, len, mfore, ofore;

	backg = BLACK;
	mfore = ofore = WHITE;
	/* find the background color, HI[len] == 'm' */
	len = strlen(HI) - 1;
	if (len > 3) 
	if (isdigit(HI[len-1]) && 
	    isdigit(HI[len-2]) && HI[len-2] != 3) {
			backg = HI[len-1] - '0';
			mfore = HILITE_MONSTER;
			ofore = HILITE_OBJECT;
	}
	if (mfore == backg || ofore == backg) {
		if (len < 7) mfore = ofore = WHITE;
		else {
			if (HI[2] == '3') mfore = ofore = HI[3] - '0';
			else if (HI[4] == '3') mfore = ofore = HI[5] - '0';
			else mfore = ofore = WHITE; /* give up! */
		}
	}

	HI_MON = (char *) alloc(sizeof("E[0;33;44;54m"));
	sprintf(HI_MON, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 
	        mfore, backg);
	HI_OBJ = (char *) alloc(sizeof("E[0;33;44;54m"));
	sprintf(HI_OBJ, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 
	        ofore, backg);
}

#endif
SHAR_EOF
if test 8638 -ne "`wc -c < 'termcap.c.new'`"
then
	echo shar: error transmitting "'termcap.c.new'" '(should have been 8638 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'topten.c.new'" '(12536 characters)'
if test -f 'topten.c.new'
then
	echo shar: will not over-write existing file "'topten.c.new'"
else
cat << \SHAR_EOF > 'topten.c.new'
/*	SCCS Id: @(#)topten.c	2.3	88/02/01
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#include <stdio.h>
#include "hack.h"
#ifdef GENIX
#define	void	int	/* jhn - mod to prevent compiler from bombing */
#endif

#define	Sprintf	(void) sprintf
extern char plname[], pl_character[];
#ifndef MSC		/* set by the Microsoft "C" compiler */
extern	char	*itoa();
#endif
extern	char	*ordin(), *eos();
extern int done_hup, done_stopprint;

#define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry))
#define	NAMSZ	10
#define	DTHSZ	60
#define	PERSMAX	 3		/* entries per name/uid per char. allowed */
#define	POINTSMIN	1	/* must be > 0 */
#define	ENTRYMAX	100	/* must be >= 10 */
#ifndef MSDOS
#define	PERS_IS_UID		/* delete for PERSMAX per name; now per uid */
#endif
struct toptenentry {
	struct toptenentry *tt_next;
	long int points;
	int level,maxlvl,hp,maxhp;
	int uid;
	char plchar;
	char sex;
	char name[NAMSZ+1];
	char death[DTHSZ+1];
	char date[7];		/* yymmdd */
} *tt_head;

topten(){
	int uid = getuid();
	int rank, rank0 = -1, rank1 = 0;
	int occ_cnt = PERSMAX;
	register struct toptenentry *t0, *t1, *tprev;
	char *recfile = RECORD;
#ifdef UNIX
	char *reclock = "record_lock";
#endif
	int sleepct = 300;
	FILE *rfile;
	register flg = 0;
	extern char *getdate();
#ifdef LOGFILE
	char *lgfile = LOGFILE;
	FILE *lfile;
	char *loglock = "logfile_lock";
	int sleeplgct = 30;
#endif

#ifndef DGK
#define	HUP	if(!done_hup)
#else
#define HUP
#endif

#ifdef UNIX
	while(link(recfile, reclock) == -1) {
		HUP perror(reclock);
		if(!sleepct--) {
			HUP puts("I give up. Sorry.");
			HUP puts("Perhaps there is an old record_lock around?");
			return;
		}
		HUP printf("Waiting for access to record file. (%d)\n",
			sleepct);
		HUP (void) fflush(stdout);
		sleep(1);
	}
#endif
	if(!(rfile = fopen(recfile,"r"))){
		HUP puts("Cannot open record file!");
		goto unlock;
	}
	HUP (void) putchar('\n');

	/* create a new 'topten' entry */
	t0 = newttentry();
	t0->level = dlevel;
	t0->maxlvl = maxdlevel;
	t0->hp = u.uhp;
	t0->maxhp = u.uhpmax;
	t0->points = u.urexp;
	t0->plchar = pl_character[0];
	t0->sex = (flags.female ? 'F' : 'M');
	t0->uid = uid;
	(void) strncpy(t0->name, plname, NAMSZ);
	(t0->name)[NAMSZ] = 0;
	(void) strncpy(t0->death, killer, DTHSZ);
	(t0->death)[DTHSZ] = 0;
	(void) strcpy(t0->date, getdate());

	/* assure minimum number of points */
	if(t0->points < POINTSMIN)
		t0->points = 0;
#ifdef LOGFILE		/* used for debugging (who dies of what, where) */
	while(link(lgfile, loglock) == -1) {
		HUP perror(loglock);
		if(!sleeplgct--) {
			HUP puts("I give up. Sorry.");
			HUP puts("Perhaps there is an old logfile_lock around?");
			goto lgend;
		}
		HUP printf("Waiting for access to log file. (%d)\n",
 			sleeplgct);
		HUP (void) fflush(stdout);
		sleep(1);
	}
	if(!(lfile = fopen(lgfile,"a"))){
		HUP puts("Cannot open log file!");
		goto lgend;
	}
	fprintf(lfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n",
	    t0->date, t0->uid,
	    t0->level, t0->maxlvl,
	    t0->hp, t0->maxhp, t0->points,
	    t0->plchar, t0->sex, t0->name, t0->death);
	fclose(lfile);
	(void) unlink(loglock);
      lgend:;	
#endif

	t1 = tt_head = newttentry();
	tprev = 0;
	/* rank0: -1 undefined, 0 not_on_list, n n_th on list */
	for(rank = 1; ; ) {
	  if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
		t1->date, &t1->uid,
		&t1->level, &t1->maxlvl,
		&t1->hp, &t1->maxhp, &t1->points,
		&t1->plchar, &t1->sex, t1->name, t1->death) != 11
	  || t1->points < POINTSMIN)
			t1->points = 0;
	  if(rank0 < 0 && t1->points < t0->points) {
		rank0 = rank++;
		if(tprev == 0)
			tt_head = t0;
		else
			tprev->tt_next = t0;
		t0->tt_next = t1;
		occ_cnt--;
		flg++;		/* ask for a rewrite */
	  } else
		tprev = t1;
	  if(t1->points == 0) break;
	  if(
#ifdef PERS_IS_UID
	     t1->uid == t0->uid &&
#else
	     strncmp(t1->name, t0->name, NAMSZ) == 0 &&
#endif
	     t1->plchar == t0->plchar && --occ_cnt <= 0){
		if(rank0 < 0){
			rank0 = 0;
			rank1 = rank;
	HUP printf("You didn't beat your previous score of %ld points.\n\n",
				t1->points);
		}
		if(occ_cnt < 0){
			flg++;
			continue;
		}
	  }
	  if(rank <= ENTRYMAX){
		t1 = t1->tt_next = newttentry();
		rank++;
	  }
	  if(rank > ENTRYMAX){
		t1->points = 0;
		break;
	  }
	}
	if(flg) {	/* rewrite record file */
		(void) fclose(rfile);
		if(!(rfile = fopen(recfile,"w"))){
			HUP puts("Cannot write record file\n");
			goto unlock;
		}

		if(!done_stopprint) if(rank0 > 0){
		    if(rank0 <= 10)
			puts("You made the top ten list!\n");
		    else
		printf("You reached the %d%s place on the top %d list.\n\n",
			rank0, ordin(rank0), ENTRYMAX);
		}
	}
	if(rank0 == 0) rank0 = rank1;
	if(rank0 <= 0) rank0 = rank;
	if(!done_stopprint) outheader();
	t1 = tt_head;
	for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
	  if(flg) fprintf(rfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n",
	    t1->date, t1->uid,
	    t1->level, t1->maxlvl,
	    t1->hp, t1->maxhp, t1->points,
	    t1->plchar, t1->sex, t1->name, t1->death);
	  if(done_stopprint) continue;
	  if(rank > flags.end_top &&
	    (rank < rank0-flags.end_around || rank > rank0+flags.end_around)
	    && (!flags.end_own ||
#ifdef PERS_IS_UID
				  t1->uid != t0->uid
#else
				  strncmp(t1->name, t0->name, NAMSZ)
#endif
		)) continue;
	  if(rank == rank0-flags.end_around &&
	     rank0 > flags.end_top+flags.end_around+1 &&
	     !flags.end_own)
		(void) putchar('\n');
	  if(rank != rank0)
		(void) outentry(rank, t1, 0);
	  else if(!rank1)
		(void) outentry(rank, t1, 1);
	  else {
		int t0lth = outentry(0, t0, -1);
		int t1lth = outentry(rank, t1, t0lth);
		if(t1lth > t0lth) t0lth = t1lth;
		(void) outentry(0, t0, t0lth);
	  }
	}
	if(rank0 >= rank) if(!done_stopprint)
		(void) outentry(0, t0, 1);
	(void) fclose(rfile);
unlock:	;
#ifdef UNIX
	(void) unlink(reclock);
#endif
}

outheader() {
char linebuf[BUFSZ];
register char *bp;
#ifdef KJSMODS
	(void) strcpy(linebuf, " No  Points    Name");
#else
	(void) strcpy(linebuf, "Number Points  Name");
#endif
	bp = eos(linebuf);
	while(bp < linebuf + COLNO - 9) *bp++ = ' ';
	(void) strcpy(bp, "Hp [max]");
	puts(linebuf);
}

/* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */
int
outentry(rank,t1,so) register struct toptenentry *t1; {
boolean quit = FALSE, killed = FALSE, starv = FALSE;
char linebuf[BUFSZ];
	linebuf[0] = 0;
	if(rank) Sprintf(eos(linebuf), "%3d", rank);
		else Sprintf(eos(linebuf), "   ");
#ifdef KJSMODS
	Sprintf(eos(linebuf), " %7ld %10s", t1->points, t1->name);
#else
# ifdef DGKMOD
	Sprintf(eos(linebuf), " %6ld %10s", t1->points, t1->name);
# else
	Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name);
# endif
#endif
	if(t1->plchar == 'X') Sprintf(eos(linebuf), " ");
	else Sprintf(eos(linebuf), "-%c ", t1->plchar);
	if(!strncmp("escaped", t1->death, 7)) {
	  if(!strcmp(" (with amulet)", t1->death+7))
	    Sprintf(eos(linebuf), "escaped the dungeon with amulet");
	  else
	    Sprintf(eos(linebuf), "escaped the dungeon [max level %d]",
	      t1->maxlvl);
	} else {
	  if(!strncmp(t1->death,"quit",4)) {
	    quit = TRUE;
#ifndef KJSMODS
	    if(t1->maxhp < 3*t1->hp && t1->maxlvl < 4)
		Sprintf(eos(linebuf), "cravenly gave up");
	    else
#endif
		Sprintf(eos(linebuf), "quit");
	  }
	  else if(!strcmp(t1->death,"choked"))
	    Sprintf(eos(linebuf), "choked on %s food",
		(t1->sex == 'F') ? "her" : "his");
	  else if(!strncmp(t1->death,"starv",5))
	    Sprintf(eos(linebuf), "starved to death"), starv = TRUE;
	  else Sprintf(eos(linebuf), ", killed"), killed = TRUE;
	  Sprintf(eos(linebuf), " on%s level %d",
	    (killed || starv) ? "" : " dungeon", t1->level);
	  if(t1->maxlvl != t1->level)
	    Sprintf(eos(linebuf), " [max %d]", t1->maxlvl);
	  if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4);
	}
	if(killed) Sprintf(eos(linebuf), " by %s%s",
	  (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4))
		? "" :
	  index(vowels,*t1->death) ? "an " : "a ",
	  t1->death);
	Sprintf(eos(linebuf), ".");
	if(t1->maxhp) {
	  register char *bp = eos(linebuf);
	  char hpbuf[10];
	  int hppos;
#ifdef KJSMODS
	  int lngr = strlen(linebuf);
#endif
	  Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-");
	  hppos = COLNO - 7 - strlen(hpbuf);
#ifdef KJSMODS
	  if (lngr >= hppos) hppos = (2*COLNO) - 7 - strlen(hpbuf);
#endif
	  if(bp <= linebuf + hppos) {
	    /* pad any necessary blanks to the hit point entry */
	    while(bp < linebuf + hppos) *bp++ = ' ';
	    (void) strcpy(bp, hpbuf);
	    Sprintf(eos(bp), " [%d]", t1->maxhp);
	  }
	}
	if(so == 0) puts(linebuf);
	else if(so > 0) {
	  register char *bp = eos(linebuf);
	  if(so >= COLNO) so = COLNO-1;
	  while(bp < linebuf + so) *bp++ = ' ';
	  *bp = 0;
	  standoutbeg();
	  fputs(linebuf,stdout);
	  standoutend();
	  (void) putchar('\n');
	}
	return(strlen(linebuf));
}

char *
itoa(a) int a; {
static char buf[12];
	Sprintf(buf,"%d",a);
	return(buf);
}

char *
ordin(n) int n; {
register int d = n%10;
	return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" :
		(d==2) ? "nd" : "rd");
}

char *
eos(s)
register char *s;
{
	while(*s) s++;
	return(s);
}

/*
 * Called with args from main if argc >= 0. In this case, list scores as
 * requested. Otherwise, find scores for the current player (and list them
 * if argc == -1).
 */
prscore(argc,argv) int argc; char **argv; {
	extern char *hname;
	char **players;
	int playerct;
	int rank;
	register struct toptenentry *t1, *t2;
	char *recfile = RECORD;
	FILE *rfile;
	register flg = 0;
	register int i;
#ifdef nonsense
	long total_score = 0L;
	char totchars[10];
	int totcharct = 0;
#endif
	int outflg = (argc >= -1);
#ifdef PERS_IS_UID
	int uid = -1;
#else
	char *player0;
#endif

	if(!(rfile = fopen(recfile,"r"))){
		puts("Cannot open record file!");
		return;
	}

	if(argc > 1 && !strncmp(argv[1], "-s", 2)){
		if(!argv[1][2]){
			argc--;
			argv++;
		} else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) {
			argv[1]++;
			argv[1][0] = '-';
		} else	argv[1] += 2;
	}
	if(argc <= 1){
#ifdef PERS_IS_UID
		uid = getuid();
		playerct = 0;
#else
		player0 = plname;
		if(!*player0)
			player0 = "hackplayer";
		playerct = 1;
		players = &player0;
#endif
	} else {
		playerct = --argc;
		players = ++argv;
	}
	if(outflg) putchar('\n');

	t1 = tt_head = newttentry();
	for(rank = 1; ; rank++) {
	  if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
		t1->date, &t1->uid,
		&t1->level, &t1->maxlvl,
		&t1->hp, &t1->maxhp, &t1->points,
		&t1->plchar, &t1->sex, t1->name, t1->death) != 11)
			t1->points = 0;
	  if(t1->points == 0) break;
#ifdef PERS_IS_UID
	  if(!playerct && t1->uid == uid)
		flg++;
	  else
#endif
	  for(i = 0; i < playerct; i++){
		if(strcmp(players[i], "all") == 0 ||
		   strncmp(t1->name, players[i], NAMSZ) == 0 ||
		  (players[i][0] == '-' &&
		   players[i][1] == t1->plchar &&
		   players[i][2] == 0) ||
		  (digit(players[i][0]) && rank <= atoi(players[i])))
			flg++;
	  }
	  t1 = t1->tt_next = newttentry();
	}
	(void) fclose(rfile);
	if(!flg) {
	    if(outflg) {
		printf("Cannot find any entries for ");
		if(playerct < 1) printf("you.\n");
		else {
		  if(playerct > 1) printf("any of ");
		  for(i=0; i<playerct; i++)
			printf("%s%s", players[i], (i<playerct-1)?", ":".\n");
		  printf("Call is: %s -s [playernames]\n", hname);
		}
	    }
	    return;
	}

	if(outflg) outheader();
	t1 = tt_head;
	for(rank = 1; t1->points != 0; rank++, t1 = t2) {
		t2 = t1->tt_next;
#ifdef PERS_IS_UID
		if(!playerct && t1->uid == uid)
			goto outwithit;
		else
#endif
		for(i = 0; i < playerct; i++){
			if(strcmp(players[i], "all") == 0 ||
			   strncmp(t1->name, players[i], NAMSZ) == 0 ||
			  (players[i][0] == '-' &&
			   players[i][1] == t1->plchar &&
			   players[i][2] == 0) ||
			  (digit(players[i][0]) && rank <= atoi(players[i]))){
			outwithit:
				if(outflg)
				    (void) outentry(rank, t1, 0);
#ifdef nonsense
				total_score += t1->points;
				if(totcharct < sizeof(totchars)-1)
				    totchars[totcharct++] = t1->plchar;
#endif
				break;
			}
		}
		free((char *) t1);
	}
#ifdef nonsense
	totchars[totcharct] = 0;

	/* We would like to determine whether he is experienced. However,
	   the information collected here only tells about the scores/roles
	   that got into the topten (top 100?). We should maintain a
	   .hacklog or something in his home directory. */
	flags.beginner = (total_score < 6000);
	for(i=0; i<6; i++)
	    if(!index(totchars, "CFKSTWX"[i])) {
		flags.beginner = 1;
		if(!pl_character[0]) pl_character[0] = "CFKSTWX"[i];
		break;
	}
#endif /* nonsense /**/
}
SHAR_EOF
if test 12536 -ne "`wc -c < 'topten.c.new'`"
then
	echo shar: error transmitting "'topten.c.new'" '(should have been 12536 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
						Mike Stephenson

Mail:	Genamation Inc.		Phone:	(416) 475-9434
	351 Steelcase Rd. W
	Markham, Ontario.	UUCP:	uunet!{mnetor,utzoo}!genat!genpyr!mike
	Canada   L3R 3W1		uunet!{mnetor,utzoo}!genat!mike