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:
raf 2026-04-09 09:35:52 +03:00
commit c2412ac4b1
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
8 changed files with 151 additions and 21 deletions

View file

@ -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) {