Home | History | Annotate | Line # | Download | only in larn
create.c revision 1.6
      1  1.6  christos /* $NetBSD: create.c,v 1.6 1997/10/18 20:03:09 christos Exp $	 */
      2  1.6  christos 
      3  1.6  christos /* create.c		Larn is copyrighted 1986 by Noah Morgan. */
      4  1.6  christos 
      5  1.6  christos #include <sys/cdefs.h>
      6  1.2   mycroft #ifndef lint
      7  1.6  christos __RCSID("$NetBSD: create.c,v 1.6 1997/10/18 20:03:09 christos Exp $");
      8  1.6  christos #endif				/* not lint */
      9  1.2   mycroft 
     10  1.1       cgd #include "header.h"
     11  1.6  christos #include "extern.h"
     12  1.6  christos #include <unistd.h>
     13  1.6  christos static void fillroom __P((int, int));
     14  1.6  christos 
     15  1.1       cgd /*
     16  1.1       cgd 	makeplayer()
     17  1.1       cgd 
     18  1.1       cgd 	subroutine to create the player and the players attributes
     19  1.1       cgd 	this is called at the beginning of a game and at no other time
     20  1.1       cgd  */
     21  1.6  christos void
     22  1.1       cgd makeplayer()
     23  1.6  christos {
     24  1.6  christos 	int i;
     25  1.6  christos 	scbr();
     26  1.6  christos 	clear();
     27  1.6  christos 	c[HPMAX] = c[HP] = 10;	/* start player off with 15 hit points	 */
     28  1.6  christos 	c[LEVEL] = 1;		/* player starts at level one		 */
     29  1.6  christos 	c[SPELLMAX] = c[SPELLS] = 1;	/* total # spells starts off as 3 */
     30  1.6  christos 	c[REGENCOUNTER] = 16;
     31  1.6  christos 	c[ECOUNTER] = 96;	/* start regeneration correctly */
     32  1.1       cgd 	c[SHIELD] = c[WEAR] = c[WIELD] = -1;
     33  1.6  christos 	for (i = 0; i < 26; i++)
     34  1.6  christos 		iven[i] = 0;
     35  1.6  christos 	spelknow[0] = spelknow[1] = 1;	/* he knows protection, magic missile */
     36  1.6  christos 	if (c[HARDGAME] <= 0) {
     37  1.6  christos 		iven[0] = OLEATHER;
     38  1.6  christos 		iven[1] = ODAGGER;
     39  1.6  christos 		ivenarg[1] = ivenarg[0] = c[WEAR] = 0;
     40  1.6  christos 		c[WIELD] = 1;
     41  1.6  christos 	}
     42  1.6  christos 	playerx = rnd(MAXX - 2);
     43  1.6  christos 	playery = rnd(MAXY - 2);
     44  1.6  christos 	oldx = 0;
     45  1.6  christos 	oldy = 25;
     46  1.6  christos 	gltime = 0;		/* time clock starts at zero	 */
     47  1.1       cgd 	cbak[SPELLS] = -50;
     48  1.6  christos 	for (i = 0; i < 6; i++)
     49  1.6  christos 		c[i] = 12;	/* make the attributes, ie str, int, etc. */
     50  1.1       cgd 	recalc();
     51  1.6  christos }
     52  1.6  christos 
     53  1.6  christos 
     54  1.1       cgd /*
     55  1.1       cgd 	newcavelevel(level)
     56  1.1       cgd 	int level;
     57  1.1       cgd 
     58  1.1       cgd 	function to enter a new level.  This routine must be called anytime the
     59  1.1       cgd 	player changes levels.  If that level is unknown it will be created.
     60  1.1       cgd 	A new set of monsters will be created for a new level, and existing
     61  1.1       cgd 	levels will get a few more monsters.
     62  1.1       cgd 	Note that it is here we remove genocided monsters from the present level.
     63  1.1       cgd  */
     64  1.6  christos void
     65  1.1       cgd newcavelevel(x)
     66  1.6  christos 	int             x;
     67  1.6  christos {
     68  1.6  christos 	int             i, j;
     69  1.6  christos 	if (beenhere[level])
     70  1.6  christos 		savelevel();	/* put the level back into storage	 */
     71  1.6  christos 	level = x;		/* get the new level and put in working
     72  1.6  christos 				 * storage */
     73  1.6  christos 	if (beenhere[x] == 0)
     74  1.6  christos 		for (i = 0; i < MAXY; i++)
     75  1.6  christos 			for (j = 0; j < MAXX; j++)
     76  1.6  christos 				know[j][i] = mitem[j][i] = 0;
     77  1.6  christos 	else {
     78  1.6  christos 		getlevel();
     79  1.6  christos 		sethp(0);
     80  1.6  christos 		goto chgn;
     81  1.6  christos 	}
     82  1.6  christos 	makemaze(x);
     83  1.6  christos 	makeobject(x);
     84  1.6  christos 	beenhere[x] = 1;
     85  1.6  christos 	sethp(1);
     86  1.1       cgd 
     87  1.1       cgd #if WIZID
     88  1.6  christos 	if (wizard || x == 0)
     89  1.1       cgd #else
     90  1.6  christos 	if (x == 0)
     91  1.1       cgd #endif
     92  1.1       cgd 
     93  1.6  christos 		for (j = 0; j < MAXY; j++)
     94  1.6  christos 			for (i = 0; i < MAXX; i++)
     95  1.6  christos 				know[i][j] = 1;
     96  1.6  christos chgn:	checkgen();		/* wipe out any genocided monsters */
     97  1.6  christos }
     98  1.1       cgd 
     99  1.1       cgd /*
    100  1.1       cgd 	makemaze(level)
    101  1.1       cgd 	int level;
    102  1.1       cgd 
    103  1.1       cgd 	subroutine to make the caverns for a given level.  only walls are made.
    104  1.1       cgd  */
    105  1.6  christos static int      mx, mxl, mxh, my, myl, myh, tmp2;
    106  1.6  christos void
    107  1.6  christos makemaze(k)
    108  1.6  christos 	int             k;
    109  1.6  christos {
    110  1.6  christos 	int             i, j, tmp;
    111  1.6  christos 	int             z;
    112  1.6  christos 	if (k > 1 && (rnd(17) <= 4 || k == MAXLEVEL - 1 || k == MAXLEVEL + MAXVLEVEL - 1)) {
    113  1.6  christos 		if (cannedlevel(k));
    114  1.6  christos 		return;		/* read maze from data file */
    115  1.6  christos 	}
    116  1.6  christos 	if (k == 0)
    117  1.6  christos 		tmp = 0;
    118  1.6  christos 	else
    119  1.6  christos 		tmp = OWALL;
    120  1.6  christos 	for (i = 0; i < MAXY; i++)
    121  1.6  christos 		for (j = 0; j < MAXX; j++)
    122  1.6  christos 			item[j][i] = tmp;
    123  1.6  christos 	if (k == 0)
    124  1.6  christos 		return;
    125  1.6  christos 	eat(1, 1);
    126  1.6  christos 	if (k == 1)
    127  1.6  christos 		item[33][MAXY - 1] = 0;	/* exit from dungeon */
    128  1.6  christos 
    129  1.6  christos 	/* now for open spaces -- not on level 10	 */
    130  1.6  christos 	if (k != MAXLEVEL - 1) {
    131  1.6  christos 		tmp2 = rnd(3) + 3;
    132  1.6  christos 		for (tmp = 0; tmp < tmp2; tmp++) {
    133  1.6  christos 			my = rnd(11) + 2;
    134  1.6  christos 			myl = my - rnd(2);
    135  1.6  christos 			myh = my + rnd(2);
    136  1.6  christos 			if (k < MAXLEVEL) {
    137  1.6  christos 				mx = rnd(44) + 5;
    138  1.6  christos 				mxl = mx - rnd(4);
    139  1.6  christos 				mxh = mx + rnd(12) + 3;
    140  1.6  christos 				z = 0;
    141  1.6  christos 			} else {
    142  1.6  christos 				mx = rnd(60) + 3;
    143  1.6  christos 				mxl = mx - rnd(2);
    144  1.6  christos 				mxh = mx + rnd(2);
    145  1.1       cgd 				z = makemonst(k);
    146  1.6  christos 			}
    147  1.6  christos 			for (i = mxl; i < mxh; i++)
    148  1.6  christos 				for (j = myl; j < myh; j++) {
    149  1.6  christos 					item[i][j] = 0;
    150  1.6  christos 					if ((mitem[i][j] = z))
    151  1.6  christos 						hitp[i][j] = monster[z].hitpoints;
    152  1.1       cgd 				}
    153  1.1       cgd 		}
    154  1.1       cgd 	}
    155  1.6  christos 	if (k != MAXLEVEL - 1) {
    156  1.6  christos 		my = rnd(MAXY - 2);
    157  1.6  christos 		for (i = 1; i < MAXX - 1; i++)
    158  1.6  christos 			item[i][my] = 0;
    159  1.6  christos 	}
    160  1.6  christos 	if (k > 1)
    161  1.6  christos 		treasureroom(k);
    162  1.6  christos }
    163  1.1       cgd 
    164  1.1       cgd /*
    165  1.1       cgd 	function to eat away a filled in maze
    166  1.1       cgd  */
    167  1.6  christos void
    168  1.6  christos eat(xx, yy)
    169  1.6  christos 	int             xx, yy;
    170  1.6  christos {
    171  1.6  christos 	int             dir, try;
    172  1.6  christos 	dir = rnd(4);
    173  1.6  christos 	try = 2;
    174  1.6  christos 	while (try) {
    175  1.6  christos 		switch (dir) {
    176  1.6  christos 		case 1:
    177  1.6  christos 			if (xx <= 2)
    178  1.6  christos 				break;	/* west	 */
    179  1.6  christos 			if ((item[xx - 1][yy] != OWALL) || (item[xx - 2][yy] != OWALL))
    180  1.6  christos 				break;
    181  1.6  christos 			item[xx - 1][yy] = item[xx - 2][yy] = 0;
    182  1.6  christos 			eat(xx - 2, yy);
    183  1.6  christos 			break;
    184  1.6  christos 
    185  1.6  christos 		case 2:
    186  1.6  christos 			if (xx >= MAXX - 3)
    187  1.6  christos 				break;	/* east	 */
    188  1.6  christos 			if ((item[xx + 1][yy] != OWALL) || (item[xx + 2][yy] != OWALL))
    189  1.6  christos 				break;
    190  1.6  christos 			item[xx + 1][yy] = item[xx + 2][yy] = 0;
    191  1.6  christos 			eat(xx + 2, yy);
    192  1.6  christos 			break;
    193  1.6  christos 
    194  1.6  christos 		case 3:
    195  1.6  christos 			if (yy <= 2)
    196  1.6  christos 				break;	/* south	 */
    197  1.6  christos 			if ((item[xx][yy - 1] != OWALL) || (item[xx][yy - 2] != OWALL))
    198  1.6  christos 				break;
    199  1.6  christos 			item[xx][yy - 1] = item[xx][yy - 2] = 0;
    200  1.6  christos 			eat(xx, yy - 2);
    201  1.6  christos 			break;
    202  1.6  christos 
    203  1.6  christos 		case 4:
    204  1.6  christos 			if (yy >= MAXY - 3)
    205  1.6  christos 				break;	/* north	 */
    206  1.6  christos 			if ((item[xx][yy + 1] != OWALL) || (item[xx][yy + 2] != OWALL))
    207  1.6  christos 				break;
    208  1.6  christos 			item[xx][yy + 1] = item[xx][yy + 2] = 0;
    209  1.6  christos 			eat(xx, yy + 2);
    210  1.6  christos 			break;
    211  1.6  christos 		};
    212  1.6  christos 		if (++dir > 4) {
    213  1.6  christos 			dir = 1;
    214  1.6  christos 			--try;
    215  1.1       cgd 		}
    216  1.1       cgd 	}
    217  1.6  christos }
    218  1.1       cgd 
    219  1.1       cgd /*
    220  1.1       cgd  *	function to read in a maze from a data file
    221  1.1       cgd  *
    222  1.1       cgd  *	Format of maze data file:  1st character = # of mazes in file (ascii digit)
    223  1.1       cgd  *				For each maze: 18 lines (1st 17 used) 67 characters per line
    224  1.1       cgd  *
    225  1.1       cgd  *	Special characters in maze data file:
    226  1.1       cgd  *
    227  1.1       cgd  *		#	wall			D	door			.	random monster
    228  1.1       cgd  *		~	eye of larn		!	cure dianthroritis
    229  1.1       cgd  *		-	random object
    230  1.1       cgd  */
    231  1.6  christos int
    232  1.1       cgd cannedlevel(k)
    233  1.6  christos 	int             k;
    234  1.6  christos {
    235  1.6  christos 	char           *row;
    236  1.6  christos 	int             i, j;
    237  1.6  christos 	int             it, arg, mit, marg;
    238  1.6  christos 	if (lopen(larnlevels) < 0) {
    239  1.6  christos 		write(1, "Can't open the maze data file\n", 30);
    240  1.6  christos 		died(-282);
    241  1.6  christos 		return (0);
    242  1.6  christos 	}
    243  1.6  christos 	i = lgetc();
    244  1.6  christos 	if (i <= '0') {
    245  1.6  christos 		died(-282);
    246  1.6  christos 		return (0);
    247  1.6  christos 	}
    248  1.6  christos 	for (i = 18 * rund(i - '0'); i > 0; i--)
    249  1.6  christos 		lgetl();	/* advance to desired maze */
    250  1.6  christos 	for (i = 0; i < MAXY; i++) {
    251  1.1       cgd 		row = lgetl();
    252  1.6  christos 		for (j = 0; j < MAXX; j++) {
    253  1.1       cgd 			it = mit = arg = marg = 0;
    254  1.6  christos 			switch (*row++) {
    255  1.6  christos 			case '#':
    256  1.6  christos 				it = OWALL;
    257  1.6  christos 				break;
    258  1.6  christos 			case 'D':
    259  1.6  christos 				it = OCLOSEDDOOR;
    260  1.6  christos 				arg = rnd(30);
    261  1.6  christos 				break;
    262  1.6  christos 			case '~':
    263  1.6  christos 				if (k != MAXLEVEL - 1)
    264  1.6  christos 					break;
    265  1.6  christos 				it = OLARNEYE;
    266  1.6  christos 				mit = rund(8) + DEMONLORD;
    267  1.6  christos 				marg = monster[mit].hitpoints;
    268  1.6  christos 				break;
    269  1.6  christos 			case '!':
    270  1.6  christos 				if (k != MAXLEVEL + MAXVLEVEL - 1)
    271  1.6  christos 					break;
    272  1.6  christos 				it = OPOTION;
    273  1.6  christos 				arg = 21;
    274  1.6  christos 				mit = DEMONLORD + 7;
    275  1.6  christos 				marg = monster[mit].hitpoints;
    276  1.6  christos 				break;
    277  1.6  christos 			case '.':
    278  1.6  christos 				if (k < MAXLEVEL)
    279  1.6  christos 					break;
    280  1.6  christos 				mit = makemonst(k + 1);
    281  1.6  christos 				marg = monster[mit].hitpoints;
    282  1.6  christos 				break;
    283  1.6  christos 			case '-':
    284  1.6  christos 				it = newobject(k + 1, &arg);
    285  1.6  christos 				break;
    286  1.6  christos 			};
    287  1.6  christos 			item[j][i] = it;
    288  1.6  christos 			iarg[j][i] = arg;
    289  1.6  christos 			mitem[j][i] = mit;
    290  1.6  christos 			hitp[j][i] = marg;
    291  1.1       cgd 
    292  1.1       cgd #if WIZID
    293  1.1       cgd 			know[j][i] = (wizard) ? 1 : 0;
    294  1.1       cgd #else
    295  1.1       cgd 			know[j][i] = 0;
    296  1.1       cgd #endif
    297  1.1       cgd 		}
    298  1.6  christos 	}
    299  1.1       cgd 	lrclose();
    300  1.6  christos 	return (1);
    301  1.6  christos }
    302  1.1       cgd 
    303  1.1       cgd /*
    304  1.1       cgd 	function to make a treasure room on a level
    305  1.1       cgd 	level 10's treasure room has the eye in it and demon lords
    306  1.1       cgd 	level V3 has potion of cure dianthroritis and demon prince
    307  1.1       cgd  */
    308  1.6  christos void
    309  1.1       cgd treasureroom(lv)
    310  1.6  christos 	int             lv;
    311  1.6  christos {
    312  1.6  christos 	int             tx, ty, xsize, ysize;
    313  1.6  christos 
    314  1.6  christos 	for (tx = 1 + rnd(10); tx < MAXX - 10; tx += 10)
    315  1.6  christos 		if ((lv == MAXLEVEL - 1) || (lv == MAXLEVEL + MAXVLEVEL - 1) || rnd(13) == 2) {
    316  1.6  christos 			xsize = rnd(6) + 3;
    317  1.6  christos 			ysize = rnd(3) + 3;
    318  1.6  christos 			ty = rnd(MAXY - 9) + 1;	/* upper left corner of room */
    319  1.6  christos 			if (lv == MAXLEVEL - 1 || lv == MAXLEVEL + MAXVLEVEL - 1)
    320  1.6  christos 				troom(lv, xsize, ysize, tx = tx + rnd(MAXX - 24), ty, rnd(3) + 6);
    321  1.6  christos 			else
    322  1.6  christos 				troom(lv, xsize, ysize, tx, ty, rnd(9));
    323  1.1       cgd 		}
    324  1.6  christos }
    325  1.1       cgd 
    326  1.1       cgd /*
    327  1.6  christos  *	subroutine to create a treasure room of any size at a given location
    328  1.6  christos  *	room is filled with objects and monsters
    329  1.1       cgd  *	the coordinate given is that of the upper left corner of the room
    330  1.1       cgd  */
    331  1.6  christos void
    332  1.6  christos troom(lv, xsize, ysize, tx, ty, glyph)
    333  1.6  christos 	int             lv, xsize, ysize, tx, ty, glyph;
    334  1.6  christos {
    335  1.6  christos 	int             i, j;
    336  1.6  christos 	int             tp1, tp2;
    337  1.6  christos 	for (j = ty - 1; j <= ty + ysize; j++)
    338  1.6  christos 		for (i = tx - 1; i <= tx + xsize; i++)	/* clear out space for
    339  1.6  christos 							 * room */
    340  1.6  christos 			item[i][j] = 0;
    341  1.6  christos 	for (j = ty; j < ty + ysize; j++)
    342  1.6  christos 		for (i = tx; i < tx + xsize; i++) {	/* now put in the walls */
    343  1.6  christos 			item[i][j] = OWALL;
    344  1.6  christos 			mitem[i][j] = 0;
    345  1.6  christos 		}
    346  1.6  christos 	for (j = ty + 1; j < ty + ysize - 1; j++)
    347  1.6  christos 		for (i = tx + 1; i < tx + xsize - 1; i++)	/* now clear out
    348  1.6  christos 								 * interior */
    349  1.6  christos 			item[i][j] = 0;
    350  1.6  christos 
    351  1.6  christos 	switch (rnd(2)) {	/* locate the door on the treasure room */
    352  1.6  christos 	case 1:
    353  1.6  christos 		item[i = tx + rund(xsize)][j = ty + (ysize - 1) * rund(2)] = OCLOSEDDOOR;
    354  1.6  christos 		iarg[i][j] = glyph;	/* on horizontal walls */
    355  1.6  christos 		break;
    356  1.6  christos 	case 2:
    357  1.6  christos 		item[i = tx + (xsize - 1) * rund(2)][j = ty + rund(ysize)] = OCLOSEDDOOR;
    358  1.6  christos 		iarg[i][j] = glyph;	/* on vertical walls */
    359  1.6  christos 		break;
    360  1.6  christos 	};
    361  1.6  christos 
    362  1.6  christos 	tp1 = playerx;
    363  1.6  christos 	tp2 = playery;
    364  1.6  christos 	playery = ty + (ysize >> 1);
    365  1.6  christos 	if (c[HARDGAME] < 2)
    366  1.6  christos 		for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2)
    367  1.6  christos 			for (i = 0, j = rnd(6); i <= j; i++) {
    368  1.6  christos 				something(lv + 2);
    369  1.6  christos 				createmonster(makemonst(lv + 1));
    370  1.6  christos 			}
    371  1.6  christos 	else
    372  1.6  christos 		for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2)
    373  1.6  christos 			for (i = 0, j = rnd(4); i <= j; i++) {
    374  1.6  christos 				something(lv + 2);
    375  1.6  christos 				createmonster(makemonst(lv + 3));
    376  1.1       cgd 			}
    377  1.1       cgd 
    378  1.6  christos 	playerx = tp1;
    379  1.6  christos 	playery = tp2;
    380  1.6  christos }
    381  1.1       cgd 
    382  1.1       cgd 
    383  1.1       cgd /*
    384  1.1       cgd 	***********
    385  1.1       cgd 	MAKE_OBJECT
    386  1.1       cgd 	***********
    387  1.1       cgd 	subroutine to create the objects in the maze for the given level
    388  1.1       cgd  */
    389  1.6  christos void
    390  1.1       cgd makeobject(j)
    391  1.6  christos 	int             j;
    392  1.6  christos {
    393  1.6  christos 	int             i;
    394  1.6  christos 	if (j == 0) {
    395  1.6  christos 		fillroom(OENTRANCE, 0);	/* entrance to dungeon			 */
    396  1.6  christos 		fillroom(ODNDSTORE, 0);	/* the DND STORE				 */
    397  1.6  christos 		fillroom(OSCHOOL, 0);	/* college of Larn				 */
    398  1.6  christos 		fillroom(OBANK, 0);	/* 1st national bank of larn 	 */
    399  1.6  christos 		fillroom(OVOLDOWN, 0);	/* volcano shaft to temple 	 */
    400  1.6  christos 		fillroom(OHOME, 0);	/* the players home & family 	 */
    401  1.6  christos 		fillroom(OTRADEPOST, 0);	/* the trading post			 */
    402  1.6  christos 		fillroom(OLRS, 0);	/* the larn revenue service 	 */
    403  1.1       cgd 		return;
    404  1.6  christos 	}
    405  1.6  christos 	if (j == MAXLEVEL)
    406  1.6  christos 		fillroom(OVOLUP, 0);	/* volcano shaft up from the temple */
    407  1.1       cgd 
    408  1.6  christos 	/* make the fixed objects in the maze STAIRS	 */
    409  1.6  christos 	if ((j > 0) && (j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1))
    410  1.6  christos 		fillroom(OSTAIRSDOWN, 0);
    411  1.6  christos 	if ((j > 1) && (j != MAXLEVEL))
    412  1.6  christos 		fillroom(OSTAIRSUP, 0);
    413  1.6  christos 
    414  1.6  christos 	/* make the random objects in the maze		 */
    415  1.6  christos 
    416  1.6  christos 	fillmroom(rund(3), OBOOK, j);
    417  1.6  christos 	fillmroom(rund(3), OALTAR, 0);
    418  1.6  christos 	fillmroom(rund(3), OSTATUE, 0);
    419  1.6  christos 	fillmroom(rund(3), OPIT, 0);
    420  1.6  christos 	fillmroom(rund(3), OFOUNTAIN, 0);
    421  1.6  christos 	fillmroom(rnd(3) - 2, OIVTELETRAP, 0);
    422  1.6  christos 	fillmroom(rund(2), OTHRONE, 0);
    423  1.6  christos 	fillmroom(rund(2), OMIRROR, 0);
    424  1.6  christos 	fillmroom(rund(2), OTRAPARROWIV, 0);
    425  1.6  christos 	fillmroom(rnd(3) - 2, OIVDARTRAP, 0);
    426  1.6  christos 	fillmroom(rund(3), OCOOKIE, 0);
    427  1.6  christos 	if (j == 1)
    428  1.6  christos 		fillmroom(1, OCHEST, j);
    429  1.6  christos 	else
    430  1.6  christos 		fillmroom(rund(2), OCHEST, j);
    431  1.6  christos 	if ((j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1))
    432  1.6  christos 		fillmroom(rund(2), OIVTRAPDOOR, 0);
    433  1.6  christos 	if (j <= 10) {
    434  1.6  christos 		fillmroom((rund(2)), ODIAMOND, rnd(10 * j + 1) + 10);
    435  1.6  christos 		fillmroom(rund(2), ORUBY, rnd(6 * j + 1) + 6);
    436  1.6  christos 		fillmroom(rund(2), OEMERALD, rnd(4 * j + 1) + 4);
    437  1.6  christos 		fillmroom(rund(2), OSAPPHIRE, rnd(3 * j + 1) + 2);
    438  1.6  christos 	}
    439  1.6  christos 	for (i = 0; i < rnd(4) + 3; i++)
    440  1.6  christos 		fillroom(OPOTION, newpotion());	/* make a POTION	 */
    441  1.6  christos 	for (i = 0; i < rnd(5) + 3; i++)
    442  1.6  christos 		fillroom(OSCROLL, newscroll());	/* make a SCROLL	 */
    443  1.6  christos 	for (i = 0; i < rnd(12) + 11; i++)
    444  1.6  christos 		fillroom(OGOLDPILE, 12 * rnd(j + 1) + (j << 3) + 10);	/* make GOLD	 */
    445  1.6  christos 	if (j == 5)
    446  1.6  christos 		fillroom(OBANK2, 0);	/* branch office of the bank */
    447  1.6  christos 	froom(2, ORING, 0);	/* a ring mail 			 */
    448  1.6  christos 	froom(1, OSTUDLEATHER, 0);	/* a studded leather	 */
    449  1.6  christos 	froom(3, OSPLINT, 0);	/* a splint mail		 */
    450  1.6  christos 	froom(5, OSHIELD, rund(3));	/* a shield				 */
    451  1.6  christos 	froom(2, OBATTLEAXE, rund(3));	/* a battle axe			 */
    452  1.6  christos 	froom(5, OLONGSWORD, rund(3));	/* a long sword			 */
    453  1.6  christos 	froom(5, OFLAIL, rund(3));	/* a flail				 */
    454  1.6  christos 	froom(4, OREGENRING, rund(3));	/* ring of regeneration */
    455  1.6  christos 	froom(1, OPROTRING, rund(3));	/* ring of protection	 */
    456  1.6  christos 	froom(2, OSTRRING, 4);	/* ring of strength + 4 */
    457  1.6  christos 	froom(7, OSPEAR, rnd(5));	/* a spear				 */
    458  1.6  christos 	froom(3, OORBOFDRAGON, 0);	/* orb of dragon slaying */
    459  1.6  christos 	froom(4, OSPIRITSCARAB, 0);	/* scarab of negate spirit */
    460  1.6  christos 	froom(4, OCUBEofUNDEAD, 0);	/* cube of undead control	 */
    461  1.6  christos 	froom(2, ORINGOFEXTRA, 0);	/* ring of extra regen		 */
    462  1.6  christos 	froom(3, ONOTHEFT, 0);	/* device of antitheft 		 */
    463  1.6  christos 	froom(2, OSWORDofSLASHING, 0);	/* sword of slashing */
    464  1.6  christos 	if (c[BESSMANN] == 0) {
    465  1.6  christos 		froom(4, OHAMMER, 0);	/* Bessman's flailing hammer */
    466  1.6  christos 		c[BESSMANN] = 1;
    467  1.6  christos 	}
    468  1.6  christos 	if (c[HARDGAME] < 3 || (rnd(4) == 3)) {
    469  1.6  christos 		if (j > 3) {
    470  1.6  christos 			froom(3, OSWORD, 3);	/* sunsword + 3  		 */
    471  1.6  christos 			froom(5, O2SWORD, rnd(4));	/* a two handed sword	 */
    472  1.6  christos 			froom(3, OBELT, 4);	/* belt of striking		 */
    473  1.6  christos 			froom(3, OENERGYRING, 3);	/* energy ring			 */
    474  1.6  christos 			froom(4, OPLATE, 5);	/* platemail + 5 		 */
    475  1.1       cgd 		}
    476  1.1       cgd 	}
    477  1.6  christos }
    478  1.1       cgd 
    479  1.1       cgd /*
    480  1.1       cgd 	subroutine to fill in a number of objects of the same kind
    481  1.1       cgd  */
    482  1.1       cgd 
    483  1.6  christos void
    484  1.6  christos fillmroom(n, what, arg)
    485  1.6  christos 	int             n, arg;
    486  1.6  christos 	char            what;
    487  1.6  christos {
    488  1.6  christos 	int             i;
    489  1.6  christos 	for (i = 0; i < n; i++)
    490  1.6  christos 		fillroom(what, arg);
    491  1.6  christos }
    492  1.6  christos void
    493  1.6  christos froom(n, itm, arg)
    494  1.6  christos 	int             n, arg;
    495  1.6  christos 	char            itm;
    496  1.6  christos {
    497  1.6  christos 	if (rnd(151) < n)
    498  1.6  christos 		fillroom(itm, arg);
    499  1.6  christos }
    500  1.1       cgd 
    501  1.1       cgd /*
    502  1.1       cgd 	subroutine to put an object into an empty room
    503  1.1       cgd  *	uses a random walk
    504  1.1       cgd  */
    505  1.1       cgd static void
    506  1.6  christos fillroom(what, arg)
    507  1.6  christos 	int             arg;
    508  1.6  christos 	char            what;
    509  1.6  christos {
    510  1.6  christos 	int             x, y;
    511  1.1       cgd 
    512  1.1       cgd #ifdef EXTRA
    513  1.1       cgd 	c[FILLROOM]++;
    514  1.1       cgd #endif
    515  1.1       cgd 
    516  1.6  christos 	x = rnd(MAXX - 2);
    517  1.6  christos 	y = rnd(MAXY - 2);
    518  1.6  christos 	while (item[x][y]) {
    519  1.1       cgd 
    520  1.1       cgd #ifdef EXTRA
    521  1.6  christos 		c[RANDOMWALK]++;/* count up these random walks */
    522  1.1       cgd #endif
    523  1.1       cgd 
    524  1.6  christos 		x += rnd(3) - 2;
    525  1.6  christos 		y += rnd(3) - 2;
    526  1.6  christos 		if (x > MAXX - 2)
    527  1.6  christos 			x = 1;
    528  1.6  christos 		if (x < 1)
    529  1.6  christos 			x = MAXX - 2;
    530  1.6  christos 		if (y > MAXY - 2)
    531  1.6  christos 			y = 1;
    532  1.6  christos 		if (y < 1)
    533  1.6  christos 			y = MAXY - 2;
    534  1.6  christos 	}
    535  1.6  christos 	item[x][y] = what;
    536  1.6  christos 	iarg[x][y] = arg;
    537  1.6  christos }
    538  1.1       cgd 
    539  1.1       cgd /*
    540  1.1       cgd 	subroutine to put monsters into an empty room without walls or other
    541  1.1       cgd 	monsters
    542  1.1       cgd  */
    543  1.6  christos int
    544  1.1       cgd fillmonst(what)
    545  1.6  christos 	int            what;
    546  1.6  christos {
    547  1.6  christos 	int             x, y, trys;
    548  1.6  christos 	for (trys = 5; trys > 0; --trys) {	/* max # of creation attempts */
    549  1.6  christos 		x = rnd(MAXX - 2);
    550  1.6  christos 		y = rnd(MAXY - 2);
    551  1.6  christos 		if ((item[x][y] == 0) && (mitem[x][y] == 0) && ((playerx != x) || (playery != y))) {
    552  1.6  christos 			mitem[x][y] = what;
    553  1.6  christos 			know[x][y] = 0;
    554  1.6  christos 			hitp[x][y] = monster[what].hitpoints;
    555  1.6  christos 			return (0);
    556  1.1       cgd 		}
    557  1.1       cgd 	}
    558  1.6  christos 	return (-1);		/* creation failure */
    559  1.6  christos }
    560  1.1       cgd 
    561  1.1       cgd /*
    562  1.1       cgd 	creates an entire set of monsters for a level
    563  1.1       cgd 	must be done when entering a new level
    564  1.1       cgd 	if sethp(1) then wipe out old monsters else leave them there
    565  1.1       cgd  */
    566  1.6  christos void
    567  1.1       cgd sethp(flg)
    568  1.6  christos 	int             flg;
    569  1.6  christos {
    570  1.6  christos 	int             i, j;
    571  1.6  christos 	if (flg)
    572  1.6  christos 		for (i = 0; i < MAXY; i++)
    573  1.6  christos 			for (j = 0; j < MAXX; j++)
    574  1.6  christos 				stealth[j][i] = 0;
    575  1.6  christos 	if (level == 0) {
    576  1.6  christos 		c[TELEFLAG] = 0;
    577  1.6  christos 		return;
    578  1.6  christos 	}			/* if teleported and found level 1 then know
    579  1.6  christos 				 * level we are on */
    580  1.6  christos 	if (flg)
    581  1.6  christos 		j = rnd(12) + 2 + (level >> 1);
    582  1.6  christos 	else
    583  1.6  christos 		j = (level >> 1) + 1;
    584  1.6  christos 	for (i = 0; i < j; i++)
    585  1.6  christos 		fillmonst(makemonst(level));
    586  1.1       cgd 	positionplayer();
    587  1.6  christos }
    588  1.1       cgd 
    589  1.1       cgd /*
    590  1.1       cgd  *	Function to destroy all genocided monsters on the present level
    591  1.1       cgd  */
    592  1.6  christos void
    593  1.1       cgd checkgen()
    594  1.6  christos {
    595  1.6  christos 	int             x, y;
    596  1.6  christos 	for (y = 0; y < MAXY; y++)
    597  1.6  christos 		for (x = 0; x < MAXX; x++)
    598  1.1       cgd 			if (monster[mitem[x][y]].genocided)
    599  1.6  christos 				mitem[x][y] = 0;	/* no more monster */
    600  1.6  christos }
    601