diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 78e56e78..9c180e2e 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -186,17 +186,26 @@ void SlotView::draw(const DrawContext& pctx, const Assets& assets) { } } - if (stack.getCount() > 1) { + if (stack.getCount() > 1 || stack.getFields() != nullptr) { auto font = assets.get("normal"); - std::wstring text = std::to_wstring(stack.getCount()); + + if (stack.getCount() > 1) { + std::wstring text = std::to_wstring(stack.getCount()); - int x = pos.x+slotSize-text.length()*8; - int y = pos.y+slotSize-16; + int x = pos.x+slotSize-text.length()*8; + int y = pos.y+slotSize-16; - batch->setColor({0, 0, 0, 1.0f}); - font->draw(*batch, text, x+1, y+1, nullptr, 0); - batch->setColor(glm::vec4(1.0f)); - font->draw(*batch, text, x, y, nullptr, 0); + batch->setColor({0, 0, 0, 1.0f}); + font->draw(*batch, text, x+1, y+1, nullptr, 0); + batch->setColor(glm::vec4(1.0f)); + font->draw(*batch, text, x, y, nullptr, 0); + } + if (stack.getFields() != nullptr) { + batch->setColor({0, 0, 0, 1.0f}); + font->draw(*batch, L"#", pos.x+1, pos.y+1, nullptr, 0); + batch->setColor(glm::vec4(1.0f)); + font->draw(*batch, L"#", pos.x, pos.y, nullptr, 0); + } } } diff --git a/src/items/Inventory.cpp b/src/items/Inventory.cpp index 1d27e261..5978f283 100644 --- a/src/items/Inventory.cpp +++ b/src/items/Inventory.cpp @@ -72,8 +72,12 @@ void Inventory::deserialize(const dv::value& src) { if (item.has("count")){ count = item["count"].asInteger(); } + dv::value fields = nullptr; + if (item.has("fields")) { + fields = item["fields"]; + } auto& slot = slots[i]; - slot.set(ItemStack(id, count)); + slot.set(ItemStack(id, count, fields)); } } @@ -92,6 +96,10 @@ dv::value Inventory::serialize() const { if (count) { slotmap["count"] = count; } + const auto& fields = item.getFields(); + if (fields != nullptr) { + slotmap["fields"] = fields; + } } return map; } @@ -110,5 +118,3 @@ void Inventory::convert(dv::value& data, const ContentReport* report) { inventory.convert(report); data = inventory.serialize(); } - -const size_t Inventory::npos = -1; diff --git a/src/items/Inventory.hpp b/src/items/Inventory.hpp index f0efdfe1..29205640 100644 --- a/src/items/Inventory.hpp +++ b/src/items/Inventory.hpp @@ -26,10 +26,6 @@ public: itemid_t id, size_t begin = 0, size_t end = -1, size_t minCount = 1 ); - inline size_t size() const { - return slots.size(); - } - void move( ItemStack& item, const ContentIndices& indices, @@ -46,17 +42,21 @@ public: void convert(const ContentReport* report); static void convert(dv::value& data, const ContentReport* report); - inline void setId(int64_t id) { + size_t size() const { + return slots.size(); + } + + void setId(int64_t id) { this->id = id; } - inline int64_t getId() const { + int64_t getId() const { return id; } - inline bool isVirtual() const { + bool isVirtual() const { return id < 0; } - static const size_t npos; + static constexpr size_t npos = -1; }; diff --git a/src/items/ItemStack.cpp b/src/items/ItemStack.cpp index fdf1ff80..3e63371a 100644 --- a/src/items/ItemStack.cpp +++ b/src/items/ItemStack.cpp @@ -3,13 +3,18 @@ #include "content/Content.hpp" #include "ItemDef.hpp" -ItemStack::ItemStack(itemid_t item, itemcount_t count) - : item(item), count(count) { +ItemStack::ItemStack(itemid_t item, itemcount_t count, dv::value data) + : item(item), count(count), fields(std::move(data)) { } void ItemStack::set(const ItemStack& item) { + set(ItemStack(item)); +} + +void ItemStack::set(ItemStack&& item) { this->item = item.item; this->count = item.count; + this->fields = std::move(item.fields); if (count == 0) { this->item = 0; } @@ -22,14 +27,14 @@ bool ItemStack::accepts(const ItemStack& other) const { if (isEmpty()) { return true; } - return item == other.getItemId(); + return item == other.getItemId() && other.fields == nullptr; } void ItemStack::move(ItemStack& item, const ContentIndices& indices) { auto& def = indices.items.require(item.getItemId()); itemcount_t count = std::min(item.count, def.stackSize - this->count); if (isEmpty()) { - set(ItemStack(item.getItemId(), count)); + set(ItemStack(item.getItemId(), count, std::move(item.fields))); } else { setCount(this->count + count); } @@ -39,6 +44,27 @@ void ItemStack::move(ItemStack& item, const ContentIndices& indices) { void ItemStack::setCount(itemcount_t count) { this->count = count; if (count == 0) { - item = 0; + clear(); } } + +void ItemStack::setField(std::string_view name, dv::value value) { + if (fields == nullptr) { + if (value == nullptr) { + return; + } + fields = dv::object(); + } + if (value == nullptr) { + fields.erase(std::string(name)); + return; + } + fields[std::string(name)] = std::move(value); +} + +dv::value* ItemStack::getField(const std::string& name) const { + if (fields == nullptr) { + return nullptr; + } + return fields.at(name).ptr; +} diff --git a/src/items/ItemStack.hpp b/src/items/ItemStack.hpp index e2892bf3..c7ff7e0c 100644 --- a/src/items/ItemStack.hpp +++ b/src/items/ItemStack.hpp @@ -2,20 +2,31 @@ #include "constants.hpp" #include "typedefs.hpp" +#include "data/dv.hpp" class ContentIndices; class ItemStack { itemid_t item = ITEM_EMPTY; itemcount_t count = 0; + dv::value fields = nullptr; public: ItemStack() = default; - ItemStack(itemid_t item, itemcount_t count); + ItemStack(itemid_t item, itemcount_t count, dv::value data=nullptr); void set(const ItemStack& item); + void set(ItemStack&& item); void setCount(itemcount_t count); + /// @brief Set a field in the item stack data. + void setField(std::string_view name, dv::value value); + + /// @brief Get a field from the item stack data. + /// @param name field name + /// @return value pointer or nullptr if the field does not exist. + dv::value* getField(const std::string& name) const; + bool accepts(const ItemStack& item) const; /// @brief Move items from one stack to another. @@ -24,19 +35,23 @@ public: /// @param indices content indices void move(ItemStack& item, const ContentIndices& indices); - inline void clear() { + void clear() { set(ItemStack(0, 0)); } - inline bool isEmpty() const { + bool isEmpty() const { return item == ITEM_EMPTY; } - inline itemid_t getItemId() const { + itemid_t getItemId() const { return item; } - inline itemcount_t getCount() const { + itemcount_t getCount() const { return count; } + + const dv::value& getFields() const { + return fields; + } };