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: }

Defined functions

can_move defined in line 264; used 3 times
can_turn defined in line 575; used 4 times
check_hunger defined in line 336; used 4 times
gr_dir defined in line 476; used 1 times
  • in line 42
heal defined in line 511; used 1 times
is_passable defined in line 190; used 3 times
move_onto defined in line 280; used 1 times
multiple_move_rogue defined in line 143; used 2 times
next_to_something defined in line 203; used 1 times
one_move_rogue defined in line 30; used 5 times
rest defined in line 462; used 1 times
turn_passage defined in line 585; used 2 times

Defined variables

m_moves defined in line 19; used 6 times
sccsid defined in line 14; never used
you_can_move_again defined in line 21; used 3 times
Last modified: 1987-11-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4054
Valid CSS Valid XHTML 1.0 Strict