|
|
1.1 root 1: /*
2: * room.c
3: *
4: * This source herein may be modified and/or distributed by anybody who
5: * so desires, with the following restrictions:
6: * 1.) No portion of this notice shall be removed.
7: * 2.) Credit shall not be taken for the creation of this source.
8: * 3.) This code is not to be traded, sold, or used for personal
9: * gain or profit.
10: *
11: */
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)room.c 5.1 (Berkeley) 11/25/87";
15: #endif /* not lint */
16:
17: #include "rogue.h"
18:
19: room rooms[MAXROOMS];
20: boolean rooms_visited[MAXROOMS];
21:
22: extern short blind;
23: extern boolean detect_monster, jump, passgo, no_skull, ask_quit;
24: extern char *nick_name, *fruit, *save_file, *press_space;
25:
26: #define NOPTS 7
27:
28: struct option {
29: char *prompt;
30: boolean is_bool;
31: char **strval;
32: boolean *bval;
33: } options[NOPTS] = {
34: {
35: "Show position only at end of run (\"jump\"): ",
36: 1, (char **) 0, &jump
37: },
38: {
39: "Follow turnings in passageways (\"passgo\"): ",
40: 1, (char **) 0, &passgo
41: },
42: {
43: "Don't print skull when killed (\"noskull\" or \"notombstone\"): ",
44: 1, (char **) 0, &no_skull
45: },
46: {
47: "Ask player before saying 'Okay, bye-bye!' (\"askquit\"): ",
48: 1, (char **) 0, &ask_quit
49: },
50: {
51: "Name (\"name\"): ",
52: 0, &nick_name
53: },
54: {
55: "Fruit (\"fruit\"): ",
56: 0, &fruit
57: },
58: {
59: "Save file (\"file\"): ",
60: 0, &save_file
61: }
62: };
63:
64: light_up_room(rn)
65: int rn;
66: {
67: short i, j;
68:
69: if (!blind) {
70: for (i = rooms[rn].top_row;
71: i <= rooms[rn].bottom_row; i++) {
72: for (j = rooms[rn].left_col;
73: j <= rooms[rn].right_col; j++) {
74: if (dungeon[i][j] & MONSTER) {
75: object *monster;
76:
77: if (monster = object_at(&level_monsters, i, j)) {
78: dungeon[monster->row][monster->col] &= (~MONSTER);
79: monster->trail_char =
80: get_dungeon_char(monster->row, monster->col);
81: dungeon[monster->row][monster->col] |= MONSTER;
82: }
83: }
84: mvaddch(i, j, get_dungeon_char(i, j));
85: }
86: }
87: mvaddch(rogue.row, rogue.col, rogue.fchar);
88: }
89: }
90:
91: light_passage(row, col)
92: {
93: short i, j, i_end, j_end;
94:
95: if (blind) {
96: return;
97: }
98: i_end = (row < (DROWS-2)) ? 1 : 0;
99: j_end = (col < (DCOLS-1)) ? 1 : 0;
100:
101: for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
102: for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) {
103: if (can_move(row, col, row+i, col+j)) {
104: mvaddch(row+i, col+j, get_dungeon_char(row+i, col+j));
105: }
106: }
107: }
108: }
109:
110: darken_room(rn)
111: short rn;
112: {
113: short i, j;
114:
115: for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) {
116: for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) {
117: if (blind) {
118: mvaddch(i, j, ' ');
119: } else {
120: if (!(dungeon[i][j] & (OBJECT | STAIRS)) &&
121: !(detect_monster && (dungeon[i][j] & MONSTER))) {
122: if (!imitating(i, j)) {
123: mvaddch(i, j, ' ');
124: }
125: if ((dungeon[i][j] & TRAP) && (!(dungeon[i][j] & HIDDEN))) {
126: mvaddch(i, j, '^');
127: }
128: }
129: }
130: }
131: }
132: }
133:
134: get_dungeon_char(row, col)
135: register row, col;
136: {
137: register unsigned short mask = dungeon[row][col];
138:
139: if (mask & MONSTER) {
140: return(gmc_row_col(row, col));
141: }
142: if (mask & OBJECT) {
143: object *obj;
144:
145: obj = object_at(&level_objects, row, col);
146: return(get_mask_char(obj->what_is));
147: }
148: if (mask & (TUNNEL | STAIRS | HORWALL | VERTWALL | FLOOR | DOOR)) {
149: if ((mask & (TUNNEL| STAIRS)) && (!(mask & HIDDEN))) {
150: return(((mask & STAIRS) ? '%' : '#'));
151: }
152: if (mask & HORWALL) {
153: return('-');
154: }
155: if (mask & VERTWALL) {
156: return('|');
157: }
158: if (mask & FLOOR) {
159: if (mask & TRAP) {
160: if (!(dungeon[row][col] & HIDDEN)) {
161: return('^');
162: }
163: }
164: return('.');
165: }
166: if (mask & DOOR) {
167: if (mask & HIDDEN) {
168: if (((col > 0) && (dungeon[row][col-1] & HORWALL)) ||
169: ((col < (DCOLS-1)) && (dungeon[row][col+1] & HORWALL))) {
170: return('-');
171: } else {
172: return('|');
173: }
174: } else {
175: return('+');
176: }
177: }
178: }
179: return(' ');
180: }
181:
182: get_mask_char(mask)
183: register unsigned short mask;
184: {
185: switch(mask) {
186: case SCROL:
187: return('?');
188: case POTION:
189: return('!');
190: case GOLD:
191: return('*');
192: case FOOD:
193: return(':');
194: case WAND:
195: return('/');
196: case ARMOR:
197: return(']');
198: case WEAPON:
199: return(')');
200: case RING:
201: return('=');
202: case AMULET:
203: return(',');
204: default:
205: return('~'); /* unknown, something is wrong */
206: }
207: }
208:
209: gr_row_col(row, col, mask)
210: short *row, *col;
211: unsigned short mask;
212: {
213: short rn;
214: short r, c;
215:
216: do {
217: r = get_rand(MIN_ROW, DROWS-2);
218: c = get_rand(0, DCOLS-1);
219: rn = get_room_number(r, c);
220: } while ((rn == NO_ROOM) ||
221: (!(dungeon[r][c] & mask)) ||
222: (dungeon[r][c] & (~mask)) ||
223: (!(rooms[rn].is_room & (R_ROOM | R_MAZE))) ||
224: ((r == rogue.row) && (c == rogue.col)));
225:
226: *row = r;
227: *col = c;
228: }
229:
230: gr_room()
231: {
232: short i;
233:
234: do {
235: i = get_rand(0, MAXROOMS-1);
236: } while (!(rooms[i].is_room & (R_ROOM | R_MAZE)));
237:
238: return(i);
239: }
240:
241: party_objects(rn)
242: {
243: short i, j, nf = 0;
244: object *obj;
245: short n, N, row, col;
246: boolean found;
247:
248: N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) *
249: ((rooms[rn].right_col - rooms[rn].left_col) - 1);
250: n = get_rand(5, 10);
251: if (n > N) {
252: n = N - 2;
253: }
254: for (i = 0; i < n; i++) {
255: for (j = found = 0; ((!found) && (j < 250)); j++) {
256: row = get_rand(rooms[rn].top_row+1,
257: rooms[rn].bottom_row-1);
258: col = get_rand(rooms[rn].left_col+1,
259: rooms[rn].right_col-1);
260: if ((dungeon[row][col] == FLOOR) || (dungeon[row][col] == TUNNEL)) {
261: found = 1;
262: }
263: }
264: if (found) {
265: obj = gr_object();
266: place_at(obj, row, col);
267: nf++;
268: }
269: }
270: return(nf);
271: }
272:
273: get_room_number(row, col)
274: register row, col;
275: {
276: short i;
277:
278: for (i = 0; i < MAXROOMS; i++) {
279: if ((row >= rooms[i].top_row) && (row <= rooms[i].bottom_row) &&
280: (col >= rooms[i].left_col) && (col <= rooms[i].right_col)) {
281: return(i);
282: }
283: }
284: return(NO_ROOM);
285: }
286:
287: is_all_connected()
288: {
289: short i, starting_room;
290:
291: for (i = 0; i < MAXROOMS; i++) {
292: rooms_visited[i] = 0;
293: if (rooms[i].is_room & (R_ROOM | R_MAZE)) {
294: starting_room = i;
295: }
296: }
297:
298: visit_rooms(starting_room);
299:
300: for (i = 0; i < MAXROOMS; i++) {
301: if ((rooms[i].is_room & (R_ROOM | R_MAZE)) && (!rooms_visited[i])) {
302: return(0);
303: }
304: }
305: return(1);
306: }
307:
308: visit_rooms(rn)
309: int rn;
310: {
311: short i;
312: short oth_rn;
313:
314: rooms_visited[rn] = 1;
315:
316: for (i = 0; i < 4; i++) {
317: oth_rn = rooms[rn].doors[i].oth_room;
318: if ((oth_rn >= 0) && (!rooms_visited[oth_rn])) {
319: visit_rooms(oth_rn);
320: }
321: }
322: }
323:
324: draw_magic_map()
325: {
326: short i, j, ch, och;
327: unsigned short mask = (HORWALL | VERTWALL | DOOR | TUNNEL | TRAP | STAIRS |
328: MONSTER);
329: unsigned short s;
330:
331: for (i = 0; i < DROWS; i++) {
332: for (j = 0; j < DCOLS; j++) {
333: s = dungeon[i][j];
334: if (s & mask) {
335: if (((ch = mvinch(i, j)) == ' ') ||
336: ((ch >= 'A') && (ch <= 'Z')) || (s & (TRAP | HIDDEN))) {
337: och = ch;
338: dungeon[i][j] &= (~HIDDEN);
339: if (s & HORWALL) {
340: ch = '-';
341: } else if (s & VERTWALL) {
342: ch = '|';
343: } else if (s & DOOR) {
344: ch = '+';
345: } else if (s & TRAP) {
346: ch = '^';
347: } else if (s & STAIRS) {
348: ch = '%';
349: } else if (s & TUNNEL) {
350: ch = '#';
351: } else {
352: continue;
353: }
354: if ((!(s & MONSTER)) || (och == ' ')) {
355: addch(ch);
356: }
357: if (s & MONSTER) {
358: object *monster;
359:
360: if (monster = object_at(&level_monsters, i, j)) {
361: monster->trail_char = ch;
362: }
363: }
364: }
365: }
366: }
367: }
368: }
369:
370: dr_course(monster, entering, row, col)
371: object *monster;
372: boolean entering;
373: short row, col;
374: {
375: short i, j, k, rn;
376: short r, rr;
377:
378: monster->row = row;
379: monster->col = col;
380:
381: if (mon_sees(monster, rogue.row, rogue.col)) {
382: monster->trow = NO_ROOM;
383: return;
384: }
385: rn = get_room_number(row, col);
386:
387: if (entering) { /* entering room */
388: /* look for door to some other room */
389: r = get_rand(0, MAXROOMS-1);
390: for (i = 0; i < MAXROOMS; i++) {
391: rr = (r + i) % MAXROOMS;
392: if ((!(rooms[rr].is_room & (R_ROOM | R_MAZE))) || (rr == rn)) {
393: continue;
394: }
395: for (k = 0; k < 4; k++) {
396: if (rooms[rr].doors[k].oth_room == rn) {
397: monster->trow = rooms[rr].doors[k].oth_row;
398: monster->tcol = rooms[rr].doors[k].oth_col;
399: if ((monster->trow == row) &&
400: (monster->tcol == col)) {
401: continue;
402: }
403: return;
404: }
405: }
406: }
407: /* look for door to dead end */
408: for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
409: for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
410: if ((i != monster->row) && (j != monster->col) &&
411: (dungeon[i][j] & DOOR)) {
412: monster->trow = i;
413: monster->tcol = j;
414: return;
415: }
416: }
417: }
418: /* return monster to room that he came from */
419: for (i = 0; i < MAXROOMS; i++) {
420: for (j = 0; j < 4; j++) {
421: if (rooms[i].doors[j].oth_room == rn) {
422: for (k = 0; k < 4; k++) {
423: if (rooms[rn].doors[k].oth_room == i) {
424: monster->trow = rooms[rn].doors[k].oth_row;
425: monster->tcol = rooms[rn].doors[k].oth_col;
426: return;
427: }
428: }
429: }
430: }
431: }
432: /* no place to send monster */
433: monster->trow = NO_ROOM;
434: } else { /* exiting room */
435: if (!get_oth_room(rn, &row, &col)) {
436: monster->trow = NO_ROOM;
437: } else {
438: monster->trow = row;
439: monster->tcol = col;
440: }
441: }
442: }
443:
444: get_oth_room(rn, row, col)
445: short rn, *row, *col;
446: {
447: short d = -1;
448:
449: if (*row == rooms[rn].top_row) {
450: d = UPWARD/2;
451: } else if (*row == rooms[rn].bottom_row) {
452: d = DOWN/2;
453: } else if (*col == rooms[rn].left_col) {
454: d = LEFT/2;
455: } else if (*col == rooms[rn].right_col) {
456: d = RIGHT/2;
457: }
458: if ((d != -1) && (rooms[rn].doors[d].oth_room >= 0)) {
459: *row = rooms[rn].doors[d].oth_row;
460: *col = rooms[rn].doors[d].oth_col;
461: return(1);
462: }
463: return(0);
464: }
465:
466: edit_opts()
467: {
468: char save[NOPTS+1][DCOLS];
469: short i, j;
470: short ch;
471: boolean done = 0;
472: char buf[MAX_OPT_LEN + 2];
473:
474: for (i = 0; i < NOPTS+1; i++) {
475: for (j = 0; j < DCOLS; j++) {
476: save[i][j] = mvinch(i, j);
477: }
478: if (i < NOPTS) {
479: opt_show(i);
480: }
481: }
482: opt_go(0);
483: i = 0;
484:
485: while (!done) {
486: refresh();
487: ch = rgetchar();
488: CH:
489: switch(ch) {
490: case '\033':
491: done = 1;
492: break;
493: case '\012':
494: case '\015':
495: if (i == (NOPTS - 1)) {
496: mvaddstr(NOPTS, 0, press_space);
497: refresh();
498: wait_for_ack();
499: done = 1;
500: } else {
501: i++;
502: opt_go(i);
503: }
504: break;
505: case '-':
506: if (i > 0) {
507: opt_go(--i);
508: } else {
509: sound_bell();
510: }
511: break;
512: case 't':
513: case 'T':
514: case 'f':
515: case 'F':
516: if (options[i].is_bool) {
517: *(options[i].bval) = (((ch == 't') || (ch == 'T')) ? 1 : 0);
518: opt_show(i);
519: opt_go(++i);
520: break;
521: }
522: default:
523: if (options[i].is_bool) {
524: sound_bell();
525: break;
526: }
527: j = 0;
528: if ((ch == '\010') || ((ch >= ' ') && (ch <= '~'))) {
529: opt_erase(i);
530: do {
531: if ((ch >= ' ') && (ch <= '~') && (j < MAX_OPT_LEN)) {
532: buf[j++] = ch;
533: buf[j] = '\0';
534: addch(ch);
535: } else if ((ch == '\010') && (j > 0)) {
536: buf[--j] = '\0';
537: move(i, j + strlen(options[i].prompt));
538: addch(' ');
539: move(i, j + strlen(options[i].prompt));
540: }
541: refresh();
542: ch = rgetchar();
543: } while ((ch != '\012') && (ch != '\015') && (ch != '\033'));
544: if (j != 0) {
545: (void) strcpy(*(options[i].strval), buf);
546: }
547: opt_show(i);
548: goto CH;
549: } else {
550: sound_bell();
551: }
552: break;
553: }
554: }
555:
556: for (i = 0; i < NOPTS+1; i++) {
557: move(i, 0);
558: for (j = 0; j < DCOLS; j++) {
559: addch(save[i][j]);
560: }
561: }
562: }
563:
564: opt_show(i)
565: int i;
566: {
567: char *s;
568: struct option *opt = &options[i];
569:
570: opt_erase(i);
571:
572: if (opt->is_bool) {
573: s = *(opt->bval) ? "True" : "False";
574: } else {
575: s = *(opt->strval);
576: }
577: addstr(s);
578: }
579:
580: opt_erase(i)
581: int i;
582: {
583: struct option *opt = &options[i];
584:
585: mvaddstr(i, 0, opt->prompt);
586: clrtoeol();
587: }
588:
589: opt_go(i)
590: int i;
591: {
592: move(i, strlen(options[i].prompt));
593: }
594:
595: do_shell()
596: {
597: #ifdef UNIX
598: char *sh;
599:
600: md_ignore_signals();
601: if (!(sh = md_getenv("SHELL"))) {
602: sh = "/bin/sh";
603: }
604: move(LINES-1, 0);
605: refresh();
606: stop_window();
607: printf("\nCreating new shell...\n");
608: md_shell(sh);
609: start_window();
610: wrefresh(curscr);
611: md_heed_signals();
612: #endif
613: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.