mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-18 06:03:47 +03:00
Upload
This commit is contained in:
232
gamemodes/helix/gamemode/items/base/sh_stackable.lua
Normal file
232
gamemodes/helix/gamemode/items/base/sh_stackable.lua
Normal file
@@ -0,0 +1,232 @@
|
||||
--[[
|
||||
| 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
|
||||
}
|
||||
Reference in New Issue
Block a user