Maze works well now and there's something placed in all rooms and dead ends. Will need to randomize it more so not every dead end is an enemy.

master
Zed A. Shaw 2 weeks ago
parent a0b785cb2a
commit ac252bf09d
  1. 1
      assets/config.json
  2. 2
      assets/devices.json
  3. 2
      assets/items.json
  4. 3
      map.hpp
  5. 2
      maze.cpp
  6. 107
      worldbuilder.cpp
  7. 4
      worldbuilder.hpp

@ -323,7 +323,6 @@
},
"worldgen": {
"enemy_probability": 50,
"empty_room_probability": 1,
"device_probability": 10
},
"graphics": {

@ -40,7 +40,7 @@
"description": "Watch where you're going.",
"inventory_count": 0,
"components": [
{"_type": "Tile", "display": 6855,
{"_type": "Tile", "display": 95,
"foreground": [24, 205, 189],
"background": [24, 205, 189]
},

@ -34,7 +34,7 @@
"name": "Small Barrel",
"description": "A small rotten barrel that may hold things.",
"components": [
{"_type": "Tile", "display": 43754,
{"_type": "Tile", "display": 85,
"foreground": [150, 100, 189],
"background": [150, 100, 189]
},

@ -19,8 +19,6 @@ struct Room {
size_t y = 0;
size_t width = 0;
size_t height = 0;
Point entry{(size_t)-1, (size_t)-1};
Point exit{(size_t)-1, (size_t)-1};
};
class Map {
@ -31,6 +29,7 @@ public:
Matrix $walls;
Pathing $paths;
std::vector<Room> $rooms;
std::vector<Point> $dead_ends;
Map(size_t width, size_t height);

@ -28,7 +28,6 @@ inline bool complete(Matrix& maze) {
}
}
// dbc::sentinel("LOL it's complete eh?");
return true;
}
@ -136,6 +135,7 @@ void maze::hunt_and_kill(Matrix& maze, std::vector<Room>& rooms, std::vector<Poi
for(auto& room : rooms) {
Point room_ul{room.x - room.width - 1, room.y - room.height - 1};
Point room_lr{room.x + room.width - 1, room.y + room.height - 1};
if(at.x >= room_ul.x && at.y >= room_ul.y &&
at.x <= room_lr.x && at.y <= room_lr.y)
{

@ -10,70 +10,28 @@
using namespace fmt;
using namespace components;
inline int make_split(Room &cur, bool horiz) {
size_t dimension = horiz ? cur.height : cur.width;
int min = dimension / WORLDBUILD_DIVISION;
int max = dimension - min;
return Random::uniform<int>(min, max);
}
void rand_side(Room &room, Point &door) {
dbc::check(int(room.width) > 0 && int(room.height) > 0, "Weird room with 0 for height or width.");
int rand_x = Random::uniform<int>(0, room.width - 1);
int rand_y = Random::uniform<int>(0, room.height - 1);
switch(Random::uniform<int>(0,3)) {
case 0: // north
door.x = room.x + rand_x;
door.y = room.y-1;
break;
case 1: // south
door.x = room.x + rand_x;
door.y = room.y + room.height;
break;
case 2: // east
door.x = room.x + room.width;
door.y = room.y + rand_y;
break;
case 3: // west
door.x = room.x - 1;
door.y = room.y + rand_y;
break;
default:
dbc::sentinel("impossible side");
}
}
void WorldBuilder::add_door(Room &room) {
rand_side(room, room.entry);
rand_side(room, room.exit);
}
void WorldBuilder::generate_map() {
std::vector<Point> dead_ends;
maze::hunt_and_kill($map.$walls, $map.$rooms, dead_ends);
// run it once to find dead ends
maze::hunt_and_kill($map.$walls, $map.$rooms, $map.$dead_ends);
for(auto at : dead_ends) {
// use those dead ends to randomly place rooms
for(auto at : $map.$dead_ends) {
if(Random::uniform(0,1)) {
Room cur{at.x, at.y, 2, 2};
add_door(cur);
$map.add_room(cur);
}
}
maze::hunt_and_kill($map.$walls, $map.$rooms, dead_ends);
// run it again to create the final map with rooms
// NOTE: hund_and_kill is responsible for clearing the map correctly
maze::hunt_and_kill($map.$walls, $map.$rooms, $map.$dead_ends);
$map.expand();
$map.load_tiles();
}
DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, json &entity_data, int in_room) {
DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, json &entity_data, Point pos_out) {
auto item = world.entity();
Point pos_out;
bool placed = $map.place_entity(in_room, pos_out);
dbc::check(placed, "failed to randomly place item in room");
world.set<Position>(item, {pos_out.x+1, pos_out.y+1});
if(entity_data["inventory_count"] > 0) {
@ -86,6 +44,14 @@ DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, j
return item;
}
DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, json &entity_data, int in_room) {
Point pos_out;
bool placed = $map.place_entity(in_room, pos_out);
dbc::check(placed, "failed to randomly place item in room");
return configure_entity_in_map(world, entity_data, pos_out);
}
inline json &select_entity_type(GameConfig &config, json &gen_config) {
int enemy_test = Random::uniform<int>(0,100);
int device_test = Random::uniform<int>(0, 100);
@ -99,32 +65,37 @@ inline json &select_entity_type(GameConfig &config, json &gen_config) {
}
}
void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config) {
auto &gen_config = config.game["worldgen"];
for(size_t room_num = $map.room_count() - 1; room_num > 0; room_num--) {
int empty_room = Random::uniform<int>(0, 100);
if(empty_room < gen_config["empty_room_probability"]) continue;
json& entity_db = select_entity_type(config, gen_config);
inline json& random_entity_data(GameConfig& config, json& gen_config) {
json& entity_db = select_entity_type(config, gen_config);
std::vector<std::string> keys;
for(auto& el : entity_db.items()) {
auto& data = el.value();
std::vector<std::string> keys;
for(auto& el : entity_db.items()) {
auto& data = el.value();
if(data["placement"] == nullptr) {
keys.push_back(el.key());
}
if(data["placement"] == nullptr) {
keys.push_back(el.key());
}
}
int rand_entity = Random::uniform<int>(0, keys.size() - 1);
std::string key = keys[rand_entity];
// BUG: this may crash if PLAYER_TILE isn't first
return entity_db[key];
}
int rand_entity = Random::uniform<int>(0, keys.size() - 1);
std::string key = keys[rand_entity];
// BUG: this may crash if PLAYER_TILE isn't first
auto entity_data = entity_db[key];
void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config) {
auto& gen_config = config.game["worldgen"];
for(size_t room_num = $map.room_count() - 1; room_num > 0; room_num--) {
// pass that to the config as it'll be a generic json
auto& entity_data = random_entity_data(config, gen_config);
configure_entity_in_map(world, entity_data, room_num);
}
for(auto& at : $map.$dead_ends) {
auto& entity_data = random_entity_data(config, gen_config);
configure_entity_in_map(world, entity_data, at);
}
}
void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) {

@ -14,10 +14,12 @@ class WorldBuilder {
$components(components)
{ }
void add_door(Room &room);
void generate_map();
DinkyECS::Entity configure_entity_in_map(DinkyECS::World &world, nlohmann::json &entity_data, Point pos);
DinkyECS::Entity configure_entity_in_map(DinkyECS::World &world, nlohmann::json &entity_data, int in_room);
void place_entities(DinkyECS::World &world);
void generate(DinkyECS::World &world);
void randomize_entities(DinkyECS::World &world, components::GameConfig &config);

Loading…
Cancel
Save