Source:NetHack 2.3e/makemon.c

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