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