|
|
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.