diff --git a/constants.hpp b/constants.hpp index c0ed0d8..38df811 100644 --- a/constants.hpp +++ b/constants.hpp @@ -9,3 +9,6 @@ const int WALL_VALUE = 1; const int SPACE_VALUE = 0; const int WALL_PATH_LIMIT = 1000; const int WALL_LIGHT_LEVEL = 3; +const int WORLDBUILD_DIVISION = 4; +const int WORLDBUILD_SHRINK = 2; +const int WORLDBUILD_MAX_PATH = 200; diff --git a/gui.cpp b/gui.cpp index 44b5058..2174fdb 100644 --- a/gui.cpp +++ b/gui.cpp @@ -168,6 +168,10 @@ void GUI::handle_world_events() { } } +void GUI::shutdown() { + $renderer.close(); +} + bool GUI::handle_ui_events() { using KB = sf::Keyboard; using MOUSE = sf::Mouse; @@ -179,8 +183,7 @@ bool GUI::handle_ui_events() { while($renderer.poll_event(event)) { if(event.type == sf::Event::Closed) { - // BUG: This should call a GUI::shutdown so I can do saves and stuff. - $renderer.close(); + shutdown(); } else if(event.type == sf::Event::KeyPressed) { if(KB::isKeyPressed(KB::Left)) { @@ -207,14 +210,12 @@ bool GUI::handle_ui_events() { $status_ui.$component->OnEvent(Event::Return); } } else if(MOUSE::isButtonPressed(MOUSE::Left)) { - sf::Vector2i pos = MOUSE::getPosition($renderer.$window); - Mouse mev; - mev.button = Mouse::Button::Left, - // BUG: renderer should have a function that handles mouse coordinates - // BUG: optionally maybe have it in panel? Seems to work though. - mev.x=pos.x / $renderer.$ui_bounds.width; - mev.y=pos.y / $renderer.$ui_bounds.height; - // BUG: maybe also handle mouse motion events? + Point pos = $renderer.mouse_position(); + Mouse mev{ + .button=Mouse::Button::Left, + .x=int(pos.x), .y=int(pos.y) + }; + $status_ui.$component->OnEvent(Event::Mouse("", mev)); } } diff --git a/gui.hpp b/gui.hpp index bc7d739..cc3256e 100644 --- a/gui.hpp +++ b/gui.hpp @@ -68,6 +68,6 @@ public: void run_systems(); void save_world(); void shake(); - + void shutdown(); int main(bool run_once=false); }; diff --git a/pathing.cpp b/pathing.cpp index 26fa49f..9aae6b3 100644 --- a/pathing.cpp +++ b/pathing.cpp @@ -5,9 +5,7 @@ using std::vector; -inline void add_neighbors(PointList &neighbors, Matrix &closed, size_t y, size_t x) { - size_t h = closed.size(); - size_t w = closed[0].size(); +inline void add_neighbors(PointList &neighbors, Matrix &closed, size_t y, size_t x, size_t w, size_t h) { vector rows{y - 1, y, y + 1}; vector cols{x - 1, x, x + 1}; @@ -17,7 +15,6 @@ inline void add_neighbors(PointList &neighbors, Matrix &closed, size_t y, size_t (0 <= col && col < w) && closed[row][col] == 0) { - // BUG: maybe value here? closed[row][col] = 1; neighbors.push_back({.x=col, .y=row}); } @@ -39,18 +36,18 @@ void Pathing::compute_paths(Matrix &walls) { // First pass: Add starting pixels and put them in closed for(size_t counter = 0; counter < $height * $width; counter++) { - size_t x = counter % $width; // BUG: is this right? + size_t x = counter % $width; size_t y = counter / $width; if($input[y][x] == 0) { $paths[y][x] = 0; - closed[y][x] = 1; // BUG: value here? + closed[y][x] = 1; starting_pixels.push_back({x,y}); } } // Second pass: Add border to open for(auto sp : starting_pixels) { - add_neighbors(open_pixels, closed, sp.y, sp.x); + add_neighbors(open_pixels, closed, sp.y, sp.x, $width, $height); } // Third pass: Iterate filling in the open list @@ -59,7 +56,7 @@ void Pathing::compute_paths(Matrix &walls) { PointList next_open; for(auto sp : open_pixels) { $paths[sp.y][sp.x] = counter; - add_neighbors(next_open, closed, sp.y, sp.x); + add_neighbors(next_open, closed, sp.y, sp.x, $width, $height); } open_pixels = next_open; } @@ -71,8 +68,8 @@ void Pathing::compute_paths(Matrix &walls) { } void Pathing::set_target(const Point &at, int value) { - // BUG: not using value here but it can be < 0 for deeper slopes - $input[at.y][at.x] = 0; + // FUTURE: I'll eventually allow setting this to negatives for priority + $input[at.y][at.x] = value; } void Pathing::clear_target(const Point &at) { diff --git a/render.cpp b/render.cpp index f453f5c..f471268 100644 --- a/render.cpp +++ b/render.cpp @@ -83,7 +83,6 @@ void SFMLRender::render_grid(const std::wstring &text, sf::Color default_fg, sf: float height_delta = 0; sf::Sprite &sprite = get_text_sprite(last_tile); const float start_x = x; - // BUG: get default_fg from panel too sf::Color cur_fg = default_fg; sf::Color cur_bg = default_bg; @@ -230,6 +229,15 @@ void SFMLRender::draw(Panel &panel, float x_offset, float y_offset) { } } +Point SFMLRender::mouse_position() { + sf::Vector2i pos = sf::Mouse::getPosition($window); + + return { + size_t(pos.x / $ui_bounds.width), + size_t(pos.y / $ui_bounds.height) + }; +} + void SFMLRender::init_terminal() { #if defined(_WIN64) || defined(_WIN32) _setmode(_fileno(stdout), _O_U16TEXT); diff --git a/render.hpp b/render.hpp index bc3f107..ed7d203 100644 --- a/render.hpp +++ b/render.hpp @@ -67,5 +67,6 @@ struct SFMLRender { int font_size() { return $map_font_size; } void clear() { $window.clear(); } void display() { $window.display(); } + Point mouse_position(); static void init_terminal(); }; diff --git a/status.txt b/status.txt index 842020b..ff57051 100644 --- a/status.txt +++ b/status.txt @@ -1,11 +1,6 @@ TODAY'S GOAL: -* Pathing::compute_paths can take a starting level to implement lower directions, or possibly setting a value lower? - * Fix " room should always be found" -* Pathing::set_target isn't using value, but that implements the above. -https://www.roguebasin.com/index.php/Dijkstra_Maps_Visualized - * Fix BUG markers as much as possible. * Make room generation have "texture" or state like mossy, flooded, etc. @@ -13,6 +8,10 @@ https://www.roguebasin.com/index.php/Dijkstra_Maps_Visualized TODO: * Lua integration +* Save file needs work, it's not saving gold and lights. + +* Move all keyboard and mouse events into SFMLRender so it's completely abstracted away and can be changed to a different backend if I want. + * When fighting two enemies with lots of attacks it crashes because one dies and isn't there. Test by making enemies immortal. * LightRender can just use the Dijkstra map paths to calculate light strenght from the point rather than doing the box thing. * $paths.$paths is annoying. @@ -22,7 +21,6 @@ TODO: * Think up an enemy system. * Write a method for renderer that can translate coordinates. * Can std::any be defaulted to a noop in the events? -* Save file isn't saving gold. * Inventory needs to be better, but need some kinds of "weapons" or other loot to get and not just gold. * Create a few more enemy types to fight. * Devise a more complete map/world generator that can use the loot and enemies better. diff --git a/tests/dijkstra.json b/tests/dijkstra.json index cafb3c2..1ee6990 100644 --- a/tests/dijkstra.json +++ b/tests/dijkstra.json @@ -36,4 +36,25 @@ [1, 0, 1000, 2], [1, 1, 1000, 3] ] -}] +}, +{ + "input": [ + [1, 1, 1, 0], + [1, 1, 1, 1], + [1, 0, 1, 1], + [1, 1, 1, 1] + ], + "walls": [ + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 1, 0], + [0, 0, 1, 0] + ], + "expected": [ + [2, 2, 1, 0], + [1, 1, 1, 1], + [1, 0, 1000, 2], + [1, 1, 1000, 3] + ] +} +] diff --git a/worldbuilder.cpp b/worldbuilder.cpp index 9c5af05..b7cefc4 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -6,8 +6,7 @@ using namespace fmt; inline int make_split(Room &cur, bool horiz) { size_t dimension = horiz ? cur.height : cur.width; - // BUG: this might be better as a configurable 4 number - int min = dimension / 4; + int min = dimension / WORLDBUILD_DIVISION; int max = dimension - min; return Random::uniform(min, max); @@ -156,13 +155,11 @@ void WorldBuilder::make_room(size_t origin_x, size_t origin_y, size_t w, size_t void WorldBuilder::place_rooms() { for(auto &cur : $map.$rooms) { - cur.x += 2; - cur.y += 2; - cur.width -= 4; - cur.height -= 4; + cur.x += WORLDBUILD_SHRINK; + cur.y += WORLDBUILD_SHRINK; + cur.width -= WORLDBUILD_SHRINK * 2; + cur.height -= WORLDBUILD_SHRINK * 2; - // BUG: should I do this each time I connect rooms - // BUG: rather than once when the room is created? add_door(cur); make_room(cur.x, cur.y, cur.width, cur.height); } @@ -187,7 +184,7 @@ bool WorldBuilder::dig_tunnel(PointList &holes, Point &src, Point &target) { if(paths[out.y][out.x] == 0) { return true; } - } while(found && ++count < 200); + } while(found && ++count < WORLDBUILD_MAX_PATH); return false; }