diff --git a/assets/config.json b/assets/config.json index c85a6ac..2ea598d 100644 --- a/assets/config.json +++ b/assets/config.json @@ -38,8 +38,8 @@ "player": { }, "worldgen": { - "enemy_probability": 30, - "empty_room_probability": 10, - "device_probability": 20 + "enemy_probability": 10, + "empty_room_probability": 1, + "device_probability": 10 } } diff --git a/assets/enemies.json b/assets/enemies.json index 3494e77..aa32116 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -8,7 +8,7 @@ }, {"_type": "Combat", "hp": 200, "max_hp": 200, "damage": 50, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "LightSource", "strength": 50, "radius": 1.0}, + {"_type": "LightSource", "strength": 40, "radius": 1.5}, {"_type": "EnemyConfig", "hearing_distance": 5}, {"_type": "Animation", "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0} ] diff --git a/components.cpp b/components.cpp index d246ced..e293823 100644 --- a/components.cpp +++ b/components.cpp @@ -2,14 +2,10 @@ #include "point.hpp" namespace components { - ENROLL_COMPONENT(Loot, amount); ENROLL_COMPONENT(Position, location.x, location.y); - ENROLL_COMPONENT(Weapon, damage); - ENROLL_COMPONENT(Curative, hp); ENROLL_COMPONENT(EnemyConfig, hearing_distance); ENROLL_COMPONENT(Motion, dx, dy, random); ENROLL_COMPONENT(Combat, hp, max_hp, damage, dead); - ENROLL_COMPONENT(LightSource, strength, radius); ENROLL_COMPONENT(Device, config, events); ENROLL_COMPONENT(Animation, scale, simple, frames, speed); ENROLL_COMPONENT(Sound, attack, death); diff --git a/components.hpp b/components.hpp index 9f364cf..e66a14f 100644 --- a/components.hpp +++ b/components.hpp @@ -109,4 +109,8 @@ namespace components { // these need to be here if you're using components::convert outside of components.cpp ENROLL_COMPONENT(Tile, display, foreground, background); ENROLL_COMPONENT(Sprite, name); + ENROLL_COMPONENT(Curative, hp); + ENROLL_COMPONENT(LightSource, strength, radius); + ENROLL_COMPONENT(Weapon, damage); + ENROLL_COMPONENT(Loot, amount); } diff --git a/guecs.cpp b/guecs.cpp index aa42f3f..b4fccba 100644 --- a/guecs.cpp +++ b/guecs.cpp @@ -103,15 +103,19 @@ namespace guecs { if((x >= cell.x && x <= cell.x + cell.w) && (y >= cell.y && y <= cell.y + cell.h)) { - auto& cn = $world.get(ent); - clicked.action(ent, cn.name); + if(auto action_data = get_if(ent)) { + clicked.action(ent, action_data->data); + } else { + clicked.action(ent, {}); + } } }); } Clickable make_action(DinkyECS::World& target, Events::GUI event) { - return {[&, event](auto ent, auto&){ - target.send(event, ent, {}); + return {[&, event](auto ent, auto data){ + // remember that ent is passed in from the UI::mouse handler + target.send(event, ent, data); }}; } } diff --git a/guecs.hpp b/guecs.hpp index d386323..c73df59 100644 --- a/guecs.hpp +++ b/guecs.hpp @@ -10,6 +10,7 @@ #include "events.hpp" #include "constants.hpp" #include "components.hpp" +#include namespace guecs { using std::shared_ptr, std::make_shared; @@ -50,7 +51,10 @@ namespace guecs { }; struct Clickable { - std::function action; + /* This is actually called by UI::mouse and passed the entity ID of the + * button pressed so you can interact with it in the event handler. + */ + std::function action; }; struct Sprite { @@ -95,6 +99,10 @@ namespace guecs { } }; + struct ActionData { + std::any data; + }; + struct CellName { std::string name; }; @@ -157,6 +165,7 @@ namespace guecs { template void set_init(DinkyECS::Entity ent, Comp val) { + dbc::check(has(ent),"WRONG! slot is missing its cell?!"); auto& cell = get(ent); val.init(cell); $world.set(ent, val); diff --git a/gui_fsm.cpp b/gui_fsm.cpp index 33f8940..7139a05 100644 --- a/gui_fsm.cpp +++ b/gui_fsm.cpp @@ -355,10 +355,13 @@ namespace gui { $main_ui.dead_entity(entity); } } break; - case eGUI::NOOP: - $status_ui.log(fmt::format("NOOP EVENT! {},{}", evt, entity)); - $status_ui.update(); - break; + case eGUI::NOOP: { + if(data.type() == typeid(std::string)) { + auto name = std::any_cast(data); + $status_ui.log(fmt::format("NOOP EVENT! {},{} name={}", evt, entity, name)); + } + $status_ui.update(); + } break; default: $status_ui.log(fmt::format("INVALID EVENT! {},{}", evt, entity)); $status_ui.update(); diff --git a/status_ui.cpp b/status_ui.cpp index 8535d88..13b5939 100644 --- a/status_ui.cpp +++ b/status_ui.cpp @@ -31,14 +31,58 @@ namespace gui { auto button = $gui.entity(name); $gui.set(button, {}); $gui.set(button, {""}); - $gui.set(button, - guecs::make_action(*$level.world, Events::GUI::NOOP)); + $gui.set(button, {std::make_any(name)}); + $gui.set(button, { + [&](auto ent, auto data){ select_slot(ent, data); } + }); } } $gui.init(); } + void StatusUI::select_slot(DinkyECS::Entity ent, std::any) { + auto cn = $gui.get(ent); + auto world = $level.world; + + 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); + + 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; + } + } + } + + update(); + } + } + /* WARNING: This is really not the greatest way to do this. */ void StatusUI::update() { if($gui.has($log_to)) { @@ -62,11 +106,17 @@ namespace gui { auto& item = inventory.get(i); auto comp_sprite = components::get(item.data); $gui.set_init(slot, {comp_sprite.name}); - - std::string count_label = item.count > 1 ? fmt::format("{}", item.count): ""; - + std::string count_label = fmt::format("{}", item.count); auto& label = $gui.get(slot); label.text->setString(count_label); + + auto& sprite = $gui.get(slot); + + if(item.count == 0) { + sprite.sprite->setColor({125, 125, 125}); + } else { + sprite.sprite->setColor({255, 255, 255}); + } } } } diff --git a/status_ui.hpp b/status_ui.hpp index d092103..6f0e698 100644 --- a/status_ui.hpp +++ b/status_ui.hpp @@ -11,14 +11,15 @@ namespace gui { guecs::UI $gui; DinkyECS::Entity $log_to; std::array $slots = { - "slot1", "slot2", "slot3" - "slot4", "slot5", "slot6" + "slot1", "slot2", "slot3", + "slot4", "slot5", "slot6", "slot7", "slot8", "slot9" }; std::deque $messages; GameLevel $level; StatusUI(GameLevel level); + void select_slot(DinkyECS::Entity ent, std::any data); void update_level(GameLevel &level) { $level = level; } void log(std::string msg); void render(); diff --git a/systems.cpp b/systems.cpp index b8e5b77..3011fc4 100644 --- a/systems.cpp +++ b/systems.cpp @@ -189,7 +189,6 @@ void System::collision(GameLevel &level) { auto player = world.get_the(); const auto& player_position = world.get(player.entity); - auto& player_combat = world.get(player.entity); // this is guaranteed to not return the given position auto [found, nearby] = collider.neighbors(player_position.location); @@ -210,16 +209,11 @@ void System::collision(GameLevel &level) { if(world.has(entity)) { inventory.add(item); - auto &new_light = world.get(entity); - world.set(player.entity, new_light); - inventory.light = new_light; world.remove(entity); } if(world.has(entity)) { inventory.add(item); - auto &weapon = world.get(entity); - player_combat.damage = weapon.damage; world.remove(entity); } @@ -230,8 +224,7 @@ void System::collision(GameLevel &level) { } if(world.has(entity)) { - auto& cure = world.get(entity); - player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp); + inventory.add(item); world.remove(entity); } diff --git a/worldbuilder.hpp b/worldbuilder.hpp index 51c7471..61eb51e 100644 --- a/worldbuilder.hpp +++ b/worldbuilder.hpp @@ -28,7 +28,6 @@ class WorldBuilder { DinkyECS::Entity configure_entity_in_map(DinkyECS::World &world, nlohmann::json &entity_data, int in_room); 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); void place_stairs(DinkyECS::World& world, components::GameConfig& config); };