Amiga Hack Source (Part 9 of 13)

John A. Toebes, VIII jcz at ncsu.UUCP
Sun Feb 23 02:51:14 AEST 1986


#file hack.zap.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */

#include "hack.h"

extern struct monst *makemon();
struct monst *bhit();
char *exclam();

char *fl[]= {
	"magic missile",
	"bolt of fire",
	"sleep ray",
	"bolt of cold",
	"death ray"
};

dozap()
{
	register struct obj *obj;
	register struct monst *mtmp;
	xchar zx,zy;
	register int num;

	obj = getobj("/", "zap");
	if(!obj) return(0);
	if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
		pline("Nothing Happens");
		return(1);
	}
	if(obj->spe == 0)
		pline("You wrest one more spell from the worn-out wand.");
	if(!(objects[obj->otyp].bits & NODIR) && !getdir())
		return(1); /* make him pay for knowing !NODIR */
	obj->spe--;
	if(objects[obj->otyp].bits & IMMEDIATE) {
		if((u.uswallow && (mtmp = u.ustuck)) ||
		   (mtmp = bhit(u.dx,u.dy,rn1(8,6),0))) {
			wakeup(mtmp);
			switch(obj->otyp) {
			case WAN_STRIKING:
				if(rnd(20) < 10+mtmp->data->ac) {
					register int tmp = d(2,12);
					hit("wand", mtmp, exclam(tmp));
					mtmp->mhp -= tmp;
					if(mtmp->mhp < 1) killed(mtmp);
				} else miss("wand", mtmp);
				break;
			case WAN_SLOW_MONSTER:
				mtmp->mspeed = MSLOW;
				break;
			case WAN_SPEED_MONSTER:
				mtmp->mspeed = MFAST;
				break;
			case WAN_UNDEAD_TURNING:
				if(index("WVZ&",mtmp->data->mlet)) {
					mtmp->mhp -= rnd(8);
					if(mtmp->mhp<1) killed(mtmp);
					else mtmp->mflee = 1;
				}
				break;
			case WAN_POLYMORPH:
				if( newcham(mtmp,&mons[rn2(CMNUM)]) )
					objects[obj->otyp].oc_name_known = 1;
				break;
			case WAN_CANCELLATION:
				mtmp->mcan = 1;
				break;
			case WAN_TELEPORT_MONSTER:
				rloc(mtmp);
				break;
			case WAN_MAKE_INVISIBLE:
				mtmp->minvis = 1;
				break;
#ifdef WAN_PROBING
			case WAN_PROBING:
				mstatusline(mtmp);
				break;
#endif WAN_PROBING
			default:
				pline("What an interesting wand (%d)",
					obj->otyp);
				impossible();
			}
		}
	} else {
	switch(obj->otyp){
		case WAN_LIGHT:
			litroom(TRUE);
			break;
		case WAN_SECRET_DOOR_DETECTION:
			if(!findit()) return(1);
			break;
		case WAN_CREATE_MONSTER:
			{ register int cnt = 1;
			if(!rn2(23)) cnt += rn2(7) + 1;
			while(cnt--)
			    (void) makemon((struct permonst *) 0, u.ux, u.uy);
			}
			break;
		case WAN_WISHING:
			{ char buf[BUFSZ];
			  register struct obj *otmp;
			  extern struct obj *readobjnam(), *addinv();
		      if(u.uluck + rn2(5) < 0) {
			pline("Unfortunately, nothing happens.");
			break;
		      }
		      pline("You may wish for an object. What do you want? ");
		      getlin(buf);
		      otmp = readobjnam(buf);
		      otmp = addinv(otmp);
		      prinv(otmp);
		      break;
			}
		case WAN_DIGGING:
			{ register struct rm *room;
			  register int digdepth;
			if(u.uswallow) {
				pline("You pierce %s's stomach wall!",
					monnam(u.ustuck));
				u.uswallow = 0;
				mnexto(u.ustuck);
				u.ustuck->mhp = 1;	/* almost dead */
				u.ustuck = 0;
				setsee();
				docrt();
				break;
			}
			zx = u.ux+u.dx;
			zy = u.uy+u.dy;
			if(!isok(zx,zy)) break;
			digdepth = 4 + rn2(10);
			if(levl[zx][zy].typ == CORR) num = CORR;
			else num = ROOM;
			Tmp_at(-1, '*');	/* open call */
			while(digdepth--) {
				if(zx == 0 || zx == COLNO-1 ||
					 zy == 0 || zy == ROWNO-1)
					break;
				room = &levl[zx][zy];
				Tmp_at(zx,zy);
				if(!xdnstair){
					if(zx < 3 || zx > COLNO-3 ||
					    zy < 3 || zy > ROWNO-3)
						break;
					if(room->typ == HWALL ||
					    room->typ == VWALL){
						room->typ = ROOM;
						break;
					}
				} else if(num == ROOM || num == 10){
					if(room->typ != ROOM && room->typ) {
						if(room->typ != CORR)
							room->typ = DOOR;
						if(num == 10) break;
						num = 10;
					} else if(!room->typ)
						room->typ = CORR;
				} else {
					if(room->typ != CORR && room->typ) {
						room->typ = DOOR;
						break;
					} else room->typ = CORR;
				}
				mnewsym(zx,zy);
				zx += u.dx;
				zy += u.dy;
			}
			mnewsym(zx,zy);	/* not always necessary */
			Tmp_at(-1,-1);	/* closing call */
			break;
			}
		default:
			buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
				u.ux, u.uy, u.dx, u.dy);
			break;
		}
		if(!objects[obj->otyp].oc_name_known) {
			u.urexp += 10;
			objects[obj->otyp].oc_name_known = 1;
		}
	}
	return(1);
}

char *
exclam(force)
register int force;
{
	/* force == 0 occurs e.g. with sleep ray */
	/* note that large force is usual with wands so that !! would
		require information about hand/weapon/wand */
	return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
}

hit(str,mtmp,force)
register char *str;
register struct monst *mtmp;
register char *force;		/* usually either "." or "!" */
{
	if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str);
	else pline("The %s hits %s%s", str, monnam(mtmp), force);
}

miss(str,mtmp)
register char *str;
register struct monst *mtmp;
{
	if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str);
	else pline("The %s misses %s.",str,monnam(mtmp));
}

/* sets bhitpos to the final position of the weapon thrown */
/* coord bhitpos; */

/* check !u.uswallow before calling bhit() */
struct monst *
bhit(ddx,ddy,range,sym)
register int ddx,ddy,range;
char sym;
{
	register struct monst *mtmp;

	bhitpos.x = u.ux;
	bhitpos.y = u.uy;

	if(sym) tmp_at(-1, sym);	/* open call */
	while(range--) {
		bhitpos.x += ddx;
		bhitpos.y += ddy;
		if(mtmp = m_at(bhitpos.x,bhitpos.y)){
			if(sym) tmp_at(-1, -1);	/* close call */
			return(mtmp);
		}
		if(levl[bhitpos.x][bhitpos.y].typ<CORR) {
			bhitpos.x -= ddx;
			bhitpos.y -= ddy;
			break;
		}
		if(sym) tmp_at(bhitpos.x, bhitpos.y);
	}
	if(sym) tmp_at(-1, 0);	/* leave last symbol */
	return(0);
}

struct monst *
boomhit(dx,dy) {
	register int i, ct;
	register struct monst *mtmp;
	char sym = ')';
	extern schar xdir[], ydir[];

	bhitpos.x = u.ux;
	bhitpos.y = u.uy;

	for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
	tmp_at(-1, sym);	/* open call */
	for(ct=0; ct<10; ct++) {
		if(i == 8) i = 0;
		sym = ')' + '(' - sym;
		tmp_at(-2, sym);	/* change let call */
		dx = xdir[i];
		dy = ydir[i];
		bhitpos.x += dx;
		bhitpos.y += dy;
		if(mtmp = m_at(bhitpos.x, bhitpos.y)){
			tmp_at(-1,-1);
			return(mtmp);
		}
		if(levl[bhitpos.x][bhitpos.y].typ<CORR) {
			bhitpos.x -= dx;
			bhitpos.y -= dy;
			break;
		}
		if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
			if(rn2(20) >= 10+u.ulevel){	/* we hit ourselves */
				(void) thitu(10, rnd(10), "boomerang");
				break;
			} else {	/* we catch it */
				tmp_at(-1,-1);
				pline("Skillfully, you catch the boomerang.");
				return((struct monst *) -1);
			}
		}
		tmp_at(bhitpos.x, bhitpos.y);
		if(ct % 5 != 0) i++;
	}
	tmp_at(-1, -1);	/* do not leave last symbol */
	return(0);
}

char
dirlet(dx,dy) register int dx,dy; {
	return
		(dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
}

/* type < 0: monster spitting fire at you */
buzz(type,sx,sy,dx,dy)
register int type;
register xchar sx,sy;
register int dx,dy;
{
	register char *fltxt = (type < 0) ? "blaze of fire" : fl[type];
	struct rm *lev;
	xchar range;
	struct monst *mon;

	if(u.uswallow) {
		register int tmp;

		if(type < 0) return;
		tmp = zhit(u.ustuck, type);
		pline("The %s rips into %s%s",
			fltxt, monnam(u.ustuck), exclam(tmp));
		return;
	}
	if(type < 0) pru();
	range = rn1(7,7);
	Tmp_at(-1, dirlet(dx,dy));	/* open call */
	while(range-- > 0) {
		sx += dx;
		sy += dy;
		if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy);
		else {
			int bounce = 0;
			if(cansee(sx-dx,sy-dy)) pline("The %s bounces!",fltxt);
			if(levl[sx][sy-dy].typ > DOOR) bounce = 1;
			if(levl[sx-dx][sy].typ > DOOR) {
				if(!bounce || rn2(2)) bounce = 2;
			}
			switch(bounce){
			case 0:
				dx = -dx;
				dy = -dy;
				continue;
			case 1:
				dy = -dy;
				sx -= dx;
				break;
			case 2:
				dx = -dx;
				sy -= dy;
				break;
			}
			Tmp_at(-2,dirlet(dx,dy));
			continue;
		}
		if((mon = m_at(sx,sy)) &&
		   (type >= 0 || mon->data->mlet != 'D')) {
			wakeup(mon);
			if(rnd(20) < 18 + mon->data->ac) {
				register int tmp = zhit(mon,type);
				if(mon->mhp < 1) {
					if(type < 0) {
					    if(cansee(mon->mx,mon->my))
					      pline("%s is killed by the %s!",
						Monnam(mon), fltxt);
					    mondied(mon);
					} else
					    killed(mon);
				} else
					hit(fltxt, mon, exclam(tmp));
				range -= 2;
			} else
				miss(fltxt,mon);
		} else if(sx == u.ux && sy == u.uy) {
			if(rnd(20) < 18+u.uac) {
				register int dam = 0;
				range -= 2;
				pline("The %s hits you!",fltxt);
				switch(type) {
				case 0:
					dam = d(2,6);
					break;
				case -1:	/* dragon fire */
				case 1:
					if(Fire_resistance)
						pline("You don't feel hot!");
					else dam = d(6,6);
					break;
				case 2:
					nomul(-rnd(25)); /* sleep ray */
					break;
				case 3:
					if(Cold_resistance)
						pline("You don't feel cold!");
					else dam = d(6,6);
					break;
				case 4:
					u.uhp = -1;
				}
				losehp(dam,fltxt);
			} else pline("The %s whizzes by you!",fltxt);
		}
		if(lev->typ <= DOOR) {
			int bounce = 0, rmn;
			if(cansee(sx,sy)) pline("The %s bounces!",fltxt);
			range--;
			if(!dx || !dy || !rn2(20)){
				dx = -dx;
				dy = -dy;
			} else {
			  if((rmn = levl[sx][sy-dy].typ) > DOOR &&
			    (
			     rmn >= ROOM ||
				levl[sx+dx][sy-dy].typ > DOOR)){
				bounce = 1;
			  }
			  if((rmn = levl[sx-dx][sy].typ) > DOOR &&
			    (
			     rmn >= ROOM ||
				levl[sx-dx][sy+dy].typ > DOOR)){
				if(!bounce || rn2(2)){
					bounce = 2;
				}
			  }
			  switch(bounce){
			  case 0:
				dy = -dy;
				dx = -dx;
				break;
			  case 1:
				dy = -dy;
				break;
			  case 2:
				dx = -dx;
				break;
			  }
			  Tmp_at(-2, dirlet(dx,dy));
			}
		}
	}
	Tmp_at(-1,-1);
}

zhit(mon,type)			/* returns damage to mon */
register struct monst *mon;
register int type;
{
	register int tmp = 0;

	switch(type) {
	case 0:			/* magic missile */
		tmp = d(2,6);
		break;
	case -1:		/* Dragon blazing fire */
	case 1:			/* fire */
		if(index("Dg", mon->data->mlet)) break;
		tmp = d(6,6);
		if(mon->data->mlet == 'Y') tmp += 7;
		break;
	case 2:			/* sleep*/
		mon->mfroz = 1;
		break;
	case 3:			/* cold */
		if(index("YFgf", mon->data->mlet)) break;
		tmp = d(6,6);
		if(mon->data->mlet == 'D') tmp += 7;
		break;
	case 4:			/* death*/
		if(index("WVZ",mon->data->mlet)) break;
		tmp = mon->mhp+1;
		break;
	}
	mon->mhp -= tmp;
	return(tmp);
}
#file makedefs.c
/* construct definitions of object constants */
#define	DEF_FILE	"def.objects.h"
#define	LINSZ	1000
#define	STRSZ	40

int fd;
char string[STRSZ];

main(){
register int index = 0;
register int propct = 0;
register char *sp;
	fd = open(DEF_FILE, 0);
	if(fd < 0) {
		perror(DEF_FILE);
		exit(1);
	}
	skipuntil("objects[] = {");
	while(getentry()) {
		if(!*string){
			index++;
			continue;
		}
		for(sp = string; *sp; sp++)
			if(*sp == ' ' || *sp == '\t')
				*sp = '_';
		if(!strncmp(string, "RIN_", 4)){
			capitalize(string+4);
			printf("#define	%s	u.uprops[%d].p_flgs\n",
				string+4, propct++);
		}
		for(sp = string; *sp; sp++) capitalize(sp);
		/* avoid trouble with stupid C preprocessors */
		if(!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
			printf("/* #define %s	%d */\n", string, index);
		else
			printf("#define	%s	%d\n", string, index);
		index++;
	}
	printf("\n#define	CORPSE	DEAD_HUMAN\n");
	printf("#define	LAST_GEM	(JADE+1)\n");
	printf("#define	LAST_RING	%d\n", propct);
	printf("#define	NROFOBJECTS	%d\n", index-1);
}

char line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
int eof;

readline(){
register int n = read(fd, lp0, (line+LINSZ)-lp0);
	if(n < 0){
		printf("Input error.\n");
		exit(1);
	}
	if(n == 0) eof++;
	lpe = lp0+n;
}

char
nextchar(){
	if(lp == lpe){
		readline();
		lp = lp0;
	}
	return((lp == lpe) ? 0 : *lp++);
}

skipuntil(s) char *s; {
register char *sp0, *sp1;
loop:
	while(*s != nextchar())
		if(eof) {
			printf("Cannot skipuntil %s\n", s);
			exit(1);
		}
	if(strlen(s) > lpe-lp+1){
		register char *lp1, *lp2;
		lp2 = lp;
		lp1 = lp = lp0;
		while(lp2 != lpe) *lp1++ = *lp2++;
		lp2 = lp0;	/* save value */
		lp0 = lp1;
		readline();
		lp0 = lp2;
		if(strlen(s) > lpe-lp+1) {
			printf("error in skipuntil");
			exit(1);
		}
	}
	sp0 = s+1;
	sp1 = lp;
	while(*sp0 && *sp0 == *sp1) sp0++, sp1++;
	if(!*sp0){
		lp = sp1;
		return(1);
	}
	goto loop;
}

getentry(){
int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
int prefix = 0;
char ch;
#define	NSZ	10
char identif[NSZ], *ip;
	string[0] = string[4] = 0;
	/* read until {...} or XXX(...) followed by ,
	   skip comment and #define lines
	   deliver 0 on failure
	 */
	while(1) {
		ch = nextchar();
	swi:
		if(letter(ch)){
			ip = identif;
			do {
				if(ip < identif+NSZ-1) *ip++ = ch;
				ch = nextchar();
			} while(letter(ch) || digit(ch));
			*ip = 0;
			while(ch == ' ' || ch == '\t') ch = nextchar();
			if(ch == '(' && !inparens && !stringseen)
				if(!strcmp(identif, "WAND") ||
				   !strcmp(identif, "RING") ||
				   !strcmp(identif, "POTION") ||
				   !strcmp(identif, "SCROLL"))
				(void) strncpy(string, identif, 3),
				string[3] = '_',
				prefix = 4;
		}
		switch(ch) {
		case '/':
			/* watch for comment */
			if((ch = nextchar()) == '*')
				skipuntil("*/");
			goto swi;
		case '{':
			inbraces++;
			continue;
		case '(':
			inparens++;
			continue;
		case '}':
			inbraces--;
			if(inbraces < 0) return(0);
			continue;
		case ')':
			inparens--;
			if(inparens < 0) {
				printf("too many ) ?");
				exit(1);
			}
			continue;
		case '\n':
			/* watch for #define at begin of line */
			if((ch = nextchar()) == '#'){
				register char pch;
				/* skip until '\n' not preceded by '\\' */
				do {
					pch = ch;
					ch = nextchar();
				} while(ch != '\n' || pch == '\\');
				continue;
			}
			goto swi;
		case ',':
			if(!inparens && !inbraces){
				if(prefix && !string[prefix])
					string[0] = 0;
				if(stringseen) return(1);
				printf("unexpected ,\n");
				exit(1);
			}
			commaseen++;
			continue;
		case '\'':
			if((ch = nextchar()) == '\\') ch = nextchar();
			if(nextchar() != '\''){
				printf("strange character denotation?\n");
				exit(1);
			}
			continue;
		case '"':
			{
				register char *sp = string + prefix;
				register char pch;
				register int store = (inbraces || inparens)
					&& !stringseen++ && !commaseen;
				do {
					pch = ch;
					ch = nextchar();
					if(store && sp < string+STRSZ)
						*sp++ = ch;
				} while(ch != '"' || pch == '\\');
				if(store) *--sp = 0;
				continue;
			}
		}
	}
}

capitalize(sp) register char *sp; {
	if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a';
}

letter(ch) register char ch; {
	return( ('a' <= ch && ch <= 'z') ||
		('A' <= ch && ch <= 'Z') );
}

digit(ch) register char ch; {
	return( '0' <= ch && ch <= '9' );
}

#file mklev.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* mklev.c version 1.0.1 - new makecorridor() */
#ifndef MKLEV
#define	MKLEV
#endif
#include <stdio.h>
#include "hack.h"
#include "def.trap.h"

extern struct monst *makemon();

static char tspe[2],**args;
static int doorindex;
static schar nxcor;

char ismklev;
struct mkroom *croom, *troom;
boolean goldseen;
int nroom;
int smeq[MAXNROFROOMS+1];
char *tfile;

#ifdef WIZARD
extern boolean wizard;
#endif

#define somex() ((rand()%(croom->hx-croom->lx+1))+croom->lx)
#define somey() ((rand()%(croom->hy-croom->ly+1))+croom->ly)

extern char nul[40];
extern struct rm levl[COLNO][ROWNO];
extern struct monst *fmon;
extern struct obj *fobj;
extern struct gen *fgold, *ftrap;
extern char *fut_geno;      /* monsters that should not be created anymore */
extern struct mkroom rooms[MAXNROFROOMS+1];
extern coord doors[DOORMAX];
extern int comp();
extern xchar dlevel;
extern xchar xdnstair,xupstair,ydnstair,yupstair;
   
zeroout(addr, len)
char *addr;
int len;
{
	while(--len>0) *addr++=0;
}

mklev()
{
	register unsigned tryct;

	tfile = lock;
	troom = NULL;
	doorindex = 0;
	nroom = 0;

	if(getbones()) return;
	ismklev = 1;
	if(dlevel < rn1(3, 26)) tspe[0] = 'a';   /* normal level */
	else tspe[0] = 'b';         /* maze */
	tspe[1] = 0;

	/* zap the object bases */
	{int i;extern int bases[];
	for(i=0;i<15;bases[i++]=0);}

	/* zap the room pictures */
	zeroout(levl,COLNO*ROWNO*sizeof(struct rm));

	fmon = NULL;
	fobj = NULL;
	fgold = ftrap = NULL;
   
	zeroout( doors, sizeof(coord)*DOORMAX);

	xdnstair = xupstair = ydnstair = yupstair = 0;
	zeroout(rooms, (MAXNROFROOMS+1)*sizeof(struct mkroom));

	init_objects();
	rooms[0].hx = -1;   /* in case we are in a maze */

	/* a: normal; b: maze */
	if(*tspe == 'b') {
		makemaz();
#ifdef DOSAVE
		{
		int fd;
		if((fd = creat(tfile,FMASK)) < 0) 
			panic("Cannot create %s\n", tfile);
		savelev(fd);
		close(fd);
		}
#endif
		ismklev = 0;
		return(0);
	}

	/* construct the rooms */
	while(nroom < (MAXNROFROOMS/3)) {
		croom = rooms;
		nroom = 0;
		(void) makerooms(0);      /* not secret */
	}

	/* for each room: put things inside */
	for(croom = rooms; croom->hx > 0; croom++) {

		/* put a sleeping monster inside */
		if(!rn2(3)) (void)
			makemon((struct permonst *) 0, somex(), somey());

		/* put traps and mimics inside */
		goldseen = FALSE;
		while(!rn2(8-(dlevel/6))) mktrap(0,0);
		if(!goldseen && !rn2(3)) mkgold(0,somex(),somey());
		if(!rn2(3)) {
			mkobj_at(0, somex(), somey());
			tryct = 0;
			while(!rn2(5)) {
				if(++tryct > 100){
					myprintf("tryct overflow4\n");
					break;
				}
				mkobj_at(0, somex(), somey());
			}
		}
	}
	tryct = 0;
	do {
		if(++tryct > 1000) panic("Cannot make dnstairs\n");
		croom = &rooms[rn2(nroom)];
		xdnstair = somex();
		ydnstair = somey();
	} while((*tspe =='n' && (!(xdnstair%2) || !(ydnstair%2))) ||
		g_at(xdnstair,ydnstair,ftrap));
	levl[xdnstair][ydnstair].scrsym ='>';
	levl[xdnstair][ydnstair].typ = STAIRS;
	troom = croom;
	do {
		if(++tryct > 2000) panic("Cannot make upstairs\n");
		croom = &rooms[rn2(nroom)];
		xupstair = somex();
		yupstair = somey();
	} while(croom == troom || m_at(xupstair,yupstair) ||
		g_at(xupstair,yupstair,ftrap));
	levl[xupstair][yupstair].scrsym ='<';
	levl[xupstair][yupstair].typ = STAIRS;

#ifdef DEBUG
	dumpit();
#endif
	qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
	makecorridors();
	make_niches();

	/* make a secret treasure vault, not connected to the rest */
	if(nroom < (2*MAXNROFROOMS/3)) if(!rn2(3)) {
		register int x,y;
		troom = croom = &rooms[nroom];
		if(makerooms(1)) {      /* make secret room */
			troom->rtype = 6;      /* treasure vault */
			for(x = troom->lx; x <= troom->hx; x++)
			for(y = troom->ly; y <= troom->hy; y++)
				mkgold(rnd(dlevel*100) + 50, x, y);
			if(!rn2(3))
				makevtele();
		}
	}

#ifdef WIZARD
	if(wizard){
		if(rn2(3)) mkshop(); else mkzoo();
	} else
#endif WIZARD
	if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 2)
		mkshop();
	else
		if(dlevel > 6 && !rn2(7) )
			mkzoo();
#ifdef DOSAVE
	{
	int fd;
	if((fd = creat(tfile,FMASK)) < 0) 
		panic("Cannot create %s\n", tfile);
	savelev(fd);
	close(fd);
	}
#endif
	ismklev = 0;
	return(0);
}

makerooms(secret)
int secret;
{
	register int lowx, lowy;
	register int tryct = 0;

   while(nroom < (MAXNROFROOMS/2) || secret)
      for(lowy = rn1(3,3); lowy < ROWNO-7; lowy += rn1(2,4))
         {
         for(lowx = rn1(3,4); lowx < COLNO-10; lowx += rn1(2,7))
            {
            if (tryct++ > 10000) return(0);

            if ((lowy += (rn2(5)-2)) < 3)
               lowy = 3;
            else
               if(lowy > ROWNO-6)
                  lowy = ROWNO-6;

            if(levl[lowx][lowy].typ) continue;

            if ((secret && maker(lowx, 1, lowy, 1)) ||
                (!secret && maker(lowx,rn1(9,2),lowy,rn1(4,2))
                && nroom+2 > MAXNROFROOMS)) return(1);
            }
         }
	return(1);
}

comp(x,y)
register struct mkroom *x,*y;
{
   if(x->lx < y->lx) return(-1);
   return(x->lx > y->lx);
}

coord
finddpos(xl,yl,xh,yh) {
coord ff;
register int x,y;
	ff.x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
	ff.y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
	if(okdoor(ff.x, ff.y)) return(ff);
	if(xl < xh) for(x = xl; x <= xh; x++)
		if(okdoor(x, ff.y)){
			ff.x = x;
			return(ff);
		}
	if(yl < yh) for(y = yl; y <= yh; y++)
		if(okdoor(ff.x, y)){
			ff.y = y;
			return(ff);
		}
	return(ff);
}

/* if allowable, create a door at [x,y] */
okdoor(x,y)
register int x,y;
{
	if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||
	   levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||
	   levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||
	   levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||
	   (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
	   doorindex >= DOORMAX)
		return(0);
	return(1);
}

dodoor(x,y,aroom)
register int x,y;
register struct mkroom *aroom;
{
	if(doorindex >= DOORMAX) panic("DOORMAX exceeded?");
	if(!okdoor(x,y) && nxcor) return;
	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
}

dosdoor(x,y,aroom,type)
register int x,y;
register struct mkroom *aroom;
register int type;
{
	register struct mkroom *broom;
	register int tmp;

	levl[x][y].typ = type;
	if(type == DOOR)
		levl[x][y].scrsym ='+';
	aroom->doorct++;
	broom = aroom+1;
	if(broom->hx < 0) tmp = doorindex; else
	for(tmp = doorindex; tmp > broom->fdoor; tmp--)
		doors[tmp] = doors[tmp-1];
	doorindex++;
	doors[tmp].x = x;
	doors[tmp].y = y;
	for( ; broom->hx >= 0; broom++) broom->fdoor++;
}

/* Only called from makerooms() */
maker(lowx,ddx,lowy,ddy)
schar lowx,ddx,lowy,ddy;
{
	register int x, y, hix = lowx+ddx, hiy = lowy+ddy;

	if(nroom >= MAXNROFROOMS) return(0);
	if(hix > COLNO-5) hix = COLNO-5;
	if(hiy > ROWNO-4) hiy = ROWNO-4;
chk:
	if(hix <= lowx || hiy <= lowy) return(0);

	/* check area around room (and make room smaller if necessary) */
	for(x = lowx-4; x <= hix+4; x++)
		for(y = lowy-3; y <= hiy+3; y++)
			if(levl[x][y].typ) {
				if(rn2(3)) return(0);
				lowx = x+5;
				lowy = y+4;
				goto chk;
			}

	/* on low levels the room is lit (usually) */
	/* secret vaults are always lit */
	if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1))
		for(x = lowx-1; x <= hix+1; x++)
			for(y = lowy-1; y <= hiy+1; y++)
				levl[x][y].lit = 1;
	croom->lx = lowx;
	croom->hx = hix;
	croom->ly = lowy;
	croom->hy = hiy;
	croom->rtype = croom->doorct = croom->fdoor = 0;
	for(x = lowx-1; x <= hix+1; x++)
	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
		levl[x][y].scrsym = '-';
		levl[x][y].typ = HWALL;
	}
	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
	    for(y = lowy; y <= hiy; y++) {
		levl[x][y].scrsym = '|';
		levl[x][y].typ = VWALL;
	}
	for(x = lowx; x <= hix; x++)
	    for(y = lowy; y <= hiy; y++) {
		levl[x][y].scrsym = '.';
		levl[x][y].typ = ROOM;
	}
	croom++;
	croom->hx = -1;
	smeq[nroom] = nroom;
	nroom++;
	return(1);
}

makecorridors() {
	register int a,b;

	nxcor = 0;
	for(a = 0; a < nroom-1; a++)
		join(a, a+1);
	for(a = 0; a < nroom-2; a++)
	    if(smeq[a] != smeq[a+2])
		join(a, a+2);
	for(a = 0; a < nroom; a++)
	    for(b = 0; b < nroom; b++)
		if(smeq[a] != smeq[b])
		    join(a, b);
	if(nroom > 2)
	    for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
		a = rn2(nroom);
		b = rn2(nroom-2);
		if(b >= a) b += 2;
		join(a, b);
	    }
}

join(a,b)
register int a,b;
{
	coord cc,tt;
	register int tx, ty, xx, yy;
	register struct rm *crm;
	register int dx, dy, dix, diy, cct;

	croom = &rooms[a];
	troom = &rooms[b];

	/* find positions cc and tt for doors in croom and troom
	   and direction for a corridor between them */

   if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
   if(troom->lx > croom->hx) {
      dx = 1;
      dy = 0;
      xx = croom->hx+1;
      tx = troom->lx-1;
      cc = finddpos(xx,croom->ly,xx,croom->hy);
      tt = finddpos(tx,troom->ly,tx,troom->hy);
   } else if(troom->hy < croom->ly) {
      dy = -1;
      dx = 0;
      yy = croom->ly-1;
      cc = finddpos(croom->lx,yy,croom->hx,yy);
      ty = troom->hy+1;
      tt = finddpos(troom->lx,ty,troom->hx,ty);
   } else if(troom->hx < croom->lx) {
      dx = -1;
      dy = 0;
      xx = croom->lx-1;
      tx = troom->hx+1;
      cc = finddpos(xx,croom->ly,xx,croom->hy);
      tt = finddpos(tx,troom->ly,tx,troom->hy);
   } else {
      dy = 1;
      dx = 0;
      yy = croom->hy+1;
      ty = troom->ly-1;
      cc = finddpos(croom->lx,yy,croom->hx,yy);
      tt = finddpos(troom->lx,ty,troom->hx,ty);
   }
	xx = cc.x;
	yy = cc.y;
	tx = tt.x - dx;
	ty = tt.y - dy;
	if(nxcor && levl[xx+dx][yy+dy].typ)
		return;
	dodoor(xx,yy,croom);

	cct = 0;
	while(xx != tx || yy != ty) {
	    xx += dx;
	    yy += dy;

	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
	    if(cct++ > 500 || (nxcor && !rn2(35)))
		return;

	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
		return;		/* impossible */

	    crm = &levl[xx][yy];
	    if(!(crm->typ)) {
		if(rn2(100)) {
			crm->typ = CORR;
			crm->scrsym = CORR_SYM;
		} else {
			crm->typ = SCORR;
			crm->scrsym = ' ';
		}
		if(nxcor && !rn2(50)) {
			mkobj_at(ROCK_SYM, xx, yy);
		}
	    } else
	    if(crm->typ != CORR && crm->typ != SCORR) {
		/* strange ... */
      return;
	    }

	    /* find next corridor position */
	    dix = abs(xx-tx);
	    diy = abs(yy-ty);

	    /* do we have to change direction ? */
	    if(dy && dix > diy) {
		register int ddx = (xx > tx) ? -1 : 1;

		crm = &levl[xx+ddx][yy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
		    dx = ddx;
		    dy = 0;
		    continue;
		}
	    } else if(dx && diy > dix) {
		register int ddy = (yy > ty) ? -1 : 1;

		crm = &levl[xx][yy+ddy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
		    dy = ddy;
		    dx = 0;
		    continue;
		}
	    }

	    /* continue straight on? */
	    crm = &levl[xx+dx][yy+dy];
	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
		continue;

	    /* no, what must we do now?? */
	    if(dx) {
		dx = 0;
		dy = (ty < yy) ? -1 : 1;
		crm = &levl[xx+dx][yy+dy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
		    continue;
		dy = -dy;
		continue;
	    } else {
		dy = 0;
		dx = (tx < xx) ? -1 : 1;
		crm = &levl[xx+dx][yy+dy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
		    continue;
		dx = -dx;
		continue;
	    }
   }
	/* we succeeded in digging the corridor */
	dodoor(tt.x, tt.y, troom);

	if(smeq[a] < smeq[b])
		smeq[b] = smeq[a];
	else
		smeq[a] = smeq[b];
}

make_niches()
{
	register int ct = rn2(nroom/2 + 1)+1;
	while(ct--) makeniche(FALSE);
}

makevtele()
{
	makeniche(TRUE);
}

makeniche(with_trap)
boolean with_trap;
{
	register struct mkroom *aroom;
	register struct rm *rm;
	register int vct = 8;
	coord dd;
	register int dy,xx,yy;
	register struct gen *gtmp;

	if(doorindex < DOORMAX)
	  while(vct--) {
	    aroom = &rooms[rn2(nroom-1)];
	    if(aroom->rtype != 0) continue;	/* not an ordinary room */
	    if(rn2(2)) {
		dy = 1;
		dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1);
	    } else {
		dy = -1;
		dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1);
	    }
	    xx = dd.x;
	    yy = dd.y;
	    if((rm = &levl[xx][yy+dy])->typ) continue;
	    if(with_trap || !rn2(4)) {
		rm->typ = SCORR;
		rm->scrsym = ' ';
		if(with_trap) {
		    gtmp = newgen();
		    gtmp->gx = xx;
		    gtmp->gy = yy+dy;
		    gtmp->gflag = TELEP_TRAP | ONCE;
		    gtmp->ngen = ftrap;
		    ftrap = gtmp;
		    make_engr_at(xx,yy-dy,"ad ae?ar um");
		}
		dosdoor(xx,yy,aroom,SDOOR);
	    } else {
		rm->typ = CORR;
		rm->scrsym = CORR_SYM;
		if(rn2(7))
		    dosdoor(xx,yy,aroom,rn2(5) ? SDOOR : DOOR);
		else {
		    mksobj_at(SCROLL_SYM,SCR_TELEPORTATION,xx,yy+dy);
		    if(!rn2(3)) mkobj_at(0,xx,yy+dy);
		}
	    }
	    return;
      }
}

/* make a trap somewhere (in croom if mazeflag = 0) */
mktrap(num,mazeflag)
register int num,mazeflag;
{
	register struct gen *gtmp;
	register int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0;
	register xchar mx,my;


   if(!num || num >= TRAPNUM) {
      nopierc = (dlevel < 4) ? 1 : 0;
      nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
      if(index(fut_geno, 'M')) nomimic = 1;
      kind = rn2(TRAPNUM - nopierc - nomimic);
      /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
   } else kind = num;

   if(kind == MIMIC) {
		register struct monst *mtmp;

      fakedoor = (!rn2(3) && !mazeflag);
      fakegold = (!fakedoor && !rn2(2));
      if(fakegold) goldseen = TRUE;
      do {
         if(++tryct > 200) return;
         if(fakedoor) {
            /* note: fakedoor maybe on actual door */
            if(rn2(2)){
               if(rn2(2))
                  mx = croom->hx+1;
               else mx = croom->lx-1;
               my = somey();
            } else {
               if(rn2(2))
                  my = croom->hy+1;
               else my = croom->ly-1;
               mx = somex();
            }
         } else if(mazeflag) {
            extern coord mazexy();
            coord mm;
            mm = mazexy();
            mx = mm.x;
            my = mm.y;
         } else {
            mx = somex();
            my = somey();
         }
      } while(m_at(mx,my));
      if(mtmp = makemon(PM_MIMIC,mx,my))
          mtmp->mimic =
         fakegold ? '$' : fakedoor ? '+' :
         (mazeflag && rn2(2)) ? AMULET_SYM :
         "=/)%?![<>" [ rn2(9) ];
      return;
   }
   gtmp = newgen();
   gtmp->gflag = kind;
   do {
      if(++tryct > 200){
         free((char *) gtmp);
         return;
      }
      if(mazeflag){
         extern coord mazexy();
         coord mm;
         mm = mazexy();
         gtmp->gx = mm.x;
         gtmp->gy = mm.y;
      } else {
         gtmp->gx = somex();
         gtmp->gy = somey();
      }
   } while(g_at(gtmp->gx, gtmp->gy, ftrap));
   gtmp->ngen = ftrap;
   ftrap = gtmp;
   if(mazeflag && !rn2(10) && gtmp->gflag < PIERC) gtmp->gflag |= SEEN;
}

#ifdef DEBUG
dumpit()
   {
   int x, y;
   struct rm *room;

   cgetret(); 

   /* kludge in making everything visible */
   for(y=0; y < ROWNO; y++)
      for(x=0; x < COLNO-3; x++)
         if ( (room = &levl[x][y])->typ)
            at(x,y, (room->scrsym) ? room->scrsym : '?');
   }
#endif
#file mklv.makemaz.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */

#include "mklev.h"
extern struct monst *makemon();
extern coord mazexy();

makemaz()
{
	int x,y;
	register int zx,zy;
	coord mm;

	for(x = 2; x < COLNO-1; x++)
		for(y = 2; y < ROWNO-1; y++)
			levl[x][y].typ = (x%2 && y%2) ? 0 : HWALL;
	mm = mazexy();
	zx = mm.x;
	zy = mm.y;
	walkfrom(zx,zy);
	mkobj_at(AMULET_SYM, zx, zy);
	mkobj_at(ROCK_SYM, zx, zy);	/* put a rock on top of the amulet */
	/* (probably this means that one needs a wand of digging to reach 
	    the amulet - we must make sure that the player has a chance of
	    getting one; let us say when he kills the minotaur; of course
	    the minotaur itself may be blocked behind rocks, but well...) */
	for(x = 2; x < COLNO-1; x++)
		for(y = 2; y < ROWNO-1; y++) {
			switch(levl[x][y].typ) {
			case HWALL:
				levl[x][y].scrsym = '-';
				break;
			case ROOM:
				levl[x][y].scrsym = '.';
				break;
			}
		}
	for(x = rn1(8,11); x; x--) {
		mm = mazexy();
		mkobj_at(0, mm.x, mm.y);
	}
	for(x = rn1(10,2); x; x--) {
		mm = mazexy();
		mkobj_at(ROCK_SYM, mm.x, mm.y);
	}
	mm = mazexy();
	(void) makemon(PM_MINOTAUR, mm.x, mm.y);
	for(x = rn1(5,7); x; x--) {
		mm = mazexy();
		(void) makemon((struct permonst *) 0, mm.x, mm.y);
	}
	for(x = rn1(6,7); x; x--) {
		mm = mazexy();
		mkgold(0,mm.x,mm.y);
	}
	for(x = rn1(6,7); x; x--)
		mktrap(0,1);
	mm = mazexy();
	levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = '<';
	levl[xupstair][yupstair].typ = STAIRS;
	xdnstair = ydnstair = 0;
}

walkfrom(x,y) int x,y; {
register int q,a,dir;
int dirs[4];
	levl[x][y].typ = ROOM;
	while(1) {
		q = 0;
		for(a = 0; a < 4; a++)
			if(okay(x,y,a)) dirs[q++]= a;
		if(!q) return;
		dir = dirs[rn2(q)];
		move(&x,&y,dir);
		levl[x][y].typ = ROOM;
		move(&x,&y,dir);
		walkfrom(x,y);
	}
}

move(x,y,dir)
register int *x, *y;
register int dir;
{
	switch(dir){
		case 0: --(*y); break;
		case 1: (*x)++; break;
		case 2: (*y)++; break;
		case 3: --(*x); break;
	}
}

okay(x,y,dir)
int x,y;
register int dir;
{
	move(&x,&y,dir);
	move(&x,&y,dir);
	if(x<3 || y<3 || x>COLNO-3 || y>ROWNO-3 || levl[x][y].typ != 0)
		return(0);
	else
		return(1);
}

coord
mazexy(){
	coord mm;
	mm.x = 3 + 2*rn2(COLNO/2 - 2);
	mm.y = 3 + 2*rn2(ROWNO/2 - 2);
	return mm;
}
#file mklv.shk.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */

#ifndef QUEST
#include "mklev.h"
#include "def.eshk.h"
#define   ESHK   ((struct eshk *)(&(shk->mextra[0])))
extern struct monst *makemon();

extern char shtypes[]; /* = "=/)%?!["; ** 8 shoptypes: 7 specialised, 1 mixed */
schar shprobs[] = { 3,3,5,5,10,10,14,50 };   /* their probabilities */

mkshop(){
register struct mkroom *sroom;
register int sh,sx,sy,i;
register char let;
int roomno;
register struct monst *shk;
   for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
      if(sroom->hx < 0) return;
      if(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
         sroom->ly <= ydnstair && ydnstair <= sroom->hy) continue;
      if(sroom->lx <= xupstair && xupstair <= sroom->hx &&
         sroom->ly <= yupstair && yupstair <= sroom->hy) continue;
      if(
#ifdef WIZARD
         wizard ||
#endif WIZARD
         sroom->doorct == 1) break;
   }
#ifdef WIZARD
   if(wizard){
      extern char *getenv();
      register char *ep = getenv("SHOPTYPE");
      if(ep){
         if(*ep == 'z' || *ep == 'Z'){
            mkzoo();
            return;
         }
         for(i=0; shtypes[i]; i++)
            if(*ep == shtypes[i]) break;
         let = i;
         goto gotlet;
      }
   }
#endif WIZARD
   for(i = rn2(100),let = 0; (i -= shprobs[let])>= 0; let++)
      if(!shtypes[let]) break;   /* superfluous */
#ifdef WIZARD
gotlet:
#endif WIZARD
   sroom->rtype = 8+let;
   let = shtypes[let];
   sh = sroom->fdoor;
   sx = doors[sh].x;
   sy = doors[sh].y;
   if(sx == sroom->lx-1) sx++; else
   if(sx == sroom->hx+1) sx--; else
   if(sy == sroom->ly-1) sy++; else
   if(sy == sroom->hy+1) sy--; else {
      myprintf("Where is shopdoor?");
      return;
   }
   if(!(shk = makemon(PM_SHK,sx,sy))) return;
   shk->isshk = shk->mpeaceful = 1;
   shk->msleep = 0;
   shk->mtrapseen = ~0;   /* we know all the traps already */
   ESHK->shoproom = roomno;
   ESHK->shd = doors[sh];
   ESHK->shk.x = sx;
   ESHK->shk.y = sy;
   ESHK->robbed = 0;
   ESHK->visitct = 0;
   shk->mgold = 1000 + 30*rnd(100);   /* initial capital */
   ESHK->billct = 0;
   findname(ESHK->shknam, let);
   for(sx = sroom->lx; sx <= sroom->hx; sx++)
   for(sy = sroom->ly; sy <= sroom->hy; sy++){
      register struct monst *mtmp;
      if((sx == sroom->lx && doors[sh].x == sx-1) ||
         (sx == sroom->hx && doors[sh].x == sx+1) ||
         (sy == sroom->ly && doors[sh].y == sy-1) ||
         (sy == sroom->hy && doors[sh].y == sy+1)) continue;
      if(rn2(100) < dlevel && !m_at(sx,sy) &&
         (mtmp = makemon(PM_MIMIC, sx, sy))){
         mtmp->mimic =
             (let && rn2(10) < dlevel) ? let : ']';
         continue;
      }
      mkobj_at(let, sx, sy);
   }
#ifdef WIZARD
   if(wizard) myprintf("I made a %c-shop.", let ? let : 'g');
#endif WIZARD
}

mkzoo(){
register struct mkroom *sroom;
register int sh,sx,sy,i;
int goldlim = 500 * dlevel;
   for(sroom = &rooms[0]; ; sroom++){
      if(sroom->hx < 0) return;
      if(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
         sroom->ly <= ydnstair && ydnstair <= sroom->hy) continue;
      if(sroom->lx <= xupstair && xupstair <= sroom->hx &&
         sroom->ly <= yupstair && yupstair <= sroom->hy) continue;
      if(sroom->doorct == 1) break;
   }
   sroom->rtype = 7;
   sh = sroom->fdoor;
   for(sx = sroom->lx; sx <= sroom->hx; sx++)
   for(sy = sroom->ly; sy <= sroom->hy; sy++){
      if((sx == sroom->lx && doors[sh].x == sx-1) ||
         (sx == sroom->hx && doors[sh].x == sx+1) ||
         (sy == sroom->ly && doors[sh].y == sy-1) ||
         (sy == sroom->hy && doors[sh].y == sy+1)) continue;
      (void) makemon((struct permonst *) 0,sx,sy);
      i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
      if(i >= goldlim) i = 5*dlevel;
      goldlim -= i;
      mkgold(10 + rn2(i), sx, sy);
   }
#ifdef WIZARD
   if(wizard) myprintf("I made a zoo.");
#endif WIZARD
}

dist2(x0,y0,x1,y1){
   return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
}

sq(a) int a; {
   return(a*a);
}
#endif QUEST
#file mklv.shknam.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */



#include "mklev.h"



char *shkliquors[] = {

	/* Ukraine */

	"Njezjin", "Tsjernigof", "Gomel", "Ossipewsk", "Gorlowka",

	/* N. Russia */

	"Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja",

	"Narodnaja", "Kyzyl",

	/* Silezie */

	"Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice",

	"Brzeg", "Krnov", "Hradec Kralove",

	/* Schweiz */

	"Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm",

	"Flims", "Vals", "Schuls", "Zum Loch",

	0

};



char *shkbooks[] = {

	/* Eire */

	"Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch",

	"Loughrea", "Croagh", "Maumakeogh", "Ballyjamesduff",

	"Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra",

	"Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan",

	"Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh",

	"Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea",

	"Culdaff", "Dunfanaghy", "Inishbofin", "Kesh",

	0

};



char *shkarmors[] = {

	/* Turquie */

	"Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep",

	"Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak",

	"Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt",

	"Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni",

	"Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat",

	"Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan",

	0

};



char *shkwands[] = {

	/* Wales */

	"Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach",

	"Rhaeader", "Llandrindod", "Llanfair-ym-muallt",

	"Y-Fenni", "Measteg", "Rhydaman", "Beddgelert",

	"Curig", "Llanrwst", "Llanerchymedd", "Caergybi",

	/* Scotland */

	"Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar",

	"Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven",

	"Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch",

	"Kyleakin", "Dunvegan",

	0

};



char *shkrings[] = {

	/* Hollandse familienamen */

	"Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken",

	"Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy",

	"Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix",

	"Ypey",

	/* Skandinaviske navne */

	"Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",

	"Enontekis", "Rovaniemi", "Avasaksa", "Haparanda",

	"Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske",

	0

};



char *shkfoods[] = {

	/* Indonesia */

	"Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan",

	"Bandjar", "Parbalingga", "Bojolali", "Sarangan",

	"Ngebel", "Djombang", "Ardjawinangun", "Berbek",

	"Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi",

	"Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan",

	"Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe",

	"Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe",

	0

};



char *shkweapons[] = {

	/* Perigord */

	"Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard",

	"Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac",

	"Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac",

	"Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac",

	"Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon",

	"Eymoutiers", "Eygurande", "Eauze", "Labouheyre",

	0

};



char *shkgeneral[] = {

	/* Suriname */

	"Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi",

	"Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo",

	"Akalapi", "Sipaliwini",

	/* Greenland */

	"Annootok", "Upernavik", "Angmagssalik",

	/* N. Canada */

	"Aklavik", "Inuvik", "Tuktoyaktuk",

	"Chicoutimi", "Ouiatchouane", "Chibougamau",

	"Matagami", "Kipawa", "Kinojevis",

	"Abitibi", "Maganasipi",

	/* Iceland */

	"Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri",

	"Holmavik",

	0

};



struct shk_nx {

	char x;

	char **xn;

} shk_nx[] = {

	{ POTION_SYM,	shkliquors },

	{ SCROLL_SYM,	shkbooks },

	{ ARMOR_SYM,	shkarmors },

	{ WAND_SYM,	shkwands },

	{ RING_SYM,	shkrings },

	{ FOOD_SYM,	shkfoods },

	{ WEAPON_SYM,	shkweapons },

	{ 0,		shkgeneral }

};



findname(nampt, let) char *nampt; char let; {

register struct shk_nx *p = shk_nx;

register char **q;

register int i;

	while(p->x && p->x != let) p++;

	q = p->xn;

	for(i=0; i<dlevel; i++) if(!q[i]){

		/* Not enough names, try general name */

		if(let) findname(nampt, 0);

		else (void) strcpy(nampt, "Dirk");

		return;

	}

	(void) strncpy(nampt, q[i], PL_NSIZ);

	nampt[PL_NSIZ-1] = 0;

}

#file rnd.c
#define RND(x)	((rand()>>3) % x)

rn1(x,y)
register int x,y;
{
	return(RND(x)+y);
}

rn2(x)
register int x;
{
	return(RND(x));
}

rnd(x)
register int x;
{
	return(RND(x)+1);
}

d(n,x)
register int n,x;
{
	register int tmp = n;

	while(n--) tmp += RND(x);
	return(tmp);
}
#file savelev.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* savelev.h version 1.0.1 - also save engravings from MKLEV */

#include "hack.h"
#include <stdio.h>
extern struct monst *restmonchn();
extern struct obj *restobjchn();
extern struct obj *billobjs;
extern char *itoa();

extern char nul[];
#ifndef NOWORM
#include	"def.wseg.h"

extern struct wseg *wsegs[32], *wheads[32];
extern long wgrowtime[32];
#endif NOWORM

savelev(fd){
#ifndef NOWORM
	register struct wseg *wtmp, *wtmp2;
	register int tmp;
#endif NOWORM

	if(fd < 0)
           panic("Save on bad file!");

	bwrite(fd,(char *) levl,sizeof(levl));
	bwrite(fd,(char *) &moves,sizeof(long));
	bwrite(fd,(char *) &xupstair,sizeof(xupstair));
	bwrite(fd,(char *) &yupstair,sizeof(yupstair));
	bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
	bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
	savemonchn(fd, fmon);
	savegenchn(fd, fgold);
	savegenchn(fd, ftrap);
	saveobjchn(fd, fobj);
	saveobjchn(fd, billobjs);
/*	if (!ismklev) */
	   billobjs = 0;
	save_engravings(fd);
#ifndef QUEST
	bwrite(fd,(char *) rooms,sizeof(rooms));
	bwrite(fd,(char *) doors,sizeof(doors));
#endif QUEST
/* 	if (!ismklev) */
	   {
	   fgold = ftrap = 0;
	   fmon = 0;
	   fobj = 0;
	   }
/*--------------------------------------------------------------------*/
#ifndef NOWORM
	bwrite(fd,(char *) wsegs,sizeof(wsegs));
	for(tmp=1; tmp<32; tmp++){
		for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
			wtmp2 = wtmp->nseg;
			bwrite(fd,(char *) wtmp,sizeof(struct wseg));
		}
/*		if (!ismklev) */
		   wsegs[tmp] = 0;
	}
	bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
#endif NOWORM
/*--------------------------------------------------------------------*/
}

bwrite(fd,loc,num)
register int fd;
register char *loc;
register unsigned num;
{
/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
	if(write(fd, loc, (int) num) != num)
		panic("cannot write %d bytes to file #%d",num,fd);
}

saveobjchn(fd,otmp)
register int fd;
register struct obj *otmp;
{
	register struct obj *otmp2;
	unsigned xl;
	int minusone = -1;

	while(otmp) {
		otmp2 = otmp->nobj;
		xl = otmp->onamelth;
		bwrite(fd, (char *) &xl, sizeof(int));
		bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
/*		if (!ismklev) */
			free((char *) otmp);
		otmp = otmp2;
	}
	bwrite(fd, (char *) &minusone, sizeof(int));
}

savemonchn(fd,mtmp)
register int fd;
register struct monst *mtmp;
{
	register struct monst *mtmp2;
	unsigned xl;
	int minusone = -1;
	int monnum;
#ifdef FUNNYRELOC
	struct permonst *monbegin = &mons[0];

	bwrite(fd, (char *) &monbegin, sizeof(monbegin));
#endif

	while(mtmp) {
		mtmp2 = mtmp->nmon;
		xl = mtmp->mxlth + mtmp->mnamelth;
		bwrite(fd, (char *) &xl, sizeof(int));

		/* JAT - just save the offset into the monster table, */
		/* it will be relocated when read in */
		monnum = mtmp->data - &mons[0];
		mtmp->data = (struct permonst *)monnum;
#ifdef DEBUGMON
		myprintf("Wrote monster #%d", monnum);
#endif
		bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
		if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
/*		if (!ismklev) */
		   free((char *) mtmp);
		mtmp = mtmp2;
	}
	bwrite(fd, (char *) &minusone, sizeof(int));
}

savegenchn(fd,gtmp)
register int fd;
register struct gen *gtmp;
{
	register struct gen *gtmp2;
	while(gtmp) {
		gtmp2 = gtmp->ngen;
		bwrite(fd, (char *) gtmp, sizeof(struct gen));
/*		if (!ismklev) */
		   free((char *) gtmp);
		gtmp = gtmp2;
	}
	bwrite(fd, nul, sizeof(struct gen));
}



More information about the Comp.sources.unix mailing list