Source:NetHack 2.2a/makemon.c

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

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

1.   /*	SCCS Id: @(#)makemon.c	2.2	87/11/29 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include	"hack.h"  5.    extern char fut_geno[]; 6.   extern char *index; 7.   extern struct obj *mkobj_at, *mksobj, *mkobj; 8.   struct monst zeromonst; 9.   extern boolean in_mklev; 10.   11.   #ifdef HARD		/* used in hell for bigger, badder demons! */ 12.    13.   struct permonst d_lord   = { "demon lord",	'&',12,13,-5,50,1,5,0 }, 14.  		d_prince = { "demon prince",	'&',14,14,-6,70,1,6,0 }; 15.  #endif 16.  #ifdef KJSMODS 17.  # ifdef KOPS 18.  struct permonst kobold = { "kobold",'K',1,6,7,0,1,4,0 }; 19.  # endif 20.  # ifdef ROCKMOLE 21.  struct permonst giant_rat = { "giant rat",'r',0,12,7,0,1,3,0 }; 22.  # endif 23.  #endif /* KJSMODS /**/ 24.   25.   /*  26.    * called with [x,y] = coordinates; 27.   *	[0,0] means anyplace 28.   *	[u.ux,u.uy] means: call mnexto (if !in_mklev) 29.   *  30.    *	In case we make an Orc or killer bee, we make an entire horde 31.   *	(swarm); note that in this case we return only one of them 32.   *	(the one at [x,y]). 33.   */  34.   struct monst * 35.  makemon(ptr,x,y) 36.  register struct permonst *ptr; 37.  {  38.   	register struct monst *mtmp; 39.  	register nleft, deep, ct; 40.  	boolean anything = (!ptr); 41.  	int zlevel = dlevel; 42.  #ifdef BVH 43.  	if(has_amulet) zlevel = 40; 44.  #endif 45.  	/* if a monster already exists at the position, return */ 46.  	if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0); 47.  	if(ptr){ 48.  		/* if you are to make a specific monster and it has 49.  		   already been genocided, return */ 50.  		if(index(fut_geno, ptr->mlet)) return((struct monst *) 0); 51.  	} else { 52.  		/* make a random (common) monster. */ 53.   		nleft = CMNUM - strlen(fut_geno); 54.  		if(index(fut_geno, 'm')) nleft++;  /* only 1 minotaur */ 55.  		if(index(fut_geno, '@')) nleft++; 56.  		if(nleft <= 0) 57.  		    return((struct monst *) 0);	/* no more monsters! */ 58.    59.   		/* determine the strongest monster to make. */ 60.   #ifdef ROCKMOLE 61.  		deep = rn2(nleft*zlevel/24 + 6); 62.  #else 63.  		deep = rn2(nleft*zlevel/24 + 7); 64.  #endif 65.  		if(deep < zlevel - 4) deep = rn2(nleft*zlevel/24 + 12); 66.  		/* if deep is greater than the number of monsters left 67.  		   to create, set deep to a random number between half 68.  		   the number left and the number left. */ 69.   		if(deep >= nleft) deep = rn1(nleft - nleft/2, nleft/2); 70.   71.   		for(ct = 0 ; ct < CMNUM ; ct++){ 72.  			ptr = &mons[ct]; 73.  			if(index(fut_geno, ptr->mlet)) continue; 74.  #ifdef KOPS 75.  			if(ptr->mlet == 'K') { 76.  # ifdef KJSMODS 77.  				/* since this is a random monster, make 78.  				   a Kobold instead of a Kop. */ 79.   				ptr = &kobold; 80.  # else 81.  				deep--; 82.  # endif 83.  				continue; 84.  			}  85.   #endif /* KOPS /**/ 86.  			if(deep-- <= 0) goto gotmon; 87.  		}  88.   		/* this can happen if you are deep in the dungeon and 89.  		   mostly weak monsters have been genocided. */ 90.   		return((struct monst *) 0); 91.  	}  92.   gotmon: 93.  #if defined(KJSMODS) && defined(ROCKMOLE) 94.  	/* make a giant rat */ 95.  	if((zlevel < 4 && ptr->mlet == 'r')  96.   	   || (zlevel == 1 && (ptr->mlet == 'h' || ptr->mlet == 'i'))  97.   	   || (zlevel == 2 && (ptr->mlet == 'o' || ptr->mlet == 'y'))  98.   	) ptr = &giant_rat; 99.  #endif 100. 	mtmp = newmonst(ptr->pxlth); 101. 	*mtmp = zeromonst;	/* clear all entries in structure */ 102. 	for(ct = 0; ct < ptr->pxlth; ct++) 103. 		((char *) &(mtmp->mextra[0]))[ct] = 0; 104. 	mtmp->nmon = fmon; 105. 	fmon = mtmp; 106. 	mtmp->m_id = flags.ident++; 107. 	mtmp->data = ptr; 108. 	mtmp->mxlth = ptr->pxlth; 109. 	if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80; 110. 	else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4); 111. 	else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8); 112. 	mtmp->mx = x;  113. mtmp->my = y; 114. mtmp->mcansee = 1; 115. 	if(ptr->mlet == 'M'){ 116. 		mtmp->mimic = 1; 117. 		mtmp->mappearance = ']'; 118. 	}  119.  	if(!in_mklev) { 120. 		if(x == u.ux && y == u.uy && ptr->mlet != ' ') 121. 			mnexto(mtmp); 122. 		if(x == 0 && y == 0) 123. 			rloc(mtmp); 124. 	}  125.  	if(ptr->mlet == 's' || ptr->mlet == 'S') { 126. 		mtmp->mhide = mtmp->mundetected = 1; 127. 		if(in_mklev) 128. 		if(mtmp->mx && mtmp->my) 129. 			(void) mkobj_at(0, mtmp->mx, mtmp->my); 130. 	}  131.  	if(ptr->mlet == ':') { 132. #ifdef DGKMOD 133. 		/* If you're protected with a ring, don't create 134. 		 * any shape-changing chameleons -dgk 135. 		 */  136.  		if (Protection_from_shape_changers) 137. 			mtmp->cham = 0; 138. 		else { 139. 			mtmp->cham = 1; 140. 			(void) newcham(mtmp,  141.  				&mons[zlevel+14+rn2(CMNUM-14-zlevel)]); 142. 		}  143.  #else 144. 		mtmp->cham = 1; 145. 		(void) newcham(mtmp, &mons[zlevel+14+rn2(CMNUM-14-zlevel)]); 146. #endif 147. 	}  148.  	if(ptr->mlet == 'I' || ptr->mlet == ';') 149. 		mtmp->minvis = 1; 150. 	if(ptr->mlet == 'L' || ptr->mlet == 'N'  151.  	    || (in_mklev && index("&w;", ptr->mlet) && rn2(5))  152.  	) mtmp->msleep = 1; 153. #ifdef HARD 154. 	if(ptr->mlet == '&' && (Inhell || u.udemigod)) { 155.  156.  		if(!rn2(3 + !Inhell + !u.udemigod)) { 157. 		    if (rn2(3 + Inhell)) mtmp->data = &d_lord; 158. 		    else  { 159. 			mtmp->data = &d_prince; 160. 			mtmp->mpeaceful = 1; 161. 			mtmp->minvis = 1; 162. 		    }  163.  		}  164.  #ifdef RPH 165. 		if(uwep) 166. 		    if(!strcmp(ONAME(uwep), "Excalibur")) 167. 			mtmp->mpeaceful = mtmp->mtame = 0; 168. #endif 169. 	}  170.  #endif /* HARD /**/ 171. #ifndef NOWORM 172. 	if(ptr->mlet == 'w' && getwn(mtmp))  initworm(mtmp); 173. #endif 174.  175.  	if(anything) 176. 	    if(ptr->mlet == 'O' || ptr->mlet == 'k'  177.  #ifdef SAC  178.  	       || ptr->mlet == '3'  179.  #endif /* SAC /**/  180.  				  ) { 181.  182.  		coord mm; 183. 		register int cnt = rnd(10); 184. 		mm.x = x;  185. mm.y = y; 186. while(cnt--) { 187. 			enexto(&mm, mm.x, mm.y); 188. 			(void) makemon(ptr, mm.x, mm.y); 189. 		}  190.  	}  191.  #ifdef DGKMOD 192. 	m_initinv(mtmp); 193. #endif 194. 	return(mtmp); 195. }  196.   197.  #ifdef DGKMOD 198. /* Give some monsters an initial inventory to use */ 199. m_initinv(mtmp) 200. struct monst *mtmp; 201. {  202.  	struct obj *otmp; 203.  204.  	switch (mtmp->data->mlet) { 205. # ifdef KAA 206. 	case '9': 207. 		if (rn2(2)) { 208. 			otmp = mksobj(ENORMOUS_ROCK); 209. 			mpickobj(mtmp, otmp); 210. 		}  211.  # endif 212. # ifdef SAC 213. 	case '3':			/* Outfit the troops */ 214. 		if (!rn2(4)) { 215. 			otmp = mksobj(HELMET); 216. 			mpickobj(mtmp, otmp); } 217. 		if (!rn2(4)) { 218. 			otmp = mksobj(CHAIN_MAIL); 219. 			mpickobj(mtmp, otmp); } 220. 		if (!rn2(3)) { 221. 			otmp = mksobj(DAGGER); 222. 			mpickobj(mtmp, otmp); } 223. 		if (!rn2(6)) { 224. 			otmp = mksobj(SPEAR); 225. 			mpickobj(mtmp, otmp); } 226. 		if (!rn2(2)) { 227. 			otmp = mksobj(TIN); 228. 			mpickobj(mtmp, otmp); } 229. # endif /* SAC /**/ 230. # ifdef KOPS 231. 	case 'K':		/* create Keystone Kops with cream pies to  232. * throw. As suggested by KAA. [MRS] 233. 				 */  234.  		if (!rn2(4)  235.  #  ifdef KJSMODS  236.    		    && !strcmp(mtmp->data->mname, "Keystone Kop")  237.  #  endif  238.  								) { 239. 			otmp = mksobj(CREAM_PIE); 240. 			otmp->quan = 2 + rnd(2); 241. 			otmp->owt = weight(otmp); 242. 			mpickobj(mtmp, otmp); 243. 		}  244.  		break; 245. 	case 'O': 246. # else 247. 	case 'K': 248. # endif 249. 		if (!rn2(4)) { 250. 			otmp = mksobj(DART); 251. 			otmp->quan = 2 + rnd(12); 252. 			otmp->owt = weight(otmp); 253. 			mpickobj(mtmp, otmp); 254. 		}  255.  		break; 256.  257.  	case 'C': 258. 		if (rn2(2)) { 259. 			otmp = mksobj(CROSSBOW); 260. 			otmp->cursed = rn2(2); 261. 			mpickobj(mtmp, otmp); 262. 			otmp = mksobj(CROSSBOW_BOLT); 263. 			otmp->quan = 2 + rnd(12); 264. 			otmp->owt = weight(otmp); 265. 			mpickobj(mtmp, otmp); 266. 		}  267.  		break; 268. 	default: 269. 		break; 270. 	}  271.  }  272.  #endif 273.  274.  enexto(cc, xx,yy) 275. coord	*cc; 276. register xchar xx,yy; 277. {  278.  	register xchar x,y; 279. 	coord foo[15], *tfoo; 280. 	int range, i;  281. 282. 	tfoo = foo; 283. 	range = 1; 284. 	do {	/* full kludge action. */ 285.  		for(x = xx-range; x <= xx+range; x++) 286. 			if(goodpos(x, yy-range)) { 287. 				tfoo->x = x;  288. (tfoo++)->y = yy-range; 289. 				if(tfoo == &foo[15]) goto foofull; 290. 			}  291.  		for(x = xx-range; x <= xx+range; x++) 292. 			if(goodpos(x,yy+range)) { 293. 				tfoo->x = x;  294. (tfoo++)->y = yy+range; 295. 				if(tfoo == &foo[15]) goto foofull; 296. 			}  297.  		for(y = yy+1-range; y < yy+range; y++) 298. 			if(goodpos(xx-range,y)) { 299. 				tfoo->x = xx-range; 300. 				(tfoo++)->y = y;  301. if(tfoo == &foo[15]) goto foofull; 302. 			}  303.  		for(y = yy+1-range; y < yy+range; y++) 304. 			if(goodpos(xx+range,y)) { 305. 				tfoo->x = xx+range; 306. 				(tfoo++)->y = y;  307. if(tfoo == &foo[15]) goto foofull; 308. 			}  309.  		range++; 310. 	} while(tfoo == foo); 311. foofull: 312. 	i = rn2(tfoo - foo); 313. 	cc->x = foo[i].x;  314. cc->y = foo[i].y; 315. return(0); 316. }  317.   318.  goodpos(x,y)	/* used only in mnexto and rloc */ 319. {  320.  	return(  321.  	! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 322. 	   m_at(x,y) || !ACCESSIBLE(levl[x][y].typ) 323. 	   || (x == u.ux && y == u.uy) 324. 	   || sobj_at(ENORMOUS_ROCK, x, y)  325. )); 326.  }  327.   328.  rloc(mtmp) 329. struct monst *mtmp; 330. {  331.  	register tx,ty; 332. 	register char ch = mtmp->data->mlet; 333.  334.  #ifndef NOWORM 335. 	if(ch == 'w' && mtmp->mx) return;	/* do not relocate worms */ 336. #endif 337. 	do { 338. 		tx = rn1(COLNO-3,2); 339. 		ty = rn2(ROWNO); 340. 	} while(!goodpos(tx,ty)); 341. 	mtmp->mx = tx; 342. 	mtmp->my = ty; 343. 	if(u.ustuck == mtmp){ 344. 		if(u.uswallow) { 345. 			u.ux = tx; 346. 			u.uy = ty; 347. 			docrt; 348. 		} else	u.ustuck = 0; 349. 	}  350.  	pmon(mtmp); 351. }  352.   353.  struct monst * 354. mkmon_at(let,x,y) 355. char let; 356. register int x,y; 357. {  358.  	register int ct; 359. 	register struct permonst *ptr; 360.  361.  	for(ct = 0; ct < CMNUM; ct++) { 362. 		ptr = &mons[ct]; 363. 		if(ptr->mlet == let) 364. 			return(makemon(ptr,x,y)); 365. 	}  366.  	return((struct monst *)0); 367. }