diff --git a/doc/en/item-properties.md b/doc/en/item-properties.md index 0240676b..8abcb93c 100644 --- a/doc/en/item-properties.md +++ b/doc/en/item-properties.md @@ -18,6 +18,14 @@ Name of the item model. The model will be loaded automatically. Default value is `packid:itemname.model`. If the model is not specified, an automatic one will be generated. +### Caption and Description +`caption` - name of item in inventory +`description` - item description in inventory + +this props allow to use `md` + +*see [Text Styles](/doc/en/text-styles.md)* + ## Behaviour ### *placing-block* diff --git a/doc/en/scripting/builtins/libinventory.md b/doc/en/scripting/builtins/libinventory.md index 428761d5..8cf2d7c3 100644 --- a/doc/en/scripting/builtins/libinventory.md +++ b/doc/en/scripting/builtins/libinventory.md @@ -97,6 +97,40 @@ inventory.set(...) inventory.set_all_data(...) ``` for moving is inefficient, use inventory.move or inventory.move_range. +```lua +-- Get item caption +inventory.get_caption( + -- id of inventory + invid: int, + -- slot id + slot: int +) +-- Set item caption +inventory.set_caption( + -- id of inventory + invid: int, + -- slot id + slot: int, + -- Item Caption + caption: string +) +-- Get item description +inventory.get_description( + -- id of inventory + invid: int, + -- slot id + slot: int +) +-- Set item description +inventory.set_description( + -- id of inventory + invid: int, + -- slot id + slot: int, + -- Item Description + description: string +) +``` ```lua -- Returns a copy of value of a local property of an item by name or nil. diff --git a/doc/en/scripting/builtins/libitem.md b/doc/en/scripting/builtins/libitem.md index a2d01632..25a7e48f 100644 --- a/doc/en/scripting/builtins/libitem.md +++ b/doc/en/scripting/builtins/libitem.md @@ -10,6 +10,9 @@ item.index(name: str) -> int -- Returns the item display name. block.caption(blockid: int) -> str +-- Returns the item display description. +item.description(itemid: int) -> str + -- Returns max stack size for the item item.stack_size(itemid: int) -> int diff --git a/doc/ru/item-properties.md b/doc/ru/item-properties.md index 68803296..8a75ca72 100644 --- a/doc/ru/item-properties.md +++ b/doc/ru/item-properties.md @@ -17,6 +17,14 @@ Значение по-умолчанию - `packid:itemname.model`. Если модель не указана, будет сгенерирована автоматическию +### Имя и Описание +`caption` - имя предмета в инвентаре +`description` - описание предмета в инвентаре + +Можно использовать `md` + +*см. [Text Styles](/doc/en/text-styles.md)* + ## Поведение ### Устанавливаемый блок - `placing-block` diff --git a/doc/ru/scripting/builtins/libinventory.md b/doc/ru/scripting/builtins/libinventory.md index 7e939ddd..97fa56ff 100644 --- a/doc/ru/scripting/builtins/libinventory.md +++ b/doc/ru/scripting/builtins/libinventory.md @@ -94,6 +94,40 @@ inventory.set(...) inventory.set_all_data(...) ``` для перемещения вляется неэффективным, используйте inventory.move или inventory.move_range. +```lua +-- Получает имя предмета в слоте +inventory.get_caption( + -- id инвентаря + invid: int, + -- индекс слота + slot: int +) +-- Задает имя предмету в слоте +inventory.set_caption( + -- id инвентаря + invid: int, + -- индекс слота + slot: int, + -- Имя предмета + caption: string +) +-- Получает описание предмета в слоте +inventory.get_description( + -- id инвентаря + invid: int, + -- индекс слота + slot: int +) +-- Задает описание предмету в слоте +inventory.set_description( + -- id инвентаря + invid: int, + -- индекс слота + slot: int, + -- Описание предмета + description: string +) +``` ```lua -- Проверяет наличие локального свойства по имени без копирования его значения. diff --git a/doc/ru/scripting/builtins/libitem.md b/doc/ru/scripting/builtins/libitem.md index 5baaed68..265bf099 100644 --- a/doc/ru/scripting/builtins/libitem.md +++ b/doc/ru/scripting/builtins/libitem.md @@ -10,6 +10,9 @@ item.index(name: str) -> int -- Возвращает название предмета, отображаемое в интерфейсе. item.caption(itemid: int) -> str +-- Возвращает описание предмета, отображаемое в интерфейсе. +item.description(itemid: int) -> str + -- Возвращает максимальный размер стопки для предмета. item.stack_size(itemid: int) -> int diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 3729d516..8a60d6b5 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -131,6 +131,44 @@ function inventory.decrement(invid, slot, count) end end +function inventory.get_caption(invid, slot) + local item_id, count = inventory.get(invid, slot) + local caption = inventory.get_data(invid, slot, "caption") + if not caption then return item.caption(item_id) end + + return caption +end + +function inventory.set_caption(invid, slot, caption) + local itemid, itemcount = inventory.get(invid, slot) + if itemid == 0 then + return + end + if caption == nil or type(caption) ~= "string" then + caption = "" + end + inventory.set_data(invid, slot, "caption", caption) +end + +function inventory.get_description(invid, slot) + local item_id, count = inventory.get(invid, slot) + local description = inventory.get_data(invid, slot, "description") + if not description then return item.description(item_id) end + + return description +end + +function inventory.set_description(invid, slot, description) + local itemid, itemcount = inventory.get(invid, slot) + if itemid == 0 then + return + end + if description == nil or type(description) ~= "string" then + description = "" + end + inventory.set_data(invid, slot, "description", description) +end + ------------------------------------------------ ------------------- Events --------------------- ------------------------------------------------ diff --git a/src/content/loading/ItemLoader.cpp b/src/content/loading/ItemLoader.cpp index 6367ccd5..1703b778 100644 --- a/src/content/loading/ItemLoader.cpp +++ b/src/content/loading/ItemLoader.cpp @@ -29,6 +29,7 @@ template<> void ContentUnitLoader::loadUnit( parentDef->cloneTo(def); } root.at("caption").get(def.caption); + root.at("description").get(def.description); std::string iconTypeStr = ""; root.at("icon-type").get(iconTypeStr); diff --git a/src/graphics/core/Font.cpp b/src/graphics/core/Font.cpp index 68cba17c..19abb9f0 100644 --- a/src/graphics/core/Font.cpp +++ b/src/graphics/core/Font.cpp @@ -57,6 +57,14 @@ static inline void draw_glyph( const FontStyle& style ) { for (int i = 0; i <= style.bold; i++) { + glm::vec4 color; + + if (style.color == glm::vec4(1, 1, 1, 1)) { + color = batch.getColor(); + } else { + color = style.color; + } + batch.sprite( pos.x + (offset.x + i / (right.x/glyphInterval/2.0f)) * right.x, pos.y + offset.y * right.y, @@ -65,7 +73,7 @@ static inline void draw_glyph( -0.15f * style.italic, 16, c, - batch.getColor() * style.color + color ); } } @@ -81,6 +89,15 @@ static inline void draw_glyph( const FontStyle& style ) { for (int i = 0; i <= style.bold; i++) { + glm::vec4 color; + + if (style.color == glm::vec4(1, 1, 1, 1)) { + color = batch.getColor(); + } else { + color = style.color; + } + + batch.sprite( pos + right * (offset.x + i) + up * offset.y, up, right / glyphInterval, @@ -88,7 +105,7 @@ static inline void draw_glyph( 0.5f, 16, c, - batch.getColor() * style.color + color ); } } diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 0cea8a66..ceb2f4a0 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -50,7 +50,7 @@ GUI::GUI(Engine& engine) tooltip = guiutil::create( *this, "" - "" + "" "" ); store("tooltip", tooltip); diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index b41dce98..a02a49da 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -1,10 +1,21 @@ #include "InventoryView.hpp" +#include +#include + #include "assets/Assets.hpp" #include "assets/assets_util.hpp" #include "content/Content.hpp" #include "frontend/LevelFrontend.hpp" #include "frontend/locale.hpp" +#include "graphics/core/Atlas.hpp" +#include "graphics/core/Batch2D.hpp" +#include "graphics/core/DrawContext.hpp" +#include "graphics/core/Font.hpp" +#include "graphics/core/Shader.hpp" +#include "graphics/core/Texture.hpp" +#include "graphics/render/BlocksPreview.hpp" +#include "graphics/ui/GUI.hpp" #include "items/Inventories.hpp" #include "items/Inventory.hpp" #include "items/ItemDef.hpp" @@ -15,17 +26,6 @@ #include "voxels/Block.hpp" #include "window/input.hpp" #include "world/Level.hpp" -#include "graphics/core/Atlas.hpp" -#include "graphics/core/Batch2D.hpp" -#include "graphics/core/Font.hpp" -#include "graphics/core/DrawContext.hpp" -#include "graphics/core/Shader.hpp" -#include "graphics/core/Texture.hpp" -#include "graphics/render/BlocksPreview.hpp" -#include "graphics/ui/GUI.hpp" - -#include -#include using namespace gui; @@ -37,21 +37,24 @@ SlotLayout::SlotLayout( slotcallback updateFunc, slotcallback shareFunc, slotcallback rightClick -) : index(index), - position(position), - background(background), - itemSource(itemSource), - updateFunc(std::move(updateFunc)), - shareFunc(std::move(shareFunc)), - rightClick(std::move(rightClick)) {} +) + : index(index), + position(position), + background(background), + itemSource(itemSource), + updateFunc(std::move(updateFunc)), + shareFunc(std::move(shareFunc)), + rightClick(std::move(rightClick)) { +} InventoryBuilder::InventoryBuilder(GUI& gui) : gui(gui) { view = std::make_shared(gui); } void InventoryBuilder::addGrid( - int cols, int count, - glm::vec2 pos, + int cols, + int count, + glm::vec2 pos, glm::vec4 padding, bool addpanel, const SlotLayout& slotLayout @@ -61,9 +64,11 @@ void InventoryBuilder::addGrid( int rows = ceildiv(count, cols); - uint width = cols * (slotSize + interval) - interval + padding.x + padding.z; - uint height = rows * (slotSize + interval) - interval + padding.y + padding.w; - + uint width = + cols * (slotSize + interval) - interval + padding.x + padding.z; + uint height = + rows * (slotSize + interval) - interval + padding.y + padding.w; + glm::vec2 vsize = view->getSize(); if (pos.x + width > vsize.x) { vsize.x = pos.x + width; @@ -85,7 +90,7 @@ void InventoryBuilder::addGrid( if (row * cols + col >= count) { break; } - glm::vec2 position ( + glm::vec2 position( col * (slotSize + interval) + padding.x, row * (slotSize + interval) + padding.y ); @@ -105,11 +110,9 @@ std::shared_ptr InventoryBuilder::build() { return view; } -SlotView::SlotView( - GUI& gui, SlotLayout layout -) : UINode(gui, glm::vec2(InventoryView::SLOT_SIZE)), - layout(std::move(layout)) -{ +SlotView::SlotView(GUI& gui, SlotLayout layout) + : UINode(gui, glm::vec2(InventoryView::SLOT_SIZE)), + layout(std::move(layout)) { setColor(glm::vec4(0, 0, 0, 0.2f)); setTooltipDelay(0.0f); } @@ -120,9 +123,24 @@ void SlotView::refreshTooltip(const ItemStack& stack, const ItemDef& item) { return; } if (itemid) { - tooltip = util::pascal_case( - langs::get(util::str2wstr_utf8(item.caption)) - ); + dv::value* caption = stack.getField("caption"); + dv::value* description = stack.getField("description"); + std::wstring captionText; + std::wstring descriptionText; + + if (description != nullptr) { + descriptionText = util::pascal_case( langs::get( util::str2wstr_utf8( description->asString() ) ) ); + } else { + descriptionText = util::pascal_case( langs::get( util::str2wstr_utf8( item.description ) ) ); + } + + if (caption != nullptr) { + captionText = util::pascal_case( langs::get( util::str2wstr_utf8( caption->asString() ) ) ); + } else { + captionText = util::pascal_case( langs::get( util::str2wstr_utf8( item.caption ) ) ); + } + + tooltip = captionText + L"\n" + descriptionText; } else { tooltip.clear(); } @@ -148,19 +166,37 @@ void SlotView::drawItemIcon( UVRegion region = previews.get(block.name); batch.rect( - pos.x, pos.y, SLOT_SIZE, SLOT_SIZE, - 0, 0, 0, region, false, true, tint + pos.x, + pos.y, + SLOT_SIZE, + SLOT_SIZE, + 0, + 0, + 0, + region, + false, + true, + tint ); break; } case ItemIconType::SPRITE: { auto textureRegion = util::get_texture_region(assets, item.icon, "blocks:notfound"); - + batch.texture(textureRegion.texture); batch.rect( - pos.x, pos.y, SLOT_SIZE, SLOT_SIZE, - 0, 0, 0, textureRegion.region, false, true, tint + pos.x, + pos.y, + SLOT_SIZE, + SLOT_SIZE, + 0, + 0, + 0, + textureRegion.region, + false, + true, + tint ); break; } @@ -184,7 +220,7 @@ void SlotView::draw(const DrawContext& pctx, const Assets& assets) { glm::vec4 tint(1, 1, 1, isEnabled() ? 1 : 0.5f); glm::vec2 pos = calcPos(); glm::vec4 color = getColor(); - + if (hover || highlighted) { tint *= 1.333f; color = glm::vec4(1, 1, 1, 0.2f); @@ -262,7 +298,7 @@ void SlotView::drawItemInfo( batch.setColor({0, 0, 0, 0.75f}); batch.rect(pos.x - 2, pos.y - 2, 6, SLOT_SIZE + 4); float t = static_cast(uses) / item.uses; - + int height = SLOT_SIZE * t; batch.setColor({(1.0f - t * 0.8f), 0.4f, t * 0.8f + 0.2f, 1.0f}); batch.rect(pos.x, pos.y + SLOT_SIZE - height, 2, height); @@ -317,8 +353,7 @@ void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) { } return; } - if (layout.itemSource) - return; + if (layout.itemSource) return; if (grabbed.isEmpty()) { if (!stack.isEmpty() && layout.taking) { grabbed.set(std::move(stack)); @@ -342,15 +377,15 @@ void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) { } else { grabbed = ItemStack(stack.getItemId(), count - 1); } - } else if (stack.accepts(grabbed) && stack.getCount() < stackDef.stackSize) { + } else if (stack.accepts(grabbed) && + stack.getCount() < stackDef.stackSize) { stack.setCount(stack.getCount() + 1); grabbed.setCount(grabbed.getCount() - 1); } } void SlotView::clicked(Mousecode button) { - if (bound == nullptr) - return; + if (bound == nullptr) return; auto exchangeSlot = std::dynamic_pointer_cast(gui.get(EXCHANGE_SLOT_NAME)); if (exchangeSlot == nullptr) { @@ -358,7 +393,7 @@ void SlotView::clicked(Mousecode button) { } ItemStack& grabbed = exchangeSlot->getStack(); ItemStack& stack = *bound; - + if (button == Mousecode::BUTTON_1) { performLeftClick(stack, grabbed); } else if (button == Mousecode::BUTTON_2) { @@ -382,9 +417,7 @@ const std::wstring& SlotView::getTooltip() const { } void SlotView::bind( - int64_t inventoryid, - ItemStack& stack, - const Content* content + int64_t inventoryid, ItemStack& stack, const Content* content ) { this->inventoryid = inventoryid; bound = &stack; @@ -403,11 +436,11 @@ InventoryView::InventoryView(GUI& gui) : Container(gui, glm::vec2()) { setColor(glm::vec4(0, 0, 0, 0.0f)); } -InventoryView::~InventoryView() {} - +InventoryView::~InventoryView() { +} std::shared_ptr InventoryView::addSlot(const SlotLayout& layout) { - uint width = InventoryView::SLOT_SIZE + layout.padding; + uint width = InventoryView::SLOT_SIZE + layout.padding; uint height = InventoryView::SLOT_SIZE + layout.padding; auto pos = layout.position; @@ -432,14 +465,12 @@ std::shared_ptr InventoryView::getInventory() const { return inventory; } - size_t InventoryView::getSlotsCount() const { return slots.size(); } void InventoryView::bind( - const std::shared_ptr& inventory, - const Content* content + const std::shared_ptr& inventory, const Content* content ) { this->inventory = inventory; this->content = content; diff --git a/src/items/ItemDef.cpp b/src/items/ItemDef.cpp index e2b54b81..1d362ebd 100644 --- a/src/items/ItemDef.cpp +++ b/src/items/ItemDef.cpp @@ -4,9 +4,11 @@ ItemDef::ItemDef(const std::string& name) : name(name) { caption = util::id_to_caption(name); + description = ""; } void ItemDef::cloneTo(ItemDef& dst) { dst.caption = caption; + dst.description = description; dst.stackSize = stackSize; dst.generated = generated; std::copy(&emission[0], &emission[3], dst.emission); diff --git a/src/items/ItemDef.hpp b/src/items/ItemDef.hpp index 00870cc3..4e7e120c 100644 --- a/src/items/ItemDef.hpp +++ b/src/items/ItemDef.hpp @@ -34,6 +34,9 @@ struct ItemDef { /// @brief Item name will shown in inventory std::string caption; + /// @brief Item description will shown in inventory + std::string description; + dv::value properties = nullptr; /// @brief Item max stack size diff --git a/src/logic/scripting/lua/libs/libitem.cpp b/src/logic/scripting/lua/libs/libitem.cpp index 84cfc859..d70a7211 100644 --- a/src/logic/scripting/lua/libs/libitem.cpp +++ b/src/logic/scripting/lua/libs/libitem.cpp @@ -57,6 +57,13 @@ static int l_caption(lua::State* L) { return 0; } +static int l_description(lua::State* L) { + if (auto def = get_item_def(L, 1)) { + return lua::pushstring(L, def->description); + } + return 0; +} + static int l_placing_block(lua::State* L) { if (auto def = get_item_def(L, 1)) { return lua::pushinteger(L, def->rt.placingBlock); @@ -108,6 +115,7 @@ const luaL_Reg itemlib[] = { {"defs_count", lua::wrap}, {"icon", lua::wrap}, {"caption", lua::wrap}, + {"description", lua::wrap}, {"placing_block", lua::wrap}, {"model_name", lua::wrap}, {"emission", lua::wrap},