[net.sources.games] PC/IX Hack repost Part 3

peterb@pbear.UUCP (06/03/85)

#!/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:
#	hack.h
#	hack.invent.c
#	hack.invinit.c
#	hack.io.c
#	hack.lev.c
#	hack.main.c
#	hack.mkobj.c
#	hack.mon.c
#	hack.mon.do.c
# This archive created: Mon Jun  3 10:38:52 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'hack.h'" '(6911 characters)'
if test -f 'hack.h'
then
	echo shar: over-writing existing file "'hack.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.h'
X/*
X * Hack.h
X */
X
X/* #define NORMAL_IO    */
X#ifdef NORMAL_IO
X
X#include <stdio.h>
X#define flush()		fflush( stdout )
X
X#else
X
X#undef putchar
X#undef getchar
X#define NULL	0
X#define STDOUT  0		/* Defines print in I/O packet */
X
X#endif NORMAL_IO
X
X#include "envir.h"
X#include "hack.name.h"
Xchar *strchr();
X#define index(s,c) strchr(s,c)
X
Xlong    pow ();
X
X#define BUFSZ   256
X
X
X/* Arguments for panic to give just an error message or a core dump */
X#define NOCORE	0
X#define CORE	1
X
X#define ON      1
X#define OFF     0
X
X#define WALL    1
X#define SDOOR   2
X#define DOOR    3
X#define CORR    4
X#define ROOM    5
X#define POOL    7
X#define VAULT   9
X
X#define TRAPNUM 9
X
X#define MSLOW   1
X#define MFAST   2
X
X#define BEAR    0
X#define ARROW   1
X#define DART    2
X#define TDOOR   3
X#define TELE    4
X#define PIT     5
X#define SLPTRP  6
X#define PIERC   7
X#define MIMIC   8
X#define SEEN    32
X
X#define UWEP	0
X#define UARM    1
X#define UARM2   2
X#define ULEFT   3
X#define URIGHT  4
X
X#define POTN    1
X#define SCRN    2
X#define WANN    4
X#define RINN    8
X
X#define UNC     1		/* unCoff(): */
X#define COFF    0
X
X#define SETC    1		/* setCon(): */
X#define CON     0
X
X#define IT1     1
X#define THEIT2  2		/* kluns */
X
X#define CHOKED  0
X#define DIED    1
X#define STARVED 2
X#define DROWNED 3
X#define QUIT    4		/* Michiel args how you died */
X#define ESCAPED 5
X
X#define NOMOVE  0
X#define MOVE    1
X#define DEAD    2
X
X#define MISS    0
X#define HIT     1
X#define KILL    2
X
X
X
Xtypedef struct func_tab {
X	char    f_char;
X	int     (*f_funct) ();
X} FUNCTIONS;
Xextern  FUNCTIONS list[];
X
X
X
Xstruct rm {
X	unsigned        scrsym;
X	unsigned        typ;
X	unsigned        new:	1;
X	unsigned        seen:	1;
X	unsigned        lit:	1;
X};
Xtypedef struct rm       PART;
Xextern  PART levl[80][22];
X
X
X
X
Xstruct mkroom {
X	char    lx, hx, ly, hy, rtype, rlit, doorct, fdoor;
X};
Xtypedef struct mkroom   MKROOM;
Xextern  MKROOM rooms[15];
X
X
X
X#define DOORMAX 100
Xstruct coord {
X	char    x, y;
X};
Xtypedef struct coord    COORDINATES;
Xextern  COORDINATES doors[DOORMAX];
X
X
X
Xstruct food {
X	char   *foodnam, prob, delay;
X	int     nutrition;
X};
Xtypedef struct food    *FOOD;
Xextern struct food      foods[];
X
X
X
Xstruct armor {
X	char   *armnam, prob, delay, a_ac, a_can;
X};
Xtypedef struct armor   *ARMOR;
Xextern struct armor     armors[];
X
X
X
X
X
Xstruct weapon {
X	char   *wepnam, prob, wsdam, wldam;
X};
Xtypedef struct weapon  *WEAPON;
Xextern struct weapon    weapons[];
X
X
X
X
Xstruct permonst {
X	char   *mname, mlet, mhd, mmove, ac, damn, damd;
X	unsigned        pxlth;
X};
Xtypedef struct permonst *MONSTDATA;
Xextern struct permonst  mon[8][7];
X#define PM_MIMIC        &mon[5][2]
X#define PM_PIERC        &mon[2][3]
X#define PM_DEMON        &mon[7][6]
X#define PM_CHAM         &mon[6][6]
X
X
X
X
Xstruct obj {
X	struct obj     *nobj;
X	char    otyp;
X	int     spe;
X	unsigned        ox:	7;
X	unsigned        oy:	5;
X	unsigned        olet:	7;
X	unsigned        quan:	5;
X	unsigned        known:	1;
X	unsigned        cursed: 1;
X	unsigned        unpaid:	1;
X};
Xtypedef struct obj     *OBJECT;
Xextern  OBJECT fobj, invent, uwep, uarm, uarm2, uleft, uright;
X
X
X
Xstruct stole {
X	OBJECT sobj;
X	unsigned        sgold;
X};
Xtypedef struct stole   *STOLE;
X
X
Xstruct monst {
X	struct monst   *nmon;
X	MONSTDATA	data;
X	STOLE		mstole;
X	char    mx, my;
X	int     mhp, orig_hp;
X	unsigned        invis:	1;
X	unsigned        cham:	1;
X	unsigned        angry:	1;	/* Michiel: only for shopkeeper */
X	unsigned        ale:	1;	/* Michiel: is it an ale?? */
X	unsigned        mspeed:	2;
X	unsigned        msleep: 1;
X	unsigned        mfroz:	1;
X	unsigned        mconf:	1;
X	unsigned        mflee:	1;
X	unsigned        mcan:	1;
X	unsigned        mtame:	1;
X	unsigned        wormno: 5;
X	unsigned        mxlth;
X	char    mextra[1];
X};
Xtypedef struct monst   *MONSTER;
Xextern  MONSTER fmon, shopkeeper, vaultkeeper;
Xextern struct permonst  treasurer;
X
XMONSTER m_at ();
X
X
X
Xstruct wseg {
X	struct wseg    *nseg;
X	char    wx, wy;
X};
X
Xtypedef struct wseg    *WORMSEGMENT;
X
X#define newseg()        (alloc( sizeof(struct wseg) )->Wseg)
X
X
Xstruct gen {
X	struct gen     *ngen;
X	char    	gx, gy;
X	unsigned        gflag;
X};
Xtypedef struct gen     *GOLD_TRAP;
Xextern  GOLD_TRAP fgold, ftrap;
X
XGOLD_TRAP g_at ();
XOBJECT o_at (), getobj ();
X
X
Xstruct flag {
X	unsigned        topl:		1;
X	unsigned        botl:		1;
X /* faint:1, screen:1, */
X	unsigned        oneline:	1;
X	unsigned        next:		1;
X	unsigned        move:		1;
X	unsigned        mv:		1;
X	unsigned        run:		2;
X	unsigned        dgold:		1;
X	unsigned        dhp:		1;
X	unsigned        dhpmax:		1;
X	unsigned        dstr:		1;
X	unsigned        dac:		1;
X	unsigned        dulev:		1;
X	unsigned        dexp:		1;
X	unsigned        dhs:		1;
X	unsigned        dscr:		1;
X};
Xtypedef struct flag     FLAG;
Xextern  FLAG flags;
X
Xstruct you {
X	char    ux, uy, ustr, ustrmax, udaminc, uac;
X	int     uhunger;
X	unsigned        ufast:		7;
X	unsigned        uconfused:	6;
X	unsigned        uinvis:		6;
X	unsigned        ulevel:		5;
X	unsigned        utrap:		3;
X	unsigned        upit:		1;
X	unsigned        uinshop:	1;
X	unsigned        uinzoo:		1;
X	unsigned        uinyard:	1;
X	unsigned        uinswamp:	1;
X	unsigned        uinknox:	1;
X	unsigned        umconf:		1;
X	unsigned        uhcursed:	1;
X	unsigned        ufireres:	1;
X	unsigned        ucoldres:	1;
X	unsigned        utel:		1;
X	unsigned        upres:		1;
X	unsigned        ustelth:	1;
X	unsigned        uagmon:		1;
X	unsigned        ufeed:		1;
X	unsigned        usearch:	1;
X	unsigned        ucinvis:	1;
X	unsigned        uregen:		1;
X	unsigned        ufloat:		1;
X	unsigned        uswallow:	1;
X	unsigned        uswldtim:	4;
X	unsigned        ucham:		1;
X	unsigned        uhs:		2;
X	unsigned        ublind;
X	short   uhp, uhpmax;
X	long    ugold, uexp, urexp;
X	MONSTER ustuck;
X};
Xtypedef struct you      YOU;
Xextern  YOU u;
X
X
X
Xextern char    *wepnam[], *pottyp[], *scrtyp[], *traps[],
X               *wantyp[], *ringtyp[], *potcol[], *scrnam[],
X               *wannam[], *rinnam[], wdam[], oiden[],
X               *potcall[], *scrcall[], *wandcall[], *ringcall[],
X                curx, cury, savx,
X                xdnstair, ydnstair, xupstair, yupstair,
X                seehx, seelx, seehy, seely,
X               *save_cm, *killer, dlevel, maxdlevel,
X                dx, dy, buf[], lock[],
X                genocided[60], oldux, olduy, wizard;
X
Xextern unsigned moves;
X
Xextern  multi;
X
X#define newmonst(xl)    (alloc( xl + sizeof(struct monst) )->Mtmp )
X#define newobj()        (alloc( sizeof(struct obj) )->Otmp )
X#define newgen()        (alloc( sizeof(struct gen) )->Gtmp )
X#define newstole()      (alloc( sizeof(struct stole) )->Stmp )
X
X
X#define CHAR_NULL	(char *)NULL
X#define OBJ_NULL	(struct obj *)NULL
X#define TRAP_NULL	(struct gen *)NULL
X#define MON_NULL	(struct monst *)NULL
X#define STOLE_NULL	(struct stole *)NULL
X
X#ifndef SHOW
Xunion PTRS {
X	GOLD_TRAP Gtmp;
X	MONSTER Mtmp;
X	OBJECT Otmp;
X	STOLE Stmp;
X	WORMSEGMENT Wseg;
X	char   *Val;
X};
X
Xextern  union PTRS * alloc ();
X#endif SHOW
SHAR_EOF
if test 6911 -ne "`wc -c 'hack.h'`"
then
	echo shar: error transmitting "'hack.h'" '(should have been 6911 characters)'
fi
echo shar: extracting "'hack.invent.c'" '(5532 characters)'
if test -f 'hack.invent.c'
then
	echo shar: over-writing existing file "'hack.invent.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.invent.c'
X/*
X * Hack.invent.c
X */
X
X#include	"hack.h"
X
X#define NOT_AT	0
X#define NO_OBJ	0
X
Xextern  WORMSEGMENT wsegs[32];
X
Xextern  OBJECT yourinvent0;
X
XOBJECT addinv (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X		if (otmp -> otyp == obj -> otyp && otmp -> olet == obj -> olet
X				&& !obj -> unpaid && !otmp -> unpaid &&
X				((obj -> otyp < F_COOKIE &&
X						obj -> olet == ')' &&
X						obj -> quan + otmp -> quan < 32 &&
X						obj -> spe == otmp -> spe) ||
X					index ("%?!*", otmp -> olet))) {
X			otmp -> quan += obj -> quan;
X			ofree (obj);
X			return otmp;
X		}
X		if (!otmp -> nobj) {
X			otmp -> nobj = obj;
X			obj -> nobj = 0;
X			return obj;
X		}
X	}
X	invent = obj;
X	obj -> nobj = 0;
X	return obj;
X}
X
Xuseup (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	if (obj -> quan > 1) {
X		obj -> quan--;
X		return;
X	}
X	if (obj == invent)
X		invent = invent -> nobj;
X	else {
X		for (otmp = invent; otmp -> nobj != obj;
X				otmp = otmp -> nobj);
X		otmp -> nobj = obj -> nobj;
X	}
X	if (!onbill (obj))
X		ofree (obj);
X}
X
Xdelobj (obj)
Xregister        OBJECT obj;
X{
X	freeobj (obj);
X	ofree (obj);
X}
X
Xofree (obj)
Xregister        OBJECT obj;
X{
X	if (obj > yourinvent0)
X		free (obj);
X}
X
X/*  Unlink obj from chain starting with fobj  */
X
Xfreeobj (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	if (obj == fobj)
X		fobj = fobj -> nobj;
X	else {
X		for (otmp = fobj; otmp -> nobj != obj; otmp = otmp -> nobj)
X			if (!otmp)
X				panic (CORE, "Try to free non-existing object");
X		otmp -> nobj = obj -> nobj;
X	}
X}
X
Xdeltrap (trap)
Xregister        GOLD_TRAP trap;
X{
X	register        GOLD_TRAP gtmp;
X
X	if (trap == ftrap)
X		ftrap = ftrap -> ngen;
X	else {
X		for (gtmp = ftrap; gtmp -> ngen != trap;
X				gtmp = gtmp -> ngen);
X		gtmp -> ngen = trap -> ngen;
X	}
X	free (trap);
X}
X
XMONSTER m_at (x, y)
Xregister        x, y;
X{
X	register        MONSTER mtmp;
X	register        WORMSEGMENT wtmp;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) {
X		if (mtmp -> mx == x && mtmp -> my == y)
X			return (mtmp);
X		if (mtmp -> wormno)
X			for (wtmp = wsegs[mtmp -> wormno]; wtmp;
X					wtmp = wtmp -> nseg)
X				if (wtmp -> wx == x && wtmp -> wy == y)
X					return (mtmp);
X	}
X	return (NOT_AT);
X}
X
XOBJECT o_at (x, y)
Xregister        x, y;
X{
X	register        OBJECT otmp;
X
X	for (otmp = fobj; otmp; otmp = otmp -> nobj)
X		if (otmp -> ox == x && otmp -> oy == y)
X			return (otmp);
X	return (NOT_AT);
X}
X
XGOLD_TRAP g_at (x, y, ptr)
Xregister        x, y;
Xregister        GOLD_TRAP ptr;
X{
X	while (ptr) {
X		if (ptr -> gx == x && ptr -> gy == y)
X			return (ptr);
X		ptr = ptr -> ngen;
X	}
X	return (NOT_AT);
X}
X
XOBJECT getobj (let, word)
Xregister char  *let, *word;
X{
X	register        OBJECT otmp;
X	register char   ilet, ilet1, ilet2;
X	char    buffer[BUFSZ], allowall = 0;
X	register        foo = 0, foo2;
X
X	if (*let == '#') {
X		let++;
X		allowall++;
X	}
X	ilet = 'a';
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X		if (!let || index (let, otmp -> olet))
X			buffer[foo++] = ilet;
X		if (ilet == 'z')
X			ilet = 'A';
X		else
X			ilet++;
X	}
X	buffer[foo] = 0;
X	if (foo > 5) {		/* Compactify string */
X		foo = foo2 = 1;
X		ilet2 = buffer[0];
X		ilet1 = buffer[1];
X		while (ilet = buffer[++foo2] = buffer[++foo]) {
X			if (ilet == ilet1 + 1) {
X				if (ilet1 == ilet2 + 1)
X					buffer[foo2 - 1] = ilet1 = '-';
X				else if (ilet2 == '-') {
X					buffer[--foo2] = ++ilet1;
X					continue;
X				}
X			}
X			ilet2 = ilet1;
X			ilet1 = ilet;
X		}
X	}
X	if (!foo && !allowall) {
X		pline ("You don't have anything to %s.", word);
X		return (NO_OBJ);
X	}
X	for (;;) {
X		pline ((foo) ? "What do you want to %s [%s or ?]? " :
X				"What do you want to %s? ", word, buffer);
X		flags.topl = 0;
X		flush ();
X		ilet = getchar ();
X		if (ilet == '\33' || ilet == ' ' || ilet == '\n')
X			if (strcmp (word, "identify"))
X				return (NO_OBJ);
X			else
X				continue;/* sukkel */
X		if (ilet == '?')
X			doinv (foo ? let : 0, 0);
X		else {
X			if (ilet >= 'A' && ilet <= 'Z')
X				ilet += 26 - 'A';
X			else
X				ilet -= 'a';
X			for (otmp = invent; otmp && ilet; ilet--,
X					otmp = otmp -> nobj);
X			if (!otmp) {
X				pline ("You don't have that object.");
X				continue;
X			}
X			break;
X		}
X	}
X	if (!allowall && let && !index (let, otmp -> olet)) {
X		pline ("That is a silly thing to %s.", word);
X		return (NO_OBJ);
X	}
X	return (otmp);
X}
X
Xprinv (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X	register char   ilet = 'a';
X
X	for (otmp = invent; otmp != obj; otmp = otmp -> nobj)
X		if (++ilet > 'z')
X			ilet = 'A';
X	prname (obj, ilet, 1);
X}
X
Xprname (obj, let, onelin)
Xregister        OBJECT obj;
Xregister char   let;
X{
X	char    li[BUFSZ];
X
X	doname (obj, buf);
X	sprintf (li, "%c - %s.", let, buf);
X	if (onelin)
X		pline (li);
X	else
X		printf ("%s\n", li);
X}
X
Xddoinv () {
X	nomove ();
X	if (!invent)
X		pline ("You are empty handed.");
X	else
X		doinv (0, 1);
X}
X
X/*
X * Page inventory done by Fred
X *
X */
X
Xdoinv (str, opt)
Xregister char  *str;
Xint     opt;
X{
X	register        OBJECT otmp;
X	register char   ilet = 'a';
X	register int    count = 1;
X	int     ct = 0;
X
X	if (!flags.oneline)
X		for (otmp = invent; otmp; otmp = otmp -> nobj)
X			if (!str || index (str, otmp -> olet))
X				ct++;
X	if (ct > 1)
X		cls ();
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X		if (!str || index (str, otmp -> olet)) {
X			prname (otmp, ilet, ct <= 1);
X			count++;
X		}
X		if (++ilet > 'z')
X			ilet = 'A';
X		if (!(count % 22) && otmp -> nobj) {
X			getret ();
X			cls ();	/* M. F. Page listing */
X		}
X	}
X	if (!str && opt)
X		doinvbill ();
X	if (ct > 1) {
X		getret ();
X		docrt ();
X	}
X}
SHAR_EOF
if test 5532 -ne "`wc -c 'hack.invent.c'`"
then
	echo shar: error transmitting "'hack.invent.c'" '(should have been 5532 characters)'
fi
echo shar: extracting "'hack.invinit.c'" '(649 characters)'
if test -f 'hack.invinit.c'
then
	echo shar: over-writing existing file "'hack.invinit.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.invinit.c'
X/*
X * Hack.invinit.c
X */
X
X#include "hack.h"
X
X/*
X * struct obj {
X *     struct obj *nobj;
X *     char otyp, spe;
X *     ox, oy, olet, quan, known, cursed, unpaid
X * };
X */
X
Xstruct obj arrows0 = {
X	(struct obj *)0,
X	W_ARROW, 0, 0, 0, ')', 25, 1, 0, 0	/* 25 +0 arrows */
X};
X
Xstruct obj bow0 = {
X	&arrows0,
X 	W_BOW, 1, 0, 0, ')', 1, 1, 0, 0		/* +1 bow */
X};
X
Xstruct obj mace0 = {
X	&bow0,
X 	W_MACE, 1, 0, 0, ')', 1, 1, 0, 0	/* +1 mace */
X};
X
Xstruct obj uarm0 = {
X	&mace0,
X 	A_RING, 4, 0, 0, '[', 1, 1, 0, 0	/* +1 ring mail */
X};
X
Xstruct obj food0 = {
X	&uarm0,
X 	F_FOOD, 0, 0, 0, '%', 2, 1, 0, 0	/* 2 food rations */
X};
X
Xstruct obj *yourinvent0 = &food0;
SHAR_EOF
if test 649 -ne "`wc -c 'hack.invinit.c'`"
then
	echo shar: error transmitting "'hack.invinit.c'" '(should have been 649 characters)'
fi
echo shar: extracting "'hack.io.c'" '(1559 characters)'
if test -f 'hack.io.c'
then
	echo shar: over-writing existing file "'hack.io.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.io.c'
X/*
X * Hack.io.c
X */
X
X#include "hack.h"
X#include <termio.h>
X
Xshort   ospeed;			/* Used by tputs */
X
Xgetlin (str)
Xregister char  *str;
X{
X	register char  *ostr = str;
X
X	flags.topl = 0;
X	flush ();
X	for (;;) {
X		*str = getchar ();
X		if (*str == '\b') {
X			if (str != ostr) {
X				str--;
X				write (1, "\b \b", 3);
X			}
X			else
X				write (1, "\7", 1);
X		}
X		else if (*str == '\n') {
X			*str = 0;
X			return;
X		}
X		else if (*str >= ' ') {
X			write (1, str, 1);
X			str++;
X		}
X	}
X}
X
Xgetret () {
X	printf ("\nHit space to continue: ");
X	flush ();
X	while (getchar () != ' ');
X}
X
Xstruct termio ttyo;
Xh_io_init() {
X	ioctl(1, TCGETA, &ttyo);
X}
X
X
X/*
X * Put together cbreak-mode and echo --- Michiel
X */
X
X	int speed_table[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600,
X			     1200, 1800, 2400, 4800, 9600, 0, 0 };
X
Xhackmode (x)
Xregister        x;
X{
X	struct termio   ttyp;
X
X	ioctl (1, TCGETA, &ttyp);/* Use of basic functions */
X	ospeed = ttyp.c_cflag & 017; /* mask out other bits */
X	ospeed = speed_table[ospeed];
X	if (x) {
X		ttyp.c_lflag &= ~ (ECHO | ICANON);
X		ttyp.c_cc[4]=0;
X		ttyp.c_cc[5]=0; /* set min and time to 0 */
X	}
X	else {
X		ttyp.c_lflag = ttyo.c_lflag;  /* reset back to original */
X		ttyp.c_cc[4]=ttyo.c_cc[4];      /* set EOF */
X		ttyp.c_cc[5]=ttyo.c_cc[5];      /* set EOL */
X	}
X	if (ioctl (1, TCSETA, &ttyp) < 0) {
X		printf ("ERROR: Cannot change tty");
X		exit (1);
X	}
X}
X
Xmore () {
X	printf (" --More--");
X	flush ();
X	while (getchar () != ' ');
X	flags.topl = 0;
X}
X
X#ifndef NORMAL_IO
Xgetchar () {
X	char    c;
X
X	read (0, &c, 1);
X	return (c);
X}
X#endif NORMAL_IO
SHAR_EOF
if test 1559 -ne "`wc -c 'hack.io.c'`"
then
	echo shar: error transmitting "'hack.io.c'" '(should have been 1559 characters)'
fi
echo shar: extracting "'hack.lev.c'" '(4721 characters)'
if test -f 'hack.lev.c'
then
	echo shar: over-writing existing file "'hack.lev.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.lev.c'
X/*
X * Hack.lev.c
X */
X
X#include "hack.h"
X#include <signal.h>
X
X#define MAXLEVEL	40
X#define ERROR		 1
X#define OK		 0
X
Xextern char    *itoa (), nul[], upxstairs[MAXLEVEL], upystairs[MAXLEVEL];
X
Xextern  WORMSEGMENT wsegs[32], wheads[32];
Xextern unsigned wgrowtime[32];
Xextern struct permonst  pm_ghost;
X
X#include "hack.savelev.c"
X
Xstruct permonst pm_ale = {
X	"giant eel", ';', 15, 6, -3, 3, 6, 0
X};
X
Xgetlev (fd) {
X	register        MONSTER mtmp;
X	register        GOLD_TRAP gtmp;
X	register        OBJECT otmp;
X	register        WORMSEGMENT wtmp;
X	int     tmp, xl;
X	unsigned        tmoves, omoves;
X	STOLE stmp;
X
X	if (fd < 0 || read (fd, levl, sizeof (levl)) != sizeof (levl))
X		return ERROR;
X	fmon = 0;
X	fobj = 0;
X	fgold = 0;
X	ftrap = 0;
X	shopkeeper = 0;
X	vaultkeeper = 0;
X	mread (fd, &omoves, sizeof (unsigned));
X	mread (fd, &xupstair, 1);
X	mread (fd, &yupstair, 1);
X	mread (fd, &xdnstair, 1);
X	mread (fd, &ydnstair, 1);
X	if (omoves)
X		tmoves = (moves > omoves) ? moves - omoves : 0;
X	for (;;) {
X		mread (fd, &xl, sizeof (int));
X		if (xl == -1)
X			break;
X		mtmp = newmonst (xl);
X		mread (fd, mtmp, xl + sizeof (struct monst));
X
X/* Michiel restore stolen objects */
X		stmp = newstole ();
X		mread (fd, stmp, sizeof (struct stole));
X		if (stmp -> sgold || stmp -> sobj) {
X			mtmp -> mstole = stmp;
X			mtmp -> mstole -> sobj = 0;
X			for (;;) {
X				otmp = newobj ();
X				mread (fd, otmp, sizeof (struct obj));
X				if (!otmp -> olet)
X					break;
X				otmp -> nobj = mtmp -> mstole -> sobj;
X				mtmp -> mstole -> sobj = otmp;
X			}
X			ofree (otmp);
X		}
X		else
X			free (stmp);
X/* Regenerate animals if you've been on another level */
X		if (omoves) {
X			if (!index (genocided, mtmp -> data -> mlet)) {
X				if (index ("ViT", mtmp -> data -> mlet))
X					mtmp -> mhp += mtmp -> mhp + tmoves;
X				else
X					mtmp -> mhp += tmoves / 20;
X				if (mtmp -> mhp > mtmp -> orig_hp)
X					mtmp -> mhp = mtmp -> orig_hp;
X				if (mtmp -> data -> mlet == '@') {
X					if (*mtmp -> data -> mname == 's')
X						shopkeeper = mtmp;
X					else if (*mtmp -> data -> mname == 'v')
X						vaultkeeper = mtmp;
X				}
X				mtmp -> nmon = fmon;
X				fmon = mtmp;
X			}
X		}
X		else {		/* Convert code from MKLEV */
X			if (mtmp -> mhp == 10)
X				mtmp -> data = &pm_ghost;
X			else if (mtmp -> ale)
X				mtmp -> data = &pm_ale;
X			else
X				mtmp -> data = &mon[mtmp -> mhp][mtmp -> orig_hp];
X			if (mtmp -> data -> mlet == 'D')
X				mtmp -> mhp = 80;
X			else
X				mtmp -> mhp = mtmp -> data -> mhd ?
X					d (mtmp -> data -> mhd, 8) : rnd (4);
X			mtmp -> orig_hp = mtmp -> mhp;
X			mtmp -> cham = (mtmp -> data -> mlet == ':');
X			mtmp -> invis = (mtmp -> data -> mlet == 'I');
X			if (mtmp -> data -> mlet == 'w' &&
X					getwn (mtmp))
X				initworm (mtmp);
X			mtmp -> nmon = fmon;
X			fmon = mtmp;
X		}
X	}
X	for (;;) {
X		gtmp = newgen ();
X		mread (fd, gtmp, sizeof (struct gen));
X		if (!gtmp -> gx)
X			break;
X		gtmp -> ngen = fgold;
X		fgold = gtmp;
X	}
X	for (;;) {
X		mread (fd, gtmp, sizeof (struct gen));
X		if (!gtmp -> gx)
X			break;
X		gtmp -> ngen = ftrap;
X		ftrap = gtmp;
X		gtmp = newgen ();
X	}
X	free (gtmp);
X	for (;;) {
X		otmp = newobj ();
X		mread (fd, otmp, sizeof (struct obj));
X		if (!otmp -> olet)
X			break;
X		otmp -> nobj = fobj;
X		fobj = otmp;
X	}
X	ofree (otmp);
X	mread (fd, rooms, sizeof (rooms));
X	mread (fd, doors, sizeof (doors));
X	if (!omoves)
X		return OK;	/* From MKLEV */
X	mread (fd, wsegs, sizeof (wsegs));
X	for (tmp = 1; tmp < 32; tmp++)
X		if (wsegs[tmp]) {
X			wheads[tmp] = wsegs[tmp] = wtmp = newseg ();
X			for (;;) {
X				mread (fd, wtmp, sizeof (struct wseg));
X				if (!wtmp -> nseg)
X					break;
X				wheads[tmp] -> nseg = wtmp = newseg ();
X				wheads[tmp] = wtmp;
X			}
X		}
X	mread (fd, wgrowtime, sizeof (wgrowtime));
X	return OK;
X}
X
Xmread (fd, buffer, len)
Xregister        fd, len;
Xregister char  *buffer;
X{
X	register        rlen;
X
X	if ((rlen = read (fd, buffer, len)) != len)
X		panic (CORE, "Read %d instead of %d bytes from file #%d\n",
X				rlen, len, fd);
X}
X
Xmklev () {
X	register        fd;
X	char    type[2];
X
X#ifndef DEBUG
X	if (getbones ()) {
X		sleep (2);
X		goto Z;
X	}
X#endif DEBUG
X	if (flags.next) {
X		flags.next = 0;
X		type[0] = 'b';
X	}
X	else if (dlevel < rn1 (3, MAXLEVEL - 3))
X		type[0] = 'a';
X	else {
X		type[0] = 'n';
X		flags.next = 1;
X	}
X	type[1] = '\0';
X	hackexec (0, "./mklev", lock, type, itoa (dlevel), genocided,
X			wizard ? "w" : "", NULL);
X	if ((fd = open (lock, 0)) < 0) {
X		pline ("Can't open %s! Second try.", lock);
X		flush ();
X		hackexec (0, "./mklev", lock, type, itoa (dlevel), genocided,
X				wizard ? "w" : "", NULL);
X		if ((fd = open (lock, 0)) < 0)
X			panic (NOCORE, "Mklev error no level");
X	}
X	getlev (fd);
X	close (fd);
XZ: 
X	if (!upxstairs[dlevel] && !upystairs[dlevel]) {
X		upxstairs[dlevel] = xupstair;
X		upystairs[dlevel] = yupstair;
X	}
X}
SHAR_EOF
if test 4721 -ne "`wc -c 'hack.lev.c'`"
then
	echo shar: error transmitting "'hack.lev.c'" '(should have been 4721 characters)'
fi
echo shar: extracting "'hack.main.c'" '(5622 characters)'
if test -f 'hack.main.c'
then
	echo shar: over-writing existing file "'hack.main.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.main.c'
X/*
X * Hack.main.c
X */
X
X#include <signal.h>
X#include "hack.h"
X
X#define exception( id )	( id == uid )
X#define HUISJES	2201
X#define WILDE	2216
X
Xextern char    *hu_stat[4], *getenv (), *malloc (), *parse ();
X
Xint     rfile;
X
XCOORDINATES doors[DOORMAX];
X
XPART levl[80][22];
XMKROOM rooms[15];
XMONSTER fmon = 0;
XGOLD_TRAP fgold = 0, ftrap = 0;
XFLAG flags;
XYOU u;
XOBJECT fobj = 0, invent, uwep, uarm,
Xuarm2 = 0, uright = 0, uleft = 0;
X
Xextern  OBJECT yourinvent0;
Xextern struct obj       mace0, uarm0;
X
Xchar    nul[20];		/* Contains zeros */
X/* Lock contains 'pid'.dlevel */
Xchar    plname[10], lock[16], wizard,
X        curx, cury, savx,
X        xupstair, yupstair, xdnstair, ydnstair,
X       *save_cm = 0, *killer, *nomvmsg, dlevel = 0,
X        dx, dy, buf[BUFSZ], genocided[60],
X        SAVEFILE[37] = SAVEDIR;
X
Xunsigned        moves = 1;
X
Xint     multi = 0, done1 (), hangup (), hackpid;
Xint     uid;
X
Xmain (argc, argv)
Xchar   *argv[];
X{
X	int     fd;
X	char *getlogin();
X	register char  *yourname = getlogin ();
X
X	uid = getuid ();
X	/*
X	 * Check on UID's
X	 */
X
X/*        if (kantoor () && !exception (HUISJES) && !exception (WILDE)) {
X		printf ("Sorry, You can't play hack now\n" );
X		flush ();
X		exit (0);
X	}       */
X
X	if (!access (LOCK, 0) && strcmp (WIZARD, yourname)) {
X		printf ("Sorry, I'm busy with debugging.\nTry again later.\n");
X		flush ();
X		exit (0);
X	}
X	h_io_init();    /* grab copy of termio struct */
X	strncpy (plname, yourname, sizeof (plname) - 1);
X#ifdef WIZARD
X	while (argc > 1 && **++argv == '-') {
X		switch (argv[0][1]) {
X			case 'w': 
X				if (!exception (HUISJES) && !exception (WILDE) && strcmp (yourname, WIZARD))
X					printf ("Sorry\n");
X				else {
X					strcpy (plname, "wizard");
X					wizard++;
X				}
X				break;
X			default: 
X				printf ("Unknown option: %s\n", *argv);
X		}
X		flush ();
X	}
X#endif WIZARD
X
X	if (chdir (PLAYGROUND) < 0)
X		panic (NOCORE, "Cannot chdir to %s!", PLAYGROUND);
X	if ((rfile = open (RECORD, 2)) < 0)
X		panic (NOCORE, "Can't open %s!", RECORD);
X	setuid (getuid ());
X	umask (0);
X	srand (hackpid = getpid ());
X	startup ();
X	signal (SIGHUP, hangup);
X	signal (SIGINT, done1);
X	hackmode (ON);
X	if (!wizard) {
X		cls ();
X		flush ();
X	}
X	strcat (SAVEFILE, plname);
X	fd = open (SAVEFILE, 0);
X	if (fd >= 0) {
X		if (dorecover (fd) < 0)
X			goto normalplay;
X		flags.move = 0;
X	}
X	else {
Xnormalplay: 
X		shuffle ();
X		invent = yourinvent0;
X		uwep = &mace0;
X		uarm = &uarm0;
X		u.uac = 6;	/* 10 - uarm->spe */
X		u.ulevel = 1;
X		u.uhunger = 900;
X		u.uhpmax = u.uhp = 12;
X		u.ustrmax = u.ustr = rn2 (20) ? 16 : rn1 (7, 14);
X		flags.move = 1;
X		dodown ();	/* a3 */
X		cls ();
X		setCon (SETC);
X		flags.botl = 1;
X		makedog ();
X	}
X	for (;;) {
X		if (flags.move) {
X			if (!u.ufast || moves % 2 == 0) {
X				if (fmon)
X					movemon ();
X				if (!rn2 (70)) {
X					makemon (0);
X					fmon -> mx = 0;
X					fmon -> my = 0;
X					rloc (fmon);
X					seeatl (fmon -> mx, fmon -> my,
X							fmon -> data -> mlet);
X				}
X			}
X			if (u.ufast && !--u.ufast)
X				pline ("You feel yourself slowing down");
X			if (u.uconfused && !--u.uconfused)
X				pline ("You feel less confused now");
X			if (u.ublind && !--u.ublind) {
X				pline ("You can see again");
X				if (!u.uswallow)
X					setCon (SETC);
X			}
X			if (u.uinvis && !--u.uinvis) {
X				if (!u.uswallow)
X					on (u.ux, u.uy);
X				pline ("You are no longer invisible");
X			}
X			++moves;
X			if (u.uhp <= 0) {
X				pline ("You die...");
X				more ();
X				done (DIED);
X			}
X			if (u.uhp < u.uhpmax) {
X				if (u.ulevel > 9) {
X					if (u.uregen || moves % 3 == 0) {
X						flags.dhp = 1;
X						u.uhp +=
X							rnd (u.ulevel - 9);
X						if (u.uhp > u.uhpmax)
X							u.uhp = u.uhpmax;
X					}
X				}
X				else if (u.uregen || moves %
X						(22 - (u.ulevel << 1)) == 0) {
X					flags.dhp = 1;
X					u.uhp++;
X				}
X			}
X			if (u.utel && !rn2 (85))
X				tele ();
X			if (u.usearch)
X				dosearch ();
X			gethungry ();
X		}
X		flags.move = 1;
X		if (flags.dscr && !flags.mv)
X			nscr ();
X		if (flags.botl)
X			bot ();
X		else if (flags.dgold) {
X			flags.dgold = 0;
X			curs (16, 24);
X			curx = 21;
X			printf ("%-5u", u.ugold);
X		}
X		if (flags.dhp) {
X			flags.dhp = 0;
X			curs (26, 24);
X			curx = 29;
X			printf ("%3d", u.uhp);
X		}
X		if (flags.dhpmax) {
X			flags.dhpmax = 0;
X			curs (30, 24);
X			printf ("%d)", u.uhpmax);
X			if (u.uhpmax < 100)
X				putchar (' ');
X			curx = (u.uhpmax < 10) ? 33 : 34;
X		}
X		if (flags.dac) {
X			flags.dac = 0;
X			curs (37, 24);
X			printf ("%-3d", u.uac);
X			curx = 40;
X		}
X		if (flags.dstr) {
X			flags.dstr = 0;
X			curs (46, 24);
X			prustr ();
X			curx = 51;
X		}
X		if (flags.dulev) {
X			flags.dulev = 0;
X			curs (57, 24);
X			printf ("%2d", u.ulevel);
X			curx = 59;
X		}
X		if (flags.dexp) {
X			flags.dexp = 0;
X			curs (60, 24);
X			if (u.ulevel < 14)
X				printf ("%-5lu", u.uexp);
X			else
X				printf ("MAX++");
X			curx = 65;
X		}
X		if (flags.dhs) {
X			flags.dhs = 0;
X			curs (71, 24);
X			printf (hu_stat[u.uhs]);
X			curx = 79;
X		}
X		if (multi < 0) {
X			if (!++multi) {
X				pline (nomvmsg ? nomvmsg :
X						"You can move again.");
X				nomvmsg = 0;
X			}
X		}
X		else {
X			if (multi) {
X				lookaround ();
X				if (!multi) {
X					flags.move = 0;
X					continue;
X				}
X				if (flags.mv) {
X					if (multi < 80 && !--multi) {
X						flags.mv = 0;
X						flags.run = 0;
X					}
X					domove ();
X				}
X				else {
X					--multi;
X					rhack (save_cm);
X				}
X			}
X			else
X				rhack (parse ());
X		}
X	}
X}
X
Xglo (n)
Xregister        n;		/* Construct the string `hackpid.n' */
X{
X/*
X	register char *tf = lock;
X
X	while( *tf && *tf != '.' )
X		tf++;
X	*tf++ = '.';
X	sprintf( tf, "%d", n );
X*/
X	sprintf (lock, "%d.%d", hackpid, n);
X}
X
Ximpossible () {
X	pline ("Program in disorder - perhaps you'd better Quit");
X}
X
SHAR_EOF
if test 5622 -ne "`wc -c 'hack.main.c'`"
then
	echo shar: error transmitting "'hack.main.c'" '(should have been 5622 characters)'
fi
echo shar: extracting "'hack.mkobj.c'" '(4439 characters)'
if test -f 'hack.mkobj.c'
then
	echo shar: over-writing existing file "'hack.mkobj.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.mkobj.c'
X/*
X * Hack.mkobj.c
X */
X
X#include "hack.h"
X#include "hack.vars.h"
X
Xmkfood () {
X	register        FOOD fp;
X	register        i = rn2 (100);
X
X	fp = &foods[0];
X	while ((i -= fp -> prob) >= 0)
X		fp++;
X	return (fp - foods);
X}
X
Xmkarm () {
X	register        ARMOR ap;
X	register        i = rn2 (100);
X
X	ap = &armors[0];
X	while ((i -= ap -> prob) >= 0)
X		ap++;
X	return (ap - armors);
X}
X
Xmkwep () {
X	register        WEAPON wp;
X	register        i = rn2 (100);
X
X	wp = &weapons[0];
X	while ((i -= wp -> prob) >= 0)
X		wp++;
X	return (wp - weapons);
X}
X
Xchar    mkobjstr[] = "))[[!!!!????%%%%//=**";
X
Xmkobj (let)
Xregister        let;
X{
X	register        OBJECT otmp;
X
X	otmp = newobj ();
X	otmp -> nobj = fobj;
X	fobj = otmp;
X	otmp -> known = 0;
X	otmp -> cursed = 0;
X	otmp -> spe = 0;
X	otmp -> unpaid = 0;
X	otmp -> quan = 1;
X	if (!let)
X		let = mkobjstr[rn2 (sizeof (mkobjstr) - 1)];
X	otmp -> olet = let;
X	switch (let) {
X
X		case ')': 
X			otmp -> otyp = mkwep ();
X			if (otmp -> otyp <= W_AMMUNITION)
X				otmp -> quan = rn1 (6, 6);
X			if (!rn2 (11))
X				otmp -> spe = rnd (3);
X			else if (!rn2 (10)) {
X				otmp -> cursed = 1;
X				otmp -> spe = -rnd (3);
X			}
X			break;
X
X		case '*': 
X			otmp -> otyp = rn2 (SIZE (potcol));
X			otmp -> quan = rn2 (6) ? 1 : 2;
X			break;
X
X		case '[': 
X			otmp -> otyp = mkarm ();
X			if (!rn2 (8))
X				otmp -> cursed = 1;
X			if (!rn2 (10))
X				otmp -> spe = rnd (3);
X			else if (!rn2 (9)) {
X				otmp -> spe = -rnd (3);
X				otmp -> cursed = 1;
X			}
X			otmp -> spe += 10 - armors[otmp -> otyp].a_ac;
X			break;
X
X		case '!': 
X			otmp -> otyp = rn2 (SIZE (pottyp));
X			break;
X
X		case '?': 
X			otmp -> otyp = rn2 (SIZE (scrtyp));
X			break;
X
X		case '%': 
X			otmp -> otyp = mkfood ();
X			otmp -> quan = rn2 (6) ? 1 : 2;
X			break;
X
X		case '/': 
X			otmp -> otyp = rn2 (SIZE (wantyp));
X			if (otmp -> otyp == Z_DEATH)
X				otmp -> otyp = rn2 (SIZE (wantyp));
X			otmp -> spe = rn1 (5, (otmp -> otyp <= Z_CREATE_MON) ?
X					11 : 4);
X		/* detection and light and create monster */
X			break;
X
X		case '=': 
X			otmp -> otyp = rn2 (SIZE (ringtyp));
X			if (otmp -> otyp >= R_GAIN_STR) {
X				if (!rn2 (3)) {
X					otmp -> spe = -rnd (2);
X					otmp -> cursed = 1;
X					break;
X				}
X				else
X					otmp -> spe = rnd (2);
X			}
X			else if (otmp -> otyp == R_TELE ||
X						otmp -> otyp == R_AGGRAV_MON ||
X					otmp -> otyp == R_HUNGER)
X				otmp -> cursed = 1;
X			break;
X
X		default: 
X			panic (CORE, "Impossible mkobj");
X	}
X}
X
Xshufl (base, num)
Xregister char  *base[];
Xregister        num;
X{
X	char  **tmp, *tmp1;
X	int     curnum;
X
X	for (curnum = num - 1; curnum > 0; curnum--) {
X		tmp = &base[rn2 (curnum)];
X		tmp1 = *tmp;
X		*tmp = base[curnum];
X		base[curnum] = tmp1;
X	}
X}
X
Xshuffle () {
X	shufl (wannam, SIZE (wantyp));
X	shufl (potcol, SIZE (potcol));
X	shufl (rinnam, SIZE (ringtyp));
X	shufl (scrnam, SIZE (scrtyp));
X}
X
Xsavenames (fd)
Xregister        fd;
X{
X	bwrite (fd, oiden, sizeof oiden);
X	bwrite (fd, potcol, sizeof potcol);
X	bwrite (fd, scrnam, sizeof scrnam);
X	bwrite (fd, wannam, sizeof wannam);
X	bwrite (fd, rinnam, sizeof rinnam);
X}
X
Xrestnames (fd)
Xregister        fd;
X{
X	mread (fd, oiden, sizeof oiden);
X	mread (fd, potcol, sizeof potcol);
X	mread (fd, scrnam, sizeof scrnam);
X	mread (fd, wannam, sizeof wannam);
X	mread (fd, rinnam, sizeof rinnam);
X}
X
X/* Restore the names we have given to things */
Xcallsrestore (fd)
Xregister        fd;
X{
X	restcalls (fd, potcall, SIZE (pottyp));
X	restcalls (fd, wandcall, SIZE (wantyp));
X	restcalls (fd, ringcall, SIZE (ringtyp));
X	restcalls (fd, scrcall, SIZE (scrtyp));
X}
X
X/* Save things we have given names to */
Xcallssave (fd)
Xregister        fd;
X{
X	savecalls (fd, potcall, SIZE (pottyp));
X	savecalls (fd, wandcall, SIZE (wantyp));
X	savecalls (fd, ringcall, SIZE (ringtyp));
X	savecalls (fd, scrcall, SIZE (scrtyp));
X}
X
Xsavecalls (fd, strings, max)
Xchar   *strings[];
Xregister int    max, fd;
X{
X	register        teller;
X
X	for (teller = 0; teller < max; ++teller) {
X		if (strings[teller])
X			bwrite (fd, strings[teller],
X					strlen (strings[teller]) + 1);
X		else
X			bwrite (fd, "\0", 1);
X	}
X}
X
Xrestcalls (fd, strings, max)
Xregister int    fd, max;
Xchar   *strings[];
X{
X	register        teller;
X	char   *str;
X	int     cnt;
X	char    buffer[BUFSZ];
X
X	str = NULL;
X	for (teller = 0; teller < max; ++teller) {
X		cnt = -1;
X		do {
X			++cnt;
X			mread (fd, str, 1);
X			buffer[cnt] = *str;
X		} while (*str != '\0');
X		if (cnt) {
X			strings[teller] = alloc (strlen (buffer) + 1) -> Val;
X			strcpy (strings[teller], buffer);
X		}
X	}
X}
SHAR_EOF
if test 4439 -ne "`wc -c 'hack.mkobj.c'`"
then
	echo shar: error transmitting "'hack.mkobj.c'" '(should have been 4439 characters)'
fi
echo shar: extracting "'hack.mon.c'" '(10311 characters)'
if test -f 'hack.mon.c'
then
	echo shar: over-writing existing file "'hack.mon.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.mon.c'
X/*
X * Hack.mon.c
X */
X
X/* Contains various monster routines */
X
X#include "hack.h"
X
Xextern char     WCLEV[], STOPGLOW[];
X
Xdist (x, y)
Xregister        x, y;
X{
X	x -= u.ux;
X	y -= u.uy;
X	return (x * x + y * y);
X}
X
Xr_free (x, y, mtmp)
Xregister        x, y;
Xregister        MONSTER mtmp;
X{
X	if (mtmp -> ale)
X		return (levl[x][y].typ == POOL);
X	else
X		return (levl[x][y].typ > SDOOR &&
X				(x != u.ux || y != u.uy) && levl[x][y].typ < POOL);
X /* DOOR,CORR,ROOM */
X}
X
X
X/* Puts m next to u, or anywhere if there isn't room there */
Xmnexto (mtmp)
XMONSTER mtmp;
X{
X	register        x, y, z;
X	struct {
X		char    zx, zy;
X	}       foo[15], *tfoo;
X	int     range;
X
X	tfoo = foo;
X	range = 1;
X	do {			/* Full kludge action */
X		for (y = 0; y < 2; y++)
X			for (x = u.ux - range; x <= u.ux + range; x++) {
X				z = range;
X				if (!y)
X					z = -z;
X				if (test (x, z += u.uy)) {
X					tfoo -> zx = x;
X					tfoo++ -> zy = z;
X					if (tfoo == &foo[15])
X						goto foofull;
X				}
X			}
X		for (x = 0; x < 2; x++)
X			for (y = u.uy + 1 - range; y < u.uy + range;
X					y++) {
X				z = range;
X				if (!x)
X					z = -z;
X				if (test (z += u.ux, y)) {
X					tfoo -> zx = z;
X					tfoo++ -> zy = y;
X					if (tfoo == &foo[15])
X						goto foofull;
X				}
X			}
X		range++;
X	} while (tfoo == foo);
Xfoofull: 
X	tfoo = &foo[rn2 (tfoo - foo)];
X	mtmp -> mx = tfoo -> zx;
X	mtmp -> my = tfoo -> zy;
X	pmon (mtmp);
X	if (mtmp -> data -> mlet == 'w')
X		initworm (mtmp);
X}
X
Xrloc (mtmp)
XMONSTER mtmp;
X{
X	register        tx, ty;
X	register char   ch = mtmp -> data -> mlet;
X
X	if (ch == 'w' && mtmp -> mx)
X		return;		/* Do not relocate worms */
X	levlsym (mtmp -> mx, mtmp -> my, ch);
X	if (mtmp -> ale) {
X		do {
X			tx = rn1 (77, 2);
X			ty = rn2 (22);
X		/* until CORR,DORR,or ROOM; or... */
X		} while (levl[tx][ty].typ != POOL || m_at (tx, ty) ||
X				(tx == u.ux && ty == u.uy));
X	}
X	else {
X		do {
X			tx = rn1 (77, 2);
X			ty = rn2 (22);
X		/* until CORR,DORR,or ROOM; or... */
X		} while (levl[tx][ty].typ < DOOR || m_at (tx, ty) ||
X				(tx == u.ux && ty == u.uy)
X				|| levl[tx][ty].typ >= 7);
X	}
X	mtmp -> mx = tx;
X	mtmp -> my = ty;
X	pmon (mtmp);
X	if (ch == 'w')
X		initworm (mtmp);
X}
X
Xtest (x, y) {
X	if (x <= 0 || x > 78 || y <= 0 || y > 20)
X		return 0;
X	if (m_at (x, y) || levl[x][y].typ < DOOR || levl[x][y].typ >= 7)
X		return 0;
X	return 1;
X}
X
Xpoisoned (string, pname)
Xregister char  *string, *pname;
X{
X	pseebl ("%s was poisoned!", string);
X	if (u.upres) {
X		pline ("The poison doesn't seem to affect you.");
X		return;
X	}
X
X	switch (rn2 (6)) {
X		case 0: 
X			u.uhp = 0;
X			break;
X		case 1: 
X		case 2: 
X		case 3: 
X			losestr (rn1 (3, 3));
X			break;
X		case 4: 
X		case 5: 
X			losehp (rn1 (10, 6), pname);
X			return;
X	}
X
X	if (u.uhp <= 0)
X		killer = pname;
X}
X
Xsteal (mtmp)
XMONSTER mtmp;
X{
X	register        OBJECT otmp, ot1;
X	register        tmp;
X
X	for (otmp = invent, tmp = 0; otmp -> nobj; otmp = otmp -> nobj, tmp++);
X
X	tmp = rn2 (tmp);
X	otmp = invent;
X	if (!tmp)
X		invent = invent -> nobj;
X	else {
X		for (; otmp && tmp; tmp--, otmp = otmp -> nobj);
X		ot1 = otmp -> nobj;
X		otmp -> nobj = ot1 -> nobj;/* rm obj from invent */
X		otmp = ot1;
X	}
X	if (otmp == uarm || otmp == uarm2) {
X		u.uac += otmp -> spe;
X		if (otmp == uarm)
X			uarm = uarm2;
X		uarm2 = 0;
X		flags.dac = 1;
X	}
X	else if (otmp == uwep)
X		uwep = 0;
X	else if (otmp == uleft) {
X		uleft = 0;
X		doring (otmp, OFF);
X	}
X	else if (otmp == uright) {
X		uright = 0;
X		doring (otmp, OFF);
X	}
X	doname (otmp, buf);
X	pline ("She stole %s.", buf);
X	stlobj (mtmp, otmp);
X}
X
Xstlobj (mtmp, otmp)
Xregister        MONSTER mtmp;
Xregister        OBJECT otmp;
X{
X	otmp -> nobj = 0;	/* Michiel: dog and two objects? */
X	if (mtmp -> mstole) {
X		otmp -> nobj = mtmp -> mstole -> sobj;
X		mtmp -> mstole -> sobj = otmp;
X		return;
X	}			/* Michiel save stolen object */
X	else {
X		mtmp -> mstole = newstole ();
X		mtmp -> mstole -> sobj = otmp;
X		mtmp -> mstole -> sgold = 0;
X	}
X}
X
Xdelmon (mtmp)
Xregister        MONSTER mtmp;
X{
X	unstuck (mtmp);		/* a3 */
X	relmon (mtmp);
X	if (mtmp == shopkeeper)
X		shkdead ();
X	if (mtmp == vaultkeeper) {
X		mtmp -> data -> mmove = -1;
X		vaultkeeper = 0;
X	}
X	if (mtmp -> wormno)
X		wormdead (mtmp);
X	free (mtmp);
X}
X
Xrelmon (mtmp)
Xregister        MONSTER mtmp;
X{
X	register        MONSTER mtmp2;
X
X	if (mtmp == fmon)
X		fmon = fmon -> nmon;
X	else {
X		for (mtmp2 = fmon; mtmp2 -> nmon != mtmp; mtmp2 = mtmp2 -> nmon);
X		mtmp2 -> nmon = mtmp -> nmon;
X	}
X}
X
X/* Release the objects the killed animal has stolen */
Xrelobj (mtmp)
Xregister        MONSTER mtmp;
X{
X	register        GOLD_TRAP gtmp;
X	register        tmp = 0;
X	OBJECT otmp, otmp2;
X
X	if (mtmp -> mstole) {	/* Michiel drop stolen obj or gold */
X		if (mtmp -> mstole -> sgold)
X			tmp = mtmp -> mstole -> sgold;
X		else {
X			otmp = mtmp -> mstole -> sobj;
X			do {
X				otmp -> ox = mtmp -> mx;
X				otmp -> oy = mtmp -> my;
X				otmp2 = otmp;
X				otmp = otmp -> nobj;
X			} while (otmp);
X			otmp2 -> nobj = fobj;
X			fobj = mtmp -> mstole -> sobj;
X			if (mtmp -> data -> mlet != 'd')
X				seeatl (otmp -> ox, otmp -> oy, otmp -> olet);
X		}
X		free (mtmp -> mstole);
X		mtmp -> mstole = NULL;
X	}
X	if (mtmp -> data -> mlet == 'L') {
X		gtmp = newgen ();
X		gtmp -> ngen = fgold;
X		gtmp -> gx = mtmp -> mx;
X		gtmp -> gy = mtmp -> my;
X		if (dlevel)
X			gtmp -> gflag = tmp + d (dlevel, 30);
X		else
X			gtmp -> gflag = tmp + d (maxdlevel, 30);
X		fgold = gtmp;
X		seeatl (mtmp -> mx, mtmp -> my, '$');
X	}
X}
X
X/* a3 */
Xunstuck (mtmp)
Xregister        MONSTER mtmp;
X{
X	if (mtmp == u.ustuck) {
X		if (u.uswallow) {
X			u.uswallow = 0;
X			u.uswldtim = 0;
X			docrt ();
X			setCon (SETC);/* Try a3 */
X		}
X		u.ustuck = 0;
X	}
X}
X
Xkilled (mtmp)
Xregister        MONSTER mtmp;
X{
X	register        tmp;
X
X	unstuck (mtmp);
X	levlsym (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet);
X	if (mtmp -> cham)
X		mtmp -> data = (PM_CHAM);
X	pseebl ("You destroy %s!", mtmp -> data -> mname);
X	if (!u.ublind && u.umconf) {
X		pline (STOPGLOW);
X		u.umconf = 0;
X	}
X	tmp = mtmp -> data -> mhd;
X	tmp *= tmp;
X	++tmp;
X	if (mtmp -> data -> ac < 3)
X		tmp += (7 - mtmp -> data -> ac) << 1;
X	if (index ("AcsSDXaeRTVWU&In:P", mtmp -> data -> mlet))
X		tmp += mtmp -> data -> mhd << 1;
X	if (index ("DeV&P", mtmp -> data -> mlet))
X		tmp += 7 * mtmp -> data -> mhd;
X	if (mtmp -> data -> mhd > 6)
X		tmp += 50;
X	if (mtmp -> ale)
X		tmp += 1000;
X	relobj (mtmp);
X	if ((index ("NTV&", mtmp -> data -> mlet) || !rn2 (5)) && !mtmp -> ale
X			&& levl[mtmp -> mx][mtmp -> my].typ > SDOOR) {
X	/* Mimic in wall? */
X		mkobj (0);
X		fobj -> ox = mtmp -> mx;
X		fobj -> oy = mtmp -> my;
X		if (!u.ublind)
X			atl (mtmp -> mx, mtmp -> my, fobj -> olet);
X	}
X	delmon (mtmp);
X	u.urexp += tmp << 2;
X	u.uexp += tmp;
X	flags.dexp = 1;
X	while (u.uexp >= 10L * pow (u.ulevel - 1)) {
X		pline (WCLEV, ++u.ulevel);
X		tmp = rnd (10);
X		if (tmp < 3)
X			tmp = rnd (10);
X		u.uhpmax += tmp;
X		u.uhp += tmp;
X		flags.dhp = 1;
X		flags.dhpmax = 1;
X		flags.dulev = 1;
X	}
X}
X
X#define TBLIND	5
X#define NOTEST	6
X
X/*VARARGS*/
Xpsee (mode, x, y, str, name, arg)/* Str bevat %s */
Xregister char  *str, *name, *arg;
X{
X	char   *a1, *a2;
X
X	a1 = "the %s";
X	a2 = "the %s";
X	if (mode == TBLIND) {
X		if (u.ublind)
X			a1 = "it";
X	}
X	else if (mode != NOTEST && !cansee (x, y))
X		switch (mode) {
X			case IT1: 
X				a1 = "it";
X				break;
X			case THEIT2: 
X				a2 = "it";
X				break;
X			case 0: 
X				return 0;
X			default: 
X				pline ("Bad(%d) mode in psee", mode);
X		}
X	sprintf (buf, str, a1, a2);
X	if (*buf >= 'a' && *buf <= 'z')
X		*buf += 'A' - 'a';
X	pline (buf, name, arg);
X	return 1;
X}
X
X/*VARARGS*/
Xp2xthe (str, name, arg)
Xregister char  *str, *name, *arg;
X{
X	psee (NOTEST, 0, 0, str, name, arg);
X}
X
Xpseebl (str, name)
Xregister char  *str, *name;
X{
X	psee (TBLIND, 0, 0, str, name, NULL);
X}
X
Xrescham () {			/* Force all chameleons to become normal */
X	register        MONSTER mtmp;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon)
X		if (mtmp -> cham) {
X			mtmp -> cham = 0;
X			if (u.uswallow && u.ustuck == mtmp) {
X				unstuck (mtmp);
X				mnexto (mtmp);
X			}
X			newcham (mtmp, PM_CHAM);
X		}
X}
X
X/* Make a chameleon look like a new monster */
Xnewcham (mtmp, mdat)
Xregister        MONSTER mtmp;
Xregister        MONSTDATA mdat;
X{
X	register        mhp, hpn, hpd;
X
X	if (mdat == mtmp -> data)
X		return;		/* Still the same monster */
X	if (u.uswallow && mdat -> mlet == 'w')
X		return;
X	if (mtmp -> wormno)
X		wormdead (mtmp);/* Throw tail away */
X	hpn = mtmp -> mhp;
X	hpd = mtmp -> data -> mhd << 3;
X	mtmp -> data = mdat;
X	mtmp -> invis = 0;
X	mtmp -> mtame = 0;
X	mhp = mdat -> mhd << 3;
X/* New hp: same fraction of max as before */
X	mtmp -> mhp = 2 + (hpn * mhp) / hpd;
X	hpn = mtmp -> orig_hp;
X	mtmp -> orig_hp = 2 + (hpn * mhp) / hpd;
X	if (mdat -> mlet == 'I') {
X		++mtmp -> invis;
X		if (cansee (mtmp -> mx, mtmp -> my))
X			prl (mtmp -> mx, mtmp -> my);
X	}
X	if (mdat -> mlet == 'w' && getwn (mtmp))
X		initworm (mtmp);
X	if (u.uswallow && mtmp == u.ustuck &&
X			!index (",'P", mdat -> mlet)) {
X		unstuck (mtmp);
X		mnexto (mtmp);
X	}
X	pmon (mtmp);
X}
X
Xmakemon (ptr)
Xregister        MONSTDATA ptr;
X{
X	register        MONSTER mtmp;
X
X	if (!ptr) {
X		do
X			ptr = &mon[rn2 (dlevel / 3 + 1) % 8][rn2 (7)];
X		while (index (genocided, ptr -> mlet));
X	}
X	else {
X		if (index (genocided, ptr -> mlet)) {
X			if (!u.ublind)
X				p2xthe ("%s vanishes!", ptr -> mname);
X			return 1;
X		}
X	}
X	mtmp = newmonst (ptr -> pxlth);
X	mtmp -> nmon = fmon;
X	fmon = mtmp;
X	mtmp -> mstole = 0;
X	mtmp -> invis = 0;
X	mtmp -> cham = 0;
X	mtmp -> msleep = 0;
X	mtmp -> mfroz = 0;
X	mtmp -> mconf = 0;
X	mtmp -> mflee = 0;
X	mtmp -> mtame = 0;
X	mtmp -> mspeed = 0;
X	mtmp -> mcan = 0;
X	mtmp -> angry = 0;
X	mtmp -> mxlth = 0;
X	mtmp -> ale = 0;
X	mtmp -> data = ptr;
X	switch (ptr -> mlet) {
X		case 'I': 
X			++mtmp -> invis;
X			break;
X		case 'L': 
X			mtmp -> msleep = u.uhcursed;
X			break;
X		case ':': 
X			++mtmp -> cham;
X			if (!u.ucham)
X				newcham (mtmp, &mon[rn1 (6, 2)][rn2 (7)]);
X			break;
X		case ';': 
X			mtmp -> ale = 1;
X			break;
X	}
X	if (ptr -> mlet != 'w' || !getwn (mtmp))
X		mtmp -> wormno = 0;
X	mtmp -> mhp = rnd (4);
X	if (ptr -> mhd)
X		mtmp -> mhp = d (ptr -> mhd, 8);
X	mtmp -> orig_hp = mtmp -> mhp;
X	return 0;
X}
X
Xsomegold () {
X	return ((u.ugold < 100L) ? u.ugold :
X			(u.ugold > 10000L) ? rnd (10000) : rnd ((int) u.ugold));
X}
X
Xmkmonat (ptr, x, y)
Xregister        MONSTDATA ptr;
Xregister        x, y;
X{
X	if (makemon (ptr))
X		return;
X	if (x == u.ux && y == u.uy)
X		mnexto (fmon);
X	else {
X		atl (x, y, ptr -> mlet);
X		fmon -> mx = x;
X		fmon -> my = y;
X	}
X}
SHAR_EOF
if test 10311 -ne "`wc -c 'hack.mon.c'`"
then
	echo shar: error transmitting "'hack.mon.c'" '(should have been 10311 characters)'
fi
echo shar: extracting "'hack.mon.do.c'" '(12240 characters)'
if test -f 'hack.mon.do.c'
then
	echo shar: over-writing existing file "'hack.mon.do.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'hack.mon.do.c'
X/*
X * Hack.mon.do.c
X */
X
X/* Contains monster control routines */
X
X#include "hack.h"
X
Xextern  MONSTER bhit ();
X
Xmovemon () {
X	register        MONSTER mtmp, mtmp2;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp2) {
X		mtmp2 = mtmp -> nmon;
X		if (mtmp -> mspeed != MSLOW || moves % 2 == 0)
X			if (dochug (mtmp))
X				continue;/* Monster died */
X		if (mtmp -> mspeed == MFAST)
X			if (dochug (mtmp))
X				continue;
X
X/* If we left the room: make monsters invis, even if they didn't move */
X
X		if (!cansee (mtmp -> mx, mtmp -> my))
X			levlsym (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet);
X		if (mtmp -> wormno && mtmp -> data -> mlet == 'w')
X			wormsee (mtmp -> wormno);
X	}
X}
X
Xjustswld (mtmp)
Xregister        MONSTER mtmp;
X{
X	newsym (mtmp -> mx, mtmp -> my);
X	mtmp -> mx = u.ux;
X	mtmp -> my = u.uy;
X	u.ustuck = mtmp;
X	at (u.ux, u.uy, mtmp -> data -> mlet);
X	pseebl ("%s swallows you!", mtmp -> data -> mname);
X	more ();
X	u.uswallow = 1;
X	docrt ();
X}
X
Xyouswld (mtmp, dam, die)
Xregister        MONSTER mtmp;
Xregister        dam, die;
X{
X	pseebl ("%s digests you!", killer = mtmp -> data -> mname);
X	if (dam > 0) {
X		u.uhp -= dam;
X		flags.dhp = 1;
X	}
X	if (u.uswldtim++ == die) {
X		pline ("It totally digests you!");
X		u.uhp = 0;
X	}
X}
X
Xx2hitu (mlev, x, name)
Xregister        mlev, x;
Xregister char  *name;		/* a3 */
X{
X	register        i;
X
X	for (i = 0; i < 2; i++)
X		hitu (mlev, (x < 0) ? d (2, x) : (x == 0) ? d (3, 4) :
X				rnd (x), name);
X}
X
Xdochug (mtmp)
Xregister        MONSTER mtmp;
X{
X	register        MONSTDATA mdat;
X	register        tmp = 0, ctmp;
X
X	if (mtmp -> mhp <= 0 && !mtmp -> mtame)
X		return 1;	/* Killed by dog or ? */
X	if (mtmp -> cham && !rn2 (6))
X		newcham (mtmp, &mon[rn1 (6, 2)][rn2 (7)]);
X	mdat = mtmp -> data;
X /* 
X  if( mdat->mhd < 0 )
X  panic( CORE, "Bad(%d)monster %c", mdat->mhd,
X  mdat->mlet );
X  */
X	if ((moves % 20 == 0 || index ("ViT", mdat -> mlet)) &&
X			mtmp -> mhp < mtmp -> orig_hp)
X		mtmp -> mhp++;	/* Regenerate monsters */
X	if (mtmp -> mfroz)
X		return 0;	/* Frozen monsters don't do anything */
X	if (mtmp -> msleep) {
X	/* Wake up a monster, or get out of here */
X		if (cansee (mtmp -> mx, mtmp -> my) && !u.ustelth &&
X				(!rn2 (7) || u.uagmon))
X			mtmp -> msleep = 0;
X		else
X			return 0;
X	}
X
X/* Confused monsters get unconfused with small probability */
X
X	if (mtmp -> mconf && !rn2 (50))
X		mtmp -> mconf = 0;
X	if (mdat -> mmove >= rnd (12) && (mtmp -> mflee || mtmp -> mconf ||
X				dist (mtmp -> mx, mtmp -> my) > 2 || mtmp -> mtame ||
X				mtmp == shopkeeper) && (tmp = m_move (mtmp, 0)) &&
X			mdat -> mmove <= 12)
X		return (tmp == 2);
X /* Move monsters and exit if rate<=12 */
X	if (tmp == 2)
X		return 1;	/* Monster died moving */
X
X	if (!index ("Ea", mdat -> mlet) && dist (mtmp -> mx, mtmp -> my) < 3
X			&& !mtmp -> mtame && mtmp != shopkeeper && u.uhp > 0) {
X		nomul (tmp = 0);
X		if (u.uswallow) {
X			if (mtmp != u.ustuck)
X				if (mdat -> mmove - 12 > rnd (12))
X					tmp = m_move (mtmp, 1);
X		}
X		else if (!index ("&DyF", mdat -> mlet)) {
X			if (mtmp -> ale && cansee (mtmp -> mx, mtmp -> my)) {
X				mtmp -> invis = 0;
X				pmon (mtmp);
X			}
X			tmp = hitu (mdat -> mhd, d (mdat -> damn, mdat -> damd),
X					mdat -> mname);
X		}
X
X/* Increase chance of hitting (no damage) for L and R */
X		if (index ("LR", mdat -> mlet) && hitu (5, 0, mdat -> mname))
X			tmp++;
X
X		ctmp = (tmp && !mtmp -> mcan && (!uarm ||
X					armors[uarm -> otyp].a_can < rnd (3)));
X
X		switch (mdat -> mlet) {
X
X			case ';': 
X				if (mtmp -> mcan)
X					break;
X				if (!u.ustuck && !rn2 (20)) {
X					p2xthe ("%s swings itself around you!",
X							mdat -> mname);
X					u.ustuck = mtmp;
X				}
X				else if (u.ustuck == mtmp && ctmp) {
X					p2xthe ("%s drowns you...", mdat -> mname);
X					more ();
X					done (DROWNED);
X				}
X				break;
X
X			case '&': 
X				if (!mtmp -> mcan && !rn2 (15)) {
X					makemon (PM_DEMON);
X					mnexto (fmon);
X				}
X				else {
X					x2hitu (10, -6, mdat -> mname);
X					x2hitu (10, 3, mdat -> mname);
X					hitu (10, rn1 (4, 2), mdat -> mname);
X				}
X				break;
X
X			case ',': 
X			case '\'': 
X				if (u.uswallow)
X					if (mdat -> mlet == ',')
X						youswld (mtmp, 4 + u.uac, 5);
X					else
X						youswld (mtmp, rnd (6), 7);
X				else if (tmp)
X					justswld (mtmp);
X				break;
X
X			case 'A': 
X				if (ctmp && rn2 (2)) {
X					pline ("You feel weaker!");
X					losestr (1);
X				}
X				break;
X
X			case 'C': 
X			case 'Y': 
X				hitu (4, rnd (6), mdat -> mname);
X				break;
X
X			case 'c': 
X				if (ctmp && !rn2 (5)) {
X					pline ("You get turned to stone!");
X					u.uhp = 0;
X				}
X				break;
X
X			case 'D': 
X				if (rn2 (6) || mtmp -> mcan) {
X					hitu (10, d (3, 10), mdat -> mname);
X					x2hitu (10, 8, mdat -> mname);
X					break;
X				}
X				pseebl ("%s breathes fire!", mdat -> mname);
X				buzz (Z_FIRE, mtmp -> mx, mtmp -> my,
X						u.ux - mtmp -> mx,
X						u.uy - mtmp -> my);
X				break;
X
X			case 'd': 
X				hitu (6, d (2, 4), mdat -> mname);
X				break;
X
X			case 'e': 
X				hitu (10, d (3, 6), mdat -> mname);
X				break;
X
X			case 'F': 
X				if (mtmp -> mcan)
X					break;
X				pseebl ("%s explodes!", mdat -> mname);
X				if (u.ucoldres)
X					pline ("You don't seem affected by it.");
X				else {
X					if (17 - (u.ulevel >> 1) > rnd (20)) {
X						pline ("You get blasted!");
X						tmp = 6;
X					}
X					else {
X						pline ("You duck the blast...");
X						tmp = 3;
X					}
X					losehp (d (tmp, 6), mdat -> mname);
X				}
X				cmdel (mtmp);
X				return 1;
X
X			case 'g': 
X				if (!ctmp || multi < 0 || rn2 (6))
X					break;
X				pseebl ("You are frozen by %ss juices", "cube'");
X				nomul (-rnd (10));
X				break;
X
X			case 'h': 
X				if (!ctmp || multi < 0 || rn2 (5))
X					break;
X				pseebl ("You are put to sleep by %ss bite!",
X						"homunculus'");
X				nomul (-rnd (10));
X				break;
X
X			case 'j': 
X				tmp = hitu (4, rnd (3), mdat -> mname);
X				tmp &= hitu (4, rnd (3), mdat -> mname);
X				if (tmp)
X					x2hitu (4, 4, mdat -> mname);
X				break;
X
X			case 'k': 
X				if ((hitu (4, rnd (4), mdat -> mname) || !rn2 (3))
X						&& ctmp)
X					poisoned ("bee's sting", mdat -> mname);
X				break;
X
X			case 'L': 
X				if (ctmp && u.ugold && rn2 (2)) {
X					u.ugold -= (ctmp = somegold ());
X					pline ("Your purse feels lighter.");
X					flags.dgold = 1;
X
X				/* Michiel save stolen gold */
X					if (mtmp -> mstole)
X						mtmp -> mstole -> sgold += ctmp;
X					else {
X						mtmp -> mstole = newstole ();
X						mtmp -> mstole -> sobj = 0;
X						mtmp -> mstole -> sgold = ctmp;
X					}
X					mtmp -> mflee = 1;
X					rloc (mtmp);
X				}
X				break;
X
X			case 'N': 
X				if (ctmp && invent && rn2 (2)) {
X					steal (mtmp);
X					rloc (mtmp);
X					mtmp -> mflee = 1;
X				}
X				break;
X
X			case 'n': 
X				x2hitu (11, -6, mdat -> mname);
X				break;
X
X			case 'o': 
X				hitu (5, rnd (6), mdat -> mname);
X				/*  tmp= ??  */
X				if (hitu (5, rnd (6), mdat -> mname) && ctmp &&
X						!u.ustuck && rn2 (2)) {
X					u.ustuck = mtmp;
X					pseebl ("%s has grabbed you!",
X							mdat -> mname);
X					u.uhp -= d (2, 8);
X					break;
X				}
X				if (u.ustuck == mtmp) {
X					pline ("You are being crushed.");
X					u.uhp -= d (2, 8);
X				}
X				break;
X
X			case 'P': 
X				if (u.uswallow)
X					youswld (mtmp, d (2, 4), 12);
X				else if (ctmp && !rn2 (4))
X					justswld (mtmp);
X				else
X					hitu (15, d (2, 4), mdat -> mname);
X				break;
X
X			case 'Q': 
X				x2hitu (3, 2, mdat -> mname);
X				break;
X
X			case 'R': 
X				if (ctmp && uarm && uarm -> otyp < A_STD_LEATHER
X						&& uarm -> spe > -2) {
X					pline ("Your armor rusts!");
X					--uarm -> spe;
X					u.uac++;
X					flags.dac = 1;
X				}
X				break;
X
X			case 'S': 
X				if (ctmp && !rn2 (8))
X					poisoned ("snake's bite", mdat -> mname);
X				break;
X
X			case 's': 
X				if (tmp && !rn2 (8))
X					poisoned ("scorpion's sting",
X							mdat -> mname);
X				x2hitu (5, 8, mdat -> mname);
X				break;
X
X			case 'T': 
X				x2hitu (6, 6, mdat -> mname);
X				break;
X
X			case 'U': 
X				x2hitu (9, 0, mdat -> mname);/* 0: d(3,4) */
X				break;
X
X			case 'v': 
X				if (ctmp && !u.ustuck)
X					u.ustuck = mtmp;
X				break;
X
X			case 'V': 
X				if (tmp)
X					u.uhp -= 4;
X				if (rn2 (3))
X					break;
X		V: 
X				if (ctmp) {/* hit by V or W */
X					if (u.ulevel > 1)
X						pline ("Goodbye level %d.",
X								u.ulevel--);
X					else
X						u.uhp = 0;
X					ctmp = rnd (10);
X					u.uhp -= ctmp;
X					u.uhpmax -= ctmp;
X					u.uexp = 10L * pow (u.ulevel - 1) - 1L;
X					flags.dhp = 1;
X					flags.dhpmax = 1;
X					flags.dulev = 1;
X					flags.dexp = 1;
X				}
X				break;
X
X			case 'W': 
X				if (rn2 (5))
X					break;
X				goto V;
X			case 'w': 
X				if (tmp)
X					wormhit (mtmp);
X				break;
X			case 'X': 
X				for (tmp = 0; tmp < 3; tmp++)
X					hitu (8, rnd (3), mdat -> mname);
X				break;
X
X			case 'y': 
X				if (mtmp -> mcan)
X					break;
X				cmdel (mtmp);
X				if (!u.ublind) {
X					pline ("You are blinded by a blast of light!");
X					u.ublind = d (4, 12);
X					unCoff (COFF, 0);
X				}
X				return 1;
X		}		/* switch */
X
X		if (u.uhp <= 0)
X			killer = mdat -> mname;
X	}
X	else if (mtmp -> ale && cansee (mtmp -> mx, mtmp -> my)) {
X		mtmp -> invis = 1;
X		newsym (mtmp -> mx, mtmp -> my);
X	}
X/* Extra movement for fast monsters */
X	if (mdat -> mmove - 12 > rnd (12))
X		tmp = m_move (mtmp, 1);
X	return (tmp == 2);
X}
X
Xcmdel (mtmp)
Xregister        MONSTER mtmp;
X{
X	register char   mx = mtmp -> mx, my = mtmp -> my;
X
X	delmon (mtmp);
X	if (cansee (mx, my))
X		newsym (mx, my);
X}
X
Xinrange (mtmp)
Xregister        MONSTER mtmp;
X{
X	int     zx, zy;
X	register char   tx = u.ux - mtmp -> mx, ty = u.uy - mtmp -> my;
X
X/* This mess figures out if the person is within 8 */
X	if ((!tx && abs (ty) < 8) || (!ty && abs (tx) < 8) ||
X			(abs (tx) == abs (ty) && abs (tx) < 8)) {
X		if (tx == 0)
X			zx = 0;
X		else
X			zx = tx / abs (tx);
X		if (ty == 0)
X			zy = 0;
X		else
X			zy = ty / abs (ty);
X/* If we don't save dx and dy a capital move may screw up: */
X		tx = dx;
X		ty = dy;
X		if (bhit (zx, zy, 8) == mtmp)
X			buzz (Z_FIRE, mtmp -> mx, mtmp -> my, dx, dy);
X		dx = zx;
X		dy = zy;
X	}
X}
X
Xm_move (mtmp, after)
Xregister        MONSTER mtmp;
X{
X	register        MONSTER mtmp2;
X	register        nix, niy, omx, omy, appr, nearer, cnt, zx, zy;
X	char    ddx, ddy, mmoved = 0;
X
X/* My dog gets a special treatment */
X	if (mtmp -> mtame)
X		return dog_move (mtmp, after);
X
X	if (u.uswallow)
X		return (1);	/* a3 */
X/* Likewise for shopkeeper */
X	if (mtmp == shopkeeper)
X		return shk_move ();
X	if (mtmp == vaultkeeper && !mtmp -> angry)
X		return (0);
X
X	if (mtmp -> data -> mlet == 't' && !rn2 (19)) {
X		if (rn2 (2)) {
X			ddx = mtmp -> mx;
X			ddy = mtmp -> my;
X			mnexto (mtmp);/* Doesn't change old position */
X			levlsym (ddx, ddy, 't');
X		}
X		else
X			rloc (mtmp);/* Rloc does */
X		return 1;
X	}
X	if (!mtmp -> mcan)
X		switch (mtmp -> data -> mlet) {
X			case 'D': 
X				inrange (mtmp);
X				break;
X			case 'U': 
X				if (!rn2 (10) && !u.uconfused &&
X						cansee (mtmp -> mx, mtmp -> my)) {
X					pline ("You are confused!");
X					u.uconfused = d (3, 4);
X				}
X				if (!mtmp -> mflee && u.uswallow &&
X						u.ustuck != mtmp)
X					return 1;
X		}
X	appr = 1;
X	if (mtmp -> mflee)
X		appr = -1;
X	if (mtmp -> mconf || u.uinvis || (index ("BI", mtmp -> data -> mlet) &&
X				!rn2 (3)))
X		appr = 0;
X	omx = mtmp -> mx;
X	omy = mtmp -> my;
X	nix = omx;
X	niy = omy;
X	cnt = 0;
X	for (ddx = -1; ddx <= 1; ddx++)
X		for (ddy = -1; ddy <= 1; ddy++)
X			if (r_free (zx = omx + ddx, zy = omy + ddy, mtmp)
X					&& (ddx || ddy)
X					&& !(ddx && ddy && (levl[omx][omy].typ == DOOR ||
X							levl[zx][zy].typ == DOOR))) {
X				if (!mtmp -> mconf && m_at (zx, zy))
X					continue;
X				nearer = (dist (zx, zy) < dist (nix, niy));
X				if ((appr > 0 && nearer) || (appr < 0 &&
X							!nearer) ||
X						(!mmoved && mtmp -> wormno) ||
X						(!appr && !rn2 (++cnt))) {
X					nix = zx;
X					niy = zy;
X					mmoved++;
X				}
X			}
X	if (mmoved) {
X		if (mtmp -> mconf && (mtmp2 = m_at (nix, niy))) {
X			if (hitmm (mtmp, mtmp2) == 1 && rn2 (4) &&
X					hitmm (mtmp2, mtmp) == 2)
X				return 2;
X			return 0;
X		}
X		if (!mtmp -> ale) {
X			mtmp -> mx = nix;
X			mtmp -> my = niy;
X		}
X		else if (levl[nix][niy].typ == POOL) {
X			mtmp -> mx = nix;
X			mtmp -> my = niy;
X		}
X
X		if (mtmp -> wormno && mtmp -> data -> mlet == 'w')
X			worm_move (mtmp);
X	}
X	else {
X		if (!rn2 (10) && index ("tNL", mtmp -> data -> mlet)) {
X			rloc (mtmp);
X			return 0;
X		}
X		if (mtmp -> wormno)
X			worm_nomove (mtmp);
X	}
X	if (mmoved || !cansee (omx, omy))
X		levlsym (omx, omy, mtmp -> data -> mlet);
X	pmon (mtmp);
X	return (mmoved);
X}
SHAR_EOF
if test 12240 -ne "`wc -c 'hack.mon.do.c'`"
then
	echo shar: error transmitting "'hack.mon.do.c'" '(should have been 12240 characters)'
fi
#	End of shell archive
exit 0