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 f85d28e932
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
8 changed files with 151 additions and 21 deletions

View file

@ -4,6 +4,7 @@
#include "map.h"
#include "movement.h"
#include "rng.h"
#include "settings.h"
#include <string.h>
// Forward declaration
@ -135,11 +136,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->position.x - e->position.x;
int dy = p->position.y - e->position.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->position.x, e->position.y, p->position.x, p->position.y, ENEMY_VIEW_RANGE);
}
@ -171,7 +170,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->position.x + dx;
int new_y = e->position.y + dy;
if (is_floor(map, new_x, new_y) && !is_enemy_at(all_enemies, enemy_count, new_x, new_y)) {
e->position.x = new_x;
e->position.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;
@ -180,14 +199,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->position.x, e->position.y, p->position.x, p->position.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) {