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: }

Defined functions

darken_room defined in line 110; used 2 times
do_shell defined in line 595; used 1 times
dr_course defined in line 370; used 1 times
draw_magic_map defined in line 324; used 2 times
edit_opts defined in line 466; used 1 times
get_mask_char defined in line 182; used 3 times
get_oth_room defined in line 444; used 1 times
gr_room defined in line 230; used 1 times
is_all_connected defined in line 287; used 1 times
opt_erase defined in line 580; used 2 times
opt_go defined in line 589; used 4 times
opt_show defined in line 564; used 3 times
party_objects defined in line 241; used 1 times
visit_rooms defined in line 308; used 2 times

Defined variables

options defined in line 33; used 9 times
rooms defined in line 19; used 102 times
sccsid defined in line 14; never used

Defined struct's

option defined in line 28; used 4 times

Defined macros

NOPTS defined in line 26; used 7 times
Last modified: 1987-11-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4322
Valid CSS Valid XHTML 1.0 Strict