diff --git a/data/items/items.xml b/data/items/items.xml index 75d92f76447..9419a89262b 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -37971,18 +37971,21 @@ + + + @@ -37995,6 +37998,7 @@ + @@ -38002,12 +38006,14 @@ + + @@ -38020,96 +38026,112 @@ + + + + + + + + + + + + + + + + @@ -40302,10 +40324,12 @@ + + diff --git a/data/modules/scripts/gamestore/init.lua b/data/modules/scripts/gamestore/init.lua index ee1315e4cdd..11fdd3866c4 100644 --- a/data/modules/scripts/gamestore/init.lua +++ b/data/modules/scripts/gamestore/init.lua @@ -1491,7 +1491,7 @@ function GameStore.processItemPurchase(player, offerId, offerCount, moveable) end local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) - if inbox and inbox:getEmptySlots() > offerCount then + if inbox then for t = 1, offerCount do local inboxItem = inbox:addItem(offerId, offerCount or 1) if moveable ~= true and inboxItem then @@ -1509,7 +1509,7 @@ function GameStore.processChargesPurchase(player, itemtype, name, charges, movea end local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) - if inbox and inbox:getEmptySlots() > 1 then + if inbox then local inboxItem = inbox:addItem(itemtype, charges) if moveable ~= true and inboxItem then @@ -1570,7 +1570,7 @@ function GameStore.processStackablePurchase(player, offerId, offerCount, offerNa end local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) - if inbox and inbox:getEmptySlots() > 0 then + if inbox then if (isKeg and offerCount > 500) or offerCount > 100 then local parcel = inbox:addItem(PARCEL_ID, 1) parcel:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime()); @@ -1627,7 +1627,7 @@ function GameStore.processHouseRelatedPurchase(player, offer) if type(itemIds) ~= "table" then itemIds = { itemIds } end - if inbox and inbox:getEmptySlots() >= #itemIds then + if inbox then for _, itemId in ipairs(itemIds) do local decoKit = inbox:addItem(23398, 1) if decoKit then @@ -1642,6 +1642,7 @@ function GameStore.processHouseRelatedPurchase(player, offer) end end end + player:sendUpdateContainer(inbox) else return error({ code = 0, message = "Please make sure you have free slots in your store inbox." }) end diff --git a/src/config/config_definitions.hpp b/src/config/config_definitions.hpp index f6df1d37b46..56c68b5db5e 100644 --- a/src/config/config_definitions.hpp +++ b/src/config/config_definitions.hpp @@ -154,7 +154,7 @@ enum integerConfig_t { STATUS_PORT, STAIRHOP_DELAY, MAX_CONTAINER, - MAX_ITEM, + MAX_CONTAINER_ITEM, MARKET_OFFER_DURATION, DEPOT_BOXES, FREE_DEPOT_LIMIT, diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 5bed1cd17ba..8fa823fe96e 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -233,7 +233,7 @@ bool ConfigManager::load() { integer[WHITE_SKULL_TIME] = getGlobalNumber(L, "whiteSkullTime", 15 * 60 * 1000); integer[STAIRHOP_DELAY] = getGlobalNumber(L, "stairJumpExhaustion", 2000); integer[MAX_CONTAINER] = getGlobalNumber(L, "maxContainer", 500); - integer[MAX_ITEM] = getGlobalNumber(L, "maxItem", 10000); + integer[MAX_CONTAINER_ITEM] = getGlobalNumber(L, "maxItem", 5000); integer[EXP_FROM_PLAYERS_LEVEL_RANGE] = getGlobalNumber(L, "expFromPlayersLevelRange", 75); integer[CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES] = getGlobalNumber(L, "checkExpiredMarketOffersEachMinutes", 60); integer[MAX_MARKET_OFFERS_AT_A_TIME_PER_PLAYER] = getGlobalNumber(L, "maxMarketOffersAtATimePerPlayer", 100); diff --git a/src/enums/item_attribute.hpp b/src/enums/item_attribute.hpp index 40934aa61ee..a245f3d5eb9 100644 --- a/src/enums/item_attribute.hpp +++ b/src/enums/item_attribute.hpp @@ -44,6 +44,7 @@ enum ItemAttribute_t : uint64_t { STORE = 31, CUSTOM = 32, LOOTMESSAGE_SUFFIX = 33, + STORE_INBOX_CATEGORY = 34, }; enum ItemDecayState_t : uint8_t { diff --git a/src/game/game.cpp b/src/game/game.cpp index 2564736aefc..da9aec2d660 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -4108,7 +4108,7 @@ void Game::playerStashWithdraw(uint32_t playerId, uint16_t itemId, uint32_t coun } } -void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index) { +void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index, uint8_t containerCategory) { Player* player = getPlayerByID(playerId); if (!player) { return; @@ -4119,6 +4119,12 @@ void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_ return; } + if (container->getID() == ITEM_STORE_INBOX) { + auto enumName = magic_enum::enum_name(static_cast(containerCategory)).data(); + container->setAttribute(ItemAttribute_t::STORE_INBOX_CATEGORY, enumName); + g_logger().debug("Setting new container with store inbox category name {}", enumName); + } + if ((index % container->capacity()) != 0 || index >= container->size()) { return; } diff --git a/src/game/game.hpp b/src/game/game.hpp index 8b7f7597e5d..4ebc928f4ff 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -295,7 +295,7 @@ class Game { void playerWrapableItem(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId); void playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std::string &text); void playerBrowseField(uint32_t playerId, const Position &pos); - void playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index); + void playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index, uint8_t containerCategory); void playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t windowTextId, const std::string &text); void playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t stackPos, uint32_t tradePlayerId, uint16_t itemId); void playerAcceptTrade(uint32_t playerId); diff --git a/src/items/containers/container.cpp b/src/items/containers/container.cpp index 8c1683c47cd..723760ac781 100644 --- a/src/items/containers/container.cpp +++ b/src/items/containers/container.cpp @@ -16,8 +16,11 @@ Container::Container(uint16_t type) : Container(type, items[type].maxItems) { - if (getID() == ITEM_GOLD_POUCH) { + m_maxItems = static_cast(g_configManager().getNumber(MAX_CONTAINER_ITEM)); + if (getID() == ITEM_GOLD_POUCH || getID() == ITEM_STORE_INBOX) { pagination = true; + m_maxItems = 2000; + maxSize = 32; } } @@ -371,22 +374,21 @@ ReturnValue Container::queryAdd(int32_t addIndex, const Thing &addThing, uint32_ } if (const Container* topParentContainer = getTopParentContainer()) { - uint32_t maxItem = static_cast(g_configManager().getNumber(MAX_ITEM)); if (const Container* addContainer = item->getContainer()) { uint32_t addContainerCount = addContainer->getContainerHoldingCount() + 1; uint32_t maxContainer = static_cast(g_configManager().getNumber(MAX_CONTAINER)); if (addContainerCount + topParentContainer->getContainerHoldingCount() > maxContainer) { - return RETURNVALUE_NOTPOSSIBLE; + return RETURNVALUE_CONTAINERISFULL; } uint32_t addItemCount = addContainer->getItemHoldingCount() + 1; - if (addItemCount + topParentContainer->getItemHoldingCount() > maxItem) { - return RETURNVALUE_NOTPOSSIBLE; + if (addItemCount + topParentContainer->getItemHoldingCount() > m_maxItems) { + return RETURNVALUE_CONTAINERISFULL; } } - if (topParentContainer->getItemHoldingCount() + 1 > maxItem) { - return RETURNVALUE_NOTPOSSIBLE; + if (topParentContainer->getItemHoldingCount() + 1 > m_maxItems) { + return RETURNVALUE_CONTAINERISFULL; } } diff --git a/src/items/containers/container.hpp b/src/items/containers/container.hpp index 30bc4003229..3ea2a2ac1a2 100644 --- a/src/items/containers/container.hpp +++ b/src/items/containers/container.hpp @@ -168,6 +168,7 @@ class Container : public Item, public Cylinder { protected: std::ostringstream &getContentDescription(std::ostringstream &os, bool oldProtocol) const; + uint32_t m_maxItems; uint32_t maxSize; uint32_t totalWeight = 0; ItemDeque itemlist; diff --git a/src/items/functions/item/attribute.hpp b/src/items/functions/item/attribute.hpp index 20cf4369435..4a68cc0ec7b 100644 --- a/src/items/functions/item/attribute.hpp +++ b/src/items/functions/item/attribute.hpp @@ -57,6 +57,7 @@ class ItemAttributeHelper { case ItemAttribute_t::PLURALNAME: case ItemAttribute_t::SPECIAL: case ItemAttribute_t::LOOTMESSAGE_SUFFIX: + case ItemAttribute_t::STORE_INBOX_CATEGORY: return true; default: return false; diff --git a/src/items/functions/item/item_parse.cpp b/src/items/functions/item/item_parse.cpp index b3324f8dd73..2172326f097 100644 --- a/src/items/functions/item/item_parse.cpp +++ b/src/items/functions/item/item_parse.cpp @@ -56,7 +56,6 @@ void ItemParse::initParse(const std::string &tmpStrValue, pugi::xml_node attribu ItemParse::parseMagicLevelPoint(tmpStrValue, valueAttribute, itemType); ItemParse::parseFieldAbsorbPercent(tmpStrValue, valueAttribute, itemType); ItemParse::parseAbsorbPercent(tmpStrValue, valueAttribute, itemType); - ItemParse::parseSupressDrunk(tmpStrValue, valueAttribute, itemType); ItemParse::parseField(tmpStrValue, attributeNode, valueAttribute, itemType); ItemParse::parseReplaceable(tmpStrValue, valueAttribute, itemType); @@ -73,6 +72,7 @@ void ItemParse::initParse(const std::string &tmpStrValue, pugi::xml_node attribu ItemParse::parseCleavePercent(tmpStrValue, valueAttribute, itemType); ItemParse::parseReflectDamage(tmpStrValue, valueAttribute, itemType); ItemParse::parseTransformOnUse(tmpStrValue, valueAttribute, itemType); + ItemParse::parsePrimaryType(tmpStrValue, valueAttribute, itemType); } void ItemParse::parseDummyRate(pugi::xml_node attributeNode, ItemType &itemType) { @@ -940,3 +940,9 @@ void ItemParse::parseTransformOnUse(const std::string_view &tmpStrValue, pugi::x itemType.m_transformOnUse = pugi::cast(valueAttribute.value()); } } + +void ItemParse::parsePrimaryType(const std::string_view &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType) { + if (tmpStrValue == "primarytype") { + itemType.m_primaryType = asLowerCaseString(valueAttribute.as_string()); + } +} diff --git a/src/items/functions/item/item_parse.hpp b/src/items/functions/item/item_parse.hpp index 28a8e71fc53..510129df918 100644 --- a/src/items/functions/item/item_parse.hpp +++ b/src/items/functions/item/item_parse.hpp @@ -155,6 +155,7 @@ const phmap::flat_hash_map ItemParseAttribut { "cleavepercent", ITEM_PARSE_CLEAVEPERCENT }, { "reflectdamage", ITEM_PARSE_REFLECTDAMAGE }, { "reflectpercentall", ITEM_PARSE_REFLECTPERCENTALL }, + { "primarytype", ITEM_PARSE_PRIMARYTYPE }, }; const phmap::flat_hash_map ItemTypesMap = { @@ -308,6 +309,7 @@ class ItemParse : public Items { static void parseCleavePercent(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parseReflectDamage(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parseTransformOnUse(const std::string_view &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); + static void parsePrimaryType(const std::string_view &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); private: // Parent of the function: static void parseField diff --git a/src/items/item.cpp b/src/items/item.cpp index a33ce1c39dd..5dca9c257e5 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -794,6 +794,17 @@ Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream &propStream) { break; } + case ATTR_STORE_INBOX_CATEGORY: { + std::string category; + if (!propStream.readString(category)) { + g_logger().error("[{}] failed to read store inbox category from item {}", __FUNCTION__, getName()); + return ATTR_READ_ERROR; + } + + setAttribute(ItemAttribute_t::STORE_INBOX_CATEGORY, category); + break; + } + default: return ATTR_READ_ERROR; } @@ -954,6 +965,10 @@ void Item::serializeAttr(PropWriteStream &propWriteStream) const { propWriteStream.write(ATTR_AMOUNT); propWriteStream.write(getAttribute(AMOUNT)); } + if (hasAttribute(STORE_INBOX_CATEGORY)) { + propWriteStream.write(ATTR_STORE_INBOX_CATEGORY); + propWriteStream.writeString(getString(ItemAttribute_t::STORE_INBOX_CATEGORY)); + } // Serialize custom attributes, only serialize if the map not is empty if (hasCustomAttribute()) { diff --git a/src/items/item.hpp b/src/items/item.hpp index 2d4c3a5a4d2..c6b3f82413f 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -35,7 +35,7 @@ class Item; class ItemProperties { public: template - T getAttribute(ItemAttribute_t type) const { + const T &getAttribute(ItemAttribute_t type) const { if constexpr (std::is_same_v) { return getString(type); } else { @@ -46,7 +46,9 @@ class ItemProperties { ); } g_logger().error("Failed to convert attribute for type {}", fmt::underlying(type)); - return {}; + + static T defaultType; + return defaultType; } bool hasAttribute(ItemAttribute_t type) const { diff --git a/src/items/items.hpp b/src/items/items.hpp index 59a65d0d8db..6e58cddd19c 100644 --- a/src/items/items.hpp +++ b/src/items/items.hpp @@ -233,6 +233,7 @@ class ItemType { std::string description; std::string runeSpellName; std::string vocationString; + std::string m_primaryType; std::unique_ptr abilities; std::unique_ptr conditionDamage; diff --git a/src/items/items_definitions.hpp b/src/items/items_definitions.hpp index 85dee43bf1a..fec5c424fb8 100644 --- a/src/items/items_definitions.hpp +++ b/src/items/items_definitions.hpp @@ -60,6 +60,7 @@ enum ReturnValue { RETURNVALUE_CANNOTPICKUP, RETURNVALUE_THISISIMPOSSIBLE, RETURNVALUE_DEPOTISFULL, + RETURNVALUE_CONTAINERISFULL, RETURNVALUE_CREATUREDOESNOTEXIST, RETURNVALUE_CANNOTUSETHISOBJECT, RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE, @@ -234,6 +235,7 @@ enum AttrTypes_t { ATTR_AMOUNT = 39, ATTR_TIER = 40, ATTR_CUSTOM = 41, + ATTR_STORE_INBOX_CATEGORY = 42, // Always the last ATTR_NONE = 0 @@ -261,6 +263,15 @@ enum ImbuementTypes_t : int64_t { IMBUEMENT_INCREASE_CAPACITY = 17 }; +enum class StoreInboxCategory_t : uint8_t { + All, + Consumable, + Bundle, + Furniture, + Houses, + Extra +}; + enum SlotPositionBits : uint32_t { SLOTP_WHEREEVER = 0xFFFFFFFF, SLOTP_HEAD = 1 << 0, @@ -465,6 +476,7 @@ enum ItemParseAttributes_t { ITEM_PARSE_CLEAVEPERCENT, ITEM_PARSE_REFLECTPERCENTALL, ITEM_PARSE_REFLECTDAMAGE, + ITEM_PARSE_PRIMARYTYPE, }; struct ImbuementInfo { diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index c616053a5e4..ec76c89e735 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -1894,6 +1894,25 @@ int PlayerFunctions::luaPlayerSendContainer(lua_State* L) { return 1; } +int PlayerFunctions::luaPlayerSendUpdateContainer(lua_State* L) { + // player:sendUpdateContainer(container) + Player* player = getUserdata(L, 1); + if (!player) { + lua_pushnil(L); + return 1; + } + + Container* container = getUserdata(L, 2); + if (!container) { + reportErrorFunc("Container is nullptr"); + return 1; + } + + player->onSendContainer(container); + pushBoolean(L, true); + return 1; +} + int PlayerFunctions::luaPlayerGetMoney(lua_State* L) { // player:getMoney() Player* player = getUserdata(L, 1); diff --git a/src/lua/functions/creatures/player/player_functions.hpp b/src/lua/functions/creatures/player/player_functions.hpp index 294c77de52e..83abc83b1f4 100644 --- a/src/lua/functions/creatures/player/player_functions.hpp +++ b/src/lua/functions/creatures/player/player_functions.hpp @@ -173,6 +173,7 @@ class PlayerFunctions final : LuaScriptInterface { registerMethod(L, "Player", "removeStashItem", PlayerFunctions::luaPlayerRemoveStashItem); registerMethod(L, "Player", "removeItem", PlayerFunctions::luaPlayerRemoveItem); registerMethod(L, "Player", "sendContainer", PlayerFunctions::luaPlayerSendContainer); + registerMethod(L, "Player", "sendUpdateContainer", PlayerFunctions::luaPlayerSendUpdateContainer); registerMethod(L, "Player", "getMoney", PlayerFunctions::luaPlayerGetMoney); registerMethod(L, "Player", "addMoney", PlayerFunctions::luaPlayerAddMoney); @@ -503,6 +504,7 @@ class PlayerFunctions final : LuaScriptInterface { static int luaPlayerRemoveStashItem(lua_State* L); static int luaPlayerRemoveItem(lua_State* L); static int luaPlayerSendContainer(lua_State* L); + static int luaPlayerSendUpdateContainer(lua_State* L); static int luaPlayerGetMoney(lua_State* L); static int luaPlayerAddMoney(lua_State* L); diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index d2c435663bd..dd386e13a0b 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -207,6 +207,33 @@ namespace { } } } + + /** + * @brief Sends the container category to the network message. + * + * @note The default value is "all", which is the first enum (0). The message must always start with "All". + * + * @details for example of enum see the StoreInboxCategory_t + * + * @param msg The network message to send the category to. + */ + template + void sendContainerCategory(NetworkMessage &msg, uint8_t categoryType = 0) { + msg.addByte(categoryType); + + const uint8_t enumCount = magic_enum::enum_count(); + msg.addByte(enumCount - 1); + + for (auto value : magic_enum::enum_values()) { + if (value == T::All) { + continue; + } + + msg.addByte(static_cast(value)); + msg.addString(magic_enum::enum_name(value).data()); + } + } + } // namespace ProtocolGame::ProtocolGame(Connection_ptr initConnection) : @@ -278,7 +305,7 @@ void ProtocolGame::AddItem(NetworkMessage &msg, uint16_t id, uint8_t count, uint msg.addByte(0x01); // Brand-new } - if (it.isWrapKit) { + if (it.isWrapKit && !oldProtocol) { msg.add(0x00); } } @@ -409,7 +436,7 @@ void ProtocolGame::AddItem(NetworkMessage &msg, const Item* item) { } } - if (it.isWrapKit) { + if (it.isWrapKit && !oldProtocol) { uint16_t unWrapId = item->getCustomAttribute("unWrapId") ? static_cast(item->getCustomAttribute("unWrapId")->getInteger()) : 0; if (unWrapId != 0) { msg.add(unWrapId); @@ -3092,7 +3119,8 @@ void ProtocolGame::parseBrowseField(NetworkMessage &msg) { void ProtocolGame::parseSeekInContainer(NetworkMessage &msg) { uint8_t containerId = msg.getByte(); uint16_t index = msg.get(); - addGameTask(&Game::playerSeekInContainer, player->getID(), containerId, index); + auto primaryType = msg.getByte(); + addGameTask(&Game::playerSeekInContainer, player->getID(), containerId, index, primaryType); } // Send methods @@ -4209,6 +4237,10 @@ void ProtocolGame::sendUnjustifiedPoints(const uint8_t &dayProgress, const uint8 } void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex) { + if (!player) { + return; + } + NetworkMessage msg; msg.addByte(0x6E); @@ -4222,6 +4254,22 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h msg.addString(container->getName()); } + const auto &enumName = container->getAttribute(ItemAttribute_t::STORE_INBOX_CATEGORY); + uint32_t totalCountToSend = 0; + std::vector itemsStoreInboxToSend; + if (container->getID() == ITEM_STORE_INBOX && enumName != "All") { + for (Item* item : container->getItemList()) { + uint16_t unWrapId = item->getCustomAttribute("unWrapId") ? static_cast(item->getCustomAttribute("unWrapId")->getInteger()) : 0; + if (unWrapId != 0) { + const auto &itemType = Item::items.getItemType(unWrapId); + if (itemType.m_primaryType == asLowerCaseString(enumName)) { + itemsStoreInboxToSend.push_back(item); + totalCountToSend++; + } + } + } + } + msg.addByte(container->capacity()); msg.addByte(hasParent ? 0x01 : 0x00); @@ -4235,6 +4283,9 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h msg.addByte(container->hasPagination() ? 0x01 : 0x00); // Pagination uint32_t containerSize = container->size(); + if (totalCountToSend != 0) { + containerSize = totalCountToSend; + } msg.add(containerSize); msg.add(firstIndex); @@ -4248,6 +4299,11 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h if (firstIndex >= containerSize) { msg.addByte(0x00); + } else if (container->getID() == ITEM_STORE_INBOX && !itemsStoreInboxToSend.empty()) { + msg.addByte(std::min(maxItemsToSend, containerSize)); + for (const auto item : itemsStoreInboxToSend) { + AddItem(msg, item); + } } else { msg.addByte(std::min(maxItemsToSend, containerSize)); @@ -4256,9 +4312,20 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h for (ItemDeque::const_iterator it = itemList.begin() + firstIndex, end = itemList.end(); i < maxItemsToSend && it != end; ++it, ++i) { AddItem(msg, *it); } + } - msg.addByte(0x00); - msg.addByte(0x00); + if (!oldProtocol) { + if (container->getID() == ITEM_STORE_INBOX) { + auto category = magic_enum::enum_cast(enumName); + if (category.has_value()) { + sendContainerCategory(msg, static_cast(category.value())); + } else { + sendContainerCategory(msg); + } + } else { + msg.addByte(0x00); + msg.addByte(0x00); + } } writeToOutputBuffer(msg); } diff --git a/src/utils/tools.cpp b/src/utils/tools.cpp index e990e8ba8a3..09e0867472e 100644 --- a/src/utils/tools.cpp +++ b/src/utils/tools.cpp @@ -1258,6 +1258,9 @@ const char* getReturnMessage(ReturnValue value) { case RETURNVALUE_DEPOTISFULL: return "You cannot put more items in this depot."; + case RETURNVALUE_CONTAINERISFULL: + return "You cannot put more items in this container."; + case RETURNVALUE_CANNOTUSETHISOBJECT: return "You cannot use this object.";