diff --git a/gui/map_view.cpp b/gui/map_view.cpp index 00306f7..0816a39 100644 --- a/gui/map_view.cpp +++ b/gui/map_view.cpp @@ -13,9 +13,8 @@ #include #include "palette.hpp" -constexpr const int map_width=13; -constexpr const int map_height=13; - +constexpr const int MAP_WIDTH=13; +constexpr const int MAP_HEIGHT=13; namespace gui { using namespace components; @@ -25,7 +24,8 @@ namespace gui { $level(level), $map_render(std::make_shared()), $map_sprite($map_render->getTexture()), - $map_tiles(matrix::make(map_width, map_height)) + $map_tiles(matrix::make(MAP_WIDTH, MAP_HEIGHT)), + $fow(matrix::make($level.map->width(), $level.map->height())) { auto player = $level.world->get_the(); $player_display = $level.world->get(player.entity).display; @@ -33,6 +33,7 @@ namespace gui { void MapViewUI::update_level(GameLevel &level) { $level = level; + $fow = matrix::make($level.map->width(), $level.map->height()); } void MapViewUI::init() { @@ -44,7 +45,7 @@ namespace gui { $gui.set($log_to, {10, THEME.DARK_MID, THEME.BORDER_COLOR, 10}); $gui.set($log_to, {L"Welcome to the Game!", 25, THEME.TEXT_COLOR, 10}); - auto map_cell = lel::center(MAP_TILE_DIM * map_width, MAP_TILE_DIM * map_height, $gui.cell_for("map_grid")); + auto map_cell = lel::center(MAP_TILE_DIM * MAP_WIDTH, MAP_TILE_DIM * MAP_HEIGHT, $gui.cell_for("map_grid")); $map_sprite.setPosition({(float)map_cell.x, (float)map_cell.y + 30}); $gui.init(); @@ -62,7 +63,17 @@ namespace gui { void MapViewUI::render(sf::RenderWindow &window, int compass_dir) { $gui.render(window); - System::draw_map($level, $map_tiles, $entity_map); + auto player = $level.world->get_the(); + auto player_pos = $level.world->get(player.entity).location; + + // NOTE: FoW is probably better done in the lighting system, because it illuminates where you've been. The light calcs could then simply set the light the player touches to 1 when it's run. + for(matrix::circle it{$fow, player_pos, 2.5}; it.next();) { + for(int x = it.left; x < it.right; x++) { + $fow[it.y][x] = 1; + } + } + + System::draw_map($level, $map_tiles, $fow, $entity_map); System::render_map($map_tiles, $entity_map, *$map_render, compass_dir, $player_display); $map_sprite.setTexture($map_render->getTexture(), true); window.draw($map_sprite); diff --git a/gui/map_view.hpp b/gui/map_view.hpp index b5d9836..8688c0a 100644 --- a/gui/map_view.hpp +++ b/gui/map_view.hpp @@ -17,6 +17,7 @@ namespace gui { std::shared_ptr $map_render; sf::Sprite $map_sprite; matrix::Matrix $map_tiles; + matrix::Matrix $fow; MapViewUI(GameLevel &level); void init(); diff --git a/systems.cpp b/systems.cpp index 268018e..f9f11ec 100644 --- a/systems.cpp +++ b/systems.cpp @@ -526,7 +526,7 @@ bool System::inventory_occupied(GameLevel& level, Entity container_id, const std } -void System::draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map) { +void System::draw_map(GameLevel& level, Matrix& grid, Matrix& fow, EntityGrid& entity_map) { World &world = *level.world; Map &map = *level.map; size_t view_x = matrix::width(grid) - 1; @@ -547,7 +547,7 @@ void System::draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map) { size_t tile_y = size_t(it.y) + cam_orig.y; size_t tile_x = size_t(it.x) + cam_orig.x; - if(matrix::inbounds(tiles, tile_x, tile_y)) { + if(matrix::inbounds(tiles, tile_x, tile_y) && fow[tile_y][tile_x]) { size_t tid = tiles[tile_y][tile_x]; grid[it.y][it.x] = tile_set[tid]; } else { @@ -558,11 +558,15 @@ void System::draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map) { // then get the enemy/item/device tiles and fill those in world.query([&](auto, auto &pos, auto &entity_glyph) { // BUG: don't I have a within bounds macro somewhere? - if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x - && pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) + if(pos.location.x >= cam_orig.x + && pos.location.x <= cam_orig.x + view_x + && pos.location.y >= cam_orig.y + && pos.location.y <= cam_orig.y + view_y) { - Point view_pos = map.map_to_camera(pos.location, cam_orig); - entity_map.insert_or_assign(view_pos, entity_glyph.display); + if(fow[pos.location.y][pos.location.x]) { + Point view_pos = map.map_to_camera(pos.location, cam_orig); + entity_map.insert_or_assign(view_pos, entity_glyph.display); + } } }); } diff --git a/systems.hpp b/systems.hpp index 727d848..6fe0fc0 100644 --- a/systems.hpp +++ b/systems.hpp @@ -39,6 +39,6 @@ namespace System { void inventory_swap(GameLevel &level, Entity container_id, const std::string& a_name, const std::string &b_name); bool inventory_occupied(GameLevel& level, Entity container_id, const std::string& name); - void draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map); + void draw_map(GameLevel& level, Matrix& grid, Matrix& fow, EntityGrid& entity_map); void render_map(Matrix& tiles, EntityGrid& entity_map, sf::RenderTexture& render, int compass_dir, wchar_t player_display); } diff --git a/tests/map.cpp b/tests/map.cpp index 9a1a463..5befe84 100644 --- a/tests/map.cpp +++ b/tests/map.cpp @@ -100,8 +100,11 @@ TEST_CASE("map image test", "[map-sprite]") { for(matrix::each_row it{level.map->walls()}; it.next();) { player_pos.location.x = it.x; player_pos.location.y = it.y; + size_t width = level.map->width(); + size_t height = level.map->height(); - System::draw_map(level, map_tiles, entity_map); + Matrix fow = matrix::make(width, height); + System::draw_map(level, map_tiles, fow, entity_map); System::render_map(map_tiles, entity_map, *render, 2, player_display); #ifdef TEST_RENDER