home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / rogue / level.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-08  |  18.9 KB  |  882 lines

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