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

Michiel B. Huisjes huisjes at ark.UUCP
Wed Feb 6 16:46:04 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 01 of 05:'
echo 'x - hack.debug.c'
sed 's/^X//' > hack.debug.c << '/'
X/*
X * Hack.debug.c
X *
X * Debug function, only exists when DEBUG  if defined
X * Michiel and Fred
X */
X
X#include "hack.h"
X
X#ifdef DEBUG
Xdebug () {
X	nomove ();
X	pline( "You're in the debug function!" );
X}
X#endif DEBUG
/
echo 'x - hack.do.c'
sed 's/^X//' > hack.do.c << '/'
X/*
X * Hack.do.c
X */
X
X#include "hack.h"
X
Xextern char     NOTHIN[], WCLEV[], *nomvmsg;
X
Xchar    WELDED[] = "The %s is welded into your hand!";
X
X#define LETTER(ch)      ((ch >= '@' && ch <= 'Z' ) || \
X						       (ch >= 'a' && ch <= 'z'))
X#define CURSED		1
X#define NOTCURSED       0
X#define MAXLEVEL       40
X
X#define SIZE( x ) 	sizeof( x )/sizeof( x[0] )
X
X/* Routines to do various user commands */
X
Xdoglow (num)
Xregister        num;
X{
X	pline ("Your %s glows %s for a %s.", (flags.dac) ?
X		armors[uarm -> otyp].armnam : weapons[uwep -> otyp].wepnam,
X		(num < 0) ?
X		"black" : "green",
X		(num * num == 1) ?
X		"moment" : "while");
X}
X
Xdoread () {
X	register        OBJECT otmp;
X	register        MONSTER mtmp, mtmp2;
X	register        GOLD_TRAP gtmp;
X	OBJECT otmp2, otmp3;
X	int     num, zx, zy, xtmp, ytmp;
X
X	if (!(otmp = getobj ("?", "read"))) {
X		nomove ();
X		return;
X	}
X	pline ("As you read the scroll, it disappears.");
X
X /* 
X  Sometimes a scroll doesn't do anything
X  */
X	if (!rn2 (20)) {
X		pline ("You can't read the dialect!");
X		useup (otmp);
X		return;
X	}
X
X	switch (otmp -> otyp) {
X
X		case S_ENCH_ARMOR: 
X			if (!uarm) {
X				nothin (otmp);
X				return;
X			}
X			uarm -> cursed = 0;
X			uarm -> spe++;
X			u.uac--;
X			flags.dac = 1;
X			doglow (1);
X			break;
X
X		case S_DROP: 
X/*
X * New scroll instead of scroll of monster confusion. This scroll
X * drops everything you have on you. And put it somewhere on the level
X * Michiel and Fred
X */
X			pline ("Bloody hell, what's going on?");
X			do {
X				xtmp = rn2 (80);
X				ytmp = rn2 (22);
X			} while (levl[xtmp][ytmp].typ != ROOM);
X			useup (otmp);
X			oiden[S_DROP] |= SCRN;
X			doring (uleft, OFF);
X		/* Checked on existence in routine */
X			doring (uright, OFF);
X			for (otmp2 = invent; otmp2; otmp2 = otmp3) {
X				otmp3 = otmp2 -> nobj;
X				if (otmp2 == uarm || otmp2 == uarm2) {
X					u.uac += otmp2 -> spe;
X					flags.dac = 1;
X				}
X				otmp2 -> ox = xtmp;
X				otmp2 -> oy = ytmp;
X				subfrombill (otmp2);
X				otmp -> unpaid = 0;
X				otmp2 -> nobj = fobj;
X				fobj = otmp2;
X			}
X			if (u.ugold) {
X				gtmp = newgen ();
X				gtmp -> gx = xtmp;
X				gtmp -> gy = ytmp;
X				gtmp -> gflag = (unsigned) u.ugold;
X				gtmp -> ngen = fgold;
X				fgold = gtmp;
X				u.ugold = 0L;
X				flags.dgold = 1;
X			}
X			uright = NULL;
X			uleft = NULL;
X			uwep = NULL;
X			invent = NULL;
X			uarm = NULL;
X			uarm2 = NULL;
X			levl[xtmp][ytmp].scrsym = fobj -> olet;
X			levl[xtmp][ytmp].new = 0;
X			return;
X
X		case S_CURSE_LEV: /* Michiel */
X			pline ("Your body begins to glow black.");
X			docurse ();
X			u.uhcursed = 1;
X			break;
X
X		case S_REM_CURSE: 
X			pline ("You feel like someone is helping you.");
X			if (uleft)
X				uleft -> cursed = 0;
X			if (uright)
X				uright -> cursed = 0;
X			if (uarm)
X				uarm -> cursed = 0;
X			if (uarm2)
X				uarm2 -> cursed = 0;
X			if (uwep)
X				uwep -> cursed = 0;
X			break;
X
X		case S_ENCH_WEP: 
X		case S_DAM_WEP: 
X			if (!uwep) {
X				nothin (otmp);
X				return;
X			}
X			num = 5 - otmp -> otyp;/* 4 or 6 */
X			if (!rn2 (6))
X				num <<= 1;
X			uwep -> spe += num;
X			if (num > 0)
X				uwep -> cursed = 0;
X			doglow (num);
X			break;
X
X		case S_CREAT_MON: 
X			makemon (0);
X			mnexto (fmon);
X			break;
X
X		case S_GENOCIDE: 
X			pline ("You have found a scroll of genocide!");
X			do {
X				pline ("What monster do you want to genocide (Type the letter)? ");
X				flags.topl = 0;
X				getlin (buf);
X			} while (strlen (buf) != 1 || !LETTER (*buf) ||
X					 /* a3 */ index (genocided, *buf));
X			strcat (genocided, buf);
X			for (mtmp = fmon; mtmp; mtmp = mtmp2) {
X				mtmp2 = mtmp -> nmon;
X				if (mtmp -> data -> mlet == *buf)
X					cmdel (mtmp);
X			}
X			if (*buf == '@') {
X				killer = "scroll of genocide";
X				u.uhp = 0;
X			}
X			break;
X
X		case S_DESTR_ARMOR: 
X			if (!uarm) {
X				nothin (otmp);
X				return;
X			}
X			pline ("Your armor turns to dust and falls to the floor!");
X			u.uac += uarm -> spe;
X			flags.dac = 1;
X			useup (uarm);
X			uarm = uarm2;
X			uarm2 = 0;
X			break;
X
X		case S_LIGHT: 
X			litroom ();
X			break;
X
X		case S_TELEPORT: 
X/* 
X * Extended by Michiel and Fred:
X * One can jump between levels
X */
X			pline ("The scroll turns into an elevator.");
X			do {
X				pline ("Which stock please? ");
X				getlin (buf);
X				num = atoi (buf);
X			} while (num > MAXLEVEL - 3 && num != dlevel);
X			if (!*buf)
X				break;
X			if (num <= 0)
X				pline ("Don't fool around");
X			else if (num == dlevel)
X				tele ();
X			else if (u.ufloat || u.ustuck || getinventory ("\"")) {
X				nothin (otmp);
X				pline ("The elevator vanishes");
X				return;
X			}
X			else {
X				home ();
X				flush ();
X				keepdogs (1);
X				unCoff (COFF, 1);
X				dosavelev ();
X				if (num > dlevel) {
X					dlevel = (num > maxdlevel) ?
X						maxdlevel : num - 1;
X					while (dlevel < num) {
X						dodown ();
X						levl[u.ux][u.uy].scrsym = '<';
X					}
X				}
X				else {
X					dlevel = num + 1;
X					doup ();
X					levl[u.ux][u.uy].scrsym = '>';
X				}
X				land ();
X				losedogs ();
X				setCon (CON);
X				inshop ();/* a3: zie tele */
X			}
X			pline ("The elevator vanishes");
X			break;
X
X		case S_GOLD_DETEC: 
X			if (!fgold) {
X				nothin (otmp);
X				return;
X			}
X			cls ();
X			for (gtmp = fgold; gtmp; gtmp = gtmp -> ngen)
X				at (gtmp -> gx, gtmp -> gy, '$');
X			prme ();
X			pline ("You feel very greedy, and sense gold!");
X			more ();
X			docrt ();
X			break;
X
X		case S_IDENTIFY: 
X			pline ("This is an identify scroll.");
X			useup (otmp);
X			oiden[S_IDENTIFY] |= SCRN;
X			otmp = getobj (0, "identify");
X			if (otmp) {
X				switch (otmp -> olet) {
X					case '!': 
X						oiden[otmp -> otyp] |= POTN;
X						break;
X					case '?': 
X						oiden[otmp -> otyp] |= SCRN;
X						break;
X					case '/': 
X						oiden[otmp -> otyp] |= WANN;
X					case '[': 
X					case ')': 
X						otmp -> known = 1;
X						break;
X					case '=': 
X						oiden[otmp -> otyp] |= RINN;
X						if (otmp -> otyp >= R_GAIN_STR)
X							otmp -> known = 1;
X						break;
X				}
X				prinv (otmp);
X			}
X			return;
X
X		case S_MAG_MAP: 
X			pline ("On this scroll is a map!");
X			for (zy = 0; zy < 22; zy++)
X				for (zx = 0; zx < 80; zx++) {
X					if ((num = levl[zx][zy].typ) == SDOOR) {
X						levl[zx][zy].typ = DOOR;
X						atl (zx, zy, '+');
X					}
X					else if ((num >= WALL && num <= CORR) &&
X					/* or DOOR; no SDOOR */
X							!levl[zx][zy].seen)
X						newunseen (zx, zy);
X					else if (num >= 30 && num <= 41)
X						newunseen (zx, zy);
X				}
X			newunseen (xupstair, yupstair);
X			if (xdnstair)/* maze */
X				newunseen (xdnstair, ydnstair);
X			break;
X
X		case S_FIRE: 
X			pline ("The scroll erupts in a tower of flame!");
X			if (u.ufireres)
X				pline ("You are uninjured.");
X			else {
X				num = rnd (6);
X				losehp (num, "scroll of fire");
X				u.uhpmax -= num;
X				flags.dhpmax = 1;
X			}
X			break;
X
X		default: 
X			pline ("Bad(%d)scroll", otmp -> otyp);
X			impossible ();
X
X	}
X	if (!(oiden[otmp -> otyp] & SCRN)) {
X		if (otmp -> otyp > S_CREAT_MON && (otmp -> otyp != S_LIGHT
X					|| !u.ublind)) {
X			oiden[otmp -> otyp] |= SCRN;
X			u.urexp += 10;
X		}
X		else if (!scrcall[otmp -> otyp])
X			docall (otmp);
X	}
X	if (u.uhcursed && otmp -> otyp == S_REM_CURSE) {
X		u.uhcursed = 0;
X		pline ("Your body stops glowing black.");
X	}
X	useup (otmp);
X}
X
Xlitroom () {
X	register        zx, zy;
X
X	if (!xdnstair || !dlevel) {
X		pline (NOTHIN);
X		return;
X	}
X	if (levl[u.ux][u.uy].typ == CORR) {
X		if (!u.ublind)
X			pline ("The corridor lights up around you, then fades.");
X		return;
X	}
X	else if (!u.ublind)
X		if (levl[u.ux][u.uy].lit)
X			pline ("The room lights up around you.");
X		else
X			pline ("The room is lit.");
X	if (levl[u.ux][u.uy].lit)
X		return;
X	if (levl[u.ux][u.uy].typ == DOOR) {
X		if (levl[u.ux][u.uy + 1].typ == ROOM)
X			zy = u.uy + 1;
X		else if (levl[u.ux][u.uy - 1].typ == ROOM)
X			zy = u.uy - 1;
X		else
X			zy = u.uy;
X		if (levl[u.ux + 1][u.uy].typ == ROOM)
X			zx = u.ux + 1;
X		else if (levl[u.ux - 1][u.uy].typ == ROOM)
X			zx = u.ux - 1;
X		else
X			zx = u.ux;
X	}
X	else {
X		zx = u.ux;
X		zy = u.uy;
X	}
X	for (seelx = u.ux; levl[seelx - 1][zy].typ % 2; seelx--);
X /* ROOM or WALL or DOOR */
X	for (seehx = u.ux; levl[seehx + 1][zy].typ % 2; seehx++);
X	for (seely = u.uy; levl[zx][seely - 1].typ % 2; seely--);
X	for (seehy = u.uy; levl[zx][seehy + 1].typ % 2; seehy++);
X	for (zy = seely; zy <= seehy; zy++)
X		for (zx = seelx; zx <= seehx; zx++) {
X			levl[zx][zy].lit = 1;
X			if (!u.ublind && dist (zx, zy) > 2)
X				prl (zx, zy);
X		}
X}
X
Xdodrink () {
X	register        OBJECT otmp, objs;
X	register        MONSTER mtmp;
X	register        num;
X
X	if (!(otmp = getobj ("!", "drink"))) {
X		nomove ();
X		return;
X	}
X	switch (otmp -> otyp) {
X
X		case P_REST_STR: 
X			pline ("Wow!  This makes you feel great!");
X			if (u.ustr < u.ustrmax) {
X				u.ustr = u.ustrmax;
X				flags.dstr = 1;
X			}
X			break;
X
X		case P_BOOZE: 
X			pline ("Ooph!  This tastes like liquid fire!");
X			u.uconfused += d (3, 8);
X			if (u.uhp < u.uhpmax)
X				losehp (-1, "");
X			if (!rn2 (4)) {
X				pline ("You pass out.");
X				multi = -rnd (15);
X				nomvmsg = "You awake with a headache.";
X			}
X			break;
X
X		case P_INVIS: 
X			pline ("Gee!  All of a sudden, you can't see yourself.");
X			newsym (u.ux, u.uy);
X			u.uinvis += rn1 (15, 31);
X			break;
X
X		case P_JUICE: 
X			pline ("This tastes like fruit juice.");
X			lesshungry (20);
X			break;
X
X		case P_HEALING: 
X			pline ("You begin to feel better.");
X			num = rnd (10);
X	H: 
X			if (u.uhp + num > u.uhpmax) {
X				u.uhp = ++u.uhpmax;
X				if (otmp -> otyp == P_EXTRA_HEALING)
X					u.uhp = ++u.uhpmax;
X				flags.dhpmax = 1;
X			}
X			else
X				u.uhp += num;
X			flags.dhp = 1;
X			if (u.ublind)
X				u.ublind = 1;
X			break;
X
X		case P_FROZEN: 
X			pline ("Your feet are frozen to the floor!");
X			nomul (-rn1 (10, 25));
X			break;
X
X		case P_MONDETEC: 
X			if (!fmon) {
X				nothin (otmp);
X				return;
X			}
X			cls ();
X			for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon)
X				at (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet);
X			killer = "monster";
X	P: 
X			prme ();
X			pline ("You sense the presence of %ss.", killer);
X			more ();
X			docrt ();
X			break;
X
X		case P_OBJDETEC: 
X			if (!fobj) {
X				nothin (otmp);
X				return;
X			}
X			cls ();
X			for (objs = fobj; objs; objs = objs -> nobj)
X				at (objs -> ox, objs -> oy, objs -> olet);
X			killer = "object";
X			goto P;
X
X		case P_POISON: 
X			pline ("Yech! This stuff tastes like poison.");
X			losestr (rn1 (4, 3));
X			losehp (rnd (10), "poison potion");
X			break;
X
X		case P_CONF: 
X			pline ("Huh, What?  Where am I?");
X			u.uconfused += rn1 (7, 16);
X			break;
X
X		case P_GAIN_STR: 
X			if (u.ustr == 118) {
X				pline ("You've had enough of it!");
X				break;/* Michiel */
X			}
X			pline ("Wow do you feel strong!");
X			if (u.ustr > 17)
X				u.ustr += rnd (118 - u.ustr);
X			else
X				u.ustr++;
X			if (u.ustr > u.ustrmax)
X				u.ustrmax = u.ustr;
X			flags.dstr = 1;
X			break;
X
X		case P_SPEED: 
X			pline ("You are suddenly moving much faster.");
X			u.ufast += rn1 (10, 100);
X			break;
X
X		case P_BLIND: 
X			pline ("A cloud of darkness falls upon you.");
X			u.ublind += rn1 (100, 250);
X			unCoff (COFF, 0);
X			break;
X
X		case P_GAIN_LEV: 
X			num = rnd (10);
X			u.uhpmax += num;
X			u.uhp += num;
X			if (u.ulevel < 14) {/* a3 */
X				pline ("You feel more experienced.");
X				u.uexp = (10 * pow (u.ulevel - 1)) + 1;
X				pline (WCLEV, ++u.ulevel);
X				flags.dulev = 1;
X				flags.dexp = 1;
X			}
X			else
X				pline ("You feel more capable.");
X			flags.dhpmax = 1;
X			flags.dhp = 1;
X			break;
X
X		case P_EXTRA_HEALING: 
X			pline ("You feel much better.");
X			num = d (2, 20) + 1;
X			goto H; /* a3 */
X
X		default: 
X			pline ("Bad(%d)potion", otmp -> otyp);
X			impossible ();
X	}
X
X	if (!(oiden[otmp -> otyp] & POTN)) {
X		if (otmp -> otyp > P_BOOZE) {
X			oiden[otmp -> otyp] |= POTN;
X			u.urexp += 10;
X		}
X		else if (!potcall[otmp -> otyp])
X			docall (otmp);
X	}
X	useup (otmp);
X}
X
Xnothin (obj)
Xregister        OBJECT obj;
X{
X	pline ("You have a strange feeling for a moment, then it passes.");
X	if (obj -> olet == '?') {
X		if ((!(oiden[obj -> otyp] & SCRN)) &&
X				(!scrcall[obj -> otyp]))
X			docall (obj);
X	}
X	else if ((!(oiden[obj -> otyp] & POTN)) &&
X			(!potcall[obj -> otyp]))
X		docall (obj);
X	useup (obj);
X}
X
Xdodrop () {
X	register        OBJECT obj, otmp;
X	register int    num;
X
X	if (!(obj = getobj (0, "drop"))) {
X		nomove ();
X		return;
X	}
X	if (obj -> quan > 1 && !obj -> unpaid) {
X		pline ("How many do you want to drop (%d max) ?",
X				obj -> quan);
X		getlin (buf);
X		num = atoi (buf);
X
X		if (num > obj -> quan || (num <= 0 && *buf) ||
X				*buf == 0) {
X			if (num != 0)
X				pline ("You can't drop that %s!",
X						(num > 0) ? "many" : "few");
X			nomove ();
X			return;
X		}
X		if (num != obj -> quan) {
X			otmp = newobj ();
X			*otmp = *obj;/* Copies whole structure */
X			obj -> quan = num;
X			otmp -> quan -= num;
X			obj -> nobj = otmp;
X		}
X	}
X	if (obj == uarm || obj == uarm2 ||
X			obj == uright || obj == uleft) {
X		pline ("You cannot drop something you are wearing.");
X		nomove ();
X		return;
X	}
X /* (a3) i.p.v. `if( obj==uwep) uwep=0;':  */
X	if (obj == uwep && uwepcursed ())
X		return;
X	dropit (obj);
X	doname (fobj, buf);
X	pline ("You dropped %s.", buf);
X	subfrombill (obj);
X}
X
Xgemsdrop () {
X	register        OBJECT obj;
X	register        counting = 0;
X
X	for (obj = invent; obj;) {
X		if (obj -> olet == '*') {
X			counting += obj -> quan;
X			dropit (obj);
X			subfrombill (obj);
X			obj = invent;
X		}
X		else
X			obj = obj -> nobj;
X	}
X	if (!counting) {
X		nomove ();
X		pline ("You ain't got no gems, Hacker!");
X	}
X	else
X		pline ("You dropped %d gem%s.", counting,
X				counting == 1 ? "" : "s");
X}
X
Xuwepcursed () {			/* a3,drop or throw uwep */
X	if (uwep -> cursed) {
X		multi = 0;	/* Dowield() */
X		pline (WELDED, weapons[uwep -> otyp].wepnam);
X		return CURSED;
X	}
X	uwep = 0;
X	return NOTCURSED;
X}
X
Xgetinventory (string)
Xchar   *string;
X{
X	register        OBJECT otmp;
X
X	for (otmp = invent; otmp && !index (string, otmp -> olet); otmp =
X			otmp -> nobj);
X	return (otmp ? 1 : 0);
X}
X
Xdropit (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	if (obj == invent)
X		invent = invent -> nobj;
X	else {
X		for (otmp = invent; otmp -> nobj != obj;
X				otmp = otmp -> nobj);
X		otmp -> nobj = obj -> nobj;
X	}
X	obj -> ox = u.ux;
X	obj -> oy = u.uy;
X	obj -> nobj = fobj;
X	fobj = obj;
X	if (u.uinvis)
X		newsym (u.ux, u.uy);
X}
/
echo 'x - hack.h'
sed 's/^X//' > hack.h << '/'
X/*
X * Hack.h
X */
X
X#define NORMAL_IO
X#ifdef NORMAL_IO
X
X#include <stdio.h>
X#define flush()		fflush( stdout )
X
X#else
X
X#undef putchar
X#undef getchar
X#define NULL	0
X#define STDOUT  0		/* Defines print in I/O packet */
X
X#endif NORMAL_IO
X
X#include "envir.h"
X#include "hack.name.h"
X
Xchar   *index ();
X
Xlong    pow ();
X
X#define BUFSZ   256
X
X
X/* Arguments for panic to give just an error message or a core dump */
X#define NOCORE	0
X#define CORE	1
X
X#define ON      1
X#define OFF     0
X
X#define WALL    1
X#define SDOOR   2
X#define DOOR    3
X#define CORR    4
X#define ROOM    5
X#define POOL    7
X#define VAULT   9
X
X#define TRAPNUM 9
X
X#define MSLOW   1
X#define MFAST   2
X
X#define BEAR    0
X#define ARROW   1
X#define DART    2
X#define TDOOR   3
X#define TELE    4
X#define PIT     5
X#define SLPTRP  6
X#define PIERC   7
X#define MIMIC   8
X#define SEEN    32
X
X#define UWEP	0
X#define UARM    1
X#define UARM2   2
X#define ULEFT   3
X#define URIGHT  4
X
X#define POTN    1
X#define SCRN    2
X#define WANN    4
X#define RINN    8
X
X#define UNC     1		/* unCoff(): */
X#define COFF    0
X
X#define SETC    1		/* setCon(): */
X#define CON     0
X
X#define IT1     1
X#define THEIT2  2		/* kluns */
X
X#define CHOKED  0
X#define DIED    1
X#define STARVED 2
X#define DROWNED 3
X#define QUIT    4		/* Michiel args how you died */
X#define ESCAPED 5
X
X#define NOMOVE  0
X#define MOVE    1
X#define DEAD    2
X
X#define MISS    0
X#define HIT     1
X#define KILL    2
X
X
X
Xtypedef struct func_tab {
X	char    f_char;
X	int     (*f_funct) ();
X} FUNCTIONS;
Xextern  FUNCTIONS list[];
X
X
X
Xstruct rm {
X	unsigned        scrsym:	7;
X	unsigned        typ:	6;
X	unsigned        new:	1;
X	unsigned        seen:	1;
X	unsigned        lit:	1;
X};
Xtypedef struct rm       PART;
Xextern  PART levl[80][22];
X
X
X
X
Xstruct mkroom {
X	char    lx, hx, ly, hy, rtype, rlit, doorct, fdoor;
X};
Xtypedef struct mkroom   MKROOM;
Xextern  MKROOM rooms[15];
X
X
X
X#define DOORMAX 100
Xstruct coord {
X	char    x, y;
X};
Xtypedef struct coord    COORDINATES;
Xextern  COORDINATES doors[DOORMAX];
X
X
X
Xstruct food {
X	char   *foodnam, prob, delay;
X	int     nutrition;
X};
Xtypedef struct food    *FOOD;
Xextern struct food      foods[];
X
X
X
Xstruct armor {
X	char   *armnam, prob, delay, a_ac, a_can;
X};
Xtypedef struct armor   *ARMOR;
Xextern struct armor     armors[];
X
X
X
X
X
Xstruct weapon {
X	char   *wepnam, prob, wsdam, wldam;
X};
Xtypedef struct weapon  *WEAPON;
Xextern struct weapon    weapons[];
X
X
X
X
Xstruct permonst {
X	char   *mname, mlet, mhd, mmove, ac, damn, damd;
X	unsigned        pxlth;
X};
Xtypedef struct permonst *MONSTDATA;
Xextern struct permonst  mon[8][7];
X#define PM_MIMIC        &mon[5][2]
X#define PM_PIERC        &mon[2][3]
X#define PM_DEMON        &mon[7][6]
X#define PM_CHAM         &mon[6][6]
X
X
X
X
Xstruct obj {
X	struct obj     *nobj;
X	char    otyp;
X	int     spe;
X	unsigned        ox:	7;
X	unsigned        oy:	5;
X	unsigned        olet:	7;
X	unsigned        quan:	5;
X	unsigned        known:	1;
X	unsigned        cursed: 1;
X	unsigned        unpaid:	1;
X};
Xtypedef struct obj     *OBJECT;
Xextern  OBJECT fobj, invent, uwep, uarm, uarm2, uleft, uright;
X
X
X
Xstruct stole {
X	OBJECT sobj;
X	unsigned        sgold;
X};
Xtypedef struct stole   *STOLE;
X
X
Xstruct monst {
X	struct monst   *nmon;
X	MONSTDATA	data;
X	STOLE		mstole;
X	char    mx, my;
X	int     mhp, orig_hp;
X	unsigned        invis:	1;
X	unsigned        cham:	1;
X	unsigned        angry:	1;	/* Michiel: only for shopkeeper */
X	unsigned        ale:	1;	/* Michiel: is it an ale?? */
X	unsigned        mspeed:	2;
X	unsigned        msleep: 1;
X	unsigned        mfroz:	1;
X	unsigned        mconf:	1;
X	unsigned        mflee:	1;
X	unsigned        mcan:	1;
X	unsigned        mtame:	1;
X	unsigned        wormno: 5;
X	unsigned        mxlth;
X	char    mextra[1];
X};
Xtypedef struct monst   *MONSTER;
Xextern  MONSTER fmon, shopkeeper, vaultkeeper;
Xextern struct permonst  treasurer;
X
XMONSTER m_at ();
X
X
X
Xstruct wseg {
X	struct wseg    *nseg;
X	char    wx, wy;
X};
X
Xtypedef struct wseg    *WORMSEGMENT;
X
X#define newseg()        (alloc( sizeof(struct wseg) )->Wseg)
X
X
Xstruct gen {
X	struct gen     *ngen;
X	char    	gx, gy;
X	unsigned        gflag;
X};
Xtypedef struct gen     *GOLD_TRAP;
Xextern  GOLD_TRAP fgold, ftrap;
X
XGOLD_TRAP g_at ();
XOBJECT o_at (), getobj ();
X
X
Xstruct flag {
X	unsigned        topl:		1;
X	unsigned        botl:		1;
X /* faint:1, screen:1, */
X	unsigned        oneline:	1;
X	unsigned        next:		1;
X	unsigned        move:		1;
X	unsigned        mv:		1;
X	unsigned        run:		2;
X	unsigned        dgold:		1;
X	unsigned        dhp:		1;
X	unsigned        dhpmax:		1;
X	unsigned        dstr:		1;
X	unsigned        dac:		1;
X	unsigned        dulev:		1;
X	unsigned        dexp:		1;
X	unsigned        dhs:		1;
X	unsigned        dscr:		1;
X};
Xtypedef struct flag     FLAG;
Xextern  FLAG flags;
X
Xstruct you {
X	char    ux, uy, ustr, ustrmax, udaminc, uac;
X	int     uhunger;
X	unsigned        ufast:		7;
X	unsigned        uconfused:	6;
X	unsigned        uinvis:		6;
X	unsigned        ulevel:		5;
X	unsigned        utrap:		3;
X	unsigned        upit:		1;
X	unsigned        uinshop:	1;
X	unsigned        uinzoo:		1;
X	unsigned        uinyard:	1;
X	unsigned        uinswamp:	1;
X	unsigned        uinknox:	1;
X	unsigned        umconf:		1;
X	unsigned        uhcursed:	1;
X	unsigned        ufireres:	1;
X	unsigned        ucoldres:	1;
X	unsigned        utel:		1;
X	unsigned        upres:		1;
X	unsigned        ustelth:	1;
X	unsigned        uagmon:		1;
X	unsigned        ufeed:		1;
X	unsigned        usearch:	1;
X	unsigned        ucinvis:	1;
X	unsigned        uregen:		1;
X	unsigned        ufloat:		1;
X	unsigned        uswallow:	1;
X	unsigned        uswldtim:	4;
X	unsigned        ucham:		1;
X	unsigned        uhs:		2;
X	unsigned        ublind;
X	short   uhp, uhpmax;
X	long    ugold, uexp, urexp;
X	MONSTER ustuck;
X};
Xtypedef struct you      YOU;
Xextern  YOU u;
X
X
X
Xextern char    *wepnam[], *pottyp[], *scrtyp[], *traps[],
X               *wantyp[], *ringtyp[], *potcol[], *scrnam[],
X               *wannam[], *rinnam[], wdam[], oiden[],
X               *potcall[], *scrcall[], *wandcall[], *ringcall[],
X                curx, cury, savx,
X                xdnstair, ydnstair, xupstair, yupstair,
X                seehx, seelx, seehy, seely,
X               *save_cm, *killer, dlevel, maxdlevel,
X                dx, dy, buf[], lock[],
X                genocided[60], oldux, olduy, wizard;
X
Xextern unsigned moves;
X
Xextern  multi;
X
X#define newmonst(xl)    (alloc( xl + sizeof(struct monst) )->Mtmp )
X#define newobj()        (alloc( sizeof(struct obj) )->Otmp )
X#define newgen()        (alloc( sizeof(struct gen) )->Gtmp )
X#define newstole()      (alloc( sizeof(struct stole) )->Stmp )
X
X
X#define CHAR_NULL	(char *)NULL
X#define OBJ_NULL	(struct obj *)NULL
X#define TRAP_NULL	(struct gen *)NULL
X#define MON_NULL	(struct monst *)NULL
X#define STOLE_NULL	(struct stole *)NULL
X
X#ifndef SHOW
Xunion PTRS {
X	GOLD_TRAP Gtmp;
X	MONSTER Mtmp;
X	OBJECT Otmp;
X	STOLE Stmp;
X	WORMSEGMENT Wseg;
X	char   *Val;
X};
X
Xextern  union PTRS * alloc ();
X#endif SHOW
/
echo 'x - hack.mon.do.c'
sed 's/^X//' > hack.mon.do.c << '/'
X/*
X * Hack.mon.do.c
X */
X
X/* Contains monster control routines */
X
X#include "hack.h"
X
Xextern  MONSTER bhit ();
X
Xmovemon () {
X	register        MONSTER mtmp, mtmp2;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp2) {
X		mtmp2 = mtmp -> nmon;
X		if (mtmp -> mspeed != MSLOW || moves % 2 == 0)
X			if (dochug (mtmp))
X				continue;/* Monster died */
X		if (mtmp -> mspeed == MFAST)
X			if (dochug (mtmp))
X				continue;
X
X/* If we left the room: make monsters invis, even if they didn't move */
X
X		if (!cansee (mtmp -> mx, mtmp -> my))
X			levlsym (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet);
X		if (mtmp -> wormno && mtmp -> data -> mlet == 'w')
X			wormsee (mtmp -> wormno);
X	}
X}
X
Xjustswld (mtmp)
Xregister        MONSTER mtmp;
X{
X	newsym (mtmp -> mx, mtmp -> my);
X	mtmp -> mx = u.ux;
X	mtmp -> my = u.uy;
X	u.ustuck = mtmp;
X	at (u.ux, u.uy, mtmp -> data -> mlet);
X	pseebl ("%s swallows you!", mtmp -> data -> mname);
X	more ();
X	u.uswallow = 1;
X	docrt ();
X}
X
Xyouswld (mtmp, dam, die)
Xregister        MONSTER mtmp;
Xregister        dam, die;
X{
X	pseebl ("%s digests you!", killer = mtmp -> data -> mname);
X	if (dam > 0) {
X		u.uhp -= dam;
X		flags.dhp = 1;
X	}
X	if (u.uswldtim++ == die) {
X		pline ("It totally digests you!");
X		u.uhp = 0;
X	}
X}
X
Xx2hitu (mlev, x, name)
Xregister        mlev, x;
Xregister char  *name;		/* a3 */
X{
X	register        i;
X
X	for (i = 0; i < 2; i++)
X		hitu (mlev, (x < 0) ? d (2, x) : (x == 0) ? d (3, 4) :
X				rnd (x), name);
X}
X
Xdochug (mtmp)
Xregister        MONSTER mtmp;
X{
X	register        MONSTDATA mdat;
X	register        tmp = 0, ctmp;
X
X	if (mtmp -> mhp <= 0 && !mtmp -> mtame)
X		return 1;	/* Killed by dog or ? */
X	if (mtmp -> cham && !rn2 (6))
X		newcham (mtmp, &mon[rn1 (6, 2)][rn2 (7)]);
X	mdat = mtmp -> data;
X /* 
X  if( mdat->mhd < 0 )
X  panic( CORE, "Bad(%d)monster %c", mdat->mhd,
X  mdat->mlet );
X  */
X	if ((moves % 20 == 0 || index ("ViT", mdat -> mlet)) &&
X			mtmp -> mhp < mtmp -> orig_hp)
X		mtmp -> mhp++;	/* Regenerate monsters */
X	if (mtmp -> mfroz)
X		return 0;	/* Frozen monsters don't do anything */
X	if (mtmp -> msleep) {
X	/* Wake up a monster, or get out of here */
X		if (cansee (mtmp -> mx, mtmp -> my) && !u.ustelth &&
X				(!rn2 (7) || u.uagmon))
X			mtmp -> msleep = 0;
X		else
X			return 0;
X	}
X
X/* Confused monsters get unconfused with small probability */
X
X	if (mtmp -> mconf && !rn2 (50))
X		mtmp -> mconf = 0;
X	if (mdat -> mmove >= rnd (12) && (mtmp -> mflee || mtmp -> mconf ||
X				dist (mtmp -> mx, mtmp -> my) > 2 || mtmp -> mtame ||
X				mtmp == shopkeeper) && (tmp = m_move (mtmp, 0)) &&
X			mdat -> mmove <= 12)
X		return (tmp == 2);
X /* Move monsters and exit if rate<=12 */
X	if (tmp == 2)
X		return 1;	/* Monster died moving */
X
X	if (!index ("Ea", mdat -> mlet) && dist (mtmp -> mx, mtmp -> my) < 3
X			&& !mtmp -> mtame && mtmp != shopkeeper && u.uhp > 0) {
X		nomul (tmp = 0);
X		if (u.uswallow) {
X			if (mtmp != u.ustuck)
X				if (mdat -> mmove - 12 > rnd (12))
X					tmp = m_move (mtmp, 1);
X		}
X		else if (!index ("&DyF", mdat -> mlet)) {
X			if (mtmp -> ale && cansee (mtmp -> mx, mtmp -> my)) {
X				mtmp -> invis = 0;
X				pmon (mtmp);
X			}
X			tmp = hitu (mdat -> mhd, d (mdat -> damn, mdat -> damd),
X					mdat -> mname);
X		}
X
X/* Increase chance of hitting (no damage) for L and R */
X		if (index ("LR", mdat -> mlet) && hitu (5, 0, mdat -> mname))
X			tmp++;
X
X		ctmp = (tmp && !mtmp -> mcan && (!uarm ||
X					armors[uarm -> otyp].a_can < rnd (3)));
X
X		switch (mdat -> mlet) {
X
X			case ';': 
X				if (mtmp -> mcan)
X					break;
X				if (!u.ustuck && !rn2 (20)) {
X					p2xthe ("%s swings itself around you!",
X							mdat -> mname);
X					u.ustuck = mtmp;
X				}
X				else if (u.ustuck == mtmp && ctmp) {
X					p2xthe ("%s drowns you...", mdat -> mname);
X					more ();
X					done (DROWNED);
X				}
X				break;
X
X			case '&': 
X				if (!mtmp -> mcan && !rn2 (15)) {
X					makemon (PM_DEMON);
X					mnexto (fmon);
X				}
X				else {
X					x2hitu (10, -6, mdat -> mname);
X					x2hitu (10, 3, mdat -> mname);
X					hitu (10, rn1 (4, 2), mdat -> mname);
X				}
X				break;
X
X			case ',': 
X			case '\'': 
X				if (u.uswallow)
X					if (mdat -> mlet == ',')
X						youswld (mtmp, 4 + u.uac, 5);
X					else
X						youswld (mtmp, rnd (6), 7);
X				else if (tmp)
X					justswld (mtmp);
X				break;
X
X			case 'A': 
X				if (ctmp && rn2 (2)) {
X					pline ("You feel weaker!");
X					losestr (1);
X				}
X				break;
X
X			case 'C': 
X			case 'Y': 
X				hitu (4, rnd (6), mdat -> mname);
X				break;
X
X			case 'c': 
X				if (ctmp && !rn2 (5)) {
X					pline ("You get turned to stone!");
X					u.uhp = 0;
X				}
X				break;
X
X			case 'D': 
X				if (rn2 (6) || mtmp -> mcan) {
X					hitu (10, d (3, 10), mdat -> mname);
X					x2hitu (10, 8, mdat -> mname);
X					break;
X				}
X				pseebl ("%s breathes fire!", mdat -> mname);
X				buzz (Z_FIRE, mtmp -> mx, mtmp -> my,
X						u.ux - mtmp -> mx,
X						u.uy - mtmp -> my);
X				break;
X
X			case 'd': 
X				hitu (6, d (2, 4), mdat -> mname);
X				break;
X
X			case 'e': 
X				hitu (10, d (3, 6), mdat -> mname);
X				break;
X
X			case 'F': 
X				if (mtmp -> mcan)
X					break;
X				pseebl ("%s explodes!", mdat -> mname);
X				if (u.ucoldres)
X					pline ("You don't seem affected by it.");
X				else {
X					if (17 - (u.ulevel >> 1) > rnd (20)) {
X						pline ("You get blasted!");
X						tmp = 6;
X					}
X					else {
X						pline ("You duck the blast...");
X						tmp = 3;
X					}
X					losehp (d (tmp, 6), mdat -> mname);
X				}
X				cmdel (mtmp);
X				return 1;
X
X			case 'g': 
X				if (!ctmp || multi < 0 || rn2 (6))
X					break;
X				pseebl ("You are frozen by %ss juices", "cube'");
X				nomul (-rnd (10));
X				break;
X
X			case 'h': 
X				if (!ctmp || multi < 0 || rn2 (5))
X					break;
X				pseebl ("You are put to sleep by %ss bite!",
X						"homunculus'");
X				nomul (-rnd (10));
X				break;
X
X			case 'j': 
X				tmp = hitu (4, rnd (3), mdat -> mname);
X				tmp &= hitu (4, rnd (3), mdat -> mname);
X				if (tmp)
X					x2hitu (4, 4, mdat -> mname);
X				break;
X
X			case 'k': 
X				if ((hitu (4, rnd (4), mdat -> mname) || !rn2 (3))
X						&& ctmp)
X					poisoned ("bee's sting", mdat -> mname);
X				break;
X
X			case 'L': 
X				if (ctmp && u.ugold && rn2 (2)) {
X					u.ugold -= (ctmp = somegold ());
X					pline ("Your purse feels lighter.");
X					flags.dgold = 1;
X
X				/* Michiel save stolen gold */
X					if (mtmp -> mstole)
X						mtmp -> mstole -> sgold += ctmp;
X					else {
X						mtmp -> mstole = newstole ();
X						mtmp -> mstole -> sobj = 0;
X						mtmp -> mstole -> sgold = ctmp;
X					}
X					mtmp -> mflee = 1;
X					rloc (mtmp);
X				}
X				break;
X
X			case 'N': 
X				if (ctmp && invent && rn2 (2)) {
X					steal (mtmp);
X					rloc (mtmp);
X					mtmp -> mflee = 1;
X				}
X				break;
X
X			case 'n': 
X				x2hitu (11, -6, mdat -> mname);
X				break;
X
X			case 'o': 
X				hitu (5, rnd (6), mdat -> mname);
X				/*  tmp= ??  */
X				if (hitu (5, rnd (6), mdat -> mname) && ctmp &&
X						!u.ustuck && rn2 (2)) {
X					u.ustuck = mtmp;
X					pseebl ("%s has grabbed you!",
X							mdat -> mname);
X					u.uhp -= d (2, 8);
X					break;
X				}
X				if (u.ustuck == mtmp) {
X					pline ("You are being crushed.");
X					u.uhp -= d (2, 8);
X				}
X				break;
X
X			case 'P': 
X				if (u.uswallow)
X					youswld (mtmp, d (2, 4), 12);
X				else if (ctmp && !rn2 (4))
X					justswld (mtmp);
X				else
X					hitu (15, d (2, 4), mdat -> mname);
X				break;
X
X			case 'Q': 
X				x2hitu (3, 2, mdat -> mname);
X				break;
X
X			case 'R': 
X				if (ctmp && uarm && uarm -> otyp < A_STD_LEATHER
X						&& uarm -> spe > -2) {
X					pline ("Your armor rusts!");
X					--uarm -> spe;
X					u.uac++;
X					flags.dac = 1;
X				}
X				break;
X
X			case 'S': 
X				if (ctmp && !rn2 (8))
X					poisoned ("snake's bite", mdat -> mname);
X				break;
X
X			case 's': 
X				if (tmp && !rn2 (8))
X					poisoned ("scorpion's sting",
X							mdat -> mname);
X				x2hitu (5, 8, mdat -> mname);
X				break;
X
X			case 'T': 
X				x2hitu (6, 6, mdat -> mname);
X				break;
X
X			case 'U': 
X				x2hitu (9, 0, mdat -> mname);/* 0: d(3,4) */
X				break;
X
X			case 'v': 
X				if (ctmp && !u.ustuck)
X					u.ustuck = mtmp;
X				break;
X
X			case 'V': 
X				if (tmp)
X					u.uhp -= 4;
X				if (rn2 (3))
X					break;
X		V: 
X				if (ctmp) {/* hit by V or W */
X					if (u.ulevel > 1)
X						pline ("Goodbye level %d.",
X								u.ulevel--);
X					else
X						u.uhp = 0;
X					ctmp = rnd (10);
X					u.uhp -= ctmp;
X					u.uhpmax -= ctmp;
X					u.uexp = 10L * pow (u.ulevel - 1) - 1L;
X					flags.dhp = 1;
X					flags.dhpmax = 1;
X					flags.dulev = 1;
X					flags.dexp = 1;
X				}
X				break;
X
X			case 'W': 
X				if (rn2 (5))
X					break;
X				goto V;
X			case 'w': 
X				if (tmp)
X					wormhit (mtmp);
X				break;
X			case 'X': 
X				for (tmp = 0; tmp < 3; tmp++)
X					hitu (8, rnd (3), mdat -> mname);
X				break;
X
X			case 'y': 
X				if (mtmp -> mcan)
X					break;
X				cmdel (mtmp);
X				if (!u.ublind) {
X					pline ("You are blinded by a blast of light!");
X					u.ublind = d (4, 12);
X					unCoff (COFF, 0);
X				}
X				return 1;
X		}		/* switch */
X
X		if (u.uhp <= 0)
X			killer = mdat -> mname;
X	}
X	else if (mtmp -> ale && cansee (mtmp -> mx, mtmp -> my)) {
X		mtmp -> invis = 1;
X		newsym (mtmp -> mx, mtmp -> my);
X	}
X/* Extra movement for fast monsters */
X	if (mdat -> mmove - 12 > rnd (12))
X		tmp = m_move (mtmp, 1);
X	return (tmp == 2);
X}
X
Xcmdel (mtmp)
Xregister        MONSTER mtmp;
X{
X	register char   mx = mtmp -> mx, my = mtmp -> my;
X
X	delmon (mtmp);
X	if (cansee (mx, my))
X		newsym (mx, my);
X}
X
Xinrange (mtmp)
Xregister        MONSTER mtmp;
X{
X	int     zx, zy;
X	register char   tx = u.ux - mtmp -> mx, ty = u.uy - mtmp -> my;
X
X/* This mess figures out if the person is within 8 */
X	if ((!tx && abs (ty) < 8) || (!ty && abs (tx) < 8) ||
X			(abs (tx) == abs (ty) && abs (tx) < 8)) {
X		if (tx == 0)
X			zx = 0;
X		else
X			zx = tx / abs (tx);
X		if (ty == 0)
X			zy = 0;
X		else
X			zy = ty / abs (ty);
X/* If we don't save dx and dy a capital move may screw up: */
X		tx = dx;
X		ty = dy;
X		if (bhit (zx, zy, 8) == mtmp)
X			buzz (Z_FIRE, mtmp -> mx, mtmp -> my, dx, dy);
X		dx = zx;
X		dy = zy;
X	}
X}
X
Xm_move (mtmp, after)
Xregister        MONSTER mtmp;
X{
X	register        MONSTER mtmp2;
X	register        nix, niy, omx, omy, appr, nearer, cnt, zx, zy;
X	char    ddx, ddy, mmoved = 0;
X
X/* My dog gets a special treatment */
X	if (mtmp -> mtame)
X		return dog_move (mtmp, after);
X
X	if (u.uswallow)
X		return (1);	/* a3 */
X/* Likewise for shopkeeper */
X	if (mtmp == shopkeeper)
X		return shk_move ();
X	if (mtmp == vaultkeeper && !mtmp -> angry)
X		return (0);
X
X	if (mtmp -> data -> mlet == 't' && !rn2 (19)) {
X		if (rn2 (2)) {
X			ddx = mtmp -> mx;
X			ddy = mtmp -> my;
X			mnexto (mtmp);/* Doesn't change old position */
X			levlsym (ddx, ddy, 't');
X		}
X		else
X			rloc (mtmp);/* Rloc does */
X		return 1;
X	}
X	if (!mtmp -> mcan)
X		switch (mtmp -> data -> mlet) {
X			case 'D': 
X				inrange (mtmp);
X				break;
X			case 'U': 
X				if (!rn2 (10) && !u.uconfused &&
X						cansee (mtmp -> mx, mtmp -> my)) {
X					pline ("You are confused!");
X					u.uconfused = d (3, 4);
X				}
X				if (!mtmp -> mflee && u.uswallow &&
X						u.ustuck != mtmp)
X					return 1;
X		}
X	appr = 1;
X	if (mtmp -> mflee)
X		appr = -1;
X	if (mtmp -> mconf || u.uinvis || (index ("BI", mtmp -> data -> mlet) &&
X				!rn2 (3)))
X		appr = 0;
X	omx = mtmp -> mx;
X	omy = mtmp -> my;
X	nix = omx;
X	niy = omy;
X	cnt = 0;
X	for (ddx = -1; ddx <= 1; ddx++)
X		for (ddy = -1; ddy <= 1; ddy++)
X			if (r_free (zx = omx + ddx, zy = omy + ddy, mtmp)
X					&& (ddx || ddy)
X					&& !(ddx && ddy && (levl[omx][omy].typ == DOOR ||
X							levl[zx][zy].typ == DOOR))) {
X				if (!mtmp -> mconf && m_at (zx, zy))
X					continue;
X				nearer = (dist (zx, zy) < dist (nix, niy));
X				if ((appr > 0 && nearer) || (appr < 0 &&
X							!nearer) ||
X						(!mmoved && mtmp -> wormno) ||
X						(!appr && !rn2 (++cnt))) {
X					nix = zx;
X					niy = zy;
X					mmoved++;
X				}
X			}
X	if (mmoved) {
X		if (mtmp -> mconf && (mtmp2 = m_at (nix, niy))) {
X			if (hitmm (mtmp, mtmp2) == 1 && rn2 (4) &&
X					hitmm (mtmp2, mtmp) == 2)
X				return 2;
X			return 0;
X		}
X		if (!mtmp -> ale) {
X			mtmp -> mx = nix;
X			mtmp -> my = niy;
X		}
X		else if (levl[nix][niy].typ == POOL) {
X			mtmp -> mx = nix;
X			mtmp -> my = niy;
X		}
X
X		if (mtmp -> wormno && mtmp -> data -> mlet == 'w')
X			worm_move (mtmp);
X	}
X	else {
X		if (!rn2 (10) && index ("tNL", mtmp -> data -> mlet)) {
X			rloc (mtmp);
X			return 0;
X		}
X		if (mtmp -> wormno)
X			worm_nomove (mtmp);
X	}
X	if (mmoved || !cansee (omx, omy))
X		levlsym (omx, omy, mtmp -> data -> mlet);
X	pmon (mtmp);
X	return (mmoved);
X}
/
echo 'x - mklev.make.c'
sed 's/^X//' > mklev.make.c << '/'
X/*
X * Mklev.make.c
X */
X
X#define ZOO		1
X#define GRAVEYARD	2
X#define SWAMP		3
X#define FORT_KNOX	4
X#define MAZE		6
X
X#define NORMAL_IO
X#include "hack.h"
X
Xextern char     mmon[8][8];
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
Xextern  PART levl[80][22];
X
Xextern  MONSTER fmon;
Xextern  OBJECT fobj;
Xextern  GOLD_TRAP fgold, ftrap;
X
Xextern  MKROOM rooms[15], *croom;
X
Xextern  COORDINATES doors[DOORMAX];
X
Xextern int      doorindex, nroom, comp ();
X
Xextern char     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
Xmakemaz () {
X
X/* This is all Kenny's fault.  He seems to have his x and y reversed */
X
X	int     xx, yy, a, q, sp, dir, dirs[5], stack[200];
X	register int    zx, zy;
X	register        OBJECT otmp;
X
X	for (xx = 2; xx < 19; xx++)
X		for (yy = 2; yy < 77; yy++) {
X			if (xx % 2 == 0 || yy % 2 == 0)
X				levl[yy][xx].typ++;/* WALL==1 */
X		}
X	zx = MAZY;
X	zy = MAZX;
X	sp = 1;
X	stack[1] = 100 * zx + zy;
X	while (sp) {
X		xx = stack[sp] / 100;
X		yy = stack[sp] % 100;
X		levl[yy][xx].typ = 2;
X		q = 0;
X		for (a = 0; a < 4; a++)
X			if (okay (xx, yy, a))
X				dirs[q++] = a;
X		if (q) {
X			dir = dirs[rn2 (q)];
X			move (&xx, &yy, dir);
X			levl[yy][xx].typ = 0;
X			move (&xx, &yy, dir);
X			stack[++sp] = 100 * xx + yy;
X		}
X		else
X			sp--;
X	}
X	for (xx = 2; xx < 77; xx++)
X		for (yy = 2; yy < 19; yy++) {/* This was mine */
X			if (levl[xx][yy].typ == WALL)
X				levl[xx][yy].scrsym = '-';
X			else {
X				levl[xx][yy].typ = ROOM;
X				levl[xx][yy].scrsym = '.';
X			}
X		}
X	for (xx = rn1 (8, 11); xx; xx--) {
X		mkobj (0);
X		levl[(fobj -> ox = MAZX)][(fobj -> oy = MAZY)].scrsym = fobj -> olet;
X	}
X	for (xx = rn1 (5, 7); xx; xx--)
X		makemon (1, MAZX, MAZY);
X	for (xx = rn1 (6, 7); xx; xx--)
X		mkgold (0, MAZX, MAZY);
X	for (xx = rn1 (6, 7); xx; xx--)
X		mktrap (0, 1);
X	levl[(xupstair = MAZX)][(yupstair = MAZY)].scrsym = '<';
X	levl[zy][zx].scrsym = '"';
X	otmp = newobj ();
X	otmp -> nobj = fobj;
X	fobj = otmp;
X	otmp -> ox = zy;
X	otmp -> oy = zx;
X	otmp -> olet = '"';
X	xdnstair = 0;
X	ydnstair = 0;
X}
X
X/* Make a trap somewhere (in croom if mazeflag=0) */
Xmktrap (num, mazeflag)
Xregister int    num, mazeflag;
X{
X	register        GOLD_TRAP gtmp;
X	register int    nopierc;
X	int     nomimic, fakedoor, fakegold, tryct = 0;
X
X	gtmp = newgen ();
X	if (!num || num >= TRAPNUM) {
X		nopierc = (dlevel < 4);
X		nomimic = (dlevel < 9 || goldseen);
X		gtmp -> gflag = rn2 (TRAPNUM - nopierc - nomimic);
X/* Note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
X	}
X	else
X		gtmp -> gflag = num;
X	fakedoor = (gtmp -> gflag == MIMIC && rn2 (2) && !mazeflag);
X	fakegold = (gtmp -> gflag == MIMIC && !fakedoor);
X	do {
X		if (++tryct > 200) {
X			printf ("tryct overflow7\n");
X			free (gtmp);
X			return;
X		}
X		if (mazeflag) {
X			gtmp -> gx = MAZX;
X			gtmp -> gy = MAZY;
X		}
X		else if (!fakedoor) {
X			gtmp -> gx = somex ();
X			gtmp -> gy = somey ();
X		}
X		else {
X			if (rn2 (2)) {
X				if (rn2 (2))
X					gtmp -> gx = croom -> hx + 1;
X				else
X					gtmp -> gx = croom -> lx - 1;
X				gtmp -> gy = somey ();
X			}
X			else {
X				if (rn2 (2))
X					gtmp -> gy = croom -> hy + 1;
X				else
X					gtmp -> gy = croom -> ly - 1;
X				gtmp -> gx = somex ();
X			}
X		}
X	} while (g_at (gtmp -> gx, gtmp -> gy, (fakegold) ? fgold : ftrap));
X	if (!fakegold) {
X		gtmp -> ngen = ftrap;
X		ftrap = gtmp;
X	}
X	else {
X		gtmp -> gflag = 0;
X		gtmp -> ngen = fgold;
X		fgold = gtmp;
X		goldseen++;
X	}
X	if (mazeflag && !rn2 (10) && gtmp -> gflag < PIERC)
X		gtmp -> gflag |= SEEN;
X	if (fakedoor)
X		num = '+';
X	else if (fakegold)
X		num = '$';
X	else
X		return;
X	levl[gtmp -> gx][gtmp -> gy].scrsym = num;
X}
X
Xmkgold (num, goldx, goldy)
Xregister int    num;
X{
X	register        GOLD_TRAP gtmp;
X
X	gtmp = newgen ();
X	gtmp -> ngen = fgold;
X	levl[gtmp -> gx = goldx][gtmp -> gy = goldy].scrsym = '$';
X	gtmp -> gflag = (num) ? num : 1 + rnd (dlevel + 2) * rnd (30);
X	fgold = gtmp;
X}
X
X/*VARARGS*/
Xpanic (str, arg1, arg2)
Xregister char  *str;
X{
X	fprintf (stderr, "\nMKLEV ERROR: ");
X	fprintf (stderr, str, arg1, arg2);
X	abort ();
X}
X
Xmakemon (sl, monx, mony)
Xregister int    sl, monx, mony;
X{
X	register        MONSTER mtmp;
X	register int    tryct = 0;
X
X	mtmp = newmonst (0);
X	mtmp -> mstole = STOLE_NULL;
X	mtmp -> msleep = sl;
X	mtmp -> mx = monx;
X	mtmp -> my = mony;
X	mtmp -> mfroz = 0;
X	mtmp -> mconf = 0;
X	mtmp -> mflee = 0;
X	mtmp -> mspeed = 0;
X	mtmp -> mtame = 0;
X	mtmp -> angry = 0;
X	mtmp -> mxlth = 0;
X	mtmp -> wormno = 0;
X	mtmp -> ale = 0;
X	if (levl[monx][mony].typ == POOL) {
X		mtmp -> ale = 1;
X		mtmp -> invis = 1;
X	}
X	else {
X		do {
X			if (++tryct > 100) {
X				printf ("tryct overflow8\n");
X				free (mtmp);
X				return;
X			}
X			mtmp -> mhp = rn2 (dlevel / 3 + 1) % 8;
X			mtmp -> orig_hp = rn2 (7);
X		} while (index (geno, mmon[mtmp -> mhp][mtmp -> orig_hp]));
X	}
X	mtmp -> nmon = fmon;
X	fmon = mtmp;
X}
X
X
Xchar    shtypes[] = "=/)%?![";	/* 8 shoptypes: 7 specialised, 1 mixed */
Xchar    shprobs[] = {
X	3, 3, 5, 5, 10, 10, 14, 50
X};				/* Their probabilities */
X
Xmkshop () {
X	register        MKROOM * sroom;
X	register int    sh, sx, sy, i;
X	register char   let;
X
X	for (sroom = &rooms[0];; sroom++) {
X		if (sroom -> hx < 0)
X			return;
X		if (ch_upstairs (sroom) || ch_dnstairs (sroom))
X			continue;
X		if (sroom -> doorct == 1)
X			break;
X	}
X	for (i = rn2 (100), let = 0; (i -= shprobs[let]) >= 0; let++)
X		if (!shtypes[let])
X			break;	/* Superfluous */
X	sroom -> rtype = 8 + let;
X	let = shtypes[let];
X	sh = sroom -> fdoor;
X	for (sx = sroom -> lx; sx <= sroom -> hx; sx++)
X		for (sy = sroom -> ly; sy <= sroom -> hy; sy++) {
X			if (sx == sroom -> lx && doors[sh].x == sx - 1 ||
X					sx == sroom -> hx && doors[sh].x == sx + 1 ||
X					sy == sroom -> ly && doors[sh].y == sy - 1 ||
X					sy == sroom -> hy && doors[sh].y == sy + 1)
X				continue;
X			mkobj (let);
X			levl[fobj -> ox = sx][fobj -> oy = sy].scrsym =
X				fobj -> olet;
X		}
X}
X
Xmkzoo () {
X	register        MKROOM * zroom;
X	register int    zx, zy;
X
X	for (;;) {
X		zroom = &rooms[rn2 (nroom)];
X		if (zroom -> hx < 0 || zroom -> rtype >= 8 ||
X				ch_upstairs (zroom))
X			continue;/* Niet in kamer met terugweg */
X		break;		/* Kamer gevonden */
X	}
X	zroom -> rtype = ZOO;
X	for (zx = zroom -> lx; zx <= zroom -> hx; zx++)
X		for (zy = zroom -> ly; zy <= zroom -> hy; zy++) {
X			if (!m_at (zx, zy)) {
X				mkgold (0, zx, zy);
X				makemon (1, zx, zy);
X			}
X		}
X}
X
X
Xmkyard () {
X	register        MKROOM * yroom;
X	register int    yx, yy;
X
X	for (;;) {
X		yroom = &rooms[rn2 (nroom)];
X		if (yroom -> hx < 0 || yroom -> rtype >= 8 ||
X				ch_upstairs (yroom))
X			continue;/* Niet in kamer met terugweg */
X		break;		/* Kamer gevonden */
X	}
X	yroom -> rtype = GRAVEYARD;
X	for (yx = yroom -> lx; yx <= yroom -> hx; yx++)
X		for (yy = yroom -> ly; yy <= yroom -> hy; yy++) {
X			if (!mymakemon (yx, yy)) {
X				if (fmon -> mhp == 7)
X					mymakemon (yx, yy);
X			/* Not so many demons */
X				mkgold (0, yx, yy);
X				if (fmon -> mhp != 1) {
X					mkobj (0);
X					if (rn2 (8))
X						fobj -> cursed = 1;
X					levl[fobj -> ox = yx][fobj -> oy = yy].scrsym = fobj -> olet;
X				}
X			}
X		}
X}
X
X#define NOMON	1
X#define MON	0
X
Xmymakemon (monx, mony) {
X	register        MONSTER mtmp;
X	register int    tryct = 0;
X	register int    tmp = 0;
X
X	if (m_at (monx, mony))
X		return NOMON;
X	mtmp = newmonst (0);
X	mtmp -> mstole = STOLE_NULL;
X	mtmp -> msleep = 1;
X	mtmp -> mx = monx;
X	mtmp -> my = mony;
X	mtmp -> mfroz = 0;
X	mtmp -> mconf = 0;
X	mtmp -> mflee = 0;
X	mtmp -> mspeed = 0;
X	mtmp -> mtame = 0;
X	mtmp -> angry = 0;
X	mtmp -> mxlth = 0;
X	mtmp -> wormno = 0;
X	do {
X		if (++tryct > 1000) {
X			printf ("tryct overflow yard\n");
X			free (mtmp);
X			return NOMON;
X		}
X		tmp = putyard (mtmp);
X	} while (index (geno, mmon[mtmp -> mhp][mtmp -> orig_hp]) || tmp);
X	mtmp -> nmon = fmon;
X	fmon = mtmp;
X	return 0;
X}
X
Xputyard (mtmp)
XMONSTER mtmp;
X{
X	switch (rn2 (5)) {
X		case 0: 
X			mtmp -> mhp = 1;/* level 3 */
X			mtmp -> orig_hp = 6;/* ZOMBIE */
X			break;
X		case 1: 
X			if (dlevel < 18)
X				return NOMON;
X			mtmp -> mhp = 6;/* level 18 */
X			mtmp -> orig_hp = 2;/* VAMPIRE */
X			break;
X		case 2: 
X			mtmp -> mhp = 4;/* level 12 */
X			mtmp -> orig_hp = 5;/* Wraith */
X			break;
X		case 3: 
X			if (dlevel < 21)
X				return NOMON;
X			mtmp -> mhp = 7;/* level 21 */
X			mtmp -> orig_hp = 6;/* DEMON */
X			break;
X		case 4: 
X			mtmp -> mhp = 10;/* altijd */
X			mtmp -> orig_hp = 10;/* GHOST */
X			break;
X		default: 
X			mtmp -> mhp = rn2 (dlevel / 3 + 1) % 8;
X			mtmp -> orig_hp = rn2 (7);
X	}
X	return MON;
X}
X
Xmkswamp () {
X	register        MKROOM * zroom;
X	register int    zx, zy;
X	register int    first = 0;
X
X	for (;;) {
X		zroom = &rooms[rn2 (nroom)];
X		if (zroom -> hx < 0)
X			return;
X		if (ch_upstairs (zroom) || ch_dnstairs (zroom))
X			continue;
X		if (zroom -> hx < 0 || zroom -> rtype >= 8)
X			continue;
X	/* Niet in kamer met terugweg of weg naar beneden */
X		break;		/* Kamer gevonden */
X	}
X	zroom -> rtype = SWAMP;
X	for (zx = zroom -> lx; zx <= zroom -> hx; zx++)
X		for (zy = zroom -> ly; zy <= zroom -> hy; zy++) {
X			if ((zx + zy) % 2 && !o_at (zx, zy) &&
X					!g_at (zx, zy, fgold) && !m_at (zx, zy) &&
X					ch_doors (zx, zy)) {
X				levl[zx][zy].typ = POOL;
X				levl[zx][zy].scrsym = '}';
X				if (!first) {
X					makemon (0, zx, zy);
X					++first;
X				}
X				else if (!rn2 (4))
X					makemon (0, zx, zy);
X			}
X		}
X}
X
Xch_doors (zx, zy)
Xregister int    zx, zy;
X{
X	register int    xx, yy;
X	register int    status = 1;
X
X	for (xx = zx - 1; xx <= zx + 1; xx++)
X		for (yy = zy - 1; yy <= zy + 1; yy++) {
X			if (levl[xx][yy].typ == DOOR)
X				status = 0;
X			else if (levl[xx][yy].typ == SDOOR) {
X				levl[xx][yy].typ = DOOR;
X				levl[xx][yy].scrsym = '+';
X				status = 0;
X			}
X		}
X	return status;
X}
X
Xmk_knox () {
X	register        MKROOM * kroom;
X	register int    kx, ky;
X	register int    tmp = 10000;
X	OBJECT otmp;
X	MONSTER mtmp;
X	GOLD_TRAP gtmp;
X
X	for (kroom = &rooms[0];; ++kroom) {
X		if (kroom -> hx < 0)
X			return;
X		if (ch_upstairs (kroom) || ch_dnstairs (kroom))
X			continue;
X		if ((kroom -> rtype >= 8 || kroom -> rtype <= SWAMP)
X				&& kroom -> rtype)
X				/* Shop or Zoo or Graveyard or Swamp */
X			continue;
X		if (kroom -> hx - kroom -> lx <= 3 || kroom -> hy - kroom -> ly <= 3)
X			continue;
X		break;
X	}
X	kroom -> rtype = FORT_KNOX;
X	kx = ((kroom -> hx - kroom -> lx) / 2) + kroom -> lx;
X	ky = ((kroom -> hy - kroom -> ly) / 2) + kroom -> ly;
X	for (tx = kx - 1; tx <= kx + 1; ++tx)
X		for (ty = ky - 1; ty <= ky + 1; ++ty) {
X			if (tx == kx && ty == ky)
X				continue;
X			if ((otmp = o_at (tx, ty))) {
X				otmp -> ox = kx;
X				otmp -> oy = ky;
X			}
X			if ((mtmp = m_at (tx, ty)))
X				delmon (mtmp);
X			if ((gtmp = g_at (tx, ty, fgold))) {
X				tmp += gtmp -> gflag;
X				delgen (gtmp, fgold);
X			}
X			if ((gtmp = g_at (tx, ty, ftrap)))
X				delgen (gtmp, ftrap);
X			levl[tx][ty].typ = VAULT;
X			levl[tx][ty].scrsym = (ty == ky) ? '|' : '-';
X		}
X	mkgold (tmp, kx, ky);
X}
X
Xch_upstairs (mroom)
Xregister        MKROOM * mroom;
X{
X	return (mroom -> lx <= xupstair && xupstair <= mroom -> hx &&
X			mroom -> ly <= yupstair && yupstair <= mroom -> hy);
X}
X
Xch_dnstairs (mroom)
Xregister        MKROOM * mroom;
X{
X	return (mroom -> lx <= xdnstair && xdnstair <= mroom -> hx &&
X			mroom -> ly <= ydnstair && ydnstair <= mroom -> hy);
X}
X
Xdelmon (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;
X				mtmp2 = mtmp2 -> nmon);
X		mtmp2 -> nmon = mtmp -> nmon;
X	}
X}
X
Xdelgen (gtmp, key)
Xregister        GOLD_TRAP gtmp, key;
X{
X	register        GOLD_TRAP gtmp2;
X
X	if (gtmp == key)
X		key = key -> ngen;
X	else {
X		for (gtmp2 = key; gtmp2 -> ngen != gtmp;
X				gtmp2 = gtmp2 -> ngen);
X		gtmp2 -> ngen = gtmp -> ngen;
X	}
X}
/
echo 'Part 01 of Hack complete.'
exit
-- 

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



More information about the Comp.sources.unix mailing list