Now have a mostly working inventory UI and can pickup items and see them. Next up, being able to use things by clicking on them.

master
Zed A. Shaw 10 months ago
parent fa6311f10c
commit b7f49aa719
  1. 1
      components.cpp
  2. 1
      components.hpp
  3. 13
      dinky_components.hpp
  4. 13
      guecs.hpp
  5. 5
      gui_fsm.cpp
  6. 4
      levelmanager.cpp
  7. 1
      levelmanager.hpp
  8. 67
      status_ui.cpp
  9. 7
      status_ui.hpp

@ -11,7 +11,6 @@ namespace components {
ENROLL_COMPONENT(Combat, hp, max_hp, damage, dead);
ENROLL_COMPONENT(LightSource, strength, radius);
ENROLL_COMPONENT(Device, config, events);
ENROLL_COMPONENT(Sprite, name);
ENROLL_COMPONENT(Animation, scale, simple, frames, speed);
ENROLL_COMPONENT(Sound, attack, death);

@ -108,4 +108,5 @@ 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);
}

@ -4,7 +4,6 @@
#include <nlohmann/json_fwd.hpp>
#include "dinkyecs.hpp"
#define ENROLL_COMPONENT(COMPONENT, ...) \
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \
template <> struct NameOf<COMPONENT> { \
@ -25,6 +24,18 @@ namespace components {
return result;
}
template<typename COMPONENT> COMPONENT get(nlohmann::json &data) {
for (auto &i : data["components"]) {
if(i["_type"] == NameOf<COMPONENT>::name) {
COMPONENT result;
from_json(i, result);
return result;
}
}
return {};
}
template <typename COMPONENT> void enroll(ComponentMap &m) {
m[NameOf<COMPONENT>::name] = [](DinkyECS::World& world, DinkyECS::Entity ent, nlohmann::json &j) {
COMPONENT c;

@ -9,6 +9,7 @@
#include <functional>
#include "events.hpp"
#include "constants.hpp"
#include "components.hpp"
namespace guecs {
using std::shared_ptr, std::make_shared;
@ -154,6 +155,13 @@ namespace guecs {
$world.set<Comp>(ent, val);
}
template <typename Comp>
void set_init(DinkyECS::Entity ent, Comp val) {
auto& cell = get<lel::Cell>(ent);
val.init(cell);
$world.set<Comp>(ent, val);
}
lel::Cell& cell_for(DinkyECS::Entity entity) {
return $world.get<lel::Cell>(entity);
}
@ -168,6 +176,11 @@ namespace guecs {
return $world.get_if<Comp>(entity);
}
template <typename Comp>
bool has(DinkyECS::Entity entity) {
return $world.has<Comp>(entity);
}
template <typename Comp>
void remove(DinkyECS::Entity ent) {
$world.remove<Comp>(ent);

@ -47,6 +47,7 @@ namespace gui {
$combat_ui.render();
$status_ui.render();
$status_ui.log("Welcome to the game!");
$status_ui.update();
$renderer.init_terminal();
$map_ui.create_render();
@ -342,21 +343,25 @@ namespace gui {
// $status_ui.log(fmt::format("You picked up a {}.",
// std::string(item.data["name"])));
$status_ui.log("You picked up an item.");
$status_ui.update();
}
break;
case eGUI::ATTACK:
event(Event::ATTACK);
break;
case eGUI::DEATH: {
$status_ui.update();
if(entity != player.entity) {
$main_ui.dead_entity(entity);
}
} break;
case eGUI::NOOP:
$status_ui.log(fmt::format("NOOP EVENT! {},{}", evt, entity));
$status_ui.update();
break;
default:
$status_ui.log(fmt::format("INVALID EVENT! {},{}", evt, entity));
$status_ui.update();
}
}
}

@ -42,7 +42,9 @@ size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
// not sure if this is still needed
System::init_positions(*world, *collider);
$levels.emplace_back(index, map, world,
auto player = world->get_the<Player>();
$levels.emplace_back(index, player.entity, map, world,
make_shared<LightRender>(map->width(), map->height()),
collider);

@ -12,6 +12,7 @@ using std::shared_ptr;
struct GameLevel {
size_t index;
DinkyECS::Entity player;
shared_ptr<Map> map;
shared_ptr<DinkyECS::World> world;
shared_ptr<lighting::LightRender> lights;

@ -1,5 +1,6 @@
#include "status_ui.hpp"
#include "components.hpp"
#include "inventory.hpp"
#include "color.hpp"
#include "guecs.hpp"
#include "rand.hpp"
@ -12,35 +13,25 @@ namespace gui {
{
$gui.position(STATUS_UI_X, STATUS_UI_Y, STATUS_UI_WIDTH, STATUS_UI_HEIGHT);
$gui.layout(
"[button1 | button2 | button3]"
"[button4 | button5 | button6]"
"[button7 | button8 | button9]"
"[slot1 | slot2 | slot3]"
"[slot4 | slot5 | slot6]"
"[slot7 | slot8 | slot9]"
"[*%(100,300)log_view]"
"[_]"
"[_]");
}
void StatusUI::render() {
auto& world = $gui.world();
std::vector<std::string> fake_items{
"cinqueda", "healing_potion_small",
"torch_crappy", "barrel_small"};
for(auto& [name, cell] : $gui.cells()) {
if(name == "log_view") {
$log_to = $gui.entity("log_view");
world.set<Rectangle>($log_to, {});
world.set<Textual>($log_to, {"Welcome to the Game!", 20});
$gui.set<Rectangle>($log_to, {});
$gui.set<Textual>($log_to, {"Welcome to the Game!", 20});
} else {
size_t selected_item = Random::uniform<size_t>(0, fake_items.size() - 1);
fmt::println("fake items {} but size {}", selected_item, fake_items.size());
auto& fake_item = fake_items[selected_item];
auto button = $gui.entity(name);
world.set<Rectangle>(button, {});
world.set<Sprite>(button, {fake_item});
world.set<Clickable>(button,
$gui.set<Rectangle>(button, {});
$gui.set<Textual>(button, {""});
$gui.set<Clickable>(button,
guecs::make_action(*$level.world, Events::GUI::NOOP));
}
}
@ -48,14 +39,40 @@ namespace gui {
$gui.init();
}
void StatusUI::draw(sf::RenderWindow &window) {
auto &world = $gui.world();
auto &text = world.get<Textual>($log_to);
std::string log;
for(auto msg : $messages) {
log += msg + "\n";
/* WARNING: This is really not the greatest way to do this. */
void StatusUI::update() {
if($gui.has<Textual>($log_to)) {
auto& text = $gui.get<Textual>($log_to);
std::string log;
for(auto msg : $messages) {
log += msg + "\n";
}
text.update(log);
}
text.update(log);
auto world = $level.world;
if(world->has<components::Inventory>($level.player)) {
auto& inventory = world->get<components::Inventory>($level.player);
if(inventory.count() > 0) {
size_t limit = std::min(inventory.count(), $slots.size());
for(size_t i = 0; i < limit; i++) {
auto slot = $gui.entity($slots[i]);
auto& item = inventory.get(i);
auto comp_sprite = components::get<components::Sprite>(item.data);
$gui.set_init<guecs::Sprite>(slot, {comp_sprite.name});
std::string count_label = item.count > 1 ? fmt::format("{}", item.count): "";
auto& label = $gui.get<Textual>(slot);
label.text->setString(count_label);
}
}
}
}
void StatusUI::draw(sf::RenderWindow &window) {
$gui.render(window);
}

@ -10,6 +10,12 @@ namespace gui {
public:
guecs::UI $gui;
DinkyECS::Entity $log_to;
std::array<std::string, 9> $slots = {
"slot1", "slot2", "slot3"
"slot4", "slot5", "slot6"
"slot7", "slot8", "slot9"
};
std::deque<std::string> $messages;
GameLevel $level;
StatusUI(GameLevel level);
@ -17,5 +23,6 @@ namespace gui {
void log(std::string msg);
void render();
void draw(sf::RenderWindow &window);
void update();
};
}