The next little game in the series where I make a fancy rogue game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
roguish/map.hpp

108 lines
2.6 KiB

#pragma once
#include <vector>
#include <utility>
#include <string>
#include <random>
#include <algorithm>
#include <fmt/core.h>
#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<int> MatrixRow;
typedef std::vector<MatrixRow> 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<Room> $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};
}
};