Refactor the light calculations to be part of map instead of spread out all over. Still need to bring back lighting on walls and also pathing for enemies is currently busted.

This commit is contained in:
Zed A. Shaw 2024-11-28 02:41:01 -05:00
parent 0e8a2e520a
commit 54fa1a23ce
7 changed files with 168 additions and 112 deletions

View file

@ -8,6 +8,7 @@
#include "ftxui/screen/color.hpp"
#include "ftxui/screen/terminal.hpp" // for SetColorSupport, Color, TrueColor
#include "dbc.hpp"
#include "lights.hpp"
const bool DEBUG_MAP=false;
@ -15,68 +16,21 @@ using std::string;
using namespace fmt;
using namespace components;
using ftxui::Color;
const int LIGHT_MIN = 20;
const int LIGHT_MAX = 160;
using lighting::LightSource;
void System::lighting(DinkyECS::World &world, Map &game_map, Player &player) {
using std::min, std::max, std::clamp;
auto &lighting = game_map.lighting();
std::vector<Point> has_light;
for(auto &row : lighting) {
for(size_t i = 0; i < row.size(); i++) {
row[i] = LIGHT_MIN;
}
}
game_map.reset_light();
world.query<Position, LightSource>([&](const auto &ent, auto &position, auto &lightsource) {
game_map.set_target(position.location);
game_map.set_light_target(position.location);
});
game_map.make_paths();
auto &paths = game_map.paths();
game_map.path_light();
world.query<Position, LightSource>([&](const auto &ent, auto &position, auto &lightsource) {
game_map.clear_target(position.location);
int strength = 255 - lightsource.strength;
size_t dist = size_t((float(lightsource.strength) / 255.0) * 3) + 1;
size_t min_x = max(position.location.x, dist) - dist;
size_t max_x = min(position.location.x + dist, game_map.width() - 1);
size_t min_y = max(position.location.y, dist) - dist;
size_t max_y = min(position.location.y + dist, game_map.height() - 1);
for(size_t x = min_x; x <= max_x; ++x) {
for(size_t y = min_y; y <= max_y; ++y) {
int dnum = paths[y][x];
int light = std::clamp(255 - (strength * dnum), LIGHT_MIN, LIGHT_MAX);
if(lighting[y][x] < light) {
lighting[y][x] = light;
if(light > LIGHT_MIN) {
has_light.push_back({x, y});
}
}
}
}
game_map.render_light(lightsource, position.location);
});
const int UNPATH = game_map.limit();
for(auto point : has_light) {
for(int i = -1; i <= 1; i++) {
for(int j = -1; j <= 1; j++) {
if(!game_map.inmap(point.x+i, point.y+j)) continue;
if(paths[point.y+j][point.x+i] == UNPATH) {
lighting[point.y+j][point.x+i] = LIGHT_MAX;
}
}
}
}
}
void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player) {
@ -184,7 +138,7 @@ void System::collision(DinkyECS::World &world, Player &player) {
world.send<Events::GUI>(Events::GUI::LOOT, entity, loot);
inventory.gold += loot.amount;
light.strength = 100;
light.strength = 3;
collider.remove(loot_pos.location);
} else {
println("UNKNOWN COLLISION TYPE {}", entity);
@ -232,7 +186,7 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canv
if(tile == config.WALL_TILE) {
canvas.DrawText(x * 2, y * 4, config.WALL_TILE, [light_value](auto &pixel) {
if(light_value > LIGHT_MIN) {
if(light_value > lighting::MIN) {
pixel.foreground_color = Color::HSV(230, 20, 10);
pixel.background_color = Color::HSV(230, 20, light_value / 2);
} else {