Fixed maze cleanup, improved door placement
This commit is contained in:
parent
a83a60de0c
commit
6dab039298
1 changed files with 59 additions and 23 deletions
|
@ -14,6 +14,7 @@ struct Room {
|
|||
const char walltile = '#';
|
||||
const char floortile = '.';
|
||||
const char doortile = '+';
|
||||
const char testtile = ' ';
|
||||
|
||||
bool aabb(Room &a, Room &b) {
|
||||
return a.pos.x <= b.pos.x + b.size.x && a.pos.x + a.size.x >= b.pos.x &&
|
||||
|
@ -81,7 +82,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) {
|
|||
|
||||
// Room placement
|
||||
std::vector<Room> rooms;
|
||||
for (int i = 0; i < sqrt(width*height) * 6; i++) {
|
||||
for (int i = 0; i < sqrt(width*height); i++) {
|
||||
Room room;
|
||||
room.size = vec2i(rng.get_int(6, 12), rng.get_int(6, 12));
|
||||
room.pos = vec2i(rng.get_int(width - room.size.x), rng.get_int(height - room.size.y));
|
||||
|
@ -136,7 +137,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) {
|
|||
if (x == 0) {
|
||||
dx = -1;
|
||||
}
|
||||
else if (x == r.size.x) {
|
||||
else if (x == r.size.x-1) {
|
||||
dx = 1;
|
||||
}
|
||||
|
||||
|
@ -144,7 +145,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) {
|
|||
if (y == 0) {
|
||||
dy = -1;
|
||||
}
|
||||
else if (y == r.size.y) {
|
||||
else if (y == r.size.y-1) {
|
||||
dy = 1;
|
||||
}
|
||||
|
||||
|
@ -163,14 +164,22 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) {
|
|||
if (potential_doors.empty()) continue;
|
||||
|
||||
// Pick up to 3 spots and place doorss
|
||||
int doors_amount = potential_doors.size() < 3 ? potential_doors.size() : 3;
|
||||
doors_amount = rng.get_int(1, doors_amount);
|
||||
int doors_amount = potential_doors.size() < 3 ? potential_doors.size() : 4;
|
||||
doors_amount = rng.get_int(2, doors_amount);
|
||||
|
||||
for (int i = 0; i < doors_amount; i++) {
|
||||
//for (int i = 0; i < potential_doors.size(); i++) {
|
||||
if (potential_doors.empty()) break;
|
||||
|
||||
int r = rng.get_int(potential_doors.size()-1);
|
||||
vec2i pos = potential_doors.at(r);
|
||||
map.set_tile(pos.x, pos.y, doortile);
|
||||
potential_doors.erase(r + potential_doors.begin());
|
||||
for (int j = potential_doors.size() - 1; j >= 0; j--) {
|
||||
if ((pos - potential_doors[j]).dist() <= 4) {
|
||||
potential_doors.erase(j + potential_doors.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
@ -191,34 +200,61 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) {
|
|||
}
|
||||
}
|
||||
}
|
||||
int pass_amount = sqrt(width*height)*2;
|
||||
int pass_amount = 100;
|
||||
for (int pass = 0; pass < pass_amount; pass++) {
|
||||
if (dead_ends.empty()) break;
|
||||
std::vector<vec2i> new_dead_ends;
|
||||
for (vec2i pos : dead_ends) {
|
||||
map.set_tile(pos.x, pos.y, walltile);
|
||||
std::vector<vec2i> neigh { vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) };
|
||||
for (int i = neigh.size() - 1; i >= 0; i--) {
|
||||
vec2i p = neigh[i];
|
||||
if (map.get_tile(p.x, p.y) == walltile) {
|
||||
neigh.erase(neigh.begin() + i);
|
||||
int count = 0;
|
||||
vec2i next;
|
||||
for (vec2i n : neigh) {
|
||||
if (map.get_tile(n.x, n.y) == walltile) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
count++;
|
||||
next = n;
|
||||
}
|
||||
}
|
||||
if (neigh.size() == 1) {
|
||||
std::vector<vec2i> neigh2{ vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) };
|
||||
int count = 0;
|
||||
for (vec2i pos : neigh2) {
|
||||
if (map.get_tile(pos.x, pos.y) == walltile) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count >= neigh2.size() - 1) {
|
||||
new_dead_ends.emplace_back(vec2i(pos.x, pos.y));
|
||||
}
|
||||
if (count == 1) {
|
||||
map.set_tile(pos.x, pos.y, walltile);
|
||||
new_dead_ends.emplace_back(next);
|
||||
}
|
||||
else if (count == 0) {
|
||||
map.set_tile(pos.x, pos.y, walltile);
|
||||
}
|
||||
}
|
||||
dead_ends = new_dead_ends;
|
||||
}
|
||||
|
||||
|
||||
/* flood-fill the map to see that you can actually reach everywhere
|
||||
bool started = false;
|
||||
for (int x = 0; x < map.get_width(); x++) {
|
||||
for (int y = 0; y < map.get_height(); y++) {
|
||||
if (map.get_tile(x,y) == floortile) {
|
||||
std::vector<vec2i> stack{vec2i(x,y)};
|
||||
map.set_tile(x, y, testtile);
|
||||
while (!stack.empty()) {
|
||||
vec2i pos = stack.back();
|
||||
stack.pop_back();
|
||||
|
||||
auto neigh = map.get_neighbours(pos.x, pos.y);
|
||||
for (vec2i n : neigh) {
|
||||
char tile = map.get_tile(n.x, n.y);
|
||||
if (tile == floortile || tile == doortile) {
|
||||
map.set_tile(pos.x, pos.y, testtile);
|
||||
stack.emplace_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
started = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (started) break;
|
||||
}
|
||||
//*/
|
||||
return map;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue