forked from NotAShelf/rogged
various: implement fog of war; make enemy AI slightly more intelligent
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I3e22dbc5e10690871255980c52a24c226a6a6964
This commit is contained in:
parent
1d738c35d4
commit
c2412ac4b1
8 changed files with 151 additions and 21 deletions
47
src/enemy.c
47
src/enemy.c
|
|
@ -3,6 +3,7 @@
|
|||
#include "common.h"
|
||||
#include "map.h"
|
||||
#include "rng.h"
|
||||
#include "settings.h"
|
||||
#include <string.h>
|
||||
|
||||
// Forward declaration
|
||||
|
|
@ -134,11 +135,9 @@ int is_enemy_at(const Enemy *enemies, int count, int x, int y) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Check if enemy can see player (adjacent)
|
||||
static int can_see_player(Enemy *e, Player *p) {
|
||||
int dx = p->x - e->x;
|
||||
int dy = p->y - e->y;
|
||||
return (dx >= -1 && dx <= 1 && dy >= -1 && dy <= 1);
|
||||
// Check if enemy can see player (within view range and line of sight)
|
||||
static int can_see_player(Enemy *e, Player *p, Map *map) {
|
||||
return can_see_entity(map, e->x, e->y, p->x, p->y, ENEMY_VIEW_RANGE);
|
||||
}
|
||||
|
||||
// Check if position is occupied by player
|
||||
|
|
@ -178,7 +177,27 @@ static void enemy_move_toward_player(Enemy *e, Player *p, Map *map, Enemy *all_e
|
|||
}
|
||||
}
|
||||
|
||||
// Perform a single action for an enemy (attack if adjacent, otherwise move)
|
||||
// Move enemy in a random direction (patrol)
|
||||
static void enemy_patrol(Enemy *e, Map *map, Enemy *all_enemies, int enemy_count) {
|
||||
if (rng_int(0, 100) > ENEMY_PATROL_MOVE_CHANCE)
|
||||
return;
|
||||
|
||||
int dx = rng_int(-1, 1);
|
||||
int dy = rng_int(-1, 1);
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
return;
|
||||
|
||||
int new_x = e->x + dx;
|
||||
int new_y = e->y + dy;
|
||||
|
||||
if (is_floor(map, new_x, new_y) && !is_enemy_at(all_enemies, enemy_count, new_x, new_y)) {
|
||||
e->x = new_x;
|
||||
e->y = new_y;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform a single action for an enemy (attack if visible, otherwise patrol)
|
||||
void enemy_act(Enemy *e, Player *p, Map *map, Enemy *all_enemies, int enemy_count) {
|
||||
if (!e->alive)
|
||||
return;
|
||||
|
|
@ -187,14 +206,22 @@ void enemy_act(Enemy *e, Player *p, Map *map, Enemy *all_enemies, int enemy_coun
|
|||
if (combat_has_effect(e->effects, e->effect_count, EFFECT_STUN))
|
||||
return;
|
||||
|
||||
// Check if adjacent to player - attack
|
||||
if (can_see_player(e, p)) {
|
||||
int can_see = can_see_player(e, p, map);
|
||||
|
||||
// Attack if adjacent to player
|
||||
if (can_see && can_see_entity(map, e->x, e->y, p->x, p->y, 1)) {
|
||||
combat_enemy_attack(e, p);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, move toward player
|
||||
enemy_move_toward_player(e, p, map, all_enemies, enemy_count);
|
||||
// Move toward player if visible
|
||||
if (can_see) {
|
||||
enemy_move_toward_player(e, p, map, all_enemies, enemy_count);
|
||||
return;
|
||||
}
|
||||
|
||||
// Player not visible - patrol randomly
|
||||
enemy_patrol(e, map, all_enemies, enemy_count);
|
||||
}
|
||||
|
||||
void enemy_update_all(Enemy enemies[], int count, Player *p, Map *map) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue