The problem is when I give the player items greater than stack limit it does not stack properly.
Here’s a video showing the problem: https://www.youtube.com/watch?v=31QAaaF4m2Y
It works when I give the player items less than the stack limit, but when I give more it doesn’t work.
My code:
local function GetItems(inventory, itemName)
local itemsFound = {}
local amountOfItems = 0
if type(inventory) == "table" then
for _, itemTable in ipairs(inventory) do
print(itemTable, itemTable.Name)
if type(itemTable) == "table" and itemTable.Name == itemName then
table.insert(itemsFound, itemTable)
amountOfItems += itemTable.Amount
end
end
end
return amountOfItems, itemsFound
end
local function FixStacks(inventory, itemsFound, itemInstance, amountOfItems)
local amountRemoved = 0
local stackCapacity = itemInstance.Value
for _, itemTable in ipairs(itemsFound) do
if itemTable.Amount > stackCapacity then
amountRemoved += itemTable.Amount - stackCapacity
itemTable.Amount = stackCapacity
end
itemTable = itemTable.Amount <= stackCapacity and itemTable.Amount or stackCapacity
end
if amountRemoved > 0 then
local amountLeftOver = amountRemoved - math.floor(amountRemoved / stackCapacity)
for i = 1, math.floor(amountRemoved / stackCapacity) do
table.insert(inventory, {
["ID"] = HttpService:GenerateGUID(false),
["Name"] = itemInstance.Name,
["Image"] = itemInstance.Image.Texture,
["Amount"] = stackCapacity
})
end
table.insert(inventory, {
["ID"] = HttpService:GenerateGUID(false),
["Name"] = itemInstance.Name,
["Image"] = itemInstance.Image.Texture,
["Amount"] = stackCapacity
})
end
end
local function GiveItem(player, profile, itemName, amount)
if typeof(player) == "Instance" and player:IsDescendantOf(Players) and type(profile) == "table" and type(profile.Data) == "table" and type(profile.Data.Inventory) == "table" then
if type(itemName) == "string" and Items:FindFirstChild(itemName) and Items:FindFirstChild(itemName):IsA("IntValue") then
local itemInstance = Items:FindFirstChild(itemName)
amount = math.floor(amount)
amount = amount >= 1 and amount or 1
table.insert(profile.Data.Inventory, {
["ID"] = HttpService:GenerateGUID(false),
["Name"] = itemName,
["Image"] = itemInstance.Image.Texture,
["Amount"] = amount or 1
})
local amountOfItems, itemsFound = GetItems(profile.Data.Inventory, itemName)
FixStacks(profile.Data.Inventory, itemsFound, itemInstance, amountOfItems)
UpdateInventory:FireClient(player, profile.Data.Inventory)
end
end
end
I got the FixStacks function giving the right amount of items now but it creates too many stacks.
New FixStacks Code:
local function FixStacks(inventory, itemsFound, itemInstance, amountOfItems)
local stackCapacity = itemInstance.Value
for _, itemTable in ipairs(itemsFound) do
if itemTable.Amount > stackCapacity then
local amountRemoved = itemTable.Amount - stackCapacity
itemTable.Amount = stackCapacity
while amountRemoved > 0 do
local stackToAdd = math.min(stackCapacity, amountRemoved)
table.insert(inventory, {
["ID"] = HttpService:GenerateGUID(false),
["Name"] = itemInstance.Name,
["Image"] = itemInstance.Image.Texture,
["Amount"] = stackToAdd
})
amountRemoved = amountRemoved - stackToAdd
end
end
end
end
local function GetItems(inventory, itemName)
local itemsFound = {}
local amountOfItems = 0
local firstEmptySlot = 1
if type(inventory) == "table" and Items:FindFirstChild(itemName) then
for index, itemTable in next, inventory do
if type(itemTable) == "table" and itemTable.Name == itemName then
table.insert(itemsFound, itemTable)
amountOfItems += itemTable.Amount
if firstEmptySlot == 1 and itemTable.Amount < Items:FindFirstChild(itemName).Value then
firstEmptySlot = index
end
end
end
end
return amountOfItems, itemsFound, firstEmptySlot
end
local function FixStacks(inventory, itemsFound, itemInstance, amountOfItems)
local stackCapacity = itemInstance.Value
for _, itemTable in ipairs(itemsFound) do
if itemTable.Amount > stackCapacity then
local amountRemoved = itemTable.Amount - stackCapacity
itemTable.Amount = stackCapacity
while amountRemoved > 0 do
local stackToAdd = math.min(stackCapacity, amountRemoved)
table.insert(inventory, {
["ID"] = HttpService:GenerateGUID(false),
["Name"] = itemInstance.Name,
["Image"] = itemInstance.Image.Texture,
["Amount"] = stackToAdd
})
amountRemoved = amountRemoved - stackToAdd
end
local newAmountOfItems, newItemsFound = GetItems(inventory, itemInstance.Name)
if #newItemsFound > 0 then
FixStacks(inventory, newItemsFound, itemInstance, newAmountOfItems)
end
end
end
end
local function GiveItem(player, profile, itemName, amount)
if typeof(player) == "Instance" and player:IsDescendantOf(Players) and type(profile) == "table" and type(profile.Data) == "table" and type(profile.Data.Inventory) == "table" then
if type(itemName) == "string" and Items:FindFirstChild(itemName) and Items:FindFirstChild(itemName):IsA("IntValue") then
local itemInstance = Items:FindFirstChild(itemName)
amount = math.floor(amount)
amount = amount >= 1 and amount or 1
local amountOfItems, itemsFound, firstEmptySlot = GetItems(profile.Data.Inventory, itemName)
if amountOfItems <= 0 then
table.insert(profile.Data.Inventory, {
["ID"] = HttpService:GenerateGUID(false),
["Name"] = itemName,
["Image"] = itemInstance.Image.Texture,
["Amount"] = amount or 1
})
else
itemsFound[firstEmptySlot].Amount += amount
end
amountOfItems, itemsFound, firstEmptySlot = GetItems(profile.Data.Inventory, itemName)
FixStacks(profile.Data.Inventory, itemsFound, itemInstance, amountOfItems)
UpdateInventory:FireClient(player, profile.Data.Inventory)
end
end
end