nexus/ai.c

161 lines
3.6 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 wantdb = B_TRUE;
int db = B_FALSE;
object_t *curwep,*bestwep;
flag_t *f;
lifeform_t *target;
char buf[BUFLEN];
if (wantdb && haslos(player, lf->cell)) {
db = B_TRUE;
} else {
db = B_FALSE;
}
if (db) dblog("AIMOVE: %s", lf->race->name);
// if lifeform isn't alive, skip turn
if (isdead(lf)) {
if (db) dblog(".oO { i am not alive, skipping turn. }");
taketime(lf, SPEED_DEAD);
return;
}
// do we have a better weapon we could use?
curwep = getweapon(lf);
bestwep = getbestweapon(lf);
if (curwep != bestwep) {
if (db) dblog(".oO { i have a better weapon than my current one (%s > %s) }",bestwep->type->name, curwep ? curwep->type->name : "nothing");
// weild better one
weild(lf, bestwep);
return;
}
// do we already have a target we are attacking?
f = hasflag(lf->flags, F_TARGET);
if (f) {
int targid;
if (db) dblog(".oO { i have a target... }");
targid = f->val[0];
target = findlf(lf->cell->map, targid);
if (target) {
if (db) dblog(".oO { my target is lfid %d (%s). }", targid, target->race->name);
if (haslos(lf, target->cell)) {
if (db) dblog(".oO { i can see my target. will move towards it. }");
movetowards(lf, target->cell);
return;
} else {
if (db) dblog(".oO { i cannot see my target }");
// TODO: move towards last known location
// just try to move in a random direction
if (db) dblog(".oO { will move randomly }");
dorandommove(lf, B_NOBADMOVES);
return;
}
}
} else {
// not attacking anyone in particular
if (db) dblog(".oO { i do not have a target. }");
// TODO: are we hostile? if so, look for a target
f = hasflag(lf->flags, F_HOSTILE);
if (f) {
int x,y;
cell_t *c;
if (db) dblog(".oO { i am hostile. looking for a target. }");
// 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) {
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
// 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...
if (db) dblog(".oO { moving towards my new target }");
movetowards(lf, c);
return;
}
}
}
}
}
// just try to move in a random direction
if (db) dblog(".oO { default - moving randomly }");
dorandommove(lf, B_NOBADMOVES);
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);
}
}