Source:Hack 1.0/hack.makemon.c

Below is the full text to hack.makemon.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.makemon.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2.     3.    #ifdef MKLEV 4.   #include	"mklev.h"  5.    extern char *fut_geno; 6.   #else MKLEV 7.   #include	"hack.h"  8.    extern char fut_geno[]; 9.   #endif MKLEV 10.   11.    12.   extern char *index; 13.   14.   struct monst zeromonst; 15.   16.   /*  17.    * called with [x,y] = coordinates; 18.   *	[0,0] means anyplace 19.   *	[u.ux,u.uy] means: call mnexto (not in MKLEV) 20.   *  21.    *	In case we make an Orc or killer bee, we make an entire horde (swarm); 22.   *	note that in this case we return only one of them (the one at [x,y]). 23.   */  24.   struct monst * 25.  makemon(ptr,x,y) 26.  register struct permonst *ptr; 27.  {  28.   	register struct monst *mtmp; 29.  	register tmp, ct; 30.  	boolean anything = (!ptr); 31.   32.   	if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0); 33.  	if(ptr){ 34.  		if(index(fut_geno, ptr->mlet)) return((struct monst *) 0); 35.  	} else { 36.  		ct = CMNUM - strlen(fut_geno); 37.  		if(index(fut_geno, 'm')) ct++;  /* make only 1 minotaur */ 38.  		if(index(fut_geno, '@')) ct++; 39.  		if(ct <= 0) return(0); 		  /* no more monsters! */ 40.   		tmp = rn2(ct*dlevel/24 + 7); 41.  		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12); 42.  		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2); 43.  		for(ct = 0; ct < CMNUM; ct++){ 44.  			ptr = &mons[ct]; 45.  			if(index(fut_geno, ptr->mlet)) 46.  				continue; 47.  			if(!tmp--) goto gotmon; 48.  		}  49.    panic("makemon?"); 50.  	}  51.   gotmon: 52.  	mtmp = newmonst(ptr->pxlth); 53.  	*mtmp = zeromonst;	/* clear all entries in structure */ 54.  	for(ct = 0; ct < ptr->pxlth; ct++) 55.  		((char *) &(mtmp->mextra[0]))[ct] = 0; 56.  	mtmp->nmon = fmon; 57.  	fmon = mtmp; 58.  #ifndef MKLEV 59.  	mtmp->m_id = flags.ident++; 60.  #endif MKLEV 61.  	mtmp->data = ptr; 62.  	mtmp->mxlth = ptr->pxlth; 63.  	if(ptr->mlet == 'D') mtmp->orig_hp = mtmp->mhp = 80; 64.  	else if(!ptr->mlevel) mtmp->orig_hp = mtmp->mhp = rnd(4); 65.  	else mtmp->orig_hp = mtmp->mhp = d(ptr->mlevel, 8); 66.  	mtmp->mx = x;  67. mtmp->my = y; 68. mtmp->mcansee = 1; 69.  	if(ptr->mlet == 'M') 70.  		mtmp->mimic = ']'; 71.  #ifndef MKLEV 72.  	if(x == u.ux && y == u.uy) 73.  		mnexto(mtmp); 74.  	if(x == 0 && y == 0) 75.  		rloc(mtmp); 76.  #endif MKLEV 77.  	if(ptr->mlet == 's' || ptr->mlet == 'S') { 78.  		mtmp->mhide = mtmp->mundetected = 1; 79.  #ifdef MKLEV 80.  		if(mtmp->mx && mtmp->my) 81.  			mkobj_at(0, mtmp->mx, mtmp->my); 82.  #endif MKLEV 83.  	}  84.   	if(ptr->mlet == ':') { 85.  		mtmp->cham = 1; 86.  #ifndef MKLEV 87.  		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 88.  #endif MKLEV 89.  	}  90.   	if(ptr->mlet == 'I') mtmp->minvis = 1; 91.  	if(ptr->mlet == 'L' || ptr->mlet == 'N'  92.   #ifdef MKLEV  93.   		|| rn2(5)  94.   #endif MKLEV  95.   	) mtmp->msleep = 1; 96.   97.   #ifndef NOWORM 98.  #ifndef MKLEV 99.  	if(ptr->mlet == 'w' && getwn(mtmp)) 100. 		initworm(mtmp); 101. #endif MKLEV 102. #endif NOWORM 103.  104.  	if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') { 105. 		coord enexto; 106. 		coord mm; 107. 		register int cnt = rnd(10); 108. 		mm.x = x;  109. mm.y = y; 110. while(cnt--) { 111. 			mm = enexto(mm.x, mm.y); 112. 			(void) makemon(ptr, mm.x, mm.y); 113. 		}  114.  	}  115.   116.  	return(mtmp); 117. }  118.   119.  coord 120. enexto(xx,yy) 121. register xchar xx,yy; 122. {  123.  	register xchar x,y; 124. 	coord foo[15], *tfoo; 125. 	int range; 126.  127.  	tfoo = foo; 128. 	range = 1; 129. 	do {	/* full kludge action. */ 130.  		for(x = xx-range; x <= xx+range; x++) 131. 			if(goodpos(x, yy-range)) { 132. 				tfoo->x = x;  133. tfoo++->y = yy-range; 134. 				if(tfoo == &foo[15]) goto foofull; 135. 			}  136.  		for(x = xx-range; x <= xx+range; x++) 137. 			if(goodpos(x,yy+range)) { 138. 				tfoo->x = x;  139. tfoo++->y = yy+range; 140. 				if(tfoo == &foo[15]) goto foofull; 141. 			}  142.  		for(y = yy+1-range; y < yy+range; y++) 143. 			if(goodpos(xx-range,y)) { 144. 				tfoo->x = xx-range; 145. 				tfoo++->y = y;  146. if(tfoo == &foo[15]) goto foofull; 147. 			}  148.  		for(y = yy+1-range; y < yy+range; y++) 149. 			if(goodpos(xx+range,y)) { 150. 				tfoo->x = xx+range; 151. 				tfoo++->y = y;  152. if(tfoo == &foo[15]) goto foofull; 153. 			}  154.   range++; 155. 	} while(tfoo == foo); 156. foofull: 157. 	return( foo[rn2(tfoo-foo)] ); 158. }  159.   160.  goodpos(x,y)	/* used only in mnexto and rloc */ 161. {  162.  	return(  163.  	! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 164. 	   m_at(x,y) || levl[x][y].typ < DOOR 165. #ifndef MKLEV 166. 	   || (x == u.ux && y == u.uy) 167. 	   || sobj_at(ENORMOUS_ROCK, x, y)  168. #endif MKLEV 169. 	));  170.  }