diff --git a/components.hpp b/components.hpp index e66a14f..2775315 100644 --- a/components.hpp +++ b/components.hpp @@ -1,17 +1,23 @@ #pragma once -#include "dinkyecs.hpp" #include "components.hpp" -#include "constants.hpp" #include "config.hpp" -#include "dinky_components.hpp" +#include "constants.hpp" +#include "dinkyecs.hpp" #include "point.hpp" -#include #include +#include +#include +#include +#include + +#define ENROLL_COMPONENT(COMPONENT, ...) \ + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \ + template <> struct NameOf { \ + static constexpr const char *name = #COMPONENT; \ + }; namespace components { - struct Player { - DinkyECS::Entity entity; - }; + using namespace nlohmann; struct Position { Point location; @@ -104,7 +110,7 @@ namespace components { void step(sf::Vector2f& scale_out, sf::IntRect& rect_out); }; - void configure(ComponentMap& component_map); + template struct NameOf; // these need to be here if you're using components::convert outside of components.cpp ENROLL_COMPONENT(Tile, display, foreground, background); @@ -113,4 +119,42 @@ namespace components { ENROLL_COMPONENT(LightSource, strength, radius); ENROLL_COMPONENT(Weapon, damage); ENROLL_COMPONENT(Loot, amount); + + + using ReflFuncSignature = std::function; + using ComponentMap = std::unordered_map; + struct Player { + DinkyECS::Entity entity; + }; + + template COMPONENT convert(nlohmann::json &data) { + COMPONENT result; + from_json(data, result); + return result; + } + + template COMPONENT get(nlohmann::json &data) { + for (auto &i : data["components"]) { + if(i["_type"] == NameOf::name) { + COMPONENT result; + from_json(i, result); + return result; + } + } + + return {}; + } + + template void enroll(ComponentMap &m) { + m[NameOf::name] = [](DinkyECS::World& world, DinkyECS::Entity ent, nlohmann::json &j) { + COMPONENT c; + from_json(j, c); + world.set(ent, c); + }; + } + + void configure(ComponentMap& component_map); + + void configure_entity(const ComponentMap& component_map, DinkyECS::World& world, DinkyECS::Entity ent, json& data); + } diff --git a/dinky_components.hpp b/dinky_components.hpp deleted file mode 100644 index f894edb..0000000 --- a/dinky_components.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include -#include -#include -#include "dinkyecs.hpp" - -#define ENROLL_COMPONENT(COMPONENT, ...) \ - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \ - template <> struct NameOf { \ - static constexpr const char *name = #COMPONENT; \ - }; - -namespace components { - using namespace nlohmann; - - template struct NameOf; - - using ReflFuncSignature = std::function; - using ComponentMap = std::unordered_map; - - template COMPONENT convert(nlohmann::json &data) { - COMPONENT result; - from_json(data, result); - return result; - } - - template COMPONENT get(nlohmann::json &data) { - for (auto &i : data["components"]) { - if(i["_type"] == NameOf::name) { - COMPONENT result; - from_json(i, result); - return result; - } - } - - return {}; - } - - template void enroll(ComponentMap &m) { - m[NameOf::name] = [](DinkyECS::World& world, DinkyECS::Entity ent, nlohmann::json &j) { - COMPONENT c; - from_json(j, c); - world.set(ent, c); - }; - } - - void configure_entity(const ComponentMap& component_map, DinkyECS::World& world, DinkyECS::Entity ent, json& data); -} diff --git a/inventory.cpp b/inventory.cpp index 3059dcd..8df47ed 100644 --- a/inventory.cpp +++ b/inventory.cpp @@ -40,4 +40,31 @@ namespace components { return -1; } + + std::pair Inventory::use(GameLevel &level, size_t at) { + auto& player_combat = level.world->get(level.player); + auto& item = get(at); + + if(item.count == 0) return {false, item.data["name"]}; + + if(item.data["id"] == "SWORD_RUSTY") { + auto weapon = components::get(item.data); + player_combat.damage = weapon.damage; + } else if(item.data["id"] == "POTION_HEALING_SMALL") { + auto cure = components::get(item.data); + player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp); + } else if(item.data["id"] == "TORCH_BAD") { + auto new_light = components::get(item.data); + level.world->set(level.player, new_light); + light = new_light; + } else { + return {false, fmt::format("UNKNOWN ITEM: {}", (std::string)item.data["id"])}; + } + + decrease(at, 1); + return {true, item.data["name"]}; + } + + + } diff --git a/inventory.hpp b/inventory.hpp index ff79549..50795b6 100644 --- a/inventory.hpp +++ b/inventory.hpp @@ -1,6 +1,7 @@ #pragma once #include "components.hpp" #include +#include "levelmanager.hpp" namespace components { using namespace nlohmann; @@ -26,5 +27,7 @@ namespace components { int item_index(std::string id); void erase_item(size_t at); + + std::pair use(GameLevel &level, size_t at); }; } diff --git a/levelmanager.hpp b/levelmanager.hpp index 29a58c1..b96582f 100644 --- a/levelmanager.hpp +++ b/levelmanager.hpp @@ -6,7 +6,7 @@ #include #include #include "spatialmap.hpp" -#include "dinky_components.hpp" +#include "components.hpp" using std::shared_ptr; diff --git a/status_ui.cpp b/status_ui.cpp index 13b5939..5c591a4 100644 --- a/status_ui.cpp +++ b/status_ui.cpp @@ -47,34 +47,15 @@ namespace gui { if(world->has($level.player)) { auto& inventory = world->get($level.player); + for(size_t i = 0; i < inventory.count(); i++) { if($slots[i] == cn.name) { - auto& player_combat = world->get($level.player); - auto& item = inventory.get(i); + auto [used, name] = inventory.use($level, i); - if(item.count == 0) continue; - - if(item.data["id"] == "SWORD_RUSTY") { - auto weapon = components::get(item.data); - player_combat.damage = weapon.damage; - inventory.decrease(i, 1); - log("You equip a new sword."); - break; - } else if(item.data["id"] == "POTION_HEALING_SMALL") { - auto cure = components::get(item.data); - int prev_hp = player_combat.hp; - player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp); - log(fmt::format("Healed player from {} to {}", prev_hp, player_combat.hp)); - inventory.decrease(i, 1); - break; - } else if(item.data["id"] == "TORCH_BAD") { - auto new_light = components::get(item.data); - world->set($level.player, new_light); - inventory.light = new_light; - inventory.decrease(i, 1); - - log("You are using a new torch."); - break; + if(used) { + log(fmt::format("Used item: {}", name)); + } else { + log(fmt::format("You are out of {}.", name)); } } } diff --git a/systems.cpp b/systems.cpp index 3011fc4..30bff27 100644 --- a/systems.cpp +++ b/systems.cpp @@ -141,6 +141,7 @@ void System::death(GameLevel &level, components::ComponentMap& components) { auto entity_data = config.items["GRAVE_STONE"]; components::configure_entity(components, world, ent, entity_data["components"]); if(entity_data["inventory_count"] > 0) { + // right here use a std::any that's already converted instead? world.set(ent, {entity_data["inventory_count"], entity_data}); } } @@ -248,15 +249,6 @@ void System::collision(GameLevel &level) { } } -void System::pickup(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::Entity item) { - dbc::pre("System::pickup actor doesn't have inventory", world.has(actor)); - dbc::pre("System::pickup item isn't configured with InventoryItem.", world.has(item)); - - auto& inventory = world.get(actor); - auto& invitem = world.get(item); - - inventory.add(invitem); -} void System::device(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::Entity item) { auto& device = world.get(item); diff --git a/systems.hpp b/systems.hpp index 2395ea6..8c821b5 100644 --- a/systems.hpp +++ b/systems.hpp @@ -14,7 +14,6 @@ namespace System { void enemy_pathing(GameLevel &level); void init_positions(DinkyECS::World &world, SpatialMap &collider); - void pickup(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::Entity item); void device(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::Entity item); void plan_motion(DinkyECS::World& world, Point move_to); void draw_entities(DinkyECS::World &world, Map &map, const Matrix &lights, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y);