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