Better random entity placement and config of entities is now more generic.

This commit is contained in:
Zed A. Shaw 2025-01-13 16:23:33 -05:00
parent 641a405a06
commit b16405cfdc
6 changed files with 61 additions and 50 deletions

View file

@ -168,83 +168,61 @@ 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>();
DinkyECS::Entity configure_entity_in_map(DinkyECS::World &world, Map &game_map, json &entity_data, int in_room) {
auto item = world.entity();
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_out.x+1, pos_out.y+1});
if(item_data["inventory_count"] > 0) {
world.set<InventoryItem>(item, {item_data["inventory_count"], item_data});
if(entity_data["inventory_count"] > 0) {
world.set<InventoryItem>(item, {entity_data["inventory_count"], entity_data});
}
if(item_data.contains("components")) {
components::configure(world, item, item_data);
if(entity_data.contains("components")) {
components::configure(world, item, entity_data);
}
return item;
}
DinkyECS::Entity place_combatant(DinkyECS::World &world, Map &game_map, std::string name, int in_room) {
auto &config = world.get_the<GameConfig>();
auto enemy = world.entity();
auto enemy_data = config.enemies[name];
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});
void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config) {
int rand_type = Random::uniform<int>(0,1);
json entity_db = rand_type == 0 ? config.enemies.json() : config.items.json();
if(enemy_data.contains("components")) {
components::configure(world, enemy, enemy_data);
std::vector<std::string> keys;
for(auto &el : entity_db.items()) {
keys.push_back(el.key());
}
if(!world.has<Motion>(enemy)) {
world.set<Motion>(enemy, {0,0});
}
for(size_t room_num = $map.room_count() - 1; room_num > 0; room_num--) {
int has_entity = Random::uniform<int>(0, 1);
return enemy;
if(has_entity == 0) {
int rand_entity = Random::uniform<int>(0, keys.size() - 1);
std::string key = keys[rand_entity];
auto entity_data = entity_db[key];
// pass that to the config as it'll be a generic json
auto entity = configure_entity_in_map(world, $map, entity_data, room_num);
(void)entity;
}
}
}
void WorldBuilder::place_entities(DinkyECS::World &world) {
auto &config = world.get_the<GameConfig>();
// configure a player as a fact of the world
auto player_ent = place_combatant(world, $map, "PLAYER_TILE", 0);
auto player_data = config.enemies["PLAYER_TILE"];
auto player_ent = configure_entity_in_map(world, $map, player_data, 0);
// configure player in the world
Player player{player_ent};
world.set_the<Player>(player);
world.set<LightSource>(player.entity, {50,1.0});
world.set<Inventory>(player.entity, {5});
{
std::vector<std::string> keys;
for(auto &el : config.items.json().items()) {
keys.push_back(el.key());
}
for(size_t room_num = 1; room_num < $map.room_count(); room_num++) {
std::string key = keys[room_num % keys.size()];
place_item(world, $map, key, room_num);
}
}
{
std::vector<std::string> keys;
for(auto &el : config.enemies.json().items()) {
keys.push_back(el.key());
}
for(size_t room_num = $map.room_count() - 1; room_num > 0; room_num--) {
int has_combatant = Random::uniform<int>(0, 3);
if(has_combatant == 0) {
std::string key = keys[room_num % keys.size()];
place_combatant(world, $map, key, room_num);
}
}
}
randomize_entities(world, config);
}
void WorldBuilder::generate(DinkyECS::World &world) {