Fixed up the map generator so that it's placing entities in non-overlapping tiles and adapting the style for the size. It can also deal with maps that have no rooms better and places the stairs better.

This commit is contained in:
Zed A. Shaw 2025-05-22 12:24:59 -04:00
parent 5f1a453fb4
commit 4eaf3c35d6
11 changed files with 55 additions and 45 deletions

View file

@ -12,21 +12,41 @@ using namespace components;
void WorldBuilder::generate_map() {
maze::Builder maze($map);
size_t x_diff = $map.width() / 4;
size_t y_diff = $map.height() / 4;
maze.divide({x_diff, y_diff}, {$map.width() - x_diff, $map.height() - y_diff});
maze.hunt_and_kill();
maze.randomize_rooms();
dbc::check($map.$dead_ends.size() > 0, "world builder/maze builder made a map with no dead ends.");
if($map.width() > 20) {
maze.inner_box(4, 2);
}
maze.hunt_and_kill();
$map.expand();
$map.load_tiles();
}
DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, json &entity_data, Point pos_out) {
bool WorldBuilder::find_open_spot(Point& pos_out) {
// NOTE: still spawning near a player but not sure if this is the place
// to solve that. Idea: Get the player, don't place anything too close.
for(matrix::rando_rect it{$map.walls(), pos_out.x, pos_out.y, 3}; it.next();) {
Point test{size_t(it.x), size_t(it.y)};
if($map.can_move(test) && !$collision.occupied(test)) {
pos_out = test;
return true;
}
}
return false;
}
DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, json &entity_data, Point pos) {
bool found = find_open_spot(pos);
dbc::check(found, "Failed to find a place for this thing.");
auto item = world.entity();
world.set<Position>(item, {pos_out.x+1, pos_out.y+1});
world.set<Position>(item, {pos.x, pos.y});
if(entity_data["inventory_count"] > 0) {
world.set<InventoryItem>(item, {entity_data["inventory_count"], entity_data});
@ -36,6 +56,8 @@ DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, j
components::configure_entity($components, world, item, entity_data["components"]);
}
$collision.insert(pos, item);
return item;
}
@ -97,8 +119,9 @@ void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config
void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) {
auto& device_config = config.devices.json();
auto entity_data = device_config["STAIRS_DOWN"];
int last_room = $map.room_count() - 1;
configure_entity_in_room(world, entity_data, last_room);
auto at_end = $map.$dead_ends.back();
configure_entity_in_map(world, entity_data, at_end);
}
void WorldBuilder::configure_starting_items(DinkyECS::World &world) {