Inventory system basically works now but is in a alpha hack stage. Time to refactor.

master
Zed A. Shaw 2 weeks ago
parent b7f49aa719
commit e0e7a1027c
  1. 6
      assets/config.json
  2. 2
      assets/enemies.json
  3. 4
      components.cpp
  4. 4
      components.hpp
  5. 12
      guecs.cpp
  6. 11
      guecs.hpp
  7. 9
      gui_fsm.cpp
  8. 60
      status_ui.cpp
  9. 5
      status_ui.hpp
  10. 9
      systems.cpp
  11. 1
      worldbuilder.hpp

@ -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
}
}

@ -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}
]

@ -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);

@ -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);
}

@ -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<CellName>(ent);
clicked.action(ent, cn.name);
if(auto action_data = get_if<ActionData>(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<Events::GUI>(event, ent, {});
return {[&, event](auto ent, auto data){
// remember that ent is passed in from the UI::mouse handler
target.send<Events::GUI>(event, ent, data);
}};
}
}

@ -10,6 +10,7 @@
#include "events.hpp"
#include "constants.hpp"
#include "components.hpp"
#include <any>
namespace guecs {
using std::shared_ptr, std::make_shared;
@ -50,7 +51,10 @@ namespace guecs {
};
struct Clickable {
std::function<void(DinkyECS::Entity ent, std::string &name)> 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<void(DinkyECS::Entity ent, std::any data)> 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 <typename Comp>
void set_init(DinkyECS::Entity ent, Comp val) {
dbc::check(has<lel::Cell>(ent),"WRONG! slot is missing its cell?!");
auto& cell = get<lel::Cell>(ent);
val.init(cell);
$world.set<Comp>(ent, val);

@ -355,10 +355,13 @@ namespace gui {
$main_ui.dead_entity(entity);
}
} break;
case eGUI::NOOP:
$status_ui.log(fmt::format("NOOP EVENT! {},{}", evt, entity));
case eGUI::NOOP: {
if(data.type() == typeid(std::string)) {
auto name = std::any_cast<std::string>(data);
$status_ui.log(fmt::format("NOOP EVENT! {},{} name={}", evt, entity, name));
}
$status_ui.update();
break;
} break;
default:
$status_ui.log(fmt::format("INVALID EVENT! {},{}", evt, entity));
$status_ui.update();

@ -31,14 +31,58 @@ namespace gui {
auto button = $gui.entity(name);
$gui.set<Rectangle>(button, {});
$gui.set<Textual>(button, {""});
$gui.set<Clickable>(button,
guecs::make_action(*$level.world, Events::GUI::NOOP));
$gui.set<ActionData>(button, {std::make_any<std::string>(name)});
$gui.set<Clickable>(button, {
[&](auto ent, auto data){ select_slot(ent, data); }
});
}
}
$gui.init();
}
void StatusUI::select_slot(DinkyECS::Entity ent, std::any) {
auto cn = $gui.get<CellName>(ent);
auto world = $level.world;
if(world->has<components::Inventory>($level.player)) {
auto& inventory = world->get<components::Inventory>($level.player);
for(size_t i = 0; i < inventory.count(); i++) {
if($slots[i] == cn.name) {
auto& player_combat = world->get<components::Combat>($level.player);
auto& item = inventory.get(i);
if(item.count == 0) continue;
if(item.data["id"] == "SWORD_RUSTY") {
auto weapon = components::get<components::Weapon>(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<components::Curative>(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<components::LightSource>(item.data);
world->set<components::LightSource>($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<Textual>($log_to)) {
@ -62,11 +106,17 @@ namespace gui {
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): "";
std::string count_label = fmt::format("{}", item.count);
auto& label = $gui.get<Textual>(slot);
label.text->setString(count_label);
auto& sprite = $gui.get<guecs::Sprite>(slot);
if(item.count == 0) {
sprite.sprite->setColor({125, 125, 125});
} else {
sprite.sprite->setColor({255, 255, 255});
}
}
}
}

@ -11,14 +11,15 @@ namespace gui {
guecs::UI $gui;
DinkyECS::Entity $log_to;
std::array<std::string, 9> $slots = {
"slot1", "slot2", "slot3"
"slot4", "slot5", "slot6"
"slot1", "slot2", "slot3",
"slot4", "slot5", "slot6",
"slot7", "slot8", "slot9"
};
std::deque<std::string> $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();

@ -189,7 +189,6 @@ void System::collision(GameLevel &level) {
auto player = world.get_the<Player>();
const auto& player_position = world.get<Position>(player.entity);
auto& player_combat = world.get<Combat>(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<LightSource>(entity)) {
inventory.add(item);
auto &new_light = world.get<LightSource>(entity);
world.set<LightSource>(player.entity, new_light);
inventory.light = new_light;
world.remove<LightSource>(entity);
}
if(world.has<Weapon>(entity)) {
inventory.add(item);
auto &weapon = world.get<Weapon>(entity);
player_combat.damage = weapon.damage;
world.remove<Weapon>(entity);
}
@ -230,8 +224,7 @@ void System::collision(GameLevel &level) {
}
if(world.has<Curative>(entity)) {
auto& cure = world.get<Curative>(entity);
player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp);
inventory.add(item);
world.remove<Curative>(entity);
}

@ -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);
};

Loading…
Cancel
Save