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

Michiel B. Huisjes huisjes at ark.UUCP
Wed Feb 6 16:48:51 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 03 of 05:'
echo 'x - hack.c'
sed 's/^X//' > hack.c << '/'
X/*
X * Hack.c
X */
X
X#include "hack.h"
X
Xextern char     news0 (), *setan ();
X
Xextern char     seelx, seehx, seely, seehy;/* Corners of lit room */
X /* l for Low, h for High */
X
X#define CANSEE 		1
X#define CANNOTSEE 	0
X#define HITYOU		1
X#define MISSYOU		0
X#define MONALIVE	1
X#define MONDEAD		0
X
X
Xchar   *
X        lowc (str)
Xregister char  *str;
X{
X	if (*str >= 'A' && *str <= 'Z')
X		*buf = *str + 'a' - 'A';
X	else
X		*buf = *str++;
X	buf[1] = 0;
X	return (buf);
X}
X
X/* (a3) mix van setsee() en seeon() */
XsetCon (setc) {			/* setc: 1-setsee, 0-seeon (we just went to a
X				   new level) */
X	register        x, y;
X	register        MONSTER mtmp;
X	int     lx, hx, ly, hy;
X
X	if (u.ublind) {
X		if (setc)
X			pru ();
X		else
X			docrt ();
X		return;
X	}
X	if (levl[u.ux][u.uy].lit) {
X		for (seelx = u.ux; levl[seelx - 1][u.uy].lit; seelx--);
X		for (seehx = u.ux; levl[seehx + 1][u.uy].lit; seehx++);
X		for (seely = u.uy; levl[u.ux][seely - 1].lit; seely--);
X		for (seehy = u.uy; levl[u.ux][seehy + 1].lit; seehy++);
X		lx = seelx;
X		hx = seehx;
X		ly = seely;
X		hy = seehy;
X	}
X	else {
X		seehx = 0;
X		lx = u.ux - 1;
X		hx = u.ux + 1;
X		ly = u.uy - 1;
X		hy = u.uy + 1;
X		if (setc) {
X			seelx = lx;
X			seehx = hx;
X			seely = ly;
X			seehy = hy;
X		}
X	}
X	for (x = lx; x <= hx; x++)
X		for (y = ly; y <= hy; y++) {
X			if (setc)
X				prl (x, y);
X			else {
X				if (!levl[u.ux][u.uy].lit &&
X						!levl[x][y].typ)
X					continue;
X				levl[x][y].seen = 1;
X				if (mtmp = m_at (x, y))
X					pmon (mtmp);
X			}
X		}
X	if (!setc) {
X		docrt ();
X		return;
X	}
X	if (!levl[u.ux][u.uy].lit)
X		seehx = 0;	/* Seems necessary elsewhere */
X	else {
X		if (seely == u.uy)
X			for (x = u.ux - 1; x <= u.ux + 1; x++)
X				prl (x, seely - 1);
X		if (seehy == u.uy)
X			for (x = u.ux - 1; x <= u.ux + 1; x++)
X				prl (x, seehy + 1);
X		if (seelx == u.ux)
X			for (y = u.uy - 1; y <= u.uy + 1; y++)
X				prl (seelx - 1, y);
X		if (seehx == u.ux)
X			for (y = u.uy - 1; y <= u.uy + 1; y++)
X				prl (seehx - 1, y);
X	}
X}
X
XunCoff (unc, mode) {
X /* 
X  * (a3) mix van unsee() en seeoff()
X  * unc: 1-unsee, 0-seeoff
X  * mode: 1-redo @ (misc movement),
X  * 0-leave them (blindness (Usually))
X  */
X
X	register        x, y;
X	register        PART * lev;
X	int     lx, hx, ly, hy;
X
X	if (seehx) {
X		lx = seelx;
X		hx = seehx;
X		ly = seely;
X		hy = seehy;
X	}
X	else {
X		lx = u.ux - 1;
X		hx = u.ux + 1;
X		ly = u.uy - 1;
X		hy = u.uy + 1;
X	}
X	for (x = lx; x <= hx; x++)
X		for (y = ly; y <= hy; y++) {
X			lev = &levl[x][y];
X			if (lev -> scrsym == '@' && mode) {
X				if (unc)
X					newsym (x, y);
X				else
X					lev -> scrsym = news0 (x, y);
X			}
X			else if (!seehx && lev -> scrsym == '.') {
X				if (mode) {
X					if (unc) {
X						lev -> scrsym = ' ';
X						lev -> new = 1;
X						on (x, y);
X					}
X				}
X				else
X					lev -> seen = 0;
X			}
X		}
X	seehx = 0;
X}
X
Xhitu (mlev, dam, name)
Xregister        mlev, dam;
Xregister char  *name;
X{
X	mlev += (u.uac - 1);
X	if (multi < 0)
X		mlev += 4;
X	if (u.uinvis)
X		mlev -= 2;
X	if (mlev < rnd (20)) {
X		pseebl ("%s misses", name);
X		return (MISSYOU);
X	}
X	pseebl ("%s hits!", name);
X	if (name == NULL)
X		impossible ();
X	losehp (dam, name);
X	return (HITYOU);
X}
X
Xcansee (x, y)
Xchar    x, y;
X{
X	if (u.ublind || u.uswallow)
X		return (CANNOTSEE);
X	if (dist (x, y) < 3)
X		return (CANSEE);
X	if (levl[x][y].lit && seelx <= x && x <= seehx && seely <= y &&
X			y <= seehy)
X		return (CANSEE);
X	return (CANNOTSEE);
X}
X
Xlong
X        pow (num)
Xregister        num;		/* Returns 2^num */
X{
X	return (1 << num);
X}
X
Xland () {			/* a3 */
X	do {
X		u.ux = rn2 (80);
X		u.uy = rn2 (22);
X	} while (levl[u.ux][u.uy].typ != ROOM || m_at (u.ux, u.uy));
X}
X
Xtele () {
X	unCoff (UNC, 0);	/* Dat was een 1 (a3) */
X	unstuck (u.ustuck);	/* a3 */
X	u.utrap = 0;
X	do
X		land ();
X	while (o_at (u.ux, u.uy) || g_at (u.ux, u.uy, ftrap) ||
X			g_at (u.ux, u.uy, fgold));
X	setCon (SETC);
X	inshop ();
X}
X
Xchar   *
X        sitoa (a)
Xregister int    a;
X{
X	static char     buffer[8];
X
X	sprintf (buffer, "+%d", a);
X	return ((a < 0) ? buffer + 1 : buffer);
X}
X
Xdoname (obj, buffer)
Xregister        OBJECT obj;
Xregister char  *buffer;
X{
X	switch (obj -> olet) {
X
X		case '"': 
X			strcpy (buffer, "The amulet of Frobozz");
X			break;
X
X		case '%': 
X			if (obj -> quan > 1)
X				sprintf (buffer, "%d %ss", obj -> quan,
X						foods[obj -> otyp].foodnam);
X			else
X				strcpy (buffer, setan (foods[obj -> otyp].foodnam));
X			break;
X
X		case ')': 
X			killer = weapons[obj -> otyp].wepnam;/* a3 */
X			if (obj -> known) {
X				if (obj -> quan > 1)
X					sprintf (buffer, "%d %s %ss", obj -> quan,
X							sitoa (obj -> spe), killer);
X				else
X					sprintf (buffer, "a %s %s", sitoa (obj -> spe),
X							killer);
X			}
X			else {
X				if (obj -> quan > 1)
X					sprintf (buffer, "%d %ss", obj -> quan,
X							killer);
X				else
X					strcpy (buffer, setan (killer));
X			}
X			if (obj == uwep)
X				strcat (buffer, " (weapon in hand)");
X			break;
X
X		case '[': 
X			if (obj -> known)
X				sprintf (buffer, "%s %s",
X						sitoa (obj -> spe - 10 + armors[obj -> otyp].a_ac),
X						armors[obj -> otyp].armnam);
X			else
X				strcpy (buffer, armors[obj -> otyp].armnam);
X			if (obj == uarm || obj == uarm2)
X				strcat (buffer, " (being worn)");
X			break;
X
X		case '!': 
X			if (oiden[obj -> otyp] & POTN || potcall[obj -> otyp]) {
X				if (obj -> quan > 1)
X					sprintf (buffer, "%d potions ", obj -> quan);
X				else
X					strcpy (buffer, "a potion ");
X				while (*buffer)
X					buffer++;
X				if (potcall[obj -> otyp])
X					sprintf (buffer, "called %s",
X							potcall[obj -> otyp]);
X				else
X					sprintf (buffer, "of %s",
X							pottyp[obj -> otyp]);
X			}
X			else {
X				killer = " potion";
X		P: 
X				if (obj -> quan > 1)
X					sprintf (buffer, "%d %s%ss", obj -> quan,
X							potcol[obj -> otyp], killer);
X				else
X					sprintf (buffer, "%s%s",
X							setan (potcol[obj -> otyp]),
X							killer);
X			}
X			break;
X
X		case '?': 
X			if (obj -> quan > 1)
X				sprintf (buffer, "%d scrolls ", obj -> quan);
X			else
X				strcpy (buffer, "a scroll ");
X			while (*buffer)
X				buffer++;
X			if (oiden[obj -> otyp] & SCRN)
X				sprintf (buffer, "of %s", scrtyp[obj -> otyp]);
X			else if (scrcall[obj -> otyp])
X				sprintf (buffer, "called %s", scrcall[obj -> otyp]);
X			else
X				sprintf (buffer, "labeled %s", scrnam[obj -> otyp]);
X			break;
X
X		case '/': 
X			if (oiden[obj -> otyp] & WANN)
X				sprintf (buffer, "a wand of %s", wantyp[obj -> otyp]);
X			else if (wandcall[obj -> otyp])
X				sprintf (buffer, "a wand called %s",
X						wandcall[obj -> otyp]);
X			else
X				sprintf (buffer, "%s wand",
X						setan (wannam[obj -> otyp]));
X			if (obj -> known) {
X				while (*buffer)
X					buffer++;
X				sprintf (buffer, " (%d)", obj -> spe);
X			}
X			break;
X
X		case '=': 
X			if (oiden[obj -> otyp] & RINN) {
X				if (obj -> known)
X					sprintf (buffer, "a %s ring of %s",
X							sitoa (obj -> spe),
X							ringtyp[obj -> otyp]);
X				else
X					sprintf (buffer, "a ring of %s",
X							ringtyp[obj -> otyp]);
X			}
X			else if (ringcall[obj -> otyp])
X				sprintf (buffer, "a ring called %s",
X						ringcall[obj -> otyp]);
X			else
X				sprintf (buffer, "%s ring",
X						setan (rinnam[obj -> otyp]));
X			if (obj == uright)
X				strcat (buffer, " (on right hand)");
X			if (obj == uleft)
X				strcat (buffer, " (on left hand)");
X			break;
X
X		case '*': 
X			killer = " gem";
X			goto P;
X
X		case '_': 
X			sprintf (buffer, "%s key",
X					setan (potcol[obj -> otyp - 30]));
X			break;
X
X		default: 
X			sprintf (buffer, "a%dglorkum %c(0%o)%d", obj -> otyp,
X					obj -> olet, obj -> olet, obj -> spe);
X	}
X	if (obj -> unpaid)
X		strcat (buffer, " (unpaid)");
X}
X
Xabon () {
X	if (u.ustr == 3)
X		return - 3;
X	if (u.ustr < 6)
X		return - 2;
X	if (u.ustr < 8)
X		return - 1;
X	if (u.ustr < 17)
X		return 0;
X	if (u.ustr < 69)
X		return 1;	/* up to 18/50 */
X	if (u.ustr < 118)
X		return 2;
X	return 3;
X}
X
Xdbon () {
X	if (u.ustr < 6)
X		return - 1;
X	if (u.ustr < 16)
X		return 0;
X	if (u.ustr < 18)
X		return 1;
X	if (u.ustr == 18)
X		return 2;	/* up to 18 */
X	if (u.ustr < 94)
X		return 3;	/* up to 18/75 */
X	if (u.ustr < 109)
X		return 4;	/* up to 18/90 */
X	if (u.ustr < 118)
X		return 5;	/* up to 18/99 */
X	return 6;		/* 18/00 */
X}
X
Xlosestr (num)
Xregister        num;
X{
X	u.ustr -= num;
X	while (u.ustr < 3) {
X		u.ustr++;
X		u.uhp -= 6;
X		u.uhpmax -= 6;
X		flags.dhp = flags.dhpmax = 1;
X	}
X	flags.dstr = 1;
X}
X
Xlosehp (n, knam)
Xregister        n;
Xchar   *knam;
X{
X	u.uhp -= n;
X	flags.dhp = 1;
X	if (u.uhp <= 0)
X		killer = knam;
X}
X
Xchar   *
X        setan (str)
Xregister char  *str;		/* a3 */
X{
X	static char     buffer[BUFSZ];
X
X	sprintf (buffer, "a%s %s", index ("aeiou", *str) ? "n" : "", str);
X	return buffer;
X}
X
Xweight (obj)
Xregister        OBJECT obj;
X{
X	switch (obj -> olet) {
X		case '"': 
X			return 2;
X		case '[': 
X			return 8;
X		case '%': 
X			if (obj -> otyp)/* Not a food ration */
X		case '*': 
X				return obj -> quan;
X		case '?': 
X			return (obj -> quan * 3);
X		case '!': 
X			return (obj -> quan << 1);
X		case ')': 
X			if (obj -> otyp == W_TWOH_SWORD)
X				return 4;
X			if (obj -> otyp <= W_AMMUNITION)/* darst arrows etc */
X				return (obj -> quan >> 1);
X		case '/': 
X			return 3;
X		case '_': 
X		case '=': 
X			return 1;
X		default: 
X			pline ("Weight: bad(%d) object 0%o.", obj -> otyp,
X					obj -> olet);
X			return 0;
X	}
X}
X
Xchar    mlarge[] = "bCDdegIlmnoPSsTUwY',&";
X
Xhmon (monst, obj)
Xregister        MONSTER monst;
Xregister        OBJECT obj;
X{
X	register        tmp;
X
X	if (!obj || obj == uwep && (obj -> otyp >= W_USE_AMMO ||
X				obj -> otyp <= W_AMMUNITION))
X		tmp = rnd (2);
X	else {
X		if (index (mlarge, monst -> data -> mlet)) {
X			tmp = rnd (weapons[obj -> otyp].wldam);
X			if (obj -> otyp == W_TWOH_SWORD)
X				tmp += d (2, 6);
X			else if (obj -> otyp == W_LONG_SWORD)
X				tmp += rnd (4);
X		}
X		else {
X			tmp = rnd (weapons[obj -> otyp].wsdam);
X			if (obj -> otyp == W_FLAIL || obj -> otyp == W_MACE)
X				tmp++;
X		}
X		tmp += obj -> spe;
X	}
X	tmp += u.udaminc + dbon ();
X	if (u.uswallow) {
X		if (monst -> data -> mlet == 'P')
X			tmp++;
X	}
X	else if (tmp <= 0)
X		tmp = 1;
X	monst -> mhp -= tmp;
X	return alive (monst);
X}
X
Xalive (monst)
Xregister        MONSTER monst;
X{
X	if (monst -> mhp > 0)
X		return (MONALIVE);
X	killed (monst);
X	return (MONDEAD);
X}
/
echo 'x - hack.dog.c'
sed 's/^X//' > hack.dog.c << '/'
X/*
X * Hack.dog.c
X */
X
X#include        "hack.h"
X#include        "hack.dog.h"
X
X#define UNDEF   127		/* Some large number */
X#define EDOG(mp)        ( (struct edog *)(&(mp->mextra[0])) )
X
Xextern struct permonst  li_dog, dog, la_dog;
X
Xchar    SADFEEL[] = "You have a sad feeling for a moment, then it passes";
X
Xmakedog () {
X	if (makemon (&li_dog))
X		return;		/* Dogs were genocided */
X	mnexto (fmon);
X	initedog (fmon);
X}
X
Xinitedog (mtmp)
Xregister        MONSTER mtmp;
X{
X	mtmp -> mtame = 1;
X	EDOG (mtmp) -> hungrytime = 1000 + moves;
X	EDOG (mtmp) -> eattime = 0;
X	EDOG (mtmp) -> droptime = 0;
X	EDOG (mtmp) -> dropdist = 10000;
X	EDOG (mtmp) -> apport = 10;
X	EDOG (mtmp) -> carry = 0;
X}
X
X/* Attach the monsters that went down (or up) together with @ */
X
XMONSTER mydogs = 0;
X
Xlosedogs () {
X	register        MONSTER mtmp;
X
X	while (mtmp = mydogs) {
X		mydogs = mtmp -> nmon;
X		mtmp -> nmon = fmon;
X		fmon = mtmp;
X		mnexto (mtmp);
X	}
X}
X
Xkeepdogs (checkdist)
Xint     checkdist;
X{
X	register        MONSTER mtmp;
X	register        PART * dr;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon)
X		if (mtmp -> mtame) {
X			if (checkdist && dist (mtmp -> mx, mtmp -> my) > 2) {
X				mtmp -> mtame = 0;/* Dog becomes wild */
X				mtmp -> mxlth = 0;
X				continue;
X			}
X			relmon (mtmp);
X			mtmp -> nmon = mydogs;
X			mydogs = mtmp;
X			dr = &levl[mtmp -> mx][mtmp -> my];
X			if (dr -> scrsym == mtmp -> data -> mlet)
X				dr -> scrsym = news0 (mtmp -> mx, mtmp -> my);
X		/* We destroyed the link, so use recursion */
X			keepdogs (checkdist);
X			return;	/* (admittedly somewhat primitive) */
X		}
X}
X
X#define GDIST(x, y) ((x - gx)*(x - gx) + (y - gy)*(y - gy) )
X#define DDIST(x, y) ((x - omx)*(x - omx) + (y - omy)*(y - omy) )
X
Xdog_move (mtmp, after)
Xregister        MONSTER mtmp;
X{
X	register        MONSTER mtmp2;
X	register struct edog   *edog = EDOG (mtmp);
X	int     nix, niy, omx, omy, appr, nearer, cnt, udist, zx, zy;
X	register        OBJECT obj;
X	register        GOLD_TRAP trap;
X	char    ddx, ddy, dogroom, uroom,
X	        gx = 0, gy = 0, gtyp;/* Current goal */
X
X	if (moves <= edog -> eattime)
X		return NOMOVE;	/* Dog is still eating */
X	omx = mtmp -> mx;
X	omy = mtmp -> my;
X	if (moves > edog -> hungrytime + 500 && !mtmp -> mconf) {
X		mtmp -> mconf = 1;
X		mtmp -> orig_hp /= 3;
X		if (mtmp -> mhp > mtmp -> orig_hp)
X			mtmp -> mhp = mtmp -> orig_hp;
X		psee (0, omx, omy, "%s is confused from hunger",
X				mtmp -> data -> mname);
X	}
X	else if (moves > edog -> hungrytime + 750 || mtmp -> mhp <= 0) {
X		if (!psee (0, omx, omy, "%s dies from hunger",
X					mtmp -> data -> mname))
X			pline (SADFEEL);
X		levlsym (omx, omy, mtmp -> data -> mlet);
X		delmon (mtmp);
X		return DEAD;
X	}
X	dogroom = inroom (omx, omy);
X	uroom = inroom (u.ux, u.uy);
X	udist = dist (omx, omy);
X
X/*
X * if we are carrying stg then we drop it (perhaps near @ )
X * Note: if apport == 1 then our behaviour is independent of udist
X */
X	if (edog -> carry) {
X		if (!rn2 (udist) || !rn2 (edog -> apport))
X			if (rn2 (10) < edog -> apport) {
X				relobj (mtmp);
X				if (edog -> apport > 1)
X					edog -> apport--;
X				edog -> carry = 0;
X			}
X	}
X	else {
X		if (obj = o_at (omx, omy))
X			if (rn2 (20) < edog -> apport + 3)
X				if (rn2 (udist) || !rn2 (edog -> apport)) {
X					edog -> carry = 1;
X					freeobj (obj);
X					levlsym (omx, omy, obj -> olet);
X					stlobj (mtmp, obj);
X				}
X	}
X
X/* First we look for food */
X	gtyp = UNDEF;		/* No goal as yet */
X	obj = fobj;
X	while (obj) {
X		if (obj -> olet == '%'
X				&& inroom (obj -> ox, obj -> oy) == dogroom
X				&& (gtyp == UNDEF || (gtyp != 1 && obj -> otyp == 1)
X					|| (((gtyp != 1 && obj -> otyp < 5)
X							|| (gtyp == 1 && obj -> otyp == 1))
X						&& DDIST (obj -> ox, obj -> oy) < DDIST (gx, gy)))) {
X			gx = obj -> ox;
X			gy = obj -> oy;
X			gtyp = obj -> otyp;
X		}
X		else if ((gtyp == UNDEF || gtyp == 67) && dogroom >= 0
X					&& inroom (obj -> ox, obj -> oy) == dogroom
X					&& uroom == dogroom
X				&& !edog -> carry && edog -> apport > rn2 (8)) {
X			gx = obj -> ox;
X			gy = obj -> oy;
X			gtyp = 66 + obj -> cursed;/* Random */
X		}
X		obj = obj -> nobj;
X	}
X	if (gtyp == UNDEF
X			|| (gtyp != 1 && gtyp != 66 && moves < edog -> hungrytime)) {
X		if (dogroom < 0 || dogroom == uroom) {
X			gx = u.ux;
X			gy = u.uy;
X		}
X		else {
X			int     tmp = rooms[dogroom].fdoor;
X
X			cnt = rooms[dogroom].doorct;
X			gx = gy = 100;/* Random, far away */
X			while (cnt--) {
X				if (dist (gx, gy) > dist (doors[tmp].x,
X							doors[tmp].y)) {
X					gx = doors[tmp].x;
X					gy = doors[tmp].y;
X				}
X				tmp++;
X
X			}
X			if (gy == 100)
X				panic (CORE, "No doors nearby?");
X			if (gx == omx && gy == omy) {
X				gx = u.ux;
X				gy = u.uy;
X			}
X		}
X		appr = 0;
X		if (udist >= 9)
X			appr++;
X		else if (mtmp -> mflee)
X			appr--;
X		if (after && udist <= 4 && gx == u.ux && gy == u.uy)
X			return NOMOVE;
X		if (udist > 1) {
X			if (levl[u.ux][u.uy].typ < ROOM || !rn2 (4) ||
X					(edog -> carry && rn2 (edog -> apport)))
X				appr = 1;
X		}
X/* If you have dog food he'll follow you more closely */
X		if (appr == 0) {
X			obj = invent;
X			while (obj) {
X				if (obj -> olet == '%' && obj -> otyp == 1) {
X					appr = 1;
X					break;
X				}
X				obj = obj -> nobj;
X			}
X		}
X	}
X	else
X		appr = 1;
X	if (mtmp -> mconf)
X		appr = 0;
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 (!ddx && !ddy)
X				continue;
X			zx = omx + ddx;
X			zy = omy + ddy;
X			if (mtmp2 = m_at (zx, zy)) {
X				if (mtmp2 -> data -> mhd >= mtmp -> data -> mhd + 2)
X					continue;
X				if (mtmp2 -> mtame)
X					continue;
X				if (after)
X					return NOMOVE;
X			/* Hit only once each move */
X				if (hitmm (mtmp, mtmp2) == HIT && rn2 (4) &&
X						hitmm (mtmp2, mtmp) == DEAD)
X					return DEAD;
X				return NOMOVE;
X			}
X			if (r_free (zx, zy, mtmp) && !(ddx && ddy
X						&& (levl[omx][omy].typ == DOOR
X							|| levl[zx][zy].typ == DOOR))) {
X/* M_at(zx,zy) is impossible here */
X
X/* Dog avoids unseen traps */
X				if ((trap = g_at (zx, zy, ftrap))
X						&& !(trap -> gflag & SEEN) && rn2 (10))
X					continue;
X
X/* Dog eschewes cursed objects but likes dog food */
X				obj = fobj;
X				while (obj) {
X					if (obj -> ox != zx || obj -> oy != zy)
X						goto nextobj;
X					if (obj -> cursed)
X						goto newdxy;
X					if (obj -> olet == '%' &&
X							(obj -> otyp == 1 || (obj -> otyp < 5 &&
X									edog -> hungrytime <= moves))) {
X						nix = zx;
X						niy = zy;
X						edog -> eattime = moves +
X							foods[obj -> otyp].delay;
X						edog -> hungrytime = moves + 5 *
X							foods[obj -> otyp].nutrition;
X						if (cansee (nix, niy)) {
X
X							char    buffer[BUFSZ];
X
X							doname (obj, buffer);
X							pline ("The %s ate %s.", mtmp -> data -> mname, buffer);
X						}
X						delobj (obj);
X/* perhaps this was a reward */
X						edog -> apport += 200 / (edog -> dropdist + moves - edog -> droptime);
X						goto newdogpos;
X					}
X			nextobj: 
X					obj = obj -> nobj;
X				}
X
X				nearer = GDIST (zx, zy) - GDIST (nix, niy);
X				nearer *= appr;
X				if (!nearer && !rn2 (++cnt) || nearer < 0
X						|| nearer > 0 && (omx == nix && omy ==
X							niy && !rn2 (3) || !rn2 (12))) {
X					nix = zx;
X					niy = zy;
X					if (nearer < 0)
X						cnt = 0;
X				}
X			}
X	newdxy: 	;
X		}
Xnewdogpos: 
X	if (nix != omx || niy != omy) {
X		mtmp -> mx = nix;
X		mtmp -> my = niy;
X	}
X	levlsym (omx, omy, mtmp -> data -> mlet);
X	pmon (mtmp);
X	return MOVE;
X}
X
Xhitmm (magr, mdef)
Xregister        MONSTER magr, mdef;
X{
X	register        MONSTDATA pa = magr -> data;
X	register        MONSTDATA pd = mdef -> data;
X	int     hit;
X	char    tmp, vis;
X
X	if (index ("Eay", magr -> data -> mlet))
X		return NOMOVE;
X	tmp = pd -> ac + pa -> mhd - 1;
X	if (mdef -> mconf || mdef -> mfroz || mdef -> msleep) {
X		tmp += 4;
X		mdef -> msleep = 0;
X	}
X	hit = (tmp >= rnd (20));
X	vis = (cansee (magr -> mx, magr -> my) &&
X			cansee (mdef -> mx, mdef -> my));
X	if (vis)
X		pline ("The %s %s the %s.", pa -> mname,
X				(hit) ? "hits" : "misses", pd -> mname);
X	else
X		pline ("You hear some noises %s.",
X				(dist (magr -> mx, magr -> my) > 15) ? "in the distance"
X				: "");
X	if (hit) {
X		if ((mdef -> mhp -= d (pa -> damn, pa -> damd)) <= 0) {
X			if (vis)
X				p2xthe ("%s is killed!", pd -> mname);
X			else
X			if (mdef -> mtame)
X				pline (SADFEEL);
X			unstuck (mdef);/* a3 */
X			relobj (mdef);
X			levlsym (mdef -> mx, mdef -> my, pd -> mlet);
X			magr -> orig_hp += rnd (pd -> mhd + 1);
X			if (magr -> mtame && magr -> orig_hp >
X					pa -> mhd << 3) {
X				if (pa == &li_dog)
X					magr -> data = pa = &dog;
X				else if (pa == &dog)
X					magr -> data = pa = &la_dog;
X			}
X			delmon (mdef);
X			hit = DEAD;
X		}
X	}
X	return hit;
X}
X
X/* Return roomnumber or -1 */
Xinroom (x, y)
Xchar    x, y;
X{
X	register        MKROOM * croom = &rooms[0];
X
X	if (xdnstair && dlevel)	/* a3 */
X		while (croom -> hx >= 0) {
X			if (croom -> hx >= x - 1 && croom -> lx <= x + 1
X					&& croom -> hy >= y - 1 && croom -> ly <= y + 1)
X				return (croom - rooms);
X			croom++;
X		}
X	return - 1;		/* In corridor or in maze */
X}
X
X#define NOTTAME 0
X#define TAME    1
X
Xtamedog (mtmp, obj)
Xregister        MONSTER mtmp;
Xregister        OBJECT obj;
X{
X	register        MONSTER mtmp2;
X
X	if (obj -> otyp >= 5 || mtmp -> mtame)
X		return NOTTAME;
X	psee (0, mtmp -> mx, mtmp -> my, "%s devours %s.",
X			mtmp -> data -> mname, foods[obj -> otyp].foodnam);
X	delobj (obj);
X	mtmp2 = newmonst (sizeof (struct edog));
X	*mtmp2 = *mtmp;
X	mtmp2 -> mxlth = sizeof (struct edog);
X	initedog (mtmp2);
X	mtmp2 -> nmon = fmon;
X	fmon = mtmp2;
X	delmon (mtmp);		/* %% */
X	return TAME;
X}
/
echo 'x - hack.invinit.c'
sed 's/^X//' > 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;
/
echo 'x - hack.pri.c'
sed 's/^X//' > hack.pri.c << '/'
X/*
X * Hack.pri.c
X */
X
X#include "hack.h"
X
Xchar    scrlx, scrhx, scrly, scrhy;
X
Xextern short    ospeed;
Xchar    xcurses[200];		/* Contain's curser stuff */
Xchar   *HO, *CL, *CE, *CM, *UP, *BC;
Xchar    PC;
Xextern char    *tgetstr (), *getenv (), *tgoto (), *malloc ();
Xint     putch ();
X /* Corners of new area on screen */
Xextern char     SAVEFILE[];
X
XCOORDINATES ou = {
X	-1, 0
X};				/* Coordinates of @ on screen (if ou.x>=0) */
X
Xextern char    *getenv (), *hu_stat[4];/* In eat.c */
X#ifdef NORMAL_IO
Xchar    obuf[BUFSIZ];
X#endif NORMAL_IO
X
Xstartup () {
X	char   *bp = malloc (1024);
X	char   *atcurs = xcurses;
X
X	if (tgetent (bp, getenv ("TERM")) <= 0)
X		panic (NOCORE, "I know about many terminals but alas, not this one\n");
X	PC = tgetflag ("pc");
X	HO = tgetstr ("ho", &atcurs);
X	CL = tgetstr ("cl", &atcurs);
X	CE = tgetstr ("ce", &atcurs);
X	UP = tgetstr ("up", &atcurs);
X	if (!(BC = tgetstr ("bc", &atcurs))) {
X		if (!tgetflag ("bs"))
X			panic (NOCORE,
X					"You don't have a backspaced terminal\n");
X		BC = (char *) NULL;
X	}
X	if (!(CM = tgetstr ("cm", &atcurs)))
X		panic (NOCORE, "Hack needs cursor addressible terminals\n");
X	else if (!UP || !CL || tgetflag ("os"))
X		panic (NOCORE, "Hack needs `up' and `cl' and no `os'\n");
X	free (bp);
X#ifdef NORMAL_IO
X	setbuf (stdout, obuf);
X#endif NORMAL_IO
X}
X
X/*VARARGS*/
Xpanic (coredump, str, a1, a2, a3, a4, a5, a6)
Xregister char  *str;
X{
X	home ();
X#ifdef NORMAL_IO
X	printf ("ERROR:  ", 10);
X#else
X	WRITE ("ERROR:  ", 10);
X#endif NORMAL_IO
X	printf (str, a1, a2, a3, a4, a5, a6);
X	hackmode (OFF);
X	if (!unlink (SAVEFILE))
X		printf ("Savefile removed.\n");
X	flush ();
X	if (coredump)
X		abort ();
X	exit (2);
X}
X
Xseeatl (x, y, c)
Xregister        x, y, c;
X{
X	if (cansee (x, y))
X		atl (x, y, c);
X}
X
Xcls () {
X	tputs (CL, 0, putch);
X	curx = 1;
X	cury = 1;
X	ou.x = -1;
X	flags.topl = 0;
X}
X
Xhome () {
X	if (HO)
X		tputs (HO, 0, putch);
X	else
X		tgoto (CM, 0, 0);
X	curx = 1;
X	cury = 1;
X}
X
Xatl (x, y, ch)
Xregister        x, y;
X{
X	register        PART * crm = &levl[x][y];
X
X	if (crm -> scrsym == ch)
X		return;
X	if (x < 0 || x > 79 || y < 0 || y > 21)
X		panic (CORE, "atl(%d,%d,%c_%d_)", x, y, ch, ch);
X	crm -> scrsym = ch;
X	crm -> new = 1;
X	on (x, y);
X}
X
Xon (x, y)
Xregister        x, y;
X{
X	if (flags.dscr) {
X		if (x < scrlx)
X			scrlx = x;
X		else if (x > scrhx)
X			scrhx = x;
X		if (y < scrly)
X			scrly = y;
X		else if (y > scrhy)
X			scrhy = y;
X	}
X	else {
X		flags.dscr = 1;
X		scrlx = scrhx = x;
X		scrly = scrhy = y;
X	}
X}
X
Xat (x, y, ch)
Xregister        x, y;
Xregister char   ch;
X{
X	if (!ch || x < 0 || x > 79 || y < 0 || y > 21)
X		panic (CORE, "at(%d %d,%d) at %d %d", x, y, ch,
X				u.ux, u.uy);
X	y += 2;
X	curs (x, y);
X	putchar (ch == '\t' ? ' ' : ch);
X	curx++;
X}
X
Xprme () {
X	if (!u.uinvis)
X		at (u.ux, u.uy, '@');
X}
X
Xpru () {
X	prl (u.ux, u.uy);
X}
X
Xprl (x, y) {
X	register        PART * room;
X	register        MONSTER mtmp;
X
X	room = &levl[x][y];
X	if (!room -> typ || (room -> typ < DOOR &&
X				levl[u.ux][u.uy].typ == CORR))
X		return;
X	if ((mtmp = m_at (x, y)) && (!mtmp -> invis || u.ucinvis))
X		atl (x, y,
X				(mtmp -> wormno && (mtmp -> mx != x || mtmp -> my != y)) ?
X				'~' :
X				mtmp -> data -> mlet);
X	else
X		newunseen (x, y);
X}
X
Xnewunseen (x, y)
Xregister        x, y;
X{
X	if (!levl[x][y].seen) {
X		levl[x][y].new = 1;
X		on (x, y);
X	}
X}
X
Xchar
X        news0 (x, y)
Xregister        x, y;
X{
X	register        OBJECT otmp;
X	register        GOLD_TRAP gtmp;
X	PART * room;
X	register char   tmp;
X
X	room = &levl[x][y];
X	if (!u.ublind && (otmp = o_at (x, y)))
X		tmp = otmp -> olet;
X	else if (!u.ublind && g_at (x, y, fgold))
X		tmp = '$';
X	else if (gtmp = g_at (x, y, ftrap)) {
X		if (gtmp -> gflag == MIMIC)
X			tmp = '+';
X		else if (gtmp -> gflag & SEEN)
X			tmp = '^';
X		else
X			tmp = '.';
X	}
X	else if (room -> typ >= 30 && room -> typ <= 41)
X		tmp = '0';
X	else
X		switch (room -> typ) {
X
X			case SDOOR: 
X			case WALL: 
X				if ((room - 1) -> typ == WALL && (room + 1) -> typ
X						== WALL)
X					tmp = '|';
X				else
X					tmp = '-';
X				break;
X
X			case DOOR: 
X				tmp = '+';
X				break;
X
X			case ROOM: 
X				if (x == xupstair && y == yupstair)
X					tmp = '<';
X				else if (x == xdnstair && y == ydnstair)
X					tmp = '>';
X				else if (room -> lit || cansee (x, y) || u.ublind)
X					tmp = '.';
X				else
X					tmp = ' ';
X				break;
X
X			case CORR: 
X				tmp = '#';
X				break;
X
X			case POOL: 
X				tmp = '}';
X				break;
X			case VAULT: 
X				tmp = '-';
X				break;
X
X			default: 
X				tmp = '`';
X				impossible ();
X		}
X	return tmp;
X}
X
Xnewsym (x, y)
Xregister        x, y;
X{
X	atl (x, y, news0 (x, y));
X}
X
Xlevlsym (x, y, c)
Xregister        x, y, c;
X{
X	if (levl[x][y].scrsym == c)
X		newsym (x, y);
X}
X
Xnosee (x, y)
Xregister        x, y;
X{
X	register        PART * room;
X
X	room = &levl[x][y];
X	if (room -> scrsym == '.' && !room -> lit && !u.ublind) {
X		if (room -> new && (x != oldux || y != olduy))
X			room -> new = 0;
X		else {
X			room -> scrsym = ' ';
X			room -> new = 1;
X			on (x, y);
X		}
X	}
X}
X
Xprl1 (x, y)
Xregister        x, y;
X{
X	register        count;
X
X	if (dx) {
X		if (dy) {
X			prl (x - (dx << 1), y);
X			prl (x - dx, y);
X			prl (x, y);
X			prl (x, y - dy);
X			prl (x, y - (dy << 1));
X		}
X		else
X			for (count = -1; count <= 1; ++count)
X				prl (x, y + count);
X	}
X	else
X		for (count = -1; count <= 1; ++count)
X			prl (x + count, y);
X}
X
Xnose1 (x, y)
Xregister        x, y;
X{
X	register        count;
X
X	if (dx)
X		if (dy) {
X			nosee (x, u.uy);
X			nosee (x, u.uy - dy);
X			nosee (x, y);
X			nosee (u.ux - dx, y);
X			nosee (u.ux, y);
X		}
X		else
X			for (count = -1; count <= 1; ++count)
X				nosee (x, y + count);
X	else
X		for (count = -1; count <= 1; ++count)
X			nosee (x + count, y);
X}
X
Xdoreprint () {
X	nomove ();
X	pline ("\200");		/* Michiel: Code for repeating last message */
X}
X
X/* VARARGS1 */
Xpline (line, arg1, arg2, arg3, arg4)
Xregister char  *line;
X{
X	char    pbuf[BUFSZ];
X	static char     prevbuf[BUFSZ];
X
X	if (index (line, '\200'))
X		strcpy (pbuf, prevbuf);
X	else {
X		if (!index (line, '%'))
X			strcpy (pbuf, line);
X		else
X			sprintf (pbuf, line, arg1, arg2, arg3, arg4);
X		if (multi && !strcmp (pbuf, prevbuf))
X			return;
X		strcpy (prevbuf, pbuf);
X	}
X	if (flags.dscr)
X		nscr ();
X	if (flags.topl) {
X		curs (savx, 1);
X		more ();
X	}
X	flags.topl = 1;
X	home ();
X	cl_end ();
X	printf (pbuf);
X	savx = strlen (pbuf);
X	curx = ++savx;
X}
X
Xprustr () {
X	if (u.ustr > 18) {
X		if (u.ustr > 117)
X			printf ("18/00");
X		else
X			printf ("18/%02d", u.ustr - 18);
X	}
X	else
X		printf ("%-5d", u.ustr);
X	curx += 5;
X}
X
Xpmon (mtmp)
Xregister        MONSTER mtmp;
X{
X	if (!mtmp -> invis || u.ucinvis)
X		seeatl (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet);
X}
X
Xdocrt () {
X	cls ();
X	if (u.uswallow) {
X		curs (u.ux - 1, u.uy - 1);
X		printf ("/-\\");
X		curs (u.ux - 1, u.uy);
X		printf ("|@|");
X		curs (u.ux - 1, u.uy + 1);
X		printf ("\\-/");
X		curx = u.ux + 2;
X	}
X	else
X		donscrt (0, 0);	/* a3 */
X	bot ();
X}
X
Xnscr () {
X	register        umv;
X
X	umv = ((ou.x < 0 && !u.uinvis) || (ou.x >= 0 &&
X				(u.uinvis || ou.x != u.ux || ou.y != u.uy)));
X	if (ou.x >= 0 && umv && !levl[ou.x][ou.y].new)
X		newsym (ou.x, ou.y);
X	donscrt (1, umv);
X}
X
Xdonscrt (mode, umv) {		/* mode: 0- docrt(), 1- nscr()  */
X	register        PART * room;
X	register        x, y, ly, hy, lx, hx;
X
X	if (u.uinvis) {
X		if (mode)
X			ou.x = -1;
X	}
X	else {
X		ou.x = u.ux;
X		ou.y = u.uy;
X		if (mode && umv)
X			atl (ou.x, ou.y, '@');
X		else {
X			(room = &levl[ou.x][ou.y]) -> scrsym = '@';
X			if (!mode)
X				room -> seen = 1;
X			else
X				room -> new = 0;
X		}
X	}
X	if (mode) {
X		ly = scrly;
X		hy = scrhy;
X		lx = scrlx;
X		hx = scrhx;
X	}
X	else {
X		ly = 0;
X		hy = 21;
X		lx = 0;
X		hx = 79;
X	}
X	for (y = ly; y <= hy; y++)
X		for (x = lx; x <= hx; x++)
X			if ((room = &levl[x][y]) -> new) {
X				room -> new = 0;
X				at (x, y, room -> scrsym);
X				if (room -> scrsym == ' ') {
X					room -> seen = 0;
X					room -> scrsym = '.';
X				}
X				else
X					room -> seen = 1;
X			}
X			else if (!mode)
X				if (room -> seen)
X					at (x, y, room -> scrsym);
X	flags.dscr = 0;
X	scrhx = 0;
X	scrhy = 0;
X	scrlx = 80;
X	scrly = 22;
X}
X
Xbot () {
X	flags.botl = 0;
X	flags.dhp = 0;
X	flags.dhpmax = 0;
X	flags.dac = 0;
X	flags.dstr = 0;
X	flags.dgold = 0;
X	flags.dhs = 0;
X	curs (1, 24);
X	printf ("Level %-4dGold %-7UHp%4d(%d)",
X			dlevel, u.ugold, u.uhp, u.uhpmax);
X	if (u.uhpmax < 10)
X		printf ("  ");
X	else if (u.uhpmax < 100)
X		putchar (' ');
X	printf ("Ac %-5dStr ", u.uac);
X	prustr ();
X	printf ("  Exp%3d/", u.ulevel);
X	if (u.ulevel < 14)
X		printf ("%-11U", u.uexp);
X	else
X		printf ("%-11s", "MAX++");
X	printf ("%s", hu_stat[u.uhs]);
X	curx = 78;
X}
X
Xcurs (x, y)
Xregister        x, y;
X{
X	if (y == cury && x == curx)
X		return;		/* Do nothing, gracefully */
X	tputs (tgoto (CM, x - 1, y - 1), 0, putch);
X	flush ();
X	cury = y;
X	curx = x;
X}
X
Xcl_end () {
X	if (CE)
X		tputs (CE, 0, putch);
X	else {
X		printf ("%80s", "");
X		home ();
X	}
X}
X
Xputch (c)
Xchar    c;
X{
X#ifdef NORMAL_IO
X	putchar (c);
X#else
X	WRITE (&c, 1);
X#endif NORMAL_IO
X}
/
echo 'x - mklev.c'
sed 's/^X//' > mklev.c << '/'
X/*
X * Mklev.c
X */
X
X#define NORMAL_IO
X#include "hack.h"
X
Xchar   *tfile, *tspe, **args, nul[20];
X
X#include "mklev.svlev.c"
X
Xchar    mmon[8][8] = {
X	"BGHJKLr",
X	"aEhiOyZ",
X	"AfNpQqv",
X	"bCcgjkS",
X	"FoRstWw",
X	"dlMmTuY",
X	"IUVXxz:",
X	"De'n,P&"
X};
X
X#define MAZX ((rnd(37) << 1) + 1)
X#define MAZY ((rnd(8) << 1) + 1)
X
X#define somex() rn1( croom->hx - croom->lx + 1, croom->lx )
X#define somey() rn1( croom->hy - croom->ly + 1, croom->ly )
X
X#define NOT_HERE	0
X
XPART levl[80][22];
X
XMONSTER fmon;
XOBJECT fobj;
XGOLD_TRAP fgold, ftrap;
X
XMKROOM rooms[15], *croom, *troom;
X
XCOORDINATES doors[DOORMAX];
X
Xint     doorindex = 0, nroom, comp ();
X
Xchar    dlevel, *geno, goldseen,
X        xdnstair, xupstair, ydnstair, yupstair,
X        wizard, nxcor, x, y,
X        dx, dy, tx, ty;
X /* For corridors and other things... */
X
X#define RUIN	5
X#define MAZE	6
X
Xmain (argc, argv)
Xchar   *argv[];
X{
X	char    lowy, lowx;
X	register unsigned       tryct;
X
X	if (argc < 6)
X		panic ("Too few arguments!!");
X	args = argv;
X	tfile = argv[1];
X	tspe = argv[2];
X	dlevel = atoi (argv[3]);
X	if (dlevel >= 30)
X		dlevel = 30;
X	geno = argv[4];
X	wizard = (*argv[5] == 'w');
X	srand (getpid ());
X/* for( lowy=2;lowy<19;lowy++) for( lowx=2;lowx<77;lowx++ )
X	 				levl[lowx][lowy].typ = 0; * /
X
X/*
X * a: normal;
X * b: maze;
X * n: next level will be maze
X */
X	if (*tspe == 'b') {
X		makemaz ();
X		savelev ();
X		exit (1);
X	}
X
X/* Construct the rooms */
X	croom = rooms;
X	tryct = 0;
X	while (nroom < 7) {
X		for (lowy = rn1 (3, 3); lowy < 15; lowy += rn1 (2, 4))
X			for (lowx = rn1 (3, 4); lowx < 70; lowx +=
X					rn1 (2, 7)) {
X				if (++tryct > 10000) {
X					printf ("tryct overflow\n");
X					goto jumpout;
X				}
X				if ((lowy += rn1 (5, -2)) < 3)
X					lowy = 3;
X				else if (lowy > 16)
X					lowy = 16;
X				if (levl[lowx][lowy].typ)
X					continue;
X				if (maker (lowx, rn1 (9, lowx + 2), lowy,
X							rn1 (4, lowy + 2)) && nroom > 13)
X					goto jumpout;
X			}
X	}
Xjumpout: 
X	croom -> hx = -1;
X
X/* For each room: put things inside */
X	for (croom = rooms; croom -> hx > 0; croom++) {
X
X/* Put a sleeping monster inside */
X		if (!rn2 (3))
X			makemon (1, somex (), somey ());
X
X/* Put traps and mimics inside */
X		goldseen = 0;
X		while (!rn2 (8 - (dlevel / 6)))
X			mktrap (0, 0);
X		if (!goldseen && !rn2 (3))
X			mkgold (0, somex (), somey ());
X		tryct = 0;
X		if (!rn2 (3))
X			do {
X				mkobj (0);
X				levl[fobj -> ox = somex ()][fobj -> oy = somey ()].scrsym = fobj -> olet;
X				if (tryct++ > 100) {
X					printf ("tryct overflow4\n");
X					break;
X				}
X			} while (!rn2 (5));
X	}
X	tryct = 0;
X	do {
X		if (++tryct > 1000)
X			panic ("Cannot make dnstairs\n");
X		croom = &rooms[rn2 (nroom)];
X		xdnstair = somex ();
X		ydnstair = somey ();
X	} while ((*tspe == 'n' &&
X				(xdnstair % 2 == 0 || ydnstair % 2 == 0)) ||
X			g_at (xdnstair, ydnstair, ftrap));
X	levl[xdnstair][ydnstair].scrsym = '>';
X	troom = croom;
X	do {
X		if (++tryct > 2000)
X			panic ("Cannot make upstairs\n");
X		croom = &rooms[rn2 (nroom)];
X		xupstair = somex ();
X		yupstair = somey ();
X	} while (croom == troom || m_at (xupstair, yupstair) ||
X			o_at (xupstair, yupstair) ||
X			g_at (xupstair, yupstair, ftrap));
X	levl[xupstair][yupstair].scrsym = '<';
X	qsort (rooms, nroom, sizeof (MKROOM), comp);
X	croom = rooms;
X	troom = croom + 1;
X	nxcor = 0;
X	mkpos ();
X	do
X		makecor (x + dx, y + dy);
X	while (croom -> hx > 0 && troom -> hx > 0);
X	if ((dlevel < 10 && rn2 (2)) || (dlevel > 9 && !rn2 (3)) ||
X			wizard)
X		mkshop ();
X	if (dlevel > 7 && !rn2 (6))
X		mkzoo ();
X	else if (dlevel > 11 && !rn2 (6) || wizard)
X		mkyard ();
X	else if ((dlevel > 18 && !rn2 (6)))
X		mkswamp ();
X	else if ((dlevel > 8 && !rn2 (8)) || wizard)
X		mk_knox ();
X	savelev ();
X}
X
Xcomp (xcoord, ycoord)
Xregister        MKROOM * xcoord, *ycoord;
X{
X	if (xcoord -> lx < ycoord -> lx)
X		return - 1;
X	return (xcoord -> lx > ycoord -> lx);
X}
X
Xmkpos () {
X	if (troom -> hx < 0 || croom -> hx < 0)
X		return;
X	if (troom -> lx > croom -> hx) {
X		x = croom -> hx + 1;
X		dx = 1;
X		tx = troom -> lx - 1;
X	}
X	else if (troom -> hy < croom -> ly) {
X		y = croom -> ly - 1;
X		dy = -1;
X		dx = 0;
X		ty = troom -> hy + 1;
X	}
X	else if (troom -> hx < croom -> lx) {
X		x = croom -> lx - 1;
X		dx = -1;
X		tx = troom -> hx + 1;
X	}
X	else {
X		y = croom -> hy + 1;
X		dy = 1;
X		dx = 0;
X		ty = troom -> ly - 1;
X	}
X	if (dx) {
X		dy = 0;
X		y = croom -> ly + rn2 (croom -> hy - croom -> ly + 1);
X		ty = troom -> ly + rn2 (troom -> hy - troom -> ly + 1);
X	}
X	else {
X		x = croom -> lx + rn2 (croom -> hx - croom -> lx + 1);
X		tx = troom -> lx + rn2 (troom -> hx - troom -> lx + 1);
X	}
X	if (levl[x + dx][y + dy].typ) {
X		if (nxcor)
X			newloc ();
X		else {
X			dodoor (x, y, croom);
X			x += dx;
X			y += dy;
X		}
X		return;
X	}
X	dodoor (x, y, croom);
X}
X
Xdodoor (doorx, doory, aroom)
Xregister int    doorx, doory;
Xregister        MKROOM * aroom;
X{
X	register        MKROOM * broom;
X	register int    tmp;
X
X	if ((tmp = levl[doorx - 1][doory].typ) == DOOR || tmp == SDOOR)
X		return;
X	if ((tmp = levl[doorx + 1][doory].typ) == DOOR || tmp == SDOOR)
X		return;
X	if ((tmp = levl[doorx][doory - 1].typ) == DOOR || tmp == SDOOR)
X		return;
X	if ((tmp = levl[doorx][doory + 1].typ) == DOOR || tmp == SDOOR)
X		return;
X	if (levl[doorx][doory].typ != WALL || doorindex >= DOORMAX)
X		return;
X	if (!rn2 (8))
X		levl[doorx][doory].typ = SDOOR;
X	else {
X		levl[doorx][doory].scrsym = '+';
X		levl[doorx][doory].typ = DOOR;
X	}
X	aroom -> doorct++;
X	broom = aroom + 1;
X	if (broom -> hx < 0)
X		tmp = doorindex;
X	else
X		for (tmp = doorindex; tmp > broom -> fdoor; tmp--) {
X			doors[tmp].x = doors[tmp - 1].x;
X			doors[tmp].y = doors[tmp - 1].y;
X		}
X	doorindex++;
X	doors[tmp].x = doorx;
X	doors[tmp].y = doory;
X	for (; broom -> hx >= 0; broom++)
X		broom -> fdoor++;
X}
X
Xnewloc () {
X	register int    tryct = 0;
X
X	++croom;
X	++troom;
X	if (nxcor || croom -> hx < 0 || troom -> hx < 0) {
X		if (nxcor++ > rn1 (nroom, 4)) {
X			croom = &rooms[nroom];
X			return;
X		}
X		do {
X			if (++tryct > 100) {
X				printf ("tryct overflow5\n");
X				croom = &rooms[nroom];
X				return;
X			}
X			croom = &rooms[rn2 (nroom)];
X			troom = &rooms[rn2 (nroom)];
X		}
X		while (croom == troom || (troom == croom + 1 &&
X					!rn2 (3)));
X	}
X	mkpos ();
X}
X
Xmove (xdir, ydir, dir)
Xregister int   *xdir, *ydir, dir;
X{
X	switch (dir) {
X		case 0: 
X			--(*xdir);
X			break;
X		case 1: 
X			(*ydir)++;
X			break;
X		case 2: 
X			(*xdir)++;
X			break;
X		case 3: 
X			--(*ydir);
X			break;
X	}
X}
X
Xokay (xx, yy, dir)
Xint     xx, yy;
Xregister int    dir;
X{
X	move (&xx, &yy, dir);
X	move (&xx, &yy, dir);
X	if (xx < 3 || yy < 3 || xx > 17 || yy > 75 || levl[yy][xx].typ != 0)
X		return 0;
X	return 1;
X}
X
Xmaker (lowx, hix, lowy, hiy)
Xchar    lowx, hix, lowy, hiy;
X{
X	register        PART * ltmp, *lmax;
X	register int    tmpx;
X
X	if (hix > 75)
X		hix = 75;
X	if (hiy > 18)
X		hiy = 18;
X	for (tmpx = lowx - 4; tmpx < hix + 5; tmpx++)
X		for (ltmp = &levl[tmpx][lowy - 3],
X				lmax = &levl[tmpx][hiy + 4];
X				ltmp != lmax; ltmp++)
X			if (ltmp -> typ)
X				return 0;
X	if (10 > rnd (dlevel)) {
X		for (tmpx = lowx - 1; tmpx < hix + 2; tmpx++)
X			for (ltmp = &levl[tmpx][lowy - 1],
X					lmax = &levl[tmpx][hiy + 2];
X					ltmp != lmax; ltmp++)
X				ltmp -> lit = 1;
X	}
X	croom -> lx = lowx;
X	croom -> hx = hix;
X	croom -> ly = lowy;
X	croom -> hy = hiy;
X	croom -> rtype = 0;
X	croom -> doorct = 0;
X	croom -> fdoor = 0;
X	croom++;
X	for (tmpx = lowx - 1; tmpx <= hix + 1; tmpx++) {
X		ltmp = &levl[tmpx][lowy - 1];
X		lmax = &levl[tmpx][hiy + 1];
X		ltmp -> scrsym = '-';
X		ltmp -> typ = WALL;
X		while (++ltmp != lmax) {
X			if (tmpx >= lowx && tmpx <= hix) {
X				ltmp -> scrsym = '.';
X				ltmp -> typ = ROOM;
X			}
X			else {
X				ltmp -> scrsym = '|';
X				ltmp -> typ = WALL;
X			}
X		}
X		ltmp -> scrsym = '-';
X		ltmp -> typ = WALL;
X	}
X /* 
X  -------
X  |.....|
X  |.....|		(This sort of room is made) (a3)
X  |.....|
X  -------
X  */
X	++nroom;
X	return 1;
X}
X
Xmakecor (nx, ny)
Xregister int    nx, ny;
X{
X	register        PART * crm;
X	register int    dix, diy;
X
X	if (nxcor && !rn2 (35)) {
X		newloc ();
X		return;
X	}
X	dix = abs (nx - tx);
X	diy = abs (ny - ty);
X	if (nx == 79 || !nx || !ny || ny == 21) {
X		if (nxcor) {
X			newloc ();
X			return;
X		}
X		printf ("something went wrong. we try again...\n");
X		execl ("./mklev", args[0], tfile, tspe, args[3],
X				args[4], 0);
X		panic ("cannot execute ./mklev\n");
X	}
X	if (dy && dix > diy) {
X		dy = 0;
X		dx = (nx > tx) ? -1 : 1;
X	}
X	else if (dx && diy > dix) {
X		dx = 0;
X		dy = (ny > ty) ? -1 : 1;
X	}
X	crm = &levl[nx][ny];
X	if (!crm -> typ) {
X		crm -> typ = CORR;
X		crm -> scrsym = '#';
X		x = nx;
X		y = ny;
X		return;
X	}
X	if (crm -> typ == CORR) {
X		x = nx;
X		y = ny;
X		return;
X	}
X	if (nx == tx && ny == ty) {
X		dodoor (nx, ny, troom);
X		newloc ();
X		return;
X	}
X	if (x + dx != nx || y + dy != ny)
X		return;
X	if (dx) {
X		dy = 1;
X		if (ty < ny || levl[nx + dx][ny - 1].typ != ROOM)
X			dy = -1;
X		dx = 0;
X	}
X	else {
X		dx = 1;
X		if (tx < nx || levl[nx - 1][ny + dy].typ != ROOM)
X			dx = -1;
X		dy = 0;
X	}
X}
X
XMONSTER m_at (monx, mony)
Xregister int    monx, mony;
X{
X	register        MONSTER mtmp;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon)
X		if (mtmp -> mx == monx && mtmp -> my == mony)
X			return (mtmp);
X	return (NOT_HERE);
X}
X
XOBJECT o_at (objx, objy)
Xregister int    objx, objy;
X{
X	register        OBJECT obj;
X
X	for (obj = fobj; obj; obj = obj -> nobj)
X		if (obj -> ox == objx && obj -> oy == objy)
X			return (obj);
X	return (NOT_HERE);
X}
X
XGOLD_TRAP g_at (gtx, gty, ptr)
Xregister int    gtx, gty;
Xregister        GOLD_TRAP ptr;
X{
X	while (ptr) {
X		if (ptr -> gx == gtx && ptr -> gy == gty)
X			return (ptr);
X		ptr = ptr -> ngen;
X	}
X	return NOT_HERE;
X}
/
echo 'x - show.c'
sed 's/^X//' > show.c << '/'
X/*
X * Showlevel.c
X */
X
X#define NORMAL_IO
X#define SHOW
X#include "hack.h"
X
XPART levl[80][22];
X
Xchar    mmon[8][8] = {
X	"BGHJKLr",
X	"aEhiOyZ",
X	"AfNpQqv",
X	"bCcgjkS",
X	"FoRstWw",
X	"dlMmTuY",
X	"IUVXxz:",
X	"De'n,P&"
X};
X
Xchar    stairs[4], mbuf[1000], obuf[BUFSIZ];
X
Xunsigned        omoves;
Xextern char    *setan ();
X
Xmain (argc, argv)
Xint     argc;
Xchar  **argv;
X{
X	register        fd;
X	register        MONSTER mtmp = (MONSTER) mbuf;
X	char    buffer[100];
X	struct stole    stmp;
X	struct obj      otmp;
X	char    buf[BUFSZ];
X	int     xl;
X
X	setbuf (stdout, obuf);
X	if (!strcmp (argv[1], "-r")) {
X		showrecord ();
X		exit (0);
X	}
X	if (!strcmp (argv[1], "-d")) {
X		delrecord ();
X		exit (0);
X	}
X	while (--argc) {
X		printf ("Next file is %s\n", argv[argc]);
X		if ((fd = open (argv[argc], 0)) < 0) {
X			printf ("Cannot open %s\n", argv[argc]);
X			getret ();
X			continue;
X		}
X		if (read (fd, levl, sizeof levl) != sizeof levl) {
X			printf ("Error reading level\n");
X			getret ();
X			continue;
X		}
X		show ();
X		mread (fd, &omoves, sizeof (unsigned));
X		mread (fd, stairs, 4);
X		mread (fd, &xl, sizeof (int));
X		printf ("Show Monsters? (%sSpecified) ", omoves ? "Not " : "");
X		fflush (stdout);
X		gets (buffer);
X		if (strcmp (buffer, "y"))
X			continue;
X		while (xl != -1) {
X			mread (fd, mtmp, xl + sizeof (struct monst));
X			mread (fd, &stmp, sizeof (struct stole));
X			if (!omoves) {
X				if (mtmp -> mhp == 10 && mtmp -> orig_hp == 10)
X					printf ("\' \'");
X				else if (mtmp -> mhp == 9 && mtmp -> orig_hp == 9)
X					printf ("Ale");
X				else
X					printf ("%c",
X							mmon[mtmp -> mhp][mtmp -> orig_hp]);
X				printf (" at [%d,%d]", mtmp -> mx, mtmp -> my);
X			}
X			else {
X				printf ("monster at [%d,%d]", mtmp -> mx, mtmp -> my);
X				if (stmp.sgold || stmp.sobj) {
X					printf (" stole ");
X					if (stmp.sgold)
X						printf ("%u goldpieces", stmp.sgold);
X					for (;;) {
X						mread (fd, &otmp,
X								sizeof (struct obj));
X						if (!otmp.olet)
X							break;
X						doname (otmp.olet, buf);
X						printf (" %s", buf);
X					}
X				}
X			}
X			if (mtmp -> msleep)
X				printf (" SLEEP");
X			if (mtmp -> invis)
X				printf (" INVIS");
X			if (mtmp -> cham)
X				printf (" CHAM");
X			if (mtmp -> mspeed)
X				printf (" MSPEED");
X			if (mtmp -> mconf)
X				printf (" MCONF");
X			if (mtmp -> mflee)
X				printf (" MFLEE");
X			if (mtmp -> mcan)
X				printf (" MCAN");
X			if (mtmp -> mtame)
X				printf (" TAME");
X			if (mtmp -> angry)
X				printf (" MANGRY");
X			if (mtmp -> wormno)
X				printf (" WORM[%d]", mtmp -> wormno);
X			if (mtmp -> mxlth)
X				printf (" +%d extra", mtmp -> mxlth);
X			if (mtmp -> mfroz)
X				printf (" FROZ");
X			putchar ('\n');
X			mread (fd, &xl, sizeof (int));
X		}
X		getret ();
X	}
X}
X
Xmread (fd, buf, n) {
X	register        nn;
X
X	if ((nn = read (fd, buf, n)) != n) {
X		printf ("error: read %d instead of %d bytes\n", nn, n);
X		exit (2);
X	}
X}
X
Xshow () {
X	register        i, j;
X
X	for (j = 0; j < 22; j++)
X		for (i = 0; i < 80; i++)
X			pch (levl[i][j].scrsym);
X	printf ("***     ");
X}
X
Xpch (ch)
Xchar    ch;
X{
X	putchar (ch ? ch : '_');
X}
X
Xextern char    *malloc ();
X
Xchar   *
X        alloc (num)
Xregister        num;
X{
X	register char  *val;
X
X	if (!(val = malloc (num)))
X		error ("Cannot get %d bytes", num);
X	return val;
X}
X
Xerror (s) {
X	printf (s);
X	putchar ('\n');
X	fflush (stdout);
X	exit (1);
X}
X
Xextern char    *itoa ();
X
X#define	NAMESIZE	 8
X#define	DEATHSIZE	40
X
Xstruct recitem {
X	long    points;
X	int     level, maxlvl, hp, maxhp;
X	char    str[NAMESIZE + 1], death[DEATHSIZE + 1];
X}               record;
X
Xshowrecord () {
X	register        killed;
X	register        place = 0;
X	register        rfile;
X
X	if ((rfile = open (RECORD, 0)) < 0)
X		error ("Cannot open %s", RECORD);
X	printf ("Number Points Name\n");
X	while (read (rfile, &record, sizeof (struct recitem)) > 0) {
X		printf ("%2d  %6D %8s ", ++place, record.points,
X			record.str);
X		killed = 0;
X		if (*record.death == 'e')
X			printf ("escaped the dungeon [max level %d]",
X				record.maxlvl);
X		else {
X			switch (record.death[1]) {
X				case 'u': 
X					printf ("quit");
X					break;
X				case 'h': 
X					printf ("choked in his/her food");
X					break;
X				case 't': 
X					printf ("starved");
X					break;
X				case 'r': 
X					printf ("drowned");
X					break;
X				default: 
X					printf ("was killed");
X					killed++;
X			}
X			                                                        printf (" on%s level %d", killed ? "" :
X				                                                        " dungeon", record.level);
X			if (record.maxlvl != record.level)
X				printf (" [%d]", record.maxlvl);
X		}
X		if (killed)
X			printf (" by %s", record.death);
X		putchar ('.');
X		if (record.maxhp)
X			printf (" Hp: %s [%d]", (record.hp > 0) ?
X					itoa (record.hp) : "-", record.maxhp);
X		putchar ('\n');
X	}
X	close (rfile);
X}
X
Xint     deleted[45];
X
Xdelrecord () {
X	register int    fd, fd2;
X	int     count = 0;
X
X	printf ("Delete (Terminate with a zero): ");
X	fflush (stdout);
X	fd = open (RECORD, 0);
X	fd2 = creat (".Temp", 0777);
X	if (fd < 0 || fd2 < 0) {
X		printf ("Cannot open files!\n");
X		exit (2);
X	}
X	do {
X		scanf ("%d", &count);
X		++deleted[count];
X	} while (count);
X	fprintf (stderr, "Deleted nr");
X	count = 1;
X	while (read (fd, &record, sizeof (struct recitem)) >    0) {
X		if (!deleted[count])
X			write (fd2, &record, sizeof (struct recitem));
X		else
X			                                                fprintf (stderr, " %d", count);
X		                                              ++count;
X	}
X	                                                        putc ('\n', stderr);
X	close (fd);
X	close (fd2);
X	execl ("/bin/mv", "mv", ".Temp", RECORD, NULL);
X}
X
Xchar   *
X        itoa (a)
Xregister int    a;
X{
X	static char     buf[8];
X
X	sprintf (buf, "%d", a);
X	return (buf);
X}
X
Xdoname (let, buf)
Xregister char   let;
Xregister char  *buf;
X{
X	switch (let) {
X
X		case '"': 
X			strcpy (buf, "The amulet of Frobozz");
X			break;
X
X		case '%': 
X			strcpy (buf, "some food");
X			break;
X
X		case ')': 
X			strcpy (buf, "a weapon");
X			break;
X
X		case '[': 
X			strcpy (buf, "armor");
X			break;
X
X		case '!': 
X			strcpy (buf, "a potion");
X			break;
X
X		case '?': 
X			strcpy (buf, "a scroll");
X			break;
X
X		case '/': 
X			strcpy (buf, "a wand");
X			break;
X
X		case '=': 
X			strcpy (buf, "a ring");
X			break;
X
X		case '*': 
X			strcpy (buf, "a gem");
X			break;
X
X		default: 
X			sprintf (buf, "a glorkum %c(0%o)", let, let);
X	}
X}
X
Xgetret () {
X	printf ("AHit j<return>k to continue");
X	fflush (stdout);
X	while (getchar () != '\n');
X}
/
echo 'Part 03 of Hack complete.'
exit
-- 

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



More information about the Comp.sources.unix mailing list