--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] ITEM.name = "Stackable Base" ITEM.description = "Makes items stackable." ITEM.category = "Base" ITEM.maxStackSize = 1 ITEM.bInstanceMaxstack = false ITEM.bNoSplit = false do local META = ix.meta.inventory function META:GetItemCount(uniqueID, onlyMain) local i = 0 for _, v in pairs(self:GetItems(onlyMain)) do if (v.uniqueID == uniqueID) then i = i + v:GetStackSize() end end return i end end do -- Define this on all items to make life easier local ITEM = ix.meta.item or {} function ITEM:GetStackSize() return self:GetData("stack", self.bInstanceMaxstack and self.maxStackSize or 1) end function ITEM:IsSingleItem() return self:GetStackSize() <= 1 end function ITEM:IsFullStack() return self:GetStackSize() == (self.maxStackSize or 1) end end hook.Add("CanPlayerInteractItem", "ixStackableItemBase", function(client, action, item, data) if (!isentity(item) or !IsValid(item)) then return end if (action == "take") then return end local itemID = item.ixItemID if (!itemID) then return end item = ix.item.instances[itemID] if (!item) then return end if (item and item.maxStackSize and item.maxStackSize > 1 and !item:IsSingleItem()) then return false end end) hook.Add("InventoryItemAdded", "ixStackableItemInvAdd", function(oldInv, newInv, item) if (oldInv != nil or !item.maxStackSize or item.maxStackSize == 1) then return end if (item:IsFullStack() or item:GetData("bIsSplit")) then item:SetData("bIsSplit", nil) return end local items = newInv:GetItemsByUniqueID(item.uniqueID, true) local id = item:GetID() for _, v in ipairs(items) do if (v:GetID() == id) then continue end local totalSize = item:GetStackSize() if (v:GetStackSize() < v.maxStackSize) then local toMove = math.min(v.maxStackSize - v:GetStackSize(), totalSize) v:AddStack(toMove) totalSize = totalSize - toMove if (totalSize == 0) then return ix.meta.item.Remove(item) end end item:SetData("stack", totalSize) end end) if (CLIENT) then function ITEM:PaintOver(item, w, h) if (!item:IsSingleItem()) then draw.SimpleText( item:GetStackSize(), "DermaDefault", w - 5, h - 5, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_BOTTOM, 1, color_black ) end if (item.outlineColor) then surface.SetDrawColor(item.outlineColor) surface.DrawOutlinedRect(1, 1, w - 2, h - 2) end end else function ITEM:Remove(bNoReplication, bNoDelete) return self:RemoveStack(1, bNoReplication, bNoDelete) end function ITEM:AddStack(amount) local stack = self:GetData("stack") if (stack) then return self:SetStack(stack + amount) end end function ITEM:RemoveStack(amount, bNoReplication, bNoDelete) local stack = self:GetData("stack") if (stack) then return self:SetStack(stack - amount) end end function ITEM:SetStack(amount, bNoReplication, bNoDelete) self:SetData("stack", math.Clamp(amount, 0, self.maxStackSize)) if (self:GetStackSize() == 0) then return ix.meta.item.Remove(self, bNoReplication, bNoDelete) end return true end end function ITEM:OnInstanced() if (!self:GetData("stack")) then self:SetStack(self:GetStackSize()) end end ITEM.functions.combine = { OnRun = function(item, data) local other = ix.item.instances[data[1]] if (other:GetStackSize() + item:GetStackSize() > item.maxStackSize) then local added = item.maxStackSize - item:GetStackSize() item:AddStack(added) -- set to max stack size other:RemoveStack(added) else item:AddStack(other:GetStackSize()) other:RemoveStack(other:GetStackSize()) if (item.junk) then if (!item.player:GetCharacter():GetInventory():Add(item.junk)) then ix.item.Spawn(item.junk, item.player) end end end return false end, OnCanRun = function(item, data) if (!item.maxStackSize or item.maxStackSize < 2) then return false end local other = ix.item.instances[data[1]] if (!other or other.uniqueID != item.uniqueID) then return false end end } ITEM.functions.split = { name = "Diviser", isMulti = true, multiOptions = function(item, player) local options = {{name = "1", data = {1}}} for i = 5, item:GetStackSize() - 1, 5 do options[#options + 1] = {name = tostring(i), data = {i}} end if (item:GetStackSize() > 2) then options[#options + 1] = {name = "Plus", data = {-1}, OnClick = function(itemTable) Derma_StringRequest("Diviser", "Combien d'items souhaitez-vous déplacer en une nouvelle pile ?", LocalPlayer().ixLastStackSize or "", function(text) local amount = tonumber(text) if (!amount or amount <= 0 or amount >= itemTable:GetStackSize()) then return end LocalPlayer().ixLastStackSize = amount net.Start("ixInventoryAction") net.WriteString("split") net.WriteUInt(itemTable.id, 32) net.WriteUInt(itemTable.invID, 32) net.WriteTable({amount}) net.SendToServer() end) return false end} end return options end, OnRun = function(item, data) local amount = math.floor(tonumber(data and data[1] or 1) or 0) if (!amount or amount <= 0 or amount >= item:GetStackSize()) then return false end local inventory = ix.item.inventories[item.invID] if (item.junk) then local junk = inventory:HasItem(item.junk) if (junk) then junk:Remove() end end inventory:Add(item.uniqueID, 1, {stack = amount, bIsSplit = true}) item:RemoveStack(amount) return false end, OnCanRun = function(item) if (IsValid(item.entity)) then return false end if (!item.maxStackSize or item.maxStackSize < 2 or item.bNoSplit == true) then return false end local inventory = ix.item.inventories[item.invID] if (item.junk and !inventory:HasItem(item.junk)) then return false end return !IsValid(item.entity) and !item:IsSingleItem() and inventory:FindEmptySlot(item.width, item.height) != nil end }