timesynk/npc.c

88 lines
2.4 KiB
C

#include "npc.h"
#include "tile.h"
#include "stubs.h" // for interface
#include "game.h" // for current_map
void npcThink(struct Tile *npc) {
struct NpcTile *npc_data = npc->data;
struct Tile *target;
switch (npc_data->behavior) {
case BEHAVE_AGGRESSIVE:
if (!npc_data->target) { // find a player
if ((target = npcFindTile(npc, PLAYER))) {
interfacePrint("The nupi, fueled by bloodlust, shrieks in rage");
npc_data->target = target;
}
} else {
npcMoveToTarget(npc, npc_data);
}
break;
case BEHAVE_WANDER:
npcMoveRandom(npc);
break;
}
}
void npcMoveToTarget(struct Tile *npc, struct NpcTile *npc_data) {
int current_x = npc->x;
int current_y = npc->y;
struct Tile *target_tile;
target_tile = npc_data->target;
if (target_tile) {
if (npc->x < target_tile->x) {
current_x++;
} else if (npc->x > target_tile->x) {
current_x--;
}
if (npc->y < target_tile->y) {
current_y++;
} else if (npc->y > target_tile->y) {
current_y--;
}
if (!gameCollision(current_x, current_y)) {
gameMoveTile(npc, current_x, current_y);
}
}
}
void npcMoveRandom(struct Tile *npc) {
int target_x = npc->x + (roll(0, 2)-1);
int target_y = npc->y + (roll(0, 2)-1);
if (!gameCollision(target_x, target_y)) {
gameMoveTile(npc, target_x, target_y);
}
}
struct Tile *npcFindTile(struct Tile *npc, int tile_type) {
struct Tile *final_target;
struct NpcTile *npc_data = npc->data;
struct Tile *current_tile;
int step_x = npc->x - npc_data->vision;
int step_y = npc->y - npc_data->vision;
int end_x = npc->x + npc_data->vision;
int end_y = npc->y + npc_data->vision;
int found_x = 0;
int found_y = 0;
while (step_x < end_x) {
step_y = npc->y - (npc_data->vision);
while (step_y < end_y) {
if (step_x >= 0 && step_y >= 0 && step_x < current_map->width && step_y < current_map->height) {
current_tile = &current_map->matrix[step_x][step_y];
while (current_tile) {
if (current_tile->tid == tile_type) {
if ( ( (npc->x-step_x) + (npc->y-step_y)) < (npc->x-found_x + npc->y-found_y) ) {
found_x = step_x;
found_y = step_y;
final_target = current_tile;
}
}
current_tile = current_tile->next;
}
}
step_y++;
}
step_x++;
}
return final_target;
}