1: /*
   2:  * level.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[] = "@(#)level.c	5.1 (Berkeley) 11/25/87";
  15: #endif /* not lint */
  16: 
  17: #include "rogue.h"
  18: 
  19: #define swap(x,y) {t = x; x = y; y = t;}
  20: 
  21: short cur_level = 0;
  22: short max_level = 1;
  23: short cur_room;
  24: char *new_level_message = 0;
  25: short party_room = NO_ROOM;
  26: short r_de;
  27: 
  28: long level_points[MAX_EXP_LEVEL] = {
  29:           10L,
  30:           20L,
  31:           40L,
  32:           80L,
  33:          160L,
  34:          320L,
  35:          640L,
  36:         1300L,
  37:         2600L,
  38:         5200L,
  39:        10000L,
  40:        20000L,
  41:        40000L,
  42:        80000L,
  43:       160000L,
  44:       320000L,
  45:      1000000L,
  46:      3333333L,
  47:      6666666L,
  48:       MAX_EXP,
  49:     99900000L
  50: };
  51: 
  52: short random_rooms[MAXROOMS] = {3, 7, 5, 2, 0, 6, 1, 4, 8};
  53: 
  54: extern boolean being_held, wizard, detect_monster;
  55: extern boolean see_invisible;
  56: extern short bear_trap, levitate, extra_hp, less_hp, cur_room;
  57: 
  58: make_level()
  59: {
  60:     short i, j;
  61:     short must_1, must_2, must_3;
  62:     boolean big_room;
  63: 
  64:     if (cur_level < LAST_DUNGEON) {
  65:         cur_level++;
  66:     }
  67:     if (cur_level > max_level) {
  68:         max_level = cur_level;
  69:     }
  70:     must_1 = get_rand(0, 5);
  71: 
  72:     switch(must_1) {
  73:     case 0:
  74:         must_1 = 0;
  75:         must_2 = 1;
  76:         must_3 = 2;
  77:         break;
  78:     case 1:
  79:         must_1 = 3;
  80:         must_2 = 4;
  81:         must_3 = 5;
  82:         break;
  83:     case 2:
  84:         must_1 = 6;
  85:         must_2 = 7;
  86:         must_3 = 8;
  87:         break;
  88:     case 3:
  89:         must_1 = 0;
  90:         must_2 = 3;
  91:         must_3 = 6;
  92:         break;
  93:     case 4:
  94:         must_1 = 1;
  95:         must_2 = 4;
  96:         must_3 = 7;
  97:         break;
  98:     case 5:
  99:         must_1 = 2;
 100:         must_2 = 5;
 101:         must_3 = 8;
 102:         break;
 103:     }
 104:     if (rand_percent(8)) {
 105:         party_room = 0;
 106:     }
 107:     big_room = ((party_room != NO_ROOM) && rand_percent(1));
 108:     if (big_room) {
 109:         make_room(BIG_ROOM, 0, 0, 0);
 110:     } else {
 111:         for (i = 0; i < MAXROOMS; i++) {
 112:             make_room(i, must_1, must_2, must_3);
 113:         }
 114:     }
 115:     if (!big_room) {
 116:         add_mazes();
 117: 
 118:         mix_random_rooms();
 119: 
 120:         for (j = 0; j < MAXROOMS; j++) {
 121: 
 122:             i = random_rooms[j];
 123: 
 124:             if (i < (MAXROOMS-1)) {
 125:                 (void) connect_rooms(i, i+1);
 126:             }
 127:             if (i < (MAXROOMS-3)) {
 128:                 (void) connect_rooms(i, i+3);
 129:             }
 130:             if (i < (MAXROOMS-2)) {
 131:                 if (rooms[i+1].is_room & R_NOTHING) {
 132:                     if (connect_rooms(i, i+2)) {
 133:                         rooms[i+1].is_room = R_CROSS;
 134:                     }
 135:                 }
 136:             }
 137:             if (i < (MAXROOMS-6)) {
 138:                 if (rooms[i+3].is_room & R_NOTHING) {
 139:                     if (connect_rooms(i, i+6)) {
 140:                         rooms[i+3].is_room = R_CROSS;
 141:                     }
 142:                 }
 143:             }
 144:             if (is_all_connected()) {
 145:                 break;
 146:             }
 147:         }
 148:         fill_out_level();
 149:     }
 150:     if (!has_amulet() && (cur_level >= AMULET_LEVEL)) {
 151:         put_amulet();
 152:     }
 153: }
 154: 
 155: make_room(rn, r1, r2, r3)
 156: short rn, r1, r2, r3;
 157: {
 158:     short left_col, right_col, top_row, bottom_row;
 159:     short width, height;
 160:     short row_offset, col_offset;
 161:     short i, j, ch;
 162: 
 163:     switch(rn) {
 164:     case 0:
 165:         left_col = 0;
 166:         right_col = COL1-1;
 167:         top_row = MIN_ROW;
 168:         bottom_row = ROW1-1;
 169:         break;
 170:     case 1:
 171:         left_col = COL1+1;
 172:         right_col = COL2-1;
 173:         top_row = MIN_ROW;
 174:         bottom_row = ROW1-1;
 175:         break;
 176:     case 2:
 177:         left_col = COL2+1;
 178:         right_col = DCOLS-1;
 179:         top_row = MIN_ROW;
 180:         bottom_row = ROW1-1;
 181:         break;
 182:     case 3:
 183:         left_col = 0;
 184:         right_col = COL1-1;
 185:         top_row = ROW1+1;
 186:         bottom_row = ROW2-1;
 187:         break;
 188:     case 4:
 189:         left_col = COL1+1;
 190:         right_col = COL2-1;
 191:         top_row = ROW1+1;
 192:         bottom_row = ROW2-1;
 193:         break;
 194:     case 5:
 195:         left_col = COL2+1;
 196:         right_col = DCOLS-1;
 197:         top_row = ROW1+1;
 198:         bottom_row = ROW2-1;
 199:         break;
 200:     case 6:
 201:         left_col = 0;
 202:         right_col = COL1-1;
 203:         top_row = ROW2+1;
 204:         bottom_row = DROWS - 2;
 205:         break;
 206:     case 7:
 207:         left_col = COL1+1;
 208:         right_col = COL2-1;
 209:         top_row = ROW2+1;
 210:         bottom_row = DROWS - 2;
 211:         break;
 212:     case 8:
 213:         left_col = COL2+1;
 214:         right_col = DCOLS-1;
 215:         top_row = ROW2+1;
 216:         bottom_row = DROWS - 2;
 217:         break;
 218:     case BIG_ROOM:
 219:         top_row = get_rand(MIN_ROW, MIN_ROW+5);
 220:         bottom_row = get_rand(DROWS-7, DROWS-2);
 221:         left_col = get_rand(0, 10);;
 222:         right_col = get_rand(DCOLS-11, DCOLS-1);
 223:         rn = 0;
 224:         goto B;
 225:     }
 226:     height = get_rand(4, (bottom_row - top_row + 1));
 227:     width = get_rand(7, (right_col - left_col - 2));
 228: 
 229:     row_offset = get_rand(0, ((bottom_row - top_row) - height + 1));
 230:     col_offset = get_rand(0, ((right_col - left_col) - width + 1));
 231: 
 232:     top_row += row_offset;
 233:     bottom_row = top_row + height - 1;
 234: 
 235:     left_col += col_offset;
 236:     right_col = left_col + width - 1;
 237: 
 238:     if ((rn != r1) && (rn != r2) && (rn != r3) && rand_percent(40)) {
 239:         goto END;
 240:     }
 241: B:
 242:     rooms[rn].is_room = R_ROOM;
 243: 
 244:     for (i = top_row; i <= bottom_row; i++) {
 245:         for (j = left_col; j <= right_col; j++) {
 246:             if ((i == top_row) || (i == bottom_row)) {
 247:                 ch = HORWALL;
 248:             } else if ( ((i != top_row) && (i != bottom_row)) &&
 249:                         ((j == left_col) || (j == right_col))) {
 250:                 ch = VERTWALL;
 251:             } else {
 252:                 ch = FLOOR;
 253:             }
 254:             dungeon[i][j] = ch;
 255:         }
 256:     }
 257: END:
 258:     rooms[rn].top_row = top_row;
 259:     rooms[rn].bottom_row = bottom_row;
 260:     rooms[rn].left_col = left_col;
 261:     rooms[rn].right_col = right_col;
 262: }
 263: 
 264: connect_rooms(room1, room2)
 265: short room1, room2;
 266: {
 267:     short row1, col1, row2, col2, dir;
 268: 
 269:     if ((!(rooms[room1].is_room & (R_ROOM | R_MAZE))) ||
 270:         (!(rooms[room2].is_room & (R_ROOM | R_MAZE)))) {
 271:         return(0);
 272:     }
 273:     if (same_row(room1, room2) &&
 274:         (rooms[room1].left_col > rooms[room2].right_col)) {
 275:         put_door(&rooms[room1], LEFT, &row1, &col1);
 276:         put_door(&rooms[room2], RIGHT, &row2, &col2);
 277:         dir = LEFT;
 278:     } else if (same_row(room1, room2) &&
 279:         (rooms[room2].left_col > rooms[room1].right_col)) {
 280:         put_door(&rooms[room1], RIGHT, &row1, &col1);
 281:         put_door(&rooms[room2], LEFT, &row2, &col2);
 282:         dir = RIGHT;
 283:     } else if (same_col(room1, room2) &&
 284:         (rooms[room1].top_row > rooms[room2].bottom_row)) {
 285:         put_door(&rooms[room1], UPWARD, &row1, &col1);
 286:         put_door(&rooms[room2], DOWN, &row2, &col2);
 287:         dir = UPWARD;
 288:     } else if (same_col(room1, room2) &&
 289:         (rooms[room2].top_row > rooms[room1].bottom_row)) {
 290:         put_door(&rooms[room1], DOWN, &row1, &col1);
 291:         put_door(&rooms[room2], UPWARD, &row2, &col2);
 292:         dir = DOWN;
 293:     } else {
 294:         return(0);
 295:     }
 296: 
 297:     do {
 298:         draw_simple_passage(row1, col1, row2, col2, dir);
 299:     } while (rand_percent(4));
 300: 
 301:     rooms[room1].doors[dir/2].oth_room = room2;
 302:     rooms[room1].doors[dir/2].oth_row = row2;
 303:     rooms[room1].doors[dir/2].oth_col = col2;
 304: 
 305:     rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_room = room1;
 306:     rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_row = row1;
 307:     rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_col = col1;
 308:     return(1);
 309: }
 310: 
 311: clear_level()
 312: {
 313:     short i, j;
 314: 
 315:     for (i = 0; i < MAXROOMS; i++) {
 316:         rooms[i].is_room = R_NOTHING;
 317:         for (j = 0; j < 4; j++) {
 318:             rooms[i].doors[j].oth_room = NO_ROOM;
 319:         }
 320:     }
 321: 
 322:     for (i = 0; i < MAX_TRAPS; i++) {
 323:         traps[i].trap_type = NO_TRAP;
 324:     }
 325:     for (i = 0; i < DROWS; i++) {
 326:         for (j = 0; j < DCOLS; j++) {
 327:             dungeon[i][j] = NOTHING;
 328:         }
 329:     }
 330:     detect_monster = see_invisible = 0;
 331:     being_held = bear_trap = 0;
 332:     party_room = NO_ROOM;
 333:     rogue.row = rogue.col = -1;
 334:     clear();
 335: }
 336: 
 337: put_door(rm, dir, row, col)
 338: room *rm;
 339: short dir;
 340: short *row, *col;
 341: {
 342:     short wall_width;
 343: 
 344:     wall_width = (rm->is_room & R_MAZE) ? 0 : 1;
 345: 
 346:     switch(dir) {
 347:     case UPWARD:
 348:     case DOWN:
 349:         *row = ((dir == UPWARD) ? rm->top_row : rm->bottom_row);
 350:         do {
 351:             *col = get_rand(rm->left_col+wall_width,
 352:                 rm->right_col-wall_width);
 353:         } while (!(dungeon[*row][*col] & (HORWALL | TUNNEL)));
 354:         break;
 355:     case RIGHT:
 356:     case LEFT:
 357:         *col = (dir == LEFT) ? rm->left_col : rm->right_col;
 358:         do {
 359:             *row = get_rand(rm->top_row+wall_width,
 360:                 rm->bottom_row-wall_width);
 361:         } while (!(dungeon[*row][*col] & (VERTWALL | TUNNEL)));
 362:         break;
 363:     }
 364:     if (rm->is_room & R_ROOM) {
 365:         dungeon[*row][*col] = DOOR;
 366:     }
 367:     if ((cur_level > 2) && rand_percent(HIDE_PERCENT)) {
 368:         dungeon[*row][*col] |= HIDDEN;
 369:     }
 370:     rm->doors[dir/2].door_row = *row;
 371:     rm->doors[dir/2].door_col = *col;
 372: }
 373: 
 374: draw_simple_passage(row1, col1, row2, col2, dir)
 375: short row1, col1, row2, col2, dir;
 376: {
 377:     short i, middle, t;
 378: 
 379:     if ((dir == LEFT) || (dir == RIGHT)) {
 380:         if (col1 > col2) {
 381:             swap(row1, row2);
 382:             swap(col1, col2);
 383:         }
 384:         middle = get_rand(col1+1, col2-1);
 385:         for (i = col1+1; i != middle; i++) {
 386:             dungeon[row1][i] = TUNNEL;
 387:         }
 388:         for (i = row1; i != row2; i += (row1 > row2) ? -1 : 1) {
 389:             dungeon[i][middle] = TUNNEL;
 390:         }
 391:         for (i = middle; i != col2; i++) {
 392:             dungeon[row2][i] = TUNNEL;
 393:         }
 394:     } else {
 395:         if (row1 > row2) {
 396:             swap(row1, row2);
 397:             swap(col1, col2);
 398:         }
 399:         middle = get_rand(row1+1, row2-1);
 400:         for (i = row1+1; i != middle; i++) {
 401:             dungeon[i][col1] = TUNNEL;
 402:         }
 403:         for (i = col1; i != col2; i += (col1 > col2) ? -1 : 1) {
 404:             dungeon[middle][i] = TUNNEL;
 405:         }
 406:         for (i = middle; i != row2; i++) {
 407:             dungeon[i][col2] = TUNNEL;
 408:         }
 409:     }
 410:     if (rand_percent(HIDE_PERCENT)) {
 411:         hide_boxed_passage(row1, col1, row2, col2, 1);
 412:     }
 413: }
 414: 
 415: same_row(room1, room2)
 416: {
 417:     return((room1 / 3) == (room2 / 3));
 418: }
 419: 
 420: same_col(room1, room2)
 421: {
 422:     return((room1 % 3) == (room2 % 3));
 423: }
 424: 
 425: add_mazes()
 426: {
 427:     short i, j;
 428:     short start;
 429:     short maze_percent;
 430: 
 431:     if (cur_level > 1) {
 432:         start = get_rand(0, (MAXROOMS-1));
 433:         maze_percent = (cur_level * 5) / 4;
 434: 
 435:         if (cur_level > 15) {
 436:             maze_percent += cur_level;
 437:         }
 438:         for (i = 0; i < MAXROOMS; i++) {
 439:             j = ((start + i) % MAXROOMS);
 440:             if (rooms[j].is_room & R_NOTHING) {
 441:                 if (rand_percent(maze_percent)) {
 442:                 rooms[j].is_room = R_MAZE;
 443:                 make_maze(get_rand(rooms[j].top_row+1, rooms[j].bottom_row-1),
 444:                     get_rand(rooms[j].left_col+1, rooms[j].right_col-1),
 445:                     rooms[j].top_row, rooms[j].bottom_row,
 446:                     rooms[j].left_col, rooms[j].right_col);
 447:                 hide_boxed_passage(rooms[j].top_row, rooms[j].left_col,
 448:                     rooms[j].bottom_row, rooms[j].right_col,
 449:                     get_rand(0, 2));
 450:                 }
 451:             }
 452:         }
 453:     }
 454: }
 455: 
 456: fill_out_level()
 457: {
 458:     short i, rn;
 459: 
 460:     mix_random_rooms();
 461: 
 462:     r_de = NO_ROOM;
 463: 
 464:     for (i = 0; i < MAXROOMS; i++) {
 465:         rn = random_rooms[i];
 466:         if ((rooms[rn].is_room & R_NOTHING) ||
 467:             ((rooms[rn].is_room & R_CROSS) && coin_toss())) {
 468:             fill_it(rn, 1);
 469:         }
 470:     }
 471:     if (r_de != NO_ROOM) {
 472:         fill_it(r_de, 0);
 473:     }
 474: }
 475: 
 476: fill_it(rn, do_rec_de)
 477: int rn;
 478: boolean do_rec_de;
 479: {
 480:     short i, tunnel_dir, door_dir, drow, dcol;
 481:     short target_room, rooms_found = 0;
 482:     short srow, scol, t;
 483:     static short offsets[4] = {-1, 1, 3, -3};
 484:     boolean did_this = 0;
 485: 
 486:     for (i = 0; i < 10; i++) {
 487:         srow = get_rand(0, 3);
 488:         scol = get_rand(0, 3);
 489:         t = offsets[srow];
 490:         offsets[srow] = offsets[scol];
 491:         offsets[scol] = t;
 492:     }
 493:     for (i = 0; i < 4; i++) {
 494: 
 495:         target_room = rn + offsets[i];
 496: 
 497:         if (((target_room < 0) || (target_room >= MAXROOMS)) ||
 498:             (!(same_row(rn,target_room) || same_col(rn,target_room))) ||
 499:             (!(rooms[target_room].is_room & (R_ROOM | R_MAZE)))) {
 500:             continue;
 501:         }
 502:         if (same_row(rn, target_room)) {
 503:             tunnel_dir = (rooms[rn].left_col < rooms[target_room].left_col) ?
 504:                 RIGHT : LEFT;
 505:         } else {
 506:             tunnel_dir = (rooms[rn].top_row < rooms[target_room].top_row) ?
 507:                 DOWN : UPWARD;
 508:         }
 509:         door_dir = ((tunnel_dir + 4) % DIRS);
 510:         if (rooms[target_room].doors[door_dir/2].oth_room != NO_ROOM) {
 511:             continue;
 512:         }
 513:         if (((!do_rec_de) || did_this) ||
 514:             (!mask_room(rn, &srow, &scol, TUNNEL))) {
 515:             srow = (rooms[rn].top_row + rooms[rn].bottom_row) / 2;
 516:             scol = (rooms[rn].left_col + rooms[rn].right_col) / 2;
 517:         }
 518:         put_door(&rooms[target_room], door_dir, &drow, &dcol);
 519:         rooms_found++;
 520:         draw_simple_passage(srow, scol, drow, dcol, tunnel_dir);
 521:         rooms[rn].is_room = R_DEADEND;
 522:         dungeon[srow][scol] = TUNNEL;
 523: 
 524:         if ((i < 3) && (!did_this)) {
 525:             did_this = 1;
 526:             if (coin_toss()) {
 527:                 continue;
 528:             }
 529:         }
 530:         if ((rooms_found < 2) && do_rec_de) {
 531:             recursive_deadend(rn, offsets, srow, scol);
 532:         }
 533:         break;
 534:     }
 535: }
 536: 
 537: recursive_deadend(rn, offsets, srow, scol)
 538: short rn;
 539: short *offsets;
 540: short srow, scol;
 541: {
 542:     short i, de;
 543:     short drow, dcol, tunnel_dir;
 544: 
 545:     rooms[rn].is_room = R_DEADEND;
 546:     dungeon[srow][scol] = TUNNEL;
 547: 
 548:     for (i = 0; i < 4; i++) {
 549:         de = rn + offsets[i];
 550:         if (((de < 0) || (de >= MAXROOMS)) ||
 551:             (!(same_row(rn, de) || same_col(rn, de)))) {
 552:             continue;
 553:         }
 554:         if (!(rooms[de].is_room & R_NOTHING)) {
 555:             continue;
 556:         }
 557:         drow = (rooms[de].top_row + rooms[de].bottom_row) / 2;
 558:         dcol = (rooms[de].left_col + rooms[de].right_col) / 2;
 559:         if (same_row(rn, de)) {
 560:             tunnel_dir = (rooms[rn].left_col < rooms[de].left_col) ?
 561:                 RIGHT : LEFT;
 562:         } else {
 563:             tunnel_dir = (rooms[rn].top_row < rooms[de].top_row) ?
 564:                 DOWN : UPWARD;
 565:         }
 566:         draw_simple_passage(srow, scol, drow, dcol, tunnel_dir);
 567:         r_de = de;
 568:         recursive_deadend(de, offsets, drow, dcol);
 569:     }
 570: }
 571: 
 572: boolean
 573: mask_room(rn, row, col, mask)
 574: short rn;
 575: short *row, *col;
 576: unsigned short mask;
 577: {
 578:     short i, j;
 579: 
 580:     for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
 581:         for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
 582:             if (dungeon[i][j] & mask) {
 583:                 *row = i;
 584:                 *col = j;
 585:                 return(1);
 586:             }
 587:         }
 588:     }
 589:     return(0);
 590: }
 591: 
 592: make_maze(r, c, tr, br, lc, rc)
 593: short r, c, tr, br, lc, rc;
 594: {
 595:     char dirs[4];
 596:     short i, t;
 597: 
 598:     dirs[0] = UPWARD;
 599:     dirs[1] = DOWN;
 600:     dirs[2] = LEFT;
 601:     dirs[3] = RIGHT;
 602: 
 603:     dungeon[r][c] = TUNNEL;
 604: 
 605:     if (rand_percent(20)) {
 606:         for (i = 0; i < 10; i++) {
 607:             short t1, t2;
 608: 
 609:             t1 = get_rand(0, 3);
 610:             t2 = get_rand(0, 3);
 611: 
 612:             swap(dirs[t1], dirs[t2]);
 613:         }
 614:     }
 615:     for (i = 0; i < 4; i++) {
 616:         switch(dirs[i]) {
 617:         case UPWARD:
 618:             if (((r-1) >= tr) &&
 619:                 (dungeon[r-1][c] != TUNNEL) &&
 620:                 (dungeon[r-1][c-1] != TUNNEL) &&
 621:                 (dungeon[r-1][c+1] != TUNNEL) &&
 622:                 (dungeon[r-2][c] != TUNNEL)) {
 623:                 make_maze((r-1), c, tr, br, lc, rc);
 624:             }
 625:             break;
 626:         case DOWN:
 627:             if (((r+1) <= br) &&
 628:                 (dungeon[r+1][c] != TUNNEL) &&
 629:                 (dungeon[r+1][c-1] != TUNNEL) &&
 630:                 (dungeon[r+1][c+1] != TUNNEL) &&
 631:                 (dungeon[r+2][c] != TUNNEL)) {
 632:                 make_maze((r+1), c, tr, br, lc, rc);
 633:             }
 634:             break;
 635:         case LEFT:
 636:             if (((c-1) >= lc) &&
 637:                 (dungeon[r][c-1] != TUNNEL) &&
 638:                 (dungeon[r-1][c-1] != TUNNEL) &&
 639:                 (dungeon[r+1][c-1] != TUNNEL) &&
 640:                 (dungeon[r][c-2] != TUNNEL)) {
 641:                 make_maze(r, (c-1), tr, br, lc, rc);
 642:             }
 643:             break;
 644:         case RIGHT:
 645:             if (((c+1) <= rc) &&
 646:                 (dungeon[r][c+1] != TUNNEL) &&
 647:                 (dungeon[r-1][c+1] != TUNNEL) &&
 648:                 (dungeon[r+1][c+1] != TUNNEL) &&
 649:                 (dungeon[r][c+2] != TUNNEL)) {
 650:                 make_maze(r, (c+1), tr, br, lc, rc);
 651:             }
 652:             break;
 653:         }
 654:     }
 655: }
 656: 
 657: hide_boxed_passage(row1, col1, row2, col2, n)
 658: short row1, col1, row2, col2, n;
 659: {
 660:     short i, j, t;
 661:     short row, col, row_cut, col_cut;
 662:     short h, w;
 663: 
 664:     if (cur_level > 2) {
 665:         if (row1 > row2) {
 666:             swap(row1, row2);
 667:         }
 668:         if (col1 > col2) {
 669:             swap(col1, col2);
 670:         }
 671:         h = row2 - row1;
 672:         w = col2 - col1;
 673: 
 674:         if ((w >= 5) || (h >= 5)) {
 675:             row_cut = ((h >= 2) ? 1 : 0);
 676:             col_cut = ((w >= 2) ? 1 : 0);
 677: 
 678:             for (i = 0; i < n; i++) {
 679:                 for (j = 0; j < 10; j++) {
 680:                     row = get_rand(row1 + row_cut, row2 - row_cut);
 681:                     col = get_rand(col1 + col_cut, col2 - col_cut);
 682:                     if (dungeon[row][col] == TUNNEL) {
 683:                         dungeon[row][col] |= HIDDEN;
 684:                         break;
 685:                     }
 686:                 }
 687:             }
 688:         }
 689:     }
 690: }
 691: 
 692: put_player(nr)
 693: short nr;       /* try not to put in this room */
 694: {
 695:     short rn = nr, misses;
 696:     short row, col;
 697: 
 698:     for (misses = 0; ((misses < 2) && (rn == nr)); misses++) {
 699:         gr_row_col(&row, &col, (FLOOR | TUNNEL | OBJECT | STAIRS));
 700:         rn = get_room_number(row, col);
 701:     }
 702:     rogue.row = row;
 703:     rogue.col = col;
 704: 
 705:     if (dungeon[rogue.row][rogue.col] & TUNNEL) {
 706:         cur_room = PASSAGE;
 707:     } else {
 708:         cur_room = rn;
 709:     }
 710:     if (cur_room != PASSAGE) {
 711:         light_up_room(cur_room);
 712:     } else {
 713:         light_passage(rogue.row, rogue.col);
 714:     }
 715:     rn = get_room_number(rogue.row, rogue.col);
 716:     wake_room(rn, 1, rogue.row, rogue.col);
 717:     if (new_level_message) {
 718:         message(new_level_message, 0);
 719:         new_level_message = 0;
 720:     }
 721:     mvaddch(rogue.row, rogue.col, rogue.fchar);
 722: }
 723: 
 724: drop_check()
 725: {
 726:     if (wizard) {
 727:         return(1);
 728:     }
 729:     if (dungeon[rogue.row][rogue.col] & STAIRS) {
 730:         if (levitate) {
 731:             message("you're floating in the air!", 0);
 732:             return(0);
 733:         }
 734:         return(1);
 735:     }
 736:     message("I see no way down", 0);
 737:     return(0);
 738: }
 739: 
 740: check_up()
 741: {
 742:     if (!wizard) {
 743:         if (!(dungeon[rogue.row][rogue.col] & STAIRS)) {
 744:             message("I see no way up", 0);
 745:             return(0);
 746:         }
 747:         if (!has_amulet()) {
 748:             message("your way is magically blocked", 0);
 749:             return(0);
 750:         }
 751:     }
 752:     new_level_message = "you feel a wrenching sensation in your gut";
 753:     if (cur_level == 1) {
 754:         win();
 755:     } else {
 756:         cur_level -= 2;
 757:         return(1);
 758:     }
 759:     return(0);
 760: }
 761: 
 762: add_exp(e, promotion)
 763: int e;
 764: boolean promotion;
 765: {
 766:     char mbuf[40];
 767:     short new_exp;
 768:     short i, hp;
 769: 
 770:     rogue.exp_points += e;
 771: 
 772:     if (rogue.exp_points >= level_points[rogue.exp-1]) {
 773:         new_exp = get_exp_level(rogue.exp_points);
 774:         if (rogue.exp_points > MAX_EXP) {
 775:             rogue.exp_points = MAX_EXP + 1;
 776:         }
 777:         for (i = rogue.exp+1; i <= new_exp; i++) {
 778:             sprintf(mbuf, "welcome to level %d", i);
 779:             message(mbuf, 0);
 780:             if (promotion) {
 781:                 hp = hp_raise();
 782:                 rogue.hp_current += hp;
 783:                 rogue.hp_max += hp;
 784:             }
 785:             rogue.exp = i;
 786:             print_stats(STAT_HP | STAT_EXP);
 787:         }
 788:     } else {
 789:         print_stats(STAT_EXP);
 790:     }
 791: }
 792: 
 793: get_exp_level(e)
 794: long e;
 795: {
 796:     short i;
 797: 
 798:     for (i = 0; i < (MAX_EXP_LEVEL - 1); i++) {
 799:         if (level_points[i] > e) {
 800:             break;
 801:         }
 802:     }
 803:     return(i+1);
 804: }
 805: 
 806: hp_raise()
 807: {
 808:     int hp;
 809: 
 810:     hp = (wizard ? 10 : get_rand(3, 10));
 811:     return(hp);
 812: }
 813: 
 814: show_average_hp()
 815: {
 816:     char mbuf[80];
 817:     float real_average;
 818:     float effective_average;
 819: 
 820:     if (rogue.exp == 1) {
 821:         real_average = effective_average = 0.00;
 822:     } else {
 823:         real_average = (float)
 824:             ((rogue.hp_max - extra_hp - INIT_HP) + less_hp) / (rogue.exp - 1);
 825:         effective_average = (float) (rogue.hp_max - INIT_HP) / (rogue.exp - 1);
 826: 
 827:     }
 828:     sprintf(mbuf, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average,
 829:         effective_average, extra_hp, less_hp);
 830:     message(mbuf, 0);
 831: }
 832: 
 833: mix_random_rooms()
 834: {
 835:     short i, t;
 836:     short x, y;
 837: 
 838:     for (i = 0; i < (3 * MAXROOMS); i++) {
 839:         do {
 840:             x = get_rand(0, (MAXROOMS-1));
 841:             y = get_rand(0, (MAXROOMS-1));
 842:         } while (x == y);
 843:         swap(random_rooms[x], random_rooms[y]);
 844:     }
 845: }

Defined functions

add_mazes defined in line 425; used 1 times
check_up defined in line 740; used 1 times
clear_level defined in line 311; used 1 times
connect_rooms defined in line 264; used 4 times
draw_simple_passage defined in line 374; used 3 times
drop_check defined in line 724; used 1 times
fill_it defined in line 476; used 2 times
fill_out_level defined in line 456; used 1 times
get_exp_level defined in line 793; used 1 times
hide_boxed_passage defined in line 657; used 2 times
hp_raise defined in line 806; used 2 times
make_level defined in line 58; used 1 times
make_maze defined in line 592; used 5 times
make_room defined in line 155; used 2 times
mask_room defined in line 572; used 2 times
mix_random_rooms defined in line 833; used 2 times
put_door defined in line 337; used 9 times
put_player defined in line 692; used 2 times
recursive_deadend defined in line 537; used 2 times
same_col defined in line 420; used 4 times
same_row defined in line 415; used 6 times
show_average_hp defined in line 814; used 1 times

Defined variables

cur_room declared in line 56; defined in line 23; used 29 times
level_points defined in line 28; used 4 times
new_level_message defined in line 24; used 5 times
r_de defined in line 26; used 4 times
random_rooms defined in line 52; used 4 times
sccsid defined in line 14; never used

Defined macros

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