147 lines
2.8 KiB
C
147 lines
2.8 KiB
C
|
#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;
|
||
|
}
|
||
|
|
||
|
|