From 419124f48f083dc468e4f82910a358860d29c223 Mon Sep 17 00:00:00 2001 From: KrecikOnDexin Date: Sun, 10 Sep 2023 22:55:10 +0200 Subject: [PATCH] Configurable stack size (#4528) --------- Co-authored-by: AKnopik PC --- data/lib/core/container.lua | 2 +- data/npc/lib/npc.lua | 4 ++-- data/npc/lib/npcsystem/modules.lua | 2 +- src/container.cpp | 15 ++++++++------- src/game.cpp | 23 ++++++++++++----------- src/game.h | 2 ++ src/iomarket.cpp | 2 +- src/luascript.cpp | 22 ++++++++++++---------- src/npc.cpp | 2 +- src/player.cpp | 8 ++++---- 10 files changed, 44 insertions(+), 38 deletions(-) diff --git a/data/lib/core/container.lua b/data/lib/core/container.lua index 672d5832e4..14d516ffec 100644 --- a/data/lib/core/container.lua +++ b/data/lib/core/container.lua @@ -20,7 +20,7 @@ function Container.createLootItem(self, item) end while itemCount > 0 do - local count = math.min(100, itemCount) + local count = math.min(ITEM_STACK_SIZE, itemCount) local subType = count if itemType:isFluidContainer() then diff --git a/data/npc/lib/npc.lua b/data/npc/lib/npc.lua index 85e4dc3adf..87cb6ff025 100644 --- a/data/npc/lib/npc.lua +++ b/data/npc/lib/npc.lua @@ -18,9 +18,9 @@ function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, bac local stuff if inBackpacks then stuff = Game.createItem(backpack, 1) - stuff:addItem(itemid, math.min(100, amount)) + stuff:addItem(itemid, math.min(ITEM_STACK_SIZE, amount)) else - stuff = Game.createItem(itemid, math.min(100, amount)) + stuff = Game.createItem(itemid, math.min(ITEM_STACK_SIZE, amount)) end return Player(cid):addItemEx(stuff, ignoreCap) ~= RETURNVALUE_NOERROR and 0 or amount, 0 end diff --git a/data/npc/lib/npcsystem/modules.lua b/data/npc/lib/npcsystem/modules.lua index 38b36c2882..13922f04d8 100644 --- a/data/npc/lib/npcsystem/modules.lua +++ b/data/npc/lib/npcsystem/modules.lua @@ -529,7 +529,7 @@ if not Modules then yesNode = nil, noNode = nil, noText = "", - maxCount = 100, + maxCount = ITEM_STACK_SIZE, amount = 0 } diff --git a/src/container.cpp b/src/container.cpp index 40e4934a6e..9cf461c91d 100644 --- a/src/container.cpp +++ b/src/container.cpp @@ -334,22 +334,23 @@ ReturnValue Container::queryMaxCount(int32_t index, const Thing& thing, uint32_t // Iterate through every item and check how much free stackable slots there is. uint32_t slotIndex = 0; for (Item* containerItem : itemlist) { - if (containerItem != item && containerItem->equals(item) && containerItem->getItemCount() < 100) { + if (containerItem != item && containerItem->equals(item) && + containerItem->getItemCount() < ITEM_STACK_SIZE) { if (queryAdd(slotIndex++, *item, count, flags) == RETURNVALUE_NOERROR) { - n += 100 - containerItem->getItemCount(); + n += ITEM_STACK_SIZE - containerItem->getItemCount(); } } } } else { const Item* destItem = getItemByIndex(index); - if (item->equals(destItem) && destItem->getItemCount() < 100) { + if (item->equals(destItem) && destItem->getItemCount() < ITEM_STACK_SIZE) { if (queryAdd(index, *item, count, flags) == RETURNVALUE_NOERROR) { - n = 100 - destItem->getItemCount(); + n = ITEM_STACK_SIZE - destItem->getItemCount(); } } } - maxQueryCount = freeSlots * 100 + n; + maxQueryCount = freeSlots * ITEM_STACK_SIZE + n; if (maxQueryCount < count) { return RETURNVALUE_CONTAINERNOTENOUGHROOM; } @@ -449,14 +450,14 @@ Cylinder* Container::queryDestination(int32_t& index, const Thing& thing, Item** bool autoStack = !hasBitSet(FLAG_IGNOREAUTOSTACK, flags); if (autoStack && item->isStackable() && item->getParent() != this) { - if (*destItem && (*destItem)->equals(item) && (*destItem)->getItemCount() < 100) { + if (*destItem && (*destItem)->equals(item) && (*destItem)->getItemCount() < ITEM_STACK_SIZE) { return this; } // try find a suitable item to stack with uint32_t n = 0; for (Item* listItem : itemlist) { - if (listItem != item && listItem->equals(item) && listItem->getItemCount() < 100) { + if (listItem != item && listItem->equals(item) && listItem->getItemCount() < ITEM_STACK_SIZE) { *destItem = listItem; index = n; return this; diff --git a/src/game.cpp b/src/game.cpp index 6e959cf0cf..433ea30543 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1222,7 +1222,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t n; if (item->equals(toItem)) { - n = std::min(100 - toItem->getItemCount(), m); + n = std::min(ITEM_STACK_SIZE - toItem->getItemCount(), m); toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + n); updateItem = toItem; } else { @@ -1346,7 +1346,7 @@ ReturnValue Game::internalAddItem(Cylinder* toCylinder, Item* item, int32_t inde if (item->isStackable() && item->equals(toItem)) { uint32_t m = std::min(item->getItemCount(), maxQueryCount); - uint32_t n = std::min(100 - toItem->getItemCount(), m); + uint32_t n = std::min(ITEM_STACK_SIZE - toItem->getItemCount(), m); toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + n); @@ -1608,7 +1608,7 @@ void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) money -= currencyCoins * worth; while (currencyCoins > 0) { - const uint16_t count = std::min(100, currencyCoins); + const uint16_t count = std::min(ITEM_STACK_SIZE, currencyCoins); Item* remaindItem = Item::CreateItem(it.second, count); @@ -1864,7 +1864,8 @@ void Game::playerEquipItem(uint32_t playerId, uint16_t spriteId) internalGetPosition(equipItem, fromPos, fromStackPos); } - if (slotItem && slotItem->getID() == it.id && (!it.stackable || slotItem->getItemCount() == 100 || !equipItem)) { + if (slotItem && slotItem->getID() == it.id && + (!it.stackable || slotItem->getItemCount() == ITEM_STACK_SIZE || !equipItem)) { internalMoveItem(slotItem->getParent(), player, CONST_SLOT_WHEREEVER, slotItem, slotItem->getItemCount(), nullptr, 0, player, nullptr, &fromPos, &toPos); } else if (equipItem) { @@ -2753,8 +2754,8 @@ void Game::playerRequestTrade(uint32_t playerId, const Position& pos, uint8_t st } Container* tradeContainer = tradeItem->getContainer(); - if (tradeContainer && tradeContainer->getItemHoldingCount() + 1 > 100) { - player->sendCancelMessage("You can only trade up to 100 objects at once."); + if (tradeContainer && tradeContainer->getItemHoldingCount() + 1 > ITEM_STACK_SIZE) { + player->sendCancelMessage("You can only trade up to " + std::to_string(ITEM_STACK_SIZE) + " objects at once."); return; } @@ -3054,7 +3055,7 @@ void Game::internalCloseTrade(Player* player, bool sendCancel /* = true*/) void Game::playerPurchaseItem(uint32_t playerId, uint16_t spriteId, uint8_t count, uint8_t amount, bool ignoreCap /* = false*/, bool inBackpacks /* = false*/) { - if (amount == 0 || amount > 100) { + if (amount == 0 || amount > ITEM_STACK_SIZE) { return; } @@ -3091,7 +3092,7 @@ void Game::playerPurchaseItem(uint32_t playerId, uint16_t spriteId, uint8_t coun void Game::playerSellItem(uint32_t playerId, uint16_t spriteId, uint8_t count, uint8_t amount, bool ignoreEquipped) { - if (amount == 0 || amount > 100) { + if (amount == 0 || amount > ITEM_STACK_SIZE) { return; } @@ -5459,7 +5460,7 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 if (it.stackable) { uint16_t tmpAmount = offer.amount; while (tmpAmount > 0) { - int32_t stackCount = std::min(100, tmpAmount); + int32_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(it.id, stackCount); if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; @@ -5567,7 +5568,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 if (it.stackable) { uint16_t tmpAmount = amount; while (tmpAmount > 0) { - uint16_t stackCount = std::min(100, tmpAmount); + uint16_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(it.id, stackCount); if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { @@ -5614,7 +5615,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 if (it.stackable) { uint16_t tmpAmount = amount; while (tmpAmount > 0) { - uint16_t stackCount = std::min(100, tmpAmount); + uint16_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(it.id, stackCount); if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; diff --git a/src/game.h b/src/game.h index eeb89d9837..e73a25ddf6 100644 --- a/src/game.h +++ b/src/game.h @@ -61,6 +61,8 @@ static constexpr int32_t RANGE_BROWSE_FIELD_INTERVAL = 400; static constexpr int32_t RANGE_WRAP_ITEM_INTERVAL = 400; static constexpr int32_t RANGE_REQUEST_TRADE_INTERVAL = 400; +static constexpr uint8_t ITEM_STACK_SIZE = 100; + /** * Main Game class. * This class is responsible to control everything that happens diff --git a/src/iomarket.cpp b/src/iomarket.cpp index c9c1cce455..c2116aff8d 100644 --- a/src/iomarket.cpp +++ b/src/iomarket.cpp @@ -131,7 +131,7 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) if (itemType.stackable) { uint16_t tmpAmount = amount; while (tmpAmount > 0) { - uint16_t stackCount = std::min(100, tmpAmount); + uint16_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(itemType.id, stackCount); if (g_game.internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { diff --git a/src/luascript.cpp b/src/luascript.cpp index 4a53e03adf..4528841690 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -1581,6 +1581,8 @@ void LuaScriptInterface::registerFunctions() registerEnum(GAME_STATE_CLOSING); registerEnum(GAME_STATE_MAINTAIN); + registerEnum(ITEM_STACK_SIZE); + registerEnum(MESSAGE_STATUS_DEFAULT); registerEnum(MESSAGE_STATUS_WARNING); registerEnum(MESSAGE_EVENT_ADVANCE); @@ -3533,7 +3535,7 @@ int LuaScriptInterface::luaDoPlayerAddItem(lua_State* L) itemCount = std::max(1, count); } else if (it.hasSubType()) { if (it.stackable) { - itemCount = static_cast(std::ceil(static_cast(count) / 100)); + itemCount = static_cast(std::ceil(static_cast(count) / ITEM_STACK_SIZE)); } else { itemCount = 1; } @@ -3544,8 +3546,8 @@ int LuaScriptInterface::luaDoPlayerAddItem(lua_State* L) while (itemCount > 0) { uint16_t stackCount = subType; - if (it.stackable && stackCount > 100) { - stackCount = 100; + if (it.stackable && stackCount > ITEM_STACK_SIZE) { + stackCount = ITEM_STACK_SIZE; } Item* newItem = Item::CreateItem(itemId, stackCount); @@ -4786,7 +4788,7 @@ int LuaScriptInterface::luaGameCreateItem(lua_State* L) const ItemType& it = Item::items[id]; if (it.stackable) { - count = std::min(count, 100); + count = std::min(count, ITEM_STACK_SIZE); } Item* item = Item::CreateItem(id, count); @@ -5827,7 +5829,7 @@ int LuaScriptInterface::luaTileAddItem(lua_State* L) uint32_t subType = getNumber(L, 3, 1); - Item* item = Item::CreateItem(itemId, std::min(subType, 100)); + Item* item = Item::CreateItem(itemId, std::min(subType, ITEM_STACK_SIZE)); if (!item) { lua_pushnil(L); return 1; @@ -7084,7 +7086,7 @@ int LuaScriptInterface::luaItemTransform(lua_State* L) const ItemType& it = Item::items[itemId]; if (it.stackable) { - subType = std::min(subType, 100); + subType = std::min(subType, ITEM_STACK_SIZE); } ScriptEnvironment* env = getScriptEnv(); @@ -7370,7 +7372,7 @@ int LuaScriptInterface::luaContainerAddItem(lua_State* L) if (it.hasSubType()) { if (it.stackable) { - itemCount = std::ceil(count / 100.f); + itemCount = std::ceil(count / static_cast(ITEM_STACK_SIZE)); } subType = count; @@ -7390,7 +7392,7 @@ int LuaScriptInterface::luaContainerAddItem(lua_State* L) uint32_t flags = getNumber(L, 5, 0); for (int32_t i = 1; i <= itemCount; ++i) { - int32_t stackCount = std::min(subType, 100); + int32_t stackCount = std::min(subType, ITEM_STACK_SIZE); Item* item = Item::CreateItem(itemId, stackCount); if (!item) { reportErrorFunc(L, getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND)); @@ -9760,7 +9762,7 @@ int LuaScriptInterface::luaPlayerAddItem(lua_State* L) itemCount = std::max(1, count); } else if (it.hasSubType()) { if (it.stackable) { - itemCount = std::ceil(count / 100.f); + itemCount = std::ceil(count / static_cast(ITEM_STACK_SIZE)); } subType = count; @@ -9781,7 +9783,7 @@ int LuaScriptInterface::luaPlayerAddItem(lua_State* L) for (int32_t i = 1; i <= itemCount; ++i) { int32_t stackCount = subType; if (it.stackable) { - stackCount = std::min(stackCount, 100); + stackCount = std::min(stackCount, ITEM_STACK_SIZE); subType -= stackCount; } diff --git a/src/npc.cpp b/src/npc.cpp index 46a9f3e1d7..7171b874a2 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -899,7 +899,7 @@ int NpcScriptInterface::luaDoSellItem(lua_State* L) const ItemType& it = Item::items[itemId]; if (it.stackable) { while (amount > 0) { - int32_t stackCount = std::min(100, amount); + int32_t stackCount = std::min(ITEM_STACK_SIZE, amount); Item* item = Item::CreateItem(it.id, stackCount); if (item && actionId != 0) { item->setActionId(actionId); diff --git a/src/player.cpp b/src/player.cpp index d6358e93fc..09c31c2c45 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2688,7 +2688,7 @@ ReturnValue Player::queryMaxCount(int32_t index, const Thing& thing, uint32_t co } } } else if (inventoryItem->isStackable() && item->equals(inventoryItem) && - inventoryItem->getItemCount() < 100) { + inventoryItem->getItemCount() < ITEM_STACK_SIZE) { uint32_t remainder = (100 - inventoryItem->getItemCount()); if (queryAdd(slotIndex, *item, remainder, flags) == RETURNVALUE_NOERROR) { @@ -2714,7 +2714,7 @@ ReturnValue Player::queryMaxCount(int32_t index, const Thing& thing, uint32_t co } if (destItem) { - if (destItem->isStackable() && item->equals(destItem) && destItem->getItemCount() < 100) { + if (destItem->isStackable() && item->equals(destItem) && destItem->getItemCount() < ITEM_STACK_SIZE) { maxQueryCount = 100 - destItem->getItemCount(); } else { maxQueryCount = 0; @@ -2788,7 +2788,7 @@ Cylinder* Player::queryDestination(int32_t& index, const Thing& thing, Item** de if (autoStack && isStackable) { // try find an already existing item to stack with if (queryAdd(slotIndex, *item, item->getItemCount(), 0) == RETURNVALUE_NOERROR) { - if (inventoryItem->equals(item) && inventoryItem->getItemCount() < 100) { + if (inventoryItem->equals(item) && inventoryItem->getItemCount() < ITEM_STACK_SIZE) { index = slotIndex; *destItem = inventoryItem; return this; @@ -2847,7 +2847,7 @@ Cylinder* Player::queryDestination(int32_t& index, const Thing& thing, Item** de } // try find an already existing item to stack with - if (tmpItem->equals(item) && tmpItem->getItemCount() < 100) { + if (tmpItem->equals(item) && tmpItem->getItemCount() < ITEM_STACK_SIZE) { index = n; *destItem = tmpItem; return tmpContainer;