Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
This commit is contained in:
commit
4662bbf65b
44 changed files with 15930 additions and 0 deletions
384
rogue3/move.c
Normal file
384
rogue3/move.c
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* Hero movement commands
|
||||
*
|
||||
* @(#)move.c 3.26 (Berkeley) 6/15/81
|
||||
*
|
||||
* Rogue: Exploring the Dungeons of Doom
|
||||
* Copyright (C) 1980, 1981 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
|
||||
*/
|
||||
|
||||
void
|
||||
do_run(int 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.)
|
||||
*/
|
||||
|
||||
void
|
||||
do_move(int dy, int dx)
|
||||
{
|
||||
int ch;
|
||||
|
||||
firstmove = FALSE;
|
||||
if (no_move)
|
||||
{
|
||||
no_move--;
|
||||
msg("You are still stuck in the bear trap");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Do a confused move (maybe)
|
||||
*/
|
||||
if (rnd(100) < 80 && on(player, ISHUH))
|
||||
nh = *rndmove(&player);
|
||||
else
|
||||
{
|
||||
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 < 0 || nh.y > LINES - 1
|
||||
|| !diag_ok(&hero, &nh))
|
||||
{
|
||||
after = FALSE;
|
||||
running = FALSE;
|
||||
return;
|
||||
}
|
||||
if (running && ce(hero, nh))
|
||||
after = running = FALSE;
|
||||
ch = winat(nh.y, nh.x);
|
||||
if (on(player, ISHELD) && ch != 'F')
|
||||
{
|
||||
msg("You are being held");
|
||||
return;
|
||||
}
|
||||
switch(ch)
|
||||
{
|
||||
case ' ':
|
||||
case '|':
|
||||
case '-':
|
||||
case SECRETDOOR:
|
||||
after = running = FALSE;
|
||||
return;
|
||||
case TRAP:
|
||||
ch = be_trapped(&nh);
|
||||
if (ch == TRAPDOOR || ch == TELTRAP)
|
||||
return;
|
||||
goto move_stuff;
|
||||
case GOLD:
|
||||
case POTION:
|
||||
case SCROLL:
|
||||
case FOOD:
|
||||
case WEAPON:
|
||||
case ARMOR:
|
||||
case RING:
|
||||
case AMULET:
|
||||
case STICK:
|
||||
running = FALSE;
|
||||
take = ch;
|
||||
default:
|
||||
move_stuff:
|
||||
if (ch == PASSAGE && winat(hero.y, hero.x) == DOOR)
|
||||
light(&hero);
|
||||
else if (ch == DOOR)
|
||||
{
|
||||
running = FALSE;
|
||||
if (winat(hero.y, hero.x) == PASSAGE)
|
||||
light(&nh);
|
||||
}
|
||||
else if (ch == STAIRS)
|
||||
running = FALSE;
|
||||
else if (isupper(ch))
|
||||
{
|
||||
running = FALSE;
|
||||
fight(&nh, ch, cur_weapon, FALSE);
|
||||
return;
|
||||
}
|
||||
ch = winat(hero.y, hero.x);
|
||||
wmove(cw, unc(hero));
|
||||
waddch(cw, ch);
|
||||
hero = nh;
|
||||
wmove(cw, unc(hero));
|
||||
waddch(cw, PLAYER);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to illuminate a room.
|
||||
* If it is dark, remove anything that might move.
|
||||
*/
|
||||
|
||||
void
|
||||
light(coord *cp)
|
||||
{
|
||||
struct room *rp;
|
||||
int j, k;
|
||||
int ch;
|
||||
int rch;
|
||||
struct linked_list *item;
|
||||
|
||||
if ((rp = roomin(cp)) != NULL && !on(player, ISBLIND))
|
||||
{
|
||||
for (j = 0; j < rp->r_max.y; j++)
|
||||
{
|
||||
for (k = 0; k < rp->r_max.x; k++)
|
||||
{
|
||||
ch = show(rp->r_pos.y + j, rp->r_pos.x + k);
|
||||
wmove(cw, rp->r_pos.y + j, rp->r_pos.x + k);
|
||||
/*
|
||||
* Figure out how to display a secret door
|
||||
*/
|
||||
if (ch == SECRETDOOR)
|
||||
{
|
||||
if (j == 0 || j == rp->r_max.y - 1)
|
||||
ch = '-';
|
||||
else
|
||||
ch = '|';
|
||||
}
|
||||
/*
|
||||
* If the room is a dark room, we might want to remove
|
||||
* monsters and the like from it (since they might
|
||||
* move)
|
||||
*/
|
||||
if (isupper(ch))
|
||||
{
|
||||
item = wake_monster(rp->r_pos.y+j, rp->r_pos.x+k);
|
||||
if (((struct thing *) ldata(item))->t_oldch == ' ')
|
||||
if (!(rp->r_flags & ISDARK))
|
||||
((struct thing *) ldata(item))->t_oldch =
|
||||
mvwinch(stdscr, rp->r_pos.y+j, rp->r_pos.x+k);
|
||||
}
|
||||
if (rp->r_flags & ISDARK)
|
||||
{
|
||||
rch = mvwinch(cw, rp->r_pos.y+j, rp->r_pos.x+k);
|
||||
switch (rch)
|
||||
{
|
||||
case DOOR:
|
||||
case STAIRS:
|
||||
case TRAP:
|
||||
case '|':
|
||||
case '-':
|
||||
case ' ':
|
||||
ch = rch;
|
||||
when FLOOR:
|
||||
ch = (on(player, ISBLIND) ? FLOOR : ' ');
|
||||
otherwise:
|
||||
ch = ' ';
|
||||
}
|
||||
}
|
||||
mvwaddch(cw, rp->r_pos.y+j, rp->r_pos.x+k, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* show:
|
||||
* returns what a certain thing will display as to the un-initiated
|
||||
*/
|
||||
|
||||
int
|
||||
show(int y, int x)
|
||||
{
|
||||
int ch = winat(y, x);
|
||||
struct linked_list *it;
|
||||
struct thing *tp;
|
||||
|
||||
if (ch == TRAP)
|
||||
return (trap_at(y, x)->tr_flags & ISFOUND) ? TRAP : FLOOR;
|
||||
else if (ch == 'M' || ch == 'I')
|
||||
{
|
||||
if ((it = find_mons(y, x)) == NULL)
|
||||
fatal("Can't find monster in show");
|
||||
tp = (struct thing *) ldata(it);
|
||||
if (ch == 'M')
|
||||
ch = tp->t_disguise;
|
||||
/*
|
||||
* Hide invisible monsters
|
||||
*/
|
||||
else if (off(player, CANSEE))
|
||||
ch = mvwinch(stdscr, y, x);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* be_trapped:
|
||||
* The guy stepped on a trap.... Make him pay.
|
||||
*/
|
||||
|
||||
int
|
||||
be_trapped(coord *tc)
|
||||
{
|
||||
struct trap *tp;
|
||||
int ch;
|
||||
|
||||
tp = trap_at(tc->y, tc->x);
|
||||
count = running = FALSE;
|
||||
mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, TRAP);
|
||||
tp->tr_flags |= ISFOUND;
|
||||
switch (ch = tp->tr_type)
|
||||
{
|
||||
case TRAPDOOR:
|
||||
level++;
|
||||
new_level();
|
||||
msg("You fell into a trap!");
|
||||
when BEARTRAP:
|
||||
no_move += BEARTIME;
|
||||
msg("You are caught in a bear trap");
|
||||
when SLEEPTRAP:
|
||||
no_command += SLEEPTIME;
|
||||
msg("A strange white mist envelops you and you fall asleep");
|
||||
when ARROWTRAP:
|
||||
if (swing(pstats.s_lvl-1, pstats.s_arm, 1))
|
||||
{
|
||||
msg("Oh no! An arrow shot you");
|
||||
if ((pstats.s_hpt -= roll(1, 6)) <= 0)
|
||||
{
|
||||
msg("The arrow killed you.");
|
||||
death('a');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct linked_list *item;
|
||||
struct object *arrow;
|
||||
|
||||
msg("An arrow shoots past you.");
|
||||
item = new_item(sizeof *arrow);
|
||||
arrow = (struct object *) ldata(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; /* "arrow bug" FIX */
|
||||
fall(item, FALSE);
|
||||
}
|
||||
when TELTRAP:
|
||||
teleport();
|
||||
when DARTTRAP:
|
||||
if (swing(pstats.s_lvl+1, pstats.s_arm, 1))
|
||||
{
|
||||
msg("A small dart just hit you in the shoulder");
|
||||
if ((pstats.s_hpt -= roll(1, 4)) <= 0)
|
||||
{
|
||||
msg("The dart killed you.");
|
||||
death('d');
|
||||
}
|
||||
if (!ISWEARING(R_SUSTSTR))
|
||||
chg_str(-1);
|
||||
}
|
||||
else
|
||||
msg("A small dart whizzes by your ear and vanishes.");
|
||||
}
|
||||
flush_type(); /* flush typeahead */
|
||||
return(ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* trap_at:
|
||||
* find the trap at (y,x) on screen.
|
||||
*/
|
||||
|
||||
struct trap *
|
||||
trap_at(int y, int x)
|
||||
{
|
||||
struct trap *tp, *ep;
|
||||
|
||||
ep = &traps[ntraps];
|
||||
for (tp = traps; tp < ep; tp++)
|
||||
if (tp->tr_pos.y == y && tp->tr_pos.x == x)
|
||||
break;
|
||||
if (tp == ep)
|
||||
{
|
||||
sprintf(prbuf, "Trap at %d,%d not in array", y, x);
|
||||
fatal(prbuf);
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* rndmove:
|
||||
* move in a random direction if the monster/person is confused
|
||||
*/
|
||||
|
||||
coord *
|
||||
rndmove(struct thing *who)
|
||||
{
|
||||
int x, y;
|
||||
int ch;
|
||||
int ex, ey, nopen = 0;
|
||||
struct linked_list *item;
|
||||
struct object *obj;
|
||||
static coord ret; /* what we will be returning */
|
||||
static coord dest;
|
||||
|
||||
ret = who->t_pos;
|
||||
/*
|
||||
* Now go through the spaces surrounding the player and
|
||||
* set that place in the array to true if the space can be
|
||||
* moved into
|
||||
*/
|
||||
ey = ret.y + 1;
|
||||
ex = ret.x + 1;
|
||||
for (y = who->t_pos.y - 1; y <= ey; y++)
|
||||
if (y >= 0 && y < LINES)
|
||||
for (x = who->t_pos.x - 1; x <= ex; x++)
|
||||
{
|
||||
if (x < 0 || x >= COLS)
|
||||
continue;
|
||||
ch = winat(y, x);
|
||||
if (step_ok(ch))
|
||||
{
|
||||
dest.y = y;
|
||||
dest.x = x;
|
||||
if (!diag_ok(&who->t_pos, &dest))
|
||||
continue;
|
||||
if (ch == SCROLL)
|
||||
{
|
||||
item = NULL;
|
||||
for (item = lvl_obj; item != NULL; item = next(item))
|
||||
{
|
||||
obj = (struct object *) ldata(item);
|
||||
if (y == obj->o_pos.y && x == obj->o_pos.x)
|
||||
break;
|
||||
}
|
||||
if (item != NULL && obj->o_which == S_SCARE)
|
||||
continue;
|
||||
}
|
||||
if (rnd(++nopen) == 0)
|
||||
ret = dest;
|
||||
}
|
||||
}
|
||||
return &ret;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue