Source:NetHack 3.0.0/extralev.c

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

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

1.   /*	SCCS Id: @(#)extralev.c	3.0	88/04/11			*/ 2.   /*	Copyright 1988, 1989 by Ken Arromdee				*/ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /* block some unused #defines to avoid overloading some cpp's */ 6.   #define MONATTK_H 7.   #include "hack.h"  8. 9.   #ifdef REINCARNATION 10.   11.   struct rogueroom { 12.  	xchar rlx, rly; 13.  	xchar dx, dy; 14.  	boolean real; 15.  	uchar doortable; 16.  	int nroom; /* Only meaningful for "real" rooms */ 17.  };  18.   #define UP 1 19.  #define DOWN 2 20.  #define LEFT 4 21.  #define RIGHT 8 22.   23.   static struct rogueroom r[3][3]; 24.   25.   static 26.  void 27.  roguejoin(x1,y1,x2,y2, horiz) 28.  int x1,y1,x2,y2; 29.  int horiz; 30.  {  31.   	register int x,y,middle; 32.  #define MAX(a,b) (((a) > (b)) ? (a) : (b)) 33.  #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 34.  	if (horiz) { 35.  		middle = x1 + rn2(x2-x1+1); 36.  		for(x=MIN(x1,middle); x<=MAX(x1,middle); x++) 37.  			corr(x, y1); 38.  		for(y=MIN(y1,y2); y<=MAX(y1,y2); y++) 39.  			corr(middle,y); 40.  		for(x=MIN(middle,x2); x<=MAX(middle,x2); x++) 41.  			corr(x, y2); 42.  	} else { 43.  		middle = y1 + rn2(y2-y1+1); 44.  		for(y=MIN(y1,middle); y<=MAX(y1,middle); y++) 45.  			corr(x1, y); 46.  		for(x=MIN(x1,x2); x<=MAX(x1,x2); x++) 47.  			corr(x, middle); 48.  		for(y=MIN(middle,y2); y<=MAX(middle,y2); y++) 49.  			corr(x2,y); 50.  	}  51.   }  52.    53.   static 54.  void 55.  roguecorr(x, y, dir) 56.  int x,y,dir; 57.  {  58.   	register int fromx, fromy, tox, toy; 59.   60.   	if (dir==DOWN) { 61.  		r[x][y].doortable &= ~DOWN; 62.  		if (!r[x][y].real) { 63.  			fromx = r[x][y].rlx; fromy = r[x][y].rly; 64.  			fromx += 1 + 26*x; fromy += 7*y; 65.  		} else { 66.  			fromx = r[x][y].rlx + rn2(r[x][y].dx); 67.  			fromy = r[x][y].rly + r[x][y].dy; 68.  			fromx += 1 + 26*x; fromy += 7*y; 69.  			if (!IS_WALL(levl[fromx][fromy].typ)) 70.  				impossible("down: no wall at %d,%d?",fromx,  71.   									fromy); 72.  			dodoor(fromx, fromy, &rooms[r[x][y].nroom]); 73.  			levl[fromx][fromy].doormask = D_NODOOR; 74.  			fromy++; 75.  		}  76.   		if(y >= 2) { 77.  			impossible("down door from %d,%d going nowhere?",x,y); 78.  			return; 79.  		}  80.   		y++; 81.  		r[x][y].doortable &= ~UP; 82.  		if (!r[x][y].real) { 83.  			tox = r[x][y].rlx; toy = r[x][y].rly; 84.  			tox += 1 + 26*x; toy += 7*y; 85.  		} else { 86.  			tox = r[x][y].rlx + rn2(r[x][y].dx); 87.  			toy = r[x][y].rly - 1; 88.  			tox += 1 + 26*x; toy += 7*y; 89.  			if (!IS_WALL(levl[tox][toy].typ)) 90.  				impossible("up: no wall at %d,%d?",tox,toy); 91.  			dodoor(tox, toy, &rooms[r[x][y].nroom]); 92.  			levl[tox][toy].doormask = D_NODOOR; 93.  			toy--; 94.  		}  95.   		roguejoin(fromx, fromy, tox, toy, FALSE); 96.  		return; 97.  	} else if (dir == RIGHT) { 98.  		r[x][y].doortable &= ~RIGHT; 99.  		if (!r[x][y].real) { 100. 			fromx = r[x][y].rlx; fromy = r[x][y].rly; 101. 			fromx += 1 + 26*x; fromy += 7*y; 102. 		} else { 103. 			fromx = r[x][y].rlx + r[x][y].dx; 104. 			fromy = r[x][y].rly + rn2(r[x][y].dy); 105. 			fromx += 1 + 26*x; fromy += 7*y; 106. 			if (!IS_WALL(levl[fromx][fromy].typ)) 107. 				impossible("down: no wall at %d,%d?",fromx,  108.  									fromy); 109. 			dodoor(fromx, fromy, &rooms[r[x][y].nroom]); 110. 			levl[fromx][fromy].doormask = D_NODOOR; 111. 			fromx++; 112. 		}  113.  		if(x >= 2) { 114. 			impossible("right door from %d,%d going nowhere?",x,y); 115. 			return; 116. 		}  117.  		x++; 118. 		r[x][y].doortable &= ~LEFT; 119. 		if (!r[x][y].real) { 120. 			tox = r[x][y].rlx; toy = r[x][y].rly; 121. 			tox += 1 + 26*x; toy += 7*y; 122. 		} else { 123. 			tox = r[x][y].rlx - 1; 124. 			toy = r[x][y].rly + rn2(r[x][y].dy); 125. 			tox += 1 + 26*x; toy += 7*y; 126. 			if (!IS_WALL(levl[tox][toy].typ)) 127. 				impossible("left: no wall at %d,%d?",tox,toy); 128. 			dodoor(tox, toy, &rooms[r[x][y].nroom]); 129. 			levl[tox][toy].doormask = D_NODOOR; 130. 			tox--; 131. 		}  132.  		roguejoin(fromx, fromy, tox, toy, TRUE); 133. 		return; 134. 	} else impossible("corridor in direction %d?",dir); 135. }  136.  			  137.  /* Modified walkfrom from mkmaze.c */ 138. static 139. void 140. miniwalk(x, y)  141. int x,y; 142. {  143.  	register int q, dir; 144. 	int dirs[4]; 145.  146.  	while(1) { 147. 		q = 0; 148. #define doorhere (r[x][y].doortable) 149. 		if (x>0 && (!(doorhere & LEFT)) &&  150.  					(!r[x-1][y].doortable || !rn2(10))) 151. 			dirs[q++] = 0; 152. 		if (x<2 && (!(doorhere & RIGHT)) &&  153.  					(!r[x+1][y].doortable || !rn2(10))) 154. 			dirs[q++] = 1; 155. 		if (y>0 && (!(doorhere & UP)) &&  156.  					(!r[x][y-1].doortable || !rn2(10))) 157. 			dirs[q++] = 2; 158. 		if (y<2 && (!(doorhere & DOWN)) &&  159.  					(!r[x][y+1].doortable || !rn2(10))) 160. 			dirs[q++] = 3; 161. 	/* Rogue levels aren't just 3 by 3 mazes; they have some extra 162. 	 * connections, thus that 1/10 chance 163. 	 */  164.  		if (!q) return; 165. 		dir = dirs[rn2(q)]; 166. 		switch(dir) { /* Move in direction */ 167. 			case 0: doorhere |= LEFT; 168. 				x--; 169. 				doorhere |= RIGHT; 170. 				break; 171. 			case 1: doorhere |= RIGHT; 172. 				x++; 173. 				doorhere |= LEFT; 174. 				break; 175. 			case 2: doorhere |= UP; 176. 				y--; 177. 				doorhere |= DOWN; 178. 				break; 179. 			case 3: doorhere |= DOWN; 180. 				y++; 181. 				doorhere |= UP; 182. 				break; 183. 		}  184.  		miniwalk(x,y); 185. 	}  186.  }  187.   188.  void 189. makeroguerooms { 190. 	register struct mkroom *croom; 191. 	register int x,y; 192. 	int x2, y2; 193. 	/* Rogue levels are structured 3 by 3, with each section containing 194. 	 * a room or an intersection. The minimum width is 2 each way. 195. 	 * One difference between these and "real" Rogue levels: real Rogue 196. 	 * uses 24 rows and NetHack only 23. So we cheat a bit by making the 197. 	 * second row of rooms not as deep. 198. 	 *  199.  	 * Each normal space has 6/7 rows and 25 columns in which a room may 200. 	 * actually be placed. Walls go from rows 0-5/6 and columns 0-24. 201. 	 * Not counting walls, the room may go in  202. * rows 1-5 and columns 1-23 (numbering starting at 0). A room 203. 	 * coordinate of this type may be converted to a level coordinate 204. 	 * by adding 1+28*x to the column, and 7*y to the row. (The 1 205.  	 * is because column 0 isn't used [we only use 1-78]). 206. 	 * Room height may be 2-4 (2-5 on last row), length 2-23 (not  207.  	 * counting walls) 208. 	 */  209.  #define here r[x][y] 210.  211.  	nroom = 0; 212. 	for(y=0; y<3; y++) for(x=0; x<3; x++) { 213. 		/* Note: we want to insure at least 1 room. So, if the 214. 		 * first 8 are all dummies, force the last to be a room. 215. 		 */  216.  		if (!rn2(5) && (nroom || (x<2 && y<2))) { 217. 			/* Arbitrary: dummy rooms may only go where real 218. 			 * ones do. 219. 			 */  220.  			here.real = FALSE; 221. 			here.rlx = rn1(22, 2); 222. 			here.rly = rn1((y==2)?4:3, 2); 223. 		} else { 224. 			here.real = TRUE; 225. 			here.dx = rn1(22, 2); /* 2-23 long, plus walls */ 226. 			here.dy = rn1((y==2)?4:3, 2); /* 2-5 high, plus walls */ 227.  228.  			/* boundaries of room floor */ 229. 			here.rlx = rnd(23 - here.dx + 1); 230. 			here.rly = rnd(((y==2) ? 5 : 4)- here.dy + 1); 231. 			nroom++; 232. 		}  233.  		here.doortable = 0; 234. 	}  235.  	miniwalk(rn2(3), rn2(3)); 236. 	nroom = 0; 237. 	for(y=0; y<3; y++) for(x=0; x<3; x++) { 238. 		if (here.real) { /* Make a room */ 239. 			r[x][y].nroom = nroom; 240. 			croom = &rooms[nroom]; 241. 			/* Illumination. Strictly speaking, it should be lit 242. 			 * only if above level 10, but since Rogue rooms are 243. 			 * only encountered below level 10...  244. */ 245.  			if (!rn2(7)) { 246. 				for(x2 = 1+26*x+here.rlx-1;  247.  				    x2 <= 1+26*x+here.rlx+here.dx; x2++) 248. 				for(y2 = 7*y+here.rly-1;  249.  				    y2 <= 7*y+here.rly+here.dy; y2++) 250. 					levl[x2][y2].lit = 1; 251. 				croom->rlit = 1; 252. 			} else croom->rlit = 0; 253. 			croom->lx = 1 + 26*x + here.rlx; 254. 			croom->ly = 7*y + here.rly; 255. 			croom->hx = 1 + 26*x + here.rlx + here.dx - 1; 256. 			croom->hy = 7*y + here.rly + here.dy - 1; 257. 			/* Walls, doors, and floors. */ 258.  #define lowx croom->lx 259. #define lowy croom->ly 260. #define hix croom->hx 261. #define hiy croom->hy 262. 			for(x2 = lowx-1; x2 <= hix+1; x2++) 263. 			    for(y2 = lowy-1; y2 <= hiy+1; y2 += (hiy-lowy+2)) { 264. 				levl[x2][y2].scrsym = HWALL_SYM; 265. 				levl[x2][y2].typ = HWALL; 266. 			}  267.  			for(x2 = lowx-1; x2 <= hix+1; x2 += (hix-lowx+2)) 268. 			    for(y2 = lowy; y2 <= hiy; y2++) { 269. 				levl[x2][y2].scrsym = VWALL_SYM; 270. 				levl[x2][y2].typ = VWALL; 271. 			}  272.  			for(x2 = lowx; x2 <= hix; x2++) 273. 			    for(y2 = lowy; y2 <= hiy; y2++) { 274. 				levl[x2][y2].scrsym = ROOM_SYM; 275. 				levl[x2][y2].typ = ROOM; 276. 			}  277.  			levl[lowx-1][lowy-1].typ = TLCORNER; 278. 			levl[hix+1][lowy-1].typ = TRCORNER; 279. 			levl[lowx-1][hiy+1].typ = BLCORNER; 280. 			levl[hix+1][hiy+1].typ = BRCORNER; 281. 			levl[lowx-1][lowy-1].scrsym = TLCORN_SYM; 282. 			levl[hix+1][lowy-1].scrsym = TRCORN_SYM; 283. 			levl[lowx-1][hiy+1].scrsym = BLCORN_SYM; 284. 			levl[hix+1][hiy+1].scrsym = BRCORN_SYM; 285.  286.  			/* Misc. */ 287. 			smeq[nroom] = nroom; 288. 			croom->rtype = OROOM; 289. 			croom++; 290. 			croom->hx = -1; 291. 			nroom++; 292. 		}  293.  	}  294.   295.  	/* Now, add connecting corridors. */ 296.  	for(y=0; y<3; y++) for(x=0; x<3; x++) { 297. 		if (here.doortable & DOWN) 298. 			roguecorr(x, y, DOWN); 299. 		if (here.doortable & RIGHT) 300. 			roguecorr(x, y, RIGHT); 301. 		if (here.doortable & LEFT) 302. 			impossible ("left end of %d, %d never connected?",x,y); 303. 		if (here.doortable & UP) 304. 			impossible ("up end of %d, %d never connected?",x,y); 305. 	}  306.  }  307.   308.  void 309. corr(x,y) 310. {  311.  	if (rn2(50)) { 312. 		levl[x][y].typ = CORR; 313. 		levl[x][y].scrsym = CORR_SYM; 314. 	} else { 315. 		levl[x][y].typ = SCORR; 316. 		levl[x][y].scrsym = STONE_SYM; 317. 	}  318.  }  319.   320.  void 321. makerogueghost 322. {  323.  	register struct monst *ghost; 324. 	struct obj *ghostobj; 325. 	struct mkroom *croom; 326. 	int x,y; 327.  328.  	if (!nroom) return; /* Should never happen */ 329. 	croom = &rooms[rn2(nroom)]; 330. 	x = somex(croom); y = somey(croom); 331. 	if (!(ghost = makemon(&mons[PM_GHOST], x, y))) 332. 		return; 333. 	ghost->msleep = 1; 334. 	Strcpy((char *)ghost->mextra, roguename); 335.  336.  	if (rn2(4)) { 337. 		ghostobj = mksobj_at(FOOD_RATION,x,y); 338. 		ghostobj->quan = rnd(7); 339. 		ghostobj->owt = weight(ghostobj); 340. 	}  341.  	if (rn2(2)) { 342. 		ghostobj = mksobj_at(MACE,x,y); 343. 		ghostobj->spe = rnd(3); 344. 		if (rn2(4)) curse(ghostobj); 345. 	} else { 346. 		ghostobj = mksobj_at(TWO_HANDED_SWORD,x,y); 347. 		ghostobj->spe = rnd(5) - 2; 348. 		if (rn2(4)) curse(ghostobj); 349. 	}  350.  	ghostobj = mksobj_at(BOW,x,y); 351. 	ghostobj->spe = 1; 352. 	if (rn2(4)) curse(ghostobj); 353.  354.  	ghostobj = mksobj_at(ARROW,x,y); 355. 	ghostobj->spe = 0; 356. 	ghostobj->quan = rn1(10,25); 357. 	ghostobj->owt = weight(ghostobj); 358. 	if (rn2(4)) curse(ghostobj); 359.  360.  	if (rn2(2)) { 361. 		ghostobj = mksobj_at(RING_MAIL,x,y); 362. 		ghostobj->spe = rn2(3); 363. 		if (!rn2(3)) ghostobj->rustfree = 1; 364. 		if (rn2(4)) curse(ghostobj); 365. 	} else { 366. 		ghostobj = mksobj_at(PLATE_MAIL,x,y); 367. 		ghostobj->spe = rnd(5) - 2; 368. 		if (!rn2(3)) ghostobj->rustfree = 1; 369. 		if (rn2(4)) curse(ghostobj); 370. 	}  371.  	if (rn2(2)) { 372. 		ghostobj = mksobj_at(AMULET_OF_YENDOR,x,y); 373. 		ghostobj->spe = -1; 374. 		ghostobj->known = TRUE; 375. 	}  376.  }  377.  #endif /* REINCARNATION /**/