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 2 weeks 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(Combat, hp, max_hp, damage, dead);
ENROLL_COMPONENT(LightSource, strength, radius); ENROLL_COMPONENT(LightSource, strength, radius);
ENROLL_COMPONENT(Device, config, events); ENROLL_COMPONENT(Device, config, events);
ENROLL_COMPONENT(Sprite, name);
ENROLL_COMPONENT(Animation, scale, simple, frames, speed); ENROLL_COMPONENT(Animation, scale, simple, frames, speed);
ENROLL_COMPONENT(Sound, attack, death); 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 // these need to be here if you're using components::convert outside of components.cpp
ENROLL_COMPONENT(Tile, display, foreground, background); ENROLL_COMPONENT(Tile, display, foreground, background);
ENROLL_COMPONENT(Sprite, name);
} }

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

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

@ -47,6 +47,7 @@ namespace gui {
$combat_ui.render(); $combat_ui.render();
$status_ui.render(); $status_ui.render();
$status_ui.log("Welcome to the game!"); $status_ui.log("Welcome to the game!");
$status_ui.update();
$renderer.init_terminal(); $renderer.init_terminal();
$map_ui.create_render(); $map_ui.create_render();
@ -342,21 +343,25 @@ namespace gui {
// $status_ui.log(fmt::format("You picked up a {}.", // $status_ui.log(fmt::format("You picked up a {}.",
// std::string(item.data["name"]))); // std::string(item.data["name"])));
$status_ui.log("You picked up an item."); $status_ui.log("You picked up an item.");
$status_ui.update();
} }
break; break;
case eGUI::ATTACK: case eGUI::ATTACK:
event(Event::ATTACK); event(Event::ATTACK);
break; break;
case eGUI::DEATH: { case eGUI::DEATH: {
$status_ui.update();
if(entity != player.entity) { if(entity != player.entity) {
$main_ui.dead_entity(entity); $main_ui.dead_entity(entity);
} }
} break; } break;
case eGUI::NOOP: case eGUI::NOOP:
$status_ui.log(fmt::format("NOOP EVENT! {},{}", evt, entity)); $status_ui.log(fmt::format("NOOP EVENT! {},{}", evt, entity));
$status_ui.update();
break; break;
default: default:
$status_ui.log(fmt::format("INVALID EVENT! {},{}", evt, entity)); $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 // not sure if this is still needed
System::init_positions(*world, *collider); 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()), make_shared<LightRender>(map->width(), map->height()),
collider); collider);

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

@ -1,5 +1,6 @@
#include "status_ui.hpp" #include "status_ui.hpp"
#include "components.hpp" #include "components.hpp"
#include "inventory.hpp"
#include "color.hpp" #include "color.hpp"
#include "guecs.hpp" #include "guecs.hpp"
#include "rand.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.position(STATUS_UI_X, STATUS_UI_Y, STATUS_UI_WIDTH, STATUS_UI_HEIGHT);
$gui.layout( $gui.layout(
"[button1 | button2 | button3]" "[slot1 | slot2 | slot3]"
"[button4 | button5 | button6]" "[slot4 | slot5 | slot6]"
"[button7 | button8 | button9]" "[slot7 | slot8 | slot9]"
"[*%(100,300)log_view]" "[*%(100,300)log_view]"
"[_]" "[_]"
"[_]"); "[_]");
} }
void StatusUI::render() { 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()) { for(auto& [name, cell] : $gui.cells()) {
if(name == "log_view") { if(name == "log_view") {
$log_to = $gui.entity("log_view"); $log_to = $gui.entity("log_view");
world.set<Rectangle>($log_to, {}); $gui.set<Rectangle>($log_to, {});
world.set<Textual>($log_to, {"Welcome to the Game!", 20}); $gui.set<Textual>($log_to, {"Welcome to the Game!", 20});
} else { } 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); auto button = $gui.entity(name);
world.set<Rectangle>(button, {}); $gui.set<Rectangle>(button, {});
world.set<Sprite>(button, {fake_item}); $gui.set<Textual>(button, {""});
world.set<Clickable>(button, $gui.set<Clickable>(button,
guecs::make_action(*$level.world, Events::GUI::NOOP)); guecs::make_action(*$level.world, Events::GUI::NOOP));
} }
} }
@ -48,14 +39,40 @@ namespace gui {
$gui.init(); $gui.init();
} }
void StatusUI::draw(sf::RenderWindow &window) { /* WARNING: This is really not the greatest way to do this. */
auto &world = $gui.world(); void StatusUI::update() {
auto &text = world.get<Textual>($log_to); if($gui.has<Textual>($log_to)) {
std::string log; auto& text = $gui.get<Textual>($log_to);
for(auto msg : $messages) { std::string log;
log += msg + "\n"; 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); $gui.render(window);
} }

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

Loading…
Cancel
Save