Annotation of early-roguelike/rogue3/move.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Hero movement commands
! 3: *
! 4: * @(#)move.c 3.26 (Berkeley) 6/15/81
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 8: * All rights reserved.
! 9: *
! 10: * See the file LICENSE.TXT for full copyright and licensing information.
! 11: */
! 12:
! 13: #include "curses.h"
! 14: #include <ctype.h>
! 15: #include "rogue.h"
! 16:
! 17: /*
! 18: * Used to hold the new hero position
! 19: */
! 20:
! 21: coord nh;
! 22:
! 23: /*
! 24: * do_run:
! 25: * Start the hero running
! 26: */
! 27:
! 28: void
! 29: do_run(int ch)
! 30: {
! 31: running = TRUE;
! 32: after = FALSE;
! 33: runch = ch;
! 34: }
! 35:
! 36: /*
! 37: * do_move:
! 38: * Check to see that a move is legal. If it is handle the
! 39: * consequences (fighting, picking up, etc.)
! 40: */
! 41:
! 42: void
! 43: do_move(int dy, int dx)
! 44: {
! 45: int ch;
! 46:
! 47: firstmove = FALSE;
! 48: if (no_move)
! 49: {
! 50: no_move--;
! 51: msg("You are still stuck in the bear trap");
! 52: return;
! 53: }
! 54: /*
! 55: * Do a confused move (maybe)
! 56: */
! 57: if (rnd(100) < 80 && on(player, ISHUH))
! 58: nh = *rndmove(&player);
! 59: else
! 60: {
! 61: nh.y = hero.y + dy;
! 62: nh.x = hero.x + dx;
! 63: }
! 64:
! 65: /*
! 66: * Check if he tried to move off the screen or make an illegal
! 67: * diagonal move, and stop him if he did.
! 68: */
! 69: if (nh.x < 0 || nh.x > COLS-1 || nh.y < 0 || nh.y > LINES - 1
! 70: || !diag_ok(&hero, &nh))
! 71: {
! 72: after = FALSE;
! 73: running = FALSE;
! 74: return;
! 75: }
! 76: if (running && ce(hero, nh))
! 77: after = running = FALSE;
! 78: ch = winat(nh.y, nh.x);
! 79: if (on(player, ISHELD) && ch != 'F')
! 80: {
! 81: msg("You are being held");
! 82: return;
! 83: }
! 84: switch(ch)
! 85: {
! 86: case ' ':
! 87: case '|':
! 88: case '-':
! 89: case SECRETDOOR:
! 90: after = running = FALSE;
! 91: return;
! 92: case TRAP:
! 93: ch = be_trapped(&nh);
! 94: if (ch == TRAPDOOR || ch == TELTRAP)
! 95: return;
! 96: goto move_stuff;
! 97: case GOLD:
! 98: case POTION:
! 99: case SCROLL:
! 100: case FOOD:
! 101: case WEAPON:
! 102: case ARMOR:
! 103: case RING:
! 104: case AMULET:
! 105: case STICK:
! 106: running = FALSE;
! 107: take = ch;
! 108: default:
! 109: move_stuff:
! 110: if (ch == PASSAGE && winat(hero.y, hero.x) == DOOR)
! 111: light(&hero);
! 112: else if (ch == DOOR)
! 113: {
! 114: running = FALSE;
! 115: if (winat(hero.y, hero.x) == PASSAGE)
! 116: light(&nh);
! 117: }
! 118: else if (ch == STAIRS)
! 119: running = FALSE;
! 120: else if (isupper(ch))
! 121: {
! 122: running = FALSE;
! 123: fight(&nh, ch, cur_weapon, FALSE);
! 124: return;
! 125: }
! 126: ch = winat(hero.y, hero.x);
! 127: wmove(cw, unc(hero));
! 128: waddch(cw, ch);
! 129: hero = nh;
! 130: wmove(cw, unc(hero));
! 131: waddch(cw, PLAYER);
! 132: }
! 133: }
! 134:
! 135: /*
! 136: * Called to illuminate a room.
! 137: * If it is dark, remove anything that might move.
! 138: */
! 139:
! 140: void
! 141: light(coord *cp)
! 142: {
! 143: struct room *rp;
! 144: int j, k;
! 145: int ch;
! 146: int rch;
! 147: struct linked_list *item;
! 148:
! 149: if ((rp = roomin(cp)) != NULL && !on(player, ISBLIND))
! 150: {
! 151: for (j = 0; j < rp->r_max.y; j++)
! 152: {
! 153: for (k = 0; k < rp->r_max.x; k++)
! 154: {
! 155: ch = show(rp->r_pos.y + j, rp->r_pos.x + k);
! 156: wmove(cw, rp->r_pos.y + j, rp->r_pos.x + k);
! 157: /*
! 158: * Figure out how to display a secret door
! 159: */
! 160: if (ch == SECRETDOOR)
! 161: {
! 162: if (j == 0 || j == rp->r_max.y - 1)
! 163: ch = '-';
! 164: else
! 165: ch = '|';
! 166: }
! 167: /*
! 168: * If the room is a dark room, we might want to remove
! 169: * monsters and the like from it (since they might
! 170: * move)
! 171: */
! 172: if (isupper(ch))
! 173: {
! 174: item = wake_monster(rp->r_pos.y+j, rp->r_pos.x+k);
! 175: if (((struct thing *) ldata(item))->t_oldch == ' ')
! 176: if (!(rp->r_flags & ISDARK))
! 177: ((struct thing *) ldata(item))->t_oldch =
! 178: mvwinch(stdscr, rp->r_pos.y+j, rp->r_pos.x+k);
! 179: }
! 180: if (rp->r_flags & ISDARK)
! 181: {
! 182: rch = mvwinch(cw, rp->r_pos.y+j, rp->r_pos.x+k);
! 183: switch (rch)
! 184: {
! 185: case DOOR:
! 186: case STAIRS:
! 187: case TRAP:
! 188: case '|':
! 189: case '-':
! 190: case ' ':
! 191: ch = rch;
! 192: when FLOOR:
! 193: ch = (on(player, ISBLIND) ? FLOOR : ' ');
! 194: otherwise:
! 195: ch = ' ';
! 196: }
! 197: }
! 198: mvwaddch(cw, rp->r_pos.y+j, rp->r_pos.x+k, ch);
! 199: }
! 200: }
! 201: }
! 202: }
! 203:
! 204: /*
! 205: * show:
! 206: * returns what a certain thing will display as to the un-initiated
! 207: */
! 208:
! 209: int
! 210: show(int y, int x)
! 211: {
! 212: int ch = winat(y, x);
! 213: struct linked_list *it;
! 214: struct thing *tp;
! 215:
! 216: if (ch == TRAP)
! 217: return (trap_at(y, x)->tr_flags & ISFOUND) ? TRAP : FLOOR;
! 218: else if (ch == 'M' || ch == 'I')
! 219: {
! 220: if ((it = find_mons(y, x)) == NULL)
! 221: fatal("Can't find monster in show");
! 222: tp = (struct thing *) ldata(it);
! 223: if (ch == 'M')
! 224: ch = tp->t_disguise;
! 225: /*
! 226: * Hide invisible monsters
! 227: */
! 228: else if (off(player, CANSEE))
! 229: ch = mvwinch(stdscr, y, x);
! 230: }
! 231: return ch;
! 232: }
! 233:
! 234: /*
! 235: * be_trapped:
! 236: * The guy stepped on a trap.... Make him pay.
! 237: */
! 238:
! 239: int
! 240: be_trapped(coord *tc)
! 241: {
! 242: struct trap *tp;
! 243: int ch;
! 244:
! 245: tp = trap_at(tc->y, tc->x);
! 246: count = running = FALSE;
! 247: mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, TRAP);
! 248: tp->tr_flags |= ISFOUND;
! 249: switch (ch = tp->tr_type)
! 250: {
! 251: case TRAPDOOR:
! 252: level++;
! 253: new_level();
! 254: msg("You fell into a trap!");
! 255: when BEARTRAP:
! 256: no_move += BEARTIME;
! 257: msg("You are caught in a bear trap");
! 258: when SLEEPTRAP:
! 259: no_command += SLEEPTIME;
! 260: msg("A strange white mist envelops you and you fall asleep");
! 261: when ARROWTRAP:
! 262: if (swing(pstats.s_lvl-1, pstats.s_arm, 1))
! 263: {
! 264: msg("Oh no! An arrow shot you");
! 265: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
! 266: {
! 267: msg("The arrow killed you.");
! 268: death('a');
! 269: }
! 270: }
! 271: else
! 272: {
! 273: struct linked_list *item;
! 274: struct object *arrow;
! 275:
! 276: msg("An arrow shoots past you.");
! 277: item = new_item(sizeof *arrow);
! 278: arrow = (struct object *) ldata(item);
! 279: arrow->o_type = WEAPON;
! 280: arrow->o_which = ARROW;
! 281: init_weapon(arrow, ARROW);
! 282: arrow->o_count = 1;
! 283: arrow->o_pos = hero;
! 284: arrow->o_hplus = arrow->o_dplus = 0; /* "arrow bug" FIX */
! 285: fall(item, FALSE);
! 286: }
! 287: when TELTRAP:
! 288: teleport();
! 289: when DARTTRAP:
! 290: if (swing(pstats.s_lvl+1, pstats.s_arm, 1))
! 291: {
! 292: msg("A small dart just hit you in the shoulder");
! 293: if ((pstats.s_hpt -= roll(1, 4)) <= 0)
! 294: {
! 295: msg("The dart killed you.");
! 296: death('d');
! 297: }
! 298: if (!ISWEARING(R_SUSTSTR))
! 299: chg_str(-1);
! 300: }
! 301: else
! 302: msg("A small dart whizzes by your ear and vanishes.");
! 303: }
! 304: flush_type(); /* flush typeahead */
! 305: return(ch);
! 306: }
! 307:
! 308: /*
! 309: * trap_at:
! 310: * find the trap at (y,x) on screen.
! 311: */
! 312:
! 313: struct trap *
! 314: trap_at(int y, int x)
! 315: {
! 316: struct trap *tp, *ep;
! 317:
! 318: ep = &traps[ntraps];
! 319: for (tp = traps; tp < ep; tp++)
! 320: if (tp->tr_pos.y == y && tp->tr_pos.x == x)
! 321: break;
! 322: if (tp == ep)
! 323: {
! 324: sprintf(prbuf, "Trap at %d,%d not in array", y, x);
! 325: fatal(prbuf);
! 326: }
! 327: return tp;
! 328: }
! 329:
! 330: /*
! 331: * rndmove:
! 332: * move in a random direction if the monster/person is confused
! 333: */
! 334:
! 335: coord *
! 336: rndmove(struct thing *who)
! 337: {
! 338: int x, y;
! 339: int ch;
! 340: int ex, ey, nopen = 0;
! 341: struct linked_list *item;
! 342: struct object *obj = NULL;
! 343: static coord ret; /* what we will be returning */
! 344: static coord dest;
! 345:
! 346: ret = who->t_pos;
! 347: /*
! 348: * Now go through the spaces surrounding the player and
! 349: * set that place in the array to true if the space can be
! 350: * moved into
! 351: */
! 352: ey = ret.y + 1;
! 353: ex = ret.x + 1;
! 354: for (y = who->t_pos.y - 1; y <= ey; y++)
! 355: if (y >= 0 && y < LINES)
! 356: for (x = who->t_pos.x - 1; x <= ex; x++)
! 357: {
! 358: if (x < 0 || x >= COLS)
! 359: continue;
! 360: ch = winat(y, x);
! 361: if (step_ok(ch))
! 362: {
! 363: dest.y = y;
! 364: dest.x = x;
! 365: if (!diag_ok(&who->t_pos, &dest))
! 366: continue;
! 367: if (ch == SCROLL)
! 368: {
! 369: item = NULL;
! 370: for (item = lvl_obj; item != NULL; item = next(item))
! 371: {
! 372: obj = (struct object *) ldata(item);
! 373: if (y == obj->o_pos.y && x == obj->o_pos.x)
! 374: break;
! 375: }
! 376: if (item != NULL && obj->o_which == S_SCARE)
! 377: continue;
! 378: }
! 379: if (rnd(++nopen) == 0)
! 380: ret = dest;
! 381: }
! 382: }
! 383: return &ret;
! 384: }
CVSweb