|
|
|
#include "lights.hpp"
|
|
|
|
#include "constants.hpp"
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
namespace lighting {
|
|
|
|
void LightRender::render_light(LightSource source, Point at) {
|
|
|
|
Point min, max;
|
|
|
|
clear_light_target(at);
|
|
|
|
vector<Point> has_light;
|
|
|
|
|
|
|
|
|
|
|
|
for(matrix::in_box it{$lightmap, at.x, at.y, (size_t)source.distance}; it.next();) {
|
|
|
|
if($paths.$paths[it.y][it.x] != WALL_PATH_LIMIT) {
|
|
|
|
$lightmap[it.y][it.x] = light_level(source.strength, it.x, it.y);
|
|
|
|
has_light.push_back({it.x, it.y});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const int wall_light = source.strength + WALL_LIGHT_LEVEL;
|
|
|
|
for(auto point : has_light) {
|
|
|
|
for(matrix::in_box it{$lightmap, point.x, point.y, 1}; it.next();) {
|
|
|
|
if($paths.$paths[it.y][it.x] == WALL_PATH_LIMIT) {
|
|
|
|
$lightmap[it.y][it.x] = light_level(wall_light, point.x, point.y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int LightRender::light_level(int level, size_t x, size_t y) {
|
|
|
|
size_t at = level + $paths.$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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void LightRender::reset_light() {
|
|
|
|
for(auto &row : $lightmap) {
|
|
|
|
row.assign(row.size(), lighting::MIN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LightRender::clear_light_target(const Point &at) {
|
|
|
|
$paths.clear_target(at);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LightRender::set_light_target(const Point &at, int value) {
|
|
|
|
$paths.set_target(at, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LightRender::path_light(Matrix &walls) {
|
|
|
|
$paths.compute_paths(walls);
|
|
|
|
}
|
|
|
|
}
|