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