Source:NetHack 3.0.0/mkroom.c

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

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

1.   /*	SCCS Id: @(#)mkroom.c	3.0	88/11/24 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /*  6.     * Entry points: 7.    *	mkroom -- make and stock a room of a given type 8.    *	nexttodoor -- return TRUE if adjacent to a door 9.    *	has_dnstairs -- return TRUE if given room has a down staircase 10.   *	has_upstairs -- return TRUE if given room has an up staircase 11.   *	dist2 -- Euclidean square-of-distance function 12.   *	courtmon -- generate a court monster 13.   */  14.   #include "hack.h"  15. 16.  static void mkshop, mkzoo, mkswamp; 17.  #ifdef ORACLE 18.  static void mkdelphi; 19.  #endif 20.  #if defined(ALTARS) && defined(THEOLOGY) 21.  static void mktemple; 22.  #endif 23.   24.   static struct permonst *morguemon; 25.  #ifdef ARMY 26.  static struct permonst *squadmon; 27.  #endif 28.   29.   #define sq(x) ((x)*(x)) 30.   31.   static boolean 32.  isbig(sroom) 33.  register struct mkroom *sroom; 34.  {  35.   	register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); 36.  	return( area > 20 ); 37.  }  38.    39.   void 40.  mkroom(roomtype) 41.  /* make and stock a room of a given type */ 42.  int	roomtype; 43.  {  44.    45.       if (roomtype >= SHOPBASE) 46.  	mkshop;	/* someday, we should be able to specify shop type */ 47.      else switch(roomtype) { 48.  #ifdef THRONES 49.  	case COURT:	mkzoo(COURT); break; 50.  #endif 51.  	case ZOO:	mkzoo(ZOO); break; 52.  	case BEEHIVE:	mkzoo(BEEHIVE); break; 53.  	case MORGUE:	mkzoo(MORGUE); break; 54.  	case BARRACKS:	mkzoo(BARRACKS); break; 55.  	case SWAMP:	mkswamp; break; 56.  #ifdef ORACLE 57.  	case DELPHI:	mkdelphi; break; 58.  #endif 59.  #if defined(ALTARS) && defined(THEOLOGY) 60.  	case TEMPLE:	mktemple; break; 61.  #endif 62.  	default:	impossible("Tried to make a room of type %d.", roomtype); 63.      }  64.   }  65.    66.   static void 67.  mkshop 68.  {  69.   	register struct mkroom *sroom; 70.  	int i = -1; 71.  #ifdef WIZARD 72.  	register char *ep; 73.   74.   	/* first determine shoptype */ 75.  	if(wizard){ 76.  		ep = getenv("SHOPTYPE"); 77.  		if(ep){ 78.  			if(*ep == 'z' || *ep == 'Z'){ 79.  				mkzoo(ZOO); 80.  				return; 81.  			}  82.   			if(*ep == 'm' || *ep == 'M'){ 83.  				mkzoo(MORGUE); 84.  				return; 85.  			}  86.   			if(*ep == 'b' || *ep == 'B'){ 87.  				mkzoo(BEEHIVE); 88.  				return; 89.  			}  90.   #ifdef THRONES 91.  			if(*ep == 't' || *ep == 'T'){ 92.  				mkzoo(COURT); 93.  				return; 94.  			}  95.   #endif 96.  #ifdef ARMY 97.  			if(*ep == 's' || *ep == 'S'){ 98.  				mkzoo(BARRACKS); 99.  				return; 100. 			}  101.  #endif /* ARMY */ 102. #if defined(ALTARS) && defined(THEOLOGY) 103. 			if(*ep == '_'){ 104. 				mktemple; 105. 				return; 106. 			}  107.  #endif 108. 			if(*ep == '}'){ 109. 				mkswamp; 110. 				return; 111. 			}  112.  			for(i=0; shtypes[i].name; i++) 113. 				if(*ep == shtypes[i].symb) goto gottype; 114. 			i = -1; 115. 		}  116.  	}  117.  gottype: 118. #endif 119. 	for(sroom = &rooms[0]; ; sroom++){ 120. 		if(sroom->hx < 0) return; 121. 		if(sroom - rooms >= nroom) { 122. 			pline("rooms not closed by -1?"); 123. 			return; 124. 		}  125.  		if(sroom->rtype != OROOM) continue; 126. 		if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) 127. 			continue; 128. 		if(  129.  #ifdef WIZARD  130.  		   (wizard && ep && sroom->doorct != 0) ||  131.  #endif  132.  			sroom->doorct == 1) break; 133. 	}  134.   135.  	if(i < 0) {			/* shoptype not yet determined */ 136. 	    register int j;  137. 138. 	    /* pick a shop type at random */ 139. 	    for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++) 140. 		if (j < 0)	break; 141.  142.  	    /* big rooms cannot be wand or book shops, 143. 	     * - so make them general stores 144. 	     */  145.  	    if(isbig(sroom) && (shtypes[i].symb == WAND_SYM 146. #ifdef SPELLS 147. 				|| shtypes[i].symb == SPBOOK_SYM 148. #endif 149. 								)) i = 0; 150. 	}  151.  	sroom->rtype = SHOPBASE + i;  152. 153. 	/* stock the room with a shopkeeper and artifacts */ 154. 	stock_room(&(shtypes[i]), sroom); 155. }  156.   157.  static struct mkroom * 158. pick_room 159. /* pick an unused room, preferably with only one door */ 160. {  161.  	register struct mkroom *sroom; 162. 	register int i = nroom; 163.  164.  	for(sroom = &rooms[rn2(nroom)]; i--; sroom++) { 165. 		if(sroom == &rooms[nroom]) 166. 			sroom = &rooms[0]; 167. 		if(sroom->hx < 0) 168. 			return (struct mkroom *)0; 169. 		if(sroom->rtype != OROOM)	continue; 170. 		if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 171. 			continue; 172. 		if(sroom->doorct == 1 || !rn2(5)) 173. 			return sroom; 174. 	}  175.  	return (struct mkroom *)0; 176. }  177.   178.  static void 179. mkzoo(type) 180. int type; 181. {  182.  	register struct mkroom *sroom; 183. 	struct monst *mon; 184. 	register int sx,sy,i; 185. 	int sh, tx, ty, goldlim = 500 * dlevel; 186.  187.  	if(!(sroom = pick_room)) return; 188.  189.  	sroom->rtype = type; 190. 	sh = sroom->fdoor; 191. 	switch(type) { 192. 	    case COURT: 193. 		tx = somex(sroom); ty = somey(sroom); break; 194. 		/* TODO: try to ensure the enthroned monster is an M2_PRINCE */ 195. 	    case BEEHIVE: 196. 		tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2; 197. 		ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2; 198. 		break; 199. 	}  200.  	for(sx = sroom->lx; sx <= sroom->hx; sx++) 201. 	    for(sy = sroom->ly; sy <= sroom->hy; sy++){ 202. 		if((sx == sroom->lx && doors[sh].x == sx-1) ||  203.  		   (sx == sroom->hx && doors[sh].x == sx+1) ||  204.  		   (sy == sroom->ly && doors[sh].y == sy-1) ||  205.  		   (sy == sroom->hy && doors[sh].y == sy+1)) continue; 206. 		mon = makemon(  207.  #ifdef THRONES  208.  		    (type == COURT) ? courtmon :  209.  #endif  210.  #ifdef ARMY  211.  		    (type == BARRACKS) ? squadmon :  212.  #endif  213.  		    (type == MORGUE) ? morguemon :  214.  		    (type == BEEHIVE) ?  215.  			(sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 216. 			 &mons[PM_KILLER_BEE]) :  217.  		    (struct permonst *) 0,  218.  		   sx, sy); 219. 		if(mon) { 220. 			mon->msleep = 1; 221. #ifdef THRONES 222. 			if (type==COURT && mon->mpeaceful) { 223. 				mon->mpeaceful = 0; 224. 				mon->malign = max(3,abs(mon->data->maligntyp)); 225. 			}  226.  #endif 227. 		}  228.  		switch(type) { 229. 		    case ZOO: 230. 			i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y)); 231. 			if(i >= goldlim) i = 5*dlevel; 232. 			goldlim -= i;  233. mkgold((long)(10 + rn2(i)), sx, sy); 234. 			break; 235. 		    case MORGUE: 236. 			if(!rn2(5)) 237. 			    (void) mk_tt_corpse(sx, sy); 238. 			if(!rn2(10))	/* lots of treasure buried with dead */ 239. 			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy); 240. 			break; 241. 		    case BEEHIVE: 242. 			if(!rn2(3)) 243. 			    (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); 244. 			break; 245. 		    case BARRACKS: 246. 			if(!rn2(20))	/* the payroll and some loot */ 247. 			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy); 248. 			break; 249. 		}  250.  	}  251.  #ifdef THRONES 252. 	if(type == COURT)  { 253. 		levl[tx][ty].typ = THRONE; 254. 		levl[tx][ty].scrsym = THRONE_SYM; 255.  256.  		tx = somex(sroom); 257. 		ty = somey(sroom); 258. 		mkgold((long) rn1(50 * dlevel,10), sx, sy); 259. 		(void) mksobj_at(CHEST, sx, sy);    /* the royal coffers */ 260. 	}  261.  #endif 262.  263.  }  264.   265.  static struct permonst * 266. morguemon 267. {  268.  	register int i = rn2(100), hd = rn2(dlevel); 269.  270.  	if(hd > 10 && i < 10) 271. 		return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon]); 272. 	if(hd > 8 && i > 85) 273. 		return(mkclass(S_VAMPIRE)); 274.  275.  	return((i < 20) ? &mons[PM_GHOST]  276.  			: (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE)); 277. }  278.   279.  static void 280. mkswamp	/* Michiel Huisjes & Fred de Wilde */ 281. {  282.  	register struct mkroom *sroom; 283. 	register int sx,sy,i,eelct = 0; 284.  285.  	for(i=0; i<5; i++) {		/* 5 tries */ 286. 		sroom = &rooms[rn2(nroom)]; 287. 		if(sroom->hx < 0 || sroom->rtype != OROOM ||  288.  		   has_upstairs(sroom) || has_dnstairs(sroom)) 289. 			continue; 290.  291.  		/* satisfied; make a swamp */ 292. 		sroom->rtype = SWAMP; 293. 		for(sx = sroom->lx; sx <= sroom->hx; sx++) 294. 		for(sy = sroom->ly; sy <= sroom->hy; sy++) 295. 		if(levl[sx][sy].omask == 0 && levl[sx][sy].gmask == 0 &&  296.  		   levl[sx][sy].mmask == 0 &&  297.  		   !t_at(sx,sy) && !nexttodoor(sx,sy)) { 298. 		    if((sx+sy)%2) { 299. 			levl[sx][sy].typ = POOL; 300. 			levl[sx][sy].scrsym = POOL_SYM; 301. 			if(!eelct || !rn2(4)) { 302. 				(void) makemon(mkclass(S_EEL), sx, sy); 303. 				eelct++; 304. 			}  305.  		    } else if(!rn2(4))	/* swamps tend to be moldy */ 306. 			(void) makemon(mkclass(S_FUNGUS), sx, sy); 307. 		}  308.  	}  309.  }  310.   311.  #ifdef ORACLE 312. static void 313. mkdelphi 314. {  315.  	register struct mkroom *sroom; 316. 	register struct monst *oracl; 317. 	int dy,xx,yy; 318.  319.  	if(doorindex >= DOORMAX) return; 320. 	if(!(sroom = pick_room)) return; 321.  322.  	if(!place_oracle(sroom,&dy,&xx,&yy)) return; 323.  324.  	/* set up Oracle and environment */ 325. 	if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return; 326. 	sroom->rtype = DELPHI; 327. 	oracl->mpeaceful = 1; 328.  329.  	yy -= dy; 330. 	if(ACCESSIBLE(levl[xx-1][yy].typ)) 331. 		(void) mkstatue(&mons[PM_FOREST_CENTAUR], xx-1, yy); 332. 	if(ACCESSIBLE(levl[xx][yy].typ)) 333. 		(void) mkstatue(&mons[PM_MOUNTAIN_CENTAUR], xx, yy); 334. 	if(ACCESSIBLE(levl[xx+1][yy].typ)) 335. 		(void) mkstatue(&mons[PM_PLAINS_CENTAUR], xx+1, yy); 336. # ifdef FOUNTAINS 337. 	mkfount(0,sroom); 338. # endif 339. }  340.  #endif 341.  342.  #if defined(ALTARS) && defined(THEOLOGY) 343. void 344. shrine_pos(sx,sy,troom) 345. int *sx,*sy; 346. struct mkroom *troom; 347. {  348.  	*sx = troom->lx + ((troom->hx - troom->lx) / 2); 349. 	*sy = troom->ly + ((troom->hy - troom->ly) / 2); 350. }  351.   352.  static void 353. mktemple 354. {  355.  	register struct mkroom *sroom; 356. 	int sx,sy; 357.  358.  	if(!(sroom = pick_room)) return; 359.  360.  	/* set up Priest and shrine */ 361. 	sroom->rtype = TEMPLE; 362. 	shrine_pos(&sx,&sy,sroom); 363. 	/*  364.  	 * In temples, shrines are blessed altars 365. 	 * located in the center of the room 366. 	 */  367.  	levl[sx][sy].typ = ALTAR; 368. 	levl[sx][sy].scrsym = ALTAR_SYM; 369. 	levl[sx][sy].altarmask = rn2((int)A_LAW+1) | A_SHRINE; 370. 	priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask); 371. }  372.  #endif 373.  374.  boolean 375. nexttodoor(sx,sy) 376. register int sx, sy; 377. {  378.  	register int dx, dy; 379. 	register struct rm *lev; 380. 	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) 381. 		if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||  382.  		    lev->typ == SDOOR) 383. 			return(TRUE); 384. 	return(FALSE); 385. }  386.   387.  boolean 388. has_dnstairs(sroom) 389. register struct mkroom *sroom; 390. {  391.  	return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&  392.  		   sroom->ly <= ydnstair && ydnstair <= sroom->hy); 393. }  394.   395.  boolean 396. has_upstairs(sroom) 397. register struct mkroom *sroom; 398. {  399.  	return(sroom->lx <= xupstair && xupstair <= sroom->hx &&  400.  		   sroom->ly <= yupstair && yupstair <= sroom->hy); 401. }  402.   403.  int 404. dist2(x0,y0,x1,y1) 405. int x0, y0, x1, y1; 406. {  407.  	register int dx = x0 - x1, dy = y0 - y1; 408. 	return sq(dx) + sq(dy); 409. }  410.   411.  #ifdef THRONES 412. struct permonst * 413. courtmon 414. {  415.  	int     i = rn2(60) + rn2(3*dlevel); 416. 	if (i > 100)		return(mkclass(S_DRAGON)); 417. 	else if (i > 95)	return(mkclass(S_GIANT)); 418. 	else if (i > 85)	return(mkclass(S_TROLL)); 419. 	else if (i > 75)	return(mkclass(S_CENTAUR)); 420. 	else if (i > 60)	return(mkclass(S_ORC)); 421. 	else if (i > 45)	return(&mons[PM_BUGBEAR]); 422. 	else if (i > 30)	return(&mons[PM_HOBGOBLIN]); 423. 	else if (i > 15)	return(mkclass(S_GNOME)); 424. 	else			return(mkclass(S_KOBOLD)); 425. }  426.  #endif /* THRONES /**/ 427.  428.  #ifdef ARMY 429. #define	    NSTYPES	(PM_CAPTAIN-PM_SOLDIER+1) 430.  431.  struct { 432.     unsigned	pm; 433.     unsigned	prob; 434. }   squadprob[NSTYPES] = { 435.     PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1 436. };  437.   438.  static struct permonst * 439. squadmon {	    /* return soldier types. */ 440.   441.  	register struct permonst *ptr; 442. 	register int	i, cpro, sel = rnd(80+dlevel); 443.  444.  	for(cpro = i = 0; i < NSTYPES; i++) 445. 	    if((cpro += squadprob[i].prob) > sel) { 446.  447.  		ptr = &mons[squadprob[i].pm]; 448. 		goto gotone; 449. 	    }  450.  	ptr = &mons[squadprob[rn2(NSTYPES)].pm]; 451. gotone: 452. 	if(!(ptr->geno & G_GENOD))  return(ptr); 453. 	else			    return((struct permonst *) 0); 454. }  455.  #endif /* ARMY /* */