Hack sources for PDP11/44 and PDP11/45 (part 2 of 5)

Michiel B. Huisjes huisjes at ark.UUCP
Wed Feb 6 16:47:31 AEST 1985


#!/bin/sh
#
# 
# 
# This is a shell archive. These archives are packed by the program 
# packmail(1). If you have the program unshar(1), I suggest you use it.
# If you don't remove anything before the cut line and then feed to
# sh(1)
# 
# =====CUT HERE=======CUT HERE=======CUT HERE=======CUT HERE=======CUT HERE===
#
echo 'Start of Hack, part 02 of 05:'
echo 'x - hack.do1.c'
sed 's/^X//' > hack.do1.c << '/'
X/*
X * Hack.do1.c
X */
X
X#include "hack.h"
X
Xextern char     NOTHIN[], WAND[];
X
Xextern  MONSTER shopkeeper;
XMONSTER vaultkeeper;
X
Xchar   *wandeffect[] = {
X	"magic missile",
X	"bolt of fire",
X	"sleep ray",
X	"bolt of cold",
X	"death ray",
X	"bolt of confusion"
X};
X
X#define MAXLEVEL	40
X
Xchar    vaultflag[MAXLEVEL];
X
XMONSTER bhit ();
X
X
X
X/* More various user do commands */
X
X
X
X
Xdozap () {
X	register        OBJECT obj;
X	register        MONSTER mtmp;
X	char    zx, zy;
X	register        num;
X
X	if (!(obj = getobj ("/", "zap"))) {
X		nomove ();
X		return;
X	}
X	if (!obj -> spe) {
X		pline (NOTHIN);
X		return;
X	}
X	obj -> spe--;
X	if (obj -> otyp <= Z_CREATE_MON) {
X		switch (obj -> otyp) {
X
X			case Z_LIGHT: 
X				if (dlevel)
X					litroom ();
X				else
X					pline (NOTHIN);
X				break;
X
X			case Z_DETEC: 
X				if (!findit ())
X					return;
X				break;
X
X			case Z_CREATE_MON: 
X				makemon (0);
X				mnexto (fmon);
X				break;
X		}
X
X		if (oiden[obj -> otyp] & WANN)
X			return;
X		u.urexp += 10;
X		oiden[obj -> otyp] |= WANN;
X		return;
X	}
X	if (!getdir ()) {
X		obj -> spe++;
X		nomove ();
X		return;
X	}
X	if (obj -> otyp <= Z_TELEPORT) {
X		if (mtmp = bhit (dx, dy, rn1 (8, 6))) {
X			switch (obj -> otyp) {
X
X				case Z_EXHAUST: 
X					pline ("You fight and fight and fight......");
X					home ();
X					flush ();
X					sleep (2);
X					flags.topl = 0;
X					u.uhp -= mtmp -> mhp;
X					if (u.uhp <= 0) {
X						pseebl ("You cannot beat %s",
X								mtmp -> data -> mname);
X						pline ("You die....");
X						done (DIED);
X					}
X					else {
X						mtmp -> mhp = 0;
X						flags.dhp = 1;
X						killed (mtmp);
X					}
X					oiden[obj -> otyp] |= WANN;
X					break;
X
X				case Z_SLOW_MON: 
X					mtmp -> mspeed = MSLOW;
X					break;
X
X				case Z_SPEED_MON: 
X					mtmp -> mspeed = MFAST;
X					break;
X
X				case Z_UND_TUR: 
X					if (index (" WVZ&", mtmp -> data -> mlet)) {
X						mtmp -> mhp -= rnd (8);
X						if (alive (mtmp))
X							mtmp -> mflee = 1;
X					}
X					break;
X
X				case Z_POLYMORF: 
X					if (mtmp -> ale && !cansee (mtmp -> mx, mtmp -> my))
X						break;
X					if (mtmp == shopkeeper)
X						shkdead ();/* Michiel */
X					unstuck (mtmp);
X					newcham (mtmp, &mon[rn2 (8)][rn2 (7)]);
X					oiden[obj -> otyp] |= WANN;
X					return;
X
X				case Z_CAN: 
X					mtmp -> mcan = 1;
X					break;
X
X				case Z_TELEPORT: 
X					unstuck (u.ustuck);
X					oiden[obj -> otyp] |= WANN;
X					if (mtmp == shopkeeper)
X						setangry ();/* FRED */
X					else if (mtmp == vaultkeeper)
X						mtmp -> angry = 1;
X					rloc (mtmp);
X					break;
X
X			}
X		}
X		return;
X	}
X	if (obj -> otyp == Z_CLOSING) {
X		PART * room;
X
X		zx = u.ux + dx;
X		zy = u.uy + dy;
X		room = &levl[zx][zy];
X		while (room -> typ >= CORR) {
X			zx += dx;
X			zy += dy;
X			room = &levl[zx][zy];
X		}
X		if (room -> typ == DOOR || room -> typ == SDOOR) {
X			pline ("The %sdoor closes forever.",
X					room -> typ == SDOOR ? "secret " : "");
X			oiden[obj -> otyp] |= WANN;
X			room -> typ = WALL;
X			newsym (zx, zy);
X		}
X		return;
X	}
X	if (obj -> otyp == Z_DIGGING) {
X	/* This is further improved by Michiel and Fred */
X		PART * room;
X		int     range = 1;
X
X		zx = u.ux + dx;
X		zy = u.uy + dy;
X		num = ROOM;
X		for (;;) {
X			if (zx < 1 || zx > 78 || zy < 1 || zy > 21) {
X				zx -= dx;
X				zy -= dy;
X				break;
X			}
X			atl (zx, zy, '*');
X			at (zx, zy, '*');
X			++range;
X			room = &levl[zx][zy];
X			if (!xdnstair) {
X				if (zx < 3 || zx > 76 || zy < 3 ||
X						zy > 18)
X					break;
X				if (room -> typ == WALL) {
X					room -> typ = ROOM;
X					break;
X				}
X			}
X			else if (room -> typ == POOL)
X				goto check;
X			else if (num == ROOM || num == 10) {
X				if (room -> typ) {
X					if (room -> typ == VAULT)
X						vaultinit ();
X					if (room -> typ != ROOM) {
X						if (room -> typ == VAULT)
X							room -> typ = ROOM;
X						else
X						if (room -> typ != CORR)
X							room -> typ = DOOR;
X						if (num == 10)
X							break;
X						num = 10;
X					}
X				}
X				else
X					room -> typ = CORR;
X			}
X			else {
X				if (room -> typ == VAULT)
X					vaultinit ();
X				if (room -> typ % 4) {
X				/* WALL,(S)DOOR,ROOM */
X					room -> typ = DOOR;
X					break;
X				}
X				else
X					room -> typ = CORR;
X			}
X	check: 
X			newsym (zx, zy);
X			zx += dx;
X			zy += dy;
X		}
X		while (--range) {
X			newsym (zx, zy);
X			if (mtmp = m_at (zx, zy))
X				pmon (mtmp);
X			zx -= dx;
X			zy -= dy;
X		}
X	}
X	else
X		buzz (obj -> otyp, u.ux, u.uy, dx, dy);
X	oiden[obj -> otyp] |= WANN;
X}
X
Xhit (str, mtmp)
Xregister char  *str;
Xregister        MONSTER mtmp;
X{
X	psee (THEIT2, mtmp -> mx, mtmp -> my, "%s hits %s", str,
X			mtmp -> data -> mname);
X}
X
Xmiss (str, mtmp)
Xregister char  *str;
Xregister        MONSTER mtmp;
X{
X	psee (THEIT2, mtmp -> mx, mtmp -> my, "%s misses %s", str,
X			mtmp -> data -> mname);
X}
X
Xfindit () {
X	char    num, lx, hx, ly, hy;
X	register char   zx, zy;
X	register        GOLD_TRAP gtmp, gt1;
X
X	for (lx = u.ux; levl[lx - 1][u.uy].typ % CORR; lx--);/* typ!=0 */
X /* WALL, SDOOR, DOOR, or ROOM (see hack.h) */
X
X	for (hx = u.ux; levl[hx + 1][u.uy].typ % 4; hx++);
X	for (ly = u.uy; levl[u.ux][ly - 1].typ % 4; ly--);
X	for (hy = u.uy; levl[u.ux][hy + 1].typ % 4; hy++);
X	num = 0;
X	for (zy = ly; zy <= hy; zy++)
X		for (zx = lx; zx <= hx; zx++) {
X			if (levl[zx][zy].typ == SDOOR) {
X				levl[zx][zy].typ = DOOR;
X				atl (zx, zy, '+');
X				num++;
X			}
X			else if (gtmp = g_at (zx, zy, ftrap)) {
X				if (gtmp -> gflag == PIERC) {
X					mkmonat (PM_PIERC, zx, zy);
X					num++;
X					deltrap (gtmp);
X				}
X				else if (gtmp -> gflag == MIMIC) {
X					deltrap (gtmp);
X			M: 
X					mkmonat (PM_MIMIC, zx, zy);
X					num++;
X				}
X				else if (!gtmp -> gflag & SEEN) {
X					gtmp -> gflag |= SEEN;
X					atl (zx, zy, '^');
X					num++;
X				}
X			}
X			else if ((gtmp = g_at (zx, zy, fgold)) &&
X					!gtmp -> gflag) {
X				if (gtmp == fgold)
X					fgold = gtmp -> ngen;
X				else {
X					for (gt1 = fgold; gt1 -> ngen !=
X							gtmp; gt1 = gt1 -> ngen);
X					gt1 -> ngen = gtmp -> ngen;
X				}
X				free (gtmp);
X				goto M;
X			}
X		}
X	return (num);
X}
X
X/* Sets dx,dy to the final position of the weapon thrown */
XMONSTER bhit (ddx, ddy, range) {
X	register        MONSTER mtmp;
X
X	dx = u.ux;
X	dy = u.uy;
X	if (u.uswallow)
X		return u.ustuck;/* a3 */
X	while (range-- > 0) {
X		dx += ddx;
X		dy += ddy;
X		if (mtmp = m_at (dx, dy))
X			return (mtmp);
X		if (levl[dx][dy].typ < CORR) {
X			dx -= ddx;
X			dy -= ddy;
X			return (0);
X		}
X	}
X	return (0);
X}
X
Xbuzz (type, sx, sy, ddx, ddy)
Xregister        sx, sy;
X{
X	PART * lev;
X	register char   range, let;
X	register        MONSTER mtmp;
X	register        wandeftype = type - 11;
X
X	if (u.uswallow) {
X		pline ("The %s rips into the %s.",
X				wandeffect[wandeftype],
X				u.ustuck -> data -> mname);
X		zhit (u.ustuck, type);
X		alive (u.ustuck);/* a3 */
X		return;
X	}
X	range = rn1 (7, 7);
X	if (ddx == ddy)
X		let = '\\';
X	else if (ddx && ddy)
X		let = '/';
X	else if (ddx)
X		let = '-';
X	else
X		let = '|';
X	while (range-- > 0) {
X		sx += ddx;
X		sy += ddy;
X		if ((lev = &levl[sx][sy]) -> typ) {
X			at (sx, sy, let);
X			on (sx, sy);
X			lev -> new = 1;
X		}
X		if (mtmp = m_at (sx, sy)) {
X			if (mtmp == vaultkeeper)
X				mtmp -> angry = 1;
X			if (rnd (20) < 18 + mtmp -> data -> ac) {
X				zhit (mtmp, type);
X				if (alive (mtmp))
X					hit (wandeffect[wandeftype],
X							mtmp);
X				range -= 2;
X			}
X			else
X				miss (wandeffect[wandeftype], mtmp);
X		}
X		else if (sx == u.ux && sy == u.uy) {
X			if (rnd (20) < 18 + u.uac) {
X				range -= 2;
X				flags.dhp = 1;/* Michiel */
X				pline ("The %s hits you!",
X						wandeffect[wandeftype]);
X				switch (type) {
X					case Z_MAG_MISSILE: 
X						u.uhp -= d (2, 6);
X						break;
X					case Z_FIRE: 
X						if (u.ufireres) {
X							pline ("You don't feel hot!");
X							break;
X						}
X						u.uhp -= d (6, 6);
X						break;
X					case Z_SLEEP: 
X						nomul (-rnd (25));
X						break;
X					case Z_COLD: 
X						if (u.ucoldres) {
X							pline ("You don't feel cold!");
X							break;
X						}
X						u.uhp -= d (6, 6);
X						break;
X					case Z_DEATH: 
X						u.uhp = 0;
X						break;
X					case Z_CONF_MON: 
X						u.uconfused = d (4, 6);
X				}
X				if (u.uhp <= 0)
X					killer = wandeffect[wandeftype];
X			}
X			else
X				pline ("The %s wizzes by you!",
X						wandeffect[wandeftype]);
X		}
X		if (lev -> typ <= DOOR || lev -> typ == VAULT) {
X			psee (0, sx, sy, "%s bounces!",
X					wandeffect[wandeftype], NULL);
X			ddx = -ddx;
X			ddy = -ddy;
X			range--;
X		}
X	}
X}
X
Xzhit (mtmp, type)
Xregister        MONSTER mtmp;
Xregister        type;
X{
X	if (mtmp == shopkeeper)
X		setangry ();
X	switch (type) {
X		case Z_MAG_MISSILE: 
X			mtmp -> mhp -= d (2, 6);
X			break;
X		case Z_FIRE: 
X			if (index ("Dg", mtmp -> data -> mlet))
X				return;
X			mtmp -> mhp -= d (6, 6);
X			if (mtmp -> data -> mlet == 'Y')
X				mtmp -> mhp -= 7;
X			break;
X		case Z_SLEEP: 
X			mtmp -> mfroz = 1;
X			break;
X		case Z_COLD: 
X			if (index ("Ygf", mtmp -> data -> mlet))
X				return;
X			if (mtmp -> data -> mlet == 'D')
X				mtmp -> mhp -= 7;
X			mtmp -> mhp -= d (6, 6);
X			break;
X		case Z_DEATH: 
X			if (index ("WVZ ", mtmp -> data -> mlet))
X				return;
X			mtmp -> mhp = 0;
X			break;
X		case Z_CONF_MON: 
X			if (mtmp == u.ustuck)
X				return;
X			mtmp -> mconf = 1;
X			break;
X
X	}
X}
X
Xdowhatis () {
X	register        fd;
X	register char  *str;
X
X
X	pline ("Specify what? ");
X	flags.topl = 0;
X	getlin (buf);
X	str = buf;
X	while (*str == ' ')
X		str++;
X	nomove ();
X	buf[52] = '\0';
X	if (*(str + 1))
X		pline ("One character please.");
X	else if ((fd = open (DATA, 0)) < 0)
X		pline ("Cannot open data file!");
X	else {
X		lseek (fd, (long) (*str * 51), 0);
X		if (read (fd, buf, 51) > 0 && *buf != '\\')
X			pline (buf);
X		else
X			pline ("Unknown symbol.");
X		close (fd);
X	}
X}
X
Xdoshow () {			/* Michiel: Show everything you're wearing */
X	nomove ();
X	show (uarm2);
X	show (uarm);
X	show (uwep);
X	show (uleft);
X	show (uright);
X}
X
Xshow (otmp)
Xregister        OBJECT otmp;
X{
X	if (otmp)
X		prinv (otmp);
X}
X
Xdosearch () {
X	register char   x, y;
X	register        GOLD_TRAP tgen;
X
X	for (x = u.ux - 1; x < u.ux + 2; x++)
X		for (y = u.uy - 1; y < u.uy + 2; y++)
X			if (levl[x][y].typ == SDOOR && !rn2 (7)) {
X				levl[x][y].typ = DOOR;
X				atl (x, y, '+');
X				nomul (0);
X			}
X			else {
X				for (tgen = ftrap; tgen; tgen = tgen -> ngen)
X					if (tgen -> gx == x && tgen -> gy == y &&
X							(!rn2 (8) || ((!u.usearch) &&
X									tgen -> gflag & SEEN))) {
X						nomul (0);
X						pline ("You find a%s", traps[tgen -> gflag & 037]);
X						if ((tgen -> gflag & 037) ==
X								PIERC) {
X							deltrap (tgen);
X							mkmonat (PM_PIERC, x, y);
X							return;
X						}
X						if ((tgen -> gflag & 037) ==
X								MIMIC) {
X							deltrap (tgen);
X							mkmonat (PM_MIMIC, x, y);
X							return;
X						}
X						if (!(tgen -> gflag & SEEN)) {
X							tgen -> gflag |= SEEN;
X							atl (x, y, '^');
X						}
X					}
X			}
X}
X
Xdoset () {
X	pline ("Give one inventory per line? ");
X	flush ();
X	flags.oneline = (getchar () == 'y');
X	nomove ();
X}
X
X
X
X/*
X * The whole vault was implemented by Fred and Michiel 
X *
X */
X
X
Xstruct permonst treasurer = {
X	"treasurer", '@', 15, 12, -1, 4, 8, 0
X};
X
Xvaultinit () {
X	GOLD_TRAP gtmp;
X
X	if (vaultflag[dlevel])
X		return;
X	vaultflag[dlevel] = 1;;
X	makemon (&treasurer);
X	vaultkeeper = fmon;
X	for (gtmp = fgold; gtmp -> gflag < 10000; gtmp = gtmp -> ngen);
X	fmon -> mx = gtmp -> gx;
X	fmon -> my = gtmp -> gy;
X	if (!u.ublind)
X		pmon (fmon);
X}
/
echo 'x - hack.mon.c'
sed 's/^X//' > 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}
/
echo 'x - hack.move.c'
sed 's/^X//' > hack.move.c << '/'
X/*
X * Hack.move.c
X */
X
X#include "hack.h"
X
Xextern char     STOPGLOW[], UMISS[], *setan ();
X
X
Xextern  OBJECT addinv ();
X
Xchar    seelx, seehx, seely, seehy;/* Corners of lit room */
X /* l for Low, h for High */
X
X#define ZOO		1
X#define GRAVEYARD	2
X#define SWAMP		3
X#define FORT_KNOX	4
X
X
X/* Contains move commands */
X
Xchar    sdir[] = "hjklyubn";
Xshort   xdir[8] = {
X	-1, 0, 0, 1, -1, 1, -1, 1
X}      ,
X        ydir[8] = {
X	0, 1, -1, 0, -1, -1, 1, 1
X};
X
Xmovecm (cmd)
Xregister char  *cmd;
X{
X	register char  *dp;
X
X	if (!(dp = index (sdir, *cmd)))
X		return 0;
X	dx = xdir[dp - sdir];
X	dy = ydir[dp - sdir];
X	return 1;
X}
X
X
Xdomove () {
X	char    nx, ny, tmpx, tmpy, let;
X	register        MONSTER mtmp;
X	register        PART * tmpr, *ust;
X	GOLD_TRAP gold, trap, gtm1;
X	OBJECT otmp, obj;
X
X	if (u.uswallow) {
X		nx = u.ux;
X		ny = u.uy;
X		goto M;
X	}
X /*  n<letter> is used for u.u<letter> + d<letter>  */
X	if (u.uconfused) {
X		do {
X			dx = rn2 (3);
X			dy = rn2 (3);
X			dx--;
X			dy--;
X			tmpr = &levl[u.ux + dx][u.uy + dy];
X		}
X		while ((!dx && !dy) || tmpr -> typ < DOOR);
X	}
X	else
X		tmpr = &levl[u.ux + dx][u.uy + dy];
X	ust = &levl[u.ux][u.uy];
X	tmpx = u.ux;
X	tmpy = u.uy;
X	nx = u.ux + dx;
X	ny = u.uy + dy;
X	if (trap = g_at (nx, ny, ftrap)) {
X		if (trap -> gflag == MIMIC) {
X			nomul (0);
X			pline ("The door is actually a mimic.");
X			deltrap (trap);
X			if (makemon (PM_MIMIC)) {
X				newsym (nx, ny);
X				return;
X			}
X			if (m_at (nx, ny))
X				mnexto (fmon);
X			else {
X				fmon -> mx = nx;
X				fmon -> my = ny;
X			}
X			if (!u.ustuck)
X				u.ustuck = fmon;
X			pmon (fmon);
X			return;
X		}
X		if (trap -> gflag & SEEN)
X			nomul (0);
X	}
X	if (u.ustuck && (nx != u.ustuck -> mx || ny != u.ustuck -> my)) {
X		pseebl ("You cannot escape from %s!",
X				u.ustuck -> data -> mname);
X		nomul (0);
X		return;
X	}
XM: 
X	if (mtmp = m_at (nx, ny)) {
X/* Attack monster */
X		char    tmp;
X		register        MONSTDATA mdat = mtmp -> data;
X
X		tmp = u.ulevel - 1 + mdat -> ac + abon ();
X		if (uwep) {
X			tmp += uwep -> spe;
X			if (uwep -> otyp == W_TWOH_SWORD)
X				tmp--;
X			else if (uwep -> otyp == W_DAGGER)
X				tmp += 2;
X			else if (uwep -> otyp == W_SPEAR && index ("XDne",
X						mdat -> mlet))
X				tmp += 2;
X		}
X		if (mtmp -> msleep) {
X			mtmp -> msleep = 0;
X			tmp += 2;
X		}
X		if (mtmp -> mfroz) {
X			tmp += 4;
X			if (!rn2 (10))
X				mtmp -> mfroz = 0;
X		}
X		if (mtmp -> mflee)
X			tmp += 2;
X		if (u.utrap)
X			tmp -= 3;
X		if (mtmp == shopkeeper)
X			setangry ();
X		if (tmp < rnd (20) && !u.uswallow)
X			pseebl (UMISS, mdat -> mname);
X		else {
X/* We hit the monster; but: it might die! */
X
X			if (hmon (mtmp, uwep)) {
X			/* 0-destroy,1-hit */
X				if (!u.uswallow && !rn2 (25) &&
X						mtmp -> mhp < mtmp -> orig_hp >> 1) {
X/* You might be stucked at this point ! { FRED } */
X					if (mtmp == u.ustuck)
X						unstuck (mtmp);
X					mtmp -> mflee = 1;
X				}
X				pseebl ("You hit %s!", mdat -> mname);
X				if (u.umconf && !u.uswallow) {/* a3 */
X					if (!u.ublind) {
X						pline (STOPGLOW);
X						pseebl ("The %s appears confused.", mdat -> mname);
X					}
X					mtmp -> mconf = 1;
X					u.umconf = 0;
X				}
X				if (mtmp -> wormno)
X					cutworm (mtmp, nx, ny,
X							uwep -> otyp);
X				switch (mdat -> mlet) {
X
X					case 'a': 
X						if (rn2 (2)) {
X							pline ("You are splashed by the blob's acid!");
X							losehp (rnd (6), mdat -> mname);
X						}
X						if (!rn2 (6) && uwep) {
X							pline ("Your %s corrodes!",
X									weapons[uwep -> otyp].wepnam);
X							--uwep -> spe;
X						}
X						break;
X
X					case 'E': 
X						if (!u.ublind && rn2 (2)) {
X							pline ("You are frozen by the floating eye's gaze!");
X							nomul (rn1 (20, -20));
X							return;
X						}
X						break;
X				}
X			}
X		}
X		nomul (0);
X		return;
X	}
X
X/* Not attacking an animal, so we try to move  */
X	if (u.utrap) {
X		pline ((u.upit) ? "You are still in a pit." :
X				"You are caught in a beartrap.");
X		if (u.upit || (dx && dy) || !rn2 (5))
X			u.utrap--;
X		return;
X	}
X	if ((dx && dy && (tmpr -> typ == DOOR || ust -> typ == DOOR)) ||
X			tmpr -> typ < DOOR || tmpr -> typ == VAULT) {
X	/* 0, WALL, or SDOOR */
X		flags.move = 0;
X		nomul (0);
X		return;
X	}
X	u.ux = nx;		/* u.ux+=dx; u.uy+=dy; */
X	u.uy = ny;
X	nx += dx;
X	ny += dy;
X	if (flags.run)
X		if (tmpr -> typ == DOOR ||
X				(xupstair == u.ux && yupstair == u.uy) ||
X				(xdnstair == u.ux && ydnstair == u.uy))
X			nomul (0);
X	if (tmpr -> typ >= 30 && tmpr -> typ <= 41) {
X		for (otmp = invent; otmp; otmp = otmp -> nobj) {
X			if (otmp -> otyp == tmpr -> typ && otmp -> olet == '_') {
X				pline ("The door opens.");
X				doname (otmp, buf);
X				pline ("The %s vanishes.", buf);
X				useup (otmp);
X				tmpr -> typ = DOOR;
X				break;
X			}
X		}
X		if (!otmp) {
X			if (rn2 (2))
X				pline ("The door is locked!");
X			else
X				pline ("You cannot unlock the door!");
X			u.ux -= dx;
X			u.uy -= dy;
X			return;
X		}
X	}
X	if (ust -> scrsym == '@') {
X		newsym (tmpx, tmpy);
X		oldux = tmpx;
X		olduy = tmpy;
X	}
X	if (!u.ublind) {
X		if (ust -> lit) {
X			if (tmpr -> lit) {
X				if (tmpr -> typ == DOOR)
X					prl1 (nx, ny);
X				if (ust -> typ == DOOR)
X					nose1 (tmpx - dx, tmpy - dy);
X			}
X			else {
X				unCoff (UNC, 1);
X				prl1 (nx, ny);
X			}
X		}
X		else {
X			if (tmpr -> lit)
X				setCon (SETC);
X			else {
X				prl1 (nx, ny);
X				if (tmpr -> typ == DOOR) {
X					if (dy) {
X						prl (u.ux - 1, u.uy);
X						prl (u.ux + 1, u.uy);
X					}
X					else {
X						prl (u.ux, u.uy - 1);
X						prl (u.ux, u.uy + 1);
X					}
X				}
X			}
X			nose1 (tmpx - dx, tmpy - dy);
X		}
X	}
X	else
X		newunseen (tmpx, tmpy);
X	if (!multi)
X		pru ();
X	while (gold = g_at (u.ux, u.uy, fgold)) {
X		if (!gold -> gflag) {
X			pline ("The chest was a mimic!");
X			if (!makemon (PM_MIMIC)) {
X				mnexto (fmon);
X				u.ustuck = fmon;
X			}
X			nomul (0);
X		}
X		else {
X			if (u.uhcursed) {
X				pline ("You cannot pick up the gold!");
X				break;
X			}
X			if (gold -> gflag == 1)
X				gold -> gflag++;/* a3 */
X			pline ("%u gold pieces", gold -> gflag);
X			u.ugold += gold -> gflag;
X			flags.dgold = 1;
X		}
X		if (gold == fgold)
X			fgold = fgold -> ngen;
X		else {
X			for (gtm1 = fgold; gtm1 -> ngen != gold;
X					gtm1 = gtm1 -> ngen);
X			gtm1 -> ngen = gold -> ngen;
X		}
X		free (gold);
X		if (flags.run)
X			nomul (0);
X		if (u.uinvis)
X			newsym (u.ux, u.uy);
X	}
X	while (obj = o_at (u.ux, u.uy)) {
X		for (otmp = invent, let = 0; otmp; otmp = otmp -> nobj)
X			let += weight (otmp);
X		let += weight (obj);
X		if (let > 85) {
X			pline ("You can't carry anything more.");
X			if (flags.run)
X				nomul (0);
X			break;
X		}
X		if (let > 80)
X			pline ("You have a little trouble lifting");
X		if (!(obj -> cursed))
X			obj -> cursed = u.uhcursed;
X		freeobj (obj);
X		addtobill (obj);/* Sets obj->unpaid if necessary */
X		prinv (addinv (obj));
X	/* Might merge it with other objects */
X		if (u.uinvis)
X			newsym (u.ux, u.uy);
X		if (flags.run)
X			nomul (0);
X	}
X	if (trap) {
X		nomul (0);
X		if (trap -> gflag & SEEN && !rn2 (5))
X			pline ("You escape a%s.",
X					traps[trap -> gflag & 037]);
X		else {
X			trap -> gflag |= SEEN;
X			switch (((trap -> gflag) & 037)) {
X
X				case SLPTRP: 
X					pline ("A cloud of gas puts you to sleep!");
X					nomul (-rnd (25));
X					break;
X
X				case BEAR: 
X					u.utrap = rn1 (4, 4);
X					u.upit = 0;
X					pline ("A bear trap closes on your foot!");
X					break;
X
X				case PIERC: 
X					pline ("A piercer suddenly drops from the ceiling!");
X					deltrap (trap);
X					if (!makemon (PM_PIERC)) {
X						mnexto (fmon);
X						hitu (3, d (4, 6),
X								"falling piercer");
X					}
X					break;
X
X				case ARROW: 
X					pline ("An arrow shoots out at you!");
X					hitu (8, rnd (6), "arrow");
X					break;
X
X				case TDOOR: 
X					if (!xdnstair) {
X						pline ("A trap door in the ceiling opens and a rock falls on your head!");
X						losehp (d (2, 10),
X								"falling rock");
X						break;
X					}
X					pline ("A trap door opens up under you!");
X					if (u.ufloat || u.ustuck) {
X						pline ("For some reason you don't fall in.");
X						break;
X					}
X					more ();
X					keepdogs (1);
X					unCoff (COFF, 1);
X					do {
X						dosavelev ();
X						dodown ();
X						levl[u.ux][u.uy].scrsym = '<';
X					} while (!rn2 (4) && xdnstair);
X					land ();
X					losedogs ();
X					setCon (CON);
X					inshop ();/* a3:zie tele */
X					break;
X
X				case DART: 
X					pline ("A little dart shoots out at you!");
X					if (hitu (7, rnd (3), "little dart") &&
X							!rn2 (6))
X						poisoned ("dart", "poison dart");
X					break;
X
X				case TELE: 
X					newsym (u.ux, u.uy);
X					tele ();
X					break;
X
X				case PIT: 
X					if (u.ufloat) {
X						pline ("A pit opens up under you!");
X						pline ("You don't fall in!");
X						break;
X					}
X					pline ("You fall into a pit!");
X					u.utrap = rn1 (6, 2);
X					u.upit = 1;
X					losehp (rnd (6), "pit");
X					break;
X
X				default: 
X					pline ("Bad(%d)trap", trap -> gflag);
X					impossible ();
X			}
X		}
X	}
X	if (tmpr -> typ == DOOR && dlevel) {
X		inshop ();
X		switch (rooms[inroom (u.ux, u.uy)].rtype) {
X			case ZOO: 
X				if (!u.uinzoo) {
X					pline ("Welcome to the Zoo!");
X					u.uinzoo++;
X				}
X				break;
X			case GRAVEYARD: 
X				if (!u.uinyard) {
X					pline ("Welcome to the Graveyard!");
X					u.uinyard++;
X				}
X				break;
X			case SWAMP: 
X				if (!u.uinswamp) {
X					pline ("Welcome to the Swamp!");
X					u.uinswamp++;
X				}
X				break;
X			case FORT_KNOX: 
X				if (!u.uinknox) {
X					pline ("Welcome to Fort Knox!");
X					u.uinknox++;
X				}
X				break;
X			default: 
X				break;/* Who knows what more may come */
X		}
X	}
X	if (tmpr -> typ == CORR) {
X		if (u.uinshop)
X			inshop ();/* Outside shop now */
X		u.uinzoo = 0;	/* You left the Zoo ?? */
X		u.uinyard = 0;	/* You left the Graveyard ?? */
X		u.uinswamp = 0;	/* You left the Swamp ?? */
X		u.uinknox = 0;	/* You left Fort Knox ?? */
X	}
X	if (tmpr -> typ == POOL)
X		if (!u.ufloat) {
X			pline ("You fall into a pool!");
X			pline ("You can't swim!");
X			pline ("You drown...");
X			more ();
X			killer = "Pool of water";
X			done (DROWNED);
X		}
X}
X
X/* Stop running if we see something interesting */
Xlookaround () {
X	register        x, y, corrct = 0;
X	register        MONSTER mtmp;
X
X	if (u.ublind || flags.run < 2)
X		return;
X	for (x = u.ux - 1; x <= u.ux + 1; x++)
X		for (y = u.uy - 1; y <= u.uy + 1; y++) {
X			if (x == u.ux && y == u.uy)
X				continue;
X/* Note: we cannot call r_free: perhaps a M is hidden in the wall */
X			if (!levl[x][y].typ)
X				continue;
X			if (mtmp = m_at (x, y))
X				if (!mtmp -> mtame || (x == u.ux + dx &&
X							y == u.uy + dy)) {
X					nomul (0);
X					return;
X				}
X			if (x == u.ux - dx && y == u.uy - dy)
X				continue;
X			if (mtmp)
X				corrct++;
X			else
X				switch (levl[x][y].scrsym) {
X					case '+': 
X						if (x == u.ux || y == u.uy) {
X							nomul (0);
X							return;
X						}
X					case '0': 
X						multi = 0;
X						flags.run = 0;
X						return;
X					case '.': 
X					case '|': 
X					case '-': 
X						break;
X					case '#': 
X						corrct++;
X						break;
X					default: 
X						nomul (0);
X						return;
X				}
X		}
X	if (corrct > 1 && flags.run == 2)
X		nomul (0);
X}
X
Xnomul (nval)
Xregister        nval;
X{
X	if (multi < 0)
X		return;
X	if (flags.mv)
X		pru ();
X	multi = nval;
X	flags.mv = 0;
X	flags.run = 0;
X}
X
Xchar   *
X        parse () {
X	static char     inline[80];
X	register        foo;
X
X	oldux = 0;
X	olduy = 0;
X	flags.move = 1;
X	if (!u.uinvis)
X		curs (u.ux, u.uy + 2);
X	else
X		home ();
X	flush ();
X	while ((foo = getchar ()) >= '0' && foo <= '9')
X		multi += 10 * multi + foo - '0';
X	if (multi) {
X		multi--;
X		save_cm = inline;
X	}
X	inline[0] = foo;
X	inline[1] = 0;
X	if (foo == 'f' || foo == 'F') {
X		inline[1] = getchar ();
X		inline[2] = 0;
X	}
X	if (flags.topl) {
X		home ();
X		cl_end ();
X		flags.topl = 0;
X	}
X	return (inline);
X}
X
Xnomove () {
X	multi = 0;
X	flags.move = 0;
X}
/
echo 'x - hack.shk.c'
sed 's/^X//' > hack.shk.c << '/'
X/*
X * Hack.shk.c
X */
X
X#include "hack.h"
X
X#define BILLSZ  200
X#define ONBILL    1
X#define NOTONBILL 0
X#define GDIST(x, y)     ((x - gx)*(x - gx) + (y - gy)*(y - gy) )
X
Xstruct {
X	OBJECT op;
Xunsigned        useup:                 1;
Xunsigned        bquan:                 5;
X	unsigned        price;
X}       bill[BILLSZ];
X
XMONSTER shopkeeper;
X
Xstruct permonst shk_pm = {
X	"shopkeeper", '@', 10, 12, 0, 4, 8, 0
X};
X
Xlong    robbed = 0, total;
X
X/*
X * shoproom = index in rooms; set by inshop()
X * shlevel  = last level we initialized shopkeeper
X */
X
Xchar    billct = 0, shoproom, shlevel;
Xchar   *shopnam[] = {
X	"engagement ring", "walking cane", "antique weapon",
X	"delicatessen", "second hand book", "liquor",
X	"used armor", "assorted antiques"
X};
X
XCOORDINATES shk, shd;
X /* Usual position shopkeeper;position shop door */
X
X#define SHOP_NAME               shopnam[rooms[shoproom].rtype - 8]
X
Xshkdead () {
X	shopkeeper = 0;
X	rooms[shoproom].rtype = 0;
X	setpaid ();
X}
X
Xsetpaid () {
X	register        tmp;
X	register        OBJECT obj;
X
X	for (obj = invent; obj; obj = obj -> nobj)
X		obj -> unpaid = 0;
X	for (tmp = 0; tmp < billct; tmp++)
X		if (bill[tmp].useup)
X			ofree (bill[tmp].op);
X	billct = 0;
X}
X
Xaddupbill () {			/* Delivers result in total */
X	register        ct = billct;
X
X	total = 0;
X	while (ct--)
X		total += bill[ct].price;
X}
X
Xinshproom (x, y)
Xregister        x, y;		/* a3 */
X{
X	return (inroom (x, y) == shoproom);
X}
X
Xinshop () {
X	register        tmp = inroom (u.ux, u.uy);
X
X	if (tmp < 0 || rooms[tmp].rtype < 8) {
X		u.uinshop = 0;
X		if (billct) {
X			pline ("Somehow you escaped the shop without paying!");
X			addupbill ();
X			pline ("You stole for a total worth of %U zorkmids.", total);
X			robbed += total;
X			setpaid ();
X		}
X	}
X	else {
X		shoproom = tmp;
X		if (shlevel != dlevel)
X			shopinit ();
X		if (!u.uinshop) {
X			pline ("%s to Dirk's %s shop!",
X					(shopkeeper -> angry) ?
X					"You're not that welcome" : "Welcome",
X					SHOP_NAME);
X			++u.uinshop;
X		}
X	}
X	return (u.uinshop);
X}
X
X/* Called by useup and dothrow only */
Xonbill (obj)
Xregister        OBJECT obj;
X{
X	register        tmp;
X
X	for (tmp = 0; tmp < billct; tmp++)
X		if (bill[tmp].op == obj) {
X			bill[tmp].useup = 1;
X			obj -> unpaid = 0;/* only for doinvbill */
X			return (ONBILL);
X		}
X	return (NOTONBILL);
X}
X
Xdopay () {
X	register unsigned       tmp;
X	char    buffer[BUFSZ];
X
X	multi = 0;
X	if (!inshop ()) {
X		flags.move = 0;
X		pline ("You are not in a shop.");
X		return;
X	}
X
X	if (!shopkeeper || !inshproom (shopkeeper -> mx,
X				shopkeeper -> my)) {
X		pline ("There is nobody here to receive your payment.");
X		return;
X	}
X	if (!billct) {
X		pline ("You do not owe the shopkeeper anything.");
X		if (!u.ugold) {
X			pline ("Moreover, you have no money.");
X			return;
X		}
X		if (robbed) {
X			pline ("But since the shop has been robbed recently");
X			pline ("You %srepay the shopkeeper's expenses.", (u.ugold < robbed) ?
X					"partially " : "");
X			u.ugold -= robbed;
X			if (u.ugold < 0)
X				u.ugold = 0;
X			flags.dgold = 1;
X			robbed = 0;
X			return;
X		}
X		if (shopkeeper -> angry) {
X			pline ("But in order to appease the angry shopkeeper,");
X			if (u.ugold >= 1000L) {
X				tmp = 1000;
X				pline ("You give him 1000 gold pieces.");
X			}
X			else {
X				tmp = (int) u.ugold;
X				pline ("You give him all your money.");
X			}
X			u.ugold -= (long) tmp;
X			flags.dgold = 1;
X			if (rn2 (3)) {
X				pline ("The shopkeeper calms down.");
X				shopkeeper -> angry = 0;
X			}
X			else
X				pline ("The shopkeeper is as angry as ever.");
X		}
X		return;
X	}
X
X	while (billct) {
X		billct--;
X		bill[billct].op -> unpaid = 0;
X		doname (bill[billct].op, buffer);
X		tmp = bill[billct].price;
X		if (shopkeeper -> angry)
X			tmp += tmp / 3;
X		if (u.ugold < tmp) {
X			++bill[billct].op -> unpaid;
X			billct++;
X			pline ("You don't have gold enough to pay %s.",
X					buffer);
X			return;
X		}
X		u.ugold -= tmp;
X		flags.dgold = 1;
X		pline ("You bought %s for %d gold pieces.", buffer, tmp);
X		if (bill[billct].useup)
X			ofree (bill[billct].op);
X	}
X	pline ("Thank you for shopping in Dirk's %s store!",
X			SHOP_NAME);
X	shopkeeper -> angry = 0;
X}
X
Xpaybill () {			/* Called after dying (or quitting) with
X				   nonempty bill */
X	if (shopkeeper) {
X		addupbill ();
X		if (total > u.ugold) {
X			u.ugold = 0;
X			if (invent)
X				pline ("The shopkeeper comes and takes all your possessions.");
X		}
X		else {
X			u.ugold -= total;
X			pline ("The shopkeeper comes and takes the %D zorkmids you owed him.",
X					total);
X		}
X	}
X	more ();
X}
X
Xaddtobill (obj)
Xregister        OBJECT obj;
X{
X	if (!inshop ())
X		return;
X	if (billct == BILLSZ) {
X		pline ("You got that for free!");
X		return;
X	}
X	bill[billct].op = obj;
X	bill[billct].bquan = obj -> quan;
X	bill[billct].useup = 0;
X	bill[billct++].price = getprice (obj);
X	obj -> unpaid = 1;
X}
X
Xsubfrombill (obj)
Xregister        OBJECT obj;
X{
X	register        tmp;
X	register        OBJECT otmp;
X
X	if (!inshop ())
X		return;
X	for (tmp = 0; tmp < billct; tmp++)
X		if (bill[tmp].op == obj) {
X			obj -> unpaid = 0;
X			if (bill[tmp].bquan != obj -> quan) {
X				bill[tmp].op = otmp = newobj ();
X				*otmp = *obj;
X				otmp -> quan = (bill[tmp].bquan -=
X						obj -> quan);
X				bill[tmp].price *= otmp -> quan;
X				bill[tmp].price /= (otmp -> quan +
X						obj -> quan);
X				bill[tmp].useup = 1;
X				return;
X			}
X			billct--;
X			bill[tmp] = bill[billct];
X			return;
X		}
X/* I dropped something of my own, wanting to sell it */
X	if (shopkeeper -> msleep || shopkeeper -> mfroz ||
X			!inshproom (shopkeeper -> mx, shopkeeper -> my) ||
X			robbed || u.ux == shk.x && u.uy == shk.y ||
X			u.ux == shd.x && u.uy == shd.y)
X		return;
X	tmp = getprice (obj);
X	if (shopkeeper -> angry) {
X		tmp /= 3;
X		shopkeeper -> angry = 0;
X	}
X	else
X		tmp >>= 1;
X	if (tmp < 2)
X		tmp = 2;
X	u.ugold += tmp;
X	flags.dgold = 1;
X	doname (obj, buf);
X	pline ("You sold %s and got %d gold pieces.", buf, tmp);
X}
X
Xdoinvbill () {
X	register unsigned       tmp, cnt = 0;
X
X	for (tmp = 0; tmp < billct; tmp++)
X		if (bill[tmp].useup) {
X			if (!cnt && !flags.oneline) {
X				getret ();
X				cls ();
X				printf ("\n\nUnpaid articles already used up:\n\n");
X			}
X			strcpy (buf, "* -  ");
X			doname (bill[tmp].op, &buf[5]);
X			for (cnt = 0; buf[cnt]; cnt++);
X			while (cnt < 50)
X				buf[cnt++] = ' ';
X			sprintf (&buf[cnt], " %5d zorkmids",
X					bill[tmp].price);
X			if (flags.oneline)
X				pline (buf);
X			else
X				printf ("%s\n", buf);
X			if (!cnt % 20)
X				getret ();
X		}
X}
X
Xgetprice (obj)
Xregister        OBJECT obj;
X{
X	register        tmp, ac;
X
X	switch (obj -> olet) {
X		case '"': 
X			tmp = rnd (500);
X			break;
X		case '=': 
X		case '/': 
X			tmp = rnd (100);
X			break;
X		case '?': 
X		case '!': 
X			tmp = rnd (50);
X			break;
X		case '*': 
X			tmp = rnd (6);
X			break;
X		case '%': 
X			tmp = rnd (5 + 2000 / realhunger ());
X			break;
X		case '[': 
X			ac = obj -> spe;
X			tmp = (100 + ac * ac * rnd (10 + ac)) / 10;
X			break;
X		case ')': 
X			if (obj -> otyp <= W_AMMUNITION)
X				tmp = rnd (10);
X			else if (obj -> otyp == W_LONG_SWORD || obj -> otyp ==
X					W_TWOH_SWORD)
X				tmp = rnd (150);
X			else
X				tmp = rnd (75);
X			break;
X		case '_': 
X		default: 
X			tmp = 1000;
X	}
X	return (10 * obj -> quan * tmp);
X}
X
Xrealhunger () {			/* not completely foolproof (??) */
X	register        tmp = u.uhunger;
X	register        OBJECT otmp = invent;
X
X	while (otmp) {
X		if (otmp -> olet == '%' && !otmp -> unpaid)
X			tmp += foods[otmp -> otyp].nutrition;
X		otmp = otmp -> nobj;
X	}
X	return tmp;
X}
X
Xshopinit () {
X	register        MKROOM * sroom = &rooms[shoproom];
X	register        i, j, x, y;
X
X	shlevel = dlevel;
X	shd = doors[sroom -> fdoor];
X	shk.x = shd.x;
X	shk.y = shd.y;
X	if (shk.x == sroom -> lx - 1)
X		shk.x++;
X	else if (shk.x == sroom -> hx + 1)
X		shk.x--;
X	else if (shk.y == sroom -> ly - 1)
X		shk.y++;
X	else if (shk.y == sroom -> hy + 1)
X		shk.y--;
X	else {
X		sroom -> rtype = 0;
X		pline ("Where is shopdoor?");
X		impossible ();
X		return;
X	}
X	if (shopkeeper)
X		return;		/* We have been on this level before */
X	if (makemon (&shk_pm))
X		panic (CORE, "Cannot create shopkeeper?");
X	shopkeeper = fmon;
X	shopkeeper -> angry = u.uhcursed;
X	if (m_at (shk.x, shk.y) || (shk.x == u.ux && shk.y == u.uy)) {
X	/* (a3)`mnexto(shopkeeper)' is fout gaan */
X		prl (shk.x, shk.y);
X		for (i = -1; i < 2; i++)
X			for (j = -1; j < 2; j++)
X				if (levl[x = shk.x + i][y = shk.y + j].typ ==
X						ROOM)
X					if (!m_at (x, y)) {
X						fmon -> mx = x;
X						fmon -> my = y;
X						pmon (shopkeeper);
X						return;
X					}
X		fmon -> mx = shk.x;
X		fmon -> my = shk.y;
X		return;		/* bovenop een ander monster */
X	}
X	else {
X		fmon -> mx = shk.x;
X		fmon -> my = shk.y;
X	}
X	pmon (shopkeeper);
X}
X
Xsetangry () {
X	if (shopkeeper -> data -> mlet == '@' && !shopkeeper -> angry) {
X		pline ("The shopkeeper gets angry.");
X		++shopkeeper -> angry;
X	}
X}
X
Xshk_move () {
X	register        MONSTER mtmp;
X	char    gx, gy, omx, omy, cnt, appr,
X	        nix, niy, ddx, ddy, zx, zy, num;
X
X	omx = shopkeeper -> mx;
X	omy = shopkeeper -> my;
X	if (!u.uinshop && inshproom (omx, omy) &&
X			levl[omx][omy].typ == ROOM)
X		return NOMOVE;
X	if (shopkeeper -> angry && dist (omx, omy) < 3) {
X		hitu (shk_pm.mhd, d (shk_pm.damn, shk_pm.damd),
X				shk_pm.mname);
X		return NOMOVE;
X	}
X	appr = 1;
X	if ((shopkeeper -> angry) && !u.uinvis) {
X		gx = u.ux;	/* Fred */
X		gy = u.uy;
X	}
X	else if (shk.x == omx && shk.y == omy && !billct &&
X				!shopkeeper -> angry &&
X				(!robbed || (u.ux == shd.x && u.uy == shd.y)) &&
X			dist (omx, omy) < 3) {
X		appr = 0;
X		gx = 0;
X		gy = 0;
X	}
X	else {
X		gx = shk.x;
X		gy = shk.y;
X	}
X	cnt = 0;
X	if (omx == gx && omy == gy)
X		return NOMOVE;
X	if (shopkeeper -> mconf)
X		appr = 0;
X	nix = omx;
X	niy = omy;
X	for (ddx = -1; ddx <= 1; ddx++)
X		for (ddy = -1; ddy <= 1; ddy++) {
X			zx = omx + ddx;
X			zy = omy + ddy;
X			num = levl[zx][zy].typ;/* a3 */
X			if ((ddx || ddy) && (num == ROOM || !inshproom (omx, omy)
X						&& (num == CORR || num == DOOR)) &&
X					(shopkeeper -> mconf ||
X						((zx != u.ux || zy != u.uy) && !m_at (zx, zy))) &&
X					(!appr && !rn2 (++cnt) || appr && GDIST (zx, zy) <
X						GDIST (nix, niy))) {
X				nix = zx;
X				niy = zy;
X			}
X		}
X	if (nix != omx || niy != omy) {
X		if (shopkeeper -> mconf && (mtmp = m_at (nix, niy))) {
X			if (hitmm (shopkeeper, mtmp) == 1 && rn2 (3)
X					&& hitmm (mtmp, shopkeeper) == DEAD)
X				return DEAD;
X			return NOMOVE;
X		}
X		shopkeeper -> mx = nix;
X		shopkeeper -> my = niy;
X/* The shopkeeper might have been turned into an X */
X		levlsym (omx, omy, shopkeeper -> data -> mlet);
X		pmon (shopkeeper);
X		return MOVE;
X	}
X	return NOMOVE;
X}
/
echo 'x - mklev.svlev.c'
sed 's/^X//' > mklev.svlev.c << '/'
X/*
X * Mklev.savelev.c
X */
X
Xsavelev () {
X	register int    fd;
X	register        MONSTER mtmp, mtmp2;
X	register        GOLD_TRAP gtmp, gtmp2;
X	register        OBJECT otmp, otmp2;
X	int     minusone = -1;
X
X	if ((fd = creat (tfile, 0644)) < 0)
X		panic ("Cannot create %s\n", tfile);
X	bwrite (fd, levl, sizeof (levl));
X	bwrite (fd, nul, sizeof (unsigned));
X	bwrite (fd, (char *) & xupstair, 1);
X	bwrite (fd, (char *) & yupstair, 1);
X	bwrite (fd, (char *) & xdnstair, 1);
X	bwrite (fd, (char *) & ydnstair, 1);
X	for (mtmp = fmon; mtmp; mtmp = mtmp2) {
X		mtmp2 = mtmp -> nmon;
X		bwrite (fd, &mtmp -> mxlth, sizeof (int));
X		bwrite (fd, mtmp, mtmp -> mxlth + sizeof (struct monst));
X
X/* Michiel save stolen objects */
X		bwrite (fd, nul, sizeof (struct stole));
X	}
X	bwrite (fd, &minusone, sizeof (int));
X	for (gtmp = fgold; gtmp; gtmp = gtmp2) {
X		gtmp2 = gtmp -> ngen;
X		bwrite (fd, gtmp, sizeof (struct gen));
X		free (gtmp);
X	}
X	bwrite (fd, nul, sizeof (struct gen));
X	for (gtmp = ftrap; gtmp; gtmp = gtmp2) {
X		gtmp2 = gtmp -> ngen;
X		bwrite (fd, gtmp, sizeof (struct gen));
X		free (gtmp);
X	}
X	bwrite (fd, nul, sizeof (struct gen));
X	for (otmp = fobj; otmp; otmp = otmp2) {
X		otmp2 = otmp -> nobj;
X		bwrite (fd, otmp, sizeof (struct obj));
X		free (otmp);
X	}
X	bwrite (fd, nul, sizeof (struct obj));
X	bwrite (fd, rooms, sizeof (rooms));
X	bwrite (fd, doors, sizeof (doors));
X	fgold = TRAP_NULL;
X	ftrap = TRAP_NULL;
X	fmon = MON_NULL;
X	fobj = OBJ_NULL;
X}
X
X/*NOSTRICT*/
Xbwrite (fd, loc, num)
Xregister int    fd, num;
Xregister char  *loc;
X{
X	if (write (fd, loc, num) != num)
X		panic ("Cannot write %d bytes to file #%d", num, fd);
X}
/
echo 'Part 02 of Hack complete.'
exit
-- 

			Michiel Huisjes.
			{seismo|decvax|philabs}!mcvax!vu44!ark!huisjes



More information about the Comp.sources.unix mailing list