nexus/ai.c

125 lines
2.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include "ai.h"
#include "defs.h"
#include "flag.h"
#include "lf.h"
#include "map.h"
#include "objects.h"
extern lifeform_t *player;
void aimove(lifeform_t *lf) {
int dir;
int db = B_TRUE;
flag_t *f;
lifeform_t *target;
char buf[BUFLEN];
if (db) dblog("AIMOVE: %s", lf->race->name);
// if lifeform isn't alive, skip turn
if (isdead(lf)) {
taketime(lf, SPEED_DEAD);
return;
}
f = hasflag(lf->flags, F_TARGET);
if (f) {
int targid;
targid = f->val[0];
target = findlf(lf->cell->map, targid);
if (target) {
if (haslos(lf, target->cell)) {
movetowards(lf, target->cell);
return;
} else {
// TODO: move towards last known location
// just try to move in a random direction
dorandommove(lf);
return;
}
}
} else {
// not attacking anyone in particular
// TODO: are we hostile? if so, look for a target
f = hasflag(lf->flags, F_HOSTILE);
if (f) {
int x,y;
cell_t *c;
// look around for a target
// TODO: use our vis rang einstead of 10!
for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) {
for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) {
c = getcellat(lf->cell->map, x, y);
// cell exists and we can see it?
if (c && haslos(lf, c)) {
// player there?
if (c->lf && c->lf->controller == C_PLAYER) {
// target them!
addflag(lf->flags, F_TARGET, c->lf->id, -1, -1, "");
// tell the player
if (haslos(player, lf->cell)) {
getlfname(lf, buf);
capitalise(buf);
msg("%s sees you!", buf);
}
// then move towards them...
movetowards(lf, c);
return;
}
}
}
}
}
// just try to move in a random direction
dorandommove(lf);
return;
}
// if we get this far, just wait
dowait(lf);
}
int getdirtowards(lifeform_t *lf, cell_t *dst) {
int d;
cell_t *c;
int mindist=9999,bestdir=D_NONE;
for (d = DC_N; d <= DC_NW; d++) {
c = getcellindir(lf->cell, d);
if (!c) continue;
if (c == dst) {
// destination is adjacent!
bestdir = d;
break;
}
if (canmove(lf, d)) {
int thisdist;
thisdist = getcelldist(c, dst);
if (thisdist < mindist) {
mindist = thisdist;
bestdir = d;
}
}
}
// TODO: handle ties
return bestdir;
}
void movetowards(lifeform_t *lf, cell_t *dst) {
int dir;
// move towards them
dir = getdirtowards(lf, dst);
if (dir != D_NONE) {
trymove(lf, dir);
}
}