Annotation of early-roguelike/rogue5/move.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * hero movement commands
! 3: *
! 4: * @(#)move.c 4.49 (Berkeley) 02/05/99
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980-1983, 1985, 1999 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:
! 22: /*
! 23: * do_run:
! 24: * Start the hero running
! 25: */
! 26:
! 27: void
! 28: do_run(int ch)
! 29: {
! 30: running = TRUE;
! 31: after = FALSE;
! 32: runch = ch;
! 33: }
! 34:
! 35: /*
! 36: * do_move:
! 37: * Check to see that a move is legal. If it is handle the
! 38: * consequences (fighting, picking up, etc.)
! 39: */
! 40:
! 41: void
! 42: do_move(int dy, int dx)
! 43: {
! 44: int ch, fl;
! 45: coord nh;
! 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 (on(player, ISHUH) && rnd(5) != 0)
! 58: {
! 59: nh = rndmove(&player);
! 60: if (ce(nh, hero))
! 61: {
! 62: after = FALSE;
! 63: running = FALSE;
! 64: to_death = FALSE;
! 65: return;
! 66: }
! 67: }
! 68: else
! 69: {
! 70: over:
! 71: nh.y = hero.y + dy;
! 72: nh.x = hero.x + dx;
! 73: }
! 74:
! 75: /*
! 76: * Check if he tried to move off the screen or make an illegal
! 77: * diagonal move, and stop him if he did.
! 78: */
! 79: if (nh.x < 0 || nh.x >= NUMCOLS || nh.y <= 0 || nh.y >= NUMLINES - 1)
! 80: goto hit_bound;
! 81: if (!diag_ok(&hero, &nh))
! 82: {
! 83: after = FALSE;
! 84: running = FALSE;
! 85: return;
! 86: }
! 87: if (running && ce(hero, nh))
! 88: after = running = FALSE;
! 89: fl = flat(nh.y, nh.x);
! 90: ch = winat(nh.y, nh.x);
! 91: if (!(fl & F_REAL) && ch == FLOOR)
! 92: {
! 93: if (!on(player, ISLEVIT))
! 94: {
! 95: chat(nh.y, nh.x) = ch = TRAP;
! 96: flat(nh.y, nh.x) |= F_REAL;
! 97: }
! 98: }
! 99: else if (on(player, ISHELD) && ch != 'F')
! 100: {
! 101: msg("you are being held");
! 102: return;
! 103: }
! 104: switch (ch)
! 105: {
! 106: case ' ':
! 107: case '|':
! 108: case '-':
! 109: hit_bound:
! 110: if (passgo && running && (proom->r_flags & ISGONE)
! 111: && !on(player, ISBLIND))
! 112: {
! 113: int b1, b2;
! 114:
! 115: switch (runch)
! 116: {
! 117: case 'h':
! 118: case 'l':
! 119: b1 = (hero.y != 1 && turn_ok(hero.y - 1, hero.x));
! 120: b2 = (hero.y != NUMLINES - 2 && turn_ok(hero.y + 1, hero.x));
! 121: if (!(b1 ^ b2))
! 122: break;
! 123: if (b1)
! 124: {
! 125: runch = 'k';
! 126: dy = -1;
! 127: }
! 128: else
! 129: {
! 130: runch = 'j';
! 131: dy = 1;
! 132: }
! 133: dx = 0;
! 134: turnref();
! 135: goto over;
! 136: case 'j':
! 137: case 'k':
! 138: b1 = (hero.x != 0 && turn_ok(hero.y, hero.x - 1));
! 139: b2 = (hero.x != NUMCOLS - 1 && turn_ok(hero.y, hero.x + 1));
! 140: if (!(b1 ^ b2))
! 141: break;
! 142: if (b1)
! 143: {
! 144: runch = 'h';
! 145: dx = -1;
! 146: }
! 147: else
! 148: {
! 149: runch = 'l';
! 150: dx = 1;
! 151: }
! 152: dy = 0;
! 153: turnref();
! 154: goto over;
! 155: }
! 156: }
! 157: running = FALSE;
! 158: after = FALSE;
! 159: break;
! 160: case DOOR:
! 161: running = FALSE;
! 162: if (flat(hero.y, hero.x) & F_PASS)
! 163: enter_room(&nh);
! 164: goto move_stuff;
! 165: case TRAP:
! 166: ch = be_trapped(&nh);
! 167: if (ch == T_DOOR || ch == T_TELEP)
! 168: return;
! 169: goto move_stuff;
! 170: case PASSAGE:
! 171: /*
! 172: * when you're in a corridor, you don't know if you're in
! 173: * a maze room or not, and there ain't no way to find out
! 174: * if you're leaving a maze room, so it is necessary to
! 175: * always recalculate proom.
! 176: */
! 177: proom = roomin(&hero);
! 178: goto move_stuff;
! 179: case FLOOR:
! 180: if (!(fl & F_REAL))
! 181: be_trapped(&hero);
! 182: goto move_stuff;
! 183: case STAIRS:
! 184: seenstairs = TRUE;
! 185: /* FALLTHROUGH */
! 186: default:
! 187: running = FALSE;
! 188: if (isupper(ch) || moat(nh.y, nh.x))
! 189: fight(&nh, cur_weapon, FALSE);
! 190: else
! 191: {
! 192: if (ch != STAIRS)
! 193: take = ch;
! 194: move_stuff:
! 195: mvaddch(hero.y, hero.x, floor_at());
! 196: if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR)
! 197: leave_room(&nh);
! 198: hero = nh;
! 199: }
! 200: }
! 201: }
! 202:
! 203: /*
! 204: * turn_ok:
! 205: * Decide whether it is legal to turn onto the given space
! 206: */
! 207: int
! 208: turn_ok(int y, int x)
! 209: {
! 210: PLACE *pp;
! 211:
! 212: pp = INDEX(y, x);
! 213: return (pp->p_ch == DOOR
! 214: || (pp->p_flags & (F_REAL|F_PASS)) == (F_REAL|F_PASS));
! 215: }
! 216:
! 217: /*
! 218: * turnref:
! 219: * Decide whether to refresh at a passage turning or not
! 220: */
! 221:
! 222: void
! 223: turnref(void)
! 224: {
! 225: PLACE *pp;
! 226:
! 227: pp = INDEX(hero.y, hero.x);
! 228: if (!(pp->p_flags & F_SEEN))
! 229: {
! 230: if (jump)
! 231: {
! 232: leaveok(stdscr, TRUE);
! 233: refresh();
! 234: leaveok(stdscr, FALSE);
! 235: }
! 236: pp->p_flags |= F_SEEN;
! 237: }
! 238: }
! 239:
! 240: /*
! 241: * door_open:
! 242: * Called to illuminate a room. If it is dark, remove anything
! 243: * that might move.
! 244: */
! 245:
! 246: void
! 247: door_open(const struct room *rp)
! 248: {
! 249: int y, x;
! 250:
! 251: if (!(rp->r_flags & ISGONE))
! 252: for (y = rp->r_pos.y; y < rp->r_pos.y + rp->r_max.y; y++)
! 253: for (x = rp->r_pos.x; x < rp->r_pos.x + rp->r_max.x; x++)
! 254: if (isupper(winat(y, x)))
! 255: wake_monster(y, x);
! 256: }
! 257:
! 258: /*
! 259: * be_trapped:
! 260: * The guy stepped on a trap.... Make him pay.
! 261: */
! 262: int
! 263: be_trapped(const coord *tc)
! 264: {
! 265: PLACE *pp;
! 266: THING *arrow;
! 267: int tr;
! 268:
! 269: if (on(player, ISLEVIT))
! 270: return T_RUST; /* anything that's not a door or teleport */
! 271: running = FALSE;
! 272: count = FALSE;
! 273: pp = INDEX(tc->y, tc->x);
! 274: pp->p_ch = TRAP;
! 275: tr = pp->p_flags & F_TMASK;
! 276: pp->p_flags |= F_SEEN;
! 277: switch (tr)
! 278: {
! 279: case T_DOOR:
! 280: level++;
! 281: new_level();
! 282: msg("you fell into a trap!");
! 283: when T_BEAR:
! 284: no_move += BEARTIME;
! 285: msg("you are caught in a bear trap");
! 286: when T_MYST:
! 287: switch(rnd(11))
! 288: {
! 289: case 0: msg("you are suddenly in a parallel dimension");
! 290: when 1: msg("the light in here suddenly seems %s", rainbow[rnd(cNCOLORS)]);
! 291: when 2: msg("you feel a sting in the side of your neck");
! 292: when 3: msg("multi-colored lines swirl around you, then fade");
! 293: when 4: msg("a %s light flashes in your eyes", rainbow[rnd(cNCOLORS)]);
! 294: when 5: msg("a spike shoots past your ear!");
! 295: when 6: msg("%s sparks dance across your armor", rainbow[rnd(cNCOLORS)]);
! 296: when 7: msg("you suddenly feel very thirsty");
! 297: when 8: msg("you feel time speed up suddenly");
! 298: when 9: msg("time now seems to be going slower");
! 299: when 10: msg("you pack turns %s!", rainbow[rnd(cNCOLORS)]);
! 300: }
! 301: when T_SLEEP:
! 302: no_command += SLEEPTIME;
! 303: player.t_flags &= ~ISRUN;
! 304: msg("a strange white mist envelops you and you fall asleep");
! 305: when T_ARROW:
! 306: if (swing(pstats.s_lvl - 1, pstats.s_arm, 1))
! 307: {
! 308: pstats.s_hpt -= roll(1, 6);
! 309: if (pstats.s_hpt <= 0)
! 310: {
! 311: msg("an arrow killed you");
! 312: death('a');
! 313: }
! 314: else
! 315: msg("oh no! An arrow shot you");
! 316: }
! 317: else
! 318: {
! 319: arrow = new_item();
! 320: init_weapon(arrow, ARROW);
! 321: arrow->o_count = 1;
! 322: arrow->o_pos = hero;
! 323: fall(arrow, FALSE);
! 324: msg("an arrow shoots past you");
! 325: }
! 326: when T_TELEP:
! 327: /*
! 328: * since the hero's leaving, look() won't put a TRAP
! 329: * down for us, so we have to do it ourself
! 330: */
! 331: teleport();
! 332: mvaddch(tc->y, tc->x, TRAP);
! 333: when T_DART:
! 334: if (!swing(pstats.s_lvl+1, pstats.s_arm, 1))
! 335: msg("a small dart whizzes by your ear and vanishes");
! 336: else
! 337: {
! 338: pstats.s_hpt -= roll(1, 4);
! 339: if (pstats.s_hpt <= 0)
! 340: {
! 341: msg("a poisoned dart killed you");
! 342: death('d');
! 343: }
! 344: if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON))
! 345: chg_str(-1);
! 346: msg("a small dart just hit you in the shoulder");
! 347: }
! 348: when T_RUST:
! 349: msg("a gush of water hits you on the head");
! 350: rust_armor(cur_armor);
! 351: }
! 352: flush_type();
! 353: return tr;
! 354: }
! 355:
! 356: /*
! 357: * rndmove:
! 358: * Move in a random direction if the monster/person is confused
! 359: */
! 360: coord
! 361: rndmove(const THING *who)
! 362: {
! 363: THING *obj;
! 364: int x, y;
! 365: int ch;
! 366: coord ret; /* what we will be returning */
! 367:
! 368: y = ret.y = who->t_pos.y + rnd(3) - 1;
! 369: x = ret.x = who->t_pos.x + rnd(3) - 1;
! 370: /*
! 371: * Now check to see if that's a legal move. If not, don't move.
! 372: * (I.e., bump into the wall or whatever)
! 373: */
! 374: if (y == who->t_pos.y && x == who->t_pos.x)
! 375: return ret;
! 376: if (!diag_ok(&who->t_pos, &ret))
! 377: goto bad;
! 378: else
! 379: {
! 380: ch = winat(y, x);
! 381: if (!step_ok(ch))
! 382: goto bad;
! 383: if (ch == SCROLL)
! 384: {
! 385: for (obj = lvl_obj; obj != NULL; obj = next(obj))
! 386: if (y == obj->o_pos.y && x == obj->o_pos.x)
! 387: break;
! 388: if (obj != NULL && obj->o_which == S_SCARE)
! 389: goto bad;
! 390: }
! 391: }
! 392: return ret;
! 393:
! 394: bad:
! 395: ret = who->t_pos;
! 396: return ret;
! 397: }
! 398:
! 399: /*
! 400: * rust_armor:
! 401: * Rust the given armor, if it is a legal kind to rust, and we
! 402: * aren't wearing a magic ring.
! 403: */
! 404:
! 405: void
! 406: rust_armor(THING *arm)
! 407: {
! 408: if (arm == NULL || arm->o_type != ARMOR || arm->o_which == LEATHER ||
! 409: arm->o_arm >= 9)
! 410: return;
! 411:
! 412: if ((arm->o_flags & ISPROT) || ISWEARING(R_SUSTARM))
! 413: {
! 414: if (!to_death)
! 415: msg("the rust vanishes instantly");
! 416: }
! 417: else
! 418: {
! 419: arm->o_arm++;
! 420: if (!terse)
! 421: msg("your armor appears to be weaker now. Oh my!");
! 422: else
! 423: msg("your armor weakens");
! 424: }
! 425: }
CVSweb