Mercurial > hg > early-roguelike
diff rogue4/move.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Sat, 24 Oct 2009 16:52:52 +0000 |
parents | |
children | 1b73a8641b37 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rogue4/move.c Sat Oct 24 16:52:52 2009 +0000 @@ -0,0 +1,358 @@ +/* + * Hero movement commands + * + * @(#)move.c 4.24 (Berkeley) 5/12/82 + * + * Rogue: Exploring the Dungeons of Doom + * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman + * All rights reserved. + * + * See the file LICENSE.TXT for full copyright and licensing information. + */ + +#include <curses.h> +#include <ctype.h> +#include "rogue.h" + +/* + * Used to hold the new hero position + */ + +coord nh; + +/* + * do_run: + * Start the hero running + */ +do_run(ch) +char ch; +{ + running = TRUE; + after = FALSE; + runch = ch; +} + +/* + * do_move: + * Check to see that a move is legal. If it is handle the + * consequences (fighting, picking up, etc.) + */ +do_move(dy, dx) +int dy, dx; +{ + register char ch, fl; + + firstmove = FALSE; + if (no_move) + { + no_move--; + msg("you are still stuck in the bear trap"); + return; + } + /* + * Do a confused move (maybe) + */ + if (on(player, ISHUH) && rnd(5) != 0) + { + nh = *rndmove(&player); + if (ce(nh, hero)) + { + after = FALSE; + running = FALSE; + return; + } + } + else + { +over: + nh.y = hero.y + dy; + nh.x = hero.x + dx; + } + + /* + * Check if he tried to move off the screen or make an illegal + * diagonal move, and stop him if he did. + */ + if (nh.x < 0 || nh.x > COLS-1 || nh.y < 1 || nh.y > LINES - 2) + goto hit_bound; + if (!diag_ok(&hero, &nh)) + { + after = FALSE; + running = FALSE; + return; + } + if (running && ce(hero, nh)) + after = running = FALSE; + fl = flat(nh.y, nh.x); + ch = winat(nh.y, nh.x); + if (!(fl & F_REAL) && ch == FLOOR) + { + chat(nh.y, nh.x) = ch = TRAP; + flat(nh.y, nh.x) |= F_REAL; + } + else + if (on(player, ISHELD) && ch != 'F') + { + msg("you are being held"); + return; + } + switch (ch) + { + case ' ': + case '|': + case '-': +hit_bound: + if (passgo && running && (proom->r_flags & ISGONE) + && !on(player, ISBLIND)) + { + register bool b1, b2; + + switch (runch) + { + case 'h': + case 'l': + b1 = (((flat(hero.y - 1, hero.x) & F_PASS) || chat(hero.y - 1, hero.x) == DOOR) && hero.y != 1); + b2 = (((flat(hero.y + 1, hero.x) & F_PASS) || chat(hero.y + 1, hero.x) == DOOR) && hero.y != LINES - 2); + if (!(b1 ^ b2)) + break; + if (b1) + { + runch = 'k'; + dy = -1; + } + else + { + runch = 'j'; + dy = 1; + } + dx = 0; + turnref(); + goto over; + case 'j': + case 'k': + b1 = (((flat(hero.y, hero.x - 1) & F_PASS) || chat(hero.y, hero.x - 1) == DOOR) && hero.x != 0); + b2 = (((flat(hero.y, hero.x + 1) & F_PASS) || chat(hero.y, hero.x + 1) == DOOR) && hero.x != COLS - 1); + if (!(b1 ^ b2)) + break; + if (b1) + { + runch = 'h'; + dx = -1; + } + else + { + runch = 'l'; + dx = 1; + } + dy = 0; + turnref(); + goto over; + } + } + after = running = FALSE; + break; + case DOOR: + running = FALSE; + if (flat(hero.y, hero.x) & F_PASS) + enter_room(&nh); + goto move_stuff; + case TRAP: + ch = be_trapped(&nh); + if (ch == T_DOOR || ch == T_TELEP) + return; + goto move_stuff; + case PASSAGE: + goto move_stuff; + case FLOOR: + if (!(fl & F_REAL)) + be_trapped(&hero); + goto move_stuff; + default: + running = FALSE; + if (isupper(ch) || moat(nh.y, nh.x)) + fight(&nh, ch, cur_weapon, FALSE); + else + { + running = FALSE; + if (ch != STAIRS) + take = ch; +move_stuff: + mvaddch(hero.y, hero.x, chat(hero.y, hero.x)); + if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR) + leave_room(&nh); + hero = nh; + } + } +} + +/* + * turnref: + * Decide whether to refresh at a passage turning or not + */ +turnref() +{ + register int index; + + index = INDEX(hero.y, hero.x); + if (!(_flags[index] & F_SEEN)) + { + if (jump) + { + leaveok(stdscr, TRUE); + refresh(); + leaveok(stdscr, FALSE); + } + _flags[index] |= F_SEEN; + } +} + +/* + * door_open: + * Called to illuminate a room. If it is dark, remove anything + * that might move. + */ +door_open(rp) +struct room *rp; +{ + register int j, k; + register char ch; + register THING *item; + + if (!(rp->r_flags & ISGONE) && !on(player, ISBLIND)) + for (j = rp->r_pos.y; j < rp->r_pos.y + rp->r_max.y; j++) + for (k = rp->r_pos.x; k < rp->r_pos.x + rp->r_max.x; k++) + { + ch = winat(j, k); + move(j, k); + if (isupper(ch)) + { + item = wake_monster(j, k); + if (item->t_oldch == ' ' && !(rp->r_flags & ISDARK) + && !on(player, ISBLIND)) + item->t_oldch = chat(j, k); + } + } +} + +/* + * be_trapped: + * The guy stepped on a trap.... Make him pay. + */ +be_trapped(tc) +register coord *tc; +{ + register char tr; + register int index; + + count = running = FALSE; + index = INDEX(tc->y, tc->x); + _level[index] = TRAP; + tr = _flags[index] & F_TMASK; + switch (tr) + { + case T_DOOR: + level++; + new_level(); + msg("you fell into a trap!"); + when T_BEAR: + no_move += BEARTIME; + msg("you are caught in a bear trap"); + when T_SLEEP: + no_command += SLEEPTIME; + player.t_flags &= ~ISRUN; + msg("a strange white mist envelops you and you fall asleep"); + when T_ARROW: + if (swing(pstats.s_lvl-1, pstats.s_arm, 1)) + { + pstats.s_hpt -= roll(1, 6); + if (pstats.s_hpt <= 0) + { + msg("an arrow killed you"); + death('a'); + } + else + msg("oh no! An arrow shot you"); + } + else + { + register THING *arrow; + + arrow = new_item(); + arrow->o_type = WEAPON; + arrow->o_which = ARROW; + init_weapon(arrow, ARROW); + arrow->o_count = 1; + arrow->o_pos = hero; + arrow->o_hplus = arrow->o_dplus = 0; + fall(arrow, FALSE); + msg("an arrow shoots past you"); + } + when T_TELEP: + teleport(); + mvaddch(tc->y, tc->x, TRAP); /* since the hero's leaving, look() + won't put it on for us */ + when T_DART: + if (swing(pstats.s_lvl+1, pstats.s_arm, 1)) + { + pstats.s_hpt -= roll(1, 4); + if (pstats.s_hpt <= 0) + { + msg("a poisoned dart killed you"); + death('d'); + } + if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON)) + chg_str(-1); + msg("a small dart just hit you in the shoulder"); + } + else + msg("a small dart whizzes by your ear and vanishes"); + } + flush_type(); + return tr; +} + +/* + * rndmove: + * Move in a random direction if the monster/person is confused + */ +coord * +rndmove(who) +THING *who; +{ + register int x, y; + register char ch; + register THING *obj; + static coord ret; /* what we will be returning */ + + y = ret.y = who->t_pos.y + rnd(3) - 1; + x = ret.x = who->t_pos.x + rnd(3) - 1; + /* + * Now check to see if that's a legal move. If not, don't move. + * (I.e., bump into the wall or whatever) + */ + if (y == who->t_pos.y && x == who->t_pos.x) + return &ret; + if ((y < 0 || y >= LINES - 1) || (x < 0 || x >= COLS)) + goto bad; + else if (!diag_ok(&who->t_pos, &ret)) + goto bad; + else + { + ch = winat(y, x); + if (!step_ok(ch)) + goto bad; + if (ch == SCROLL) + { + for (obj = lvl_obj; obj != NULL; obj = next(obj)) + if (y == obj->o_pos.y && x == obj->o_pos.x) + break; + if (obj != NULL && obj->o_which == S_SCARE) + goto bad; + } + } + return &ret; + +bad: + ret = who->t_pos; + return &ret; +}