nexus/move.c

147 lines
2.8 KiB
C
Raw Normal View History

2010-12-02 12:17:54 +11:00
#include <stdio.h>
#include "attack.h"
#include "defs.h"
#include "map.h"
extern lifeform_t *player;
int canmove(lifeform_t *lf, int dir, enum ERROR *error) {
cell_t *cell;
cell = getcellindir(lf->cell, dir);
if (cell->type->solid) {
if (error) *error = E_WALLINWAY;
return B_FALSE;
}
if (cell->lf) {
if (error) *error = E_LFINWAY;
return B_FALSE;
}
return B_TRUE;
}
void dorandommove(lifeform_t *lf) {
int dir;
int tries = 0;
dir = getrandomdir(DT_COMPASS);
while (trymove(lf, dir)) {
if (++dir > DC_NW) dir = DC_N;
if (++tries >= MAXDIR_COMPASS) {
dowait(lf);
return;
}
}
}
int dowait(lifeform_t *lf) {
taketime(lf, SPEED_WAIT);
return B_FALSE;
}
void movelf(lifeform_t *lf, cell_t *newcell) {
// update current cell
lf->cell->lf = NULL;
// update lifeform
lf->cell = newcell;
// update new cell
newcell->lf = lf;
}
// basically this is a warpper for 'movelf' which
// does other game things like telling the player
// what is here.
int moveto(lifeform_t *lf, cell_t *newcell) {
// actually do the move
movelf(lf, newcell);
// tell player about things
if (lf->controller == C_PLAYER) {
int numobs;
char buf[BUFLEN];
numobs = countobs(newcell->obpile);
if (numobs == 1) {
getobname(newcell->obpile->first, buf, newcell->obpile->first->amt);
msg("You see %s here.", buf);
} else if ((numobs > 1) && (numobs <= 3)) {
msg("You see a few objects here.");
} else if ((numobs > 3) && (numobs <= 6)) {
msg("You see some objects here.");
} else if (numobs > 6) {
msg("You see many objects here.");
} else {
// just clear the message buffer
clearmsg();
}
}
}
int opendoor(lifeform_t *lf, cell_t *cell) {
char buf[BUFLEN];
if (cell->type->id == CT_DOORCLOSED) {
// open it
setcelltype(cell, CT_DOOROPEN);
if (lf->controller == C_PLAYER) {
msg("You open a door.");
} else {
// TODO: only announce if player can see it
if (haslos(player, cell)) {
getlfname(lf, buf);
capitalise(buf);
msg("%s opens a door.",buf);
}
}
taketime(lf, getmovespeed(lf));
} else {
return B_TRUE;
}
return B_FALSE;
}
int tryrun(lifeform_t *lf, int dir) {
// continue moving until we fail
while (canmove(lf, dir, NULL)) {
trymove(lf,dir);
}
}
int trymove(lifeform_t *lf, int dir) {
cell_t *cell;
enum ERROR errcode;
char buf[BUFLEN], buf2[BUFLEN];
cell = getcellindir(lf->cell, dir);
if (canmove(lf, dir, &errcode)) {
moveto(lf, cell);
taketime(lf, getmovespeed(lf));
} else {
switch (errcode) {
case E_WALLINWAY:
// is it a door in the way?
if (cell->type->id == CT_DOORCLOSED) {
// try to open it
opendoor(lf, cell);
} else {
if (lf->controller == C_PLAYER) {
msg("Ouch! You walk into a wall.");
}
}
break;
case E_LFINWAY:
// attack!
doattack(lf, cell->lf);
break;
}
return B_TRUE;
}
return B_FALSE;
}