Compare commits
2 commits
96a5a37733
...
1f6be6b92b
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f6be6b92b | ||
![]() |
a55e08e1cc |
|
@ -10,6 +10,10 @@ enum Directions : unsigned short {
|
||||||
WEST = 0x8,
|
WEST = 0x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define casel(M_switch, M_case)\
|
||||||
|
case M_case:\
|
||||||
|
M_switch##_case_##M_case
|
||||||
|
|
||||||
typedef SDL_Point Tile;
|
typedef SDL_Point Tile;
|
||||||
typedef SDL_Point Chunk;
|
typedef SDL_Point Chunk;
|
||||||
typedef unsigned Sprite;
|
typedef unsigned Sprite;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "core/roguedefs.h"
|
#include "core/roguedefs.h"
|
||||||
#include <SDL2/SDL_log.h>
|
#include <SDL2/SDL_log.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace rogue {
|
namespace rogue {
|
||||||
|
@ -123,23 +124,83 @@ std::unique_ptr<World> WorldGenerator::generate() {
|
||||||
assert(this->min_room_size < this->max_room_size && "Room size is required to generate world");
|
assert(this->min_room_size < this->max_room_size && "Room size is required to generate world");
|
||||||
assert(this->world_side_length > 0 && "World size is required to generate world");
|
assert(this->world_side_length > 0 && "World size is required to generate world");
|
||||||
assert(this->player.has_value() && "World cannot be generated without a player");
|
assert(this->player.has_value() && "World cannot be generated without a player");
|
||||||
|
|
||||||
std::unique_ptr<World> world{new World()};
|
std::unique_ptr<World> world{new World()};
|
||||||
|
Chunk start_room{this->select_start()};
|
||||||
|
this->setup_player(world, start_room);
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
Chunk WorldGenerator::select_start() const {
|
||||||
|
Chunk start{0, 0};
|
||||||
|
switch(std::rand() % 4) {
|
||||||
|
case 0:
|
||||||
|
start.y = this->world_side_length - 1;
|
||||||
|
case 1:
|
||||||
|
start.x = std::rand() % this->world_side_length;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
start.x = this->world_side_length - 1;
|
||||||
|
case 3:
|
||||||
|
start.y = std::rand() % this->world_side_length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldGenerator::generate_world(std::unique_ptr<World> &world, Chunk start) {
|
||||||
|
world->chunk_size = this->chunk_side_length;
|
||||||
|
world->shear = this->world_side_length;
|
||||||
|
world->rooms.resize(this->world_side_length * this->world_side_length);
|
||||||
|
for(Room &room : world->rooms) {
|
||||||
|
room = Room{
|
||||||
|
.hallway_paths = Directions(0x0),
|
||||||
|
.chunk_size = this->chunk_side_length,
|
||||||
|
.rect = {
|
||||||
|
(this->chunk_side_length - this->max_room_size) / 2,
|
||||||
|
(this->chunk_side_length - this->max_room_size) / 2,
|
||||||
|
this->max_room_size,
|
||||||
|
this->max_room_size
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
world->get_room(start).initialized = true;
|
||||||
|
this->generate_room(world, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldGenerator::generate_room(std::unique_ptr<World> &world, Chunk last) {
|
||||||
|
static const Chunk options[]{
|
||||||
|
{last.x + 1, last.y},
|
||||||
|
{last.x - 1, last.y},
|
||||||
|
{last.x, last.y + 1},
|
||||||
|
{last.x, last.y - 1}
|
||||||
|
};
|
||||||
|
static const Directions directions[]{
|
||||||
|
EAST, WEST, SOUTH, NORTH
|
||||||
|
};
|
||||||
|
for(size_t i{0}; i < 4; ++i) {
|
||||||
|
Chunk next{options[i]};
|
||||||
|
Room &option{world->get_room(next)};
|
||||||
|
if(options[i].x < 0 || options[i].x >= this->world_side_length
|
||||||
|
|| options[i].y < 0 || options[i].y >= this->world_side_length) {
|
||||||
|
continue;
|
||||||
|
} else if(option.initialized) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// register hallway with the last chunk
|
||||||
|
option.hallway_paths = Directions(option.hallway_paths | directions[i]);
|
||||||
|
// generate random rect that encloses center of chunk
|
||||||
|
// add hallway to the new chunk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldGenerator::setup_player(std::unique_ptr<World> &world, Chunk spawn_chunk) {
|
||||||
world->characters.push_back(player.value());
|
world->characters.push_back(player.value());
|
||||||
world->player = &world->characters[0];
|
world->player = &world->characters[0];
|
||||||
world->player->world = world.get();
|
world->player->world = world.get();
|
||||||
world->chunk_size = this->chunk_side_length;
|
world->player->location = {
|
||||||
world->shear = this->world_side_length;
|
(spawn_chunk.x * this->chunk_side_length) + (this->chunk_side_length / 2),
|
||||||
world->rooms.reserve(this->world_side_length * this->world_side_length);
|
(spawn_chunk.y * this->chunk_side_length) + (this->chunk_side_length / 2),
|
||||||
world->rooms.push_back(Room {
|
};
|
||||||
.hallway_paths = Directions(Directions::NORTH | Directions::EAST),
|
|
||||||
.chunk_size = this->chunk_side_length,
|
|
||||||
.rect = {
|
|
||||||
(this->chunk_side_length - this->max_room_size) / 2,
|
|
||||||
(this->chunk_side_length - this->max_room_size) / 2,
|
|
||||||
this->max_room_size,
|
|
||||||
this->max_room_size
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return world;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct Room {
|
||||||
// bitmask of hallways
|
// bitmask of hallways
|
||||||
Directions hallway_paths{0};
|
Directions hallway_paths{0};
|
||||||
int chunk_size{0};
|
int chunk_size{0};
|
||||||
|
bool initialized{false};
|
||||||
// the starting tile and length of the walls
|
// the starting tile and length of the walls
|
||||||
SDL_Rect rect{0, 0, 1, 1};
|
SDL_Rect rect{0, 0, 1, 1};
|
||||||
void draw(Tile pivot);
|
void draw(Tile pivot);
|
||||||
|
@ -53,6 +54,11 @@ public:
|
||||||
WorldGenerator &with_room_size(unsigned min_side_length, unsigned max_side_length);
|
WorldGenerator &with_room_size(unsigned min_side_length, unsigned max_side_length);
|
||||||
WorldGenerator &with_player(Character character);
|
WorldGenerator &with_player(Character character);
|
||||||
std::unique_ptr<World> generate();
|
std::unique_ptr<World> generate();
|
||||||
|
private:
|
||||||
|
Chunk select_start() const;
|
||||||
|
void generate_world(std::unique_ptr<World> &world, Chunk start);
|
||||||
|
void generate_room(std::unique_ptr<World> &world, Chunk last);
|
||||||
|
void setup_player(std::unique_ptr<World> &world, Chunk spawn_chunk);
|
||||||
private:
|
private:
|
||||||
std::optional<Character> player;
|
std::optional<Character> player;
|
||||||
int chunk_side_length{0}, world_side_length{0};
|
int chunk_side_length{0}, world_side_length{0};
|
||||||
|
|
Loading…
Reference in a new issue