Have a plan for the new inventory and looting system, now have to implement it. Temporarily you can't pick anything up, but it will go away.

master
Zed A. Shaw 10 months ago
parent b8d2d1870d
commit ab391aaa97
  1. 22
      autowalker.cpp
  2. 5
      components.hpp
  3. 54
      gui/status_ui.cpp
  4. 76
      inventory.cpp
  5. 35
      inventory.hpp
  6. 2
      meson.build
  7. 10
      systems.cpp
  8. 75
      tests/inventory.cpp
  9. 3
      worldbuilder.cpp

@ -1,5 +1,4 @@
#include "autowalker.hpp"
#include "inventory.hpp"
#include "ai_debug.hpp"
#include "gui/ritual_ui.hpp"
@ -344,31 +343,12 @@ bool Autowalker::player_health_good() {
}
InventoryStats Autowalker::player_item_count() {
auto& inventory = fsm.$level.world->get<components::Inventory>(fsm.$level.player);
InventoryStats stats;
for(auto& item : inventory.items) {
if(item.data["id"] == "POTION_HEALING_SMALL") {
stats.healing += item.count;
} else {
stats.other += item.count;
}
}
stats.healing = 0;
return stats;
}
void Autowalker::player_use_healing() {
auto& inventory = fsm.$level.world->get<components::Inventory>(fsm.$level.player);
// find the healing slot
for(size_t slot = 0; slot < inventory.count(); slot++) {
auto& item = inventory.get(slot);
if(item.data["id"] == "POTION_HEALING_SMALL") {
inventory.use(fsm.$level, slot);
fsm.$status_ui.update();
return;
}
}
}
void Autowalker::start_autowalk() {

@ -16,6 +16,11 @@ namespace components {
using std::string;
using namespace nlohmann;
struct InventoryItem {
int count;
json data;
};
struct SpriteEffect {
int frames;
std::shared_ptr<sf::Shader> effect;

@ -1,6 +1,5 @@
#include "gui/status_ui.hpp"
#include "components.hpp"
#include "inventory.hpp"
#include <guecs/ui.hpp>
#include "rand.hpp"
#include <fmt/xchar.h>
@ -15,11 +14,11 @@ namespace gui {
$gui.position(STATUS_UI_X, STATUS_UI_Y, STATUS_UI_WIDTH, STATUS_UI_HEIGHT);
$gui.layout(
"[ritual_ui]"
"[inv_1|inv_2|inv_3]"
"[inv_4|*%(200,300)character_view|_|inv_5]"
"[inv_6|_|_ |inv_7]"
"[inv_8|_|_ |inv_9]"
"[inv_10|inv_11|inv_12]");
"[earing|armor_head|amulet]"
"[back|*%(200,300)character_view|_|armor_bdy]"
"[hand_r|_|_ |hand_l]"
"[ring_r|_|_ |ring_l]"
"[pocket_r|armor_leg|pocket_l]");
size_t inv_id = 0;
for(auto [name, entity] : $gui.$name_ents) {
@ -36,7 +35,7 @@ namespace gui {
if(name == "character_view") {
auto char_view = $gui.entity(name);
$gui.set<Rectangle>(char_view, {});
$gui.set<Sprite>(char_view, {"peasant_girl"});
$gui.set<Sprite>(char_view, {"armored_knight"});
} else {
auto button = $gui.entity(name);
$gui.set<Rectangle>(button, {});
@ -73,47 +72,14 @@ namespace gui {
}
void StatusUI::select_slot(DinkyECS::Entity ent, any slot_name) {
dbc::check(slot_name.has_value(), "passed select_slot an any without a value");
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);
size_t inv_id = $slots[any_cast<string>(slot_name)];
if(inventory.has_item(inv_id)) {
auto [used, name] = inventory.use($level, inv_id);
}
}
(void)ent;
(void)slot_name;
dbc::log("REWRITE!");
}
/* WARNING: This is really not the greatest way to do this. */
void StatusUI::update() {
auto world = $level.world;
if(world->has<components::Inventory>($level.player)) {
auto& inventory = world->get<components::Inventory>($level.player);
for(auto& [slot_name, inv_id] : $slots) {
if(inventory.has_item(inv_id)) {
auto slot = $gui.entity(slot_name);
auto& item = inventory.get(inv_id);
auto comp_sprite = components::get<components::Sprite>(item.data);
$gui.set_init<guecs::Sprite>(slot, {comp_sprite.name});
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});
}
}
}
}
dbc::log("REWRITE ME!");
}
void StatusUI::render(sf::RenderWindow &window) {

@ -1,76 +0,0 @@
#include "inventory.hpp"
#include <fmt/core.h>
namespace components {
void Inventory::add(InventoryItem new_item) {
for(auto &slot : items) {
if(new_item.data["id"] == slot.data["id"]) {
slot.count += new_item.count;
return;
}
}
items.push_back(new_item);
}
bool Inventory::has_item(size_t at) {
return at < items.size();
}
InventoryItem& Inventory::get(size_t at) {
dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
return items[at];
}
bool Inventory::decrease(size_t at, int count) {
dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
auto &slot = items[at];
slot.count -= count;
return slot.count > 0;
}
void Inventory::erase_item(size_t at) {
dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
items.erase(items.begin() + at);
}
int Inventory::item_index(std::string id) {
for(size_t i = 0; i < items.size(); i++) {
if(items[i].data["id"] == id) {
return i;
}
}
return -1;
}
std::pair<bool, std::string> Inventory::use(GameLevel &level, size_t at) {
auto& player_combat = level.world->get<components::Combat>(level.player);
auto& item = get(at);
if(item.count == 0) return {false, item.data["name"]};
dbc::log("INVENTORY IS HARDCODED YOU FUCKING MORON!!!!!");
if(item.data["id"] == "SWORD_RUSTY") {
auto weapon = components::get<components::Weapon>(item.data);
player_combat.damage = weapon.damage;
} else if(item.data["id"] == "POTION_HEALING_SMALL") {
auto cure = components::get<components::Curative>(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<components::LightSource>(item.data);
level.world->set<components::LightSource>(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"]};
}
}

@ -1,35 +0,0 @@
#pragma once
#include "components.hpp"
#include <nlohmann/json.hpp>
#include "levelmanager.hpp"
namespace components {
using namespace nlohmann;
struct InventoryItem {
int count;
json data;
};
struct Inventory {
int gold=0;
LightSource light{0, 0};
std::vector<InventoryItem> items{};
size_t count() { return items.size(); }
void add(InventoryItem item);
bool decrease(size_t at, int count);
bool has_item(size_t at);
InventoryItem& get(size_t at);
int item_index(std::string id);
void erase_item(size_t at);
std::pair<bool, std::string> use(GameLevel &level, size_t at);
};
}

@ -105,7 +105,6 @@ sources = [
'gui/overlay_ui.cpp',
'gui/ritual_ui.cpp',
'gui/status_ui.cpp',
'inventory.cpp',
'levelmanager.cpp',
'lights.cpp',
'map.cpp',
@ -137,7 +136,6 @@ executable('runtests', sources + [
'tests/dinkyecs.cpp',
'tests/easings.cpp',
'tests/fsm.cpp',
'tests/inventory.cpp',
'tests/levelmanager.cpp',
'tests/lighting.cpp',
'tests/map.cpp',

@ -6,7 +6,6 @@
#include "spatialmap.hpp"
#include "dbc.hpp"
#include "lights.hpp"
#include "inventory.hpp"
#include "events.hpp"
#include "sound.hpp"
#include "ai.hpp"
@ -307,16 +306,17 @@ void System::collision(GameLevel &level) {
// call into that to work it, rather than this hard coded crap
auto item = world.get<InventoryItem>(entity);
auto& item_pos = world.get<Position>(entity);
auto& inventory = world.get<Inventory>(player.entity);
dbc::log("REWRITE ME!");
if(world.has<LightSource>(entity)) {
inventory.add(item);
// inventory.add(item);
world.remove<LightSource>(entity);
}
if(world.has<ritual::JunkPile>(entity)) {
auto& pile = world.get<ritual::JunkPile>(entity);
auto& blanket = world.get_the<ritual::Blanket>();
for(auto& junk : pile.contents) {
fmt::println("adding {} to blanket", junk);
blanket.add(junk);
@ -324,12 +324,12 @@ void System::collision(GameLevel &level) {
}
if(world.has<Weapon>(entity)) {
inventory.add(item);
// inventory.add(item);
world.remove<Weapon>(entity);
}
if(world.has<Curative>(entity)) {
inventory.add(item);
// inventory.add(item);
world.remove<Curative>(entity);
}

@ -1,75 +0,0 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "rand.hpp"
#include <nlohmann/json.hpp>
#include <fstream>
#include "components.hpp"
#include "inventory.hpp"
#include "dinkyecs.hpp"
#include "save.hpp"
#include "systems.hpp"
using namespace nlohmann;
using namespace fmt;
using std::string;
using namespace components;
DinkyECS::Entity add_items(components::ComponentMap component_map, DinkyECS::World &world, GameConfig &config) {
auto sword = world.entity();
json& item_data = config.items["SWORD_RUSTY"];
world.set<InventoryItem>(sword, {item_data["inventory_count"], item_data});
components::configure_entity(component_map, world, sword, item_data);
return sword;
}
TEST_CASE("basic inventory test", "[inventory]") {
// BUG: rewrite this
/*
DinkyECS::World world;
save::load_configs(world);
auto& config = world.get_the<GameConfig>();
auto sword = add_items(world, config);
auto player = world.entity();
world.set<Inventory>(player, {});
auto &inventory = world.get<Inventory>(player);
System::pickup(world, player, sword);
REQUIRE(inventory.count() == 1);
// get the item and confirm there is 1
auto &item1 = inventory.get(0);
REQUIRE(item1.count == 1);
int item_at = inventory.item_index("SWORD_RUSTY");
REQUIRE(item_at == 0);
REQUIRE(inventory.item_index("SADFASFSADF") == -1);
System::pickup(world, player, sword);
REQUIRE(item1.count == 2);
System::pickup(world, player, sword);
REQUIRE(item1.count == 3);
System::pickup(world, player, sword);
REQUIRE(inventory.count() == 1);
REQUIRE(item1.count == 4);
inventory.decrease(0, 1);
REQUIRE(item1.count == 3);
inventory.decrease(0, 2);
REQUIRE(item1.count == 1);
bool active = inventory.decrease(0, 1);
REQUIRE(item1.count == 0);
REQUIRE(active == false);
inventory.erase_item(0);
REQUIRE(inventory.count() == 0);
*/
}

@ -3,9 +3,9 @@
#include <fmt/core.h>
#include <iostream>
#include "components.hpp"
#include "inventory.hpp"
#include "rituals.hpp"
#include "maze.hpp"
#include "textures.hpp"
using namespace fmt;
using namespace components;
@ -203,7 +203,6 @@ void WorldBuilder::place_entities(DinkyECS::World &world) {
world.set_the<ritual::Belt>({});
world.set_the<ritual::Blanket>({});
configure_starting_items(world);
world.set<Inventory>(player.entity, {5});
world.make_constant(player.entity);
}