diff --git a/docs/lua-api-gui-inventory.md b/docs/lua-api-gui-inventory.md index 93791f690..32bd92ab6 100644 --- a/docs/lua-api-gui-inventory.md +++ b/docs/lua-api-gui-inventory.md @@ -123,6 +123,15 @@ Possible values: - `block`: Set a specific block as the source - `temp`: Set a temporary inventory as the source +### `is_read_only` + +Defines if the inventory is read-only or not. + +Example: +```lua +is_read_only = false -- this is the default value +``` + ### `name` Name of the widget. **Mandatory field.** diff --git a/mods/default/blocks/furnace.lua b/mods/default/blocks/furnace.lua index e22a3f55a..3565f37bc 100644 --- a/mods/default/blocks/furnace.lua +++ b/mods/default/blocks/furnace.lua @@ -99,6 +99,8 @@ mod:block { count = 1, }, + is_read_only = true, + size = {x = 1, y = 1}, shift_destination = "inv_main,inv_hotbar", diff --git a/source/client/gui/AbstractInventoryWidget.hpp b/source/client/gui/AbstractInventoryWidget.hpp index ede15c173..7fa233fd5 100644 --- a/source/client/gui/AbstractInventoryWidget.hpp +++ b/source/client/gui/AbstractInventoryWidget.hpp @@ -31,7 +31,8 @@ class AbstractInventoryWidget : public Widget { public: - AbstractInventoryWidget(Widget *parent) : Widget(parent) {} + AbstractInventoryWidget(Widget *parent, bool isReadOnly = false) + : Widget(parent), m_isReadOnly(isReadOnly) {} virtual bool sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) = 0; virtual bool receiveItemStack(const ItemWidget *itemStack, AbstractInventoryWidget *src) = 0; @@ -44,10 +45,14 @@ class AbstractInventoryWidget : public Widget { void setFilter(const std::string &filter) { m_filter = filter; } bool doItemMatchFilter(const Item &item); + bool isReadOnly() const { return m_isReadOnly; } + protected: std::vector m_shiftDestination; std::string m_filter; + + bool m_isReadOnly = false; }; #endif // ABSTRACTINVENTORYWIDGET_HPP_ diff --git a/source/client/gui/InventoryWidget.hpp b/source/client/gui/InventoryWidget.hpp index fa102908c..10c1381a6 100644 --- a/source/client/gui/InventoryWidget.hpp +++ b/source/client/gui/InventoryWidget.hpp @@ -37,7 +37,7 @@ class ClientCommandHandler; class InventoryWidget : public AbstractInventoryWidget { public: InventoryWidget(ClientCommandHandler &client, bool isReadOnly = false, Widget *parent = nullptr) - : AbstractInventoryWidget(parent), m_client(client), m_isReadOnly(isReadOnly) {} + : AbstractInventoryWidget(parent, isReadOnly), m_client(client) {} void init(Inventory &inventory, u16 offset = 0, u16 size = 0); @@ -54,8 +54,6 @@ class InventoryWidget : public AbstractInventoryWidget { Inventory *inventory() const { return m_inventory; } - bool isReadOnly() const { return m_isReadOnly; } - ItemWidget *currentItemWidget() const { return m_currentItemWidget; } private: @@ -73,8 +71,6 @@ class InventoryWidget : public AbstractInventoryWidget { u16 m_offset = 0; u16 m_size = 0; - bool m_isReadOnly = false; - std::vector m_itemWidgets; ItemWidget *m_currentItemWidget = nullptr; diff --git a/source/client/gui/MouseItemWidget.cpp b/source/client/gui/MouseItemWidget.cpp index ec909ea92..70e733ff7 100644 --- a/source/client/gui/MouseItemWidget.cpp +++ b/source/client/gui/MouseItemWidget.cpp @@ -171,7 +171,7 @@ void MouseItemWidget::draggingBehaviour(ItemWidget *newItemWidget) { void MouseItemWidget::updateCurrentItem(ItemWidget *currentItemWidget) { if (currentItemWidget) { - bool doItemMatchFilter = !m_currentInventoryWidget || m_currentInventoryWidget->doItemMatchFilter(m_draggedStack.item()); + bool doItemMatchFilter = !m_currentInventoryWidget || (m_currentInventoryWidget->doItemMatchFilter(m_draggedStack.item()) && !m_currentInventoryWidget->isReadOnly()); if (m_isDragging && currentItemWidget != m_currentItemWidget && doItemMatchFilter) draggingBehaviour(currentItemWidget); diff --git a/source/client/states/LuaGUIState.cpp b/source/client/states/LuaGUIState.cpp index 69b02557e..43a4c16f0 100644 --- a/source/client/states/LuaGUIState.cpp +++ b/source/client/states/LuaGUIState.cpp @@ -225,7 +225,9 @@ void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf: std::string inventory, shiftDestination, filter; u16 width, height; u16 offset, count; - packet >> width >> height >> shiftDestination >> offset >> count >> inventory >> filter; + bool isReadOnly; + packet >> width >> height >> shiftDestination >> offset >> count >> inventory + >> filter >> isReadOnly; Inventory *widgetInventory = nullptr; if (inventory == "player") { @@ -264,7 +266,7 @@ void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf: } if (widgetInventory) { - m_inventoryWidgets.emplace(name, InventoryWidget{m_client, false, &m_mainWidget}); + m_inventoryWidgets.emplace(name, InventoryWidget{m_client, isReadOnly, &m_mainWidget}); auto &inventoryWidget = m_inventoryWidgets.at(name); inventoryWidget.setPosition(x, y); diff --git a/source/server/gui/InventoryWidgetDef.cpp b/source/server/gui/InventoryWidgetDef.cpp index 1bf86f220..88e329288 100644 --- a/source/server/gui/InventoryWidgetDef.cpp +++ b/source/server/gui/InventoryWidgetDef.cpp @@ -32,7 +32,7 @@ void InventoryWidgetDef::serialize(sf::Packet &packet) const { WidgetDef::serialize(packet); packet << m_width << m_height << m_shiftDestination << m_offset << m_count - << m_inventory << m_filter; + << m_inventory << m_filter << m_isReadOnly; if (m_inventory == "player") packet << m_player << m_inventoryName; @@ -49,6 +49,7 @@ void InventoryWidgetDef::loadFromLuaTable(const sol::table &table) { m_shiftDestination = table["shift_destination"].get_or(""); m_filter = table["filter"].get_or(""); + m_isReadOnly = table["is_read_only"].get_or(false); sol::optional size = table["size"]; if (size != sol::nullopt) { diff --git a/source/server/gui/InventoryWidgetDef.hpp b/source/server/gui/InventoryWidgetDef.hpp index 51551d9de..e9c011228 100644 --- a/source/server/gui/InventoryWidgetDef.hpp +++ b/source/server/gui/InventoryWidgetDef.hpp @@ -56,6 +56,7 @@ class InventoryWidgetDef : public WidgetDef { u16 m_count = 0; std::string m_filter; + bool m_isReadOnly = false; }; #endif // INVENTORYWIDGETDEF_HPP_