88 lines
2.4 KiB
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 = ¤t_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;
|
|
}
|