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