Annotation of early-roguelike/arogue5/move.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Hero movement commands
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Super-Rogue"
! 9: * Copyright (C) 1984 Robert D. Kindelberger
! 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 "curses.h"
! 20: #include <ctype.h>
! 21: #include "rogue.h"
! 22:
! 23: /*
! 24: * Used to hold the new hero position
! 25: */
! 26:
! 27: static coord nh;
! 28:
! 29: static const char Moves[3][3] = {
! 30: { 'y', 'k', 'u' },
! 31: { 'h', '\0', 'l' },
! 32: { 'b', 'j', 'n' }
! 33: };
! 34:
! 35: /*
! 36: * be_trapped:
! 37: * The guy stepped on a trap.... Make him pay.
! 38: */
! 39:
! 40: char
! 41: be_trapped(struct thing *th, coord *tc)
! 42: {
! 43: register struct trap *tp;
! 44: register char ch;
! 45: register const char *mname = NULL;
! 46: register bool is_player = (th == &player),
! 47: can_see;
! 48: register struct linked_list *mitem = NULL;
! 49:
! 50:
! 51: /* Can the player see the creature? */
! 52: can_see = (cansee(tc->y, tc->x) && (is_player || !invisible(th)));
! 53:
! 54: tp = trap_at(tc->y, tc->x);
! 55: /*
! 56: * if he's wearing boots of elvenkind, he won't set off the trap
! 57: * unless its a magic pool (they're not really traps)
! 58: */
! 59: if (is_player &&
! 60: cur_misc[WEAR_BOOTS] != NULL &&
! 61: cur_misc[WEAR_BOOTS]->o_which == MM_ELF_BOOTS &&
! 62: tp->tr_type != POOL)
! 63: return '\0';
! 64:
! 65: /*
! 66: * if the creature is flying then it won't set off the trap
! 67: */
! 68: if (on(*th, ISFLY))
! 69: return '\0';
! 70:
! 71: tp->tr_flags |= ISFOUND;
! 72:
! 73: if (!is_player) {
! 74: mitem = find_mons(th->t_pos.y, th->t_pos.x);
! 75: mname = monsters[th->t_index].m_name;
! 76: }
! 77: else {
! 78: count = running = FALSE;
! 79: mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type);
! 80: }
! 81: switch (ch = tp->tr_type) {
! 82: case TRAPDOOR:
! 83: if (is_player) {
! 84: level++;
! 85: pstats.s_hpt -= roll(1, 10);
! 86: if (pstats.s_hpt <= 0) death(D_FALL);
! 87: new_level(NORMLEV);
! 88: msg("You fell into a trap!");
! 89: }
! 90: else {
! 91: if (can_see) msg("The %s fell into a trap!", mname);
! 92:
! 93: /* See if the fall killed the monster */
! 94: if ((th->t_stats.s_hpt -= roll(1, 10)) <= 0) {
! 95: killed(mitem, FALSE, FALSE);
! 96: }
! 97: else { /* Just move monster to next level */
! 98: check_residue(th);
! 99:
! 100: /* Erase the monster from the old position */
! 101: if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
! 102: mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
! 103: mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
! 104: turn_on(*th, ISELSEWHERE);
! 105: detach(mlist, mitem);
! 106: attach(tlist, mitem); /* remember him next level */
! 107: }
! 108: }
! 109: when BEARTRAP:
! 110: if (is_stealth(th)) {
! 111: if (is_player) msg("You pass a bear trap.");
! 112: else if (can_see) msg("The %s passes a bear trap.", mname);
! 113: }
! 114: else {
! 115: th->t_no_move += BEARTIME;
! 116: if (is_player) msg("You are caught in a bear trap.");
! 117: else if (can_see) msg("The %s is caught in a bear trap.",
! 118: mname);
! 119: }
! 120: when SLEEPTRAP:
! 121: if (is_player) {
! 122: msg("A strange white mist envelops you.");
! 123: if (!ISWEARING(R_ALERT)) {
! 124: msg("You fall asleep.");
! 125: no_command += SLEEPTIME;
! 126: }
! 127: }
! 128: else {
! 129: if (can_see)
! 130: msg("A strange white mist envelops the %s.",mname);
! 131: if (on(*th, ISUNDEAD)) {
! 132: if (can_see)
! 133: msg("The mist doesn't seem to affect the %s.",mname);
! 134: }
! 135: else {
! 136: th->t_no_move += SLEEPTIME;
! 137: }
! 138: }
! 139: when ARROWTRAP:
! 140: if (swing(th->t_ctype, th->t_stats.s_lvl-1, th->t_stats.s_arm, 1))
! 141: {
! 142: if (is_player) {
! 143: msg("Oh no! An arrow shot you.");
! 144: if ((pstats.s_hpt -= roll(1, 6)) <= 0) {
! 145: msg("The arrow killed you.");
! 146: death(D_ARROW);
! 147: }
! 148: }
! 149: else {
! 150: if (can_see) msg("An arrow shot the %s.", mname);
! 151: if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0) {
! 152: if (can_see) msg("The arrow killed the %s.", mname);
! 153: killed(mitem, FALSE, FALSE);
! 154: }
! 155: }
! 156: }
! 157: else
! 158: {
! 159: register struct linked_list *item;
! 160: register struct object *arrow;
! 161:
! 162: if (is_player) msg("An arrow shoots past you.");
! 163: else if (can_see) msg("An arrow shoots by the %s.", mname);
! 164: item = new_item(sizeof *arrow);
! 165: arrow = OBJPTR(item);
! 166: arrow->o_type = WEAPON;
! 167: arrow->contents = NULL;
! 168: arrow->o_which = ARROW;
! 169: arrow->o_hplus = rnd(3) - 1;
! 170: arrow->o_dplus = rnd(3) - 1;
! 171: init_weapon(arrow, ARROW);
! 172: arrow->o_count = 1;
! 173: arrow->o_pos = *tc;
! 174: arrow->o_mark[0] = '\0';
! 175: fall(item, FALSE);
! 176: }
! 177: when TELTRAP:
! 178: if (is_player) teleport();
! 179: else {
! 180: register int rm;
! 181: struct room *old_room; /* old room of monster */
! 182:
! 183: /*
! 184: * Erase the monster from the old position
! 185: */
! 186: if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
! 187: mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
! 188: mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
! 189: /*
! 190: * check to see if room should go dark
! 191: */
! 192: if (on(*th, HASFIRE)) {
! 193: old_room=roomin(&th->t_pos);
! 194: if (old_room != NULL) {
! 195: register struct linked_list *fire_item;
! 196:
! 197: for (fire_item = old_room->r_fires; fire_item != NULL;
! 198: fire_item = next(fire_item)) {
! 199: if (THINGPTR(fire_item) == th) {
! 200: detach(old_room->r_fires, fire_item);
! 201: destroy_item(fire_item);
! 202:
! 203: if (old_room->r_fires == NULL) {
! 204: old_room->r_flags &= ~HASFIRE;
! 205: if (can_see) light(&hero);
! 206: }
! 207: }
! 208: }
! 209: }
! 210: }
! 211:
! 212: /* Get a new position */
! 213: do {
! 214: rm = rnd_room();
! 215: rnd_pos(&rooms[rm], &th->t_pos);
! 216: } until(winat(th->t_pos.y, th->t_pos.x) == FLOOR);
! 217:
! 218: /* Put it there */
! 219: mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
! 220: th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) );
! 221: /*
! 222: * check to see if room that creature appears in should
! 223: * light up
! 224: */
! 225: if (on(*th, HASFIRE)) {
! 226: register struct linked_list *fire_item;
! 227:
! 228: fire_item = creat_item();
! 229: ldata(fire_item) = (char *) th;
! 230: attach(rooms[rm].r_fires, fire_item);
! 231:
! 232: rooms[rm].r_flags |= HASFIRE;
! 233: if(cansee(th->t_pos.y, th->t_pos.x) &&
! 234: next(rooms[rm].r_fires) == NULL)
! 235: light(&hero);
! 236: }
! 237: if (can_see) msg("The %s seems to have disappeared!", mname);
! 238: }
! 239: when DARTTRAP:
! 240: if (swing(th->t_ctype, th->t_stats.s_lvl+1, th->t_stats.s_arm, 1)) {
! 241: if (is_player) {
! 242: msg("A small dart just hit you in the shoulder.");
! 243: if ((pstats.s_hpt -= roll(1, 4)) <= 0) {
! 244: msg("The dart killed you.");
! 245: death(D_DART);
! 246: }
! 247:
! 248: /* Now the poison */
! 249: if (!save(VS_POISON, &player, 0)) {
! 250: /* 75% chance it will do point damage - else strength */
! 251: if (rnd(100) < 75) {
! 252: pstats.s_hpt /= 2;
! 253: if (pstats.s_hpt == 0) death(D_POISON);
! 254: }
! 255: else if (!ISWEARING(R_SUSABILITY))
! 256: chg_str(-1);
! 257: }
! 258: }
! 259: else {
! 260: if (can_see)
! 261: msg("A small dart just hit the %s in the shoulder.",
! 262: mname);
! 263: if ((th->t_stats.s_hpt -= roll(1,4)) <= 0) {
! 264: if (can_see) msg("The dart killed the %s.", mname);
! 265: killed(mitem, FALSE, FALSE);
! 266: }
! 267: if (!save(VS_POISON, th, 0)) {
! 268: th->t_stats.s_hpt /= 2;
! 269: if (th->t_stats.s_hpt <= 0) {
! 270: if (can_see) msg("The dart killed the %s.", mname);
! 271: killed(mitem, FALSE, FALSE);
! 272: }
! 273: }
! 274: }
! 275: }
! 276: else {
! 277: if (is_player)
! 278: msg("A small dart whizzes by your ear and vanishes.");
! 279: else if (can_see)
! 280: msg("A small dart whizzes by the %s's ear and vanishes.",
! 281: mname);
! 282: }
! 283: when POOL: {
! 284: register int i;
! 285:
! 286: i = rnd(100);
! 287: if (is_player) {
! 288: if ((tp->tr_flags & ISGONE)) {
! 289: if (i < 30) {
! 290: teleport(); /* teleport away */
! 291: pool_teleport = TRUE;
! 292: }
! 293: else if((i < 45) && level > 2) {
! 294: level -= rnd(2) + 1;
! 295: cur_max = level;
! 296: new_level(NORMLEV);
! 297: pool_teleport = TRUE;
! 298: msg("You here a faint groan from below.");
! 299: }
! 300: else if(i < 70) {
! 301: level += rnd(4) + 1;
! 302: new_level(NORMLEV);
! 303: pool_teleport = TRUE;
! 304: msg("You find yourself in strange surroundings.");
! 305: }
! 306: else if(i > 95) {
! 307: msg("Oh no!!! You drown in the pool!!! --More--");
! 308: wait_for(cw,' ');
! 309: death(D_DROWN);
! 310: }
! 311: }
! 312: }
! 313: else {
! 314: if (i < 60) {
! 315: if (can_see) {
! 316: /* Drowns */
! 317: if (i < 30) msg("The %s drowned in the pool!", mname);
! 318:
! 319: /* Teleported to another level */
! 320: else msg("The %s disappeared!", mname);
! 321: }
! 322: killed(mitem, FALSE, FALSE);
! 323: }
! 324: }
! 325: }
! 326: when MAZETRAP:
! 327: if (is_player) {
! 328: pstats.s_hpt -= roll(1, 10);
! 329: level++;
! 330: msg("You fell through a trap door!");
! 331: if (pstats.s_hpt <= 0) death(D_FALL);
! 332: new_level(MAZELEV);
! 333: msg("You are surrounded by twisty passages!");
! 334: }
! 335: else {
! 336: if (can_see) msg("The %s fell into a trap!", mname);
! 337: killed(mitem, FALSE, FALSE);
! 338: }
! 339: }
! 340:
! 341: /* Move the cursor back onto the hero */
! 342: wmove(cw, hero.y, hero.x);
! 343:
! 344: md_flushinp(); /* flush typeahead */
! 345:
! 346: return(ch);
! 347: }
! 348:
! 349: /*
! 350: * blue_light:
! 351: * magically light up a room (or level or make it dark)
! 352: */
! 353:
! 354: bool
! 355: blue_light(bool blessed, bool cursed)
! 356: {
! 357: register struct room *rp;
! 358: bool ret_val=FALSE; /* Whether or not affect is known */
! 359:
! 360: rp = roomin(&hero); /* What room is hero in? */
! 361:
! 362: /* Darken the room if the magic is cursed */
! 363: if (cursed) {
! 364: if ((rp == NULL) || !lit_room(rp)) msg(nothing);
! 365: else {
! 366: rp->r_flags |= ISDARK;
! 367: if (!lit_room(rp) && (levtype != OUTSIDE || !daytime))
! 368: msg("The %s suddenly goes dark.",
! 369: levtype == OUTSIDE ? "area" : "room");
! 370: else msg(nothing);
! 371: ret_val = TRUE;
! 372: }
! 373: }
! 374: else {
! 375: ret_val = TRUE;
! 376: if (rp && !lit_room(rp) &&
! 377: (levtype != OUTSIDE || !daytime)) {
! 378: addmsg("The %s is lit", levtype == OUTSIDE ? "area" : "room");
! 379: if (!terse)
! 380: addmsg(" by a %s blue light.",
! 381: blessed ? "bright" : "shimmering");
! 382: endmsg();
! 383: }
! 384: else if (winat(hero.y, hero.x) == PASSAGE)
! 385: msg("The corridor glows %sand then fades",
! 386: blessed ? "brightly " : "");
! 387: else {
! 388: ret_val = FALSE;
! 389: msg(nothing);
! 390: }
! 391: if (blessed) {
! 392: register int i; /* Index through rooms */
! 393:
! 394: for (i=0; i<MAXROOMS; i++)
! 395: rooms[i].r_flags &= ~ISDARK;
! 396: }
! 397: else if (rp) rp->r_flags &= ~ISDARK;
! 398: }
! 399:
! 400: /*
! 401: * Light the room and put the player back up
! 402: */
! 403: light(&hero);
! 404: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 405: return(ret_val);
! 406: }
! 407:
! 408: /*
! 409: * corr_move:
! 410: * Check to see that a move is legal. If so, return correct character.
! 411: * If not, if player came from a legal place, then try to turn him.
! 412: */
! 413:
! 414: void
! 415: corr_move(int dy, int dx)
! 416: {
! 417: int legal=0; /* Number of legal alternatives */
! 418: register int y, x, /* Indexes though possible positions */
! 419: locy = 0, locx = 0; /* Hold delta of chosen location */
! 420:
! 421: /* New position */
! 422: nh.y = hero.y + dy;
! 423: nh.x = hero.x + dx;
! 424:
! 425: /* If it is a legal move, just return */
! 426: if (nh.x >= 0 && nh.x < COLS && nh.y > 0 && nh.y < LINES - 2) {
! 427:
! 428: switch (winat(nh.y, nh.x)) {
! 429: case WALL:
! 430: case '|':
! 431: case '-':
! 432: break;
! 433: default:
! 434: if (diag_ok(&hero, &nh, &player))
! 435: return;
! 436: }
! 437: }
! 438:
! 439: /* Check legal places surrounding the player -- ignore previous position */
! 440: for (y = hero.y - 1; y <= hero.y + 1; y++) {
! 441: if (y < 1 || y > LINES - 3)
! 442: continue;
! 443: for (x = hero.x - 1; x <= hero.x + 1; x++) {
! 444: /* Ignore borders of the screen */
! 445: if (x < 0 || x > COLS - 1)
! 446: continue;
! 447:
! 448: /*
! 449: * Ignore where we came from, where we are, and where we couldn't go
! 450: */
! 451: if ((x == hero.x - dx && y == hero.y - dy) ||
! 452: (x == hero.x + dx && y == hero.y + dy) ||
! 453: (x == hero.x && y == hero.y))
! 454: continue;
! 455:
! 456: switch (winat(y, x)) {
! 457: case WALL:
! 458: case '|':
! 459: case '-':
! 460: break;
! 461: default:
! 462: nh.y = y;
! 463: nh.x = x;
! 464: if (diag_ok(&hero, &nh, &player)) {
! 465: legal++;
! 466: locy = y - (hero.y - 1);
! 467: locx = x - (hero.x - 1);
! 468: }
! 469: }
! 470: }
! 471: }
! 472:
! 473: /* If we have 2 or more legal moves, make no change */
! 474: if (legal != 1) {
! 475: return;
! 476: }
! 477:
! 478: runch = Moves[locy][locx];
! 479:
! 480: /*
! 481: * For mazes, pretend like it is the beginning of a new run at each turn
! 482: * in order to get the lighting correct.
! 483: */
! 484: if (levtype == MAZELEV) firstmove = TRUE;
! 485: return;
! 486: }
! 487:
! 488: /*
! 489: * dip_it:
! 490: * Dip an object into a magic pool
! 491: */
! 492: void
! 493: dip_it(void)
! 494: {
! 495: reg struct linked_list *what;
! 496: reg struct object *ob;
! 497: reg struct trap *tp;
! 498: reg int wh, i;
! 499:
! 500: tp = trap_at(hero.y,hero.x);
! 501: if (tp == NULL || tp->tr_type != POOL) {
! 502: msg("I see no shimmering pool here");
! 503: return;
! 504: }
! 505: if (tp->tr_flags & ISGONE) {
! 506: msg("This shimmering pool appears to have used once already");
! 507: return;
! 508: }
! 509: if ((what = get_item(pack, "dip", ALL)) == NULL) {
! 510: msg("");
! 511: after = FALSE;
! 512: return;
! 513: }
! 514: ob = OBJPTR(what);
! 515: mpos = 0;
! 516: if (ob == cur_armor ||
! 517: ob == cur_misc[WEAR_BOOTS] || ob == cur_misc[WEAR_JEWEL] ||
! 518: ob == cur_misc[WEAR_GAUNTLET]|| ob == cur_misc[WEAR_CLOAK] ||
! 519: ob == cur_misc[WEAR_BRACERS] || ob == cur_misc[WEAR_NECKLACE]||
! 520: ob == cur_ring[LEFT_1] || ob == cur_ring[LEFT_2] ||
! 521: ob == cur_ring[LEFT_3] || ob == cur_ring[LEFT_4] ||
! 522: ob == cur_ring[RIGHT_1] || ob == cur_ring[RIGHT_2] ||
! 523: ob == cur_ring[RIGHT_3] || ob == cur_ring[RIGHT_4]) {
! 524: msg("You'll have to take it off first.");
! 525: return;
! 526: }
! 527: tp->tr_flags |= ISGONE;
! 528: if (ob != NULL) {
! 529: wh = ob->o_which;
! 530: ob->o_flags |= ISKNOW;
! 531: i = rnd(100);
! 532: switch(ob->o_type) {
! 533: case WEAPON:
! 534: if(i < 50) { /* enchant weapon here */
! 535: if ((ob->o_flags & ISCURSED) == 0) {
! 536: ob->o_hplus += 1;
! 537: ob->o_dplus += 1;
! 538: }
! 539: else { /* weapon was prev cursed here */
! 540: ob->o_hplus = rnd(2);
! 541: ob->o_dplus = rnd(2);
! 542: }
! 543: ob->o_flags &= ~ISCURSED;
! 544: msg("The %s glows blue for a moment.",weaps[wh].w_name);
! 545: }
! 546: else if(i < 70) { /* curse weapon here */
! 547: if ((ob->o_flags & ISCURSED) == 0) {
! 548: ob->o_hplus = -(rnd(2)+1);
! 549: ob->o_dplus = -(rnd(2)+1);
! 550: }
! 551: else { /* if already cursed */
! 552: ob->o_hplus--;
! 553: ob->o_dplus--;
! 554: }
! 555: ob->o_flags |= ISCURSED;
! 556: msg("The %s glows red for a moment.",weaps[wh].w_name);
! 557: }
! 558: else
! 559: msg(nothing);
! 560: when ARMOR:
! 561: if (i < 50) { /* enchant armor */
! 562: if((ob->o_flags & ISCURSED) == 0)
! 563: ob->o_ac -= rnd(2) + 1;
! 564: else
! 565: ob->o_ac = -rnd(3)+ armors[wh].a_class;
! 566: ob->o_flags &= ~ISCURSED;
! 567: msg("The %s glows blue for a moment",armors[wh].a_name);
! 568: }
! 569: else if(i < 75){ /* curse armor */
! 570: if ((ob->o_flags & ISCURSED) == 0)
! 571: ob->o_ac = rnd(3)+ armors[wh].a_class;
! 572: else
! 573: ob->o_ac += rnd(2) + 1;
! 574: ob->o_flags |= ISCURSED;
! 575: msg("The %s glows red for a moment.",armors[wh].a_name);
! 576: }
! 577: else
! 578: msg(nothing);
! 579: when STICK: {
! 580: int j;
! 581: j = rnd(8) + 1;
! 582: if(i < 50) { /* add charges */
! 583: ob->o_charges += j;
! 584: ws_know[wh] = TRUE;
! 585: if (ob->o_flags & ISCURSED)
! 586: ob->o_flags &= ~ISCURSED;
! 587: sprintf(outstring,"The %s %s glows blue for a moment.",
! 588: ws_made[wh],ws_type[wh]);
! 589: msg(outstring);
! 590: }
! 591: else if(i < 65) { /* remove charges */
! 592: if ((ob->o_charges -= i) < 0)
! 593: ob->o_charges = 0;
! 594: ws_know[wh] = TRUE;
! 595: if (ob->o_flags & ISBLESSED)
! 596: ob->o_flags &= ~ISBLESSED;
! 597: else
! 598: ob->o_flags |= ISCURSED;
! 599: sprintf(outstring,"The %s %s glows red for a moment.",
! 600: ws_made[wh],ws_type[wh]);
! 601: msg(outstring);
! 602: }
! 603: else
! 604: msg(nothing);
! 605: }
! 606: when SCROLL:
! 607: s_know[wh] = TRUE;
! 608: msg("The '%s' scroll unfurls.",s_names[wh]);
! 609: when POTION:
! 610: p_know[wh] = TRUE;
! 611: msg("The %s potion bubbles for a moment.",p_colors[wh]);
! 612: when RING:
! 613: if(i < 50) { /* enchant ring */
! 614: if ((ob->o_flags & ISCURSED) == 0)
! 615: ob->o_ac += rnd(2) + 1;
! 616: else
! 617: ob->o_ac = rnd(2) + 1;
! 618: ob->o_flags &= ~ISCURSED;
! 619: }
! 620: else if(i < 80) { /* curse ring */
! 621: if ((ob->o_flags & ISCURSED) == 0)
! 622: ob->o_ac = -(rnd(2) + 1);
! 623: else
! 624: ob->o_ac -= (rnd(2) + 1);
! 625: ob->o_flags |= ISCURSED;
! 626: }
! 627: r_know[wh] = TRUE;
! 628: msg("The %s ring vibrates for a moment.",r_stones[wh]);
! 629: when MM:
! 630: m_know[wh] = TRUE;
! 631: switch (ob->o_which) {
! 632: case MM_BRACERS:
! 633: case MM_PROTECT:
! 634: if(i < 50) { /* enchant item */
! 635: if ((ob->o_flags & ISCURSED) == 0)
! 636: ob->o_ac += rnd(2) + 1;
! 637: else
! 638: ob->o_ac = rnd(2) + 1;
! 639: ob->o_flags &= ~ISCURSED;
! 640: }
! 641: else if(i < 80) { /* curse item */
! 642: if ((ob->o_flags & ISCURSED) == 0)
! 643: ob->o_ac = -(rnd(2) + 1);
! 644: else
! 645: ob->o_ac -= (rnd(2) + 1);
! 646: ob->o_flags |= ISCURSED;
! 647: }
! 648: msg("The item vibrates for a moment.");
! 649: when MM_CHOKE:
! 650: case MM_DISAPPEAR:
! 651: ob->o_ac = 0;
! 652: msg ("The dust dissolves in the pool!");
! 653: }
! 654: otherwise:
! 655: msg("The pool bubbles for a moment.");
! 656: }
! 657: updpack(FALSE);
! 658: }
! 659: else
! 660: msg(nothing);
! 661: }
! 662:
! 663: /*
! 664: * do_move:
! 665: * Check to see that a move is legal. If it is handle the
! 666: * consequences (fighting, picking up, etc.)
! 667: */
! 668:
! 669: void
! 670: do_move(int dy, int dx)
! 671: {
! 672: register struct room *rp, *orp;
! 673: register char ch;
! 674: coord old_hero;
! 675: int i, wasfirstmove;
! 676:
! 677: wasfirstmove = firstmove;
! 678: firstmove = FALSE;
! 679: curprice = -1; /* if in trading post, we've moved off obj */
! 680: if (player.t_no_move) {
! 681: player.t_no_move--;
! 682: msg("You are still stuck in the bear trap");
! 683: return;
! 684: }
! 685: /*
! 686: * Do a confused move (maybe)
! 687: */
! 688: if ((on(player, ISHUH) && rnd(100) < 80) ||
! 689: (on(player, ISDANCE) && rnd(100) < 80) ||
! 690: (ISWEARING(R_DELUSION) && rnd(100) < 25))
! 691: nh = *rndmove(&player);
! 692: else {
! 693: nh.y = hero.y + dy;
! 694: nh.x = hero.x + dx;
! 695: }
! 696:
! 697: /*
! 698: * Check if he tried to move off the screen or make an illegal
! 699: * diagonal move, and stop him if he did.
! 700: */
! 701: if (nh.x < 0 || nh.x > COLS-1 || nh.y < 1 || nh.y >= LINES - 2
! 702: || !diag_ok(&hero, &nh, &player))
! 703: {
! 704: after = running = FALSE;
! 705: return;
! 706: }
! 707: if (running && ce(hero, nh))
! 708: after = running = FALSE;
! 709: ch = CCHAR( winat(nh.y, nh.x) );
! 710:
! 711: /* Take care of hero trying to move close to something frightening */
! 712: if (on(player, ISFLEE)) {
! 713: if (rnd(100) < 10) {
! 714: turn_off(player, ISFLEE);
! 715: msg("You regain your composure.");
! 716: }
! 717: else if (DISTANCE(nh.y, nh.x, player.t_dest->y, player.t_dest->x) <
! 718: DISTANCE(hero.y, hero.x, player.t_dest->y, player.t_dest->x))
! 719: return;
! 720: }
! 721:
! 722: /* Take care of hero being held */
! 723: if (on(player, ISHELD) && !isalpha(ch))
! 724: {
! 725: msg("You are being held");
! 726: return;
! 727: }
! 728:
! 729: /* assume he's not in a wall */
! 730: if (!isalpha(ch)) turn_off(player, ISINWALL);
! 731:
! 732: switch(ch) {
! 733: case '|':
! 734: case '-':
! 735: if (levtype == OUTSIDE) {
! 736: hero = nh;
! 737: new_level(OUTSIDE);
! 738: return;
! 739: }
! 740: case WALL:
! 741: case SECRETDOOR:
! 742: if (off(player, CANINWALL) || running) {
! 743: after = running = FALSE;
! 744:
! 745: /* Light if finishing run */
! 746: if (levtype == MAZELEV && lit_room(&rooms[0]))
! 747: look(FALSE, TRUE);
! 748:
! 749: after = running = FALSE;
! 750:
! 751: return;
! 752: }
! 753: turn_on(player, ISINWALL);
! 754: break;
! 755: case POOL:
! 756: if (levtype == OUTSIDE) {
! 757: lake_check(&nh);
! 758: running = FALSE;
! 759: break;
! 760: }
! 761: case MAZETRAP:
! 762: if (levtype == OUTSIDE) {
! 763: running = FALSE;
! 764: break;
! 765: }
! 766: case TRAPDOOR:
! 767: case TELTRAP:
! 768: case BEARTRAP:
! 769: case SLEEPTRAP:
! 770: case ARROWTRAP:
! 771: case DARTTRAP:
! 772: ch = be_trapped(&player, &nh);
! 773: if (ch == TRAPDOOR || ch == TELTRAP ||
! 774: pool_teleport || ch == MAZETRAP) {
! 775: pool_teleport = FALSE;
! 776: return;
! 777: }
! 778: break;
! 779: case GOLD:
! 780: case POTION:
! 781: case SCROLL:
! 782: case FOOD:
! 783: case WEAPON:
! 784: case ARMOR:
! 785: case RING:
! 786: case MM:
! 787: case RELIC:
! 788: case STICK:
! 789: running = FALSE;
! 790: take = ch;
! 791: break;
! 792: case DOOR:
! 793: case STAIRS:
! 794: running = FALSE;
! 795: break;
! 796: case POST:
! 797: running = FALSE;
! 798: new_level(POSTLEV);
! 799: return;
! 800: default:
! 801: break;
! 802: }
! 803:
! 804: if (isalpha(ch)) { /* if its a monster then fight it */
! 805: running = FALSE;
! 806: i = 1;
! 807: if (player.t_ctype == C_FIGHTER)
! 808: i += pstats.s_lvl/10;
! 809: while (i--)
! 810: fight(&nh, cur_weapon, FALSE);
! 811: return;
! 812: }
! 813:
! 814: /*
! 815: * if not fighting then move the hero
! 816: */
! 817: old_hero = hero; /* Save hero's old position */
! 818: hero = nh; /* Move the hero */
! 819: rp = roomin(&hero);
! 820: orp = roomin(&old_hero);
! 821:
! 822: /* Unlight any possible cross-corridor */
! 823: if (levtype == MAZELEV) {
! 824: register bool call_light = FALSE;
! 825: register char wall_check;
! 826:
! 827: if (wasfirstmove && lit_room(&rooms[0])) {
! 828: /* Are we moving out of a corridor? */
! 829: switch (runch) {
! 830: case 'h':
! 831: case 'l':
! 832: if (old_hero.y + 1 < LINES - 2) {
! 833: wall_check = CCHAR( winat(old_hero.y + 1, old_hero.x) );
! 834: if (!isrock(wall_check)) call_light = TRUE;
! 835: }
! 836: if (old_hero.y - 1 > 0) {
! 837: wall_check = CCHAR( winat(old_hero.y - 1, old_hero.x) );
! 838: if (!isrock(wall_check)) call_light = TRUE;
! 839: }
! 840: break;
! 841: case 'j':
! 842: case 'k':
! 843: if (old_hero.x + 1 < COLS) {
! 844: wall_check = CCHAR( winat(old_hero.y, old_hero.x + 1) );
! 845: if (!isrock(wall_check)) call_light = TRUE;
! 846: }
! 847: if (old_hero.x - 1 >= 0) {
! 848: wall_check = CCHAR( winat(old_hero.y, old_hero.x - 1) );
! 849: if (!isrock(wall_check)) call_light = TRUE;
! 850: }
! 851: break;
! 852: default:
! 853: call_light = TRUE;
! 854: }
! 855: player.t_oldpos = old_hero;
! 856: if (call_light) light(&old_hero);
! 857: }
! 858: }
! 859:
! 860: else if (orp != NULL && rp == NULL) { /* Leaving a room -- darken it */
! 861: orp->r_flags |= FORCEDARK; /* Fake darkness */
! 862: light(&old_hero);
! 863: orp->r_flags &= ~FORCEDARK; /* Restore light state */
! 864: }
! 865: else if (rp != NULL && orp == NULL){/* Entering a room */
! 866: light(&hero);
! 867: }
! 868: ch = CCHAR( winat(old_hero.y, old_hero.x) );
! 869: wmove(cw, unc(old_hero));
! 870: waddch(cw, ch);
! 871: wmove(cw, unc(hero));
! 872: waddch(cw, PLAYER);
! 873: }
! 874:
! 875: /*
! 876: * do_run:
! 877: * Start the hero running
! 878: */
! 879:
! 880: void
! 881: do_run(char ch)
! 882: {
! 883: firstmove = TRUE;
! 884: running = TRUE;
! 885: after = FALSE;
! 886: runch = ch;
! 887: }
! 888:
! 889: /*
! 890: * getdelta:
! 891: * Takes a movement character (eg. h, j, k, l) and returns the
! 892: * y and x delta corresponding to it in the remaining arguments.
! 893: * Returns TRUE if it could find it, FALSE otherwise.
! 894: */
! 895: bool
! 896: getdelta(char match, int *dy, int *dx)
! 897: {
! 898: int y, x;
! 899:
! 900: for (y = 0; y < 3; y++)
! 901: for (x = 0; x < 3; x++)
! 902: if (Moves[y][x] == match) {
! 903: *dy = y - 1;
! 904: *dx = x - 1;
! 905: return(TRUE);
! 906: }
! 907:
! 908: return(FALSE);
! 909: }
! 910:
! 911: /*
! 912: * isatrap:
! 913: * Returns TRUE if this character is some kind of trap
! 914: */
! 915: bool
! 916: isatrap(char ch)
! 917: {
! 918: switch(ch) {
! 919: case DARTTRAP:
! 920: case TELTRAP:
! 921: case TRAPDOOR:
! 922: case ARROWTRAP:
! 923: case SLEEPTRAP:
! 924: case BEARTRAP: return(TRUE);
! 925: case MAZETRAP:
! 926: case POOL: return(levtype != OUTSIDE);
! 927: default: return(FALSE);
! 928: }
! 929: }
! 930:
! 931: /*
! 932: * Called to illuminate a room.
! 933: * If it is dark, remove anything that might move.
! 934: */
! 935:
! 936: void
! 937: light(coord *cp)
! 938: {
! 939: register struct room *rp;
! 940: register int j, k, x, y;
! 941: register char ch, rch, sch;
! 942: register struct linked_list *item;
! 943: int jlow, jhigh, klow, khigh; /* Boundaries of lit area */
! 944:
! 945: if ((rp = roomin(cp)) != NULL) {
! 946: /*
! 947: * is he wearing ring of illumination?
! 948: */
! 949: if (&hero == cp && ISWEARING(R_LIGHT)) /* Must be hero's room */
! 950: rp->r_flags &= ~ISDARK;
! 951:
! 952: /* If we are in a maze, don't look at the whole room (level) */
! 953: if (levtype == MAZELEV) {
! 954: int see_radius;
! 955:
! 956: see_radius = 1;
! 957:
! 958: /* If we are looking at the hero in a rock, broaden our sights */
! 959: if (&hero == cp || &player.t_oldpos == cp) {
! 960: ch = CCHAR( winat(hero.y, hero.x) );
! 961: if (isrock(ch)) see_radius = 2;
! 962: ch = CCHAR( winat(player.t_oldpos.y, player.t_oldpos.x) );
! 963: if (isrock(ch)) see_radius = 2;
! 964: }
! 965:
! 966: jlow = max(0, cp->y - see_radius - rp->r_pos.y);
! 967: jhigh = min(rp->r_max.y, cp->y + see_radius + 1 - rp->r_pos.y);
! 968: klow = max(0, cp->x - see_radius - rp->r_pos.x);
! 969: khigh = min(rp->r_max.x, cp->x + see_radius + 1 - rp->r_pos.x);
! 970: }
! 971: else {
! 972: jlow = klow = 0;
! 973: jhigh = rp->r_max.y;
! 974: khigh = rp->r_max.x;
! 975: }
! 976: for (j = 0; j < rp->r_max.y; j++)
! 977: {
! 978: for (k = 0; k < rp->r_max.x; k++)
! 979: {
! 980: bool see_here = 0, see_before = 0;
! 981:
! 982: /* Is this in the give area -- needed for maze */
! 983: if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh))
! 984: continue;
! 985:
! 986: y = rp->r_pos.y + j;
! 987: x = rp->r_pos.x + k;
! 988:
! 989: /*
! 990: * If we are in a maze do not look at this area unless
! 991: * we can see it from where we are or where we last were
! 992: * (for erasing purposes).
! 993: */
! 994: if (levtype == MAZELEV) {
! 995: /* If we can't see it from here, could we see it before? */
! 996: if ((see_here = maze_view(y, x)) == FALSE) {
! 997: coord savhero;
! 998:
! 999: /* Could we see it from where we were? */
! 1000: savhero = hero;
! 1001: hero = player.t_oldpos;
! 1002: see_before = maze_view(y, x);
! 1003: hero = savhero;
! 1004:
! 1005: if (!see_before) continue;
! 1006: }
! 1007: }
! 1008:
! 1009: ch = show(y, x);
! 1010: wmove(cw, y, x);
! 1011: /*
! 1012: * Figure out how to display a secret door
! 1013: */
! 1014: if (ch == SECRETDOOR) {
! 1015: if (j == 0 || j == rp->r_max.y - 1)
! 1016: ch = '-';
! 1017: else
! 1018: ch = '|';
! 1019: }
! 1020: /* For monsters, if they were previously not seen and
! 1021: * now can be seen, or vice-versa, make sure that will
! 1022: * happen. This is for dark rooms as opposed to invisibility.
! 1023: *
! 1024: * Call winat() in the test because ch will not reveal
! 1025: * invisible monsters.
! 1026: */
! 1027: if (isalpha(winat(y, x))) {
! 1028: struct thing *tp; /* The monster */
! 1029:
! 1030: item = wake_monster(y, x);
! 1031: tp = THINGPTR(item);
! 1032:
! 1033: /* Previously not seen -- now can see it */
! 1034: if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x))
! 1035: tp->t_oldch = CCHAR( mvinch(y, x) );
! 1036:
! 1037: /* Previously seen -- now can't see it */
! 1038: else if (!cansee(tp->t_pos.y, tp->t_pos.x) &&
! 1039: roomin(&tp->t_pos) != NULL)
! 1040: switch (tp->t_oldch) {
! 1041: /*
! 1042: * Only blank it out if it is in a room and not
! 1043: * the border (or other wall) of the room.
! 1044: */
! 1045: case DOOR:
! 1046: case SECRETDOOR:
! 1047: case '-':
! 1048: case '|':
! 1049: break;
! 1050:
! 1051: otherwise:
! 1052: tp->t_oldch = ' ';
! 1053: }
! 1054: }
! 1055:
! 1056: /*
! 1057: * If the room is a dark room, we might want to remove
! 1058: * monsters and the like from it (since they might
! 1059: * move).
! 1060: * A dark room.
! 1061: */
! 1062: if ((!lit_room(rp) && (levtype != OUTSIDE)) ||
! 1063: (levtype == OUTSIDE && !daytime) ||
! 1064: on(player, ISBLIND) ||
! 1065: (rp->r_flags & FORCEDARK) ||
! 1066: (levtype == MAZELEV && !see_here && see_before)) {
! 1067: sch = CCHAR( mvwinch(cw, y, x) ); /* What's seen */
! 1068: rch = CCHAR( mvinch(y, x) ); /* What's really there */
! 1069: switch (rch) {
! 1070: case DOOR:
! 1071: case SECRETDOOR:
! 1072: case STAIRS:
! 1073: case TRAPDOOR:
! 1074: case TELTRAP:
! 1075: case BEARTRAP:
! 1076: case SLEEPTRAP:
! 1077: case ARROWTRAP:
! 1078: case DARTTRAP:
! 1079: case MAZETRAP:
! 1080: case POOL:
! 1081: case POST:
! 1082: case '|':
! 1083: case '-':
! 1084: case WALL:
! 1085: if (isalpha(sch)) ch = rch;
! 1086: else if (sch != FLOOR) ch = sch;
! 1087: else ch = ' '; /* Hide undiscoverd things */
! 1088: when FLOOR:
! 1089: ch = ' ';
! 1090: otherwise:
! 1091: ch = ' ';
! 1092: }
! 1093: /* Take care of our magic bookkeeping. */
! 1094: switch (sch) {
! 1095: case MAGIC:
! 1096: case BMAGIC:
! 1097: case CMAGIC:
! 1098: ch = sch;
! 1099: }
! 1100: }
! 1101: mvwaddch(cw, y, x, ch);
! 1102: }
! 1103: }
! 1104: }
! 1105: }
! 1106:
! 1107: /*
! 1108: * lit_room:
! 1109: * Called to see if the specified room is lit up or not.
! 1110: */
! 1111:
! 1112: bool
! 1113: lit_room(struct room *rp)
! 1114: {
! 1115: register struct linked_list *fire_item;
! 1116: register struct thing *fire_creature;
! 1117:
! 1118: if (!(rp->r_flags & ISDARK)) return(TRUE); /* A definitely lit room */
! 1119:
! 1120: /* Is it lit by fire light? */
! 1121: if (rp->r_flags & HASFIRE) {
! 1122: switch (levtype) {
! 1123: case MAZELEV:
! 1124: /* See if a fire creature is in line of sight */
! 1125: for (fire_item = rp->r_fires; fire_item != NULL;
! 1126: fire_item = next(fire_item)) {
! 1127: fire_creature = THINGPTR(fire_item);
! 1128: if (maze_view(fire_creature->t_pos.y,
! 1129: fire_creature->t_pos.x)) return(TRUE);
! 1130: }
! 1131:
! 1132: /* Couldn't find any in line-of-sight */
! 1133: return(FALSE);
! 1134:
! 1135: /* We should probably do something special for the outside */
! 1136: otherwise:
! 1137: return TRUE;
! 1138: }
! 1139: }
! 1140: return(FALSE);
! 1141: }
! 1142:
! 1143: /*
! 1144: * rndmove:
! 1145: * move in a random direction if the monster/person is confused
! 1146: */
! 1147:
! 1148: coord *
! 1149: rndmove(struct thing *who)
! 1150: {
! 1151: register int x, y;
! 1152: register int ex, ey, nopen = 0;
! 1153: static coord ret; /* what we will be returning */
! 1154: static coord dest;
! 1155:
! 1156: ret = who->t_pos;
! 1157: /*
! 1158: * Now go through the spaces surrounding the player and
! 1159: * set that place in the array to true if the space can be
! 1160: * moved into
! 1161: */
! 1162: ey = ret.y + 1;
! 1163: ex = ret.x + 1;
! 1164: for (y = who->t_pos.y - 1; y <= ey; y++)
! 1165: if (y > 0 && y < LINES - 2)
! 1166: for (x = who->t_pos.x - 1; x <= ex; x++)
! 1167: {
! 1168: if (x < 0 || x >= COLS)
! 1169: continue;
! 1170: if (step_ok(y, x, NOMONST, who) == TRUE)
! 1171: {
! 1172: dest.y = y;
! 1173: dest.x = x;
! 1174: if (!diag_ok(&who->t_pos, &dest, who))
! 1175: continue;
! 1176: if (rnd(++nopen) == 0)
! 1177: ret = dest;
! 1178: }
! 1179: }
! 1180: return &ret;
! 1181: }
! 1182:
! 1183:
! 1184:
! 1185: /*
! 1186: * set_trap:
! 1187: * set a trap at (y, x) on screen.
! 1188: */
! 1189:
! 1190: void
! 1191: set_trap(struct thing *tp, int y, int x)
! 1192: {
! 1193: register bool is_player = (tp == &player);
! 1194: register char selection = rnd(7) + '1';
! 1195: register char ch = 0, och;
! 1196: int thief_bonus = 0;
! 1197: int s_dext;
! 1198:
! 1199: switch (och = CCHAR( mvinch(y, x) )) {
! 1200: case WALL:
! 1201: case FLOOR:
! 1202: case PASSAGE:
! 1203: break;
! 1204: default:
! 1205: msg("The trap failed!");
! 1206: return;
! 1207: }
! 1208:
! 1209: if (is_player && player.t_ctype == C_THIEF) thief_bonus = 30;
! 1210:
! 1211: s_dext = (tp == &player) ? dex_compute() : tp->t_stats.s_dext;
! 1212:
! 1213: if (ntraps >= MAXTRAPS || ++trap_tries >= MAXTRPTRY || levtype == POSTLEV ||
! 1214: rnd(80) >= (s_dext + tp->t_stats.s_lvl/2 + thief_bonus)) {
! 1215: if (is_player) msg("The trap failed!");
! 1216: return;
! 1217: }
! 1218:
! 1219:
! 1220: if (is_player) {
! 1221: int state = 0; /* 0 -> current screen, 1 -> prompt screen, 2 -> done */
! 1222:
! 1223: msg("Which kind of trap do you wish to set? (* for a list): ");
! 1224: do {
! 1225: selection = tolower(readchar());
! 1226: switch (selection) {
! 1227: case '*':
! 1228: if (state != 1) {
! 1229: wclear(hw);
! 1230: touchwin(hw);
! 1231: mvwaddstr(hw, 2, 0, "[1] Trap Door\n[2] Bear Trap\n");
! 1232: waddstr(hw, "[3] Sleep Trap\n[4] Arrow Trap\n");
! 1233: waddstr(hw, "[5] Teleport Trap\n[6] Dart Trap\n");
! 1234: if (wizard) {
! 1235: waddstr(hw, "[7] Magic pool\n[8] Maze Trap\n");
! 1236: waddstr(hw, "[9] Trading Post\n");
! 1237: }
! 1238: mvwaddstr(hw, 0, 0, "Which kind of trap do you wish to set? ");
! 1239: draw(hw);
! 1240: state = 1; /* Now in prompt window */
! 1241: }
! 1242: break;
! 1243:
! 1244: case ESCAPE:
! 1245: if (state == 1) {
! 1246: clearok(cw, TRUE); /* Set up for redraw */
! 1247: touchwin(cw);
! 1248: }
! 1249: msg("");
! 1250:
! 1251: trap_tries--; /* Don't count this one */
! 1252: after = FALSE;
! 1253: return;
! 1254:
! 1255: case '1':
! 1256: case '2':
! 1257: case '3':
! 1258: case '4':
! 1259: case '5':
! 1260: case '6':
! 1261: case '7':
! 1262: case '8':
! 1263: case '9':
! 1264: if (selection < '7' || wizard) {
! 1265: if (state == 1) { /* In prompt window */
! 1266: clearok(cw, TRUE); /* Set up for redraw */
! 1267: touchwin(cw);
! 1268: }
! 1269:
! 1270: msg("");
! 1271:
! 1272: /* Make sure there is a floor below us for trap doors */
! 1273: if (selection == '1' && level >= nfloors) {
! 1274: if (state == 1) draw(cw);
! 1275: msg("There is no level below this one.");
! 1276: return;
! 1277: }
! 1278: state = 2; /* Finished */
! 1279: break;
! 1280: }
! 1281:
! 1282: /* Fall through for non-wizard, unusual trap case */
! 1283: default:
! 1284: if (state == 1) { /* In the prompt window */
! 1285: mvwaddstr(hw, 0, 0, "Please enter a selection between 1 and 6: ");
! 1286: draw(hw);
! 1287: }
! 1288: else { /* Normal window */
! 1289: mpos = 0;
! 1290: msg("Please enter a selection between 1 and 6: ");
! 1291: }
! 1292: }
! 1293: } while (state != 2);
! 1294: }
! 1295:
! 1296: switch (selection) {
! 1297: case '1': ch = TRAPDOOR;
! 1298: when '2': ch = BEARTRAP;
! 1299: when '3': ch = SLEEPTRAP;
! 1300: when '4': ch = ARROWTRAP;
! 1301: when '5': ch = TELTRAP;
! 1302: when '6': ch = DARTTRAP;
! 1303: when '7': ch = POOL;
! 1304: when '8': ch = MAZETRAP;
! 1305: when '9': ch = POST;
! 1306: }
! 1307:
! 1308: mvaddch(y, x, ch);
! 1309: traps[ntraps].tr_show = och;
! 1310: traps[ntraps].tr_type = ch;
! 1311: traps[ntraps].tr_pos.y = y;
! 1312: traps[ntraps].tr_pos.x = x;
! 1313: if (is_player)
! 1314: traps[ntraps].tr_flags = ISTHIEFSET;
! 1315: if (ch == POOL || ch == POST) {
! 1316: traps[ntraps].tr_flags |= ISFOUND;
! 1317: }
! 1318:
! 1319: ntraps++;
! 1320: }
! 1321:
! 1322: /*
! 1323: * show:
! 1324: * returns what a certain thing will display as to the un-initiated
! 1325: */
! 1326:
! 1327: char
! 1328: show(int y, int x)
! 1329: {
! 1330: register char ch = CCHAR( winat(y, x) );
! 1331: register struct linked_list *it;
! 1332: register struct thing *tp;
! 1333:
! 1334: if (isatrap(ch)) {
! 1335: register struct trap *trp = trap_at(y, x);
! 1336:
! 1337: return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show;
! 1338: }
! 1339: else if (isalpha(ch)) {
! 1340: if ((it = find_mons(y, x)) == NULL) {
! 1341: msg("Can't find monster in show");
! 1342: return(mvwinch(stdscr, y, x));
! 1343: }
! 1344: tp = THINGPTR(it);
! 1345:
! 1346: if (on(*tp, ISDISGUISE)) ch = tp->t_disguise; /* As a mimic */
! 1347:
! 1348: /* Hide invisible creatures */
! 1349: else if (invisible(tp)) {
! 1350: /* We can't see surprise-type creatures through "see invisible" */
! 1351: if (off(player,CANSEE) || on(*tp,CANSURPRISE))
! 1352: ch = CCHAR( mvwinch(stdscr, y, x) ); /* Invisible */
! 1353: }
! 1354: else if (on(*tp, CANINWALL)) {
! 1355: if (isrock(mvwinch(stdscr, y, x))) ch = CCHAR( winch(stdscr) ); /* As Xorn */
! 1356: }
! 1357: }
! 1358: return ch;
! 1359: }
! 1360:
! 1361:
! 1362: /*
! 1363: * trap_at:
! 1364: * find the trap at (y,x) on screen.
! 1365: */
! 1366:
! 1367: struct trap *
! 1368: trap_at(int y, int x)
! 1369: {
! 1370: register struct trap *tp, *ep;
! 1371:
! 1372: ep = &traps[ntraps];
! 1373: for (tp = traps; tp < ep; tp++)
! 1374: if (tp->tr_pos.y == y && tp->tr_pos.x == x)
! 1375: break;
! 1376: if (tp == ep)
! 1377: debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf));
! 1378: return tp;
! 1379: }
CVSweb