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