Source:NetHack 3.0.0/extralev.c
Jump to navigation
Jump to search
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
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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 /**/