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