#pragma once #include #include #include #include #include #include #include "point.hpp" #include "tser.hpp" #define INV_WALL 0 #define INV_SPACE 1 #define WALL_VALUE 1 #define SPACE_VALUE 0 struct Room { size_t x = 0; size_t y = 0; size_t width = 0; size_t height = 0; Point entry; Point exit; DEFINE_SERIALIZABLE(Room, x, y, width, height); }; typedef std::vector MatrixRow; typedef std::vector Matrix; void dump_map(const std::string &msg, Matrix &map); void add_neighbors(Matrix &closed, size_t j, size_t i); class Map { public: Matrix $input_map; Matrix $walls; Matrix $paths; std::vector $rooms; int $limit = 0; // make explicit Map(Matrix input_map, Matrix walls_map, int limit) : $input_map(input_map), $walls(walls_map), $limit(limit) { } // make random Map(size_t width, size_t height); // disable copying Map(Map &map) = delete; Matrix& paths() { return $paths; } Matrix& input_map() { return $input_map; } Matrix& walls() { return $walls; } int limit() { return $limit; } size_t width() { return $walls[0].size(); } size_t height() { return $walls.size(); } int distance(Point to) { return $paths[to.y][to.x]; } Room &room(size_t at) { return $rooms[at]; } size_t room_count() { return $rooms.size(); } void make_room(size_t origin_y, size_t origin_x, size_t width, size_t height); void add_door(Room &room); bool inmap(size_t x, size_t y); bool iswall(size_t x, size_t y); bool can_move(Point move_to) { return inmap(move_to.x, move_to.y) && !iswall(move_to.x, move_to.y); } bool neighbors(Point &out, bool up); void generate(); void place_rooms(Room &root); void make_paths(); void partition_map(Room &cur, int depth); void set_target(const Point &at, int value=0); void clear_target(const Point &at); bool walk(Point &src, Point &target); void set_door(Room &room, int value); void dump(); Point place_entity(size_t room_index); Point map_to_camera(const Point &loc, const Point &cam_orig) { return {loc.x - cam_orig.x, loc.y - cam_orig.y}; } Point center_camera(const Point &around, size_t view_x, size_t view_y) { int high_x = int(width() - view_x); int high_y = int(height() - view_y); int center_x = int(around.x - view_x / 2); int center_y = int(around.y - view_y / 2); // BUG: is clamp really the best thing here? this seems wrong. size_t start_x = high_x > 0 ? std::clamp(center_x, 0, high_x) : 0; size_t start_y = high_y > 0 ? std::clamp(center_y, 0, high_y) : 0; return {start_x, start_y}; } };