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

Michiel B. Huisjes huisjes at ark.UUCP
Wed Feb 6 16:52:11 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 04 of 05:'
echo 'x - data'
sed 's/^X//' > data << '/'
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X!       a potion                                 
X"       The amulet of Frobozz                    
X#       a corridor                               
X$       a pile, pot or chest of gold             
X%       a piece of food                          
X&       a demon                                  
X'       a lurker above                           
X\                                                
X)       a weapon                                 
X*       a gem                                    
X+       a door                                   
X,       a trapper                                
X-       a wall                                   
X.       the floor of a room                      
X/       a wand                                   
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X\                                                
X:       a chameleon                              
X;       a giant ale                              
X<       the staircase to the previous level      
X=       a ring                                   
X>       the staircase to the next level          
X?       a scroll                                 
X@       a human (or you)                         
XA       a giant ant                              
XB       a giant bat                              
XC       a centaur                                
XD       a dragon                                 
XE       a floating eye                           
XF       a freezing sphere                        
XG       a gnome                                  
XH       a hobgoblin                              
XI       an invisible stalker                     
XJ       a jackal                                 
XK       a kobold                                 
XL       a leprechaun                             
XM       a mimic                                  
XN       a nymph                                  
XO       an orc                                   
XP       a purple worm                            
XQ       a quasit                                 
XR       a rust monster                           
XS       a snake                                  
XT       a troll                                  
XU       an umber hulk                            
XV       a vampire                                
XW       a wraith                                 
XX       a xorn                                   
XY       a yeti                                   
XZ       a zombie                                 
X[       a suit of armor                          
X\                                                
X\                                                
X^       a trap                                   
X\                                                
X\                                                
Xa       an acid blob                             
Xb       a giant beetle                           
Xc       a cockatrice                             
Xd       a dog                                    
Xe       an ettin                                 
Xf       a fog cloud                              
Xg       a gelatinous cube                        
Xh       a homunculus                             
Xi       an imp                                   
Xj       a jaguar                                 
Xk       a killer bee                             
Xl       a leocrotta                              
Xm       a minouter                               
Xn       a neo-otyugh                             
Xo       an owlbear                               
Xp       a piercer                                
Xq       a quivering blob                         
Xr       a giant rat                              
Xs       a giant scorpion                         
Xt       a teleporter                             
Xu       a ugod                                   
Xv       a violet fungi                           
Xw       a long worm                              
Xx       a xerp                                   
Xy       a yellow light                           
Xz       a zelomp                                 
X\                                                
X|       a wall                                   
X}       a water filled area                      
X~       a wormsegment                            
X\                                                
/
echo 'x - hack.do.misc.c'
sed 's/^X//' > hack.do.misc.c << '/'
X/*
X * Hack.do.misc.c
X */
X
X/* Routines to do various user commands */
X
X#include <signal.h>
X#include "hack.h"
X#include "hack.do.vars.h"
X /* (MT) has 'do' structures and lists */
X
Xextern char    *getenv (), UMISS[], WELDED[];
X
X#define MAXLEVEL       40
X
XOBJECT loseone ();
X
Xint     done1 ();
X
Xchar    upxstairs[MAXLEVEL], upystairs[MAXLEVEL];
X
Xrhack (cmd)
Xregister char  *cmd;
X{
X	register        FUNCTIONS * tlist = list;
X
X	if (!cmd) {
X		pline ("Rhack: 0");
X		impossible ();
X		return;
X	}
X	if (!*cmd || *cmd == -1)
X		return;		/* Probably interrupt? */
X	if (movecm (cmd)) {
X		if (multi)
X			flags.mv = 1;
X		domove ();
X		return;
X	}
X	if (movecm (lowc (cmd))) {
X		flags.run = 1;
X		multi = 80;
X		flags.mv = 1;
X		domove ();
X		return;
X	}
X	if (*cmd == 'f' && movecm (cmd + 1)) {
X		flags.run = 2;
X		multi = 80;
X		flags.mv = 1;
X		domove ();
X		return;
X	}
X	if (*cmd == 'F' && movecm (lowc (cmd + 1))) {
X		flags.run = 3;
X		multi = 80;
X		flags.mv = 1;
X		domove ();
X		return;
X	}
X	while (tlist -> f_char) {
X		if (*cmd == tlist -> f_char) {
X			(*(tlist -> f_funct)) ();
X			return;
X		}
X		tlist++;
X	}
X	pline ("Unknown command '%s'", cmd);
X	nomove ();
X}
X
Xdoredraw () {
X	docrt ();
X	nomove ();
X}
X
X/*
X * VARIABELE ARGUMENTS, but if not given the last argument will always
X * be a NULL.		(Michiel)
X */
X/*VARARGS*/
Xhackexec (num, file, arg1, arg2, arg3, arg4, arg5, arg6)
Xregister int    num;
Xregister char  *file, *arg1;
Xchar   *arg2, *arg3, *arg4, *arg5, *arg6;
X{
X	nomove ();
X	switch (fork ()) {
X		case -1: 
X			pline ("Fork failed. Will try again.");
X			hackexec (num, file, arg1, arg2, arg3, arg4,
X					arg5, arg6);
X			break;
X		case 0: 
X			if (num) {
X				signal (SIGINT, SIG_DFL);
X				setuid (getuid ());
X				hackmode (OFF);
X				cls ();
X				flush ();
X				if (num == 2)
X					chdir (getenv ("HOME"));
X			}
X			else
X				signal (SIGINT, SIG_IGN);
X			execl (file, file, arg1, arg2, arg3, arg4, arg5, arg6);
X			panic (NOCORE, "%s: cannot execute.", file);
X			break;
X		default: 
X			signal (SIGINT, SIG_IGN);
X			signal (SIGQUIT, SIG_IGN);
X			wait (0);
X			if (num) {
X				hackmode (ON);
X				docrt ();
X			}
X			signal (SIGINT, done1);
X			signal (SIGQUIT, SIG_DFL);
X			break;
X	}
X}
X
Xdohelp () {
X	hackexec (1, MORE, HELP, NULL);
X}
X
Xdosh () {
X	register char  *str;
X
X	if (str = getenv ("SHELL"))
X		hackexec (2, str, NULL);
X	else
X		hackexec (2, "/bin/sh", "-i", NULL);
X}
X
Xdowield () {
X	register        OBJECT wep;
X
X	multi = 0;
X	if (!(wep = getobj (")", "wield")))
X		flags.move = 0;
X	else if (uwep && uwep -> cursed)
X		pline (WELDED, weapons[uwep -> otyp].wepnam);
X	else {
X		uwep = wep;
X		if (uwep -> cursed)
X			pline ("The %s welds itself to your hand!",
X					weapons[uwep -> otyp].wepnam);
X		else
X			prinv (uwep);
X	}
X}
X
Xddodown () {
X	dostairs ("down");
X}
X
Xddoup () {
X	dostairs ("up");
X}
X
Xdostairs (dir)
Xregister char  *dir;
X{
X	if (u.ustuck ||
X			(*dir == 'd' && (u.ux != xdnstair || u.uy != ydnstair)) ||
X			(*dir == 'u' && (u.ux != xupstair || u.uy != yupstair))) {
X		pline ("You can't go %s here", dir);
X		nomove ();
X		return;
X	}
X	keepdogs (1);
X	unCoff (COFF, 1);
X	dosavelev ();
X	if (*dir == 'd')
X		dodown ();
X	else
X		doup ();
X	losedogs ();
X	if (u.ucham)
X		rescham ();
X	setCon (CON);
X	if (u.uhcursed)
X		docurse ();
X}
X
Xdosavelev () {
X	register        fd;
X
X	glo (dlevel);
X	fd = creat (lock, 0644);
X	savelev (fd);
X	close (fd);
X}
X
Xextern int      uid;
X
Xchecklev (dir)			/* Michiel: Geen geknoei */
Xregister char  *dir;
X{
X	if ((upxstairs[dlevel] != xupstair ||
X				upystairs[dlevel] != yupstair) && !wizard) {
X		clearlocks ();
X		panic (NOCORE, "Way %s has been changed...", dir);
X	}
X}
X
Xdodown () {
X	register        fd;
X
X	glo (++dlevel);
X	if ((fd = open (lock, 0)) < 0)
X		mklev ();
X	else {
X		if (maxdlevel < dlevel)
X			mklev ();/* Bad file  */
X		else
X			getlev (fd);
X		close (fd);
X		checklev ("down");
X	}
X	if (maxdlevel < dlevel)
X		maxdlevel = dlevel;/* Trapdoor/stairs */
X	u.ux = xupstair;
X	u.uy = yupstair;
X	inshop ();
X}
X
Xdoup () {
X	register        fd;
X
X	if (dlevel == 1)
X		done (ESCAPED);
X	glo (--dlevel);
X	if ((fd = open (lock, 0)) < 0)
X		panic (CORE, "Cannot open %s\n", lock);
X	getlev (fd);
X	close (fd);
X	checklev ("up");
X	u.ux = xdnstair;
X	u.uy = ydnstair;
X}
X
Xm_call () {
X	register        OBJECT obj;
X
X	obj = getobj ("?!=/", "call");
X	if (obj)
X		docall (obj);
X	flags.move = 0;
X}
X
Xdocall (obj)
Xregister        OBJECT obj;
X{
X	register char  *str, **str1;
X
X	pline ("Call it:");
X	getlin (buf);
X	flags.topl = 0;
X	if (!*buf)
X		return;
X	str = alloc (strlen (buf) + 1) -> Val;
X	strcpy (str, buf);
X	switch (obj -> olet) {
X		case '_': 
X			free (str);
X			return;
X		case '?': 
X			str1 = &scrcall[obj -> otyp];
X			break;
X		case '!': 
X			str1 = &potcall[obj -> otyp];
X			break;
X		case '/': 
X			str1 = &wandcall[obj -> otyp];
X			break;
X		case '=': 
X			str1 = &ringcall[obj -> otyp];
X			break;
X		default: 
X			pline ("What a weird(%c %d)thing to call", obj -> olet, obj -> otyp);
X
X	}
X	if (*str1)
X		free (*str1);
X	*str1 = str;
X}
X
Xdonull () {
X}
X
XMONSTER bhit ();
X
Xdothrow () {
X	register        OBJECT obj;
X	register        MONSTER monst;
X	register        tmp;
X	char    x, y;
X
X	obj = getobj ("#%)", "throw");
X /* One can also throw food */
X	if (!obj || !getdir ()) {
X		nomove ();
X		return;		/* Sets dx and dy to direction */
X	}
X	if (obj == uarm || obj == uarm2 || obj == uleft ||
X			obj == uright) {
X		pline ("You can't throw something you are wearing");
X		return;
X	}
X	if (obj == uwep && uwepcursed ())
X		return;
X	monst = bhit (dx, dy, 8);
X	x = dx;
X	y = dy;
X	obj = loseone (obj);	/* Separate one out from list */
X	if (monst) {
X		if (obj -> olet == ')') {
X			tmp = u.ulevel - 1 + monst -> data -> ac + abon ();
X			if (obj -> otyp <= W_AMMUNITION) {
X				if (!uwep || uwep -> otyp != obj -> otyp +
X						11)
X					tmp -= 4;
X				else {
X					if (uwep -> cursed)
X						tmp -= uwep -> spe;
X					else
X						tmp += uwep -> spe;
X				}
X			}
X			else {
X				if (obj -> cursed)
X					tmp -= obj -> spe;
X				else
X					tmp += obj -> spe;
X			}
X			if (tmp >= rnd (20)) {
X				if (hmon (monst, obj)) {
X					hit (weapons[obj -> otyp].wepnam,
X							monst);
X					cutworm (monst, x, y, obj -> otyp);
X				}
X				else
X					monst = 0;
X				if (obj -> otyp <= W_AMMUNITION &&
X						rn2 (2)) {
X					freeobj (obj);
X					if (!onbill (obj))
X						ofree (obj);
X					return;
X				}
X			}
X			else
X				miss (weapons[obj -> otyp].wepnam, monst);
X		}
X		else {
X			psee (IT1, x, y, UMISS, monst -> data -> mname, NULL);
X			if (obj -> olet == '%' && monst -> data -> mlet == 'd')
X				if (tamedog (monst, obj))
X					return;
X		}
X/* Awake monster if sleeping */
X		if (monst) {
X			monst -> msleep = 0;
X			if (monst == shopkeeper)
X				setangry ();
X		}
X	}
X	obj -> ox = x;
X	obj -> oy = y;
X	if (obj -> unpaid && inshproom (x, y))
X		subfrombill (obj);
X	if (!m_at (x, y))
X		newsym (x, y);
X}
X
X/* Create a new object (at fobj) of multiplicity 1
X				  remove obj from invent if necessary */
XOBJECT loseone (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	if (!index ("/=", obj -> olet) && obj -> quan > 1) {
X		obj -> quan--;
X		otmp = newobj ();
X		*otmp = *obj;
X		otmp -> quan = 1;
X		otmp -> unpaid = 0;/* Obj is still on the bill */
X		otmp -> nobj = fobj;
X		fobj = otmp;
X	}
X	else {
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 -> nobj = fobj;
X		fobj = obj;
X	}
X	return (fobj);
X}
X
Xgetdir () {
X	pline ("What direction?");
X	flush ();
X	*buf = getchar ();
X	flags.topl = 0;
X	return (movecm (buf));
X}
X
Xdocurse () {
X	register        MONSTER mtmp;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) {
X		mtmp -> msleep = 0;
X		mtmp -> mtame = 0;
X	}
X	if (shopkeeper)
X		shopkeeper -> angry = 1;
X	if (vaultkeeper)
X		vaultkeeper -> angry = 1;
X}
/
echo 'x - hack.end.c'
sed 's/^X//' > hack.end.c << '/'
X/*
X * Hack.end.c
X */
X
X#include "hack.h"
X#include <signal.h>
X
X#define MAXLEVEL	40
X
Xextern char     plname[], *itoa (), *setan ();
X
Xextern int      billct, rfile;
X
Xchar    maxdlevel = 0, *strcat ();
X
Xchar   *statxx[] = {
X	"choked",
X	"died",
X	"starved",
X	"drowned",
X	"quit",
X	"escaped"
X};
X
Xdone1 () {
X	register char   c;
X
X	nomove ();
X	signal (SIGINT, done1);
X	pline ("Really quit?");
X	flush ();
X	if ((c = getchar ()) == 'y')
X		done (QUIT);
X	else if (c == 'S')
X		hangup ();
X}
X
Xdone (status)
Xregister int    status;
X{
X	if (wizard && status != QUIT && status != ESCAPED) {
X		u.ustr = (u.ustrmax += 2);
X		u.uhp = (u.uhpmax += 10);
X		u.uac--;
X		if (uwep)
X			uwep -> spe++;
X		pline ("For some reason you are still alive.");
X		nomove ();
X		flags.botl = 1;
X		return;
X	}
X	if (status == QUIT && u.uhp <= 0)
X		status = DIED;
X	if (billct)
X		paybill ();
X	clearlocks ();
X	if (status < QUIT) {	/* Not when quit or escaped */
X#ifndef DEBUG
X		savebones ();
X#endif DEBUG
X		outrip ();
X	}
X	hackmode (OFF);
X	cls ();
X	printf ("Goodbye %s...\n\n", plname);
X	u.urexp += u.ugold;
X	if (status == DIED) {
X		strcpy (killer, setan (killer));
X		u.urexp -= u.ugold / 10;
X	}
X	else
X		killer = statxx[status];
X	if (status == ESCAPED) {
X		OBJECT otmp;
X
X		u.urexp += 150;
X		for (otmp = invent; otmp; otmp = otmp -> nobj) {
X			if (otmp -> olet == '*')
X				u.urexp += otmp -> quan * 10 * rnd (250);
X			else if (otmp -> olet == '"')
X				u.urexp += 25000;
X		}
X		printf ("You escaped from the dungeon");
X	}
X	else
X		printf ("You %s on dungeon level %d,", statxx[status],
X				dlevel);
X	printf (" with %U points\n", u.urexp);
X	printf ("and %U pieces of gold, after %u moves.\n",
X			u.ugold, moves);
X	printf ("You were level %d with a maximum of %d hit points when you %s.\n\n", u.ulevel, u.uhpmax, statxx[status]);
X	topten ();
X	flush ();
X	exit (0);
X}
X
X#define	NAMESIZE	 8
X#define	DEATHSIZE	40
X#define TOPPRINT	15	/* Aantal scores dat wordt afgedrukt */
X#define	TOPLIST		25	/* Length of 'top ten' list */
X
Xtopten () {
X	int     tmp;
X	struct recitem {
X		long    points;
X		int     level, maxlvl, hp, maxhp;
X		char    str[NAMESIZE + 1], death[DEATHSIZE + 1];
X	}               rec[TOPLIST + 1], *t1;
X	register        flg;
X
X	for (t1 = rec; t1 < &rec[TOPLIST]; t1++)
X		if (read (rfile, t1, sizeof (struct recitem)) <= 0)
X			                                                t1 -> points = 0;
X	flg = 0;
X	if (u.urexp > rec[TOPLIST - 1].points && !wizard) {
X		signal (SIGINT, SIG_IGN);
X		if (u.urexp > rec[TOPPRINT - 1].points)
X			printf ("You made the top %d list!\n", TOPPRINT);
X		if (lseek (rfile, 0L, 0) < 0)
X			panic (CORE, "Cannot lseek on record file");
X
X/* Stick in new entry. NB: we save the last few
X			entries that disappeared from the list */
X
X		for (tmp = TOPLIST - 2; tmp >= 0 && rec[tmp].points <
X				u.urexp; tmp--)
X			rec[tmp + 1] = rec[tmp];
X		tmp++;		/* Point to right place */
X		rec[tmp].points = u.urexp;
X		rec[tmp].level = dlevel;
X		rec[tmp].maxlvl = maxdlevel;
X		rec[tmp].hp = u.uhp;
X		rec[tmp].maxhp = u.uhpmax;
X		strncpy (rec[tmp].str, plname, NAMESIZE);
X		rec[tmp].str[NAMESIZE] = 0;
X		strncpy (rec[tmp].death, killer, DEATHSIZE);
X		rec[tmp].death[DEATHSIZE] = 0;
X		flg++;
X	}
X	printf ("Number Points Name\n");
X	for (t1 = rec, tmp = 1; t1 < &rec[TOPLIST]; tmp++, t1++) {
X		char    killed = 0;
X
X		if (flg && t1 -> points)
X			write (rfile, t1, sizeof (struct recitem));
X		if (t1 >= &rec[TOPPRINT] || t1 -> points == 0)
X			continue;
X		printf ("%2d  %6D %8s ", tmp, t1 -> points,
X				t1 -> str);
X		if (*t1 -> death == 'e')
X			printf ("escaped the dungeon [max level %d]", t1 -> maxlvl);
X		else {
X			switch (t1 -> death[1]) {
X				case 'u': 
X					printf ("quit");
X					break;
X				case 'h': 
X					printf ("choked on his 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",
X					killed ? "" : " dungeon", t1 -> level);
X			if (t1 -> maxlvl != t1 -> level)
X				printf (" [%d]", t1 -> maxlvl);
X		}
X		if (killed)
X			printf (" by %s", t1 -> death);
X		putchar ('.');
X		if (t1 -> maxhp)
X			printf (" Hp: %s [%d]", (t1 -> hp > 0) ?
X					itoa (t1 -> hp) : "-", t1 -> maxhp);
X		putchar ('\n');
X	}
X	close (rfile);
X}
X
Xchar   *
X        itoa (a)
Xregister int    a;
X{
X	static char     buffer[8];
X
X	sprintf (buffer, "%d", a);
X	return (buffer);
X}
X
Xclearlocks () {
X	register        x;
X
X	signal (SIGINT, SIG_IGN);
X	for (x = 1; x <= MAXLEVEL; x++) {
X		glo (x);
X		if (unlink (lock))
X			break;
X	}
X#ifdef DEBUG
X	glo (0);
X	unlink (lock);
X#endif DEBUG
X}
X
Xhangup () {
X	save ();
X	clearlocks ();
X	exit (1);
X}
/
echo 'x - hack.invent.c'
sed 's/^X//' > hack.invent.c << '/'
X/*
X * Hack.invent.c
X */
X
X#include	"hack.h"
X
X#define NOT_AT	0
X#define NO_OBJ	0
X
Xextern  WORMSEGMENT wsegs[32];
X
Xextern  OBJECT yourinvent0;
X
XOBJECT addinv (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X		if (otmp -> otyp == obj -> otyp && otmp -> olet == obj -> olet
X				&& !obj -> unpaid && !otmp -> unpaid &&
X				((obj -> otyp < F_COOKIE &&
X						obj -> olet == ')' &&
X						obj -> quan + otmp -> quan < 32 &&
X						obj -> spe == otmp -> spe) ||
X					index ("%?!*", otmp -> olet))) {
X			otmp -> quan += obj -> quan;
X			ofree (obj);
X			return otmp;
X		}
X		if (!otmp -> nobj) {
X			otmp -> nobj = obj;
X			obj -> nobj = 0;
X			return obj;
X		}
X	}
X	invent = obj;
X	obj -> nobj = 0;
X	return obj;
X}
X
Xuseup (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	if (obj -> quan > 1) {
X		obj -> quan--;
X		return;
X	}
X	if (obj == invent)
X		invent = invent -> nobj;
X	else {
X		for (otmp = invent; otmp -> nobj != obj;
X				otmp = otmp -> nobj);
X		otmp -> nobj = obj -> nobj;
X	}
X	if (!onbill (obj))
X		ofree (obj);
X}
X
Xdelobj (obj)
Xregister        OBJECT obj;
X{
X	freeobj (obj);
X	ofree (obj);
X}
X
Xofree (obj)
Xregister        OBJECT obj;
X{
X	if (obj > yourinvent0)
X		free (obj);
X}
X
X/*  Unlink obj from chain starting with fobj  */
X
Xfreeobj (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X
X	if (obj == fobj)
X		fobj = fobj -> nobj;
X	else {
X		for (otmp = fobj; otmp -> nobj != obj; otmp = otmp -> nobj)
X			if (!otmp)
X				panic (CORE, "Try to free non-existing object");
X		otmp -> nobj = obj -> nobj;
X	}
X}
X
Xdeltrap (trap)
Xregister        GOLD_TRAP trap;
X{
X	register        GOLD_TRAP gtmp;
X
X	if (trap == ftrap)
X		ftrap = ftrap -> ngen;
X	else {
X		for (gtmp = ftrap; gtmp -> ngen != trap;
X				gtmp = gtmp -> ngen);
X		gtmp -> ngen = trap -> ngen;
X	}
X	free (trap);
X}
X
XMONSTER m_at (x, y)
Xregister        x, y;
X{
X	register        MONSTER mtmp;
X	register        WORMSEGMENT wtmp;
X
X	for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) {
X		if (mtmp -> mx == x && mtmp -> my == y)
X			return (mtmp);
X		if (mtmp -> wormno)
X			for (wtmp = wsegs[mtmp -> wormno]; wtmp;
X					wtmp = wtmp -> nseg)
X				if (wtmp -> wx == x && wtmp -> wy == y)
X					return (mtmp);
X	}
X	return (NOT_AT);
X}
X
XOBJECT o_at (x, y)
Xregister        x, y;
X{
X	register        OBJECT otmp;
X
X	for (otmp = fobj; otmp; otmp = otmp -> nobj)
X		if (otmp -> ox == x && otmp -> oy == y)
X			return (otmp);
X	return (NOT_AT);
X}
X
XGOLD_TRAP g_at (x, y, ptr)
Xregister        x, y;
Xregister        GOLD_TRAP ptr;
X{
X	while (ptr) {
X		if (ptr -> gx == x && ptr -> gy == y)
X			return (ptr);
X		ptr = ptr -> ngen;
X	}
X	return (NOT_AT);
X}
X
XOBJECT getobj (let, word)
Xregister char  *let, *word;
X{
X	register        OBJECT otmp;
X	register char   ilet, ilet1, ilet2;
X	char    buffer[BUFSZ], allowall = 0;
X	register        foo = 0, foo2;
X
X	if (*let == '#') {
X		let++;
X		allowall++;
X	}
X	ilet = 'a';
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X		if (!let || index (let, otmp -> olet))
X			buffer[foo++] = ilet;
X		if (ilet == 'z')
X			ilet = 'A';
X		else
X			ilet++;
X	}
X	buffer[foo] = 0;
X	if (foo > 5) {		/* Compactify string */
X		foo = foo2 = 1;
X		ilet2 = buffer[0];
X		ilet1 = buffer[1];
X		while (ilet = buffer[++foo2] = buffer[++foo]) {
X			if (ilet == ilet1 + 1) {
X				if (ilet1 == ilet2 + 1)
X					buffer[foo2 - 1] = ilet1 = '-';
X				else if (ilet2 == '-') {
X					buffer[--foo2] = ++ilet1;
X					continue;
X				}
X			}
X			ilet2 = ilet1;
X			ilet1 = ilet;
X		}
X	}
X	if (!foo && !allowall) {
X		pline ("You don't have anything to %s.", word);
X		return (NO_OBJ);
X	}
X	for (;;) {
X		pline ((foo) ? "What do you want to %s [%s or ?]? " :
X				"What do you want to %s? ", word, buffer);
X		flags.topl = 0;
X		flush ();
X		ilet = getchar ();
X		if (ilet == '\33' || ilet == ' ' || ilet == '\n')
X			if (strcmp (word, "identify"))
X				return (NO_OBJ);
X			else
X				continue;/* sukkel */
X		if (ilet == '?')
X			doinv (foo ? let : 0, 0);
X		else {
X			if (ilet >= 'A' && ilet <= 'Z')
X				ilet += 26 - 'A';
X			else
X				ilet -= 'a';
X			for (otmp = invent; otmp && ilet; ilet--,
X					otmp = otmp -> nobj);
X			if (!otmp) {
X				pline ("You don't have that object.");
X				continue;
X			}
X			break;
X		}
X	}
X	if (!allowall && let && !index (let, otmp -> olet)) {
X		pline ("That is a silly thing to %s.", word);
X		return (NO_OBJ);
X	}
X	return (otmp);
X}
X
Xprinv (obj)
Xregister        OBJECT obj;
X{
X	register        OBJECT otmp;
X	register char   ilet = 'a';
X
X	for (otmp = invent; otmp != obj; otmp = otmp -> nobj)
X		if (++ilet > 'z')
X			ilet = 'A';
X	prname (obj, ilet, 1);
X}
X
Xprname (obj, let, onelin)
Xregister        OBJECT obj;
Xregister char   let;
X{
X	char    li[BUFSZ];
X
X	doname (obj, buf);
X	sprintf (li, "%c - %s.", let, buf);
X	if (onelin)
X		pline (li);
X	else
X		printf ("%s\n", li);
X}
X
Xddoinv () {
X	nomove ();
X	if (!invent)
X		pline ("You are empty handed.");
X	else
X		doinv (0, 1);
X}
X
X/*
X * Page inventory done by Fred
X *
X */
X
Xdoinv (str, opt)
Xregister char  *str;
Xint     opt;
X{
X	register        OBJECT otmp;
X	register char   ilet = 'a';
X	register int    count = 1;
X	int     ct = 0;
X
X	if (!flags.oneline)
X		for (otmp = invent; otmp; otmp = otmp -> nobj)
X			if (!str || index (str, otmp -> olet))
X				ct++;
X	if (ct > 1)
X		cls ();
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X		if (!str || index (str, otmp -> olet)) {
X			prname (otmp, ilet, ct <= 1);
X			count++;
X		}
X		if (++ilet > 'z')
X			ilet = 'A';
X		if (!(count % 22) && otmp -> nobj) {
X			getret ();
X			cls ();	/* M. F. Page listing */
X		}
X	}
X	if (!str && opt)
X		doinvbill ();
X	if (ct > 1) {
X		getret ();
X		docrt ();
X	}
X}
/
echo 'x - hack.lev.c'
sed 's/^X//' > hack.lev.c << '/'
X/*
X * Hack.lev.c
X */
X
X#include "hack.h"
X#include <signal.h>
X
X#define MAXLEVEL	40
X#define ERROR		 1
X#define OK		 0
X
Xextern char    *itoa (), nul[], upxstairs[MAXLEVEL], upystairs[MAXLEVEL];
X
Xextern  WORMSEGMENT wsegs[32], wheads[32];
Xextern unsigned wgrowtime[32];
Xextern struct permonst  pm_ghost;
X
X#include "hack.savelev.c"
X
Xstruct permonst pm_ale = {
X	"giant eel", ';', 15, 6, -3, 3, 6, 0
X};
X
Xgetlev (fd) {
X	register        MONSTER mtmp;
X	register        GOLD_TRAP gtmp;
X	register        OBJECT otmp;
X	register        WORMSEGMENT wtmp;
X	int     tmp, xl;
X	unsigned        tmoves, omoves;
X	STOLE stmp;
X
X	if (fd < 0 || read (fd, levl, sizeof (levl)) != sizeof (levl))
X		return ERROR;
X	fmon = 0;
X	fobj = 0;
X	fgold = 0;
X	ftrap = 0;
X	shopkeeper = 0;
X	vaultkeeper = 0;
X	mread (fd, &omoves, sizeof (unsigned));
X	mread (fd, &xupstair, 1);
X	mread (fd, &yupstair, 1);
X	mread (fd, &xdnstair, 1);
X	mread (fd, &ydnstair, 1);
X	if (omoves)
X		tmoves = (moves > omoves) ? moves - omoves : 0;
X	for (;;) {
X		mread (fd, &xl, sizeof (int));
X		if (xl == -1)
X			break;
X		mtmp = newmonst (xl);
X		mread (fd, mtmp, xl + sizeof (struct monst));
X
X/* Michiel restore stolen objects */
X		stmp = newstole ();
X		mread (fd, stmp, sizeof (struct stole));
X		if (stmp -> sgold || stmp -> sobj) {
X			mtmp -> mstole = stmp;
X			mtmp -> mstole -> sobj = 0;
X			for (;;) {
X				otmp = newobj ();
X				mread (fd, otmp, sizeof (struct obj));
X				if (!otmp -> olet)
X					break;
X				otmp -> nobj = mtmp -> mstole -> sobj;
X				mtmp -> mstole -> sobj = otmp;
X			}
X			ofree (otmp);
X		}
X		else
X			free (stmp);
X/* Regenerate animals if you've been on another level */
X		if (omoves) {
X			if (!index (genocided, mtmp -> data -> mlet)) {
X				if (index ("ViT", mtmp -> data -> mlet))
X					mtmp -> mhp += mtmp -> mhp + tmoves;
X				else
X					mtmp -> mhp += tmoves / 20;
X				if (mtmp -> mhp > mtmp -> orig_hp)
X					mtmp -> mhp = mtmp -> orig_hp;
X				if (mtmp -> data -> mlet == '@') {
X					if (*mtmp -> data -> mname == 's')
X						shopkeeper = mtmp;
X					else if (*mtmp -> data -> mname == 'v')
X						vaultkeeper = mtmp;
X				}
X				mtmp -> nmon = fmon;
X				fmon = mtmp;
X			}
X		}
X		else {		/* Convert code from MKLEV */
X			if (mtmp -> mhp == 10)
X				mtmp -> data = &pm_ghost;
X			else if (mtmp -> ale)
X				mtmp -> data = &pm_ale;
X			else
X				mtmp -> data = &mon[mtmp -> mhp][mtmp -> orig_hp];
X			if (mtmp -> data -> mlet == 'D')
X				mtmp -> mhp = 80;
X			else
X				mtmp -> mhp = mtmp -> data -> mhd ?
X					d (mtmp -> data -> mhd, 8) : rnd (4);
X			mtmp -> orig_hp = mtmp -> mhp;
X			mtmp -> cham = (mtmp -> data -> mlet == ':');
X			mtmp -> invis = (mtmp -> data -> mlet == 'I');
X			if (mtmp -> data -> mlet == 'w' &&
X					getwn (mtmp))
X				initworm (mtmp);
X			mtmp -> nmon = fmon;
X			fmon = mtmp;
X		}
X	}
X	for (;;) {
X		gtmp = newgen ();
X		mread (fd, gtmp, sizeof (struct gen));
X		if (!gtmp -> gx)
X			break;
X		gtmp -> ngen = fgold;
X		fgold = gtmp;
X	}
X	for (;;) {
X		mread (fd, gtmp, sizeof (struct gen));
X		if (!gtmp -> gx)
X			break;
X		gtmp -> ngen = ftrap;
X		ftrap = gtmp;
X		gtmp = newgen ();
X	}
X	free (gtmp);
X	for (;;) {
X		otmp = newobj ();
X		mread (fd, otmp, sizeof (struct obj));
X		if (!otmp -> olet)
X			break;
X		otmp -> nobj = fobj;
X		fobj = otmp;
X	}
X	ofree (otmp);
X	mread (fd, rooms, sizeof (rooms));
X	mread (fd, doors, sizeof (doors));
X	if (!omoves)
X		return OK;	/* From MKLEV */
X	mread (fd, wsegs, sizeof (wsegs));
X	for (tmp = 1; tmp < 32; tmp++)
X		if (wsegs[tmp]) {
X			wheads[tmp] = wsegs[tmp] = wtmp = newseg ();
X			for (;;) {
X				mread (fd, wtmp, sizeof (struct wseg));
X				if (!wtmp -> nseg)
X					break;
X				wheads[tmp] -> nseg = wtmp = newseg ();
X				wheads[tmp] = wtmp;
X			}
X		}
X	mread (fd, wgrowtime, sizeof (wgrowtime));
X	return OK;
X}
X
Xmread (fd, buffer, len)
Xregister        fd, len;
Xregister char  *buffer;
X{
X	register        rlen;
X
X	if ((rlen = read (fd, buffer, len)) != len)
X		panic (CORE, "Read %d instead of %d bytes from file #%d\n",
X				rlen, len, fd);
X}
X
Xmklev () {
X	register        fd;
X	char    type[2];
X
X#ifndef DEBUG
X	if (getbones ()) {
X		sleep (2);
X		goto Z;
X	}
X#endif DEBUG
X	if (flags.next) {
X		flags.next = 0;
X		type[0] = 'b';
X	}
X	else if (dlevel < rn1 (3, MAXLEVEL - 3))
X		type[0] = 'a';
X	else {
X		type[0] = 'n';
X		flags.next = 1;
X	}
X	type[1] = '\0';
X	hackexec (0, "./mklev", lock, type, itoa (dlevel), genocided,
X			wizard ? "w" : "", NULL);
X	if ((fd = open (lock, 0)) < 0) {
X		pline ("Can't open %s! Second try.", lock);
X		flush ();
X		hackexec (0, "./mklev", lock, type, itoa (dlevel), genocided,
X				wizard ? "w" : "", NULL);
X		if ((fd = open (lock, 0)) < 0)
X			panic (NOCORE, "Mklev error no level");
X	}
X	getlev (fd);
X	close (fd);
XZ: 
X	if (!upxstairs[dlevel] && !upystairs[dlevel]) {
X		upxstairs[dlevel] = xupstair;
X		upystairs[dlevel] = yupstair;
X	}
X}
/
echo 'x - hack.main.c'
sed 's/^X//' > hack.main.c << '/'
X/*
X * Hack.main.c
X */
X
X#include <signal.h>
X#include "hack.h"
X
X#define exception( id )	( id == uid )
X#define HUISJES	2201
X#define WILDE	2216
X
Xextern char    *hu_stat[4], *getenv (), *malloc (), *parse ();
X
Xint     rfile;
X
XCOORDINATES doors[DOORMAX];
X
XPART levl[80][22];
XMKROOM rooms[15];
XMONSTER fmon = 0;
XGOLD_TRAP fgold = 0, ftrap = 0;
XFLAG flags;
XYOU u;
XOBJECT fobj = 0, invent, uwep, uarm,
Xuarm2 = 0, uright = 0, uleft = 0;
X
Xextern  OBJECT yourinvent0;
Xextern struct obj       mace0, uarm0;
X
Xchar    nul[20];		/* Contains zeros */
X/* Lock contains 'pid'.dlevel */
Xchar    plname[10], lock[16], wizard,
X        curx, cury, savx,
X        xupstair, yupstair, xdnstair, ydnstair,
X       *save_cm = 0, *killer, *nomvmsg, dlevel = 0,
X        dx, dy, buf[BUFSZ], genocided[60],
X        SAVEFILE[37] = SAVEDIR;
X
Xunsigned        moves = 1;
X
Xint     multi = 0, done1 (), hangup (), hackpid;
Xint     uid;
X
Xmain (argc, argv)
Xchar   *argv[];
X{
X	int     fd;
X	char *getlogin();
X	register char  *yourname = getlogin ();
X
X	uid = getuid ();
X	/*
X	 * Check on UID's
X	 */
X
X	if (kantoor () && !exception (HUISJES) && !exception (WILDE)) {
X		printf ("Sorry, You can't play hack now\n" );
X		flush ();
X		exit (0);
X	}
X	if (!access (LOCK, 0) && strcmp (WIZARD, yourname)) {
X		printf ("Sorry, I'm busy with debugging.\nTry again later.\n");
X		flush ();
X		exit (0);
X	}
X
X	strncpy (plname, yourname, sizeof (plname) - 1);
X#ifdef WIZARD
X	while (argc > 1 && **++argv == '-') {
X		switch (argv[0][1]) {
X			case 'w': 
X				if (!exception (HUISJES) && !exception (WILDE) && strcmp (yourname, WIZARD))
X					printf ("Sorry\n");
X				else {
X					strcpy (plname, "wizard");
X					wizard++;
X				}
X				break;
X			default: 
X				printf ("Unknown option: %s\n", *argv);
X		}
X		flush ();
X	}
X#endif WIZARD
X
X	if (chdir (PLAYGROUND) < 0)
X		panic (NOCORE, "Cannot chdir to %s!", PLAYGROUND);
X	if ((rfile = open (RECORD, 2)) < 0)
X		panic (NOCORE, "Can't open %s!", RECORD);
X	setuid (getuid ());
X	umask (0);
X	srand (hackpid = getpid ());
X	startup ();
X	signal (SIGHUP, hangup);
X	signal (SIGINT, done1);
X	hackmode (ON);
X	if (!wizard) {
X		cls ();
X		flush ();
X	}
X	strcat (SAVEFILE, plname);
X	fd = open (SAVEFILE, 0);
X	if (fd >= 0) {
X		if (dorecover (fd) < 0)
X			goto normalplay;
X		flags.move = 0;
X	}
X	else {
Xnormalplay: 
X		shuffle ();
X		invent = yourinvent0;
X		uwep = &mace0;
X		uarm = &uarm0;
X		u.uac = 6;	/* 10 - uarm->spe */
X		u.ulevel = 1;
X		u.uhunger = 900;
X		u.uhpmax = u.uhp = 12;
X		u.ustrmax = u.ustr = rn2 (20) ? 16 : rn1 (7, 14);
X		flags.move = 1;
X		dodown ();	/* a3 */
X		cls ();
X		setCon (SETC);
X		flags.botl = 1;
X		makedog ();
X	}
X	for (;;) {
X		if (flags.move) {
X			if (!u.ufast || moves % 2 == 0) {
X				if (fmon)
X					movemon ();
X				if (!rn2 (70)) {
X					makemon (0);
X					fmon -> mx = 0;
X					fmon -> my = 0;
X					rloc (fmon);
X					seeatl (fmon -> mx, fmon -> my,
X							fmon -> data -> mlet);
X				}
X			}
X			if (u.ufast && !--u.ufast)
X				pline ("You feel yourself slowing down");
X			if (u.uconfused && !--u.uconfused)
X				pline ("You feel less confused now");
X			if (u.ublind && !--u.ublind) {
X				pline ("You can see again");
X				if (!u.uswallow)
X					setCon (SETC);
X			}
X			if (u.uinvis && !--u.uinvis) {
X				if (!u.uswallow)
X					on (u.ux, u.uy);
X				pline ("You are no longer invisible");
X			}
X			++moves;
X			if (u.uhp <= 0) {
X				pline ("You die...");
X				more ();
X				done (DIED);
X			}
X			if (u.uhp < u.uhpmax) {
X				if (u.ulevel > 9) {
X					if (u.uregen || moves % 3 == 0) {
X						flags.dhp = 1;
X						u.uhp +=
X							rnd (u.ulevel - 9);
X						if (u.uhp > u.uhpmax)
X							u.uhp = u.uhpmax;
X					}
X				}
X				else if (u.uregen || moves %
X						(22 - (u.ulevel << 1)) == 0) {
X					flags.dhp = 1;
X					u.uhp++;
X				}
X			}
X			if (u.utel && !rn2 (85))
X				tele ();
X			if (u.usearch)
X				dosearch ();
X			gethungry ();
X		}
X		flags.move = 1;
X		if (flags.dscr && !flags.mv)
X			nscr ();
X		if (flags.botl)
X			bot ();
X		else if (flags.dgold) {
X			flags.dgold = 0;
X			curs (16, 24);
X			curx = 21;
X			printf ("%-5U", u.ugold);
X		}
X		if (flags.dhp) {
X			flags.dhp = 0;
X			curs (26, 24);
X			curx = 29;
X			printf ("%3d", u.uhp);
X		}
X		if (flags.dhpmax) {
X			flags.dhpmax = 0;
X			curs (30, 24);
X			printf ("%d)", u.uhpmax);
X			if (u.uhpmax < 100)
X				putchar (' ');
X			curx = (u.uhpmax < 10) ? 33 : 34;
X		}
X		if (flags.dac) {
X			flags.dac = 0;
X			curs (37, 24);
X			printf ("%-3d", u.uac);
X			curx = 40;
X		}
X		if (flags.dstr) {
X			flags.dstr = 0;
X			curs (46, 24);
X			prustr ();
X			curx = 51;
X		}
X		if (flags.dulev) {
X			flags.dulev = 0;
X			curs (57, 24);
X			printf ("%2d", u.ulevel);
X			curx = 59;
X		}
X		if (flags.dexp) {
X			flags.dexp = 0;
X			curs (60, 24);
X			if (u.ulevel < 14)
X				printf ("%-5U", u.uexp);
X			else
X				printf ("MAX++");
X			curx = 65;
X		}
X		if (flags.dhs) {
X			flags.dhs = 0;
X			curs (71, 24);
X			printf (hu_stat[u.uhs]);
X			curx = 79;
X		}
X		if (multi < 0) {
X			if (!++multi) {
X				pline (nomvmsg ? nomvmsg :
X						"You can move again.");
X				nomvmsg = 0;
X			}
X		}
X		else {
X			if (multi) {
X				lookaround ();
X				if (!multi) {
X					flags.move = 0;
X					continue;
X				}
X				if (flags.mv) {
X					if (multi < 80 && !--multi) {
X						flags.mv = 0;
X						flags.run = 0;
X					}
X					domove ();
X				}
X				else {
X					--multi;
X					rhack (save_cm);
X				}
X			}
X			else
X				rhack (parse ());
X		}
X	}
X}
X
Xglo (n)
Xregister        n;		/* Construct the string `hackpid.n' */
X{
X/*
X	register char *tf = lock;
X
X	while( *tf && *tf != '.' )
X		tf++;
X	*tf++ = '.';
X	sprintf( tf, "%d", n );
X*/
X	sprintf (lock, "%d.%d", hackpid, n);
X}
X
Ximpossible () {
X	pline ("Program in disorder - perhaps you'd better Quit");
X}
/
echo 'x - hack.mkobj.c'
sed 's/^X//' > hack.mkobj.c << '/'
X/*
X * Hack.mkobj.c
X */
X
X#include "hack.h"
X#include "hack.vars.h"
X
Xmkfood () {
X	register        FOOD fp;
X	register        i = rn2 (100);
X
X	fp = &foods[0];
X	while ((i -= fp -> prob) >= 0)
X		fp++;
X	return (fp - foods);
X}
X
Xmkarm () {
X	register        ARMOR ap;
X	register        i = rn2 (100);
X
X	ap = &armors[0];
X	while ((i -= ap -> prob) >= 0)
X		ap++;
X	return (ap - armors);
X}
X
Xmkwep () {
X	register        WEAPON wp;
X	register        i = rn2 (100);
X
X	wp = &weapons[0];
X	while ((i -= wp -> prob) >= 0)
X		wp++;
X	return (wp - weapons);
X}
X
Xchar    mkobjstr[] = "))[[!!!!????%%%%//=**";
X
Xmkobj (let)
Xregister        let;
X{
X	register        OBJECT otmp;
X
X	otmp = newobj ();
X	otmp -> nobj = fobj;
X	fobj = otmp;
X	otmp -> known = 0;
X	otmp -> cursed = 0;
X	otmp -> spe = 0;
X	otmp -> unpaid = 0;
X	otmp -> quan = 1;
X	if (!let)
X		let = mkobjstr[rn2 (sizeof (mkobjstr) - 1)];
X	otmp -> olet = let;
X	switch (let) {
X
X		case ')': 
X			otmp -> otyp = mkwep ();
X			if (otmp -> otyp <= W_AMMUNITION)
X				otmp -> quan = rn1 (6, 6);
X			if (!rn2 (11))
X				otmp -> spe = rnd (3);
X			else if (!rn2 (10)) {
X				otmp -> cursed = 1;
X				otmp -> spe = -rnd (3);
X			}
X			break;
X
X		case '*': 
X			otmp -> otyp = rn2 (SIZE (potcol));
X			otmp -> quan = rn2 (6) ? 1 : 2;
X			break;
X
X		case '[': 
X			otmp -> otyp = mkarm ();
X			if (!rn2 (8))
X				otmp -> cursed = 1;
X			if (!rn2 (10))
X				otmp -> spe = rnd (3);
X			else if (!rn2 (9)) {
X				otmp -> spe = -rnd (3);
X				otmp -> cursed = 1;
X			}
X			otmp -> spe += 10 - armors[otmp -> otyp].a_ac;
X			break;
X
X		case '!': 
X			otmp -> otyp = rn2 (SIZE (pottyp));
X			break;
X
X		case '?': 
X			otmp -> otyp = rn2 (SIZE (scrtyp));
X			break;
X
X		case '%': 
X			otmp -> otyp = mkfood ();
X			otmp -> quan = rn2 (6) ? 1 : 2;
X			break;
X
X		case '/': 
X			otmp -> otyp = rn2 (SIZE (wantyp));
X			if (otmp -> otyp == Z_DEATH)
X				otmp -> otyp = rn2 (SIZE (wantyp));
X			otmp -> spe = rn1 (5, (otmp -> otyp <= Z_CREATE_MON) ?
X					11 : 4);
X		/* detection and light and create monster */
X			break;
X
X		case '=': 
X			otmp -> otyp = rn2 (SIZE (ringtyp));
X			if (otmp -> otyp >= R_GAIN_STR) {
X				if (!rn2 (3)) {
X					otmp -> spe = -rnd (2);
X					otmp -> cursed = 1;
X					break;
X				}
X				else
X					otmp -> spe = rnd (2);
X			}
X			else if (otmp -> otyp == R_TELE ||
X						otmp -> otyp == R_AGGRAV_MON ||
X					otmp -> otyp == R_HUNGER)
X				otmp -> cursed = 1;
X			break;
X
X		default: 
X			panic (CORE, "Impossible mkobj");
X	}
X}
X
Xshufl (base, num)
Xregister char  *base[];
Xregister        num;
X{
X	char  **tmp, *tmp1;
X	int     curnum;
X
X	for (curnum = num - 1; curnum > 0; curnum--) {
X		tmp = &base[rn2 (curnum)];
X		tmp1 = *tmp;
X		*tmp = base[curnum];
X		base[curnum] = tmp1;
X	}
X}
X
Xshuffle () {
X	shufl (wannam, SIZE (wantyp));
X	shufl (potcol, SIZE (potcol));
X	shufl (rinnam, SIZE (ringtyp));
X	shufl (scrnam, SIZE (scrtyp));
X}
X
Xsavenames (fd)
Xregister        fd;
X{
X	bwrite (fd, oiden, sizeof oiden);
X	bwrite (fd, potcol, sizeof potcol);
X	bwrite (fd, scrnam, sizeof scrnam);
X	bwrite (fd, wannam, sizeof wannam);
X	bwrite (fd, rinnam, sizeof rinnam);
X}
X
Xrestnames (fd)
Xregister        fd;
X{
X	mread (fd, oiden, sizeof oiden);
X	mread (fd, potcol, sizeof potcol);
X	mread (fd, scrnam, sizeof scrnam);
X	mread (fd, wannam, sizeof wannam);
X	mread (fd, rinnam, sizeof rinnam);
X}
X
X/* Restore the names we have given to things */
Xcallsrestore (fd)
Xregister        fd;
X{
X	restcalls (fd, potcall, SIZE (pottyp));
X	restcalls (fd, wandcall, SIZE (wantyp));
X	restcalls (fd, ringcall, SIZE (ringtyp));
X	restcalls (fd, scrcall, SIZE (scrtyp));
X}
X
X/* Save things we have given names to */
Xcallssave (fd)
Xregister        fd;
X{
X	savecalls (fd, potcall, SIZE (pottyp));
X	savecalls (fd, wandcall, SIZE (wantyp));
X	savecalls (fd, ringcall, SIZE (ringtyp));
X	savecalls (fd, scrcall, SIZE (scrtyp));
X}
X
Xsavecalls (fd, strings, max)
Xchar   *strings[];
Xregister int    max, fd;
X{
X	register        teller;
X
X	for (teller = 0; teller < max; ++teller) {
X		if (strings[teller])
X			bwrite (fd, strings[teller],
X					strlen (strings[teller]) + 1);
X		else
X			bwrite (fd, "\0", 1);
X	}
X}
X
Xrestcalls (fd, strings, max)
Xregister int    fd, max;
Xchar   *strings[];
X{
X	register        teller;
X	char   *str;
X	int     cnt;
X	char    buffer[BUFSZ];
X
X	str = NULL;
X	for (teller = 0; teller < max; ++teller) {
X		cnt = -1;
X		do {
X			++cnt;
X			mread (fd, str, 1);
X			buffer[cnt] = *str;
X		} while (*str != '\0');
X		if (cnt) {
X			strings[teller] = alloc (strlen (buffer) + 1) -> Val;
X			strcpy (strings[teller], buffer);
X		}
X	}
X}
/
echo 'x - hack.save.c'
sed 's/^X//' > hack.save.c << '/'
X/*
X * Hack.save.c
X */
X
X/*
X * The old version of save () didn't work at all. Many things are changed,
X * but some things are not implemented yet, like saving in a shop, or saving
X * while swallowed or stuck
X */
X
X#include "hack.h"
X#include "hack.dog.h"
X#include <signal.h>
X
X#define MAXLEVEL	40
X
Xextern char     SAVEFILE[], nul[], upxstairs[MAXLEVEL],
X                upystairs[MAXLEVEL], shlevel, vaultflag[MAXLEVEL];
Xextern long     robbed;
Xextern unsigned starved;
Xextern  COORDINATES shk, shd;
Xextern  MONSTER shopkeeper;
Xextern  MONSTER mydogs;
X
Xsave () {
X	register        fd, ofd, tmp;
X	register        OBJECT otmp, otmp2;
X	MONSTER mtmp;
X	int     version = VERSION;
X
X	nomove ();
X	if (shopkeeper && inshproom (u.ux, u.uy)) {
X		pline ("You are not allowed to save in a shop. (Continue or Quit)");
X		return;
X	}
X	else if (u.ustuck || u.uswallow) {
X		pline ("Not implemented when you're stuck or swallowed. (Continue or Quit)");
X		return;
X	}
X	if ((fd = creat (SAVEFILE, 0644)) < 0) {
X		pline ("Cannot creat save file. (Continue or Quit)");
X		return;
X	}
X	signal (SIGINT, SIG_IGN);
X	signal (SIGQUIT, SIG_IGN);
X
X	bwrite (fd, &version, sizeof (version));
X	keepdogs (0);
X	savelev (fd);
X	for (otmp = invent; otmp; otmp = otmp2) {
X		bwrite (fd, otmp, sizeof (struct obj));
X		if (otmp == uarm)
X			bwrite (fd, "a", 1);
X		else if (otmp == uarm2)
X			bwrite (fd, "b", 1);
X		else if (otmp == uwep)
X			bwrite (fd, "w", 1);
X		else if (otmp == uleft)
X			bwrite (fd, "l", 1);
X		else if (otmp == uright)
X			bwrite (fd, "r", 1);
X		else
X			bwrite (fd, "n", 1);
X		otmp2 = otmp -> nobj;
X		ofree (otmp);
X	}
X	bwrite (fd, nul, sizeof (struct obj));
X	bwrite (fd, &flags, sizeof (struct flag));
X	bwrite (fd, &dlevel, sizeof dlevel);
X	bwrite (fd, &moves, sizeof moves);
X	bwrite (fd, &u, sizeof (struct you));
X	bwrite (fd, genocided, sizeof genocided);
X	bwrite (fd, upxstairs, sizeof upxstairs);
X	bwrite (fd, upystairs, sizeof upystairs);
X	bwrite (fd, vaultflag, sizeof vaultflag);
X
X	savenames (fd);
X
X/* SHOP part */
X	bwrite (fd, &shd, sizeof (struct coord));
X	bwrite (fd, &shk, sizeof (struct coord));
X	bwrite (fd, &shlevel, sizeof shlevel);
X	bwrite (fd, &robbed, sizeof robbed);
X
X/* Various globals */
X	bwrite (fd, &starved, sizeof starved);
X	bwrite (fd, &seehx, sizeof seehx);
X	bwrite (fd, &seelx, sizeof seelx);
X	bwrite (fd, &seehy, sizeof seehy);
X	bwrite (fd, &seely, sizeof seely);
X	bwrite (fd, &dx, sizeof dx);
X	bwrite (fd, &dy, sizeof dy);
X	bwrite (fd, &maxdlevel, sizeof maxdlevel);
X
X/* And the dog(s) if any */
X	for (mtmp = mydogs; mtmp; mtmp = mtmp -> nmon)
X		bwrite (fd, mtmp, sizeof (struct monst) +
X			                                        sizeof (struct edog));
X	bwrite (fd, nul, sizeof (struct monst) + sizeof (struct edog));
X
X	callssave (fd);
X
X	cls ();
X	printf ("Saving level ");
X	flush ();
X	for (tmp = 1;; tmp++) {
X		glo (tmp);
X		if ((ofd = open (lock, 0)) < 0)
X			break;
X		getlev (ofd);
X		close (ofd);
X		savelev (fd);
X		printf ("%2d - %s", tmp,
X				(tmp % 10) ? "" : "\n             ");
X		flush ();
X		unlink (lock);
X	}
X
X	close (fd);
X	(*index (lock, '.')) = '\0';/* Remove main lock */
X	unlink (lock);
X	printf ("\n\nSee you around...\n");
X	flush ();
X	hackmode (OFF);
X	exit (0);
X}
X
Xdorecover (fd)
Xregister        fd;
X{
X	register        nfd, tmp;
X	register        OBJECT otmp, olast;
X	MONSTER mtmp;
X	int     version;
X
X	cls ();
X	printf ("Starting up a suspended game....\n");
X	flush ();
X	mread (fd, &version, sizeof (version));
X	if (version != VERSION) {
X		printf ("Sorry, you're savefile is out of date.\n");
X		printf ("I will have to remove it.\n");
X		printf ("Type <space> to continue.");
X		close (fd);
X		unlink (SAVEFILE);
X		flush ();
X		while (getchar () != ' ');
X		return - 1;
X	}
X
X	getlev (fd);
X
X	invent = otmp = newobj ();
X	while (1) {
X		mread (fd, otmp, sizeof (struct obj));
X		if (!otmp -> olet) {
X			if (otmp == invent)
X				invent = 0;
X			else
X				olast -> nobj = 0;
X			ofree (otmp);
X			break;
X		}
X		olast = otmp;
X		olast -> nobj = otmp = newobj ();
X		mread (fd, buf, 1);
X		switch (*buf) {
X			case 'w': 
X				uwep = olast;
X				break;
X			case 'r': 
X				uright = olast;
X				break;
X			case 'l': 
X				uleft = olast;
X				break;
X			case 'a': 
X				uarm = olast;
X				break;
X			case 'b': 
X				uarm2 = olast;
X			case 'n': 
X				break;
X			default: 
X				panic (CORE, "Error reading save file");
X		}
X	}
X	mread (fd, &flags, sizeof (struct flag));
X	mread (fd, &dlevel, sizeof dlevel);
X	mread (fd, &moves, sizeof moves);
X	mread (fd, &u, sizeof (struct you));
X	mread (fd, genocided, sizeof genocided);
X	mread (fd, upxstairs, sizeof upxstairs);
X	mread (fd, upystairs, sizeof upystairs);
X	mread (fd, vaultflag, sizeof vaultflag);
X
X	restnames (fd);
X
X/* Restore shop part */
X	mread (fd, &shd, sizeof (struct coord));
X	mread (fd, &shk, sizeof (shk));
X	mread (fd, &shlevel, sizeof shlevel);
X	mread (fd, &robbed, sizeof robbed);
X
X/* Restore various globals */
X	mread (fd, &starved, sizeof starved);
X	mread (fd, &seehx, sizeof seehx);
X	mread (fd, &seelx, sizeof seelx);
X	mread (fd, &seehy, sizeof seehy);
X	mread (fd, &seely, sizeof seely);
X	mread (fd, &dx, sizeof dx);
X	mread (fd, &dy, sizeof dy);
X	mread (fd, &maxdlevel, sizeof maxdlevel);
X
X/* Let's try the dog again */
X	while (1) {
X		mtmp = newmonst (sizeof (struct edog));
X		mread (fd, mtmp, sizeof (struct monst) +
X			                                        sizeof (struct edog));
X		if (mtmp -> data == 0)
X			break;
X		else {
X			mtmp -> nmon = mydogs;
X			mydogs = mtmp;
X		}
X	}
X	free (mtmp);
X
X	callsrestore (fd);
X
X	printf ("Restoring level ");
X	flush ();
X	for (tmp = 1;; tmp++) {
X		if (getlev (fd))
X			break;
X		glo (tmp);
X		if ((nfd = creat (lock, 0644)) < 0)
X			panic (CORE, "Cannot open temp file %s!\n",
X					lock);
X		savelev (nfd);
X		printf ("%2d - %s", tmp,
X				(tmp % 10) ? "" : "\n                ");
X		flush ();
X		close (nfd);
X	}
X
X	lseek (fd, (long) (sizeof (version)), 0);
X	getlev (fd);
X	close (fd);
X	losedogs ();
X	unlink (SAVEFILE);
X	docrt ();
X	return 1;
X}
/
echo 'Part 04 of Hack complete.'
exit
-- 

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



More information about the Comp.sources.unix mailing list