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