mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
1400 lines
36 KiB
Lua
1400 lines
36 KiB
Lua
|
|
--[[
|
||
|
|
| 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/
|
||
|
|
--]]
|
||
|
|
|
||
|
|
local RECEIVER_NAME = "ixInventoryItem"
|
||
|
|
|
||
|
|
-- The queue for the rendered icons.
|
||
|
|
ICON_RENDER_QUEUE = ICON_RENDER_QUEUE or {}
|
||
|
|
|
||
|
|
local iconSize = SScaleMin(90 / 3)
|
||
|
|
|
||
|
|
local function PaintLockedSlot(slot, w, h)
|
||
|
|
surface.SetDrawColor(35, 35, 35, 85)
|
||
|
|
surface.DrawRect(1, 1, w - SScaleMin(2 / 3), h - SScaleMin(2 / 3))
|
||
|
|
surface.SetDrawColor(80, 80, 80, 255)
|
||
|
|
surface.DrawOutlinedRect(1, 1, w - SScaleMin(2 / 3), h - SScaleMin(2 / 3))
|
||
|
|
|
||
|
|
surface.SetDrawColor(80, 80, 80, 110)
|
||
|
|
surface.DrawLine( 1, 1, iconSize - SScaleMin(2 / 3), iconSize - SScaleMin(2 / 3) )
|
||
|
|
surface.DrawLine( 1, iconSize - SScaleMin(2 / 3), iconSize - SScaleMin(2 / 3), 1 )
|
||
|
|
end
|
||
|
|
|
||
|
|
-- To make making inventory variant, This must be followed up.
|
||
|
|
local function RenderNewIcon(panel, itemTable)
|
||
|
|
local model = itemTable:GetModel()
|
||
|
|
|
||
|
|
-- re-render icons
|
||
|
|
if ((itemTable.iconCam and !ICON_RENDER_QUEUE[string.utf8lower(model)]) or itemTable.forceRender) then
|
||
|
|
local iconCam = itemTable.iconCam
|
||
|
|
iconCam = {
|
||
|
|
cam_pos = iconCam.pos,
|
||
|
|
cam_ang = iconCam.ang,
|
||
|
|
cam_fov = iconCam.fov,
|
||
|
|
}
|
||
|
|
ICON_RENDER_QUEUE[string.utf8lower(model)] = true
|
||
|
|
|
||
|
|
panel.Icon:RebuildSpawnIconEx(
|
||
|
|
iconCam
|
||
|
|
)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function InventoryAction(action, itemID, invID, data)
|
||
|
|
net.Start("ixInventoryAction")
|
||
|
|
net.WriteString(action)
|
||
|
|
net.WriteUInt(itemID, 32)
|
||
|
|
net.WriteUInt(invID, 32)
|
||
|
|
net.WriteTable(data or {})
|
||
|
|
net.SendToServer()
|
||
|
|
end
|
||
|
|
|
||
|
|
local PANEL = {}
|
||
|
|
|
||
|
|
AccessorFunc(PANEL, "itemTable", "ItemTable")
|
||
|
|
AccessorFunc(PANEL, "inventoryID", "InventoryID")
|
||
|
|
|
||
|
|
function PANEL:Init()
|
||
|
|
self:Droppable(RECEIVER_NAME)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnMousePressed(code)
|
||
|
|
if (code == MOUSE_LEFT and self:IsDraggable()) then
|
||
|
|
self:MouseCapture(true)
|
||
|
|
self:DragMousePress(code)
|
||
|
|
|
||
|
|
self.clickX, self.clickY = input.GetCursorPos()
|
||
|
|
|
||
|
|
if (input.IsKeyDown(KEY_LSHIFT)) then
|
||
|
|
self:DoShiftMove()
|
||
|
|
end
|
||
|
|
elseif (code == MOUSE_RIGHT and self.DoRightClick) then
|
||
|
|
self:DoRightClick()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnMouseReleased(code)
|
||
|
|
-- move the item into the world if we're dropping on something that doesn't handle inventory item drops
|
||
|
|
if (!dragndrop.m_ReceiverSlot or dragndrop.m_ReceiverSlot.Name != RECEIVER_NAME) then
|
||
|
|
self:OnDrop(dragndrop.IsDragging())
|
||
|
|
end
|
||
|
|
|
||
|
|
self:DragMouseRelease(code)
|
||
|
|
self:SetZPos(99)
|
||
|
|
self:MouseCapture(false)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:DoShiftMove()
|
||
|
|
local itemTable = self.itemTable
|
||
|
|
local inventory = self.inventoryID
|
||
|
|
local storageInv = ix.gui.openedStorage
|
||
|
|
|
||
|
|
if (itemTable and inventory and storageInv and IsValid(storageInv)) then
|
||
|
|
net.Start("ixInventoryShiftMove")
|
||
|
|
net.WriteFloat(itemTable.id)
|
||
|
|
net.WriteFloat(storageInv:GetStorageID())
|
||
|
|
net.SendToServer()
|
||
|
|
|
||
|
|
local path = "willardnetworks/inventory/"
|
||
|
|
local randomSounds = {"inv_move1.wav", "inv_move2.wav", "inv_move3.wav", "inv_move4.mp3", "inv_move5.mp3", "inv_move6.mp3"}
|
||
|
|
surface.PlaySound(path .. table.Random(randomSounds))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:DoRightClick()
|
||
|
|
local itemTable = self.itemTable
|
||
|
|
local inventory = self.inventoryID
|
||
|
|
|
||
|
|
if (itemTable and inventory) then
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
|
||
|
|
local menu = DermaMenu()
|
||
|
|
local override = hook.Run("CreateItemInteractionMenu", self, menu, itemTable)
|
||
|
|
|
||
|
|
if (override == true) then
|
||
|
|
if (menu.Remove) then
|
||
|
|
menu:Remove()
|
||
|
|
end
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
for k, v in SortedPairs(itemTable.functions) do
|
||
|
|
if (k == "drop" or k == "combine" or k == "combined" or (v.OnCanRun and v.OnCanRun(itemTable) == false)) then
|
||
|
|
continue
|
||
|
|
end
|
||
|
|
|
||
|
|
-- is Multi-Option Function
|
||
|
|
if (v.isMulti) then
|
||
|
|
local subMenu, subMenuOption = menu:AddSubMenu(L(v.name or k), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (v.OnClick) then
|
||
|
|
send = v.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (v.sound) then
|
||
|
|
surface.PlaySound(v.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction(k, itemTable.id, inventory)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end)
|
||
|
|
subMenuOption:SetImage(v.icon or "icon16/brick.png")
|
||
|
|
|
||
|
|
if (v.multiOptions) then
|
||
|
|
local options = isfunction(v.multiOptions) and v.multiOptions(itemTable, LocalPlayer()) or v.multiOptions
|
||
|
|
|
||
|
|
for _, sub in pairs(options) do
|
||
|
|
subMenu:AddOption(L(sub.name or "subOption"), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (sub.OnClick) then
|
||
|
|
send = sub.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (sub.sound) then
|
||
|
|
surface.PlaySound(sub.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction(k, itemTable.id, inventory, sub.data)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
menu:AddOption(L(v.name or k), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (v.OnClick) then
|
||
|
|
send = v.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (v.sound) then
|
||
|
|
surface.PlaySound(v.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction(k, itemTable.id, inventory)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end):SetImage(v.icon or "icon16/brick.png")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- we want drop to show up as the last option
|
||
|
|
local info = itemTable.functions.drop
|
||
|
|
|
||
|
|
if (info and info.OnCanRun and info.OnCanRun(itemTable) != false) then
|
||
|
|
menu:AddOption(L(info.name or "drop"), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (info.OnClick) then
|
||
|
|
send = info.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (info.sound) then
|
||
|
|
surface.PlaySound(info.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction("drop", itemTable.id, inventory)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end):SetImage(info.icon or "icon16/brick.png")
|
||
|
|
end
|
||
|
|
|
||
|
|
menu:Open()
|
||
|
|
for _, v in pairs(menu:GetChildren()[1]:GetChildren()) do
|
||
|
|
v:SetFont("MenuFontNoClamp")
|
||
|
|
end
|
||
|
|
|
||
|
|
itemTable.player = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local XYchanges = {
|
||
|
|
[1] = {x = 1, y = 6},
|
||
|
|
[2] = {x = 1, y = 7},
|
||
|
|
[3] = {x = 1, y = 8},
|
||
|
|
[4] = {x = 1, y = 9},
|
||
|
|
[5] = {x = 1, y = 10},
|
||
|
|
}
|
||
|
|
|
||
|
|
function PANEL:OnDrop(bDragging, inventoryPanel, inventory, gridX, gridY)
|
||
|
|
local item = self.itemTable
|
||
|
|
|
||
|
|
if (!item or !bDragging) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (inventory and inventory.vars and inventory.vars.isEquipSlots) then
|
||
|
|
if (gridX == 5 and gridY <= 5) then
|
||
|
|
gridX, gridY = XYchanges[gridY].x, XYchanges[gridY].y
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (!IsValid(inventoryPanel)) then
|
||
|
|
local inventoryID = self.inventoryID
|
||
|
|
|
||
|
|
if (inventoryID) then
|
||
|
|
InventoryAction("drop", item.id, inventoryID, {})
|
||
|
|
end
|
||
|
|
elseif (inventoryPanel:IsAllEmpty(gridX, gridY, item.width, item.height, self)) then
|
||
|
|
local oldX, oldY = self.gridX, self.gridY
|
||
|
|
|
||
|
|
if (oldX != gridX or oldY != gridY or self.inventoryID != inventoryPanel.invID) then
|
||
|
|
self:Move(gridX, gridY, inventoryPanel)
|
||
|
|
end
|
||
|
|
elseif (inventoryPanel.combineItem) then
|
||
|
|
local combineItem = inventoryPanel.combineItem
|
||
|
|
local inventoryID = combineItem.invID
|
||
|
|
|
||
|
|
if (inventoryID) then
|
||
|
|
local info = combineItem.functions.combine
|
||
|
|
|
||
|
|
if (info and info.OnCanRun and info.OnCanRun(combineItem, {item.id}) != false) then
|
||
|
|
combineItem.player = LocalPlayer()
|
||
|
|
|
||
|
|
if (combineItem.functions.combine.sound) then
|
||
|
|
surface.PlaySound(combineItem.functions.combine.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
InventoryAction("combine", combineItem.id, inventoryID, {item.id})
|
||
|
|
combineItem.player = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local info2 = item.functions.combined
|
||
|
|
|
||
|
|
if (info2 and info2.OnCanRun and info2.OnCanRun(item, {combineItem.id}) != false) then
|
||
|
|
item.player = LocalPlayer()
|
||
|
|
|
||
|
|
InventoryAction("combined", item.id, inventoryID, {combineItem.id})
|
||
|
|
item.player = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:Move(newX, newY, givenInventory, bNoSend)
|
||
|
|
local iconSize2 = givenInventory.iconSize
|
||
|
|
local oldX, oldY = self.gridX, self.gridY
|
||
|
|
local oldParent = self:GetParent()
|
||
|
|
|
||
|
|
if (givenInventory:OnTransfer(oldX, oldY, newX, newY, oldParent, bNoSend) == false) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local isEqSlots = givenInventory:IsEquipSlotsPanel()
|
||
|
|
local x = (newX - 1 + (isEqSlots and newY > 5 and 4 or 0)) * iconSize2
|
||
|
|
local y = (newY - 1 - (isEqSlots and newY > 5 and 5 or 0)) * iconSize2 + givenInventory:GetPadding(2)
|
||
|
|
|
||
|
|
self.gridX = newX
|
||
|
|
self.gridY = newY
|
||
|
|
|
||
|
|
self:SetParent(givenInventory)
|
||
|
|
self:SetPos(x, y)
|
||
|
|
|
||
|
|
if (self.slots) then
|
||
|
|
for _, v in ipairs(self.slots) do
|
||
|
|
if (IsValid(v) and v.item == self) then
|
||
|
|
v.item = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self.slots = {}
|
||
|
|
|
||
|
|
for currentX = 1, self.gridW do
|
||
|
|
for currentY = 1, self.gridH do
|
||
|
|
local slot = givenInventory.slots[self.gridX + currentX - 1][self.gridY + currentY - 1]
|
||
|
|
|
||
|
|
slot.item = self
|
||
|
|
self.slots[#self.slots + 1] = slot
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local path = "willardnetworks/inventory/"
|
||
|
|
local randomSounds = {"inv_move1.wav", "inv_move2.wav", "inv_move3.wav", "inv_move4.mp3", "inv_move5.mp3", "inv_move6.mp3"}
|
||
|
|
surface.PlaySound(path..table.Random(randomSounds))
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:PaintOver(width, height)
|
||
|
|
local itemTable = self.itemTable
|
||
|
|
|
||
|
|
if (itemTable and itemTable.PaintOver) then
|
||
|
|
itemTable.PaintOver(self, itemTable, width, height)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:ExtraPaint(width, height)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:Paint(width, height)
|
||
|
|
surface.SetDrawColor(0, 0, 0, 85)
|
||
|
|
surface.DrawRect(2, 2, width - 0, height - 4)
|
||
|
|
|
||
|
|
self:ExtraPaint(width, height)
|
||
|
|
end
|
||
|
|
|
||
|
|
vgui.Register("ixItemIcon", PANEL, "SpawnIcon")
|
||
|
|
|
||
|
|
DEFINE_BASECLASS("DModelPanel")
|
||
|
|
|
||
|
|
PANEL = {}
|
||
|
|
|
||
|
|
AccessorFunc(PANEL, "itemTable", "ItemTable")
|
||
|
|
AccessorFunc(PANEL, "inventoryID", "InventoryID")
|
||
|
|
|
||
|
|
function PANEL:Init()
|
||
|
|
self:Droppable(RECEIVER_NAME)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnMousePressed(code)
|
||
|
|
if (code == MOUSE_LEFT and self:IsDraggable()) then
|
||
|
|
self:MouseCapture(true)
|
||
|
|
self:DragMousePress(code)
|
||
|
|
|
||
|
|
self.clickX, self.clickY = input.GetCursorPos()
|
||
|
|
|
||
|
|
if (input.IsKeyDown(KEY_LSHIFT)) then
|
||
|
|
self:DoShiftMove()
|
||
|
|
end
|
||
|
|
elseif (code == MOUSE_RIGHT and self.DoRightClick) then
|
||
|
|
self:DoRightClick()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnMouseReleased(code)
|
||
|
|
-- move the item into the world if we're dropping on something that doesn't handle inventory item drops
|
||
|
|
if (!dragndrop.m_ReceiverSlot or dragndrop.m_ReceiverSlot.Name != RECEIVER_NAME) then
|
||
|
|
self:OnDrop(dragndrop.IsDragging())
|
||
|
|
end
|
||
|
|
|
||
|
|
self:DragMouseRelease(code)
|
||
|
|
self:SetZPos(99)
|
||
|
|
self:MouseCapture(false)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:DoShiftMove()
|
||
|
|
local itemTable = self.itemTable
|
||
|
|
local inventory = self.inventoryID
|
||
|
|
local storageInv = ix.gui.openedStorage
|
||
|
|
|
||
|
|
if (itemTable and inventory and storageInv and IsValid(storageInv)) then
|
||
|
|
net.Start("ixInventoryShiftMove")
|
||
|
|
net.WriteFloat(itemTable.id)
|
||
|
|
net.WriteFloat(storageInv:GetStorageID())
|
||
|
|
net.SendToServer()
|
||
|
|
|
||
|
|
local path = "willardnetworks/inventory/"
|
||
|
|
local randomSounds = {"inv_move1.wav", "inv_move2.wav", "inv_move3.wav", "inv_move4.mp3", "inv_move5.mp3", "inv_move6.mp3"}
|
||
|
|
surface.PlaySound(path .. table.Random(randomSounds))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:DoRightClick()
|
||
|
|
local itemTable = self.itemTable
|
||
|
|
local inventory = self.inventoryID
|
||
|
|
|
||
|
|
if (itemTable and inventory) then
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
|
||
|
|
local menu = DermaMenu()
|
||
|
|
local override = hook.Run("CreateItemInteractionMenu", self, menu, itemTable)
|
||
|
|
|
||
|
|
if (override == true) then
|
||
|
|
if (menu.Remove) then
|
||
|
|
menu:Remove()
|
||
|
|
end
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
for k, v in SortedPairs(itemTable.functions) do
|
||
|
|
if (k == "drop" or k == "combine" or (v.OnCanRun and v.OnCanRun(itemTable) == false)) then
|
||
|
|
continue
|
||
|
|
end
|
||
|
|
|
||
|
|
-- is Multi-Option Function
|
||
|
|
if (v.isMulti) then
|
||
|
|
local subMenu, subMenuOption = menu:AddSubMenu(L(v.name or k), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (v.OnClick) then
|
||
|
|
send = v.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (v.sound) then
|
||
|
|
surface.PlaySound(v.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction(k, itemTable.id, inventory)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end)
|
||
|
|
subMenuOption:SetImage(v.icon or "icon16/brick.png")
|
||
|
|
|
||
|
|
if (v.multiOptions) then
|
||
|
|
local options = isfunction(v.multiOptions) and v.multiOptions(itemTable, LocalPlayer()) or v.multiOptions
|
||
|
|
|
||
|
|
for _, sub in pairs(options) do
|
||
|
|
subMenu:AddOption(L(sub.name or "subOption"), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (sub.OnClick) then
|
||
|
|
send = sub.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (sub.sound) then
|
||
|
|
surface.PlaySound(sub.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction(k, itemTable.id, inventory, sub.data)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
menu:AddOption(L(v.name or k), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (v.OnClick) then
|
||
|
|
send = v.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (v.sound) then
|
||
|
|
surface.PlaySound(v.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction(k, itemTable.id, inventory)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end):SetImage(v.icon or "icon16/brick.png")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- we want drop to show up as the last option
|
||
|
|
local info = itemTable.functions.drop
|
||
|
|
|
||
|
|
if (info and info.OnCanRun and info.OnCanRun(itemTable) != false) then
|
||
|
|
menu:AddOption(L(info.name or "drop"), function()
|
||
|
|
itemTable.player = LocalPlayer()
|
||
|
|
local send = true
|
||
|
|
|
||
|
|
if (info.OnClick) then
|
||
|
|
send = info.OnClick(itemTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (info.sound) then
|
||
|
|
surface.PlaySound(info.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (send != false) then
|
||
|
|
InventoryAction("drop", itemTable.id, inventory)
|
||
|
|
end
|
||
|
|
itemTable.player = nil
|
||
|
|
end):SetImage(info.icon or "icon16/brick.png")
|
||
|
|
end
|
||
|
|
|
||
|
|
menu:Open()
|
||
|
|
for _, v in pairs(menu:GetChildren()[1]:GetChildren()) do
|
||
|
|
v:SetFont("MenuFontNoClamp")
|
||
|
|
end
|
||
|
|
|
||
|
|
itemTable.player = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local XYchanges = {
|
||
|
|
[1] = {x = 1, y = 6},
|
||
|
|
[2] = {x = 1, y = 7},
|
||
|
|
[3] = {x = 1, y = 8},
|
||
|
|
[4] = {x = 1, y = 9},
|
||
|
|
[5] = {x = 1, y = 10},
|
||
|
|
}
|
||
|
|
|
||
|
|
function PANEL:OnDrop(bDragging, inventoryPanel, inventory, gridX, gridY)
|
||
|
|
local item = self.itemTable
|
||
|
|
|
||
|
|
if (!item or !bDragging) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (inventory and inventory.vars and inventory.vars.isEquipSlots) then
|
||
|
|
if (gridX == 5 and gridY <= 5) then
|
||
|
|
gridX, gridY = XYchanges[gridY].x, XYchanges[gridY].y
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (!IsValid(inventoryPanel)) then
|
||
|
|
local inventoryID = self.inventoryID
|
||
|
|
|
||
|
|
if (inventoryID) then
|
||
|
|
InventoryAction("drop", item.id, inventoryID, {})
|
||
|
|
end
|
||
|
|
elseif (inventoryPanel:IsAllEmpty(gridX, gridY, item.width, item.height, self)) then
|
||
|
|
local oldX, oldY = self.gridX, self.gridY
|
||
|
|
|
||
|
|
if (oldX != gridX or oldY != gridY or self.inventoryID != inventoryPanel.invID) then
|
||
|
|
self:Move(gridX, gridY, inventoryPanel)
|
||
|
|
end
|
||
|
|
elseif (inventoryPanel.combineItem) then
|
||
|
|
local combineItem = inventoryPanel.combineItem
|
||
|
|
local inventoryID = combineItem.invID
|
||
|
|
|
||
|
|
if (inventoryID) then
|
||
|
|
local info = combineItem.functions.combine
|
||
|
|
|
||
|
|
if (info and info.OnCanRun and info.OnCanRun(combineItem, {item.id}) != false) then
|
||
|
|
combineItem.player = LocalPlayer()
|
||
|
|
|
||
|
|
if (combineItem.functions.combine.sound) then
|
||
|
|
surface.PlaySound(combineItem.functions.combine.sound)
|
||
|
|
end
|
||
|
|
|
||
|
|
InventoryAction("combine", combineItem.id, inventoryID, {item.id})
|
||
|
|
combineItem.player = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local info2 = item.functions.combined
|
||
|
|
|
||
|
|
if (info2 and info2.OnCanRun and info2.OnCanRun(item, {combineItem.id}) != false) then
|
||
|
|
item.player = LocalPlayer()
|
||
|
|
InventoryAction("combined", item.id, inventoryID, {combineItem.id})
|
||
|
|
item.player = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:Move(newX, newY, givenInventory, bNoSend)
|
||
|
|
local iconSize2 = givenInventory.iconSize
|
||
|
|
local oldX, oldY = self.gridX, self.gridY
|
||
|
|
local oldParent = self:GetParent()
|
||
|
|
|
||
|
|
if (givenInventory:OnTransfer(oldX, oldY, newX, newY, oldParent, bNoSend) == false) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local isEqSlots = givenInventory:IsEquipSlotsPanel()
|
||
|
|
local x = (newX - 1 + (isEqSlots and newY > 5 and 4 or 0)) * iconSize2
|
||
|
|
local y = (newY - 1 - (isEqSlots and newY > 5 and 5 or 0)) * iconSize2 + givenInventory:GetPadding(2)
|
||
|
|
|
||
|
|
self.gridX = newX
|
||
|
|
self.gridY = newY
|
||
|
|
|
||
|
|
self:SetParent(givenInventory)
|
||
|
|
self:SetPos(x, y)
|
||
|
|
|
||
|
|
if (self.slots) then
|
||
|
|
for _, v in ipairs(self.slots) do
|
||
|
|
if (IsValid(v) and v.item == self) then
|
||
|
|
v.item = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self.slots = {}
|
||
|
|
|
||
|
|
for currentX = 1, self.gridW do
|
||
|
|
for currentY = 1, self.gridH do
|
||
|
|
local slot = givenInventory.slots[self.gridX + currentX - 1][self.gridY + currentY - 1]
|
||
|
|
|
||
|
|
slot.item = self
|
||
|
|
self.slots[#self.slots + 1] = slot
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local path = "willardnetworks/inventory/"
|
||
|
|
local randomSounds = {"inv_move1.wav", "inv_move2.wav", "inv_move3.wav", "inv_move4.mp3", "inv_move5.mp3", "inv_move6.mp3"}
|
||
|
|
surface.PlaySound(path .. table.Random(randomSounds))
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:PaintOver(width, height)
|
||
|
|
local itemTable = self.itemTable
|
||
|
|
|
||
|
|
if (itemTable and itemTable.PaintOver) then
|
||
|
|
itemTable.PaintOver(self, itemTable, width, height)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:ExtraPaint(width, height) end
|
||
|
|
|
||
|
|
function PANEL:Paint(width, height)
|
||
|
|
surface.SetDrawColor(0, 0, 0, 85)
|
||
|
|
surface.DrawRect(2, 2, width - 0, height - 4)
|
||
|
|
|
||
|
|
self:ExtraPaint(width, height)
|
||
|
|
|
||
|
|
BaseClass.Paint(self, width, height)
|
||
|
|
end
|
||
|
|
|
||
|
|
vgui.Register("ixItemIconAdvanced", PANEL, "DModelPanel")
|
||
|
|
|
||
|
|
PANEL = {}
|
||
|
|
|
||
|
|
AccessorFunc(PANEL, "iconSize", "IconSize", FORCE_NUMBER)
|
||
|
|
AccessorFunc(PANEL, "bHighlighted", "Highlighted", FORCE_BOOL)
|
||
|
|
|
||
|
|
function PANEL:Init()
|
||
|
|
self:SetIconSize(iconSize)
|
||
|
|
self:Receiver(RECEIVER_NAME, self.ReceiveDrop)
|
||
|
|
self:RequestFocus()
|
||
|
|
|
||
|
|
self.Paint = function(this, w, h)
|
||
|
|
render.ClearDepth() -- Fix for broken DModelPanel item icon depth
|
||
|
|
surface.SetDrawColor(0, 0, 0, 85)
|
||
|
|
end
|
||
|
|
|
||
|
|
self.panels = {}
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:GetPadding(index)
|
||
|
|
return select(index, self:GetDockPadding())
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:FitParent(invWidth, invHeight)
|
||
|
|
local parent = self:GetParent()
|
||
|
|
|
||
|
|
if (!IsValid(parent)) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local width, height = parent:GetSize()
|
||
|
|
local padding = 4
|
||
|
|
local iconSize2
|
||
|
|
|
||
|
|
if (invWidth > invHeight) then
|
||
|
|
iconSize2 = (width - padding * 2) / invWidth
|
||
|
|
elseif (invHeight > invWidth) then
|
||
|
|
iconSize2 = (height - padding * 2) / invHeight
|
||
|
|
else
|
||
|
|
-- we use height because the titlebar will make it more tall than it is wide
|
||
|
|
iconSize2 = (height - padding * 2) / invHeight - 4
|
||
|
|
end
|
||
|
|
|
||
|
|
self:SetSize(iconSize2 * invWidth + padding * 2, iconSize2 * invHeight + padding * 2)
|
||
|
|
self:SetIconSize(iconSize2)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnRemove()
|
||
|
|
if (self.childPanels) then
|
||
|
|
for _, v in ipairs(self.childPanels) do
|
||
|
|
if (v != self) then
|
||
|
|
v:Remove()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:ViewOnly()
|
||
|
|
self.viewOnly = true
|
||
|
|
|
||
|
|
for _, icon in pairs(self.panels) do
|
||
|
|
icon.OnMousePressed = nil
|
||
|
|
icon.OnMouseReleased = nil
|
||
|
|
icon.doRightClick = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:SetInventory(inventory, bFitParent)
|
||
|
|
if (inventory.slots) then
|
||
|
|
local invWidth, invHeight = inventory:GetSize()
|
||
|
|
self.invID = inventory:GetID()
|
||
|
|
|
||
|
|
if (IsValid(ix.gui.inv1) and ix.gui.inv1.childPanels and inventory != LocalPlayer():GetCharacter():GetInventory()) then
|
||
|
|
self:SetIconSize(ix.gui.inv1:GetIconSize())
|
||
|
|
self:SetPaintedManually(true)
|
||
|
|
self.bNoBackgroundBlur = true
|
||
|
|
|
||
|
|
ix.gui.inv1.childPanels[#ix.gui.inv1.childPanels + 1] = self
|
||
|
|
elseif (bFitParent) then
|
||
|
|
self:FitParent(invWidth, invHeight)
|
||
|
|
else
|
||
|
|
self:SetSize(self.iconSize, self.iconSize)
|
||
|
|
end
|
||
|
|
|
||
|
|
self:SetGridSize(invWidth, invHeight)
|
||
|
|
|
||
|
|
for x, items in pairs(inventory.slots) do
|
||
|
|
for y, data in pairs(items) do
|
||
|
|
if (!data.id) then continue end
|
||
|
|
|
||
|
|
local item = ix.item.instances[data.id]
|
||
|
|
|
||
|
|
if (item and !IsValid(self.panels[item.id])) then
|
||
|
|
local icon = self:AddIcon(item, item:GetModel() or "models/props_junk/popcan01a.mdl",
|
||
|
|
x, y, item.width, item.height, item:GetSkin(), item:GetModelBodygroups(), item.color, item.material, item.rotate, item.OnInventoryDraw)
|
||
|
|
|
||
|
|
if (IsValid(icon)) then
|
||
|
|
icon:SetHelixTooltip(function(tooltip)
|
||
|
|
ix.hud.PopulateItemTooltip(tooltip, item)
|
||
|
|
end)
|
||
|
|
|
||
|
|
self.panels[item.id] = icon
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnKeyCodePressed(key)
|
||
|
|
local hoveredPanel = vgui.GetHoveredPanel()
|
||
|
|
|
||
|
|
if (hoveredPanel and (hoveredPanel:GetName() == "ixItemIcon" or hoveredPanel:GetName() == "ixItemIconAdvanced")) then
|
||
|
|
if (key == KEY_Q) then
|
||
|
|
hoveredPanel:OnDrop(true)
|
||
|
|
elseif (key == KEY_R) then
|
||
|
|
local itemTable = hoveredPanel:GetItemTable()
|
||
|
|
local itemBase = itemTable.base
|
||
|
|
|
||
|
|
if (itemBase == "base_ammo") then
|
||
|
|
InventoryAction("use", itemTable.id, itemTable.invID)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:SetGridSize(w, h)
|
||
|
|
local iconSize2 = self.iconSize
|
||
|
|
local newWidth = w * iconSize2
|
||
|
|
local newHeight = h * iconSize2 + self:GetPadding(2) + self:GetPadding(4)
|
||
|
|
|
||
|
|
self.gridW = w
|
||
|
|
self.gridH = h
|
||
|
|
|
||
|
|
self:SetSize(newWidth, newHeight)
|
||
|
|
self:BuildSlots()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:PerformLayout(width, height)
|
||
|
|
if (self.Sizing and self.gridW and self.gridH) then
|
||
|
|
local newWidth = (width - 8) / self.gridW
|
||
|
|
local newHeight = (height - self:GetPadding(2) + self:GetPadding(4)) / self.gridH
|
||
|
|
|
||
|
|
self:SetIconSize((newWidth + newHeight) / 2)
|
||
|
|
self:RebuildItems()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:BuildSlots()
|
||
|
|
local iconSize2 = self.iconSize
|
||
|
|
|
||
|
|
self.slots = self.slots or {}
|
||
|
|
|
||
|
|
local function PaintSlot(slot, w, h)
|
||
|
|
surface.SetDrawColor(35, 35, 35, 85)
|
||
|
|
surface.DrawRect(1, 1, w - SScaleMin(2 / 3), h - SScaleMin(2 / 3))
|
||
|
|
|
||
|
|
surface.SetDrawColor(80, 80, 80, 255)
|
||
|
|
surface.DrawOutlinedRect(1, 1, w - SScaleMin(2 / 3), h - SScaleMin(2 / 3))
|
||
|
|
end
|
||
|
|
|
||
|
|
for _, v in ipairs(self.slots) do
|
||
|
|
for _, v2 in ipairs(v) do
|
||
|
|
v2:Remove()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self.slots = {}
|
||
|
|
|
||
|
|
for x = 1, self.gridW do
|
||
|
|
self.slots[x] = {}
|
||
|
|
|
||
|
|
for y = 1, self.gridH do
|
||
|
|
local slot = self:Add("DPanel")
|
||
|
|
slot:SetZPos(-999)
|
||
|
|
slot.gridX = x
|
||
|
|
slot.gridY = y
|
||
|
|
slot:SetPos((x - 1) * iconSize2, (y - 1) * iconSize2 + self:GetPadding(2))
|
||
|
|
slot:SetSize(iconSize2, iconSize2)
|
||
|
|
slot.Paint = PaintSlot
|
||
|
|
|
||
|
|
self.slots[x][y] = slot
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:RebuildItems()
|
||
|
|
local iconSize2 = self.iconSize
|
||
|
|
|
||
|
|
for x = 1, self.gridW do
|
||
|
|
for y = 1, self.gridH do
|
||
|
|
local slot = self.slots[x][y]
|
||
|
|
|
||
|
|
slot:SetPos((x - 1) * iconSize2, (y - 1) * iconSize2 + self:GetPadding(2))
|
||
|
|
slot:SetSize(iconSize2, iconSize2)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for _, v in pairs(self.panels) do
|
||
|
|
if (IsValid(v)) then
|
||
|
|
v:SetPos(self.slots[v.gridX][v.gridY]:GetPos())
|
||
|
|
v:SetSize(v.gridW * iconSize2, v.gridH * iconSize2)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:PaintDragPreview(width, height, mouseX, mouseY, itemPanel)
|
||
|
|
local iconSize2 = self.iconSize
|
||
|
|
local item = itemPanel:GetItemTable()
|
||
|
|
|
||
|
|
if (item) then
|
||
|
|
local inventory = ix.item.inventories[self.invID]
|
||
|
|
local dropX = math.ceil((mouseX - 0 - (itemPanel.gridW - 1) * 32) / iconSize2)
|
||
|
|
local dropY = math.ceil((mouseY - self:GetPadding(2) - (itemPanel.gridH - 1) * 32) / iconSize2)
|
||
|
|
|
||
|
|
local hoveredPanel = vgui.GetHoveredPanel()
|
||
|
|
|
||
|
|
if (IsValid(hoveredPanel) and hoveredPanel != itemPanel and hoveredPanel.GetItemTable) then
|
||
|
|
local hoveredItem = hoveredPanel:GetItemTable()
|
||
|
|
|
||
|
|
if (hoveredItem) then
|
||
|
|
local info = hoveredItem.functions.combine
|
||
|
|
local info2 = item.functions.combined
|
||
|
|
|
||
|
|
if ((info and info.OnCanRun and info.OnCanRun(hoveredItem, {item.id}) != false) or (info2 and info2.OnCanRun and info2.OnCanRun(item, {hoveredItem.id}) != false)) then
|
||
|
|
surface.SetDrawColor(ColorAlpha(derma.GetColor("Info", self, Color(200, 0, 0)), 20))
|
||
|
|
surface.DrawRect(
|
||
|
|
hoveredPanel.x,
|
||
|
|
hoveredPanel.y,
|
||
|
|
hoveredPanel:GetWide(),
|
||
|
|
hoveredPanel:GetTall()
|
||
|
|
)
|
||
|
|
|
||
|
|
self.combineItem = hoveredItem
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self.combineItem = nil
|
||
|
|
local isEquipSlots = inventory.vars and inventory.vars.isEquipSlots or false
|
||
|
|
|
||
|
|
-- don't draw grid if we're dragging it out of bounds
|
||
|
|
if (inventory) then
|
||
|
|
local invWidth, invHeight = inventory:GetSize()
|
||
|
|
if (dropX < 1 or dropY < 1 or
|
||
|
|
dropX - (isEquipSlots and dropX == 5 and 4 or 0) + itemPanel.gridW - 1 > invWidth or
|
||
|
|
dropY + itemPanel.gridH - 1 > invHeight) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for x = 0, itemPanel.gridW - 1 do
|
||
|
|
for y = 0, itemPanel.gridH - 1 do
|
||
|
|
local x2, y2 = dropX + x, dropY + y
|
||
|
|
local eqX2, eqY2 = (!isEquipSlots and x2 or 1), (!isEquipSlots and y2 or x2 == 5 and y2 + 5 or y2)
|
||
|
|
|
||
|
|
local bEmpty = self:IsEmpty(eqX2, eqY2, itemPanel)
|
||
|
|
local canMove = (hook.Run("CanMoveItemSameInv", item, inventory, eqX2, eqY2) == true)
|
||
|
|
|
||
|
|
if (isEquipSlots and canMove and bEmpty) then
|
||
|
|
surface.SetDrawColor(0, 255, 0, 10)
|
||
|
|
elseif (!isEquipSlots and bEmpty) then
|
||
|
|
surface.SetDrawColor(0, 255, 0, 10)
|
||
|
|
else
|
||
|
|
surface.SetDrawColor(255, 255, 0, 10)
|
||
|
|
end
|
||
|
|
|
||
|
|
surface.DrawRect((x2 - 1) * iconSize, (y2 - 1) * iconSize2 + self:GetPadding(2), iconSize2, iconSize2)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:PaintOver(width, height)
|
||
|
|
local panel = self.previewPanel
|
||
|
|
|
||
|
|
if (IsValid(panel)) then
|
||
|
|
local itemPanel = (dragndrop.GetDroppable() or {})[1]
|
||
|
|
|
||
|
|
if (IsValid(itemPanel)) then
|
||
|
|
if not (self.slots) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self:PaintDragPreview(width, height, self.previewX, self.previewY, itemPanel)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self.previewPanel = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:IsEmpty(x, y, this)
|
||
|
|
if (self.slots) then
|
||
|
|
return (self.slots[x] and self.slots[x][y]) and (!IsValid(self.slots[x][y].item) or self.slots[x][y].item == this)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:IsAllEmpty(x, y, width, height, this)
|
||
|
|
for x2 = 0, width - 1 do
|
||
|
|
for y2 = 0, height - 1 do
|
||
|
|
if (!self:IsEmpty(x + x2, y + y2, this)) then
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnTransfer(oldX, oldY, x, y, oldInventory, noSend)
|
||
|
|
local inventories = ix.item.inventories
|
||
|
|
local inventory = inventories[oldInventory.invID]
|
||
|
|
local inventory2 = inventories[self.invID]
|
||
|
|
local item
|
||
|
|
if (inventory) then
|
||
|
|
item = inventory:GetItemAt(oldX, oldY)
|
||
|
|
|
||
|
|
if (!item) then
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
|
||
|
|
if (hook.Run("CanTransferItem", item, inventories[oldInventory.invID], inventories[self.invID], x, y) == false) then
|
||
|
|
return false, "notAllowed"
|
||
|
|
end
|
||
|
|
|
||
|
|
if (item.CanTransfer and
|
||
|
|
item:CanTransfer(inventory, inventory != inventory2 and inventory2 or nil) == false) then
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (!noSend) then
|
||
|
|
net.Start("ixInventoryMove")
|
||
|
|
net.WriteUInt(oldX, 6)
|
||
|
|
net.WriteUInt(oldY, 6)
|
||
|
|
net.WriteUInt(x, 6)
|
||
|
|
net.WriteUInt(y, 6)
|
||
|
|
net.WriteUInt(oldInventory.invID, 32)
|
||
|
|
net.WriteUInt(self != oldInventory and self.invID or oldInventory.invID, 32)
|
||
|
|
net.SendToServer()
|
||
|
|
end
|
||
|
|
|
||
|
|
if (inventory) then
|
||
|
|
inventory.slots[oldX][oldY] = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
if (item and inventory2) then
|
||
|
|
inventory2.slots[x] = inventory2.slots[x] or {}
|
||
|
|
inventory2.slots[x][y] = item
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:IsEquipSlotsPanel()
|
||
|
|
local inventory = ix.item.inventories[self.invID]
|
||
|
|
if inventory and inventory.vars then
|
||
|
|
if inventory.vars.isEquipSlots then
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:AddIcon(item, model, x, y, w, h, skin, bodygroups, color, material, bRotate, OnInventoryDraw)
|
||
|
|
local iconSize2 = self.iconSize
|
||
|
|
local advanced = color or material or bRotate or OnInventoryDraw
|
||
|
|
|
||
|
|
w = w or 1
|
||
|
|
h = h or 1
|
||
|
|
|
||
|
|
if (self.slots[x] and self.slots[x][y]) then
|
||
|
|
local panel = advanced and self:Add("ixItemIconAdvanced") or self:Add("ixItemIcon")
|
||
|
|
panel:SetSize(w * iconSize2, h * iconSize2)
|
||
|
|
panel:SetZPos(999)
|
||
|
|
panel:InvalidateLayout(true)
|
||
|
|
panel:SetModel(model, skin, bodygroups)
|
||
|
|
panel:SetPos(self.slots[x][y]:GetPos())
|
||
|
|
panel.gridX = x
|
||
|
|
panel.gridY = y
|
||
|
|
|
||
|
|
if (advanced) then
|
||
|
|
local entity = panel:GetEntity()
|
||
|
|
color = color or Color(255, 255, 255)
|
||
|
|
|
||
|
|
if (color) then
|
||
|
|
panel:SetColor(color)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (material) then
|
||
|
|
entity:SetMaterial(material)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (skin) then
|
||
|
|
entity:SetSkin(skin)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (OnInventoryDraw) then
|
||
|
|
OnInventoryDraw(item, entity)
|
||
|
|
end
|
||
|
|
|
||
|
|
panel.LayoutEntity = function(this, entity)
|
||
|
|
if (ix.gui.menu and IsValid(ix.gui.menu)) then
|
||
|
|
this:SetColor(ColorAlpha(color, ix.gui.menu:GetAlpha()))
|
||
|
|
end
|
||
|
|
|
||
|
|
if (!bRotate) then return end
|
||
|
|
|
||
|
|
local angle = entity:GetAngles()
|
||
|
|
angle.y = angle.y + FrameTime() * 30
|
||
|
|
entity:SetAngles(angle)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (self:IsEquipSlotsPanel()) then
|
||
|
|
if self.slots[1] then
|
||
|
|
-- witness my error noia
|
||
|
|
local x1W = self.slots[1][1] and self.slots[1][1].GetWide and self.slots[1][1]:GetWide()
|
||
|
|
local x1Pos = self.slots[1][1] and self.slots[1][1].GetPos and self.slots[1][1]:GetPos()
|
||
|
|
local _, newY = false, false
|
||
|
|
if self.slots[1][y - 5] and self.slots[1][y - 5].GetPos then
|
||
|
|
_, newY = self.slots[1][y - 5]:GetPos()
|
||
|
|
end
|
||
|
|
|
||
|
|
if (y > 5 and x == 1) and (x1W and x1Pos and newY) then
|
||
|
|
panel:SetPos(x1Pos + (x1W * 4), newY)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
panel.gridW = w
|
||
|
|
panel.gridH = h
|
||
|
|
|
||
|
|
local inventory = ix.item.inventories[self.invID]
|
||
|
|
|
||
|
|
if (!inventory) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local itemTable = inventory:GetItemAt(panel.gridX, panel.gridY)
|
||
|
|
|
||
|
|
panel:SetInventoryID(inventory:GetID())
|
||
|
|
panel:SetItemTable(itemTable)
|
||
|
|
|
||
|
|
if (self.panels[itemTable:GetID()]) then
|
||
|
|
self.panels[itemTable:GetID()]:Remove()
|
||
|
|
end
|
||
|
|
|
||
|
|
if (advanced) then
|
||
|
|
if (itemTable.iconCam) then
|
||
|
|
panel:SetCamPos(itemTable.iconCam.pos)
|
||
|
|
panel:SetFOV(itemTable.iconCam.fov)
|
||
|
|
panel:SetLookAng(itemTable.iconCam.ang)
|
||
|
|
else
|
||
|
|
local entity = panel:GetEntity()
|
||
|
|
local pos = entity:GetPos()
|
||
|
|
local camData = PositionSpawnIcon(entity, pos)
|
||
|
|
|
||
|
|
if (camData) then
|
||
|
|
panel:SetCamPos(camData.origin)
|
||
|
|
panel:SetFOV(camData.fov)
|
||
|
|
panel:SetLookAng(camData.angles)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if (itemTable.exRender) then
|
||
|
|
panel.Icon:SetVisible(false)
|
||
|
|
panel.ExtraPaint = function(this, panelX, panelY)
|
||
|
|
local exIcon = ikon:GetIcon(itemTable.uniqueID)
|
||
|
|
if (exIcon) then
|
||
|
|
surface.SetMaterial(exIcon)
|
||
|
|
surface.SetDrawColor(color_white)
|
||
|
|
surface.DrawTexturedRect(0, 0, panelX, panelY)
|
||
|
|
else
|
||
|
|
ikon:renderIcon(
|
||
|
|
itemTable.uniqueID,
|
||
|
|
itemTable.width,
|
||
|
|
itemTable.height,
|
||
|
|
itemTable:GetModel(),
|
||
|
|
itemTable.iconCam
|
||
|
|
)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
-- yeah..
|
||
|
|
RenderNewIcon(panel, itemTable)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
panel.slots = {}
|
||
|
|
|
||
|
|
for i = 0, w - 1 do
|
||
|
|
for i2 = 0, h - 1 do
|
||
|
|
local slot = self.slots[x + i] and self.slots[x + i][y + i2]
|
||
|
|
|
||
|
|
if (IsValid(slot)) then
|
||
|
|
slot.item = panel
|
||
|
|
panel.slots[#panel.slots + 1] = slot
|
||
|
|
else
|
||
|
|
for _, v in ipairs(panel.slots) do
|
||
|
|
v.item = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
panel:Remove()
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return panel
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:ReceiveDrop(panels, bDropped, menuIndex, x, y)
|
||
|
|
local panel = panels[1]
|
||
|
|
|
||
|
|
if (!IsValid(panel)) then
|
||
|
|
self.previewPanel = nil
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (bDropped) then
|
||
|
|
local inventory = ix.item.inventories[self.invID]
|
||
|
|
|
||
|
|
if (inventory and panel.OnDrop) then
|
||
|
|
local dropX = math.ceil((x - 0 - (panel.gridW - 1) * 32) / self.iconSize)
|
||
|
|
local dropY = math.ceil((y - self:GetPadding(2) - (panel.gridH - 1) * 32) / self.iconSize)
|
||
|
|
|
||
|
|
panel:OnDrop(true, self, inventory, dropX, dropY)
|
||
|
|
end
|
||
|
|
|
||
|
|
self.previewPanel = nil
|
||
|
|
else
|
||
|
|
self.previewPanel = panel
|
||
|
|
self.previewX = x
|
||
|
|
self.previewY = y
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:CreateNoSlots(backpacks, type)
|
||
|
|
if backpacks.slots then
|
||
|
|
for _, v in pairs(backpacks.slots) do
|
||
|
|
if IsValid(v) then
|
||
|
|
v:Remove()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
backpacks.slots = {}
|
||
|
|
|
||
|
|
if type == "noSlots" then return end
|
||
|
|
|
||
|
|
for x = 1, (!type and 7 or type == "noLarge" and 4 or 3) do
|
||
|
|
for y = 1, 4 do
|
||
|
|
local noSlot = backpacks:Add("Panel")
|
||
|
|
noSlot:SetPos((x - 1) * iconSize + (iconSize * self:GetNoSlotsXPosMultiplier(type)), (y - 1) * iconSize + SScaleMin(30 / 3))
|
||
|
|
noSlot:SetSize(iconSize, iconSize)
|
||
|
|
|
||
|
|
noSlot.Paint = PaintLockedSlot
|
||
|
|
|
||
|
|
backpacks.slots[#backpacks.slots + 1] = noSlot
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:UpdateNoSlots()
|
||
|
|
local backpacks = ix.gui.menuInventoryParent.backpacks
|
||
|
|
if !backpacks or backpacks and !IsValid(backpacks) then return end
|
||
|
|
|
||
|
|
local char = LocalPlayer():GetCharacter()
|
||
|
|
if !char then return end
|
||
|
|
|
||
|
|
local inventory = char:GetInventory()
|
||
|
|
if !inventory then return end
|
||
|
|
|
||
|
|
local hasSmallBag = inventory:HasItem("smallbag")
|
||
|
|
local hasLargeBag = inventory:HasItem("largebag")
|
||
|
|
|
||
|
|
local smallBag = hasSmallBag and self:GetIsInEquipSlots(char, hasSmallBag)
|
||
|
|
local largeBag = hasLargeBag and self:GetIsInEquipSlots(char, hasLargeBag)
|
||
|
|
|
||
|
|
if (!smallBag and !largeBag) then
|
||
|
|
self:CreateNoSlots(backpacks)
|
||
|
|
elseif largeBag and !smallBag then
|
||
|
|
self:CreateNoSlots(backpacks, "noSmall")
|
||
|
|
elseif !largeBag and smallBag then
|
||
|
|
self:CreateNoSlots(backpacks, "noLarge")
|
||
|
|
elseif largeBag and smallBag then
|
||
|
|
self:CreateNoSlots(backpacks, "noSlots")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:GetIsInEquipSlots(char, item)
|
||
|
|
local eqSlots = char:GetEquipInventory()
|
||
|
|
if !eqSlots then return false end
|
||
|
|
|
||
|
|
if !item.invID then return false end
|
||
|
|
if item.invID != eqSlots then return false end
|
||
|
|
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:GetNoSlotsXPosMultiplier(type)
|
||
|
|
return (!type and 0 or type == "noLarge" and 3 or 4)
|
||
|
|
end
|
||
|
|
|
||
|
|
vgui.Register("ixInventory", PANEL, "Panel")
|
||
|
|
|
||
|
|
hook.Add("CreateMenuButtons", "ixInventory", function(tabs)
|
||
|
|
if (hook.Run("CanPlayerViewInventory") == false) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
tabs["inv"] = {
|
||
|
|
bDefault = true,
|
||
|
|
|
||
|
|
RowNumber = 2,
|
||
|
|
|
||
|
|
Width = 19,
|
||
|
|
|
||
|
|
Height = 17,
|
||
|
|
|
||
|
|
Icon = "willardnetworks/tabmenu/navicons/inventory.png",
|
||
|
|
|
||
|
|
Create = function(info, tempCont)
|
||
|
|
local titlePushDown = SScaleMin(30 / 3)
|
||
|
|
local padding = SScaleMin(30 / 3)
|
||
|
|
local topPushDown = SScaleMin(150 / 3)
|
||
|
|
local scale780 = SScaleMin(780 / 3)
|
||
|
|
local scale120 = SScaleMin(120 / 3)
|
||
|
|
|
||
|
|
tempCont:SetSize(ScrW(), ScrH())
|
||
|
|
|
||
|
|
local newCont = tempCont:Add("Panel")
|
||
|
|
newCont:SetSize(ScrW() - (topPushDown * 2), scale120 + scale780 + titlePushDown)
|
||
|
|
newCont:Center()
|
||
|
|
|
||
|
|
local sizeXtitle, sizeYtitle = newCont:GetWide(), scale120
|
||
|
|
local sizeXcontent, sizeYcontent = newCont:GetWide(), (scale780)
|
||
|
|
|
||
|
|
newCont.titlePanel = newCont:Add("Panel")
|
||
|
|
newCont.titlePanel:SetSize(sizeXtitle, sizeYtitle)
|
||
|
|
newCont.titlePanel:SetPos(newCont:GetWide() * 0.5 - newCont.titlePanel:GetWide() * 0.5)
|
||
|
|
|
||
|
|
local invTitleIcon = newCont.titlePanel:Add("DImage")
|
||
|
|
invTitleIcon:SetImage("willardnetworks/tabmenu/navicons/inventory.png")
|
||
|
|
invTitleIcon:SetSize(SScaleMin(19 / 3), SScaleMin(17 / 3))
|
||
|
|
|
||
|
|
local invTitle = newCont.titlePanel:Add("DLabel")
|
||
|
|
invTitle:SetFont("TitlesFontNoClamp")
|
||
|
|
invTitle:SetText("Inventaire")
|
||
|
|
invTitle:SizeToContents()
|
||
|
|
invTitle:SetPos(SScaleMin(27 / 3), (SScaleMin(17 / 3) - invTitle:GetTall()) * 0.5)
|
||
|
|
|
||
|
|
newCont.contentFrame = newCont:Add("Panel")
|
||
|
|
newCont.contentFrame:SetSize(sizeXcontent, sizeYcontent)
|
||
|
|
newCont.contentFrame:SetPos(newCont:GetWide() * 0.5 - newCont.contentFrame:GetWide() * 0.5, titlePushDown)
|
||
|
|
|
||
|
|
newCont.invFrame = newCont.contentFrame:Add("Panel")
|
||
|
|
newCont.invFrame:SetSize(newCont.contentFrame:GetWide() * 0.5 - padding, newCont.contentFrame:GetTall())
|
||
|
|
newCont.invFrame:Dock(LEFT)
|
||
|
|
newCont.invFrame:DockMargin(0, 0, padding, 0)
|
||
|
|
|
||
|
|
newCont.backpacks = newCont.invFrame:Add("Panel")
|
||
|
|
newCont.backpacks:SetTall(((iconSize + SScaleMin(2 / 3)) * 4) + SScaleMin(21 / 3))
|
||
|
|
newCont.backpacks:Dock(BOTTOM)
|
||
|
|
|
||
|
|
ix.gui.menuInventoryParent = newCont
|
||
|
|
|
||
|
|
local canvas = newCont.invFrame:Add("DTileLayout")
|
||
|
|
local canvasLayout = canvas.PerformLayout
|
||
|
|
canvas.PerformLayout = nil -- we'll layout after we add the panels instead of each time one is added
|
||
|
|
canvas:SetBorder(0)
|
||
|
|
canvas:SetSpaceX(2)
|
||
|
|
canvas:SetSpaceY(2)
|
||
|
|
canvas:Dock(FILL)
|
||
|
|
|
||
|
|
ix.gui.menuInventorynewCont = canvas
|
||
|
|
|
||
|
|
local panel = canvas:Add("ixInventory")
|
||
|
|
panel.bNoBackgroundBlur = true
|
||
|
|
panel.childPanels = {}
|
||
|
|
|
||
|
|
local char = LocalPlayer():GetCharacter()
|
||
|
|
local inventory = char:GetInventory()
|
||
|
|
|
||
|
|
if (inventory) then
|
||
|
|
panel:SetInventory(inventory)
|
||
|
|
end
|
||
|
|
|
||
|
|
ix.gui.inv1 = panel
|
||
|
|
ix.gui.inv1:UpdateNoSlots()
|
||
|
|
|
||
|
|
local bFoundLarge, bFoundSmall = false, false
|
||
|
|
for _, v in SortedPairsByMemberValue(inventory:GetItemsByBase("base_containerbags", true), "id") do
|
||
|
|
if v.invID and char.GetEquipInventory and v.invID != char:GetEquipInventory() then continue end
|
||
|
|
if (!v.isBag) then
|
||
|
|
continue
|
||
|
|
end
|
||
|
|
|
||
|
|
if (v.name != "Sac" and v.name != "Petite sacoche") then
|
||
|
|
continue
|
||
|
|
elseif (v.name == "Sac") then
|
||
|
|
if (bFoundLarge) then
|
||
|
|
continue
|
||
|
|
else
|
||
|
|
bFoundLarge = true
|
||
|
|
end
|
||
|
|
elseif (v.name == "Petite sacoche") then
|
||
|
|
if (bFoundSmall) then
|
||
|
|
continue
|
||
|
|
else
|
||
|
|
bFoundSmall = true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
v.functions.View.OnClick(v)
|
||
|
|
end
|
||
|
|
|
||
|
|
canvas.PerformLayout = canvasLayout
|
||
|
|
canvas:Layout()
|
||
|
|
|
||
|
|
newCont.charFrame = newCont.contentFrame:Add("CharFrame")
|
||
|
|
hook.Run("PostCharInfoFrameOpened", newCont.charFrame)
|
||
|
|
|
||
|
|
local backspaceTitleIcon = newCont.backpacks:Add("DImage")
|
||
|
|
backspaceTitleIcon:SetImage("willardnetworks/mainmenu/content.png")
|
||
|
|
backspaceTitleIcon:SetSize(SScaleMin(16 / 3), SScaleMin(16 / 3))
|
||
|
|
backspaceTitleIcon:SetPos(SScaleMin(1 / 3), SScaleMin(2 / 3))
|
||
|
|
|
||
|
|
local backspaceTitle = newCont.backpacks:Add("DLabel")
|
||
|
|
backspaceTitle:SetFont("SmallerTitleFontNoClamp")
|
||
|
|
backspaceTitle:SetText("Sac à dos")
|
||
|
|
backspaceTitle:SizeToContents()
|
||
|
|
backspaceTitle:SetPos(SScaleMin(25 / 3))
|
||
|
|
end
|
||
|
|
}
|
||
|
|
end)
|
||
|
|
|
||
|
|
hook.Add("PostRenderVGUI", "ixInvHelper", function()
|
||
|
|
local pnl = ix.gui.inv1
|
||
|
|
|
||
|
|
hook.Run("PostDrawInventory", pnl)
|
||
|
|
end)
|