diff --git a/map.cpp b/map.cpp index 2f941ea..4795e21 100644 --- a/map.cpp +++ b/map.cpp @@ -52,11 +52,13 @@ Map::Map(size_t width, size_t height) : $input_map(height, MatrixRow(width, 1)), $walls(height, MatrixRow(width, INV_WALL)), $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) : $limit(limit), $input_map(input_map), @@ -66,6 +68,8 @@ Map::Map(Matrix input_map, Matrix walls_map, int limit) : $height = $walls.size(); $paths = Matrix($height, MatrixRow($width, 1)); $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) { @@ -77,12 +81,12 @@ inline void matrix_assign(Matrix &out, int new_value) { /* * 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(); // Initialize the new array with every pixel at limit distance // NOTE: this is normally ones() * limit int limit = $limit == 0 ? $height * $width : $limit; - matrix_assign($paths, limit); + matrix_assign(path_for, limit); Matrix closed = $walls; PointList starting_pixels; @@ -92,8 +96,8 @@ void Map::make_paths() { for(size_t counter = 0; counter < $height * $width; counter++) { size_t x = counter % $width; // BUG: is this right? size_t y = counter / $width; - if($input_map[y][x] == 0) { - $paths[y][x] = 0; + if(input_map[y][x] == 0) { + path_for[y][x] = 0; closed[y][x] = 1; starting_pixels.push_back({.x=x,.y=y}); } @@ -109,7 +113,7 @@ void Map::make_paths() { for(; counter < limit && !open_pixels.empty(); ++counter) { PointList next_open; 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); } open_pixels = next_open; @@ -117,10 +121,14 @@ void Map::make_paths() { // Last pass: flood last 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) { INVARIANT(); dbc::pre("y out of bounds", origin_y + h < $height); @@ -384,15 +392,15 @@ void Map::reset_light() { } 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) { - set_target(at, value); + $light_input[at.y][at.x] = 0; } 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) { @@ -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) { - size_t at = level + $paths[y][x]; + size_t at = level + $light_paths[y][x]; int cur_level = $lightmap[y][x]; int new_level = at < lighting::LEVELS.size() ? lighting::LEVELS[at] : lighting::MIN; 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) { 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) { 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; for(auto point : has_light) { 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]; 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() { 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[0].size() == width(), "paths wrong width"); check($input_map.size() == height(), "input_map wrong height"); diff --git a/map.hpp b/map.hpp index f3d4085..0ca250a 100644 --- a/map.hpp +++ b/map.hpp @@ -42,6 +42,8 @@ public: Matrix $walls; Matrix $paths; Matrix $lightmap; + Matrix $light_paths; + Matrix $light_input; std::vector $rooms; Map(Matrix input_map, Matrix walls_map, int limit); @@ -76,6 +78,7 @@ public: bool neighbors(Point &out, bool up); bool inmap(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 set_target(const Point &at, int value=0); void clear_target(const Point &at);