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