125 lines
2.4 KiB
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);
|
|
}
|
|
}
|
|
|