Mostly cleaned up world get to handle more rooms and paths, but rando_rect needs to be actually random.
This commit is contained in:
parent
c19c53b15b
commit
e9277bf052
11 changed files with 257 additions and 39 deletions
|
@ -53,9 +53,10 @@ void WorldBuilder::add_door(Room &room) {
|
|||
}
|
||||
|
||||
void WorldBuilder::partition_map(Room &cur, int depth) {
|
||||
if(cur.width >= 5 && cur.width <= 10 &&
|
||||
cur.height >= 5 && cur.height <= 10) {
|
||||
$map.$rooms.push_back(cur);
|
||||
if(cur.width >= 3 && cur.width <= 6 &&
|
||||
cur.height >= 3 && cur.height <= 6)
|
||||
{
|
||||
$map.add_room(cur);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -97,9 +98,11 @@ void WorldBuilder::update_door(Point &at, int wall_or_space) {
|
|||
|
||||
|
||||
void WorldBuilder::stylize_room(int room, string tile_name, float size) {
|
||||
Point center = $map.place_entity(room);
|
||||
Point pos_out;
|
||||
bool placed = $map.place_entity(room, pos_out);
|
||||
dbc::check(placed, "failed to place style in room");
|
||||
|
||||
for(matrix::circle it{$map.$walls, center, size}; it.next();) {
|
||||
for(matrix::circle it{$map.$walls, pos_out, size}; it.next();) {
|
||||
for(int x = it.left; x < it.right; x++) {
|
||||
if(!$map.iswall(x, it.y)) {
|
||||
$map.$tiles.set_tile(x, it.y, tile_name);
|
||||
|
@ -108,22 +111,24 @@ void WorldBuilder::stylize_room(int room, string tile_name, float size) {
|
|||
}
|
||||
}
|
||||
|
||||
void WorldBuilder::generate_map() {
|
||||
PointList holes;
|
||||
void WorldBuilder::generate_rooms() {
|
||||
Room root{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = $map.$width,
|
||||
.height = $map.$height
|
||||
};
|
||||
|
||||
// BUG: depth should be configurable
|
||||
partition_map(root, 10);
|
||||
|
||||
place_rooms();
|
||||
|
||||
dbc::check($map.room_count() > 0, "map generated zero rooms, map too small?");
|
||||
}
|
||||
|
||||
void WorldBuilder::generate_map() {
|
||||
generate_rooms();
|
||||
|
||||
PointList holes;
|
||||
for(size_t i = 0; i < $map.$rooms.size() - 1; i++) {
|
||||
tunnel_doors(holes, $map.$rooms[i], $map.$rooms[i+1]);
|
||||
}
|
||||
|
@ -133,14 +138,21 @@ void WorldBuilder::generate_map() {
|
|||
|
||||
// place all the holes
|
||||
for(auto hole : holes) {
|
||||
|
||||
if(!matrix::inbounds($map.$walls, hole.x, hole.y)) {
|
||||
matrix::dump("MAP BEFORE CRASH", $map.$walls, hole.x, hole.y);
|
||||
|
||||
auto err = fmt::format("invalid hold target {},{} map is only {},{}",
|
||||
hole.x, hole.y, matrix::width($map.$walls),
|
||||
matrix::height($map.$walls));
|
||||
|
||||
dbc::sentinel(err);
|
||||
}
|
||||
|
||||
$map.$walls[hole.y][hole.x] = INV_SPACE;
|
||||
}
|
||||
|
||||
for(matrix::each_cell it{$map.$walls}; it.next();) {
|
||||
int is_wall = !$map.$walls[it.y][it.x];
|
||||
$map.$walls[it.y][it.x] = is_wall;
|
||||
}
|
||||
|
||||
$map.invert_space();
|
||||
$map.expand();
|
||||
$map.load_tiles();
|
||||
|
||||
|
@ -159,9 +171,11 @@ void WorldBuilder::generate_map() {
|
|||
DinkyECS::Entity place_item(DinkyECS::World &world, Map &game_map, std::string name, int in_room) {
|
||||
auto &config = world.get_the<GameConfig>();
|
||||
auto item = world.entity();
|
||||
auto pos = game_map.place_entity(in_room);
|
||||
Point pos_out;
|
||||
bool placed = game_map.place_entity(in_room, pos_out);
|
||||
dbc::check(placed, "failed to randomly place item in room");
|
||||
json item_data = config.items[name];
|
||||
world.set<Position>(item, {pos.x+1, pos.y+1});
|
||||
world.set<Position>(item, {pos_out.x+1, pos_out.y+1});
|
||||
|
||||
if(item_data["inventory_count"] > 0) {
|
||||
world.set<InventoryItem>(item, {item_data["inventory_count"], item_data});
|
||||
|
@ -178,7 +192,9 @@ DinkyECS::Entity place_combatant(DinkyECS::World &world, Map &game_map, std::str
|
|||
auto &config = world.get_the<GameConfig>();
|
||||
auto enemy = world.entity();
|
||||
auto enemy_data = config.enemies[name];
|
||||
auto pos = game_map.place_entity(in_room);
|
||||
Point pos;
|
||||
bool placed = game_map.place_entity(in_room, pos);
|
||||
dbc::check(placed, "failed to place combatant in room");
|
||||
world.set<Position>(enemy, {pos});
|
||||
|
||||
if(enemy_data.contains("components")) {
|
||||
|
@ -250,11 +266,8 @@ void WorldBuilder::make_room(size_t origin_x, size_t origin_y, size_t w, size_t
|
|||
|
||||
void WorldBuilder::place_rooms() {
|
||||
for(auto &cur : $map.$rooms) {
|
||||
cur.x += WORLDBUILD_SHRINK;
|
||||
cur.y += WORLDBUILD_SHRINK;
|
||||
cur.width -= WORLDBUILD_SHRINK * 2;
|
||||
cur.height -= WORLDBUILD_SHRINK * 2;
|
||||
|
||||
// println("ROOM x/y={},{}; w/h={},{}; map={},{}",
|
||||
// cur.x, cur.y, cur.width, cur.height, $map.$width, $map.$height);
|
||||
add_door(cur);
|
||||
make_room(cur.x, cur.y, cur.width, cur.height);
|
||||
}
|
||||
|
@ -281,24 +294,34 @@ inline bool random_path(Map &map, PointList &holes, Point src, Point target) {
|
|||
return target_found;
|
||||
}
|
||||
|
||||
inline void straight_path(PointList &holes, Point src, Point target) {
|
||||
inline void straight_path(Map &map, PointList &holes, Point src, Point target) {
|
||||
for(matrix::line dig{src, target}; dig.next();) {
|
||||
holes.push_back({size_t(dig.x), size_t(dig.y)});
|
||||
holes.push_back({size_t(dig.x+1), size_t(dig.y)});
|
||||
Point expand{(size_t)dig.x+1, (size_t)dig.y};
|
||||
|
||||
if(map.inmap(expand.x, expand.y)) {
|
||||
// BUG? should really just move doors away from the edge
|
||||
holes.push_back(expand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldBuilder::tunnel_doors(PointList &holes, Room &src, Room &target) {
|
||||
int path_type = Random::uniform<int>(0, 3);
|
||||
|
||||
switch(path_type) {
|
||||
case 0:
|
||||
// for now do 25% as simple straight paths
|
||||
straight_path(holes, src.exit, target.entry);
|
||||
straight_path($map, holes, src.exit, target.entry);
|
||||
break;
|
||||
case 1:
|
||||
// for now do 25% as simple straight paths
|
||||
straight_path($map, holes, src.exit, target.entry);
|
||||
break;
|
||||
default:
|
||||
// then do the rest as random with fallback
|
||||
if(!random_path($map, holes, src.exit, target.entry)) {
|
||||
straight_path(holes, src.exit, target.entry);
|
||||
straight_path($map, holes, src.exit, target.entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue