From 4532357eecfeff837178f3964813765cddf3d6ec Mon Sep 17 00:00:00 2001 From: AlmTech Software Date: Thu, 2 Jan 2020 00:25:25 +0100 Subject: [PATCH] Added Dynamic Networking for Inventory --- .../engine/core/client/cl_inventory_net.lua | 33 +++++++++++++++++- gamemode/engine/core/sh_player_binds.lua | 8 +++++ .../engine/derma/lib/cl_menu_iteminfo.lua | 1 - gamemode/engine/derma/menus/menu_charinfo.lua | 12 +++++-- gamemode/engine/lib/server/sv_inventory.lua | 34 ++++++++++++------- gamemode/engine/lib/server/sv_networking.lua | 11 ++++-- gamemode/shared.lua | 2 +- 7 files changed, 81 insertions(+), 20 deletions(-) diff --git a/gamemode/engine/core/client/cl_inventory_net.lua b/gamemode/engine/core/client/cl_inventory_net.lua index 77fd27b..ce3dc14 100644 --- a/gamemode/engine/core/client/cl_inventory_net.lua +++ b/gamemode/engine/core/client/cl_inventory_net.lua @@ -3,4 +3,35 @@ -- / / / \ | |_ __ ___ | | ___ ___| |__ \ \ -- < < / /\ \ | | '_ ` _ \| |/ _ \/ __| '_ \ > > -- \ \ / ____ \| | | | | | | | __/ (__| | | | / / --- \_\ /_/ \_\_|_| |_| |_|_|\___|\___|_| |_| /_/ \ No newline at end of file +-- \_\ /_/ \_\_|_| |_| |_|_|\___|\___|_| |_| /_/ + +Quantum.Client.InventoryNet = {} + +local function calculateNeededBits( n ) return math.ceil( math.log( n, 2 ) ) end + +Quantum.Inventory.Size = Quantum.Inventory.Width * Quantum.Inventory.Height + +function Quantum.Client.InventoryNet.SetItem( index, itemid, amount ) + if( Quantum.Client.Inventory == nil ) then Quantum.Client.Inventory = {} end + + if( amount >= 1 ) then + Quantum.Client.Inventory[index] = { itemid, amount } + else + Quantum.Client.Inventory[index] = nil + end +end + +local intcodeFunctions = { + [Quantum.IntCode.SET_ITEM] = Quantum.Client.InventoryNet.SetItem +} + +net.Receive( "quantum_item_action", function( len, pl ) + local intcode = net.ReadInt( Quantum.IntCode.BIT_SIZE ) + + -- Parameters + local index = net.ReadInt( calculateNeededBits( Quantum.Inventory.Size ) ) + local itemid = net.ReadString() + local amount = net.ReadInt( calculateNeededBits( Quantum.Inventory.MaxStackSize ) ) + + intcodeFunctions[intcode]( index, itemid, amount ) +end) \ No newline at end of file diff --git a/gamemode/engine/core/sh_player_binds.lua b/gamemode/engine/core/sh_player_binds.lua index c9631e0..e168ca4 100644 --- a/gamemode/engine/core/sh_player_binds.lua +++ b/gamemode/engine/core/sh_player_binds.lua @@ -19,6 +19,13 @@ if SERVER then money = Quantum.Server.Char.getBasicCharInfo( Quantum.Server.Char.GetCurrentCharacter( pl ) ).money }, items = Quantum.Server.Char.GetInventory( Quantum.Server.Char.GetCurrentCharacter( pl ) ) }) + end, + ["charinfo_DYNAMIC"] = function( pl ) + Quantum.Net.OpenMenu( pl, "charinfo", { char = { + model = Quantum.Server.Char.getBasicCharInfo( Quantum.Server.Char.GetCurrentCharacter( pl ) ).model, + name = Quantum.Server.Char.getBasicCharInfo( Quantum.Server.Char.GetCurrentCharacter( pl ) ).name, + money = Quantum.Server.Char.getBasicCharInfo( Quantum.Server.Char.GetCurrentCharacter( pl ) ).money + } }) end } @@ -26,6 +33,7 @@ if SERVER then if( keyfuncs[key] ) then keyfuncs[key]( ply ) end end function GM:ShowHelp( ply ) keyfuncs["mainMenu"]( ply ) end + function GM:ShowSpare1( ply ) keyfuncs["charinfo_DYNAMIC"]( ply ) end function GM:ShowSpare2( ply ) keyfuncs["charinfo"]( ply ) end end \ No newline at end of file diff --git a/gamemode/engine/derma/lib/cl_menu_iteminfo.lua b/gamemode/engine/derma/lib/cl_menu_iteminfo.lua index 2ddc2cf..32c20b9 100644 --- a/gamemode/engine/derma/lib/cl_menu_iteminfo.lua +++ b/gamemode/engine/derma/lib/cl_menu_iteminfo.lua @@ -251,7 +251,6 @@ function iteminfo.giveoptions( p, page ) -- center all of the option panels -- options.w, options.h = resizePanel( options ) for i, optionPanel in pairs( op ) do - print( optionPanel ) optionPanel:SetPos( options.w/2 - optionPanel.w/2, optionPanel.y ) end options.w, options.h = resizePanel( options ) diff --git a/gamemode/engine/derma/menus/menu_charinfo.lua b/gamemode/engine/derma/menus/menu_charinfo.lua index 11f926a..2635aa7 100644 --- a/gamemode/engine/derma/menus/menu_charinfo.lua +++ b/gamemode/engine/derma/menus/menu_charinfo.lua @@ -28,8 +28,16 @@ local function createItemAmountLabel( icon, item ) return icon.amountpanel end -function menu.open( dt ) - local items = dt.cont.items +function menu.open( dt ) + local items = {} + if( dt.cont.items == nil ) then + if( Quantum.Client.Inventory == nil ) then Quantum.Client.Inventory = {} end + items = Quantum.Client.Inventory -- dynamic networking + else + items = dt.cont.items -- static, only sent when menu opens which is rareley in this case + Quantum.Client.Inventory = items + end + -- The dynamic part will be used more often, but sometimes we need the static/old method if( !f ) then Quantum.Client.IsInMenu = true diff --git a/gamemode/engine/lib/server/sv_inventory.lua b/gamemode/engine/lib/server/sv_inventory.lua index 9fd540c..1753910 100644 --- a/gamemode/engine/lib/server/sv_inventory.lua +++ b/gamemode/engine/lib/server/sv_inventory.lua @@ -7,6 +7,8 @@ Quantum.Server.Inventory = {} +Quantum.Inventory.Size = Quantum.Inventory.Width * Quantum.Inventory.Height + function Quantum.Server.Inventory.Create( char ) char.inventory = {} @@ -21,18 +23,26 @@ local function isStackable( item ) return item.stack || false end -function Quantum.Server.Inventory.SetSlotItem( char, pos, itemid, amount ) +function Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, amount ) if( amount < 1 ) then char.inventory[pos] = nil -- remove the item + + -- Sent the new data to the client + Quantum.Net.Inventory.SetItem( pl, pos, itemid, amount ) + return end local item = Quantum.Item.Get( itemid ) if( isEquippable( item ) || !isStackable( item ) ) then amount = 1 char.inventory[pos] = { itemid } + -- Sent the new data to the client + Quantum.Net.Inventory.SetItem( pl, pos, itemid, amount ) else amount = amount || 1 char.inventory[pos] = { itemid, amount } + -- Sent the new data to the client + Quantum.Net.Inventory.SetItem( pl, pos, itemid, amount ) end end @@ -70,7 +80,7 @@ local function getStackSize( char, item ) return item.stack || 1 end -local function sortItem( char, itemid, amount ) +local function sortItem( pl, char, itemid, amount ) local item = Quantum.Item.Get( itemid ) local slotitem = Quantum.Server.Inventory.GetSlotItem( char, index ) @@ -97,14 +107,14 @@ local function sortItem( char, itemid, amount ) rest = rest - amount end local setAmt = math.Clamp( add, 1, stacksize ) - Quantum.Server.Inventory.SetSlotItem( char, index, itemid, setAmt ) + Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, setAmt ) end else local setAmt = math.Clamp( amount, 1, stacksize ) local pos = Quantum.Server.Inventory.FindItemSpot( char ) rest = rest - setAmt - Quantum.Server.Inventory.SetSlotItem( char, pos, itemid, setAmt ) + Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, setAmt ) end while( rest >= stacksize ) do @@ -120,7 +130,7 @@ local function sortItem( char, itemid, amount ) rest = rest - setAmt local pos = Quantum.Server.Inventory.FindItemSpot( char ) - Quantum.Server.Inventory.SetSlotItem( char, pos, itemid, setAmt ) + Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, setAmt ) else index = index + 1 itemInSlot = Quantum.Server.Inventory.GetSlotItem( char, index ) @@ -128,7 +138,7 @@ local function sortItem( char, itemid, amount ) 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 ) + Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, stacksize ) if( rest <= 0 ) then rest = 0 @@ -137,7 +147,7 @@ local function sortItem( char, itemid, amount ) end else rest = rest - stacksize - Quantum.Server.Inventory.SetSlotItem( char, index, itemid, stacksize ) + Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, stacksize ) end end end @@ -146,7 +156,7 @@ local function sortItem( char, itemid, amount ) local pos if( stackIndex == nil ) then pos = Quantum.Server.Inventory.FindItemSpot( char ) - Quantum.Server.Inventory.SetSlotItem( char, pos, itemid, rest ) + Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, rest ) else if( rest > 0 ) then pos = stackIndex @@ -157,7 +167,7 @@ local function sortItem( char, itemid, amount ) rest = rest - diff if( rest <= 0 ) then - Quantum.Server.Inventory.SetSlotItem( char, pos, itemid, setAmt ) + Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, setAmt ) end end end @@ -170,9 +180,9 @@ function Quantum.Server.Inventory.GiveItem( pl, itemid, amount ) -- Quantum.Serv if( item == nil ) then Quantum.Error( "Tried to give " .. tostring(pl) .. " a non-existent item! Item '" .. tostring(itemid) .. "' does not exist." ) return end - if( #inv + 1 <= Quantum.Inventory.Width * Quantum.Inventory.Height || Quantum.Server.Inventory.FindStackable( char, item ) != nil ) then + if( #inv + 1 <= Quantum.Inventory.Size || Quantum.Server.Inventory.FindStackable( char, item ) != nil ) then - sortItem( char, itemid, amount ) + sortItem( pl, char, itemid, amount ) -- Quantum.Debug( "Gave " .. char.name .. " " .. amount .. "x [" .. item.name .. "]" ) -- Send net message to client about item update -- ############################################ @@ -202,7 +212,7 @@ function Quantum.Server.Inventory.DropItem( pl, index, amount ) -- Quantum.Serve if( am_diff >= 0 ) then -- drop the item from the players inv -- remove the items am_diff from its stack - Quantum.Server.Inventory.SetSlotItem( char, index, itemid, am_diff ) + Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, am_diff ) -- spawn the item infront of the player local itemEnt = ents.Create( "q_item" ) diff --git a/gamemode/engine/lib/server/sv_networking.lua b/gamemode/engine/lib/server/sv_networking.lua index 5373bf4..d4dc816 100644 --- a/gamemode/engine/lib/server/sv_networking.lua +++ b/gamemode/engine/lib/server/sv_networking.lua @@ -119,11 +119,16 @@ end) Quantum.Net.Inventory = {} +local function calculateNeededBits( n ) return math.ceil( math.log( n, 2 ) ) end + local function WriteIntcode( intcode ) net.WriteInt( intcode, Quantum.IntCode.BIT_SIZE ) end -function Quantum.Net.Inventory.SendItem( pl, index, itemid, amount ) -- sends a item to the client with amount of it, this is a DYNAMIC networking solution +function Quantum.Net.Inventory.SetItem( pl, index, itemid, amount ) -- sends a item to the client with amount of it, this is a DYNAMIC networking solution net.Start( "quantum_item_action" ) - WriteIntcode( Quantum.IntCode.SEND_ITEM ) - net.WriteInt( index, 8 ) + WriteIntcode( Quantum.IntCode.SET_ITEM ) -- write the opcode first + net.WriteInt( index, calculateNeededBits( Quantum.Inventory.Size ) ) + net.WriteString( itemid ) + net.WriteInt( amount, calculateNeededBits( Quantum.Inventory.MaxStackSize ) ) + net.Send( pl ) end \ No newline at end of file diff --git a/gamemode/shared.lua b/gamemode/shared.lua index 7e504eb..8da42ad 100644 --- a/gamemode/shared.lua +++ b/gamemode/shared.lua @@ -21,7 +21,7 @@ include( "settings/sh_settings.lua" ) Quantum.IntCode = { - SEND_ITEM = 0, + SET_ITEM = 0, DROP_ITEM = 1, USE_ITEM = 2, EAT_ITEM = 3,