1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64: #include <sys/cdefs.h>
65: #ifndef lint
66: __RCSID("$NetBSD: hack.mklev.c,v 1.6 2003/04/02 18:36:38 jsm Exp $");
67: #endif
68:
69: #include <unistd.h>
70: #include <stdlib.h>
71: #include "hack.h"
72: #include "extern.h"
73:
74: #define somex() ((random()%(croom->hx-croom->lx+1))+croom->lx)
75: #define somey() ((random()%(croom->hy-croom->ly+1))+croom->ly)
76:
77: #include "def.mkroom.h"
78: #define XLIM 4
79:
80: #define YLIM 3
81: boolean secret;
82:
83: int smeq[MAXNROFROOMS + 1];
84: int doorindex;
85: struct rm zerorm;
86: schar nxcor;
87: boolean goldseen;
88: int nroom;
89:
90:
91: #define MAXRS 50
92:
93: struct rectangle {
94: xchar rlx, rly, rhx, rhy;
95: } rs[MAXRS + 1];
96: int rscnt, rsmax;
97:
98:
99: void
100: makelevel()
101: {
102: struct mkroom *croom, *troom;
103: unsigned tryct;
104: int x, y;
105:
106: nroom = 0;
107: doorindex = 0;
108: rooms[0].hx = -1;
109:
110: for (x = 0; x < COLNO; x++)
111: for (y = 0; y < ROWNO; y++)
112: levl[x][y] = zerorm;
113:
114: oinit();
115:
116: if (dlevel >= rn1(3, 26)) {
117: makemaz();
118: return;
119: }
120:
121: nroom = 0;
122: secret = FALSE;
123: (void) makerooms();
124:
125:
126: croom = &rooms[rn2(nroom)];
127: xdnstair = somex();
128: ydnstair = somey();
129: levl[xdnstair][ydnstair].scrsym = '>';
130: levl[xdnstair][ydnstair].typ = STAIRS;
131: if (nroom > 1) {
132: troom = croom;
133: croom = &rooms[rn2(nroom - 1)];
134: if (croom >= troom)
135: croom++;
136: }
137: xupstair = somex();
138: yupstair = somey();
139: levl[xupstair][yupstair].scrsym = '<';
140: levl[xupstair][yupstair].typ = STAIRS;
141:
142:
143: for (croom = rooms; croom->hx > 0; croom++) {
144:
145:
146:
147:
148:
149:
150:
151:
152: if (!rn2(3))
153: (void)
154: makemon((struct permonst *) 0, somex(), somey());
155:
156:
157: goldseen = FALSE;
158: while (!rn2(8 - (dlevel / 6)))
159: mktrap(0, 0, croom);
160: if (!goldseen && !rn2(3))
161: mkgold(0L, somex(), somey());
162: if (!rn2(3)) {
163: (void) mkobj_at(0, somex(), somey());
164: tryct = 0;
165: while (!rn2(5)) {
166: if (++tryct > 100) {
167: printf("tryct overflow4\n");
168: break;
169: }
170: (void) mkobj_at(0, somex(), somey());
171: }
172: }
173: }
174:
175: qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
176: makecorridors();
177: make_niches();
178:
179:
180: if (nroom <= (2 * MAXNROFROOMS / 3))
181: if (rn2(3)) {
182: troom = &rooms[nroom];
183: secret = TRUE;
184: if (makerooms()) {
185: troom->rtype = VAULT;
186: for (x = troom->lx; x <= troom->hx; x++)
187: for (y = troom->ly; y <= troom->hy; y++)
188: mkgold((long) (rnd(dlevel * 100) + 50), x, y);
189: if (!rn2(3))
190: makevtele();
191: }
192: }
193: #ifndef QUEST
194: #ifdef WIZARD
195: if (wizard && getenv("SHOPTYPE"))
196: mkshop();
197: else
198: #endif
199: if (dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3)
200: mkshop();
201: else if (dlevel > 6 && !rn2(7))
202: mkzoo(ZOO);
203: else if (dlevel > 9 && !rn2(5))
204: mkzoo(BEEHIVE);
205: else if (dlevel > 11 && !rn2(6))
206: mkzoo(MORGUE);
207: else if (dlevel > 18 && !rn2(6))
208: mkswamp();
209: #endif
210: }
211:
212: int
213: makerooms()
214: {
215: struct rectangle *rsp;
216: int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
217: int tryct = 0, xlim, ylim;
218:
219:
220: xlim = XLIM + secret;
221: ylim = YLIM + secret;
222: if (nroom == 0) {
223: rsp = rs;
224: rsp->rlx = rsp->rly = 0;
225: rsp->rhx = COLNO - 1;
226: rsp->rhy = ROWNO - 1;
227: rsmax = 1;
228: }
229: rscnt = rsmax;
230:
231:
232: while (rscnt > 0 && nroom < MAXNROFROOMS - 1) {
233: if (!secret && nroom > (MAXNROFROOMS / 3) &&
234: !rn2((MAXNROFROOMS - nroom) * (MAXNROFROOMS - nroom)))
235: return (0);
236:
237:
238: rsp = &rs[rn2(rscnt)];
239: hx = rsp->rhx;
240: hy = rsp->rhy;
241: lx = rsp->rlx;
242: ly = rsp->rly;
243:
244:
245: if (secret)
246: dx = dy = 1;
247: else {
248: dx = 2 + rn2((hx - lx - 8 > 20) ? 12 : 8);
249: dy = 2 + rn2(4);
250: if (dx * dy > 50)
251: dy = 50 / dx;
252: }
253:
254:
255: if (hx - lx < dx + dx / 2 + 2 * xlim || hy - ly < dy + dy / 3 + 2 * ylim) {
256:
257:
258: if (secret || !rn2(MAXNROFROOMS + 1 - nroom - tryct)) {
259: rscnt--;
260: rs[rsmax] = *rsp;
261: *rsp = rs[rscnt];
262: rs[rscnt] = rs[rsmax];
263: tryct = 0;
264: } else
265: tryct++;
266: continue;
267: }
268: lowx = lx + xlim + rn2(hx - lx - dx - 2 * xlim + 1);
269: lowy = ly + ylim + rn2(hy - ly - dy - 2 * ylim + 1);
270: hix = lowx + dx;
271: hiy = lowy + dy;
272:
273: if (maker(lowx, dx, lowy, dy)) {
274: if (secret)
275: return (1);
276: addrs(lowx - 1, lowy - 1, hix + 1, hiy + 1);
277: tryct = 0;
278: } else if (tryct++ > 100)
279: break;
280: }
281: return (0);
282: }
283:
284: void
285: addrs(lowx, lowy, hix, hiy)
286: int lowx, lowy, hix, hiy;
287: {
288: struct rectangle *rsp;
289: int lx, ly, hx, hy, xlim, ylim;
290: boolean discarded;
291:
292: xlim = XLIM + secret;
293: ylim = YLIM + secret;
294:
295:
296: for (rsp = &rs[rsmax - 1]; rsp >= rs; rsp--) {
297:
298: if ((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
299: (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
300: continue;
301: if ((discarded = (rsp >= &rs[rscnt]))) {
302: *rsp = rs[--rsmax];
303: } else {
304: rsmax--;
305: rscnt--;
306: *rsp = rs[rscnt];
307: if (rscnt != rsmax)
308: rs[rscnt] = rs[rsmax];
309: }
310: if (lowy - ly > 2 * ylim + 4)
311: addrsx(lx, ly, hx, lowy - 2, discarded);
312: if (lowx - lx > 2 * xlim + 4)
313: addrsx(lx, ly, lowx - 2, hy, discarded);
314: if (hy - hiy > 2 * ylim + 4)
315: addrsx(lx, hiy + 2, hx, hy, discarded);
316: if (hx - hix > 2 * xlim + 4)
317: addrsx(hix + 2, ly, hx, hy, discarded);
318: }
319: }
320:
321: void
322: addrsx(lx, ly, hx, hy, discarded)
323: int lx, ly, hx, hy;
324: boolean discarded;
325: {
326: struct rectangle *rsp;
327:
328:
329: for (rsp = rs; rsp < &rs[rsmax]; rsp++) {
330: if (lx >= rsp->rlx && hx <= rsp->rhx &&
331: ly >= rsp->rly && hy <= rsp->rhy)
332: return;
333: }
334:
335:
336: if (rsmax >= MAXRS) {
337: #ifdef WIZARD
338: if (wizard)
339: pline("MAXRS may be too small.");
340: #endif
341: return;
342: }
343: rsmax++;
344: if (!discarded) {
345: *rsp = rs[rscnt];
346: rsp = &rs[rscnt];
347: rscnt++;
348: }
349: rsp->rlx = lx;
350: rsp->rly = ly;
351: rsp->rhx = hx;
352: rsp->rhy = hy;
353: }
354:
355: int
356: comp(vx, vy)
357: const void *vx, *vy;
358: {
359: const struct mkroom *x = vx, *y = vy;
360: if (x->lx < y->lx)
361: return (-1);
362: return (x->lx > y->lx);
363: }
364:
365: coord
366: finddpos(int xl, int yl, int xh, int yh)
367: {
368: coord ff;
369: int x, y;
370:
371: x = (xl == xh) ? xl : (xl + rn2(xh - xl + 1));
372: y = (yl == yh) ? yl : (yl + rn2(yh - yl + 1));
373: if (okdoor(x, y))
374: goto gotit;
375:
376: for (x = xl; x <= xh; x++)
377: for (y = yl; y <= yh; y++)
378: if (okdoor(x, y))
379: goto gotit;
380:
381: for (x = xl; x <= xh; x++)
382: for (y = yl; y <= yh; y++)
383: if (levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR)
384: goto gotit;
385:
386: x = xl;
387: y = yh;
388: gotit:
389: ff.x = x;
390: ff.y = y;
391: return (ff);
392: }
393:
394:
395: int
396: okdoor(x, y)
397: int x, y;
398: {
399: if (levl[x - 1][y].typ == DOOR || levl[x + 1][y].typ == DOOR ||
400: levl[x][y + 1].typ == DOOR || levl[x][y - 1].typ == DOOR ||
401: levl[x - 1][y].typ == SDOOR || levl[x + 1][y].typ == SDOOR ||
402: levl[x][y - 1].typ == SDOOR || levl[x][y + 1].typ == SDOOR ||
403: (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
404: doorindex >= DOORMAX)
405: return (0);
406: return (1);
407: }
408:
409: void
410: dodoor(x, y, aroom)
411: int x, y;
412: struct mkroom *aroom;
413: {
414: if (doorindex >= DOORMAX) {
415: impossible("DOORMAX exceeded?");
416: return;
417: }
418: if (!okdoor(x, y) && nxcor)
419: return;
420: dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR);
421: }
422:
423: void
424: dosdoor(x, y, aroom, type)
425: int x, y;
426: struct mkroom *aroom;
427: int type;
428: {
429: struct mkroom *broom;
430: int tmp;
431:
432: if (!IS_WALL(levl[x][y].typ))
433: type = DOOR;
434: levl[x][y].typ = type;
435: if (type == DOOR)
436: levl[x][y].scrsym = '+';
437: aroom->doorct++;
438: broom = aroom + 1;
439: if (broom->hx < 0)
440: tmp = doorindex;
441: else
442: for (tmp = doorindex; tmp > broom->fdoor; tmp--)
443: doors[tmp] = doors[tmp - 1];
444: doorindex++;
445: doors[tmp].x = x;
446: doors[tmp].y = y;
447: for (; broom->hx >= 0; broom++)
448: broom->fdoor++;
449: }
450:
451:
452: int
453: maker(lowx, ddx, lowy, ddy)
454: schar lowx, ddx, lowy, ddy;
455: {
456: struct mkroom *croom;
457: int x, y, hix = lowx + ddx, hiy = lowy + ddy;
458: int xlim = XLIM + secret, ylim = YLIM + secret;
459:
460: if (nroom >= MAXNROFROOMS)
461: return (0);
462: if (lowx < XLIM)
463: lowx = XLIM;
464: if (lowy < YLIM)
465: lowy = YLIM;
466: if (hix > COLNO - XLIM - 1)
467: hix = COLNO - XLIM - 1;
468: if (hiy > ROWNO - YLIM - 1)
469: hiy = ROWNO - YLIM - 1;
470: chk:
471: if (hix <= lowx || hiy <= lowy)
472: return (0);
473:
474:
475: for (x = lowx - xlim; x <= hix + xlim; x++) {
476: for (y = lowy - ylim; y <= hiy + ylim; y++) {
477: if (levl[x][y].typ) {
478: #ifdef WIZARD
479: if (wizard && !secret)
480: pline("Strange area [%d,%d] in maker().", x, y);
481: #endif
482: if (!rn2(3))
483: return (0);
484: if (x < lowx)
485: lowx = x + xlim + 1;
486: else
487: hix = x - xlim - 1;
488: if (y < lowy)
489: lowy = y + ylim + 1;
490: else
491: hiy = y - ylim - 1;
492: goto chk;
493: }
494: }
495: }
496:
497: croom = &rooms[nroom];
498:
499:
500:
501: if ((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) {
502: for (x = lowx - 1; x <= hix + 1; x++)
503: for (y = lowy - 1; y <= hiy + 1; y++)
504: levl[x][y].lit = 1;
505: croom->rlit = 1;
506: } else
507: croom->rlit = 0;
508: croom->lx = lowx;
509: croom->hx = hix;
510: croom->ly = lowy;
511: croom->hy = hiy;
512: croom->rtype = croom->doorct = croom->fdoor = 0;
513:
514: for (x = lowx - 1; x <= hix + 1; x++)
515: for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
516: levl[x][y].scrsym = '-';