From b16405cfdcb479346d7e4fd8816f6088530d86a1 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 13 Jan 2025 16:23:33 -0500 Subject: [PATCH] Better random entity placement and config of entities is now more generic. --- assets/enemies.json | 4 +++ assets/items.json | 24 +++++++++++++- constants.hpp | 4 ++- status.txt | 2 ++ worldbuilder.cpp | 76 ++++++++++++++++----------------------------- worldbuilder.hpp | 3 ++ 6 files changed, 62 insertions(+), 51 deletions(-) diff --git a/assets/enemies.json b/assets/enemies.json index 6693d80..b7e72d4 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -5,6 +5,7 @@ "components": [ {"type": "Tile", "config": {"chr": "\ua66b"}}, {"type": "Combat", "config": {"hp": 200, "damage": 15}}, + {"type": "Motion", "config": {"dx": 0, "dy": 0, "random": false}}, {"type": "EnemyConfig", "config": {"hearing_distance": 5}} ] }, @@ -14,6 +15,7 @@ "components": [ {"type": "Tile", "config": {"chr": "\u06b1"}}, {"type": "Combat", "config": {"hp": 20, "damage": 15}}, + {"type": "Motion", "config": {"dx": 0, "dy": 0, "random": false}}, {"type": "EnemyConfig", "config": {"hearing_distance": 6}} ] }, @@ -24,6 +26,7 @@ {"type": "LightSource", "config": {"strength": 70, "radius": 1.8}}, {"type": "Tile", "config": {"chr": "\u06bf"}}, {"type": "Combat", "config": {"hp": 50, "damage": 35}}, + {"type": "Motion", "config": {"dx": 0, "dy": 0, "random": false}}, {"type": "EnemyConfig", "config": {"hearing_distance": 4}} ] }, @@ -43,6 +46,7 @@ "components": [ {"type": "Tile", "config": {"chr": "\u08ac"}}, {"type": "Combat", "config": {"hp": 10, "damage": 5}}, + {"type": "Motion", "config": {"dx": 0, "dy": 0, "random": false}}, {"type": "EnemyConfig", "config": {"hearing_distance": 10}} ] } diff --git a/assets/items.json b/assets/items.json index a80a419..9ff75f4 100644 --- a/assets/items.json +++ b/assets/items.json @@ -7,7 +7,7 @@ "description": "A torch that barely lights the way. You wonder if it'd be better to not see the person who murders you.", "inventory_count": 1, "components": [ - {"type": "LightSource", "config": {"strength": 70, "radius": 2.0}}, + {"type": "LightSource", "config": {"strength": 100, "radius": 4.0}}, {"type": "Tile", "config": {"chr": "\u0f08"}} ] }, @@ -71,5 +71,27 @@ {"type": "Tile", "config": {"chr": "\u03eb"}}, {"type": "Curative", "config": {"hp": 20}} ] + }, + "STAIRS_DOWN": { + "id": "STAIRS_DOWN", + "name": "Stairs Down", + "foreground": [24, 205, 189], + "background": [24, 205, 189], + "description": "Stairs that go down further into the dungeon.", + "inventory_count": 0, + "components": [ + {"type": "Tile", "config": {"chr": "\u2ac5"}} + ] + }, + "STAIRS_UP": { + "id": "STAIRS_UP", + "name": "Stairs Up", + "foreground": [24, 205, 189], + "background": [24, 205, 189], + "description": "Stairs that go up, for the weak.", + "inventory_count": 0, + "components": [ + {"type": "Tile", "config": {"chr": "\u2259"}} + ] } } diff --git a/constants.hpp b/constants.hpp index 18854ac..70b19e6 100644 --- a/constants.hpp +++ b/constants.hpp @@ -25,7 +25,9 @@ const float PERCENT = 0.01f; const wchar_t BG_TILE = L'█'; const wchar_t UI_BASE_CHAR = L'█'; const int BG_BOX_OFFSET=5; -const int GAME_MAP_X=40; + +// NOTE: max seems to be about x=240, y=120 +const int GAME_MAP_X=80; const int GAME_MAP_Y=40; const int INVENTORY_PIXEL_X=50; const int INVENTORY_PIXEL_Y=50; diff --git a/status.txt b/status.txt index fd0e2f1..6ebf0b7 100644 --- a/status.txt +++ b/status.txt @@ -1,5 +1,7 @@ TODAY'S GOAL: +* Stairs \u2ac5 for stairs down, and \u2259 stairs up + * UNKNOWN COLLISION TYPE 6 * Either reduce the amount of size_t or use amit's suggestion of 0u since small sized unsigned can be casted to size_t. diff --git a/worldbuilder.cpp b/worldbuilder.cpp index 96d4efb..8a3a5b2 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -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(); +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(item, {pos_out.x+1, pos_out.y+1}); - if(item_data["inventory_count"] > 0) { - world.set(item, {item_data["inventory_count"], item_data}); + if(entity_data["inventory_count"] > 0) { + world.set(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(); - 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(enemy, {pos}); - - if(enemy_data.contains("components")) { - components::configure(world, enemy, enemy_data); - } +void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config) { + int rand_type = Random::uniform(0,1); + json entity_db = rand_type == 0 ? config.enemies.json() : config.items.json(); - if(!world.has(enemy)) { - world.set(enemy, {0,0}); + std::vector keys; + for(auto &el : entity_db.items()) { + keys.push_back(el.key()); } - return enemy; + for(size_t room_num = $map.room_count() - 1; room_num > 0; room_num--) { + int has_entity = Random::uniform(0, 1); + + if(has_entity == 0) { + int rand_entity = Random::uniform(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(); // 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); world.set(player.entity, {50,1.0}); world.set(player.entity, {5}); - { - std::vector 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 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(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) { diff --git a/worldbuilder.hpp b/worldbuilder.hpp index cd661fc..dad04f6 100644 --- a/worldbuilder.hpp +++ b/worldbuilder.hpp @@ -2,6 +2,7 @@ #include "map.hpp" #include "dinkyecs.hpp" +#include "components.hpp" class WorldBuilder { public: @@ -21,4 +22,6 @@ class WorldBuilder { void generate_map(); void place_entities(DinkyECS::World &world); void generate(DinkyECS::World &world); + void random_entity(DinkyECS::World &world, components::GameConfig &config); + void randomize_entities(DinkyECS::World &world, components::GameConfig &config); };