Skip to content

Commit

Permalink
Configurable stack size (#4528)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: AKnopik PC <[email protected]>
  • Loading branch information
ArturKnopik and AKnopik PC authored Sep 10, 2023
1 parent 1f077ff commit 419124f
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 38 deletions.
2 changes: 1 addition & 1 deletion data/lib/core/container.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions data/npc/lib/npc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion data/npc/lib/npcsystem/modules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ if not Modules then
yesNode = nil,
noNode = nil,
noText = "",
maxCount = 100,
maxCount = ITEM_STACK_SIZE,
amount = 0
}

Expand Down
15 changes: 8 additions & 7 deletions src/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
23 changes: 12 additions & 11 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
uint32_t n;

if (item->equals(toItem)) {
n = std::min<uint32_t>(100 - toItem->getItemCount(), m);
n = std::min<uint32_t>(ITEM_STACK_SIZE - toItem->getItemCount(), m);
toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + n);
updateItem = toItem;
} else {
Expand Down Expand Up @@ -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<uint32_t>(item->getItemCount(), maxQueryCount);
uint32_t n = std::min<uint32_t>(100 - toItem->getItemCount(), m);
uint32_t n = std::min<uint32_t>(ITEM_STACK_SIZE - toItem->getItemCount(), m);

toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + n);

Expand Down Expand Up @@ -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<uint32_t>(100, currencyCoins);
const uint16_t count = std::min<uint32_t>(ITEM_STACK_SIZE, currencyCoins);

Item* remaindItem = Item::CreateItem(it.second, count);

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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<int32_t>(100, tmpAmount);
int32_t stackCount = std::min<int32_t>(ITEM_STACK_SIZE, tmpAmount);
Item* item = Item::CreateItem(it.id, stackCount);
if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
delete item;
Expand Down Expand Up @@ -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<uint16_t>(100, tmpAmount);
uint16_t stackCount = std::min<uint16_t>(ITEM_STACK_SIZE, tmpAmount);
Item* item = Item::CreateItem(it.id, stackCount);
if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) !=
RETURNVALUE_NOERROR) {
Expand Down Expand Up @@ -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<uint16_t>(100, tmpAmount);
uint16_t stackCount = std::min<uint16_t>(ITEM_STACK_SIZE, tmpAmount);
Item* item = Item::CreateItem(it.id, stackCount);
if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
delete item;
Expand Down
2 changes: 2 additions & 0 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/iomarket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint16_t>(100, tmpAmount);
uint16_t stackCount = std::min<uint16_t>(ITEM_STACK_SIZE, tmpAmount);
Item* item = Item::CreateItem(itemType.id, stackCount);
if (g_game.internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) !=
RETURNVALUE_NOERROR) {
Expand Down
22 changes: 12 additions & 10 deletions src/luascript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -3533,7 +3535,7 @@ int LuaScriptInterface::luaDoPlayerAddItem(lua_State* L)
itemCount = std::max<int32_t>(1, count);
} else if (it.hasSubType()) {
if (it.stackable) {
itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / ITEM_STACK_SIZE));
} else {
itemCount = 1;
}
Expand All @@ -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);
Expand Down Expand Up @@ -4786,7 +4788,7 @@ int LuaScriptInterface::luaGameCreateItem(lua_State* L)

const ItemType& it = Item::items[id];
if (it.stackable) {
count = std::min<uint16_t>(count, 100);
count = std::min<uint16_t>(count, ITEM_STACK_SIZE);
}

Item* item = Item::CreateItem(id, count);
Expand Down Expand Up @@ -5827,7 +5829,7 @@ int LuaScriptInterface::luaTileAddItem(lua_State* L)

uint32_t subType = getNumber<uint32_t>(L, 3, 1);

Item* item = Item::CreateItem(itemId, std::min<uint32_t>(subType, 100));
Item* item = Item::CreateItem(itemId, std::min<uint32_t>(subType, ITEM_STACK_SIZE));
if (!item) {
lua_pushnil(L);
return 1;
Expand Down Expand Up @@ -7084,7 +7086,7 @@ int LuaScriptInterface::luaItemTransform(lua_State* L)

const ItemType& it = Item::items[itemId];
if (it.stackable) {
subType = std::min<int32_t>(subType, 100);
subType = std::min<int32_t>(subType, ITEM_STACK_SIZE);
}

ScriptEnvironment* env = getScriptEnv();
Expand Down Expand Up @@ -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<float>(ITEM_STACK_SIZE));
}

subType = count;
Expand All @@ -7390,7 +7392,7 @@ int LuaScriptInterface::luaContainerAddItem(lua_State* L)
uint32_t flags = getNumber<uint32_t>(L, 5, 0);

for (int32_t i = 1; i <= itemCount; ++i) {
int32_t stackCount = std::min<int32_t>(subType, 100);
int32_t stackCount = std::min<int32_t>(subType, ITEM_STACK_SIZE);
Item* item = Item::CreateItem(itemId, stackCount);
if (!item) {
reportErrorFunc(L, getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
Expand Down Expand Up @@ -9760,7 +9762,7 @@ int LuaScriptInterface::luaPlayerAddItem(lua_State* L)
itemCount = std::max<int32_t>(1, count);
} else if (it.hasSubType()) {
if (it.stackable) {
itemCount = std::ceil(count / 100.f);
itemCount = std::ceil(count / static_cast<float>(ITEM_STACK_SIZE));
}

subType = count;
Expand All @@ -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<int32_t>(stackCount, 100);
stackCount = std::min<int32_t>(stackCount, ITEM_STACK_SIZE);
subType -= stackCount;
}

Expand Down
2 changes: 1 addition & 1 deletion src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int32_t>(100, amount);
int32_t stackCount = std::min<int32_t>(ITEM_STACK_SIZE, amount);
Item* item = Item::CreateItem(it.id, stackCount);
if (item && actionId != 0) {
item->setActionId(actionId);
Expand Down
8 changes: 4 additions & 4 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 419124f

Please sign in to comment.