From c99d34408474aadc4940f79aced3925bccbec3e1 Mon Sep 17 00:00:00 2001 From: AlmTech Software Date: Tue, 31 Dec 2019 02:31:24 +0100 Subject: [PATCH] Added item stacking & give item function --- gamemode/engine/core/sh_player_binds.lua | 2 +- gamemode/engine/derma/menus/menu_charinfo.lua | 18 +-- gamemode/engine/lib/server/sv_character.lua | 8 ++ gamemode/engine/lib/server/sv_inventory.lua | 105 ++++++++++++++++-- gamemode/engine/lib/server/sv_networking.lua | 2 + gamemode/engine/lib/sh_items.lua | 8 +- gamemode/settings/sh_items.lua | 3 +- gamemode/settings/sh_settings.lua | 2 +- 8 files changed, 126 insertions(+), 22 deletions(-) diff --git a/gamemode/engine/core/sh_player_binds.lua b/gamemode/engine/core/sh_player_binds.lua index f05bbd5..c9631e0 100644 --- a/gamemode/engine/core/sh_player_binds.lua +++ b/gamemode/engine/core/sh_player_binds.lua @@ -18,7 +18,7 @@ if SERVER then name = Quantum.Server.Char.getBasicCharInfo( Quantum.Server.Char.GetCurrentCharacter( pl ) ).name, money = Quantum.Server.Char.getBasicCharInfo( Quantum.Server.Char.GetCurrentCharacter( pl ) ).money - }, items = { [1] = {"test", 1}, [2] = {"test2", Quantum.Inventory.MaxStackSize } } }) + }, items = Quantum.Server.Char.GetInventory( Quantum.Server.Char.GetCurrentCharacter( pl ) ) }) end } diff --git a/gamemode/engine/derma/menus/menu_charinfo.lua b/gamemode/engine/derma/menus/menu_charinfo.lua index 47a02e1..c9e524a 100644 --- a/gamemode/engine/derma/menus/menu_charinfo.lua +++ b/gamemode/engine/derma/menus/menu_charinfo.lua @@ -107,6 +107,14 @@ function menu.open( dt ) itemframe:SetPos( 0, 0 ) itemframe.Paint = function( self, w, h ) end + ---- TEMPORARY: REMOVE WHEN THE MENU IS DONE ---- + local close = vgui.Create( "DButton", f ) + close:SetText( "DEV CLOSE" ) + close:SizeToContents() + close.w, close.h = close:GetSize() + close:SetPos( 0, f.h - close.h ) + close.DoClick = function( self ) f:Close() end + for ii=1, maxW * maxH, 1 do -- create all of the item panels if( ii != 1 ) then count = count + 1 end @@ -114,7 +122,7 @@ function menu.open( dt ) itempanels[ii].index = ii -- set the vars if( items[ii] ) then - itempanels[ii].item = Quantum.Item.Get( items[ii][1] ) -- get the items info through its id + itempanels[ii].item = Quantum.Item.Get( items[ii][1]) -- get the items info through its id itempanels[ii].item.amount = items[ii][2] || 1 -- get the amount end @@ -222,13 +230,7 @@ function menu.open( dt ) theme.pagetext( self ) end - ---- TEMPORARY: REMOVE WHEN THE MENU IS DONE ---- - local close = vgui.Create( "DButton", f ) - close:SetText( "DEV CLOSE" ) - close:SizeToContents() - close.w, close.h = close:GetSize() - close:SetPos( 0, f.h - close.h ) - close.DoClick = function( self ) f:Close() end + end end diff --git a/gamemode/engine/lib/server/sv_character.lua b/gamemode/engine/lib/server/sv_character.lua index 543ea48..c6dbfee 100644 --- a/gamemode/engine/lib/server/sv_character.lua +++ b/gamemode/engine/lib/server/sv_character.lua @@ -116,4 +116,12 @@ end function Quantum.Server.Char.GetInventory( char ) return char.inventory +end + +function Quantum.Server.Char.GetInventory_cl( char ) + local inv = Quantum.Server.Char.GetInventory( char ) + local returninv = {} + + for i, item in pairs( inv ) do returninv[i] = { id = item.id, amount = item.amount } end + return returninv end \ No newline at end of file diff --git a/gamemode/engine/lib/server/sv_inventory.lua b/gamemode/engine/lib/server/sv_inventory.lua index ec05253..24a7c82 100644 --- a/gamemode/engine/lib/server/sv_inventory.lua +++ b/gamemode/engine/lib/server/sv_inventory.lua @@ -17,16 +17,107 @@ local function isEquippable( item ) return item.equipable || false end -function Quantum.Server.Inventory.SetSlotItem( char, pos, item, amount ) - if( isEquippable( item ) ) then +local function isStackable( item ) + return item.stack || false +end + +function Quantum.Server.Inventory.SetSlotItem( char, pos, itemid, amount ) + local item = Quantum.Item.Get( itemid ) + if( isEquippable( item ) || !isStackable( item ) ) then amount = 1 - char.inventory[pos] = { item } + char.inventory[pos] = { itemid } else amount = amount || 1 - char.inventory[pos] = { item, amount } + char.inventory[pos] = { itemid, amount } + end + Quantum.Debug( "Gave " .. char.name .. " " .. amount .. "x [" .. item.name .. "] at " .. tostring(pos) ) +end + +function Quantum.Server.Inventory.GetSlotItem( char, pos ) return char.inventory[pos] end + +function Quantum.Server.Inventory.FindStackable( char, item ) + if( item.stack ) then + local inv = Quantum.Server.Char.GetInventory( char ) + for i, item2 in pairs( inv ) do + if( item2[1] == item.id ) then -- if the item is stackable and it is the same item + return i -- return its index + end + end + else + return end - Quantum.Debug( "Gave " .. char.name .. " " .. amount .. " [" .. item.name .. "]" ) - return end -function Quantum.Server.Inventory.GetSlotItem( char, x, y ) return char.inventory[x][y] end \ No newline at end of file +local function getStackSize( char, item ) + return item.stack || 1 +end + +local function sortItem( char, itemid, amount ) + + local item = Quantum.Item.Get( itemid ) + local slotitem = Quantum.Server.Inventory.GetSlotItem( char, index ) + local inv = Quantum.Server.Char.GetInventory( char ) + + local stacksize = getStackSize( char, item ) + + local index = Quantum.Server.Inventory.FindStackable( char, item ) || #inv + 1 + + local rest = amount + if( slotitem != nil ) then rest = rest + slotitem[2] end + + local count = 0 + + local itemInSlot = Quantum.Server.Inventory.GetSlotItem( char, index ) + + while( rest > stacksize ) do + print("######## rest:", rest ) + count = count + 1 + + if( count == 1 ) then + if( itemInSlot != nil ) then + rest = rest - ( stacksize - itemInSlot[2] ) + else + rest = rest - stacksize + end + Quantum.Server.Inventory.SetSlotItem( char, index, itemid, stacksize ) + else + index = index + 1 + itemInSlot = Quantum.Server.Inventory.GetSlotItem( char, index ) + + if( itemInSlot != nil ) then + if( itemInSlot[1] == itemid && itemInSlot[2] < stacksize ) then + rest = rest - ( stacksize - itemInSlot[2] ) + Quantum.Server.Inventory.SetSlotItem( char, index, itemid, stacksize ) + + if( rest <= 0 ) then + rest = 0 + break + end + end + else + rest = rest - stacksize + Quantum.Server.Inventory.SetSlotItem( char, index, itemid, stacksize ) + end + end + end + print("######## rest:", rest ) + + Quantum.Server.Inventory.SetSlotItem( char, #inv + 1, itemid, rest ) +end + +function Quantum.Server.Inventory.GiveItem( pl, itemid, amount ) + local char = Quantum.Server.Char.GetCurrentCharacter( pl ) + local inv = Quantum.Server.Char.GetInventory( char ) + local item = Quantum.Item.Get( itemid ) + + if( #inv + 1 <= Quantum.Inventory.Width * Quantum.Inventory.Height || Quantum.Server.Inventory.FindStackable( char, item ) != nil ) then + + sortItem( char, itemid, amount ) + -- send net message to client about item update + + Quantum.Debug( "Inventory Result" ) + PrintTable( inv ) + else + Quantum.Debug( "Tried to give " .. tostring(pl) .. " a item but their inventory is full!" ) + end +end \ No newline at end of file diff --git a/gamemode/engine/lib/server/sv_networking.lua b/gamemode/engine/lib/server/sv_networking.lua index 1ac8baa..8f2daf4 100644 --- a/gamemode/engine/lib/server/sv_networking.lua +++ b/gamemode/engine/lib/server/sv_networking.lua @@ -69,6 +69,8 @@ local function SendDatatableToClient( client, dt, type ) local net_start = net.Start( "quantum_menu_net" ) if( net_start ) then Quantum.Debug( "Sending net message to " .. tostring(client) .. "..." ) end if( table.Count(datatable) > 0 ) then -- if it's empty just dont send it because we will save 8 bits + Quantum.Debug( "###### DT: " .. tostring(datatable) ) + PrintTable( datatable ) net.WriteTable( datatable ) -- send the data to the player end net.Send( client ) diff --git a/gamemode/engine/lib/sh_items.lua b/gamemode/engine/lib/sh_items.lua index 2f93740..9f9b2b1 100644 --- a/gamemode/engine/lib/sh_items.lua +++ b/gamemode/engine/lib/sh_items.lua @@ -8,19 +8,21 @@ Quantum.Item = {} Quantum.Items = {} -function Quantum.Item.Create( id, args ) +function Quantum.Item.Create( itemid, args ) local item = { + id = itemid, name = args.name || "ERROR", -- items name desc = args.desc || "ERROR: Some idiot forgot to give this item a description.", -- items description model = args.model || "models/props_phx/gears/bevel12.mdl", -- items model - stack = args.stack, -- items max stack size + stack = args.stack || 1, -- items max stack size soulbound = args.soulbound, -- if item could be dropped/traded to other players equipable = args.equipable, -- equipable or not rarity = args.rarity || Quantum.Rarity.Trash, -- rarity of the item usefunction = args.usefunction, -- use function consumefunction = args.consumefunction --consume function } - Quantum.Items[id] = item + math.Clamp( item.stack, 1, Quantum.Inventory.MaxStackSize ) -- clamp it so it does not go over the max size + Quantum.Items[itemid] = item return item end diff --git a/gamemode/settings/sh_items.lua b/gamemode/settings/sh_items.lua index d5da324..f305e76 100644 --- a/gamemode/settings/sh_items.lua +++ b/gamemode/settings/sh_items.lua @@ -9,7 +9,6 @@ Quantum.Item.Create( "test", { name = "Test Item", desc = "This is a test item!", model = "models/props_phx/gears/bevel12.mdl", - stack = false, soulbound = true, equipable = false, rarity = Quantum.Rarity.Legendary, @@ -21,7 +20,7 @@ Quantum.Item.Create( "test2", { name = "Trash Item Test", desc = "This is literall trash\nLine breaker test :D\n\nTest :D", model = "models/props_phx/gears/bevel12.mdl", - stack = true, + stack = 25, --wrong change later to 10 or something soulbound = false, equipable = false, rarity = Quantum.Rarity.Trash, diff --git a/gamemode/settings/sh_settings.lua b/gamemode/settings/sh_settings.lua index 6731912..3ccaa25 100644 --- a/gamemode/settings/sh_settings.lua +++ b/gamemode/settings/sh_settings.lua @@ -15,7 +15,7 @@ Quantum.WorkshopLink = "https://steamcommunity.com/sharedfiles/filedetails/?id=1 Quantum.Inventory = { Height = 10, -- NOTE: MAX HEIGHT=12 Width = 16, -- NOTE: MAX WIDTH=18 - MaxStackSize = 99 -- NOTE: MAX MaxStackSize=99 + MaxStackSize = 20 -- NOTE: MAX MaxStackSize=99 } Quantum.Money = {