[net.sources] hack: changes for SVR2

gam@amdahl.UUCP (gam) (01/06/85)

I have gotten hack to compile successfully under Sys V Rel 2 and
the three shars following are the files with relevant changes.
Hack has not been played extensively here so I don't know how well
I have debugged it.

Among other things, I have used the System V 'drand48(3)' routines
for random number generation.  Also some "linting" has been done.

If you have any problems, post them to net.sources.bugs.

------------------- close cover before striking match ------------------
: This is a shar archive.  Extract with sh, not csh.
echo x - hack.do.c
sed -e 's/^X//' > hack.do.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <stdio.h>
X#include <signal.h>
X#include "hack.h"
X#include "def.func_tab.h"
X
Xextern char *getenv(),*parse(),*getlogin(),*lowc(),*unctrl();
Xextern int float_down();
Xextern char *nomovemsg, *catmore;
Xextern struct obj *splitobj(), *addinv();
Xextern boolean hmon();
X
X/*	Routines to do various user commands */
X
Xint done1();
X
Xdodrink() {
X	register struct obj *otmp,*objs;
X	register struct monst *mtmp;
X	register int unkn = 0, nothing = 0;
X
X	otmp = getobj("!", "drink");
X	if(!otmp) return(0);
X	switch(otmp->otyp){
X	case POT_RESTORE_STRENGTH:
X		unkn++;
X		pline("Wow!  This makes you feel great!");
X		if(u.ustr < u.ustrmax) {
X			u.ustr = u.ustrmax;
X			flags.botl = 1;
X		}
X		break;
X	case POT_BOOZE:
X		unkn++;
X		pline("Ooph!  This tastes like liquid fire!");
X		Confusion += d(3,8);
X		/* the whiskey makes us feel better */
X		if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
X		if(!rn2(4)) {
X			pline("You pass out.");
X			multi = -rnd(15);
X			nomovemsg = "You awake with a headache.";
X		}
X		break;
X	case POT_INVISIBILITY:
X		if(Invis)
X		  nothing++;
X		else {
X		  if(!Blind)
X		    pline("Gee!  All of a sudden, you can't see yourself.");
X		  else
X		    pline("You feel rather airy."), unkn++;
X		  newsym(u.ux,u.uy);
X		}
X		Invis += rn1(15,31);
X		break;
X	case POT_FRUIT_JUICE:
X		pline("This tastes like fruit juice.");
X		lesshungry(20);
X		break;
X	case POT_HEALING:
X		pline("You begin to feel better.");
X		flags.botl = 1;
X		u.uhp += rnd(10);
X		if(u.uhp > u.uhpmax)
X			u.uhp = ++u.uhpmax;
X		if(Blind) Blind = 1;	/* see on next move */
X		if(Sick) Sick = 0;
X		break;
X	case POT_PARALYSIS:
X		pline("Your feet are frozen to the floor!");
X		nomul(-(rn1(10,25)));
X		break;
X	case POT_MONSTER_DETECTION:
X		if(!fmon) {
X			strange_feeling(otmp);
X			return(1);
X		} else {
X			cls();
X			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X				if(mtmp->mx > 0)
X				at(mtmp->mx,mtmp->my,mtmp->data->mlet);
X			prme();
X			pline("You sense the presence of monsters.");
X			more();
X			docrt();
X		}
X		break;
X	case POT_OBJECT_DETECTION:
X		if(!fobj) {
X			strange_feeling(otmp);
X			return(1);
X		} else {
X		    for(objs = fobj; objs; objs = objs->nobj)
X			if(objs->ox != u.ux || objs->oy != u.uy)
X				goto outobjmap;
X		    pline("You sense the presence of objects close nearby.");
X		    break;
X		outobjmap:
X			cls();
X			for(objs = fobj; objs; objs = objs->nobj)
X				at(objs->ox,objs->oy,objs->olet);
X			prme();
X			pline("You sense the presence of objects.");
X			more();
X			docrt();
X		}
X		break;
X	case POT_SICKNESS:
X		pline("Yech! This stuff tastes like poison.");
X		if(Poison_resistance)
X    pline("(But in fact it was biologically contaminated orange juice.)");
X		losestr(rn1(4,3));
X		losehp(rnd(10), "poison potion");
X		break;
X	case POT_CONFUSION:
X		if(!Confusion)
X			pline("Huh, What?  Where am I?");
X		else
X			nothing++;
X		Confusion += rn1(7,16);
X		break;
X	case POT_GAIN_STRENGTH:
X		pline("Wow do you feel strong!");
X		if(u.ustr == 118) break;
X		if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
X		else u.ustr++;
X		if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
X		flags.botl = 1;
X		break;
X	case POT_SPEED:
X		if(Wounded_legs) {
X			if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
X				pline("Your legs feel somewhat better.");
X			else
X				pline("Your leg feels somewhat better.");
X			Wounded_legs = 0;
X			unkn++;
X			break;
X		}
X		if(!(Fast & ~INTRINSIC))
X			pline("You are suddenly moving much faster.");
X		else
X			pline("Your legs get new energy."), unkn++;
X		Fast += rn1(10,100);
X		break;
X	case POT_BLINDNESS:
X		if(!Blind)
X			pline("A cloud of darkness falls upon you.");
X		else
X			nothing++;
X		Blind += rn1(100,250);
X		seeoff(0);
X		break;
X	case POT_GAIN_LEVEL: 
X		pluslvl();
X		break;
X	case POT_EXTRA_HEALING:
X		pline("You feel much better.");
X		flags.botl = 1;
X		u.uhp += d(2,20)+1;
X		if(u.uhp > u.uhpmax)
X			u.uhp = (u.uhpmax += 2);
X		if(Blind) Blind = 1;
X		if(Sick) Sick = 0;
X		break;
X	case POT_LEVITATION:
X		if(!Levitation)
X			float_up();
X		else
X			nothing++;
X		Levitation += rnd(100);
X		u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
X		break;
X	default:
X		pline("What a funny potion! (%d)", otmp->otyp);
X		impossible();
X		return(0);
X	}
X	if(nothing) {
X	    unkn++;
X	    pline("You have a peculiar feeling for a moment, then it passes.");
X	}
X	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
X		if(!unkn) {
X			objects[otmp->otyp].oc_name_known = 1;
X			u.urexp += 10;
X		} else if(!objects[otmp->otyp].oc_uname)
X			docall(otmp);
X	}
X	useup(otmp);
X	return(1);
X}
X
Xpluslvl()
X{
X	register num;
X
X	pline("You feel more experienced.");
X	num = rnd(10);
X	u.uhpmax += num;
X	u.uhp += num;
X	u.uexp = (10*pow(u.ulevel-1))+1;
X	pline("Welcome to level %d.", ++u.ulevel);
X	flags.botl = 1;
X}
X
Xstrange_feeling(obj)
Xregister struct obj *obj;
X{
X	pline("You have a strange feeling for a moment, then it passes.");
X	if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
X		docall(obj);
X	useup(obj);
X}
X
Xdodrop() {
X	register struct obj *obj;
X
X	obj = getobj("0$#", "drop");
X	if(!obj) return(0);
X	if(obj->olet == '$') {
X		if(obj->quan == 0)
X			pline("You didn't drop any gold pieces.");
X		else {
X			mkgold((int) obj->quan, u.ux, u.uy);
X			pline("You dropped %u gold piece%s.",
X				obj->quan, plur(obj->quan));
X			if(Invis) newsym(u.ux, u.uy);
X		}
X		free((char *) obj);
X		return(1);
X	}
X	return(drop(obj));
X}
X
Xdrop(obj) register struct obj *obj; {
X	if(obj->owornmask & (W_ARMOR | W_RING)){
X		pline("You cannot drop something you are wearing.");
X		return(0);
X	}
X	if(obj == uwep) {
X		if(uwep->cursed) {
X			pline("Your weapon is welded to your hand!");
X			return(0);
X		}
X		setuwep((struct obj *) 0);
X	}
X	pline("You dropped %s.", doname(obj));
X	dropx(obj);
X	return(1);
X}
X
Xdropx(obj) register struct obj *obj; {
X	if(obj->otyp == CRYSKNIFE)
X		obj->otyp = WORM_TOOTH;
X	freeinv(obj);
X	obj->ox = u.ux;
X	obj->oy = u.uy;
X	obj->nobj = fobj;
X	fobj = obj;
X	if(Invis) newsym(u.ux,u.uy);
X	subfrombill(obj);
X	stackobj(obj);
X}
X
X/* drop several things */
Xdoddrop() {
X	return(ggetobj("drop", drop, 0));
X}
X
Xrhack(cmd)
Xregister char *cmd;
X{
X	register struct func_tab *tlist = list;
X	boolean firsttime = FALSE;
X	register res;
X
X	if(!cmd) {
X		firsttime = TRUE;
X		flags.nopick = 0;
X		cmd = parse();
X	}
X	if(!*cmd || *cmd == 0377)
X		return;		/* probably we just had an interrupt */
X	if(movecm(cmd)) {
X	walk:
X		if(multi) flags.mv = 1;
X		domove();
X		return;
X	}
X	if(movecm(lowc(cmd))) {
X		flags.run = 1;
X	rush:
X		if(firsttime){
X			if(!multi) multi = COLNO;
X			u.last_str_turn = 0;
X		}
X		flags.mv = 1;
X#ifdef QUEST
X		if(flags.run >= 4) finddir();
X		if(firsttime){
X			u.ux0 = u.ux + u.dx;
X			u.uy0 = u.uy + u.dy;
X		}
X#endif QUEST
X		domove();
X		return;
X	}
X	if((*cmd == 'f' && movecm(cmd+1)) ||
X		movecm(unctrl(cmd))) {
X		flags.run = 2;
X		goto rush;
X	}
X	if(*cmd == 'F' && movecm(lowc(cmd+1))) {
X		flags.run = 3;
X		goto rush;
X	}
X	if(*cmd == 'm' && movecm(cmd+1)) {
X		flags.run = 0;
X		flags.nopick = 1;
X		goto walk;
X	}
X	if(*cmd == 'M' && movecm(lowc(cmd+1))) {
X		flags.run = 1;
X		flags.nopick = 1;
X		goto rush;
X	}
X#ifdef QUEST
X	if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
X		flags.run = 4;
X		if(*cmd == 'F') flags.run += 2;
X		if(cmd[2] == '-') flags.run += 1;
X		goto rush;
X	}
X#endif QUEST
X	while(tlist->f_char) {
X		if(*cmd == tlist->f_char){
X			res = (*(tlist->f_funct))(0);
X			if(!res) {
X				flags.move = 0;
X				multi = 0;
X			}
X			return;
X		}
X		tlist++;
X	}
X	pline("Unknown command '%s'",cmd);
X	multi = flags.move = 0;
X}
X
Xdoredraw()
X{
X	docrt();
X	return(0);
X}
X
Xdohelp()
X{
X	if(child(1)){
X		execl(catmore,"more","help",(char *)0);
X		exit(1);
X	}
X	return(0);
X}
X
X#ifdef SHELL
Xdosh(){
Xregister char *str;
X	if(child(0)) {
X		(void) chdir(getenv("HOME"));
X		if(str = getenv("SHELL")) execl(str,str,(char *) 0);
X		if(strcmp("player", getlogin()))
X			execl("/bin/sh","sh",(char *) 0);
X		pline("sh: cannot execute.");
X		exit(1);
X	}
X	return(0);
X}
X#endif SHELL
X
X#ifdef BSD
X#include	<sys/wait.h>
X#endif BSD
X
Xchild(wt) {
Xregister int f = fork();
X	if(f == 0){		/* child */
X		settty((char *) 0);
X		(void) setuid(getuid());
X		return(1);
X	}
X	if(f == -1) {	/* cannot fork */
X		pline("Fork failed. Try again.");
X		return(0);
X	}
X	/* fork succeeded; wait for child to exit */
X	(void) signal(SIGINT,SIG_IGN);
X	(void) signal(SIGQUIT,SIG_IGN);
X#ifdef BSD
X	(void) wait((union wait *) 0);
X#else
X	(void) wait((int *) 0);
X#endif BSD
X	setctty();
X	(void) signal(SIGINT, (void (*)()) done1);
X#ifdef WIZARD
X	if(wizard) (void) signal(SIGQUIT,SIG_DFL);
X#endif WIZARD
X	if(wt) getret();
X	docrt();
X	return(0);
X}
X
Xdodown()
X{
X	if(u.ux != xdnstair || u.uy != ydnstair) {
X		pline("You can't go down here.");
X		return(0);
X	}
X	if(u.ustuck) {
X		pline("You are being held, and cannot go down.");
X		return(1);
X	}
X	if(Levitation) {
X		pline("You're floating high above the stairs.");
X		return(0);
X	}
X
X	goto_level(dlevel+1, TRUE);
X	return(1);
X}
X
Xdoup()
X{
X	if(u.ux != xupstair || u.uy != yupstair) {
X		pline("You can't go up here.");
X		return(0);
X	}
X	if(u.ustuck) {
X		pline("You are being held, and cannot go up.");
X		return(1);
X	}
X	if(inv_weight() + 5 > 0) {
X		pline("Your load is too heavy to climb the stairs.");
X		return(1);
X	}
X
X	goto_level(dlevel-1, TRUE);
X	return(1);
X}
X
Xgoto_level(newlevel, at_stairs)
Xregister int newlevel;
Xregister boolean at_stairs;
X{
X	register fd;
X	register boolean up = (newlevel < dlevel);
X
X	if(newlevel <= 0) done("escaped");	/* in fact < 0 is impossible */
X	if(newlevel == dlevel) return;		/* this cannot happen either */
X
X	glo(dlevel);
X	fd = creat(lock,FMASK);
X	if(fd < 0) {
X		/*
X		 * This is not quite impossible: e.g., we may have
X		 * exceeded our quota. If that is the case then we
X		 * cannot leave this level, and cannot save either.
X		 */
X		pline("A mysterious force prevents you from going %d.",
X			up ? "up" : "down");
X		return;
X	}
X
X	if(Punished) unplacebc();
X	keepdogs();
X	seeoff(1);
X	flags.nscrinh = 1;
X	u.ux = FAR;				/* hack */
X	(void) inshop();			/* probably was a trapdoor */
X
X	savelev(fd);
X	(void) close(fd);
X
X	dlevel = newlevel;
X	if(maxdlevel < dlevel)
X		maxdlevel = dlevel;
X	glo(dlevel);
X	if((fd = open(lock,0)) < 0)
X		mklev();
X	else {
X		(void) getlev(fd);
X		(void) close(fd);
X	}
X
X	if(at_stairs) {
X	    if(up) {
X		u.ux = xdnstair;
X		u.uy = ydnstair;
X		if(!u.ux) {		/* entering a maze from below? */
X		    u.ux = xupstair;	/* this will confuse the player! */
X		    u.uy = yupstair;
X		}
X		if(Punished){
X			pline("With great effort you climb the stairs");
X			placebc(1);
X		}
X	    } else {
X		u.ux = xupstair;
X		u.uy = yupstair;
X		if(inv_weight() + 5 > 0 || Punished){
X			pline("You fall down the stairs.");
X			losehp(rnd(3), "fall");
X			if(Punished) {
X			    if(uwep != uball && rn2(3)){
X				pline("... and are hit by the iron ball");
X				losehp(rnd(20), "iron ball");
X			    }
X			    placebc(1);
X			}
X			selftouch("Falling, you");
X		}
X	    }
X	} else {	/* trapdoor or level_tele */
X	    do {
X		u.ux = rnd(COLNO-1);
X		u.uy = rn2(ROWNO);
X	    } while(levl[u.ux][u.uy].typ != ROOM ||
X			m_at(u.ux,u.uy));
X	    if(Punished){
X		if(uwep != uball && !up /* %% */ && rn2(5)){
X			pline("The iron ball falls on your head.");
X			losehp(rnd(25), "iron ball");
X		}
X		placebc(1);
X	    }
X	    selftouch("Falling, you");
X	}
X	(void) inshop();
X#ifdef TRACK
X	initrack();
X#endif TRACK
X
X	losedogs();
X	flags.nscrinh = 0;
X	setsee();
X	docrt();
X	pickup();
X	read_engr_at(u.ux,u.uy);
X}
X
Xdonull() {
X	return(1);	/* Do nothing, but let other things happen */
X}
X
Xstruct monst *bhit(), *boomhit();
Xdothrow()
X{
X	register struct obj *obj;
X	register struct monst *mon;
X	register tmp;
X
X	obj = getobj("#)", "throw");	/* it is also possible to throw food */
X					/* (or jewels, or iron balls ... ) */
X	if(!obj || !getdir())
X		return(0);
X	if(obj->owornmask & (W_ARMOR | W_RING)){
X		pline("You can't throw something you are wearing");
X		return(0);
X	}
X	if(obj == uwep){
X		if(obj->cursed){
X			pline("Your weapon is welded to your hand");
X			return(1);
X		}
X		if(obj->quan > 1)
X			setuwep(splitobj(obj, 1));
X		else
X			setuwep((struct obj *) 0);
X	}
X	else if(obj->quan > 1)
X		(void) splitobj(obj, 1);
X	freeinv(obj);
X	if(u.uswallow) {
X		mon = u.ustuck;
X		bhitpos.x = mon->mx;
X		bhitpos.y = mon->my;
X	} else if(obj->otyp == BOOMERANG) {
X		mon = boomhit(u.dx,u.dy);
X		/* boomhit delivers -1 if the thing was caught */
X		if((int) mon == -1) {
X			(void) addinv(obj);
X			return(1);
X		}
X	} else
X		mon = bhit(u.dx,u.dy,
X			(!Punished || obj != uball) ? 8 :
X				!u.ustuck ? 5 : 1,
X			obj->olet);
X	if(mon) {
X		/* awake monster if sleeping */
X		wakeup(mon);
X
X		if(obj->olet == WEAPON_SYM) {
X			tmp = -1+u.ulevel+mon->data->ac+abon();
X			if(obj->otyp < ROCK) {
X				if(!uwep ||
X				    uwep->otyp != obj->otyp+(BOW-ARROW))
X					tmp -= 4;
X				else {
X					tmp += uwep->spe;
X				}
X			} else
X			if(obj->otyp == BOOMERANG) tmp += 4;
X			tmp += obj->spe;
X			if(u.uswallow || tmp >= rnd(20)) {
X				if(hmon(mon,obj,1) == TRUE){
X				  /* mon still alive */
X#ifndef NOWORM
X				  cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
X#endif NOWORM
X				} else mon = 0;
X				/* weapons thrown disappear sometimes */
X				if(obj->otyp < BOOMERANG && rn2(3)) {
X					/* check bill; free */
X					obfree(obj, (struct obj *) 0);
X					return(1);
X				}
X			} else miss(objects[obj->otyp].oc_name, mon);
X		} else if(obj->otyp == HEAVY_IRON_BALL) {
X			tmp = -1+u.ulevel+mon->data->ac+abon();
X			if(!Punished || obj != uball) tmp += 2;
X			if(u.utrap) tmp -= 2;
X			if(u.uswallow || tmp >= rnd(20)) {
X				if(hmon(mon,obj,1) == FALSE)
X					mon = 0;	/* he died */
X			} else miss("iron ball", mon);
X		} else {
X			if(cansee(bhitpos.x,bhitpos.y))
X				pline("You miss %s.",monnam(mon));
X			else pline("You miss it.");
X			if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
X				if(tamedog(mon,obj)) return(1);
X			if(obj->olet == GEM_SYM && mon->data->mlet == 'u'){
X			 if(obj->dknown && objects[obj->otyp].oc_name_known){
X			  if(objects[obj->otyp].g_val > 0){
X			    u.uluck += 5;
X			    goto valuable;
X			  } else {
X			    pline("%s is not interested in your junk.",
X				Monnam(mon));
X			  }
X			 } else { /* value unknown to @ */
X			    u.uluck++;
X			valuable:
X			    pline("%s graciously accepts your gift.",
X				Monnam(mon));
X			    mpickobj(mon, obj);
X			    rloc(mon);
X			    return(1);
X			 }
X			}
X		}
X	}
X	obj->ox = bhitpos.x;
X	obj->oy = bhitpos.y;
X	obj->nobj = fobj;
X	fobj = obj;
X	/* prevent him from throwing articles to the exit and escaping */
X	/* subfrombill(obj); */
X	stackobj(obj);
X	if(Punished && obj == uball &&
X		(bhitpos.x != u.ux || bhitpos.y != u.uy)){
X		freeobj(uchain);
X		unpobj(uchain);
X		if(u.utrap){
X			if(u.utraptype == TT_PIT)
X				pline("The ball pulls you out of the pit!");
X			else {
X			    register int side =
X				rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
X			    pline("The ball pulls you out of the bear trap.");
X			    pline("Your %s leg is severely damaged.",
X				(side == LEFT_SIDE) ? "left" : "right");
X			    Wounded_legs |= side + rnd(1000);
X			    losehp(2, "thrown ball");
X			}
X			u.utrap = 0;
X		}
X		unsee();
X		uchain->nobj = fobj;
X		fobj = uchain;
X		u.ux = uchain->ox = bhitpos.x - u.dx;
X		u.uy = uchain->oy = bhitpos.y - u.dy;
X		setsee();
X		(void) inshop();
X	}
X	if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
X	return(1);
X}
X
Xgetdir()
X{
Xchar buf[2];
X	pline("What direction?");
X	buf[0] = readchar();
X	buf[1] = 0;
X	return(movecm(buf));
X}
X
X/* split obj so that it gets size num */
X/* remainder is put in the object structure delivered by this call */
Xstruct obj *
Xsplitobj(obj, num) register struct obj *obj; register int num; {
Xregister struct obj *otmp;
X	otmp = newobj(0);
X	*otmp = *obj;		/* copies whole structure */
X	otmp->o_id = flags.ident++;
X	otmp->onamelth = 0;
X	obj->quan = num;
X	obj->owt = weight(obj);
X	otmp->quan -= num;
X	otmp->owt = weight(otmp);	/* -= obj->owt ? */
X	obj->nobj = otmp;
X	if(obj->unpaid) splitbill(obj,otmp);
X	return(otmp);
X}
X
Xchar *
Xlowc(str)
Xregister char *str;
X{
X	static char buf[2];
X
X	if(*str >= 'A' && *str <= 'Z') *buf = *str+'a'-'A';
X	else *buf = *str;
X	buf[1] = 0;
X	return(buf);
X}
X
Xchar *
Xunctrl(str)
Xregister char *str;
X{
X	static char buf[2];
X	if(*str >= ('A' & 037) && *str <= ('Z' & 037))
X		*buf = *str + 0140;
X	else *buf = *str;
X	buf[1] = 0;
X	return(buf);
X}
!Funky!Stuff!
echo x - hack.h
sed -e 's/^X//' > hack.h << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "mklev.h"
X#include "hack.onames.h"
X
X#define ON 1
X#define OFF 0
X
X#define index strchr
X
Xextern struct obj *invent, *uwep, *uarm, *uarm2, *uarmh, *uarms, *uarmg, 
X	*uleft, *uright, *fcobj;
Xextern struct obj *uchain;	/* defined iff PUNISHED */
Xextern struct obj *uball;	/* defined if PUNISHED */
Xstruct obj *o_at(), *getobj(), *sobj_at();
X
Xstruct flag {
X	unsigned ident;		/* social security number for each monster */
X	unsigned topl:2;	/* a top line (message) has been printed */
X				/* 0: top line empty; 2: no --More-- reqd. */
X	unsigned cbreak:1;	/* in cbreak mode, rogue format */
X	unsigned oneline:1;	/* give inventories 1 line at a time */
X	unsigned move:1;
X	unsigned mv:1;
X	unsigned run:3;		/* 0: h (etc), 1: H (etc), 2: fh (etc) */
X				/* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */
X	unsigned nopick:1;	/* do not pickup objects */
X	unsigned echo:1;	/* 1 to echo characters */
X	unsigned botl:1;	/* partially redo status line */
X	unsigned botlx:1;	/* print an entirely new bottom line */
X	unsigned nscrinh:1;	/* inhibit nscr() in pline(); */
X};
Xextern struct flag flags;
X
Xstruct prop {
X#define	TIMEOUT		007777	/* mask */
X#define	LEFT_RING	W_RINGL	/* 010000L */
X#define	RIGHT_RING	W_RINGR	/* 020000L */
X#define	INTRINSIC	040000L
X#define	LEFT_SIDE	LEFT_RING
X#define	RIGHT_SIDE	RIGHT_RING
X#define	BOTH_SIDES	(LEFT_SIDE | RIGHT_SIDE)
X	long p_flgs;
X	int (*p_tofn)();	/* called after timeout */
X};
X
Xstruct you {
X	xchar ux, uy;
X	schar dx, dy;		/* direction of fast move */
X#ifdef QUEST
X	schar di;		/* direction of FF */
X	xchar ux0, uy0;		/* initial position FF */
X#endif QUEST
X	xchar udisx, udisy;	/* last display pos */
X	char usym;		/* usually '@' */
X	schar uluck;
X	int last_str_turn:3;	/* 0: none, 1: half turn, 2: full turn */
X				/* +: turn right, -: turn left */
X	unsigned udispl:1;	/* @ on display */
X	unsigned ulevel:5;
X#ifdef QUEST
X	unsigned uhorizon:7;
X#endif QUEST
X	unsigned utrap:3;	/* trap timeout */
X	unsigned utraptype:1;	/* defined if utrap nonzero */
X#define	TT_BEARTRAP	0
X#define	TT_PIT		1
X	unsigned uinshop:1;
X
X
X/* perhaps these #define's should also be generated by makedefs */
X#define	TELEPAT		LAST_RING		/* not a ring */
X#define	Telepat		u.uprops[TELEPAT].p_flgs
X#define	FAST		(LAST_RING+1)		/* not a ring */
X#define	Fast		u.uprops[FAST].p_flgs
X#define	CONFUSION	(LAST_RING+2)		/* not a ring */
X#define	Confusion	u.uprops[CONFUSION].p_flgs
X#define	INVIS		(LAST_RING+3)		/* not a ring */
X#define	Invis		u.uprops[INVIS].p_flgs
X#define	GLIB		(LAST_RING+4)		/* not a ring */
X#define	Glib		u.uprops[GLIB].p_flgs
X#define	PUNISHED	(LAST_RING+5)		/* not a ring */
X#define	Punished	u.uprops[PUNISHED].p_flgs
X#define	SICK		(LAST_RING+6)		/* not a ring */
X#define	Sick		u.uprops[SICK].p_flgs
X#define	BLIND		(LAST_RING+7)		/* not a ring */
X#define	Blind		u.uprops[BLIND].p_flgs
X#define	WOUNDED_LEGS	(LAST_RING+8)		/* not a ring */
X#define Wounded_legs	u.uprops[WOUNDED_LEGS].p_flgs
X#define PROP(x) (x-RIN_ADORNMENT)       /* convert ring to index in uprops */
X	unsigned umconf:1;
X	char *usick_cause;
X	struct prop uprops[LAST_RING+9];
X
X	unsigned uswallow:1;		/* set if swallowed by a monster */
X	unsigned uswldtim:4;		/* time you have been swallowed */
X	unsigned uhs:3;			/* hunger state - see hack.eat.c */
X	schar ustr,ustrmax;
X	schar udaminc;
X	schar uac;
X	int uhp,uhpmax;
X	long int ugold,ugold0,uexp,urexp;
X	int uhunger;			/* refd only in eat.c and shk.c */
X	int uinvault;
X	struct monst *ustuck;
X	int nr_killed[CMNUM+2];		/* used for experience bookkeeping */
X};
X
Xextern struct you u;
X
Xextern char *traps[];
Xextern char *plur(), *monnam(), *Monnam(), *amonnam(), *Amonnam(),
X	*doname(), *aobjnam();
Xextern char readchar();
Xextern char vowels[];
X
Xextern xchar curx,cury;	/* cursor location on screen */
X
Xextern coord bhitpos;	/* place where thrown weapon falls to the ground */
X
Xextern xchar seehx,seelx,seehy,seely; /* where to see*/
Xextern char *save_cm,*killer;
X
Xextern xchar dlevel, maxdlevel; /* dungeon level */
X
Xextern long moves;
X
Xextern int multi;
X
X
Xextern char lock[];
X
X
X#define DIST(x1,y1,x2,y2)       (((x1)-(x2))*((x1)-(x2)) + ((y1)-(y2))*((y1)-(y2)))
X
X#define	PL_CSIZ		20	/* sizeof pl_character */
X#define	MAX_CARR_CAP	120	/* so that boulders can be heavier */
X#define	FAR	(COLNO+2)	/* position outside screen */
X
Xextern void	exit(),
X		perror(),
X		qsort(),
X		free();
!Funky!Stuff!
echo x - hack.lev.c
sed -e 's/^X//' > hack.lev.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "hack.h"
X#include <signal.h>
X#include <stdio.h>
Xextern struct monst *restmonchn();
Xextern struct obj *restobjchn();
Xextern struct obj *billobjs;
Xextern char *itoa();
X
Xextern char nul[];
X#ifndef NOWORM
X#include	"def.wseg.h"
X
Xextern struct wseg *wsegs[32], *wheads[32];
Xextern long wgrowtime[32];
X#endif NOWORM
X
X#include "savelev.h"
X
Xgetlev(fd)
X{
X	register struct gen *gtmp;
X#ifndef NOWORM
X	register struct wseg *wtmp;
X#endif NOWORM
X	register tmp;
X	long omoves;
X
X	if(fd<0 || read(fd, (char *) levl, sizeof(levl)) != sizeof(levl))
X		return(1);
X	fgold = 0;
X	ftrap = 0;
X	mread(fd, (char *)&omoves, sizeof(omoves));	/* 0 from MKLEV */
X	mread(fd, (char *)&xupstair, sizeof(xupstair));
X	mread(fd, (char *)&yupstair, sizeof(yupstair));
X	mread(fd, (char *)&xdnstair, sizeof(xdnstair));
X	mread(fd, (char *)&ydnstair, sizeof(ydnstair));
X
X	fmon = restmonchn(fd);
X	if(omoves) {
X	    /* regenerate animals while on another level */
X	    long tmoves = (moves > omoves) ? moves-omoves : 0;
X	    register struct monst *mtmp, *mtmp2;
X	    extern char genocided[];
X
X	    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
X		mtmp2 = mtmp->nmon;
X		if(index(genocided, mtmp->data->mlet)) {
X			mondead(mtmp);
X			continue;
X		}
X		if(index("ViT", mtmp->data->mlet))
X			mtmp->mhp += tmoves;
X		else
X			mtmp->mhp += tmoves/20;
X		if(mtmp->mhp > mtmp->orig_hp)
X			mtmp->mhp = mtmp->orig_hp;
X	    }
X	}
X
X	setshk();
X	setgd();
X	gtmp = newgen();
X	mread(fd, (char *)gtmp, sizeof(struct gen));
X	while(gtmp->gx) {
X		gtmp->ngen = fgold;
X		fgold = gtmp;
X		gtmp = newgen();
X		mread(fd, (char *)gtmp, sizeof(struct gen));
X	}
X	mread(fd, (char *)gtmp, sizeof(struct gen));
X	while(gtmp->gx) {
X		gtmp->ngen = ftrap;
X		ftrap = gtmp;
X		gtmp = newgen();
X		mread(fd, (char *)gtmp, sizeof(struct gen));
X	}
X	free((char *) gtmp);
X	fobj = restobjchn(fd);
X	billobjs = restobjchn(fd);
X	rest_engravings(fd);
X#ifndef QUEST
X	mread(fd, (char *)rooms, sizeof(rooms));
X	mread(fd, (char *)doors, sizeof(doors));
X#endif QUEST
X	if(!omoves) return(0);	/* from MKLEV */
X#ifndef NOWORM
X	mread(fd, (char *)wsegs, sizeof(wsegs));
X	for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
X		wheads[tmp] = wsegs[tmp] = wtmp = newseg();
X		while(1) {
X			mread(fd, (char *)wtmp, sizeof(struct wseg));
X			if(!wtmp->nseg) break;
X			wheads[tmp]->nseg = wtmp = newseg();
X			wheads[tmp] = wtmp;
X		}
X	}
X	mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
X#endif NOWORM
X	return(0);
X}
X
Xmread(fd, buf, len)
Xregister fd;
Xregister char *buf;
Xregister unsigned len;
X{
Xregister int rlen;
X	rlen = read(fd, buf, len);
X	if(rlen != len){
X		pline("Read %d instead of %d bytes\n", rlen, len);
X		panic("Cannot read %d bytes from file #%d\n", len, fd);
X	}
X}
X
X#ifdef BSD
X#include	<sys/wait.h>
X#  define NZ(stat)    (stat.w_status != 0)   /* non-zero status */
X#  define SIG(stat)   (stat.w_termsig)       /* terminated by signal */
X#  define EXIT(stat)  (stat.w_retcode)       /* non-zero exit code */
X#  define CDUMP(stat) (stat.w_coredump)      /* dumped core */
X#else
X#  define NZ(stat)    (stat != 0)
X#  define SIG(stat)   ( (stat & 0xff00) ? 0 : (stat & 0x0f) )
X#  define EXIT(stat)  ( (stat & 0x00ff) ? 0 : ((stat >> 8) & 0x0f) )
X#  define CDUMP(stat) (stat & 0200)
X#endif BSD
X
X
Xmklev()
X{
X	register int fd;
X	int fork_val;
X	char type[2];
X#ifdef BSD
X	union wait status;
X#else
X	int status;
X#endif BSD
X	extern char fut_geno[];
X
X	if(getbones()) return;
X	if(dlevel < rn1(3, 26)) type[0] = 'a';	/* normal level */
X	else type[0] = 'b';			/* maze */
X	type[1] = 0;
X	fork_val = fork();
X	switch(fork_val){
X	case 0:
X		(void) signal(SIGINT, SIG_IGN);
X		(void) signal(SIGQUIT, SIG_IGN);
X		execl("./mklev", "mklev", lock, type, itoa(dlevel), fut_geno, 
X#ifdef WIZARD
X			wizard ? "w" :
X#endif WIZARD
X					"", (char *) 0);
X		exit(2);
X	case -1:
X		settty("Cannot fork!\n");
X		exit(1);
X	default:
X		(void) fflush(stdout);	/* You fell into a trap ... */
X		(void) wait(&status);
X	}
X	if(NZ(status)) {
X		if(CDUMP(status)) {
X			settty("Mklev dumped core. Exiting...\n");
X#ifdef DEBUG
Xfprintf(stderr, "signal was %d\n", SIG(status));
X#endif
X			exit(1);
X		}
X		if(SIG(status)) {
X			settty("Mklev killed by a signal. Exiting...\n");
X			exit(1);
X		}
X		if(EXIT(status)) {
X			if(EXIT(status) == 2) {
X				settty("Cannot execl mklev.\n");
X				exit(1);
X			}
X			pline("Mklev failed. Let's try again.");
X			mklev();
X			return;
X		}
X	}
X	if((fd = open(lock, 0)) < 0) {
X		pline("Can't open %s!", lock);
X		mklev();
X		return;
X	}
X	(void) getlev(fd);
X	(void) close(fd);
X}
!Funky!Stuff!
exit
-- 
Gordon A. Moffett		...!{ihnp4,hplabs,sun}!amdahl!gam

"Her name was McGill, and she called herself Lil, but everyone knew
 her as Nancy...."

gam@amdahl.UUCP (gam) (01/06/85)

: This is a shar archive.  Extract with sh, not csh.
echo x - hack.main.c
sed -e 's/^X//' > hack.main.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
X#include "hack.h"
X
Xextern char *getlogin();
Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ];
Xextern char *getenv();
X
Xint (*afternmv)();
X
Xint done1();
Xvoid hangup();
X
Xchar safelock[] = "safelock";
Xxchar locknum;				/* max num of players */
Xchar *catmore = "/usr/bin/pg -n -s -p '--More (page %d)--'";
Xchar SAVEF[PL_NSIZ + 5] = "save/";
Xchar perm[] = "perm";
Xchar *hname;		/* name of the game (argv[0] of call) */
Xchar obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
X
Xextern char *nomovemsg;
Xextern long wailmsg;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int fd;
X#ifdef NEWS
X	int nonews = 0;
X#endif NEWS
X	char *dir;
X
X	hname = argv[0];
X
X	/*
X	 * See if we must change directory to the playground.
X	 * (Perhaps hack runs suid and playground is inaccessible
X	 *  for the player.)
X	 * The environment variable HACKDIR is overridden by a
X	 *  -d command line option.
X	 */
X	dir = getenv("HACKDIR");
X	if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
X		argc--;
X		argv++;
X		dir = argv[0]+2;
X		if(*dir == '=' || *dir == ':') dir++;
X		if(!*dir && argc > 1) {
X			argc--;
X			argv++;
X			dir = argv[0];
X		}
X		if(!*dir)
X			error("Flag -d must be followed by a directory name.");
X	}
X
X	/*
X	 * Now we know the directory containing 'record' and
X	 * may do a prscore().
X	 */
X	if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
X		if(dir) chdirx(dir);
X		prscore(argc, argv);
X		exit(0);
X	}
X
X	/*
X	 * It seems he really wants to play. Find the creation date of
X	 * this game so as to avoid restoring outdated savefiles.
X	 */
X	gethdate(hname);
X
X	/*
X	 * We cannot do chdir earlier, otherwise gethdate will fail.
X	 */
X	if(dir) chdirx(dir);
X
X	/*
X	 * Who am i? Perhaps we should use $USER instead?
X	 */
X	(void) strncpy(plname, getlogin(), sizeof(plname)-1);
X
X	/*
X	 * Process options.
X	 */
X	while(argc > 1 && argv[1][0] == '-'){
X		argv++;
X		argc--;
X		switch(argv[0][1]){
X#ifdef WIZARD
X		case 'w':
X			if(!strcmp(getlogin(), WIZARD))
X				wizard = TRUE;
X			else printf("Sorry.\n");
X			break;
X#endif WIZARD
X#ifdef NEWS
X		case 'n':
X			nonews++;
X			break;
X#endif NEWS
X		case 'u':
X			if(argv[0][2])
X			  (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X			else if(argc > 1) {
X			  argc--;
X			  argv++;
X			  (void) strncpy(plname, argv[0], sizeof(plname)-1);
X			} else
X				printf("Player name expected after -u\n");
X			break;
X		default:
X			printf("Unknown option: %s\n", *argv);
X		}
X	}
X
X	if(argc > 1)
X		locknum = atoi(argv[1]);
X	if(argc > 2)
X		catmore = argv[2];
X#ifdef WIZARD
X	if(wizard) (void) strcpy(plname, "wizard"); else
X#endif WIZARD
X	if(!*plname || !strncmp(plname, "player", 4)) askname();
X	plnamesuffix();		/* strip suffix from name */
X
X	setbuf(stdout,obuf);
X 	(void) setrand(0L);
X	startup();
X	cls();
X	(void) signal(SIGHUP, hangup);
X#ifdef WIZARD
X	if(!wizard) {
X#endif WIZARD
X		(void) signal(SIGQUIT,SIG_IGN);
X		(void) signal(SIGINT,SIG_IGN);
X		if(locknum)
X			lockcheck();
X		else
X			(void) strcpy(lock,plname);
X#ifdef WIZARD
X	} else {
X		register char *sfoo;
X		(void) strcpy(lock,plname);
X		if(sfoo = getenv("MAGIC"))
X			while(*sfoo) {
X				switch(*sfoo++) {
X				case 'n': (void) setrand((long)*sfoo++);
X					break;
X				}
X			}
X		if(sfoo = getenv("GENOCIDED")){
X			if(*sfoo == '!'){
X				extern struct permonst mons[CMNUM+2];
X				extern char genocided[], fut_geno[];
X				register struct permonst *pm = mons;
X				register char *gp = genocided;
X
X				while(pm < mons+CMNUM+2){
X					if(!index(sfoo, pm->mlet))
X						*gp++ = pm->mlet;
X					pm++;
X				}
X				*gp = 0;
X			} else
X				(void) strcpy(genocided, sfoo);
X			(void) strcpy(fut_geno, genocided);
X		}
X	}
X#endif WIZARD
X	u.uhp = 1;	/* prevent RIP on early quits */
X	u.ux = FAR;	/* prevent nscr() */
X	(void) strcat(SAVEF,plname);
X	if((fd = open(SAVEF,0)) >= 0 &&
X	   (uptodate(fd) || unlink(SAVEF) == 666)) {
X		(void) signal(SIGINT, (void (*)()) done1);
X		puts("Restoring old save file...");
X		(void) fflush(stdout);
X		dorecover(fd);
X		flags.move = 0;
X	} else {
X#ifdef NEWS
X		if(!nonews)
X			if((fd = open(NEWS,0)) >= 0)
X				outnews(fd);
X#endif NEWS
X		flags.ident = 1;
X		init_objects();
X		u_init();
X		(void) signal(SIGINT, (void (*)()) done1);
X		glo(1);
X		mklev();
X		u.ux = xupstair;
X		u.uy = yupstair;
X		(void) inshop();
X		setsee();
X		flags.botlx = 1;
X		makedog();
X		seemons();
X		docrt();
X		pickup();
X		read_engr_at(u.ux,u.uy);	/* superfluous ? */
X		flags.move = 1;
X		flags.cbreak = ON;
X		flags.echo = OFF;
X	}
X	setftty();
X#ifdef TRACK
X	initrack();
X#endif TRACK
X	for(;;) {
X		if(flags.move) {
X#ifdef TRACK
X			settrack();
X#endif TRACK
X			if(moves%2 == 0 ||
X			  (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
X				extern struct monst *makemon();
X				movemon();
X				if(!rn2(70))
X				    (void) makemon((struct permonst *)0, 0, 0);
X			}
X			if(Glib) glibr();
X			timeout();
X			++moves;
X			if(u.uhp < 1) {
X				pline("You die...");
X				done("died");
X			}
X			if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
X			    wailmsg = moves;
X			    if(u.uhp == 1)
X			    pline("You hear the wailing of the Banshee...");
X			    else
X			    pline("You hear the howling of the CwnAnnwn...");
X			}
X			if(u.uhp < u.uhpmax) {
X				if(u.ulevel > 9) {
X					if(Regeneration || !(moves%3)) {
X					    flags.botl = 1;
X					    u.uhp += rnd((int) u.ulevel-9);
X					    if(u.uhp > u.uhpmax)
X						u.uhp = u.uhpmax;
X					}
X				} else if(Regeneration ||
X					(!(moves%(22-u.ulevel*2)))) {
X					flags.botl = 1;
X					u.uhp++;
X				}
X			}
X			if(Teleportation && !rn2(85)) tele();
X			if(Searching && multi >= 0) (void) dosearch();
X			gethungry();
X			invault();
X		}
X		if(multi < 0) {
X			if(!++multi){
X				pline(nomovemsg ? nomovemsg :
X					"You can move again.");
X				nomovemsg = 0;
X				if(afternmv) (*afternmv)();
X				afternmv = 0;
X			}
X		}
X		flags.move = 1;
X		find_ac();
X#ifndef QUEST
X		if(!flags.mv || Blind)
X#endif QUEST
X		{
X			seeobjs();
X			seemons();
X			nscr();
X		}
X		if(flags.botl || flags.botlx) bot();
X		if(multi > 0) {
X#ifdef QUEST
X			if(flags.run >= 4) finddir();
X#endif QUEST
X			lookaround();
X			if(!multi) {	/* lookaround may clear multi */
X				flags.move = 0;
X				continue;
X			}
X			if(flags.mv) {
X				if(multi<COLNO && !--multi)
X					flags.mv = flags.run = 0;
X				domove();
X			} else {
X				--multi;
X				rhack(save_cm);
X			}
X		} else if(multi == 0)
X			rhack((char *) 0);
X	}
X}
X
Xlockcheck()
X{
X	extern int errno;
X	register int i, fd;
X
X	/* we ignore QUIT and INT at this point */
X	if (link(perm,safelock) == -1)
X		error("Cannot link safelock. (Try again or rm safelock.)");
X
X	for(i = 0; i < locknum; i++) {
X		lock[0]= 'a' + i;
X		if((fd = open(lock,0)) == -1) {
X			if(errno == ENOENT) goto gotlock;    /* no such file */
X			(void) unlink(safelock);
X			error("Cannot open %s", lock);
X		}
X		(void) close(fd);
X	}
X	(void) unlink(safelock);
X	error("Too many hacks running now.");
Xgotlock:
X	fd = creat(lock,FMASK);
X	if(fd == -1) {
X		error("cannot creat lock file.");
X	} else {
X		int pid;
X
X		pid = getpid();
X		if(write(fd, (char *) &pid, 2) != 2){
X			error("cannot write lock");
X		}
X		if(close(fd) == -1){
X			error("cannot close lock");
X		}
X	}
X	if(unlink(safelock) == -1){
X		error("Cannot unlink safelock");
X	}
X}
X
X/*VARARGS1*/
Xerror(s,a1,a2,a3,a4) char *s,*a1,*a2,*a3,*a4; {
X	printf("Error: ");
X	printf(s,a1,a2,a3,a4);
X	(void) putchar('\n');
X	exit(1);
X}
X
Xglo(foo)
Xregister foo;
X{
X	/* construct the string  xlock.n  */
X	register char *tf;
X
X	tf = lock;
X	while(*tf && *tf!='.') tf++;
X	(void) sprintf(tf, ".%d", foo);
X}
X
X/*
X * plname is filled either by an option (-u Player  or  -uPlayer) or
X * explicitly (-w implies wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X */
Xaskname(){
Xregister int c,ct;
X	printf("\nWho are you? ");
X	ct = 0;
X	while((c = getchar()) != '\n'){
X		if(c == EOF) error("End of input\n");
X		if(c != '-')
X		if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
X		if(ct < sizeof(plname)-1) plname[ct++] = c;
X	}
X	plname[ct] = 0;
X	if(ct == 0) askname();
X#ifdef QUEST
X	else printf("Hello %s, welcome to quest!\n", plname);
X#else
X	else printf("Hello %s, welcome to hack!\n", plname);
X#endif QUEST
X}
X
Ximpossible(){
X	pline("Program in disorder - perhaps you'd better Quit");
X}
X
X#ifdef NEWS
Xint stopnews;
X
Xvoid
Xstopnws(){
X	(void) signal(SIGINT, SIG_IGN);
X	stopnews++;
X}
X
Xoutnews(fd) int fd; {
Xvoid (*prevsig)();
Xchar ch;
X	prevsig = signal(SIGINT, stopnws);
X	while(!stopnews && read(fd,&ch,1) == 1)
X		(void) putchar(ch);
X	(void) putchar('\n');
X	(void) fflush(stdout);
X	(void) close(fd);
X	(void) signal(SIGINT, prevsig);
X	/* See whether we will ask TSKCFW: he might have told us already */
X	if(!stopnews && pl_character[0])
X		getret();
X}
X#endif NEWS
X
Xchdirx(dir) char *dir; {
X	if(chdir(dir) < 0) {
X		perror(dir);
X		error("Cannot chdir to %s.", dir);
X	}
X}
!Funky!Stuff!
echo x - hack.pri.c
sed -e 's/^X//' > hack.pri.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "hack.h"
X#include <stdio.h>
Xxchar scrlx, scrhx, scrly, scrhy;	/* corners of new area on screen */
X
Xextern char *hu_stat[];	/* in eat.c */
X
Xswallowed()
X{
X	char *ulook = "|@|";
X	ulook[1] = u.usym;
X
X	cls();
X	curs(u.ux-1, u.uy+1);
X	fputs("/-\\", stdout);
X	curx = u.ux+2;
X	curs(u.ux-1, u.uy+2);
X	fputs(ulook, stdout);
X	curx = u.ux+2;
X	curs(u.ux-1, u.uy+3);
X	fputs("\\-/", stdout);
X	curx = u.ux+2;
X	u.udispl = 1;
X	u.udisx = u.ux;
X	u.udisy = u.uy;
X}
X
X
X/*VARARGS1*/
Xboolean panicking;
X
Xpanic(str,a1,a2,a3,a4,a5,a6)
Xchar *str;
X{
X	if(panicking++) exit(1);	/* avoid loops */
X	home();
X	puts(" Suddenly, the dungeon collapses.");
X	fputs(" ERROR:  ",stdout);
X	printf(str,a1,a2,a3,a4,a5,a6);
X	if(fork())
X		done("panic");
X	else
X		abort();	/* generate core dump */
X}
X
Xatl(x,y,ch)
Xregister x,y;
X{
X	register struct rm *crm = &levl[x][y];
X
X	if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1)
X		panic("at(%d,%d,%c_%o_)",x,y,ch,ch);
X	if(crm->seen && crm->scrsym == ch) return;
X	crm->scrsym = ch;
X	crm->new = 1;
X	on_scr(x,y);
X}
X
Xon_scr(x,y)
Xregister x,y;
X{
X	if(x<scrlx) scrlx = x;
X	if(x>scrhx) scrhx = x;
X	if(y<scrly) scrly = y;
X	if(y>scrhy) scrhy = y;
X}
X
X/* call: (x,y) - display
X	(-1,0) - close (leave last symbol)
X	(-1,-1)- close (undo last symbol)
X	(-1,let)-open: initialize symbol
X	(-2,let)-change let
X*/
X
Xtmp_at(x,y) schar x,y; {
Xstatic schar prevx, prevy;
Xstatic char let;
X	if((int)x == -2){	/* change let call */
X		let = y;
X		return;
X	}
X	if((int)x == -1 && (int)y >= 0){	/* open or close call */
X		let = y;
X		prevx = -1;
X		return;
X	}
X	if(prevx >= 0 && cansee(prevx,prevy)) {
X		delay();
X		prl(prevx, prevy);	/* in case there was a monster */
X		at(prevx, prevy, levl[prevx][prevy].scrsym);
X	}
X	if(x >= 0){	/* normal call */
X		if(cansee(x,y)) at(x,y,let);
X		prevx = x;
X		prevy = y;
X	} else {	/* close call */
X		let = 0;
X		prevx = -1;
X	}
X}
X
X/* like the previous, but the symbols are first erased on completion */
XTmp_at(x,y) schar x,y; {
Xstatic char let;
Xstatic xchar cnt;
Xstatic coord tc[COLNO];		/* but watch reflecting beams! */
Xregister xx,yy;
X	if((int)x == -1) {
X		if(y > 0) {	/* open call */
X			let = y;
X			cnt = 0;
X			return;
X		}
X		/* close call (do not distinguish y==0 and y==-1) */
X		while(cnt--) {
X			xx = tc[cnt].x;
X			yy = tc[cnt].y;
X			prl(xx, yy);
X			at(xx, yy, levl[xx][yy].scrsym);
X		}
X		cnt = let = 0;	/* superfluous */
X		return;
X	}
X	if((int)x == -2) {	/* change let call */
X		let = y;
X		return;
X	}
X	/* normal call */
X	if(cansee(x,y)) {
X		if(cnt) delay();
X		at(x,y,let);
X		tc[cnt].x = x;
X		tc[cnt].y = y;
X		if(++cnt >= COLNO) panic("Tmp_at overflow?");
X		levl[x][y].new = 0;	/* prevent pline-nscr erasing --- */
X	}
X}
X
Xat(x,y,ch)
Xregister xchar x,y;
Xchar ch;
X{
X#ifndef lint
X	/* if xchar is unsigned, lint will complain about  if(x < 0)  */
X	if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1)
X		panic("At gets 0%o at %d %d(%d %d)",ch,x,y,u.ux,u.uy);
X#endif lint
X	if(!ch) {
X		home();
X		printf("At gets null at %2d %2d.",x,y);
X		curx = ROWNO+1;
X		return;
X	}
X	y += 2;
X	curs(x,y);
X	(void) putchar(ch);
X	curx++;
X}
X
Xprme(){
X	if(!Invis) at(u.ux,u.uy,u.usym);
X}
X
Xdocrt()
X{
X	register x,y;
X	register struct rm *room;
X	register struct monst *mtmp;
X
X	if(u.uswallow) {
X		swallowed();
X		return;
X	}
X	cls();
X	if(!Invis){
X		levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
X		levl[u.udisx][u.udisy].seen = 1;
X		u.udispl = 1;
X	} else	u.udispl = 0;
X
X	/* %% - is this really necessary? */
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X		if(mtmp->mdispl && !(room = &levl[mtmp->mx][mtmp->my])->new &&
X		   !room->seen)
X			mtmp->mdispl = 0;
X
X	for(y = 0; y < ROWNO; y++)
X		for(x = 0; x < COLNO; x++)
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym);
X			} else if(room->seen) at(x,y,room->scrsym);
X	scrlx = COLNO;
X	scrly = ROWNO;
X	scrhx = scrhy = 0;
X	flags.botlx = 1;
X	bot();
X}
X
Xdocorner(xmin,ymax) register xmin,ymax; {
X	register x,y;
X	register struct rm *room;
X	if(u.uswallow) {	/* Can be done more efficiently */
X		swallowed();
X		return;
X	}
X	for(y = 0; y < ymax; y++) {
X		curs(xmin,y+2);
X		cl_end();
X		for(x = xmin; x < COLNO; x++) {
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym);
X			} else if(room->seen) at(x,y,room->scrsym);
X		}
X	}
X}
X
Xpru()
X{
X	if(u.udispl && (Invis || u.udisx != u.ux || u.udisy != u.uy))
X		/* if(! levl[u.udisx][u.udisy].new) */
X			if(!vism_at(u.udisx, u.udisy))
X				newsym(u.udisx, u.udisy);
X	if(Invis) {
X		u.udispl = 0;
X		prl(u.ux,u.uy);
X	} else
X	if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
X		atl(u.ux, u.uy, u.usym);
X		u.udispl = 1;
X		u.udisx = u.ux;
X		u.udisy = u.uy;
X	}
X	levl[u.ux][u.uy].seen = 1;
X}
X
X#ifndef NOWORM
X#include	"def.wseg.h"
Xextern struct wseg *m_atseg;
X#endif NOWORM
X
X/* print a position that is visible for @ */
Xprl(x,y)
X{
X	register struct rm *room;
X	register struct monst *mtmp;
X	register struct obj *otmp;
X
X	if(x == u.ux && y == u.uy && !Invis) {
X		pru();
X		return;
X	}
X	room = &levl[x][y];
X	if((!room->typ) || (room->typ<DOOR && levl[u.ux][u.uy].typ == CORR))
X		return;
X	if((mtmp = m_at(x,y)) && !mtmp->mhide &&
X		(!mtmp->minvis || See_invisible)) {
X#ifndef NOWORM
X		if(m_atseg)
X			pwseg(m_atseg);
X		else
X#endif NOWORM
X		pmon(mtmp);
X	}
X	else if(otmp = o_at(x,y))
X		atl(x,y,otmp->olet);
X	else if(mtmp && (!mtmp->minvis || See_invisible)) {
X		/* must be a hiding monster, but not hiding right now */
X		/* assume for the moment that long worms do not hide */
X		pmon(mtmp);
X	}
X	else if(g_at(x,y,fgold)) atl(x,y,'$');
X	else if(!room->seen || room->scrsym == ' ') {
X		room->new = room->seen = 1;
X		newsym(x,y);
X		on_scr(x,y);
X	}
X	room->seen = 1;
X}
X
Xchar
Xnews0(x,y)
Xregister xchar x,y;
X{
X	register struct obj *otmp;
X	register struct gen *gtmp;
X	struct rm *room;
X	register char tmp;
X
X	room = &levl[x][y];
X	if(!room->seen) tmp = ' ';
X	else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
X	else if(!Blind && g_at(x,y,fgold)) tmp = '$';
X	else if(x == xupstair && y == yupstair) tmp = '<';
X	else if(x == xdnstair && y == ydnstair) tmp = '>';
X	else if((gtmp = g_at(x,y,ftrap)) && (gtmp->gflag & SEEN)) tmp = '^';
X	else switch(room->typ) {
X	case SCORR:
X	case SDOOR:
X		tmp = room->scrsym;	/* %% wrong after killing mimic ! */
X		break;
X	case HWALL:
X		tmp = '-';
X		break;
X	case VWALL:
X		tmp = '|';
X		break;
X	case LDOOR:
X	case DOOR:
X		tmp = '+';
X		break;
X	case CORR:
X		tmp = CORR_SYM;
X		break;
X	case ROOM:
X		if(room->lit || cansee(x,y) || Blind) tmp = '.';
X		else tmp = ' ';
X		break;
X	default: tmp = ERRCHAR;
X	}
X	return(tmp);
X}
X
Xnewsym(x,y)
Xregister x,y;
X{
X	atl(x,y,news0(x,y));
X}
X
X/* used with wand of digging: fill scrsym and force display */
Xmnewsym(x,y) register x,y; {
Xregister struct monst *mtmp = m_at(x,y);
X	if(!mtmp || (mtmp->minvis && !See_invisible) ||
X		    (mtmp->mhide && o_at(x,y))){
X		levl[x][y].scrsym = news0(x,y);
X		levl[x][y].seen = 0;
X	}
X}
X
Xnosee(x,y)
Xregister x,y;
X{
X	register struct rm *room;
X
X	room = &levl[x][y];
X	if(room->scrsym == '.' && !room->lit && !Blind) {
X		room->scrsym = ' ';
X		room->new = 1;
X		on_scr(x,y);
X	}
X}
X
X#ifndef QUEST
Xprl1(x,y)
Xregister x,y;
X{
X	if(u.dx) {
X		if(u.dy) {
X			prl(x-(2*u.dx),y);
X			prl(x-u.dx,y);
X			prl(x,y);
X			prl(x,y-u.dy);
X			prl(x,y-(2*u.dy));
X		} else {
X			prl(x,y-1);
X			prl(x,y);
X			prl(x,y+1);
X		}
X	} else {
X		prl(x-1,y);
X		prl(x,y);
X		prl(x+1,y);
X	}
X}
X
Xnose1(x,y)
Xregister x,y;
X{
X	if(u.dx) {
X		if(u.dy) {
X			nosee(x,u.uy);
X			nosee(x,u.uy-u.dy);
X			nosee(x,y);
X			nosee(u.ux-u.dx,y);
X			nosee(u.ux,y);
X		} else {
X			nosee(x,y-1);
X			nosee(x,y);
X			nosee(x,y+1);
X		}
X	} else {
X		nosee(x-1,y);
X		nosee(x,y);
X		nosee(x+1,y);
X	}
X}
X#endif QUEST
X
Xvism_at(x,y) register x,y; {
Xregister struct monst *mtmp;
Xregister int csi = See_invisible;
X	return((x == u.ux && y == u.uy && (!Invis || csi)) ? 1 :
X		((mtmp = m_at(x,y)) && (!mtmp->minvis || csi) &&
X			(!mtmp->mhide || !o_at(mtmp->mx,mtmp->my)))
X		? cansee(x,y) : 0);
X}
X
X#ifdef NEWSCR
Xpobj(obj) register struct obj *obj; {
Xregister int show = (!obj->oinvis || See_invisible) &&
X		cansee(obj->ox,obj->oy);
X	if(obj->odispl){
X		if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
X		if(!vism_at(obj->odx,obj->ody)){
X			newsym(obj->odx, obj->ody);
X			obj->odispl = 0;
X		}
X	}
X	if(show && !vism_at(obj->ox,obj->oy)){
X		atl(obj->ox,obj->oy,obj->olet);
X		obj->odispl = 1;
X		obj->odx = obj->ox;
X		obj->ody = obj->oy;
X	}
X}
X#endif NEWSCR
X
Xunpobj(obj) register struct obj *obj; {
X/* 	if(obj->odispl){
X		if(!vism_at(obj->odx, obj->ody))
X			newsym(obj->odx, obj->ody);
X		obj->odispl = 0;
X	}
X*/
X	if(!vism_at(obj->ox,obj->oy))
X		newsym(obj->ox,obj->oy);
X}
X
Xseeobjs(){
Xregister struct obj *obj, *obj2;
X	for(obj = fobj; obj; obj = obj2) {
X		obj2 = obj->nobj;
X		if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
X			&& obj->age + 250 < moves)
X				delobj(obj);
X	}
X	for(obj = invent; obj; obj = obj2) {
X		obj2 = obj->nobj;
X		if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
X			&& obj->age + 250 < moves)
X				useup(obj);
X	}
X}
X
Xseemons(){
Xregister struct monst *mtmp;
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
X		pmon(mtmp);
X#ifndef NOWORM
X		if(mtmp->wormno) wormsee(mtmp->wormno);
X#endif NOWORM
X	}
X}
X
Xpmon(mon) register struct monst *mon; {
Xregister int show =
X	((!mon->minvis || See_invisible) &&
X		(!mon->mhide || !o_at(mon->mx,mon->my)) &&
X		cansee(mon->mx,mon->my))
X	 || (Blind && Telepat);
X	if(mon->mdispl){
X		if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
X			unpmon(mon);
X	}
X	if(show && !mon->mdispl){
X		atl(mon->mx,mon->my,
X		  mon->mimic ? mon->mimic : mon->data->mlet);
X		mon->mdispl = 1;
X		mon->mdx = mon->mx;
X		mon->mdy = mon->my;
X	}
X}
X
Xunpmon(mon) register struct monst *mon; {
X	if(mon->mdispl){
X		newsym(mon->mdx, mon->mdy);
X		mon->mdispl = 0;
X	}
X}
X
Xnscr()
X{
X	register x,y;
X	register struct rm *room;
X
X	if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
X	pru();
X	for(y = scrly; y <= scrhy; y++)
X		for(x = scrlx; x <= scrhx; x++)
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym);
X			}
X	scrhx = scrhy = 0;
X	scrlx = COLNO;
X	scrly = ROWNO;
X}
X
Xchar oldbot[100], newbot[100];		/* 100 >= COLNO */
Xbot()
X{
Xregister char *ob = oldbot, *nb = newbot;
Xregister int i;
X	if(flags.botlx) *ob = 0;
X	flags.botl = flags.botlx = 0;
X	(void) sprintf(newbot, "Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Str ",
X		dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
X	if(u.ustr>18) {
X		if(u.ustr>117) (void) strcat(newbot,"18/**");
X		else (void) sprintf(newbot + strlen(newbot), "18/%02d",u.ustr-18);
X	} else (void) sprintf(newbot + strlen(newbot), "%-2d   ",u.ustr);
X	(void) sprintf(newbot + strlen(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
X	(void) strcat(newbot, hu_stat[u.uhs]);
X	for(i = 1; i<COLNO; i++) {
X		if(*ob != *nb){
X			curs(i,ROWNO+2);
X			(void) putchar(*nb ? *nb : ' ');
X			curx++;
X		}
X		if(*ob) ob++;
X		if(*nb) nb++;
X	}
X	(void) strcpy(oldbot, newbot);
X}
X
X#ifdef WAN_PROBING
Xmstatusline(mtmp) register struct monst *mtmp; {
X	pline("Status of %s: ", monnam(mtmp));
X	pline("Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Dam %d",
X	    mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->orig_hp,
X	    mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
X}
X#endif WAN_PROBING
X
Xcls(){
X	if(flags.topl == 1)
X		more();
X	flags.topl = 0;
X
X	clearscreen();
X
X	flags.botlx = 1;
X}
!Funky!Stuff!
echo x - hack.sh
sed -e 's/^X//' > hack.sh << '!Funky!Stuff!'
X
XHACK=/usr/games/HACK
XHACKDIR=/usr/games/lib/hack/tmp
XMAXNROFPLAYERS=6
XMORE="/usr/bin/pg -f -n -s -p '--More (page %d)--'"
X
Xcd $HACKDIR
Xcase $1 in
X	-s*)
X		exec $HACK $@
X		;;
X	*)
X#		/bin/cat news
X		exec $HACK $HACKDIR $MAXNROFPLAYERS $MORE
X		;;
Xesac
!Funky!Stuff!
echo x - hack.stat.c
sed -e 's/^X//' > hack.stat.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "config.h"
X
Xextern char *index();
Xstruct stat buf,hbuf;
X
Xgethdate(name) char *name; {
Xregister char *np;
X	if(stat(name, &hbuf))
X		error("Cannot get status of %s.",
X			(np = index(name, '/')) ? np+1 : name);
X}
X
Xuptodate(fd) {
X	if(fstat(fd, &buf)) {
X		pline("Cannot get status?");
X		return(0);
X	}
X	if(buf.st_ctime < hbuf.st_ctime) {
X		pline("Saved level is out of date.");
X		return(0);
X	}
X	return(1);
X}
!Funky!Stuff!
exit
-- 
Gordon A. Moffett		...!{ihnp4,hplabs,sun}!amdahl!gam

"Her name was McGill, and she called herself Lil, but everyone knew
 her as Nancy...."

gam@amdahl.UUCP (gam) (01/06/85)

: This is a shar archive.  Extract with sh, not csh.
echo x - hack.termcap.c
sed -e 's/^X//' > hack.termcap.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#define SINGLE
X#include <curses.h>
X#include <term.h>
X#include "config.h"	/* for ROWNO and COLNO */
X
Xextern char *tparm();
Xextern char *getenv();
X
Xshort ospeed;		/* terminal baudrate; used by tputs */
Xchar *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE;
Xchar PC = '\0';
X
Xstartup()
X{
X	register char *tmp;
X	char *pc;
X	int tliberr;
X
X
X	if(!(tmp = getenv("TERM")))
X		error("Can't get TERM.");
X	def_shell_mode();
X	setupterm(tmp, 0, &tliberr);
X	gettty();	/* sets ospeed */
X
X	if(tliberr < 1)
X		error("Unknown terminal type: %s.", tmp);
X	if(pc = pad_char)
X		PC = *pc;
X	if(!(BC = cursor_left)){	
X		BC = "\b";
X	}
X	HO = cursor_home;
X	if(columns < COLNO || lines < ROWNO+2)
X		error("Screen must be at least %d by %d!",
X			ROWNO+2, COLNO);
X	if(!(CL = clear_screen) || !(CE = clr_eol) ||
X		!(ND = cursor_right) ||
X		!(UP = cursor_up) || over_strike)
X		error("Hack needs clear_screen, clr_eol, cursor_up, cursor_right,\nand no over_strike.");
X	if(!(CM = cursor_address))
X		error("Use of hack on terminals without cursor_motion is unsupported...\n");
X	XD = cursor_down;
X	SO = enter_standout_mode;
X	SE = exit_standout_mode;
X	if(!SO || !SE) SO = SE = 0;
X}
X
X/* Cursor movements */
Xextern xchar curx, cury;
X
Xcurs(x,y)
Xregister int x,y;	/* not xchar: perhaps xchar is unsigned and
X			   curx-x would be unsigned as well */
X{
X
X	if (y == cury && x == curx) return;
X	if(abs(cury-y)<= 3 && abs(curx-x)<= 3) {
X		nocmov(x,y);
X	} else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
X		(void) putchar('\r');
X		curx = 1;
X		nocmov(x,y);
X	} else if(!CM) {
X		nocmov(x,y);
X	} else
X		cmov(x,y);
X}
X
Xcmov(x,y)
Xregister x,y;
X{
X	if(!CM) error("Tries to cmov from %d %d to %d %d\n",curx,cury,x,y);
X	xputs(tparm(CM,y-1,x-1));
X	cury = y;
X	curx = x;
X}
X
X
Xnocmov(x,y)
X{
X	if (curx < x) {		/* Go to the right. */
X		while (curx < x) {
X			xputs(ND);
X			curx++;
X		}
X	} else if (curx > x) {
X		while (curx > x) {	/* Go to the left. */
X			xputs(BC);
X			curx--;
X		}
X	}
X	if (cury > y) {
X		if(UP) {
X			while (cury > y) {	/* Go up. */
X				xputs(UP);
X				cury--;
X			}
X		} else cmov(x,y);
X	} else if (cury < y) {
X		if(XD) {
X			while(cury<y) {
X				xputs(XD);
X				cury++;
X			}
X		} else cmov(x,y);
X	}
X}
X
Xxputs(s) char *s; {
X	putp(s);
X}
X
Xcl_end() {
X	xputs(CE);
X}
X
Xclearscreen() {
X	xputs(CL);
X	curx = cury = 1;
X}
X
Xhome()
X{
X	if(HO) xputs(HO);
X	else xputs(tparm(CM,0,0));
X	curx = cury = 1;
X}
X
Xstandoutbeg()
X{
X	if(SO) xputs(SO);
X}
X
Xstandoutend()
X{
X	if(SE) xputs(SE);
X}
X
Xbacksp()
X{
X	xputs(BC);
X	curx--;
X}
X
Xbeep()
X{
X	xputs(bell);
X}
X
Xdelay() {
X	/* delay 40 ms - could also use a 'nap'-system call */
X	delay_output(40);
X}
!Funky!Stuff!
echo x - hack.tty.c
sed -e 's/^X//' > hack.tty.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#define SINGLE
X#include	<curses.h>
X#include	<term.h>
X#undef move
X#include	"hack.h"
X
Xextern short ospeed;
X
X
Xgettty(){
X	def_prog_mode();
X	ospeed = cur_term->Nttyb.c_cflag & CBAUD;
X/*
X	if(ospeed <= B300) flags.oneline = 1;
X*/
X}
X
X/* reset terminal to original state */
Xsettty(s) char *s; {
X	clearscreen();
X	if(s) printf(s);
X	(void) fflush(stdout);
X	reset_shell_mode();
X}
X
Xsetctty()
X{
X	reset_prog_mode();
X}
X
Xsetftty(){
Xregister int ef = (flags.echo == ON) ? ECHO : 0;
Xregister int cf = (flags.cbreak == ON) ? 0 : ICANON;
Xregister int change = 0;
X	if((cur_term->Nttyb.c_lflag & ECHO) != ef){
X		cur_term->Nttyb.c_lflag &= ~ECHO;
X		cur_term->Nttyb.c_lflag |= ef;
X		change++;
X	}
X	if((cur_term->Nttyb.c_lflag & ICANON) != cf){
X		cur_term->Nttyb.c_lflag &= ~ICANON;
X		cur_term->Nttyb.c_lflag |= cf;
X		if (cur_term->Nttyb.c_lflag & ICANON) {
X			cur_term->Nttyb.c_cc[VEOF] = cur_term->Ottyb.c_cc[VEOF];
X			cur_term->Nttyb.c_cc[VEOL] = cur_term->Ottyb.c_cc[VEOL];
X		} else {
X			cur_term->Nttyb.c_cc[VTIME] = 1;
X			cur_term->Nttyb.c_cc[VMIN] = 1;
X		}
X		change++;
X	}
X	if(change){
X		setctty();
X	}
X}
X
Xecho(n)
Xregister n;
X{
X
X	if(n == ON)
X		doecho();
X	else
X		donoecho();
X}
X
Xdoecho()
X{
X	cur_term->Nttyb.c_lflag |= ECHO;
X	setctty();
X}
X
Xdonoecho()
X{
X	cur_term->Nttyb.c_lflag &= ~ECHO;
X	setctty();
X}
X
Xgetlin(bufp)
Xregister char *bufp;
X{
X	register char *obufp = bufp;
X	register int c;
X
X	flags.topl = 2;		/* nonempty, no --More-- required */
X	for(;;) {
X		(void) fflush(stdout);
X		if((c = getchar()) == EOF) {
X			*bufp = 0;
X			return;
X		}
X		if(c == '\b') {
X			if(bufp != obufp) {
X				bufp--;
X				putstr("\b \b"); /* putsym converts \b */
X			} else	beep();
X		} else if(c == '\n') {
X			*bufp = 0;
X			return;
X		} else {
X			*bufp = c;
X			bufp[1] = 0;
X			putstr(bufp);
X			if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
X				bufp++;
X		}
X	}
X}
X
Xgetret() {
X	xgetret(TRUE);
X}
X
Xcgetret() {
X	xgetret(FALSE);
X}
X
Xxgetret(spaceflag)
Xboolean spaceflag;	/* TRUE if space (return) required */
X{
X	printf("\nHit %s to continue: ",
X		flags.cbreak ? "space" : "return");
X	xwaitforspace(spaceflag);
X}
X
Xchar morc;	/* tell the outside world what char he used */
X
Xxwaitforspace(spaceflag)
Xboolean spaceflag;
X{
Xregister int c;
X
X	(void) fflush(stdout);
X	morc = 0;
X
X	while((c = getchar()) != '\n') {
X	    if(c == EOF) {
X		settty("End of input?\n");
X		exit(0);
X	    }
X	    if(flags.cbreak) {
X		if(c == ' ') break;
X		if(!spaceflag && letter(c)) {
X			morc = c;
X			break;
X		}
X	    }
X	}
X}
X
Xchar *
Xparse()
X{
X	static char inline[COLNO];
X	register foo;
X
X	flags.move = 1;
X	if(!Invis) curs(u.ux,u.uy+2); else home();
X	(void) fflush(stdout);
X	while((foo = getchar()) >= '0' && foo <= '9')
X		multi += 10*multi+foo-'0';
X	if(multi) {
X		multi--;
X		save_cm = inline;
X	}
X	inline[0] = foo;
X	inline[1] = 0;
X	if(foo == EOF) {
X		settty("End of input?\n");
X		exit(0);
X	}
X	if(foo == 'f' || foo == 'F'){
X		inline[1] = getchar();
X#ifdef QUEST
X		if(inline[1] == foo) inline[2] = getchar(); else
X#endif QUEST
X		inline[2] = 0;
X	}
X	if(foo == 'm' || foo == 'M'){
X		inline[1] = getchar();
X		inline[2] = 0;
X	}
X	clrlin();
X	return(inline);
X}
X
Xchar
Xreadchar() {
X	register int sym;
X	(void) fflush(stdout);
X	if((sym = getchar()) == EOF) {
X		settty("End of input?\n");
X		exit(0);
X	}
X	if(flags.topl == 1) flags.topl = 2;
X	return((char) sym);
X}
!Funky!Stuff!
echo x - mklev.c
sed -e 's/^X//' > mklev.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <stdio.h>
X#include "mklev.h"
X#include "def.trap.h"
X
Xextern void	exit(),
X		free(),
X		qsort();
X
Xextern char *getlogin();
Xextern struct monst *makemon();
X
Xchar *tfile,*tspe,**args;
Xchar nul[40];
X
X#include "savelev.h"
X
X#ifdef WIZARD
Xboolean wizard;
X#endif WIZARD
X
Xlong lrand48();
X
X#define somex() (int)((lrand48()%(croom->hx-croom->lx+1))+croom->lx)
X#define somey() (int)((lrand48()%(croom->hy-croom->ly+1))+croom->ly)
X
Xstruct rm levl[COLNO][ROWNO];
Xstruct monst *fmon;
Xstruct obj *fobj;
Xstruct gen *fgold, *ftrap;
X
Xchar *fut_geno;		/* monsters that should not be created anymore */
X
Xstruct mkroom rooms[MAXNROFROOMS+1], *croom, *troom;
Xcoord doors[DOORMAX];
Xint doorindex = 0;
Xint comp();
X
Xxchar dlevel;
Xschar nxcor,xx,yy,dx,dy,tx,ty; /* for corridors and other things... */
Xboolean goldseen;
Xint nroom;
X
Xxchar xdnstair,xupstair,ydnstair,yupstair;
X
X
Xmain(argc,argv)
Xchar *argv[];
X{
X	register unsigned tryct;
X
X	if(argc < 6) panic("Too few arguments!!");
X	args = argv;
X	tfile = argv[1];
X	tspe = argv[2];
X	dlevel = atoi(argv[3]);
X	if(dlevel < 1) panic("Bad level");
X	fut_geno = argv[4];
X#ifdef WIZARD
X	wizard = (argv[5][0] == 'w');
X#endif WIZARD
X	(void) setrand(0L);
X	init_objects();
X	rooms[0].hx = -1;	/* in case we are in a maze */
X
X	/* a: normal; b: maze */
X	if(*tspe == 'b') {
X		makemaz();
X		savelev();
X		exit(0);
X	}
X
X	/* construct the rooms */
X	while(nroom < (MAXNROFROOMS/3)) {
X		croom = rooms;
X		nroom = 0;
X		(void) makerooms(0);		/* not secret */
X	}
X
X	/* for each room: put things inside */
X	for(croom = rooms; croom->hx > 0; croom++) {
X
X		/* put a sleeping monster inside */
X		if(!rn2(3)) (void)
X			makemon((struct permonst *) 0, somex(), somey());
X
X		/* put traps and mimics inside */
X		goldseen = FALSE;
X		while(!rn2(8-(dlevel/6))) mktrap(0,0);
X		if(!goldseen && !rn2(3)) mkgold(0,somex(),somey());
X		if(!rn2(3)) {
X			mkobj_at(0, somex(), somey());
X			tryct = 0;
X			while(!rn2(5)) {
X				if(++tryct > 100){
X					printf("tryct overflow4\n");
X					break;
X				}
X				mkobj_at(0, somex(), somey());
X			}
X		}
X	}
X	tryct = 0;
X	do {
X		if(++tryct > 1000) panic("Cannot make dnstairs\n");
X		croom = &rooms[rn2(nroom)];
X		xdnstair = somex();
X		ydnstair = somey();
X	} while((*tspe =='n' && (!(xdnstair%2) || !(ydnstair%2))) ||
X		g_at(xdnstair,ydnstair,ftrap));
X	levl[xdnstair][ydnstair].scrsym ='>';
X	levl[xdnstair][ydnstair].typ = STAIRS;
X	troom = croom;
X	do {
X		if(++tryct > 2000) panic("Cannot make upstairs\n");
X		croom = &rooms[rn2(nroom)];
X		xupstair = somex();
X		yupstair = somey();
X	} while(croom == troom || m_at(xupstair,yupstair) ||
X		g_at(xupstair,yupstair,ftrap));
X	levl[xupstair][yupstair].scrsym ='<';
X	levl[xupstair][yupstair].typ = STAIRS;
X
X	qsort((char *) rooms, (unsigned) nroom,
X		sizeof(struct mkroom), comp);
X
X	croom = rooms;
X	troom = croom+1;
X	nxcor = 0;
X	mkpos();
X	do makecor();
X	while (croom->hx > 0 && troom->hx > 0);
X
X	/* make a secret treasure vault, not connected to the rest */
X	if(nroom < (2*MAXNROFROOMS/3)) if(!rn2(3)) {
X		register int x,y;
X		troom = croom = &rooms[nroom];
X		if(makerooms(1)) {		/* make secret room */
X			troom->rtype = 6;		/* treasure vault */
X			for(x = troom->lx; x <= troom->hx; x++)
X			for(y = troom->ly; y <= troom->hy; y++)
X				mkgold(rnd(dlevel*100) + 50, x, y);
X		}
X	}
X
X#ifdef WIZARD
X	if(wizard){
X		if(rn2(3)) mkshop(); else mkzoo();
X	} else
X#endif WIZARD
X 	if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 2) mkshop();
X	else
X	if(dlevel > 6 && (!rn2(7) || !strcmp("david", getlogin())))
X		mkzoo();
X	savelev();
X	exit(0);
X}
X
Xmakerooms(secret) int secret; {
Xregister int lowx, lowy;
Xregister int tryct = 0;
X	while(nroom < (MAXNROFROOMS/2) || secret)
X	    for(lowy = rn1(3,3); lowy < ROWNO-7; lowy += rn1(2,4)) {
X		for(lowx = rn1(3,4); lowx < COLNO-10; lowx += rn1(2,7)) {
X			if(tryct++ > 10000) return(0);
X			if((lowy += (rn2(5)-2)) < 3) lowy = 3;
X			else if(lowy > ROWNO-6) lowy = ROWNO-6;
X			if(levl[lowx][lowy].typ) continue;
X			if((secret && maker(lowx, 1, lowy, 1)) ||
X			   (!secret && maker(lowx,rn1(9,2),lowy,rn1(4,2))
X				&& nroom+2 > MAXNROFROOMS)) return(1);
X		}
X	}
X	return(1);
X}
X
Xcomp(x,y)
Xregister struct mkroom *x,*y;
X{
X	if(x->lx < y->lx) return(-1);
X	return(x->lx > y->lx);
X}
X
Xcoord
Xfinddpos(xl,yl,xh,yh) {
Xcoord ff;
Xregister x,y;
X	ff.x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
X	ff.y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
X	if(okdoor(ff.x, ff.y)) return(ff);
X	if(xl < xh) for(x = xl; x <= xh; x++)
X		if(okdoor(x, ff.y)){
X			ff.x = x;
X			return(ff);
X		}
X	if(yl < yh) for(y = yl; y <= yh; y++)
X		if(okdoor(ff.x, y)){
X			ff.y = y;
X			return(ff);
X		}
X	return(ff);
X}
X
X/* when croom and troom exist, find position for a door in croom
X   and direction for a corridor towards position [tx,ty] in the wall
X   of troom */
Xmkpos()
X{
Xcoord cc,tt;
X	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
X	if(troom->lx > croom->hx) {
X		dx = 1;
X		dy = 0;
X		xx = croom->hx+1;
X		tx = troom->lx-1;
X		cc = finddpos(xx,croom->ly,xx,croom->hy);
X		tt = finddpos(tx,troom->ly,tx,troom->hy);
X	} else if(troom->hy < croom->ly) {
X		dy = -1;
X		dx = 0;
X		yy = croom->ly-1;
X		cc = finddpos(croom->lx,yy,croom->hx,yy);
X		ty = troom->hy+1;
X		tt = finddpos(troom->lx,ty,troom->hx,ty);
X	} else if(troom->hx < croom->lx) {
X		dx = -1;
X		dy = 0;
X		xx = croom->lx-1;
X		tx = troom->hx+1;
X		cc = finddpos(xx,croom->ly,xx,croom->hy);
X		tt = finddpos(tx,troom->ly,tx,troom->hy);
X	} else {
X		dy = 1;
X		dx = 0;
X		yy = croom->hy+1;
X		ty = troom->ly-1;
X		cc = finddpos(croom->lx,yy,croom->hx,yy);
X		tt = finddpos(troom->lx,ty,troom->hx,ty);
X	}
X	xx = cc.x;
X	yy = cc.y;
X	tx = tt.x;
X	ty = tt.y;
X	if(levl[xx+dx][yy+dy].typ) {
X		if(nxcor) newloc();
X		else {
X			dodoor(xx,yy,croom);
X			xx += dx;
X			yy += dy;
X		}
X		return;
X	}
X	dodoor(xx,yy,croom);
X}
X
X/* if allowable, create a door at [x,y] */
Xokdoor(x,y)
Xregister x,y;
X{
X	if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||
X	   levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||
X	   levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||
X	   levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||
X	   (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
X	   doorindex >= DOORMAX)
X		return(0);
X	return(1);
X}
X
Xdodoor(x,y,aroom)
Xregister x,y;
Xregister struct mkroom *aroom;
X{
X	register struct mkroom *broom;
X	register tmp;
X	if(doorindex >= DOORMAX) panic("DOORMAX exceeded?");
X	if(!okdoor(x,y) && nxcor) return;
X	if(!rn2(8)) levl[x][y].typ = SDOOR;
X	else {
X		levl[x][y].scrsym ='+';
X		levl[x][y].typ = DOOR;
X	}
X	aroom->doorct++;
X	broom = aroom+1;
X	if(broom->hx < 0) tmp = doorindex; else
X	for(tmp = doorindex; tmp > broom->fdoor; tmp--)
X		doors[tmp] = doors[tmp-1];
X	doorindex++;
X	doors[tmp].x = x;
X	doors[tmp].y = y;
X	for( ; broom->hx >= 0; broom++) broom->fdoor++;
X}
X
Xnewloc()
X{
X	register a,b;
X	register int tryct = 0;
X
X	++croom;
X	++troom;
X	if(nxcor || croom->hx < 0 || troom->hx < 0) {
X		if(nxcor++ > rn1(nroom,4)) {
X			croom = &rooms[nroom];
X			return;
X		}
X		do {
X			if(++tryct > 100){
X				printf("tryct overflow5\n");
X				croom = &rooms[nroom];
X				return;
X			}
X			a = rn2(nroom);
X			b = rn2(nroom);
X			croom = &rooms[a];
X			troom = &rooms[b];
X		} while(croom == troom || (troom == croom+1 && !rn2(3)));
X	}
X	mkpos();
X}
X
X/* make a trap somewhere (in croom if mazeflag = 0) */
Xmktrap(num,mazeflag)
Xregister num,mazeflag;
X{
X	register struct gen *gtmp;
X	register int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0;
X	register xchar mx,my;
X
X	if(!num || num >= TRAPNUM) {
X		nopierc = (dlevel < 4) ? 1 : 0;
X		nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
X		if(index(fut_geno, 'M')) nomimic = 1;
X		kind = rn2(TRAPNUM - nopierc - nomimic);
X		/* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
X	} else kind = num;
X
X	if(kind == MIMIC) {
X		register struct monst *mtmp;
X
X		fakedoor = (!rn2(3) && !mazeflag);
X		fakegold = (!fakedoor && !rn2(2));
X		if(fakegold) goldseen = TRUE;
X		do {
X			if(++tryct > 200) return;
X			if(fakedoor) {
X				/* note: fakedoor maybe on actual door */
X				if(rn2(2)){
X					if(rn2(2))
X						mx = croom->hx+1;
X					else mx = croom->lx-1;
X					my = somey();
X				} else {
X					if(rn2(2))
X						my = croom->hy+1;
X					else my = croom->ly-1;
X					mx = somex();
X				}
X			} else if(mazeflag) {
X				extern coord mazexy();
X				coord mm;
X				mm = mazexy();
X				mx = mm.x;
X				my = mm.y;
X			} else {
X				mx = somex();
X				my = somey();
X			}
X		} while(m_at(mx,my));
X		if(mtmp = makemon(PM_MIMIC,mx,my))
X		    mtmp->mimic =
X			fakegold ? '$' : fakedoor ? '+' :
X			(mazeflag && rn2(2)) ? AMULET_SYM :
X			"=/)%?![<>" [ rn2(9) ];
X		return;
X	}
X	gtmp = newgen();
X	gtmp->gflag = kind;
X	do {
X		if(++tryct > 200){
X			printf("tryct overflow7\n");
X			free((char *) gtmp);
X			return;
X		}
X		if(mazeflag){
X			extern coord mazexy();
X			coord mm;
X			mm = mazexy();
X			gtmp->gx = mm.x;
X			gtmp->gy = mm.y;
X		} else {
X			gtmp->gx = somex();
X			gtmp->gy = somey();
X		}
X	} while(g_at(gtmp->gx, gtmp->gy, ftrap));
X	gtmp->ngen = ftrap;
X	ftrap = gtmp;
X	if(mazeflag && !rn2(10) && gtmp->gflag < PIERC) gtmp->gflag |= SEEN;
X}
X
X/*VARARGS1*/
Xpanic(str,arg1,arg2,arg3)
Xchar *str,*arg1,*arg2,*arg3;
X{
X	char bufr[BUFSZ];
X	extern int sprintf();
X	(void) sprintf(bufr,str,arg1,arg2,arg3);
X	(void) write(1,"\nMKLEV ERROR:  ",15);
X	puts(bufr);
X	(void) fflush(stdout);
X	exit(1);
X}
X
Xmaker(lowx,ddx,lowy,ddy)
Xschar lowx,ddx,lowy,ddy;
X{
X	register x, y, hix = lowx+ddx, hiy = lowy+ddy;
X
X	if(nroom >= MAXNROFROOMS) return(0);
X	if(hix > COLNO-5) hix = COLNO-5;
X	if(hiy > ROWNO-4) hiy = ROWNO-4;
Xchk:
X	if(hix <= lowx || hiy <= lowy) return(0);
X
X	/* check area around room (and make room smaller if necessary) */
X	for(x = lowx-4; x <= hix+4; x++)
X		for(y = lowy-3; y <= hiy+3; y++)
X			if(levl[x][y].typ) {
X				if(rn2(3)) return(0);
X				lowx = x+5;
X				lowy = y+4;
X				goto chk;
X			}
X
X	/* on low levels the room is lit (usually) */
X	/* secret vaults are always lit */
X	if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1))
X		for(x = lowx-1; x <= hix+1; x++)
X			for(y = lowy-1; y <= hiy+1; y++)
X				levl[x][y].lit = 1;
X	croom->lx = lowx;
X	croom->hx = hix;
X	croom->ly = lowy;
X	croom->hy = hiy;
X	croom->rtype = croom->doorct = croom->fdoor = 0;
X	for(x = lowx-1; x <= hix+1; x++)
X	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
X		levl[x][y].scrsym = '-';
X		levl[x][y].typ = HWALL;
X	}
X	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
X	    for(y = lowy; y <= hiy; y++) {
X		levl[x][y].scrsym = '|';
X		levl[x][y].typ = VWALL;
X	}
X	for(x = lowx; x <= hix; x++)
X	    for(y = lowy; y <= hiy; y++) {
X		levl[x][y].scrsym = '.';
X		levl[x][y].typ = ROOM;
X	}
X	croom++;
X	croom->hx = -1;
X	nroom++;
X	return(1);
X}
X
Xmakecor() {
X	register nx, ny;
X	register struct rm *crm;
X	register dix, diy, secondtry = 0;
X
Xtryagain:
X	nx = xx + dx;
X	ny = yy + dy;
X
X	if(nxcor && !rn2(35)) {
X		newloc();
X		return;
X	}
X	if(nx == COLNO-1 || nx == 0 || ny == 0 || ny == ROWNO-1) {
X		if(nxcor) {
X			newloc();
X			return;
X		} else {
X			printf("something went wrong. we try again...\n");
X		execl("./mklev",args[0],tfile,tspe,args[3],args[4],args[5],0);
X			panic("cannot execute ./mklev\n");
X		}
X	}
X
X	dix = abs(nx-tx);
X	diy = abs(ny-ty);
X	if(dy && dix > diy) {
X		dy = 0;
X		dx = (nx > tx) ? -1 : 1;
X	} else if(dx && diy > dix) {
X		dx = 0;
X		dy = (ny > ty) ? -1 : 1;
X	}
X
X	crm = &levl[nx][ny];
X	if(!(crm->typ)) {
X		if(rn2(100)) {
X			crm->typ = CORR;
X			crm->scrsym = CORR_SYM;
X		} else {
X			crm->typ = SCORR;
X			crm->scrsym = ' ';
X		}
X		xx = nx;
X		yy = ny;
X		if(nxcor && !rn2(50)) {
X			mkobj_at(ROCK_SYM, nx, ny);
X		}
X		return;
X	}
X	if(crm->typ == CORR || crm->typ == SCORR) {
X		xx = nx;
X		yy = ny;
X		return;
X	}
X	if(nx == tx && ny == ty) {
X		dodoor(nx,ny,troom);
X		newloc();
X		return;
X	}
X	if(!secondtry++ && (nx != xx+dx || ny != yy+dy))
X		goto tryagain;
X	if(dx) {
X		if(ty < ny) dy = -1;
X		else dy = levl[nx+dx][ny-1].typ == ROOM?1:-1;
X		dx = 0;
X	} else {
X		if(tx < nx) dx = -1;
X		else dx = levl[nx-1][ny+dy].typ == ROOM?1:-1;
X		dy = 0;
X	}
X}
X
Xstruct monst *
Xm_at(x,y)
Xregister x,y;
X{
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X		if(mtmp->mx == x && mtmp->my == y) return(mtmp);
X	return(0);
X}
X
Xstruct gen *
Xg_at(x,y,ptr)
Xregister x,y;
Xregister struct gen *ptr;
X{
X	while(ptr) {
X		if(ptr->gx == x && ptr->gy == y) return(ptr);
X		ptr = ptr->ngen;
X	}
X	return(0);
X}
!Funky!Stuff!
echo x - mklev.h
sed -e 's/^X//' > mklev.h << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "config.h"
X
X#ifdef BSD
X#include <strings.h>		/* declarations for strcat etc. */
X#else
X#include <string.h>		/* idem on System V */
X#define	index	strchr
X#define	rindex	strrchr
X#endif BSD
X
X#include	"def.objclass.h"
X
Xtypedef struct {
X	xchar x,y;
X} coord;
X
X#include	"def.monst.h"	/* uses coord */
X#include	"def.gen.h"
X#include	"def.obj.h"
X
Xextern int	sprintf();
X
X#define	BUFSZ	256	/* for getlin buffers */
X#define	PL_NSIZ	32	/* name of player, ghost, shopkeeper */
X
X#define	HWALL 1	/* Level location types */
X#define	VWALL 2
X#define	SDOOR 3
X#define	SCORR 4
X#define	LDOOR 5
X#define	DOOR 6	/* smallest accessible type */
X#define	CORR 7
X#define	ROOM 8
X#define	STAIRS 9
X#ifdef QUEST
X#define	CORR_SYM	':'
X#else
X#define	CORR_SYM	'#'
X#endif QUEST
X
X#define	ERRCHAR	'{'
X
X#define TRAPNUM 9
X
Xstruct rm {
X	char scrsym;
X	unsigned typ:5;
X	unsigned new:1;
X	unsigned seen:1;
X	unsigned lit:1;
X};
Xextern struct rm levl[COLNO][ROWNO];
X
X#ifndef QUEST
Xstruct mkroom {
X	xchar lx,hx,ly,hy;
X	schar rtype,rlit,doorct,fdoor;
X};
X#define	MAXNROFROOMS	15
Xextern struct mkroom rooms[MAXNROFROOMS+1];
X#define	DOORMAX	100
Xextern coord doors[DOORMAX];
X#endif QUEST
X
X
X#include	"def.permonst.h"
Xextern struct permonst mons[];
X#define PM_ACIDBLOB	&mons[7]
X#define	PM_PIERC	&mons[17]
X#define	PM_MIMIC	&mons[37]
X#define	PM_CHAM		&mons[47]
X#define	PM_DEMON	&mons[54]
X#define	PM_MINOTAUR	&mons[55]	/* last in mons array */
X#define	PM_SHK		&mons[56]	/* very last */
X#define	CMNUM		55		/* number of common monsters */
X
Xextern long *alloc();
X
Xextern xchar xdnstair, ydnstair, xupstair, yupstair; /* stairs up and down. */
X
Xextern xchar dlevel;
X#ifdef WIZARD
Xextern boolean wizard;
X#endif WIZARD
X#define	newstring(x)	(char *) alloc((unsigned)(x))
!Funky!Stuff!
echo x - rnd.c
sed -e 's/^X//' > rnd.c << '!Funky!Stuff!'
X#include <sys/types.h>
X#define RND(x)	((lrand48()>>3) % x)
Xlong lrand48();
X
Xsetrand(arg)
Xlong arg;
X{
X	time_t time();
X	void srand48();
X
X	if (arg) {
X		srand48(arg);
X	} else {
X		srand48(time(0));
X	}
X}
X
Xrn1(x,y)
Xregister x,y;
X{
X	return(RND(x)+y);
X}
X
Xrn2(x)
Xregister x;
X{
X	return(RND(x));
X}
X
Xrnd(x)
Xregister x;
X{
X	return(RND(x)+1);
X}
X
Xd(n,x)
Xregister n,x;
X{
X	register tmp = n;
X
X	while(n--) tmp += RND(x);
X	return(tmp);
X}
!Funky!Stuff!
echo x - savelev.h
sed -e 's/^X//' > savelev.h << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#ifdef MKLEV
X
Xsavelev(){
X	int fd;
X
X#else
Xextern struct obj *billobjs;
X
Xsavelev(fd){
X#ifndef NOWORM
X	register struct wseg *wtmp, *wtmp2;
X	register tmp;
X#endif NOWORM
X
X#endif MKLEV
X
X#ifdef MKLEV
X	if((fd = creat(tfile,FMASK)) < 0) panic("Cannot create %s\n", tfile);
X#else
X	if(fd < 0) panic("Save on bad file!");
X#endif MKLEV
X	bwrite(fd,(char *) levl,sizeof(levl));
X#ifdef MKLEV
X	bwrite(fd,(char *) nul,sizeof(long));
X#else
X	bwrite(fd,(char *) &moves,sizeof(long));
X#endif MKLEV
X	bwrite(fd,(char *) &xupstair,sizeof(xupstair));
X	bwrite(fd,(char *) &yupstair,sizeof(yupstair));
X	bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
X	bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
X	savemonchn(fd, fmon);
X	savegenchn(fd, fgold);
X	savegenchn(fd, ftrap);
X	saveobjchn(fd, fobj);
X#ifdef MKLEV
X	saveobjchn(fd, (struct obj *) 0);
X	bwrite(fd,(char *) nul, sizeof(unsigned));
X#else
X	saveobjchn(fd, billobjs);
X	billobjs = 0;
X	save_engravings(fd);
X#endif MKLEV
X#ifndef QUEST
X	bwrite(fd,(char *) rooms,sizeof(rooms));
X	bwrite(fd,(char *) doors,sizeof(doors));
X#endif QUEST
X	fgold = ftrap = 0;
X	fmon = 0;
X	fobj = 0;
X#ifndef MKLEV
X/*--------------------------------------------------------------------*/
X#ifndef NOWORM
X	bwrite(fd,(char *) wsegs,sizeof(wsegs));
X	for(tmp=1; tmp<32; tmp++){
X		for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
X			wtmp2 = wtmp->nseg;
X			bwrite(fd,(char *) wtmp,sizeof(struct wseg));
X		}
X		wsegs[tmp] = 0;
X	}
X	bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
X#endif NOWORM
X/*--------------------------------------------------------------------*/
X#endif MKLEV
X}
X
Xbwrite(fd,loc,num)
Xregister fd;
Xregister char *loc;
Xregister unsigned num;
X{
X	if(write(fd, loc, num) != num)
X		panic("cannot write %d bytes to file #%d",num,fd);
X}
X
Xsaveobjchn(fd,otmp)
Xregister fd;
Xregister struct obj *otmp;
X{
X	register struct obj *otmp2;
X	unsigned xl;
X	int minusone = -1;
X
X	while(otmp) {
X		otmp2 = otmp->nobj;
X		xl = otmp->onamelth;
X		bwrite(fd, (char *) &xl, sizeof(int));
X		bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
X		free((char *) otmp);
X		otmp = otmp2;
X	}
X	bwrite(fd, (char *) &minusone, sizeof(int));
X}
X
Xsavemonchn(fd,mtmp)
Xregister fd;
Xregister struct monst *mtmp;
X{
X	register struct monst *mtmp2;
X	unsigned xl;
X	int minusone = -1;
X	struct permonst *monbegin = &mons[0];
X
X	bwrite(fd, (char *) &monbegin, sizeof(monbegin));
X
X	while(mtmp) {
X		mtmp2 = mtmp->nmon;
X		xl = mtmp->mxlth + mtmp->mnamelth;
X		bwrite(fd, (char *) &xl, sizeof(int));
X		bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
X		if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
X		free((char *) mtmp);
X		mtmp = mtmp2;
X	}
X	bwrite(fd, (char *) &minusone, sizeof(int));
X}
X
Xsavegenchn(fd,gtmp)
Xregister fd;
Xregister struct gen *gtmp;
X{
X	register struct gen *gtmp2;
X	while(gtmp) {
X		gtmp2 = gtmp->ngen;
X		bwrite(fd, (char *) gtmp, sizeof(struct gen));
X		free((char *) gtmp);
X		gtmp = gtmp2;
X	}
X	bwrite(fd, nul, sizeof(struct gen));
X}
!Funky!Stuff!
exit
-- 
Gordon A. Moffett		...!{ihnp4,hplabs,sun}!amdahl!gam

"Her name was McGill, and she called herself Lil, but everyone knew
 her as Nancy...."