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:
parent
0e8a2e520a
commit
54fa1a23ce
7 changed files with 168 additions and 112 deletions
62
systems.cpp
62
systems.cpp
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue