Make the lighting and the enemy pathing separate things, but now I think this needs to come out of map entirely.

main
Zed A. Shaw 5 months ago
parent 10c152a1c2
commit d515c33afc
  1. 38
      map.cpp
  2. 3
      map.hpp

@ -52,11 +52,13 @@ Map::Map(size_t width, size_t height) :
$input_map(height, MatrixRow(width, 1)), $input_map(height, MatrixRow(width, 1)),
$walls(height, MatrixRow(width, INV_WALL)), $walls(height, MatrixRow(width, INV_WALL)),
$paths(height, MatrixRow(width, 1)), $paths(height, MatrixRow(width, 1)),
$lightmap(height, MatrixRow(width, 0)) $lightmap(height, MatrixRow(width, 0)),
$light_paths(height, MatrixRow(width, 1)),
$light_input(height, MatrixRow(width, 1))
{ {
} }
// make explicit // Used on in tests to set an existing map
Map::Map(Matrix input_map, Matrix walls_map, int limit) : Map::Map(Matrix input_map, Matrix walls_map, int limit) :
$limit(limit), $limit(limit),
$input_map(input_map), $input_map(input_map),
@ -66,6 +68,8 @@ Map::Map(Matrix input_map, Matrix walls_map, int limit) :
$height = $walls.size(); $height = $walls.size();
$paths = Matrix($height, MatrixRow($width, 1)); $paths = Matrix($height, MatrixRow($width, 1));
$lightmap = Matrix($height, MatrixRow($width, 0)); $lightmap = Matrix($height, MatrixRow($width, 0));
$light_paths = Matrix($height, MatrixRow($width, 1));
$light_input = Matrix($height, MatrixRow($width, 1));
} }
inline void matrix_assign(Matrix &out, int new_value) { inline void matrix_assign(Matrix &out, int new_value) {
@ -77,12 +81,12 @@ inline void matrix_assign(Matrix &out, int new_value) {
/* /*
* Used https://github.com/HenrYxZ/dijkstra-map as a reference. * Used https://github.com/HenrYxZ/dijkstra-map as a reference.
*/ */
void Map::make_paths() { void Map::pathing_for(Matrix &input_map, Matrix &path_for) {
INVARIANT(); INVARIANT();
// Initialize the new array with every pixel at limit distance // Initialize the new array with every pixel at limit distance
// NOTE: this is normally ones() * limit // NOTE: this is normally ones() * limit
int limit = $limit == 0 ? $height * $width : $limit; int limit = $limit == 0 ? $height * $width : $limit;
matrix_assign($paths, limit); matrix_assign(path_for, limit);
Matrix closed = $walls; Matrix closed = $walls;
PointList starting_pixels; PointList starting_pixels;
@ -92,8 +96,8 @@ void Map::make_paths() {
for(size_t counter = 0; counter < $height * $width; counter++) { for(size_t counter = 0; counter < $height * $width; counter++) {
size_t x = counter % $width; // BUG: is this right? size_t x = counter % $width; // BUG: is this right?
size_t y = counter / $width; size_t y = counter / $width;
if($input_map[y][x] == 0) { if(input_map[y][x] == 0) {
$paths[y][x] = 0; path_for[y][x] = 0;
closed[y][x] = 1; closed[y][x] = 1;
starting_pixels.push_back({.x=x,.y=y}); starting_pixels.push_back({.x=x,.y=y});
} }
@ -109,7 +113,7 @@ void Map::make_paths() {
for(; counter < limit && !open_pixels.empty(); ++counter) { for(; counter < limit && !open_pixels.empty(); ++counter) {
PointList next_open; PointList next_open;
for(auto sp : open_pixels) { for(auto sp : open_pixels) {
$paths[sp.y][sp.x] = counter; path_for[sp.y][sp.x] = counter;
add_neighbors(next_open, closed, sp.y, sp.x); add_neighbors(next_open, closed, sp.y, sp.x);
} }
open_pixels = next_open; open_pixels = next_open;
@ -117,8 +121,12 @@ void Map::make_paths() {
// Last pass: flood last pixels // Last pass: flood last pixels
for(auto sp : open_pixels) { for(auto sp : open_pixels) {
$paths[sp.y][sp.x] = counter; path_for[sp.y][sp.x] = counter;
}
} }
void Map::make_paths() {
pathing_for($input_map, $paths);
} }
void Map::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) { void Map::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) {
@ -384,15 +392,15 @@ void Map::reset_light() {
} }
void Map::clear_light_target(const Point &at) { void Map::clear_light_target(const Point &at) {
$input_map[at.y][at.x] = 1; $light_input[at.y][at.x] = 1;
} }
void Map::set_light_target(const Point &at, int value) { void Map::set_light_target(const Point &at, int value) {
set_target(at, value); $light_input[at.y][at.x] = 0;
} }
void Map::path_light() { void Map::path_light() {
make_paths(); pathing_for($light_input, $light_paths);
} }
void Map::light_box(LightSource source, Point from, Point &min_out, Point &max_out) { void Map::light_box(LightSource source, Point from, Point &min_out, Point &max_out) {
@ -404,7 +412,7 @@ void Map::light_box(LightSource source, Point from, Point &min_out, Point &max_o
} }
int Map::light_level(int level, size_t x, size_t y) { int Map::light_level(int level, size_t x, size_t y) {
size_t at = level + $paths[y][x]; size_t at = level + $light_paths[y][x];
int cur_level = $lightmap[y][x]; int cur_level = $lightmap[y][x];
int new_level = at < lighting::LEVELS.size() ? lighting::LEVELS[at] : lighting::MIN; int new_level = at < lighting::LEVELS.size() ? lighting::LEVELS[at] : lighting::MIN;
return cur_level < new_level ? new_level : cur_level; return cur_level < new_level ? new_level : cur_level;
@ -419,7 +427,7 @@ void Map::render_light(LightSource source, Point at) {
for(size_t y = min.y; y <= max.y; ++y) { for(size_t y = min.y; y <= max.y; ++y) {
auto &light_row = $lightmap[y]; auto &light_row = $lightmap[y];
auto &path_row = $paths[y]; auto &path_row = $light_paths[y];
for(size_t x = min.x; x <= max.x; ++x) { for(size_t x = min.x; x <= max.x; ++x) {
if(path_row[x] != UNPATH) { if(path_row[x] != UNPATH) {
@ -432,7 +440,7 @@ void Map::render_light(LightSource source, Point at) {
const int wall_light = source.strength + WALL_LIGHT_LEVEL; const int wall_light = source.strength + WALL_LIGHT_LEVEL;
for(auto point : has_light) { for(auto point : has_light) {
for(int j = -1;point.y+j >= 0 && j <= 1 && point.y+j < $height; j++) { for(int j = -1;point.y+j >= 0 && j <= 1 && point.y+j < $height; j++) {
auto &path_row = $paths[point.y+j]; auto &path_row = $light_paths[point.y+j];
auto &light_row = $lightmap[point.y+j]; auto &light_row = $lightmap[point.y+j];
for(int i = -1; point.x+i >= 0 && i <= 1 && point.x+i < $width; i++) { for(int i = -1; point.x+i >= 0 && i <= 1 && point.x+i < $width; i++) {
@ -447,6 +455,8 @@ void Map::render_light(LightSource source, Point at) {
bool Map::INVARIANT() { bool Map::INVARIANT() {
using dbc::check; using dbc::check;
check($light_paths.size() == height(), "paths wrong height");
check($light_paths[0].size() == width(), "paths wrong width");
check($paths.size() == height(), "paths wrong height"); check($paths.size() == height(), "paths wrong height");
check($paths[0].size() == width(), "paths wrong width"); check($paths[0].size() == width(), "paths wrong width");
check($input_map.size() == height(), "input_map wrong height"); check($input_map.size() == height(), "input_map wrong height");

@ -42,6 +42,8 @@ public:
Matrix $walls; Matrix $walls;
Matrix $paths; Matrix $paths;
Matrix $lightmap; Matrix $lightmap;
Matrix $light_paths;
Matrix $light_input;
std::vector<Room> $rooms; std::vector<Room> $rooms;
Map(Matrix input_map, Matrix walls_map, int limit); Map(Matrix input_map, Matrix walls_map, int limit);
@ -76,6 +78,7 @@ public:
bool neighbors(Point &out, bool up); bool neighbors(Point &out, bool up);
bool inmap(size_t x, size_t y); bool inmap(size_t x, size_t y);
bool iswall(size_t x, size_t y); bool iswall(size_t x, size_t y);
void pathing_for(Matrix &input_map, Matrix &path_for);
void make_paths(); void make_paths();
void set_target(const Point &at, int value=0); void set_target(const Point &at, int value=0);
void clear_target(const Point &at); void clear_target(const Point &at);

Loading…
Cancel
Save