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 * @(#)level.c 8.1 (Berkeley) 5/31/93 37 * $FreeBSD: src/games/rogue/level.c,v 1.3 1999/11/30 03:49:23 billf Exp $ 38 * $DragonFly: src/games/rogue/level.c,v 1.2 2003/06/17 04:25:24 dillon Exp $ 39 */ 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 const char *new_level_message = 0; 61 short party_room = NO_ROOM; 62 short r_de; 63 64 const 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 const 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