diff --git a/assets/items.json b/assets/items.json new file mode 100644 index 0000000..153d318 --- /dev/null +++ b/assets/items.json @@ -0,0 +1,22 @@ +{ + "TORCH": { + "foreground": [24, 205, 189], + "background": [230, 20, 120], + "display": "\u0f08" + }, + "SWORD": { + "foreground": [24, 205, 189], + "background": [24, 205, 189], + "display":"\u1e37" + }, + "CHEST": { + "foreground": [24, 205, 189], + "background": [24, 205, 189], + "display":"\uaaea" + }, + "WALL_TORCH": { + "foreground": [24, 205, 189], + "background": [24, 205, 189], + "display": "☀" + } +} diff --git a/assets/tiles.json b/assets/tiles.json index cd93831..0ee6792 100644 --- a/assets/tiles.json +++ b/assets/tiles.json @@ -56,7 +56,7 @@ "BROKEN_TILE": { "foreground": [159, 164, 15], "background": [199, 15, 79], - "collision": false, + "collision": true, "display":"\u2274" } } diff --git a/combat.hpp b/combat.hpp index fa8f887..c50f6de 100644 --- a/combat.hpp +++ b/combat.hpp @@ -6,7 +6,7 @@ namespace components { int damage; /* NOTE: This is used to _mark_ entities as dead, to detect ones that have just died. Don't make attack automatically set it.*/ - bool dead; + bool dead = false; int attack(Combat &target); }; diff --git a/components.hpp b/components.hpp index 3e4bbb4..5d0ce74 100644 --- a/components.hpp +++ b/components.hpp @@ -29,7 +29,8 @@ namespace components { struct Inventory { int gold; - DEFINE_SERIALIZABLE(Inventory, gold); + LightSource light; + DEFINE_SERIALIZABLE(Inventory, gold, light); }; struct Tile { @@ -37,9 +38,11 @@ namespace components { DEFINE_SERIALIZABLE(Tile, chr); }; - struct MapConfig { - std::string PLAYER_TILE; - std::string ENEMY_TILE; + struct GameConfig { + Config game; + Config enemies; + Config items; + Config tiles; }; struct EnemyConfig { @@ -50,4 +53,8 @@ namespace components { bool PATHS=false; bool LIGHT=false; }; + + struct Weapon { + int damage = 0; + }; } diff --git a/config.cpp b/config.cpp index 7d169af..d5fccb4 100644 --- a/config.cpp +++ b/config.cpp @@ -1,6 +1,9 @@ #include "config.hpp" +#include "dbc.hpp" +#include using nlohmann::json; +using fmt::format; Config::Config(const std::string src_path) : $src_path(src_path) { std::ifstream infile($src_path); @@ -8,6 +11,7 @@ Config::Config(const std::string src_path) : $src_path(src_path) { } json &Config::operator[](const std::string &key) { + dbc::check($config.contains(key), format("ERROR in config, key {} doesn't exist.", key)); return $config[key]; } diff --git a/gui.cpp b/gui.cpp index aaeca80..39ae4eb 100644 --- a/gui.cpp +++ b/gui.cpp @@ -52,6 +52,7 @@ void StatusUI::create_render() { auto status_rend = Renderer([&, player]{ const auto& player_combat = $world.get(player.entity); const auto& inventory = $world.get(player.entity); + const auto& combat = $world.get(player.entity); $status_text = player_combat.hp > 0 ? "NOT DEAD" : "DEAD!!!!!!"; std::vector log_list; @@ -64,8 +65,10 @@ void StatusUI::create_render() { return hbox({ hflow( vbox( - text(format("HP: {: >3} GOLD: {: >3}", - player_combat.hp, inventory.gold)) | border, + text(format("HP: {: >3} GOLD: {: >3} DMG: {: >3}", + player_combat.hp, + inventory.gold, + combat.damage)) | border, text($status_text) | border, separator(), log_box diff --git a/gui.hpp b/gui.hpp index 88d67a9..facfaea 100644 --- a/gui.hpp +++ b/gui.hpp @@ -40,7 +40,6 @@ struct UnDumbTSS { sf::Sprite sprite; sf::Shader shader; - sf::Shader& load_shader(string filename) { bool good = shader.loadFromFile(filename, sf::Shader::Fragment); dbc::check(good, "shader could not be loaded"); diff --git a/main.cpp b/main.cpp index e91f2c6..e348355 100644 --- a/main.cpp +++ b/main.cpp @@ -24,7 +24,7 @@ namespace fs = std::filesystem; * system. */ void configure_world(DinkyECS::World &world, Map &game_map) { - const auto &config = world.get_the(); + auto &config = world.get_the(); // configure a player as a fact of the world Player player{world.entity()}; world.set_the(player); @@ -32,7 +32,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(player.entity, {game_map.place_entity(0)}); world.set(player.entity, {0, 0}); world.set(player.entity, {100, 10}); - world.set(player.entity, {config.PLAYER_TILE}); + world.set(player.entity, {config.enemies["PLAYER_TILE"]["display"]}); world.set(player.entity, {5}); world.set(player.entity, {70,1.0}); @@ -40,24 +40,38 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(enemy, {game_map.place_entity(1)}); world.set(enemy, {0,0}); world.set(enemy, {20, 10}); - world.set(enemy, {config.ENEMY_TILE}); + world.set(enemy, {config.enemies["UNICORN"]["display"]}); auto enemy2 = world.entity(); world.set(enemy2, {game_map.place_entity(2)}); world.set(enemy2, {0,0}); world.set(enemy2, {20, 10}); - world.set(enemy2, {"*"}); + world.set(enemy2, {config.enemies["SNAKE"]["display"]}); world.set(enemy2, {60,0.2f}); auto gold = world.entity(); world.set(gold, {game_map.place_entity(3)}); world.set(gold, {100}); - world.set(gold, {"$"}); + world.set(gold, {config.items["CHEST"]["display"]}); auto wall_torch = world.entity(); world.set(wall_torch, {game_map.place_entity(4)}); world.set(wall_torch, {90,3.0f}); - world.set(wall_torch, {"☀"}); + world.set(wall_torch, {config.items["WALL_TORCH"]["display"]}); + + auto torch = world.entity(); + Point at = game_map.place_entity(2); + world.set(torch, {{at.x+1, at.y+1}}); + world.set(torch, {{0}}); + world.set(torch, {70,1.5f}); + world.set(torch, {config.items["TORCH"]["display"]}); + + auto sword = world.entity(); + at = game_map.place_entity(1); + world.set(sword, {at.x+1, at.y+1}); + world.set(sword, {.damage=20}); + world.set(sword, {{0}}); + world.set(sword, {config.items["SWORD"]["display"]}); } int main(int argc, char *argv[]) { diff --git a/save.cpp b/save.cpp index 9bf76f8..11ab79b 100644 --- a/save.cpp +++ b/save.cpp @@ -84,16 +84,16 @@ void save::from_file(fs::path path, DinkyECS::World &world_out, Map &map_out) { } void save::load_configs(DinkyECS::World &world) { - Config config("./assets/config.json"); + Config game("./assets/config.json"); Config enemies("./assets/enemies.json"); + Config items("./assets/items.json"); + Config tiles("./assets/tiles.json"); - world.set_the(config); - world.set_the({ - enemies["PLAYER_TILE"]["display"], - enemies["UNICORN"]["display"], + world.set_the({ + game, enemies, items, tiles }); - auto enemy = config["enemy"]; + auto enemy = game["enemy"]; world.set_the({ enemy["HEARING_DISTANCE"] }); diff --git a/status.txt b/status.txt index 65f1b56..74168b3 100644 --- a/status.txt +++ b/status.txt @@ -1,5 +1,7 @@ TODAY'S GOAL: +* Colision fails when you place two entities on the same square, but the init_positions adds them and one deletes the other. +* Config needs to do asserts that the key exists * Create a move function for iterators that recalculates their position to make it easy to move them inside the matrix. This can then be used in lighting. Just make an iterator once, and move it around after. * Components::Tile must also die. * MapConfig must die. diff --git a/systems.cpp b/systems.cpp index 9533b45..faab231 100644 --- a/systems.cpp +++ b/systems.cpp @@ -138,14 +138,25 @@ void System::collision(DinkyECS::World &world, Player &player) { auto loot = world.get(entity); auto &loot_pos = world.get(entity); auto &inventory = world.get(player.entity); - // BUG: this should go away and be a part of inventory - auto &light = world.get(player.entity); - world.send(Events::GUI::LOOT, entity, loot); - inventory.gold += loot.amount; - light.strength = 70; - light.radius = 2; + if(world.has(entity)) { + auto &new_light = world.get(entity); + world.set(player.entity, new_light); + inventory.light = new_light; + world.remove(entity); + } else if(world.has(entity)) { + auto &weapon = world.get(entity); + player_combat.damage = weapon.damage; + world.remove(entity); + } else { + // it's just gold + inventory.gold += loot.amount; + } + collider.remove(loot_pos.location); + world.remove(entity); + world.remove(entity); + world.send(Events::GUI::LOOT, entity, loot); } else { println("UNKNOWN COLLISION TYPE {}", entity); } @@ -153,7 +164,6 @@ void System::collision(DinkyECS::World &world, Player &player) { } } -// BUG: this is kind of massive, need to maybe rethink how systems are designed. I mean...can each system be a callable class instead? void System::draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &lighting, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) { auto &tiles = game_map.tiles(); diff --git a/tests/config.cpp b/tests/config.cpp index 1231107..df373ef 100644 --- a/tests/config.cpp +++ b/tests/config.cpp @@ -13,6 +13,8 @@ using std::string; TEST_CASE("basic configuration system", "[config]") { Config config("./tests/config.json"); + REQUIRE_THROWS([&]{ config["blahblah"]; }()); + auto not_found = config["types"]["NOTFOUND"]; REQUIRE(not_found == nullptr); diff --git a/tests/gui.cpp b/tests/gui.cpp index 8c00b57..f514e63 100644 --- a/tests/gui.cpp +++ b/tests/gui.cpp @@ -20,7 +20,7 @@ TEST_CASE("load a basic gui run but don't loop", "[gui]") { WorldBuilder builder(game_map); builder.generate(); - const auto &config = world.get_the(); + auto &config = world.get_the(); // configure a player as a fact of the world Player player{world.entity()}; world.set_the(player); @@ -28,7 +28,7 @@ TEST_CASE("load a basic gui run but don't loop", "[gui]") { world.set(player.entity, {game_map.place_entity(0)}); world.set(player.entity, {0, 0}); world.set(player.entity, {100, 10}); - world.set(player.entity, {config.PLAYER_TILE}); + world.set(player.entity, {config.enemies["PLAYER_TILE"]["display"]}); world.set(player.entity, {5}); world.set(player.entity, {6,1}); diff --git a/tests/sound.cpp b/tests/sound.cpp index 0c999d2..032bdc4 100644 --- a/tests/sound.cpp +++ b/tests/sound.cpp @@ -8,7 +8,7 @@ using DinkyECS::Entity; using namespace fmt; TEST_CASE("confirm basic functionality", "[sounds]") { - REQUIRE_THROWS([&](){SoundManager sounds("./BADassets");}()); + REQUIRE_THROWS([&]{SoundManager sounds("./BADassets");}()); SoundManager sounds("./assets"); diff --git a/worldbuilder.cpp b/worldbuilder.cpp index c5a2b8c..68b3763 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -164,7 +164,6 @@ void WorldBuilder::generate() { string tile_name = room_types[room_type]; stylize_room(i, tile_name, room_size * 0.01f); } - } void WorldBuilder::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) {