|
|
1.1 ! root 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 are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)move.c 5.3 (Berkeley) 6/1/90"; ! 25: #endif /* not lint */ ! 26: ! 27: /* ! 28: * move.c ! 29: * ! 30: * This source herein may be modified and/or distributed by anybody who ! 31: * so desires, with the following restrictions: ! 32: * 1.) No portion of this notice shall be removed. ! 33: * 2.) Credit shall not be taken for the creation of this source. ! 34: * 3.) This code is not to be traded, sold, or used for personal ! 35: * gain or profit. ! 36: * ! 37: */ ! 38: ! 39: #include "rogue.h" ! 40: ! 41: short m_moves = 0; ! 42: boolean jump = 0; ! 43: char *you_can_move_again = "you can move again"; ! 44: ! 45: extern short cur_room, halluc, blind, levitate; ! 46: extern short cur_level, max_level; ! 47: extern short bear_trap, haste_self, confused; ! 48: extern short e_rings, regeneration, auto_search; ! 49: extern char hunger_str[]; ! 50: extern boolean being_held, interrupted, r_teleport, passgo; ! 51: ! 52: one_move_rogue(dirch, pickup) ! 53: short dirch, pickup; ! 54: { ! 55: short row, col; ! 56: object *obj; ! 57: char desc[DCOLS]; ! 58: short n, status, d; ! 59: ! 60: row = rogue.row; ! 61: col = rogue.col; ! 62: ! 63: if (confused) { ! 64: dirch = gr_dir(); ! 65: } ! 66: (void) is_direction(dirch, &d); ! 67: get_dir_rc(d, &row, &col, 1); ! 68: ! 69: if (!can_move(rogue.row, rogue.col, row, col)) { ! 70: return(MOVE_FAILED); ! 71: } ! 72: if (being_held || bear_trap) { ! 73: if (!(dungeon[row][col] & MONSTER)) { ! 74: if (being_held) { ! 75: message("you are being held", 1); ! 76: } else { ! 77: message("you are still stuck in the bear trap", 0); ! 78: (void) reg_move(); ! 79: } ! 80: return(MOVE_FAILED); ! 81: } ! 82: } ! 83: if (r_teleport) { ! 84: if (rand_percent(R_TELE_PERCENT)) { ! 85: tele(); ! 86: return(STOPPED_ON_SOMETHING); ! 87: } ! 88: } ! 89: if (dungeon[row][col] & MONSTER) { ! 90: rogue_hit(object_at(&level_monsters, row, col), 0); ! 91: (void) reg_move(); ! 92: return(MOVE_FAILED); ! 93: } ! 94: if (dungeon[row][col] & DOOR) { ! 95: if (cur_room == PASSAGE) { ! 96: cur_room = get_room_number(row, col); ! 97: light_up_room(cur_room); ! 98: wake_room(cur_room, 1, row, col); ! 99: } else { ! 100: light_passage(row, col); ! 101: } ! 102: } else if ((dungeon[rogue.row][rogue.col] & DOOR) && ! 103: (dungeon[row][col] & TUNNEL)) { ! 104: light_passage(row, col); ! 105: wake_room(cur_room, 0, rogue.row, rogue.col); ! 106: darken_room(cur_room); ! 107: cur_room = PASSAGE; ! 108: } else if (dungeon[row][col] & TUNNEL) { ! 109: light_passage(row, col); ! 110: } ! 111: mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col)); ! 112: mvaddch(row, col, rogue.fchar); ! 113: ! 114: if (!jump) { ! 115: refresh(); ! 116: } ! 117: rogue.row = row; ! 118: rogue.col = col; ! 119: if (dungeon[row][col] & OBJECT) { ! 120: if (levitate && pickup) { ! 121: return(STOPPED_ON_SOMETHING); ! 122: } ! 123: if (pickup && !levitate) { ! 124: if (obj = pick_up(row, col, &status)) { ! 125: get_desc(obj, desc); ! 126: if (obj->what_is == GOLD) { ! 127: free_object(obj); ! 128: goto NOT_IN_PACK; ! 129: } ! 130: } else if (!status) { ! 131: goto MVED; ! 132: } else { ! 133: goto MOVE_ON; ! 134: } ! 135: } else { ! 136: MOVE_ON: ! 137: obj = object_at(&level_objects, row, col); ! 138: (void) strcpy(desc, "moved onto "); ! 139: get_desc(obj, desc+11); ! 140: goto NOT_IN_PACK; ! 141: } ! 142: n = strlen(desc); ! 143: desc[n] = '('; ! 144: desc[n+1] = obj->ichar; ! 145: desc[n+2] = ')'; ! 146: desc[n+3] = 0; ! 147: NOT_IN_PACK: ! 148: message(desc, 1); ! 149: (void) reg_move(); ! 150: return(STOPPED_ON_SOMETHING); ! 151: } ! 152: if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) { ! 153: if ((!levitate) && (dungeon[row][col] & TRAP)) { ! 154: trap_player(row, col); ! 155: } ! 156: (void) reg_move(); ! 157: return(STOPPED_ON_SOMETHING); ! 158: } ! 159: MVED: if (reg_move()) { /* fainted from hunger */ ! 160: return(STOPPED_ON_SOMETHING); ! 161: } ! 162: return((confused ? STOPPED_ON_SOMETHING : MOVED)); ! 163: } ! 164: ! 165: multiple_move_rogue(dirch) ! 166: short dirch; ! 167: { ! 168: short row, col; ! 169: short m; ! 170: ! 171: switch(dirch) { ! 172: case '\010': ! 173: case '\012': ! 174: case '\013': ! 175: case '\014': ! 176: case '\031': ! 177: case '\025': ! 178: case '\016': ! 179: case '\002': ! 180: do { ! 181: row = rogue.row; ! 182: col = rogue.col; ! 183: if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) || ! 184: (m == STOPPED_ON_SOMETHING) || ! 185: interrupted) { ! 186: break; ! 187: } ! 188: } while (!next_to_something(row, col)); ! 189: if ( (!interrupted) && passgo && (m == MOVE_FAILED) && ! 190: (dungeon[rogue.row][rogue.col] & TUNNEL)) { ! 191: turn_passage(dirch + 96, 0); ! 192: } ! 193: break; ! 194: case 'H': ! 195: case 'J': ! 196: case 'K': ! 197: case 'L': ! 198: case 'B': ! 199: case 'Y': ! 200: case 'U': ! 201: case 'N': ! 202: while ((!interrupted) && (one_move_rogue((dirch + 32), 1) == MOVED)) ; ! 203: ! 204: if ( (!interrupted) && passgo && ! 205: (dungeon[rogue.row][rogue.col] & TUNNEL)) { ! 206: turn_passage(dirch + 32, 1); ! 207: } ! 208: break; ! 209: } ! 210: } ! 211: ! 212: is_passable(row, col) ! 213: register row, col; ! 214: { ! 215: if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) || ! 216: (col > (DCOLS-1))) { ! 217: return(0); ! 218: } ! 219: if (dungeon[row][col] & HIDDEN) { ! 220: return((dungeon[row][col] & TRAP) ? 1 : 0); ! 221: } ! 222: return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP)); ! 223: } ! 224: ! 225: next_to_something(drow, dcol) ! 226: register drow, dcol; ! 227: { ! 228: short i, j, i_end, j_end, row, col; ! 229: short pass_count = 0; ! 230: unsigned short s; ! 231: ! 232: if (confused) { ! 233: return(1); ! 234: } ! 235: if (blind) { ! 236: return(0); ! 237: } ! 238: i_end = (rogue.row < (DROWS-2)) ? 1 : 0; ! 239: j_end = (rogue.col < (DCOLS-1)) ? 1 : 0; ! 240: ! 241: for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) { ! 242: for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) { ! 243: if ((i == 0) && (j == 0)) { ! 244: continue; ! 245: } ! 246: if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) { ! 247: continue; ! 248: } ! 249: row = rogue.row + i; ! 250: col = rogue.col + j; ! 251: s = dungeon[row][col]; ! 252: if (s & HIDDEN) { ! 253: continue; ! 254: } ! 255: /* If the rogue used to be right, up, left, down, or right of ! 256: * row,col, and now isn't, then don't stop */ ! 257: if (s & (MONSTER | OBJECT | STAIRS)) { ! 258: if (((row == drow) || (col == dcol)) && ! 259: (!((row == rogue.row) || (col == rogue.col)))) { ! 260: continue; ! 261: } ! 262: return(1); ! 263: } ! 264: if (s & TRAP) { ! 265: if (!(s & HIDDEN)) { ! 266: if (((row == drow) || (col == dcol)) && ! 267: (!((row == rogue.row) || (col == rogue.col)))) { ! 268: continue; ! 269: } ! 270: return(1); ! 271: } ! 272: } ! 273: if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) { ! 274: if (++pass_count > 1) { ! 275: return(1); ! 276: } ! 277: } ! 278: if ((s & DOOR) && ((i == 0) || (j == 0))) { ! 279: return(1); ! 280: } ! 281: } ! 282: } ! 283: return(0); ! 284: } ! 285: ! 286: can_move(row1, col1, row2, col2) ! 287: { ! 288: if (!is_passable(row2, col2)) { ! 289: return(0); ! 290: } ! 291: if ((row1 != row2) && (col1 != col2)) { ! 292: if ((dungeon[row1][col1] & DOOR) || (dungeon[row2][col2] & DOOR)) { ! 293: return(0); ! 294: } ! 295: if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) { ! 296: return(0); ! 297: } ! 298: } ! 299: return(1); ! 300: } ! 301: ! 302: move_onto() ! 303: { ! 304: short ch, d; ! 305: boolean first_miss = 1; ! 306: ! 307: while (!is_direction(ch = rgetchar(), &d)) { ! 308: sound_bell(); ! 309: if (first_miss) { ! 310: message("direction? ", 0); ! 311: first_miss = 0; ! 312: } ! 313: } ! 314: check_message(); ! 315: if (ch != CANCEL) { ! 316: (void) one_move_rogue(ch, 0); ! 317: } ! 318: } ! 319: ! 320: boolean ! 321: is_direction(c, d) ! 322: short c; ! 323: short *d; ! 324: { ! 325: switch(c) { ! 326: case 'h': ! 327: *d = LEFT; ! 328: break; ! 329: case 'j': ! 330: *d = DOWN; ! 331: break; ! 332: case 'k': ! 333: *d = UPWARD; ! 334: break; ! 335: case 'l': ! 336: *d = RIGHT; ! 337: break; ! 338: case 'b': ! 339: *d = DOWNLEFT; ! 340: break; ! 341: case 'y': ! 342: *d = UPLEFT; ! 343: break; ! 344: case 'u': ! 345: *d = UPRIGHT; ! 346: break; ! 347: case 'n': ! 348: *d = DOWNRIGHT; ! 349: break; ! 350: case CANCEL: ! 351: break; ! 352: default: ! 353: return(0); ! 354: } ! 355: return(1); ! 356: } ! 357: ! 358: boolean ! 359: check_hunger(msg_only) ! 360: boolean msg_only; ! 361: { ! 362: register short i, n; ! 363: boolean fainted = 0; ! 364: ! 365: if (rogue.moves_left == HUNGRY) { ! 366: (void) strcpy(hunger_str, "hungry"); ! 367: message(hunger_str, 0); ! 368: print_stats(STAT_HUNGER); ! 369: } ! 370: if (rogue.moves_left == WEAK) { ! 371: (void) strcpy(hunger_str, "weak"); ! 372: message(hunger_str, 1); ! 373: print_stats(STAT_HUNGER); ! 374: } ! 375: if (rogue.moves_left <= FAINT) { ! 376: if (rogue.moves_left == FAINT) { ! 377: (void) strcpy(hunger_str, "faint"); ! 378: message(hunger_str, 1); ! 379: print_stats(STAT_HUNGER); ! 380: } ! 381: n = get_rand(0, (FAINT - rogue.moves_left)); ! 382: if (n > 0) { ! 383: fainted = 1; ! 384: if (rand_percent(40)) { ! 385: rogue.moves_left++; ! 386: } ! 387: message("you faint", 1); ! 388: for (i = 0; i < n; i++) { ! 389: if (coin_toss()) { ! 390: mv_mons(); ! 391: } ! 392: } ! 393: message(you_can_move_again, 1); ! 394: } ! 395: } ! 396: if (msg_only) { ! 397: return(fainted); ! 398: } ! 399: if (rogue.moves_left <= STARVE) { ! 400: killed_by((object *) 0, STARVATION); ! 401: } ! 402: ! 403: switch(e_rings) { ! 404: /*case -2: ! 405: Subtract 0, i.e. do nothing. ! 406: break;*/ ! 407: case -1: ! 408: rogue.moves_left -= (rogue.moves_left % 2); ! 409: break; ! 410: case 0: ! 411: rogue.moves_left--; ! 412: break; ! 413: case 1: ! 414: rogue.moves_left--; ! 415: (void) check_hunger(1); ! 416: rogue.moves_left -= (rogue.moves_left % 2); ! 417: break; ! 418: case 2: ! 419: rogue.moves_left--; ! 420: (void) check_hunger(1); ! 421: rogue.moves_left--; ! 422: break; ! 423: } ! 424: return(fainted); ! 425: } ! 426: ! 427: boolean ! 428: reg_move() ! 429: { ! 430: boolean fainted; ! 431: ! 432: if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) { ! 433: fainted = check_hunger(0); ! 434: } else { ! 435: fainted = 0; ! 436: } ! 437: ! 438: mv_mons(); ! 439: ! 440: if (++m_moves >= 120) { ! 441: m_moves = 0; ! 442: wanderer(); ! 443: } ! 444: if (halluc) { ! 445: if (!(--halluc)) { ! 446: unhallucinate(); ! 447: } else { ! 448: hallucinate(); ! 449: } ! 450: } ! 451: if (blind) { ! 452: if (!(--blind)) { ! 453: unblind(); ! 454: } ! 455: } ! 456: if (confused) { ! 457: if (!(--confused)) { ! 458: unconfuse(); ! 459: } ! 460: } ! 461: if (bear_trap) { ! 462: bear_trap--; ! 463: } ! 464: if (levitate) { ! 465: if (!(--levitate)) { ! 466: message("you float gently to the ground", 1); ! 467: if (dungeon[rogue.row][rogue.col] & TRAP) { ! 468: trap_player(rogue.row, rogue.col); ! 469: } ! 470: } ! 471: } ! 472: if (haste_self) { ! 473: if (!(--haste_self)) { ! 474: message("you feel yourself slowing down", 0); ! 475: } ! 476: } ! 477: heal(); ! 478: if (auto_search > 0) { ! 479: search(auto_search, auto_search); ! 480: } ! 481: return(fainted); ! 482: } ! 483: ! 484: rest(count) ! 485: { ! 486: int i; ! 487: ! 488: interrupted = 0; ! 489: ! 490: for (i = 0; i < count; i++) { ! 491: if (interrupted) { ! 492: break; ! 493: } ! 494: (void) reg_move(); ! 495: } ! 496: } ! 497: ! 498: gr_dir() ! 499: { ! 500: short d; ! 501: ! 502: d = get_rand(1, 8); ! 503: ! 504: switch(d) { ! 505: case 1: ! 506: d = 'j'; ! 507: break; ! 508: case 2: ! 509: d = 'k'; ! 510: break; ! 511: case 3: ! 512: d = 'l'; ! 513: break; ! 514: case 4: ! 515: d = 'h'; ! 516: break; ! 517: case 5: ! 518: d = 'y'; ! 519: break; ! 520: case 6: ! 521: d = 'u'; ! 522: break; ! 523: case 7: ! 524: d = 'b'; ! 525: break; ! 526: case 8: ! 527: d = 'n'; ! 528: break; ! 529: } ! 530: return(d); ! 531: } ! 532: ! 533: heal() ! 534: { ! 535: static short heal_exp = -1, n, c = 0; ! 536: static boolean alt; ! 537: ! 538: if (rogue.hp_current == rogue.hp_max) { ! 539: c = 0; ! 540: return; ! 541: } ! 542: if (rogue.exp != heal_exp) { ! 543: heal_exp = rogue.exp; ! 544: ! 545: switch(heal_exp) { ! 546: case 1: ! 547: n = 20; ! 548: break; ! 549: case 2: ! 550: n = 18; ! 551: break; ! 552: case 3: ! 553: n = 17; ! 554: break; ! 555: case 4: ! 556: n = 14; ! 557: break; ! 558: case 5: ! 559: n = 13; ! 560: break; ! 561: case 6: ! 562: n = 10; ! 563: break; ! 564: case 7: ! 565: n = 9; ! 566: break; ! 567: case 8: ! 568: n = 8; ! 569: break; ! 570: case 9: ! 571: n = 7; ! 572: break; ! 573: case 10: ! 574: n = 4; ! 575: break; ! 576: case 11: ! 577: n = 3; ! 578: break; ! 579: case 12: ! 580: default: ! 581: n = 2; ! 582: } ! 583: } ! 584: if (++c >= n) { ! 585: c = 0; ! 586: rogue.hp_current++; ! 587: if (alt = !alt) { ! 588: rogue.hp_current++; ! 589: } ! 590: if ((rogue.hp_current += regeneration) > rogue.hp_max) { ! 591: rogue.hp_current = rogue.hp_max; ! 592: } ! 593: print_stats(STAT_HP); ! 594: } ! 595: } ! 596: ! 597: static boolean ! 598: can_turn(nrow, ncol) ! 599: short nrow, ncol; ! 600: { ! 601: if ((dungeon[nrow][ncol] & TUNNEL) && is_passable(nrow, ncol)) { ! 602: return(1); ! 603: } ! 604: return(0); ! 605: } ! 606: ! 607: turn_passage(dir, fast) ! 608: short dir; ! 609: boolean fast; ! 610: { ! 611: short crow = rogue.row, ccol = rogue.col, turns = 0; ! 612: short ndir; ! 613: ! 614: if ((dir != 'h') && can_turn(crow, ccol + 1)) { ! 615: turns++; ! 616: ndir = 'l'; ! 617: } ! 618: if ((dir != 'l') && can_turn(crow, ccol - 1)) { ! 619: turns++; ! 620: ndir = 'h'; ! 621: } ! 622: if ((dir != 'k') && can_turn(crow + 1, ccol)) { ! 623: turns++; ! 624: ndir = 'j'; ! 625: } ! 626: if ((dir != 'j') && can_turn(crow - 1, ccol)) { ! 627: turns++; ! 628: ndir = 'k'; ! 629: } ! 630: if (turns == 1) { ! 631: multiple_move_rogue(ndir - (fast ? 32 : 96)); ! 632: } ! 633: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.