Annotation of early-roguelike/urogue/move.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: move.c - Hero movement commands
! 3:
! 4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
! 5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
! 6: All rights reserved.
! 7:
! 8: Based on "Advanced Rogue"
! 9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
! 10: All rights reserved.
! 11:
! 12: Based on "Rogue: Exploring the Dungeons of Doom"
! 13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 14: All rights reserved.
! 15:
! 16: See the file LICENSE.TXT for full copyright and licensing information.
! 17: */
! 18:
! 19: #include <stdlib.h>
! 20: #include <ctype.h>
! 21: #include "rogue.h"
! 22:
! 23: /*
! 24: do_run()
! 25: Start the hero running
! 26: */
! 27:
! 28: void
! 29: do_run(char ch)
! 30: {
! 31: running = TRUE;
! 32: after = FALSE;
! 33: runch = ch;
! 34:
! 35: if (doorstop && !on(player, ISBLIND))
! 36: {
! 37: door_stop = TRUE;
! 38: firstmove = TRUE;
! 39: }
! 40: }
! 41:
! 42: /*
! 43: step_ok()
! 44: returns true if it is ok for type to step on ch flgptr will be
! 45: NULL if we don't know what the monster is yet!
! 46: */
! 47:
! 48: int
! 49: step_ok(int y, int x, int can_on_monst, struct thing *flgptr)
! 50: {
! 51: struct linked_list *item;
! 52: char ch;
! 53:
! 54: /* What is here? Don't check monster window if MONSTOK is set */
! 55:
! 56: if (can_on_monst == MONSTOK)
! 57: ch = CCHAR( mvinch(y, x) );
! 58: else
! 59: ch = winat(y, x);
! 60:
! 61: switch (ch)
! 62: {
! 63: case ' ':
! 64: case '|':
! 65: case '-':
! 66: case SECRETDOOR:
! 67: if (flgptr && on(*flgptr, CANINWALL))
! 68: return(TRUE);
! 69:
! 70: return(FALSE);
! 71:
! 72: case SCROLL:
! 73: /*
! 74: * If it is a scroll, it might be a scare monster scroll so
! 75: * we need to look it up to see what type it is.
! 76: */
! 77:
! 78: if (flgptr && flgptr->t_ctype == C_MONSTER)
! 79: {
! 80: item = find_obj(y, x);
! 81:
! 82: if (item != NULL && (OBJPTR(item))->o_type == SCROLL
! 83: && (OBJPTR(item))->o_which == S_SCARE
! 84: && rnd(flgptr->t_stats.s_intel) < 12)
! 85: return(FALSE); /* All but smart ones are scared */
! 86: }
! 87: return(TRUE);
! 88:
! 89: default:
! 90: return(!isalpha(ch));
! 91: }
! 92: }
! 93:
! 94: /*
! 95: corr_move()
! 96: Check to see that a move is legal. If so, return correct
! 97: character. If not, if player came from a legal place, then try to turn
! 98: him.
! 99: */
! 100:
! 101: void
! 102: corr_move(int dy, int dx)
! 103: {
! 104: char ch;
! 105: short legal = 0; /* Number of legal alternatives */
! 106: int y = 0, x = 0; /* Holds legal new position */
! 107: int *ny, *nx; /* Point to which direction to change */
! 108:
! 109: /* New position */
! 110:
! 111: player.t_nxtpos.y = hero.y + dy;
! 112: player.t_nxtpos.x = hero.x + dx;
! 113:
! 114: /* A bad diagonal move is illegal */
! 115:
! 116: if (!diag_ok(&hero, &player.t_nxtpos, &player))
! 117: return;
! 118:
! 119: /* If it is a legal move, just return */
! 120:
! 121: if (player.t_nxtpos.x >= 0 && player.t_nxtpos.x < COLS && player.t_nxtpos.y > 0 && player.t_nxtpos.y < LINES - 2)
! 122: {
! 123: ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
! 124:
! 125: switch (ch)
! 126: {
! 127: case ' ':
! 128: case '|':
! 129: case '-':
! 130: break;
! 131: default:
! 132: return;
! 133: }
! 134: }
! 135:
! 136: /* Check the legal alternatives */
! 137:
! 138: if (dy == 0)
! 139: {
! 140: ny = &dy;
! 141: nx = &dx;
! 142: }
! 143: else
! 144: {
! 145: ny = &dx;
! 146: nx = &dy;
! 147: }
! 148:
! 149: for (*nx = 0, *ny = -1; *ny < 2; *ny += 2)
! 150: {
! 151: /* New position */
! 152: player.t_nxtpos.y = hero.y + dy;
! 153: player.t_nxtpos.x = hero.x + dx;
! 154:
! 155: if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y > LINES - 3)
! 156: continue;
! 157:
! 158: ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
! 159:
! 160: switch (ch)
! 161: {
! 162: case ' ':
! 163: case '|':
! 164: case '-':
! 165: break;
! 166: default:
! 167: legal++;
! 168: y = dy;
! 169: x = dx;
! 170: }
! 171: }
! 172:
! 173: /* If we have 2 legal moves, make no change */
! 174:
! 175: if (legal != 1)
! 176: return;
! 177:
! 178: /* Make the change */
! 179:
! 180: if (y == 0) /* Move horizontally */
! 181: {
! 182: if (x == 1)
! 183: runch = 'l';
! 184: else
! 185: runch = 'h';
! 186: }
! 187: else /* Move vertically */
! 188: {
! 189: if (y == 1)
! 190: runch = 'j';
! 191: else
! 192: runch = 'k';
! 193: }
! 194:
! 195: return;
! 196: }
! 197:
! 198:
! 199: /*
! 200: do_move()
! 201: Check to see that a move is legal. If it is handle the
! 202: consequences (fighting, picking up, etc.)
! 203: */
! 204:
! 205: void
! 206: do_move(int dy, int dx)
! 207: {
! 208: char ch;
! 209: coord old_hero;
! 210: char hch;
! 211:
! 212: firstmove = FALSE;
! 213:
! 214: if (player.t_no_move)
! 215: {
! 216: player.t_no_move--;
! 217: msg("You are still stuck in the bear trap.");
! 218: return;
! 219: }
! 220:
! 221: /* Do a confused move (maybe) */
! 222:
! 223: if ((rnd(100) < 80 && on(player, ISHUH)) ||
! 224: (is_wearing(R_DELUSION) && rnd(100) < 25) ||
! 225: on(player, STUMBLER) && rnd(40) == 0)
! 226: player.t_nxtpos = rndmove(&player);
! 227: else
! 228: {
! 229: player.t_nxtpos.y = hero.y + dy;
! 230: player.t_nxtpos.x = hero.x + dx;
! 231: }
! 232:
! 233: /*
! 234: * Check if he tried to move off the screen or make an illegal
! 235: * diagonal move, and stop him if he did.
! 236: */
! 237:
! 238: if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y >= LINES - 2
! 239: || !diag_ok(&hero, &player.t_nxtpos, &player))
! 240: {
! 241: after = fighting = running = FALSE;
! 242: return;
! 243: }
! 244:
! 245: if (running && ce(hero, player.t_nxtpos))
! 246: after = running = FALSE;
! 247:
! 248: ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
! 249:
! 250: if (isalpha(ch))
! 251: debug("Moving onto monster %c",ch);
! 252:
! 253: /* Take care of hero trying to move close to something frightening */
! 254:
! 255: if (on(player, ISFLEE))
! 256: {
! 257: if (rnd(10) < 1)
! 258: {
! 259: turn_off(player, ISFLEE);
! 260: msg("You regain your composure.");
! 261: }
! 262: else if (DISTANCE(player.t_nxtpos, player.t_chasee->t_pos) <
! 263: DISTANCE(hero,player.t_chasee->t_pos))
! 264: return;
! 265: }
! 266:
! 267: /* Take care of hero being held */
! 268:
! 269: if (on(player, ISHELD) && !isalpha(ch))
! 270: {
! 271: if (rnd(pstats.s_str) > 14)
! 272: {
! 273: msg("You break free of the hold.");
! 274:
! 275: if (--hold_count == 0)
! 276: turn_off(player, ISHELD);
! 277: }
! 278: else
! 279: {
! 280: msg("You are being held.");
! 281: return;
! 282: }
! 283: }
! 284:
! 285: /* Might lose disguise */
! 286:
! 287: if (on(player, ISDISGUISE) && rnd(11 * pstats.s_dext) == 0)
! 288: {
! 289: extinguish_fuse(FUSE_UNDISGUISE);
! 290: undisguise(NULL);
! 291: }
! 292:
! 293: /* assume he's not in a wall */
! 294:
! 295: if (!isalpha(ch))
! 296: turn_off(player, ISINWALL);
! 297:
! 298: hch = CCHAR( mvinch(hero.y, hero.x) ); /* Where hero was */
! 299: old_hero = hero; /* Save hero's old position */
! 300:
! 301: switch (ch)
! 302: {
! 303: case ' ':
! 304: case '|':
! 305: case '-':
! 306: case SECRETDOOR:
! 307: if (off(player, CANINWALL))
! 308: {
! 309: after = running = FALSE;
! 310: return;
! 311: }
! 312: else if (running)
! 313: {
! 314: after = running = FALSE;
! 315: return;
! 316: }
! 317: turn_on(player, ISINWALL);
! 318: break;
! 319:
! 320: case TRAPDOOR:
! 321: case TELTRAP:
! 322: case BEARTRAP:
! 323: case SLEEPTRAP:
! 324: case ARROWTRAP:
! 325: case DARTTRAP:
! 326: case POOL:
! 327: case MAZETRAP:
! 328: case FIRETRAP:
! 329: case POISONTRAP:
! 330: case LAIR:
! 331: case RUSTTRAP:
! 332: ch = be_trapped(&player, player.t_nxtpos);
! 333:
! 334: if (!is_wearing(R_LEVITATION) && off(player, CANFLY) &&
! 335: (old_hero.x != hero.x || old_hero.y != hero.y
! 336: || pool_teleport))
! 337: {
! 338: pool_teleport = FALSE;
! 339: return;
! 340: }
! 341:
! 342: break;
! 343:
! 344: case GOLD:
! 345: case POTION:
! 346: case SCROLL:
! 347: case FOOD:
! 348: case WEAPON:
! 349: case ARMOR:
! 350: case RING:
! 351: case ARTIFACT:
! 352: case STICK:
! 353: running = FALSE;
! 354: take = ch;
! 355: break;
! 356:
! 357: default:
! 358: break;
! 359: }
! 360:
! 361: if (ch == FIRETRAP)
! 362: light(&hero);
! 363:
! 364: hero = player.t_nxtpos; /* Move the hero */
! 365:
! 366: /* adjust lighting */
! 367:
! 368: if (roomin(hero) == NULL && (hch == '-' || hch == '|' ||
! 369: hch == DOOR || hch == SECRETDOOR))
! 370: {
! 371: /* Leaving a room -- darken it */
! 372: struct room *rp = roomin(old_hero);
! 373: int is_lit = FALSE;
! 374:
! 375: if (!(rp->r_flags & ISDARK))
! 376: is_lit = TRUE;
! 377:
! 378: rp->r_flags |= ISDARK; /* Fake darkness */
! 379: light(&old_hero);
! 380:
! 381: if (is_lit)
! 382: rp->r_flags &= ~ISDARK; /* Restore light state */
! 383: }
! 384: else if (ch == DOOR || ch == SECRETDOOR || ch == '|' || ch == '-')
! 385: {
! 386: /* Entering a room */
! 387: running = FALSE;
! 388: if (hch != '|' && hch != '-')
! 389: light(&hero); /* knows whether the hero can see things in */
! 390: }
! 391:
! 392: /* handle other situations */
! 393:
! 394: if (ch == STAIRS)
! 395: running = FALSE;
! 396: else if (ch == POST)
! 397: {
! 398: running = FALSE;
! 399: new_level(POSTLEV,0);
! 400: return;
! 401: }
! 402: else if (isalpha(ch))
! 403: {
! 404: struct linked_list *mp;
! 405: struct thing *tp;
! 406: char t;
! 407:
! 408: running = FALSE;
! 409:
! 410: mp = find_mons(hero.y, hero.x);
! 411:
! 412: if (mp == NULL)
! 413: return;
! 414:
! 415: tp = THINGPTR(mp);
! 416:
! 417: if (good_monster(*tp)) /* Exchange places with your buddy */
! 418: {
! 419: mvwaddch(cw, old_hero.y, old_hero.x, ch);
! 420: mvwaddch(mw, old_hero.y, old_hero.x, ch);
! 421: mvwaddch(mw, hero.y, hero.x, ' ');
! 422: mvwaddch(cw, hero.y, hero.x, tp->t_oldch);
! 423:
! 424: (*tp).t_pos.x = old_hero.x; /* Update monster position variables */
! 425: (*tp).t_pos.y = old_hero.y;
! 426: (*tp).t_oldpos.x = old_hero.x;
! 427: (*tp).t_oldpos.y = old_hero.y;
! 428:
! 429: t = (*tp).t_oldch;
! 430: (*tp).t_oldch = player.t_oldch;
! 431: player.t_oldch = t;
! 432:
! 433: turn_on(*tp, ISRUN);
! 434:
! 435: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 436:
! 437: /* make sure that the room shows OK */
! 438:
! 439: light(&hero);
! 440:
! 441: wrefresh(cw);
! 442: return;
! 443: }
! 444: else
! 445: {
! 446: hero = old_hero; /* Restore hero -- we'll fight instead of move */
! 447:
! 448: /* make sure that the room shows OK */
! 449: light(&hero);
! 450:
! 451: fight(&player.t_nxtpos, cur_weapon, NOTHROWN);
! 452:
! 453: return;
! 454: }
! 455: }
! 456: else
! 457: fighting = FALSE;
! 458:
! 459: ch = winat(old_hero.y, old_hero.x);
! 460: mvwaddch(cw, old_hero.y, old_hero.x, ch);
! 461: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 462: }
! 463:
! 464: /*
! 465: light()
! 466: Called to illuminate a room. If it is dark, remove anything that might
! 467: move.
! 468: */
! 469:
! 470: void
! 471: light(coord *cp)
! 472: {
! 473: struct room *rp;
! 474: int j, k, x, y;
! 475: char ch, rch;
! 476: struct linked_list *item;
! 477: int jlow, jhigh, klow, khigh; /* Boundaries of lit area */
! 478:
! 479: if ((rp = roomin(*cp)) != NULL && !on(player, ISBLIND))
! 480: {
! 481:
! 482: /* is he wearing ring of illumination and in same room? */
! 483:
! 484: if ((is_wearing(R_LIGHT) || on(player, ISELECTRIC)) &&
! 485: cp == &hero)
! 486: rp->r_flags &= ~ISDARK;
! 487:
! 488: /* If we are in a maze, don't look at the whole room (level) */
! 489:
! 490: if (levtype == MAZELEV)
! 491: {
! 492: jlow = max(0, hero.y - 2 - rp->r_pos.y);
! 493: jhigh = min(rp->r_max.y, hero.y + 2 - rp->r_pos.y + 1);
! 494: klow = max(0, hero.x - 2 - rp->r_pos.x);
! 495: khigh = min(rp->r_max.x, hero.x + 2 - rp->r_pos.x + 1);
! 496: }
! 497: else
! 498: {
! 499: jlow = klow = 0;
! 500: jhigh = rp->r_max.y;
! 501: khigh = rp->r_max.x;
! 502: }
! 503:
! 504: for (j = 0; j < rp->r_max.y; j++)
! 505: {
! 506: for (k = 0; k < rp->r_max.x; k++)
! 507: {
! 508: /* Is this in the given area -- needed for maze */
! 509:
! 510: if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh))
! 511: continue;
! 512:
! 513: y = rp->r_pos.y + j;
! 514: x = rp->r_pos.x + k;
! 515:
! 516: ch = show(y, x);
! 517: wmove(cw, y, x);
! 518:
! 519: /* Figure out how to display a secret door */
! 520:
! 521: if (ch == SECRETDOOR)
! 522: {
! 523: if (j == 0 || j == rp->r_max.y - 1)
! 524: ch = '-';
! 525: else
! 526: ch = '|';
! 527: }
! 528:
! 529: /*
! 530: * For monsters, if they were previously not
! 531: * seen and now can be seen, or vice-versa,
! 532: * make sure that will happen.
! 533: */
! 534:
! 535: if (isalpha(ch))
! 536: {
! 537: struct thing *tp;
! 538:
! 539: item = wake_monster(y, x);
! 540:
! 541: if (item == NULL)
! 542: continue;
! 543:
! 544: tp = THINGPTR(item);
! 545:
! 546: /* Previously not seen -- now can see it */
! 547:
! 548: if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x))
! 549: tp->t_oldch = CCHAR( mvinch(y, x) );
! 550:
! 551: /* Previously seen -- now can't see it */
! 552:
! 553: else if (off(player, ISBLIND) && tp->t_oldch != ' ' &&
! 554: !cansee(tp->t_pos.y, tp->t_pos.x))
! 555: tp->t_oldch = ' ';
! 556: }
! 557:
! 558: /*
! 559: * If the room is a dark room, we might want
! 560: * to remove monsters and the like from it
! 561: * (since they might move). A dark room or
! 562: * not in line-of-sight in a maze.
! 563: */
! 564:
! 565: if (((rp->r_flags & ISDARK) &&
! 566: !(rp->r_flags & HASFIRE)) ||
! 567: (levtype == MAZELEV &&
! 568: !maze_view(y, x)))
! 569: {
! 570: rch = CCHAR( mvwinch(cw, y, x) );
! 571:
! 572: switch (rch)
! 573: {
! 574: case DOOR:
! 575: case STAIRS:
! 576: case TRAPDOOR:
! 577: case TELTRAP:
! 578: case BEARTRAP:
! 579: case SLEEPTRAP:
! 580: case ARROWTRAP:
! 581: case DARTTRAP:
! 582: case POOL:
! 583: case MAZETRAP:
! 584: case FIRETRAP:
! 585: case POISONTRAP:
! 586: case LAIR:
! 587: case RUSTTRAP:
! 588: case POST:
! 589: case '|':
! 590: case '-':
! 591: case ' ':
! 592: ch = rch;
! 593: break;
! 594:
! 595: case FLOOR:
! 596: ch = (on(player, ISBLIND) ? FLOOR : ' ');
! 597: break;
! 598: default:
! 599: ch = ' ';
! 600: break;
! 601: }
! 602: }
! 603: mvwaddch(cw, y, x, ch);
! 604: }
! 605: }
! 606: }
! 607: }
! 608:
! 609: /*
! 610: blue_light()
! 611: magically light up a room (or level or make it dark)
! 612: */
! 613:
! 614: int
! 615: blue_light(int flags)
! 616: {
! 617: struct room *rp;
! 618: int blessed = (flags & ISBLESSED);
! 619: int cursed = (flags & ISCURSED);
! 620: int ret_val = FALSE; /* Whether or not affect is known */
! 621:
! 622: rp = roomin(hero); /* What room is hero in? */
! 623:
! 624: /* Darken the room if the magic is cursed */
! 625:
! 626: if (cursed)
! 627: {
! 628: if ((rp == NULL) || (rp->r_flags & ISDARK))
! 629: nothing_message(flags);
! 630: else
! 631: {
! 632: if (!(rp->r_flags & HASFIRE))
! 633: msg("The room suddenly goes dark.");
! 634: else
! 635: nothing_message(flags);
! 636:
! 637: rp->r_flags |= ISDARK;
! 638: ret_val = TRUE;
! 639: }
! 640: }
! 641: else
! 642: {
! 643: ret_val = TRUE;
! 644:
! 645: if (rp && (rp->r_flags & ISDARK) && !(rp->r_flags & HASFIRE))
! 646: {
! 647: msg("The room is lit by a %s blue light.",
! 648: blessed ? "bright" : "shimmering");
! 649: }
! 650: else if (winat(hero.y, hero.x) == PASSAGE)
! 651: msg("The corridor glows %sand then fades.", blessed ? "brightly " : "");
! 652: else
! 653: {
! 654: ret_val = FALSE;
! 655: nothing_message(flags);
! 656: }
! 657:
! 658: if (blessed)
! 659: {
! 660: short i; /* Index through rooms */
! 661:
! 662: for (i = 0; i < MAXROOMS; i++)
! 663: rooms[i].r_flags &= ~ISDARK;
! 664: }
! 665: else if (rp)
! 666: rp->r_flags &= ~ISDARK;
! 667: }
! 668:
! 669: /* Light the room and put the player back up */
! 670:
! 671: light(&hero);
! 672: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 673:
! 674: return (ret_val);
! 675: }
! 676:
! 677: /*
! 678: show()
! 679: returns what a certain thing will display as to the un-initiated
! 680: */
! 681:
! 682: char
! 683: show(int y, int x)
! 684: {
! 685: char ch = winat(y, x);
! 686: struct linked_list *it;
! 687: struct thing *tp;
! 688:
! 689: if (isatrap(ch))
! 690: {
! 691: struct trap *trp = trap_at(y, x);
! 692: return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show;
! 693: }
! 694: else if (isalpha(ch))
! 695: {
! 696: if ((it = find_mons(y, x)) == NULL)
! 697: {
! 698: debug("Can't find monster in move.");
! 699: return ' ';
! 700: }
! 701: tp = THINGPTR(it);
! 702:
! 703: if (on(*tp, ISDISGUISE))
! 704: ch = tp->t_disguise; /* As a mimic */
! 705: else if (on(*tp, ISINVIS) || (on(*tp, ISSHADOW) &&
! 706: rnd(100) < 90) || on(*tp, CANSURPRISE))
! 707: {
! 708: if (off(player, CANSEE) || on(*tp, CANSURPRISE))
! 709: ch = CCHAR( mvwinch(stdscr, y, x) ); /* Invisible */
! 710: }
! 711: else if (on(*tp, CANINWALL))
! 712: {
! 713: char tch;
! 714:
! 715: tch = CCHAR( mvwinch(stdscr, y, x) );
! 716:
! 717: if (tch == WALL || tch == '-' || tch == '|')
! 718: ch = CCHAR( winch(stdscr) ); /* As Xorn */
! 719: }
! 720: }
! 721: return(ch);
! 722: }
! 723:
! 724: /*
! 725: be_trapped()
! 726: The guy stepped on a trap.... Make him pay.
! 727: */
! 728:
! 729: char
! 730: be_trapped(struct thing *th, coord tc)
! 731: {
! 732: struct trap *tp;
! 733: char ch, *mname = NULL;
! 734: int is_player = (th == &player), can_see = cansee(tc.y, tc.x);
! 735: struct linked_list *mitem = NULL;
! 736:
! 737: tp = trap_at(tc.y, tc.x);
! 738: ch = tp->tr_type;
! 739:
! 740: if (!is_player)
! 741: {
! 742: mitem = find_mons(th->t_pos.y, th->t_pos.x);
! 743: mname = monsters[th->t_index].m_name;
! 744:
! 745: /* Flying monsters do not set off traps */
! 746:
! 747: if (!mitem || (on(*th, CANFLY) &&
! 748: (ch == BEARTRAP || ch == MAZETRAP || ch == TRAPDOOR
! 749: || ch == ARROWTRAP || ch == DARTTRAP)))
! 750: {
! 751: debug("%s avoided trap.", mname);
! 752: return(ch);
! 753: }
! 754: }
! 755: else
! 756: {
! 757: short thief_bonus = -50;
! 758:
! 759: count = running = FALSE;
! 760: mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type);
! 761:
! 762: if (no_command)
! 763: return(ch);
! 764:
! 765: if (player.t_ctype == C_THIEF || player.t_ctype == C_NINJA)
! 766: thief_bonus = 10;
! 767:
! 768: if (((is_wearing(R_LEVITATION) || on(player, CANFLY)) &&
! 769: (ch != FIRETRAP ||
! 770: (ch == FIRETRAP && !(tp->tr_flags & ISFOUND))))
! 771: || (moving && (tp->tr_flags & ISFOUND) && rnd(100) <
! 772: thief_bonus + 2 * pstats.s_dext + 5 * pstats.s_lvl) &&
! 773: (ch == BEARTRAP || ch == MAZETRAP || ch == TRAPDOOR
! 774: || ch == ARROWTRAP || ch == DARTTRAP))
! 775: {
! 776: static char trname[1024];
! 777: msg(tr_name(ch,trname));
! 778: tp->tr_flags |= ISFOUND;
! 779: return(ch);
! 780: }
! 781:
! 782: if (moving)
! 783: msg("Your attempt fails.");
! 784: }
! 785:
! 786: tp->tr_flags |= ISFOUND;
! 787:
! 788: switch(ch)
! 789: {
! 790: case TRAPDOOR:
! 791: if (is_player)
! 792: {
! 793: level++;
! 794: new_level(NORMLEV,0);
! 795: addmsg("You fell into a trap");
! 796:
! 797: if (player.t_ctype != C_THIEF
! 798: && player.t_ctype != C_ASSASIN
! 799: && player.t_ctype != C_NINJA
! 800: && rnd(pstats.s_dext) < 4)
! 801: {
! 802: addmsg(" and were damaged by the fall");
! 803:
! 804: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
! 805: {
! 806: addmsg("! The fall killed you.");
! 807: endmsg();
! 808: death(D_FALL);
! 809:
! 810: return(ch);
! 811: }
! 812: }
! 813:
! 814: addmsg("!");
! 815: endmsg();
! 816:
! 817: if (off(player, ISCLEAR) && rnd(4) < 3)
! 818: {
! 819: if (on(player, ISHUH))
! 820: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
! 821: else
! 822: light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION, AFTER);
! 823:
! 824: turn_on(player, ISHUH);
! 825: }
! 826: else
! 827: msg("You feel dizzy for a moment, but it quickly passes.");
! 828: }
! 829: else
! 830: {
! 831: if (can_see)
! 832: msg("The %s fell into a trap!", mname);
! 833:
! 834: if (on(*th, ISFAMILIAR))
! 835: turn_off(player, HASFAMILIAR);
! 836:
! 837: killed(NULL,mitem,NOMESSAGE,NOPOINTS);
! 838: }
! 839: break;
! 840:
! 841: case BEARTRAP:
! 842: if (is_stealth(th))
! 843: {
! 844: if (is_player)
! 845: msg("You pass a bear trap.");
! 846: else if (can_see)
! 847: msg("The %s passes a bear trap.", mname);
! 848: }
! 849: else
! 850: {
! 851: th->t_no_move += BEARTIME;
! 852:
! 853: if (is_player)
! 854: msg("You are caught in a bear trap.");
! 855: else if (can_see)
! 856: msg("The %s is caught in a bear trap.", mname);
! 857: }
! 858: break;
! 859:
! 860: case SLEEPTRAP:
! 861: if (is_player)
! 862: {
! 863: msg("A strange white mist envelops you.");
! 864:
! 865: if (!is_wearing(R_ALERT))
! 866: {
! 867: if (!is_wearing(R_BREATHE) && off(player, HASOXYGEN))
! 868: {
! 869: msg("You fall asleep.");
! 870: no_command += SLEEPTIME;
! 871: }
! 872: }
! 873: }
! 874: else
! 875: {
! 876: if (can_see)
! 877: msg("A strange white mist envelops the %s.", mname);
! 878:
! 879: if (on(*th, ISUNDEAD))
! 880: {
! 881: if (can_see)
! 882: msg("The mist doesn't seem to affect the %s.", mname);
! 883: }
! 884:
! 885: if (on(*th, ISUNDEAD) || on(*th, HASOXYGEN))
! 886: {
! 887: if (can_see)
! 888: msg("The mist doesn't seem to affect the %s.", mname);
! 889: }
! 890: else
! 891: {
! 892: th->t_no_move += SLEEPTIME;
! 893: }
! 894: }
! 895: break;
! 896:
! 897: case ARROWTRAP:
! 898: if (swing(th->t_ctype, th->t_stats.s_lvl - 1, th->t_stats.s_arm, 1))
! 899: {
! 900: if (is_player)
! 901: {
! 902: msg("Oh no! An arrow shot you.");
! 903:
! 904: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
! 905: {
! 906: msg("The arrow killed you.");
! 907: death(D_ARROW);
! 908: return(ch);
! 909: }
! 910: }
! 911: else
! 912: {
! 913: if (can_see)
! 914: msg("An arrow shot the %s.", mname);
! 915:
! 916: if (on(*th, NOSHARP))
! 917: {
! 918: if (can_see)
! 919: msg("The arrow has no effect!");
! 920: }
! 921: else
! 922: {
! 923: if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0)
! 924: {
! 925: if (can_see)
! 926: msg("The arrow killed the %s.", mname);
! 927:
! 928: if (on(*th, ISFAMILIAR))
! 929: turn_off(player, HASFAMILIAR);
! 930:
! 931: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 932: }
! 933: }
! 934: }
! 935: }
! 936: else
! 937: {
! 938: struct linked_list *itm;
! 939: struct object *an_arrow;
! 940:
! 941: if (is_player)
! 942: msg("An arrow shoots past you.");
! 943: else if (can_see)
! 944: msg("An arrow shoots by the %s.", mname);
! 945:
! 946: itm = new_item(sizeof *an_arrow);
! 947: an_arrow = OBJPTR(itm);
! 948: an_arrow->o_type = WEAPON;
! 949: an_arrow->o_which = ARROW;
! 950: an_arrow->o_hplus = rnd(3) - 1;
! 951: an_arrow->o_dplus = rnd(3) - 1;
! 952: init_weapon(an_arrow, ARROW);
! 953: an_arrow->o_count = 1;
! 954: an_arrow->o_pos = tc;
! 955: an_arrow->o_mark[0] = '\0';
! 956: fall(&player, itm, FALSE, FALSE);
! 957: }
! 958: break;
! 959:
! 960: case TELTRAP:
! 961: if (is_player)
! 962: {
! 963: teleport();
! 964:
! 965: if (off(player, ISCLEAR))
! 966: {
! 967: msg("Wait, what's going on here. Huh? What? Who?");
! 968:
! 969: if (on(player, ISHUH))
! 970: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
! 971: else
! 972: light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION, AFTER);
! 973:
! 974: turn_on(player, ISHUH);
! 975: }
! 976: else
! 977: msg("You feel dizzy for a moment, but it quickly passes.");
! 978: }
! 979: else
! 980: {
! 981: int rm;
! 982:
! 983: /* Erase the monster from the old position */
! 984:
! 985: if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
! 986: mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
! 987:
! 988: mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
! 989:
! 990: /* Get a new position */
! 991:
! 992: do
! 993: {
! 994: rm = rnd_room();
! 995: rnd_pos(&rooms[rm], &th->t_pos);
! 996: }
! 997: while(winat(th->t_pos.y, th->t_pos.x) != FLOOR);
! 998:
! 999: /* Put it there */
! 1000:
! 1001: mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
! 1002: th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) );
! 1003:
! 1004: if (can_see)
! 1005: msg("The %s seems to have disappeared!", mname);
! 1006: }
! 1007: break;
! 1008:
! 1009: case DARTTRAP:
! 1010:
! 1011: if (swing(th->t_ctype, th->t_stats.s_lvl + 1,th->t_stats.s_arm, 1))
! 1012: {
! 1013: if (is_player)
! 1014: {
! 1015: msg("A small dart just hit you in the shoulder.");
! 1016:
! 1017: if ((pstats.s_hpt -= roll(1, 4)) <= 0)
! 1018: {
! 1019: msg("The dart killed you.");
! 1020: death(D_DART);
! 1021: return(ch);
! 1022: }
! 1023:
! 1024: /* Now the poison */
! 1025:
! 1026: if (player.t_ctype != C_PALADIN
! 1027: && !(player.t_ctype == C_NINJA &&
! 1028: pstats.s_lvl > 12) && !save(VS_POISON))
! 1029: {
! 1030:
! 1031: /*
! 1032: * 75% chance it will do point
! 1033: * damage - else strength
! 1034: */
! 1035:
! 1036: if (rnd(100) < 75)
! 1037: {
! 1038: pstats.s_hpt /= 2;
! 1039:
! 1040: if (pstats.s_hpt == 0)
! 1041: {
! 1042: death(D_POISON);
! 1043: return(ch);
! 1044: }
! 1045: }
! 1046: else if (!is_wearing(R_SUSABILITY))
! 1047: chg_str(-1, FALSE, FALSE);
! 1048: }
! 1049: }
! 1050: else
! 1051: {
! 1052: int orig_hp = th->t_stats.s_hpt;
! 1053:
! 1054: if (can_see)
! 1055: msg("A small dart just hit the %s.", mname);
! 1056:
! 1057: /*
! 1058: * Poison has no effect on poisonous or
! 1059: * undead monsters
! 1060: */
! 1061:
! 1062: if (off(*th, CANPOISON) &&
! 1063: off(*th, ISUNDEAD) &&
! 1064: !save_throw(VS_POISON, th))
! 1065: th->t_stats.s_hpt /= 2;
! 1066:
! 1067: /* Now the dart damage */
! 1068:
! 1069: if (off(*th, NOSHARP))
! 1070: th->t_stats.s_hpt -= roll(1, 4);
! 1071:
! 1072: if (orig_hp == th->t_stats.s_hpt)
! 1073: if (can_see)
! 1074: msg("The dart has not effect!");
! 1075: else if (th->t_stats.s_hpt < 0)
! 1076: {
! 1077: if (can_see)
! 1078: msg("The dart killed the %s.", mname);
! 1079:
! 1080: if (on(*th, ISFAMILIAR))
! 1081: turn_off(player, HASFAMILIAR);
! 1082:
! 1083: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1084: }
! 1085: }
! 1086: }
! 1087: else
! 1088: {
! 1089: if (is_player)
! 1090: msg("A small dart whizzes by your ear and vanishes.");
! 1091: else if (can_see)
! 1092: msg("A small dart whizzes by the %s and vanishes.", mname);
! 1093: }
! 1094: break;
! 1095:
! 1096: case POOL:
! 1097: {
! 1098: int i;
! 1099:
! 1100: i = rnd(100);
! 1101:
! 1102: if (is_player)
! 1103: {
! 1104: if (on(player, ISELECTRIC))
! 1105: {
! 1106: msg("Oh no!!! The water shorts you out");
! 1107: extinguish_fuse(FUSE_UNELECTRIFY);
! 1108: turn_off(player, ISELECTRIC);
! 1109:
! 1110: if (!is_wearing(R_ELECTRESIST))
! 1111: {
! 1112: if ((pstats.s_hpt -= roll(1, 10)) <= 0)
! 1113: {
! 1114: addmsg("! The shock killed you.");
! 1115: endmsg();
! 1116: death(D_DROWN);
! 1117: return(ch);
! 1118: }
! 1119: }
! 1120: }
! 1121:
! 1122: if ((tp->tr_flags & ISGONE))
! 1123: {
! 1124: if (i < 30)
! 1125: {
! 1126: teleport(); /* teleport away */
! 1127:
! 1128: if (off(player, ISCLEAR))
! 1129: {
! 1130: if (on(player, ISHUH))
! 1131: lengthen_fuse(FUSE_UNCONFUSE,rnd(8)+HUHDURATION);
! 1132: else
! 1133: light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION,AFTER);
! 1134: turn_on(player, ISHUH);
! 1135: }
! 1136: else
! 1137: msg("You feel dizzy for a moment, but it quickly passes.");
! 1138:
! 1139: pool_teleport = TRUE;
! 1140: }
! 1141: else if ((i < 45) && level > 2)
! 1142: {
! 1143: level -= rnd(2) + 1;
! 1144: new_level(NORMLEV,0);
! 1145: pool_teleport = TRUE;
! 1146: msg("You here a faint groan from below.");
! 1147:
! 1148: if (off(player, ISCLEAR))
! 1149: {
! 1150: if (on(player, ISHUH))
! 1151: lengthen_fuse(FUSE_UNCONFUSE,rnd(8)+HUHDURATION);
! 1152: else
! 1153: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
! 1154:
! 1155: turn_on(player, ISHUH);
! 1156: }
! 1157: else
! 1158: msg("You feel dizzy for a moment, but it quickly passes.");
! 1159: }
! 1160: else if (i < 70)
! 1161: {
! 1162: level += rnd(4) + 1;
! 1163: new_level(NORMLEV,0);
! 1164: pool_teleport = TRUE;
! 1165: msg("You find yourself in strange surroundings.");
! 1166:
! 1167: if (off(player, ISCLEAR))
! 1168: {
! 1169: if (on(player, ISHUH))
! 1170: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
! 1171: else
! 1172: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
! 1173:
! 1174: turn_on(player, ISHUH);
! 1175: }
! 1176: else
! 1177: msg("You feel dizzy for a moment, but it quickly passes.");
! 1178: }
! 1179: else if (i > 95)
! 1180: {
! 1181: if (is_wearing(R_BREATHE) || on(player, HASOXYGEN))
! 1182: msg("You splash in the pool unharmed.");
! 1183: else
! 1184: {
! 1185: msg("Oh no!!! You drown in the pool!!! --More--");
! 1186: wait_for(' ');
! 1187: death(D_DROWN);
! 1188: return(ch);
! 1189: }
! 1190: }
! 1191: }
! 1192: }
! 1193: else
! 1194: {
! 1195: if (can_see)
! 1196: msg("The %s fell into the pool!", mname);
! 1197:
! 1198: if (i < 15)
! 1199: {
! 1200: if (off(*th, HASOXYGEN))
! 1201: {
! 1202: if (can_see)
! 1203: msg("The %s has drowned!", mname);
! 1204:
! 1205: if (on(*th, ISFAMILIAR))
! 1206: turn_off(player, HASFAMILIAR);
! 1207:
! 1208: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1209: }
! 1210: }
! 1211: }
! 1212: }
! 1213: break;
! 1214:
! 1215: case MAZETRAP:
! 1216:
! 1217: if (is_player)
! 1218: {
! 1219: level++;
! 1220: new_level(MAZELEV,0);
! 1221: addmsg("You are surrounded by twisty passages");
! 1222:
! 1223: if (rnd(4) < 1)
! 1224: {
! 1225: addmsg(" and were damaged by the fall");
! 1226:
! 1227: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
! 1228: {
! 1229: addmsg("! The fall killed you.");
! 1230: endmsg();
! 1231: death(D_FALL);
! 1232: return(ch);
! 1233: }
! 1234: }
! 1235:
! 1236: addmsg("!");
! 1237: endmsg();
! 1238:
! 1239: if (off(player, ISCLEAR))
! 1240: {
! 1241: if (on(player, ISHUH))
! 1242: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
! 1243: else
! 1244: {
! 1245: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
! 1246: turn_on(player, ISHUH);
! 1247: }
! 1248: }
! 1249: else
! 1250: msg("You feel dizzy for a moment, but it quickly passes.");
! 1251: }
! 1252: else
! 1253: {
! 1254: if (can_see)
! 1255: msg("The %s fell into a trap!", mname);
! 1256:
! 1257: if (on(*th, ISFAMILIAR))
! 1258: turn_off(player, HASFAMILIAR);
! 1259:
! 1260: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1261: }
! 1262: break;
! 1263:
! 1264: case FIRETRAP:
! 1265: {
! 1266: struct room *rp = roomin(hero);
! 1267:
! 1268: if (is_player)
! 1269: {
! 1270: if (is_wearing(R_FIRERESIST) || on(player, NOFIRE))
! 1271: msg("You pass through the flames unharmed.");
! 1272: else
! 1273: {
! 1274: addmsg("You are burned by the flames");
! 1275:
! 1276: if ((pstats.s_hpt -= roll(pstats.s_lvl, 2)) <= 0)
! 1277: {
! 1278: addmsg("! The flames killed you.");
! 1279: endmsg();
! 1280: death(D_FIRE);
! 1281: return(ch);
! 1282: }
! 1283:
! 1284: addmsg("!");
! 1285:
! 1286: endmsg();
! 1287: }
! 1288: }
! 1289: else
! 1290: {
! 1291: if (on(*th, CANBBURN))
! 1292: {
! 1293: if (can_see)
! 1294: msg("The %s is burned to death by the flames.", mname);
! 1295:
! 1296: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1297: }
! 1298: else if (on(*th, NOFIRE))
! 1299: {
! 1300: if (can_see)
! 1301: msg("The %s passes through the flames unharmed.", mname);
! 1302: }
! 1303: else
! 1304: {
! 1305: if (can_see)
! 1306: msg("The %s is burned by the flames.", mname);
! 1307:
! 1308: if ((th->t_stats.s_hpt -= roll(th->t_stats.s_lvl, 3)) < 0)
! 1309: {
! 1310: if (can_see)
! 1311: msg("The %s is burned to death by the flames.", mname);
! 1312:
! 1313: if (on(*th, ISFAMILIAR))
! 1314: turn_off(player, HASFAMILIAR);
! 1315:
! 1316: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1317: }
! 1318: else if (th->t_stats.s_intel < rnd(20))
! 1319: {
! 1320: if (can_see)
! 1321: msg("The %s turns and runs away in fear.", mname);
! 1322:
! 1323: turn_on(*th, ISFLEE);
! 1324: }
! 1325: }
! 1326: }
! 1327:
! 1328: if (rp != NULL)
! 1329: {
! 1330: rp->r_flags &= ~ISDARK;
! 1331: light(&hero);
! 1332: }
! 1333: }
! 1334: break;
! 1335:
! 1336: case POISONTRAP:
! 1337: if (is_player)
! 1338: {
! 1339: msg("You fall into a pool of poison.");
! 1340:
! 1341: if (rnd(4) > 0)
! 1342: {
! 1343: msg("You swallow some of the liquid and feel very sick.");
! 1344: pstats.s_hpt -= pstats.s_hpt / 3;
! 1345:
! 1346: if (player.t_ctype != C_PALADIN
! 1347: && !(player.t_ctype == C_NINJA &&
! 1348: pstats.s_lvl > 12)
! 1349: && !is_wearing(R_SUSABILITY))
! 1350: chg_str(-2, FALSE, FALSE);
! 1351: }
! 1352: else
! 1353: msg("The stuff tastes horrible.");
! 1354: }
! 1355: else
! 1356: {
! 1357: if (can_see)
! 1358: msg("The %s falls into the pool of poison.", mname);
! 1359:
! 1360: if (rnd(4) > 0 && off(*th, ISUNDEAD))
! 1361: if (th->t_stats.s_hpt *= 2.0 / 3.0 < 0)
! 1362: {
! 1363: if (can_see)
! 1364: msg("The %s dies from the poison.", mname);
! 1365:
! 1366: if (on(*th, ISFAMILIAR))
! 1367: turn_off(player, HASFAMILIAR);
! 1368:
! 1369: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1370: }
! 1371: }
! 1372: break;
! 1373:
! 1374: case LAIR:
! 1375: if (is_player)
! 1376: {
! 1377: msg("You found a monster lair!");
! 1378: mpos = 0;
! 1379: new_level(THRONE,0);
! 1380: }
! 1381: else
! 1382: {
! 1383: if (can_see)
! 1384: msg("The %s fell into a trap!", mname);
! 1385:
! 1386: if (on(*th, ISFAMILIAR))
! 1387: turn_off(player, HASFAMILIAR);
! 1388:
! 1389: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
! 1390: }
! 1391: break;
! 1392:
! 1393: case RUSTTRAP:
! 1394: if (is_player)
! 1395: {
! 1396: msg("You are splashed by water.");
! 1397:
! 1398: if (cur_armor != NULL &&
! 1399: cur_armor->o_which != SOFT_LEATHER &&
! 1400: cur_armor->o_which != HEAVY_LEATHER &&
! 1401: cur_armor->o_which != CUIRBOLILLI &&
! 1402: cur_armor->o_which != PADDED_ARMOR &&
! 1403: cur_armor->o_which != CRYSTAL_ARMOR &&
! 1404: cur_armor->o_which != MITHRIL &&
! 1405: !(cur_armor->o_flags & ISPROT) &&
! 1406: cur_armor->o_ac < pstats.s_arm + 1)
! 1407: {
! 1408: msg("Your armor weakens!");
! 1409: cur_armor->o_ac++;
! 1410: }
! 1411: else if (cur_armor != NULL && (cur_armor->o_flags & ISPROT))
! 1412: msg("The rust vanishes instantly!");
! 1413: }
! 1414: else
! 1415: {
! 1416: if (can_see)
! 1417: msg("The %s is splashed by water.", mname);
! 1418: }
! 1419: }
! 1420:
! 1421: return(ch);
! 1422: }
! 1423:
! 1424: /*
! 1425: dip_it()
! 1426: Dip an object into a magic pool
! 1427: */
! 1428:
! 1429: void
! 1430: dip_it(void)
! 1431: {
! 1432: struct linked_list *what;
! 1433: struct object *ob;
! 1434: struct trap *tp;
! 1435: int wh, i;
! 1436:
! 1437: tp = trap_at(hero.y, hero.x);
! 1438:
! 1439: if (tp == NULL || !(tp->tr_type == POOL || tp->tr_type == POISONTRAP))
! 1440: {
! 1441: msg("I see no pools here.");
! 1442: return;
! 1443: }
! 1444:
! 1445: if (tp->tr_flags & ISGONE)
! 1446: {
! 1447: msg("This %s appears to have been used once already.",
! 1448: (tp->tr_type == POOL ? "shimmering pool" : "poison pool"));
! 1449: return;
! 1450: }
! 1451:
! 1452: if ((what = get_item("dip", 0)) == NULL)
! 1453: {
! 1454: msg("");
! 1455: after = FALSE;
! 1456: return;
! 1457: }
! 1458:
! 1459: ob = OBJPTR(what);
! 1460: mpos = 0;
! 1461:
! 1462: if (ob == cur_armor)
! 1463: {
! 1464: msg("You have to take off your armor before you can dip it.");
! 1465: return;
! 1466: }
! 1467: else if (ob == cur_ring[LEFT_1] || ob == cur_ring[LEFT_2] ||
! 1468: ob == cur_ring[LEFT_3] || ob == cur_ring[LEFT_4] ||
! 1469: ob == cur_ring[RIGHT_1] || ob == cur_ring[RIGHT_2] ||
! 1470: ob == cur_ring[RIGHT_3] || ob == cur_ring[RIGHT_4])
! 1471: {
! 1472: msg("You have to take that ring off before you can dip it.");
! 1473: return;
! 1474: }
! 1475:
! 1476: tp->tr_flags |= ISGONE;
! 1477:
! 1478: if (ob != NULL && tp->tr_type == POOL)
! 1479: {
! 1480: wh = ob->o_which;
! 1481: ob->o_flags |= ISKNOW;
! 1482: i = rnd(100);
! 1483:
! 1484: switch (ob->o_type)
! 1485: {
! 1486: case WEAPON:
! 1487: if (i < 50)
! 1488: {
! 1489: if (!(ob->o_flags & ISCURSED))
! 1490: {
! 1491: ob->o_hplus += 1;
! 1492: ob->o_dplus += 1;
! 1493: }
! 1494: else
! 1495: {
! 1496: ob->o_hplus = rnd(2);
! 1497: ob->o_dplus = rnd(2);
! 1498: }
! 1499:
! 1500: ob->o_flags &= ~ISCURSED;
! 1501: msg("The %s glows blue for a moment.", weaps[wh].w_name);
! 1502: }
! 1503: else if (i < 70) /* curse weapon here */
! 1504: {
! 1505: if (!(ob->o_flags & ISCURSED))
! 1506: {
! 1507: ob->o_hplus = -(rnd(2) + 1);
! 1508: ob->o_dplus = -(rnd(2) + 1);
! 1509: }
! 1510: else /* if already cursed */
! 1511: {
! 1512: ob->o_hplus--;
! 1513: ob->o_dplus--;
! 1514: }
! 1515:
! 1516: ob->o_flags |= ISCURSED;
! 1517: msg("The %s glows red for a moment.", weaps[wh].w_name);
! 1518: }
! 1519: else
! 1520: msg("Nothing seems to happen.");
! 1521: break;
! 1522:
! 1523: case ARMOR:
! 1524:
! 1525: if (i < 50) /* enchant armor */
! 1526: {
! 1527: if (!(ob->o_flags & ISCURSED))
! 1528: ob->o_ac -= rnd(2) + 1;
! 1529: else
! 1530: ob->o_ac = -rnd(3) + armors[wh].a_class;
! 1531:
! 1532: ob->o_flags &= ~ISCURSED;
! 1533: msg("The %s glows blue for a moment.", armors[wh].a_name);
! 1534: }
! 1535: else if (i < 75) /* curse armor */
! 1536: {
! 1537: if (!(ob->o_flags & ISCURSED))
! 1538: ob->o_ac = rnd(3) + armors[wh].a_class;
! 1539: else
! 1540: ob->o_ac += rnd(2) + 1;
! 1541:
! 1542: ob->o_flags |= ISCURSED;
! 1543: msg("The %s glows red for a moment.", armors[wh].a_name);
! 1544: }
! 1545: else
! 1546: msg("Nothing seems to happen");
! 1547: break;
! 1548:
! 1549: case STICK:
! 1550: {
! 1551: int j;
! 1552:
! 1553: j = rnd(8) + 1;
! 1554:
! 1555: if (i < 50) /* add charges */
! 1556: {
! 1557: ob->o_charges += j;
! 1558: know_items[TYP_STICK][wh] = TRUE;
! 1559:
! 1560: if (ob->o_flags & ISCURSED)
! 1561: ob->o_flags &= ~ISCURSED;
! 1562:
! 1563: msg("The %s %s glows blue for a moment.",
! 1564: ws_made[wh], ws_type[wh]);
! 1565: }
! 1566: else if (i < 65) /* remove charges */
! 1567: {
! 1568: if ((ob->o_charges -= i) < 0)
! 1569: ob->o_charges = 0;
! 1570:
! 1571: know_items[TYP_STICK][wh] = TRUE;
! 1572:
! 1573: if (ob->o_flags & ISBLESSED)
! 1574: ob->o_flags &= ~ISBLESSED;
! 1575: else
! 1576: ob->o_flags |= ISCURSED;
! 1577:
! 1578: msg("The %s %s glows red for a moment.",
! 1579: ws_made[wh], ws_type[wh]);
! 1580: }
! 1581: else
! 1582: msg("Nothing seems to happen.");
! 1583: }
! 1584: break;
! 1585:
! 1586: case SCROLL:
! 1587:
! 1588: know_items[TYP_SCROLL][wh] = TRUE;
! 1589: msg("The '%s' scroll unfurls.", s_names[wh]);
! 1590: break;
! 1591:
! 1592: case POTION:
! 1593:
! 1594: know_items[TYP_POTION][wh] = TRUE;
! 1595: msg("The %s potion bubbles for a moment.", p_colors[wh]);
! 1596: break;
! 1597:
! 1598: case RING:
! 1599: if (i < 50) /* enchant ring */
! 1600: {
! 1601: if (!(ob->o_flags & ISCURSED))
! 1602: ob->o_ac += rnd(2) + 1;
! 1603: else
! 1604: ob->o_ac = rnd(2) + 1;
! 1605:
! 1606: ob->o_flags &= ~ISCURSED;
! 1607: }
! 1608: else if (i < 80) /* curse ring */
! 1609: {
! 1610: if (!(ob->o_flags & ISCURSED))
! 1611: ob->o_ac = -(rnd(2) + 1);
! 1612: else
! 1613: ob->o_ac -= (rnd(2) + 1);
! 1614:
! 1615: ob->o_flags |= ISCURSED;
! 1616: }
! 1617:
! 1618: know_items[TYP_RING][wh] = TRUE;
! 1619: msg("The %s ring vibrates for a moment.", r_stones[wh]);
! 1620: break;
! 1621:
! 1622: default:
! 1623: msg("The pool bubbles for a moment.");
! 1624: }
! 1625: }
! 1626: else if (ob != NULL && tp->tr_type == POISONTRAP)
! 1627: {
! 1628: if ((player.t_ctype == C_PALADIN) ||
! 1629: (player.t_ctype == C_CLERIC && rnd(2)))
! 1630: {
! 1631: msg("Trying to use poison is evil.");
! 1632: luck += 2;
! 1633: }
! 1634:
! 1635: if (ob->o_type != WEAPON || rnd(10) > 0)
! 1636: msg("Nothing seems to happen.");
! 1637: else
! 1638: {
! 1639: msg("Your %s is covered with a black sticky liquid.",
! 1640: weaps[ob->o_which].w_name);
! 1641: ob->o_flags |= ISPOISON;
! 1642: }
! 1643: }
! 1644: else
! 1645: msg("Nothing seems to happen.");
! 1646: }
! 1647:
! 1648: /*
! 1649: trap_at()
! 1650: find the trap at (y,x) on screen.
! 1651: */
! 1652:
! 1653: struct trap *
! 1654: trap_at(int y, int x)
! 1655: {
! 1656: struct trap *tp, *ep;
! 1657:
! 1658: ep = &traps[ntraps];
! 1659:
! 1660: for (tp = traps; tp < ep; tp++)
! 1661: if (tp->tr_pos.y == y && tp->tr_pos.x == x)
! 1662: break;
! 1663:
! 1664: if (tp == ep)
! 1665: {
! 1666: debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf));
! 1667: tp = NULL;
! 1668: }
! 1669:
! 1670: return(tp);
! 1671: }
! 1672:
! 1673: /*
! 1674: set_trap()
! 1675: set a trap at (y, x) on screen.
! 1676: */
! 1677:
! 1678: void
! 1679: set_trap(struct thing *tp, int y, int x)
! 1680: {
! 1681: int is_player = (tp == &player);
! 1682: int selection = rnd(7) + 1;
! 1683: char ch = 0, och;
! 1684: int thief_bonus = 0;
! 1685:
! 1686: switch(och = CCHAR( mvinch(y, x) ))
! 1687: {
! 1688: case WALL:
! 1689: case FLOOR:
! 1690: case PASSAGE:
! 1691: break;
! 1692: default:
! 1693: msg("The trap failed!");
! 1694: return;
! 1695: }
! 1696:
! 1697: if (is_player && (player.t_ctype == C_THIEF ||
! 1698: player.t_ctype == C_NINJA))
! 1699: thief_bonus = 10;
! 1700:
! 1701: if (ntraps >= 2 * MAXTRAPS || ++trap_tries >= MAXTRPTRY ||
! 1702: rnd(60) >= (tp->t_stats.s_dext + tp->t_stats.s_lvl / 2 +
! 1703: thief_bonus))
! 1704: {
! 1705: if (is_player)
! 1706: msg("The trap failed!");
! 1707:
! 1708: return;
! 1709: }
! 1710:
! 1711: /* Set up for redraw */
! 1712:
! 1713: clearok(cw, TRUE);
! 1714: touchwin(cw);
! 1715:
! 1716: if (is_player)
! 1717: {
! 1718: add_line("[1] Trap Door");
! 1719: add_line("[2] Bear Trap");
! 1720: add_line("[3] Sleep Trap");
! 1721: add_line("[4] Arrow Trap");
! 1722: add_line("[5] Teleport Trap");
! 1723: add_line("[6] Dart Trap");
! 1724: add_line("[7] Fire Trap");
! 1725: end_line();
! 1726: msg("Which trap? ");
! 1727:
! 1728: selection = (short) ((readchar() & 0177) - '0');
! 1729:
! 1730: while (selection < 1 || selection > 7)
! 1731: {
! 1732: if (selection == (short) ESCAPE - (short) '0')
! 1733: {
! 1734: after = FALSE;
! 1735: return;
! 1736: }
! 1737:
! 1738: msg("");
! 1739: msg("Please enter a selection between 1 and 7: ");
! 1740: selection = (short) ((readchar() & 0177) - '0');
! 1741: }
! 1742: }
! 1743:
! 1744: switch (selection)
! 1745: {
! 1746: case 1: ch = TRAPDOOR; break;
! 1747: case 2: ch = BEARTRAP; break;
! 1748: case 3: ch = SLEEPTRAP;break;
! 1749: case 4: ch = ARROWTRAP;break;
! 1750: case 5: ch = TELTRAP; break;
! 1751: case 6: ch = DARTTRAP; break;
! 1752: case 7: ch = FIRETRAP; break;
! 1753: }
! 1754:
! 1755: mvaddch(y, x, ch);
! 1756:
! 1757: traps[ntraps].tr_type = ch;
! 1758: traps[ntraps].tr_flags = ISTHIEFSET;
! 1759: traps[ntraps].tr_show = och;
! 1760: traps[ntraps].tr_pos.y = y;
! 1761: traps[ntraps++].tr_pos.x = x;
! 1762: }
! 1763:
! 1764:
! 1765: /*
! 1766: rndmove()
! 1767: move in a random direction if the monster/person is confused
! 1768: */
! 1769:
! 1770: coord
! 1771: rndmove(struct thing *who)
! 1772: {
! 1773: int x, y;
! 1774: int ex, ey, nopen = 0;
! 1775: coord ret; /* what we will be returning */
! 1776: coord dest;
! 1777:
! 1778: ret = who->t_pos;
! 1779:
! 1780: /*
! 1781: * Now go through the spaces surrounding the player and set that
! 1782: * place in the array to true if the space can be moved into
! 1783: */
! 1784:
! 1785: ey = ret.y + 1;
! 1786: ex = ret.x + 1;
! 1787:
! 1788: for (y = who->t_pos.y - 1; y <= ey; y++)
! 1789: if (y > 0 && y < LINES - 2)
! 1790: for (x = who->t_pos.x - 1; x <= ex; x++)
! 1791: {
! 1792: if (x < 0 || x >= COLS)
! 1793: continue;
! 1794:
! 1795: if (step_ok(y, x, NOMONST, who))
! 1796: {
! 1797: dest.y = y;
! 1798: dest.x = x;
! 1799:
! 1800: if (!diag_ok(&who->t_pos, &dest, who))
! 1801: continue;
! 1802:
! 1803: if (rnd(++nopen) == 0)
! 1804: ret = dest;
! 1805: }
! 1806: }
! 1807:
! 1808: return(ret);
! 1809: }
! 1810:
! 1811: /*
! 1812: isatrap()
! 1813: Returns TRUE if this character is some kind of trap
! 1814: */
! 1815:
! 1816: int
! 1817: isatrap(int ch)
! 1818: {
! 1819: switch(ch)
! 1820: {
! 1821: case DARTTRAP:
! 1822: case TELTRAP:
! 1823: case TRAPDOOR:
! 1824: case ARROWTRAP:
! 1825: case SLEEPTRAP:
! 1826: case POOL:
! 1827: case MAZETRAP:
! 1828: case FIRETRAP:
! 1829: case POISONTRAP:
! 1830: case LAIR:
! 1831: case RUSTTRAP:
! 1832: case BEARTRAP:
! 1833: return (TRUE);
! 1834: default:
! 1835: return (FALSE);
! 1836: }
! 1837: }
CVSweb