⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hack.mklev.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. *//* hack.mklev.c - version 1.0.3 */#include "hack.h"extern char *getlogin(), *getenv();extern struct monst *makemon();extern struct obj *mkobj_at();extern struct trap *maketrap();#define somex() ((random()%(croom->hx-croom->lx+1))+croom->lx)#define somey() ((random()%(croom->hy-croom->ly+1))+croom->ly)#include "def.mkroom.h"#define	XLIM	4	/* define minimum required space around a room */#define	YLIM	3boolean secret;		/* TRUE while making a vault: increase [XY]LIM */struct mkroom rooms[MAXNROFROOMS+1];int smeq[MAXNROFROOMS+1];coord doors[DOORMAX];int doorindex;struct rm zerorm;int comp();schar nxcor;boolean goldseen;int nroom;xchar xdnstair,xupstair,ydnstair,yupstair;/* Definitions used by makerooms() and addrs() */#define	MAXRS	50	/* max lth of temp rectangle table - arbitrary */struct rectangle {	xchar rlx,rly,rhx,rhy;} rs[MAXRS+1];int rscnt,rsmax;	/* 0..rscnt-1: currently under consideration */			/* rscnt..rsmax: discarded */makelevel(){	register struct mkroom *croom, *troom;	register unsigned tryct;	register x,y;	nroom = 0;	doorindex = 0;	rooms[0].hx = -1;	/* in case we are in a maze */	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)		levl[x][y] = zerorm;	oinit();	/* assign level dependent obj probabilities */	if(dlevel >= rn1(3, 26)) {	/* there might be several mazes */		makemaz();		return;	}	/* construct the rooms */	nroom = 0;	secret = FALSE;	(void) makerooms();	/* construct stairs (up and down in different rooms if possible) */	croom = &rooms[rn2(nroom)];	xdnstair = somex();	ydnstair = somey();	levl[xdnstair][ydnstair].scrsym ='>';	levl[xdnstair][ydnstair].typ = STAIRS;	if(nroom > 1) {		troom = croom;		croom = &rooms[rn2(nroom-1)];		if(croom >= troom) croom++;	}	xupstair = somex();	/* %% < and > might be in the same place */	yupstair = somey();	levl[xupstair][yupstair].scrsym ='<';	levl[xupstair][yupstair].typ = STAIRS;	/* for each room: put things inside */	for(croom = rooms; croom->hx > 0; croom++) {		/* put a sleeping monster inside */		/* Note: monster may be on the stairs. This cannot be		   avoided: maybe the player fell through a trapdoor		   while a monster was on the stairs. Conclusion:		   we have to check for monsters on the stairs anyway. */		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,croom);		if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey());		if(!rn2(3)) {			(void) mkobj_at(0, somex(), somey());			tryct = 0;			while(!rn2(5)) {				if(++tryct > 100){					printf("tryct overflow4\n");					break;				}				(void) mkobj_at(0, somex(), somey());			}		}	}	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)) {		troom = &rooms[nroom];		secret = TRUE;		if(makerooms()) {			troom->rtype = VAULT;		/* treasure vault */			for(x = troom->lx; x <= troom->hx; x++)			for(y = troom->ly; y <= troom->hy; y++)				mkgold((long)(rnd(dlevel*100) + 50), x, y);			if(!rn2(3))				makevtele();		}	}#ifndef QUEST#ifdef WIZARD	if(wizard && getenv("SHOPTYPE")) mkshop(); else#endif WIZARD 	if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop();	else	if(dlevel > 6 && !rn2(7)) mkzoo(ZOO);	else	if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE);	else	if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE);	else	if(dlevel > 18 && !rn2(6)) mkswamp();#endif QUEST}makerooms() {register struct rectangle *rsp;register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;int tryct = 0, xlim, ylim;	/* init */	xlim = XLIM + secret;	ylim = YLIM + secret;	if(nroom == 0) {		rsp = rs;		rsp->rlx = rsp->rly = 0;		rsp->rhx = COLNO-1;		rsp->rhy = ROWNO-1;		rsmax = 1;	}	rscnt = rsmax;	/* make rooms until satisfied */	while(rscnt > 0 && nroom < MAXNROFROOMS-1) {		if(!secret && nroom > (MAXNROFROOMS/3) &&		   !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))			return(0);		/* pick a rectangle */		rsp = &rs[rn2(rscnt)];		hx = rsp->rhx;		hy = rsp->rhy;		lx = rsp->rlx;		ly = rsp->rly;		/* find size of room */		if(secret)			dx = dy = 1;		else {			dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);			dy = 2 + rn2(4);			if(dx*dy > 50)				dy = 50/dx;		}		/* look whether our room will fit */		if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) {					/* no, too small */					/* maybe we throw this area out */			if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {				rscnt--;				rs[rsmax] = *rsp;				*rsp = rs[rscnt];				rs[rscnt] = rs[rsmax];				tryct = 0;			} else				tryct++;			continue;		}		lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);		lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);		hix = lowx + dx;		hiy = lowy + dy;		if(maker(lowx, dx, lowy, dy)) {			if(secret)				return(1);			addrs(lowx-1, lowy-1, hix+1, hiy+1);			tryct = 0;		} else			if(tryct++ > 100)				break;	}	return(0);	/* failed to make vault - very strange */}addrs(lowx,lowy,hix,hiy)register int lowx,lowy,hix,hiy;{	register struct rectangle *rsp;	register int lx,ly,hx,hy,xlim,ylim;	boolean discarded;	xlim = XLIM + secret;	ylim = YLIM + secret;	/* walk down since rscnt and rsmax change */	for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {				if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||		   (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)			continue;		if((discarded = (rsp >= &rs[rscnt]))) {			*rsp = rs[--rsmax];		} else {			rsmax--;			rscnt--;			*rsp = rs[rscnt];			if(rscnt != rsmax)				rs[rscnt] = rs[rsmax];		}		if(lowy - ly > 2*ylim + 4)			addrsx(lx,ly,hx,lowy-2,discarded);		if(lowx - lx > 2*xlim + 4)			addrsx(lx,ly,lowx-2,hy,discarded);		if(hy - hiy > 2*ylim + 4)			addrsx(lx,hiy+2,hx,hy,discarded);		if(hx - hix > 2*xlim + 4)			addrsx(hix+2,ly,hx,hy,discarded);	}}addrsx(lx,ly,hx,hy,discarded)register int lx,ly,hx,hy;boolean discarded;		/* piece of a discarded area */{	register struct rectangle *rsp;	/* check inclusions */	for(rsp = rs; rsp < &rs[rsmax]; rsp++) {		if(lx >= rsp->rlx && hx <= rsp->rhx &&		   ly >= rsp->rly && hy <= rsp->rhy)			return;	}	/* make a new entry */	if(rsmax >= MAXRS) {#ifdef WIZARD		if(wizard) pline("MAXRS may be too small.");#endif WIZARD		return;	}	rsmax++;	if(!discarded) {		*rsp = rs[rscnt];		rsp = &rs[rscnt];		rscnt++;	}	rsp->rlx = lx;	rsp->rly = ly;	rsp->rhx = hx;	rsp->rhy = hy;}comp(x,y)register struct mkroom *x,*y;{	if(x->lx < y->lx) return(-1);	return(x->lx > y->lx);}coordfinddpos(xl,yl,xh,yh) {	coord ff;	register x,y;	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));	if(okdoor(x, y))		goto gotit;	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)		if(okdoor(x, y))			goto gotit;	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)		if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR)			goto gotit;	/* cannot find something reasonable -- strange */	x = xl;	y = yh;gotit:	ff.x = x;	ff.y = y;	return(ff);}/* see whether it is allowable to create a door at [x,y] */okdoor(x,y)register 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 x,y;register struct mkroom *aroom;{	if(doorindex >= DOORMAX) {		impossible("DOORMAX exceeded?");		return;	}	if(!okdoor(x,y) && nxcor)		return;	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);}dosdoor(x,y,aroom,type)register x,y;register struct mkroom *aroom;register type;{	register struct mkroom *broom;	register tmp;	if(!IS_WALL(levl[x][y].typ))	/* avoid SDOORs with '+' as scrsym */		type = DOOR;	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 struct mkroom *croom;	register x, y, hix = lowx+ddx, hiy = lowy+ddy;	register xlim = XLIM + secret, ylim = YLIM + secret;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -