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
66
src/map.c
66
src/map.c
|
|
@ -1,6 +1,8 @@
|
|||
#include "map.h"
|
||||
#include "rng.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void map_init(Map *map) {
|
||||
|
|
@ -186,3 +188,67 @@ void dungeon_generate(Dungeon *d, Map *map, int floor_num) {
|
|||
d->room_count = map->room_count;
|
||||
memcpy(d->rooms, map->rooms, sizeof(Room) * map->room_count);
|
||||
}
|
||||
|
||||
int is_in_view_range(int x, int y, int view_x, int view_y, int range) {
|
||||
int dx = x - view_x;
|
||||
int dy = y - view_y;
|
||||
return (dx * dx + dy * dy) <= (range * range);
|
||||
}
|
||||
|
||||
static int trace_line_of_sight(const Map *map, int x1, int y1, int x2, int y2) {
|
||||
int dx = abs(x2 - x1);
|
||||
int dy = abs(y2 - y1);
|
||||
int sx = (x1 < x2) ? 1 : -1;
|
||||
int sy = (y1 < y2) ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int x = x1;
|
||||
int y = y1;
|
||||
|
||||
while (1) {
|
||||
if (!in_bounds(x, y, MAP_WIDTH, MAP_HEIGHT))
|
||||
return 0;
|
||||
|
||||
if (x == x2 && y == y2)
|
||||
return 1;
|
||||
|
||||
if (map->tiles[y][x] == TILE_WALL && !(x == x1 && y == y1))
|
||||
return 0;
|
||||
|
||||
int e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x += sx;
|
||||
}
|
||||
if (e2 < dx) {
|
||||
err += dx;
|
||||
y += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int has_line_of_sight(const Map *map, int x1, int y1, int x2, int y2) {
|
||||
if (!in_bounds(x1, y1, MAP_WIDTH, MAP_HEIGHT) || !in_bounds(x2, y2, MAP_WIDTH, MAP_HEIGHT))
|
||||
return 0;
|
||||
return trace_line_of_sight(map, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
int can_see_entity(const Map *map, int from_x, int from_y, int to_x, int to_y, int range) {
|
||||
if (!is_in_view_range(to_x, to_y, from_x, from_y, range))
|
||||
return 0;
|
||||
return has_line_of_sight(map, from_x, from_y, to_x, to_y);
|
||||
}
|
||||
|
||||
void calculate_visibility(Map *map, int x, int y) {
|
||||
memset(map->visible, 0, sizeof(map->visible));
|
||||
|
||||
for (int ty = 0; ty < MAP_HEIGHT; ty++) {
|
||||
for (int tx = 0; tx < MAP_WIDTH; tx++) {
|
||||
if (is_in_view_range(tx, ty, x, y, PLAYER_VIEW_RANGE)) {
|
||||
if (has_line_of_sight(map, x, y, tx, ty)) {
|
||||
map->visible[ty][tx] = 1;
|
||||
map->remembered[ty][tx] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue