First, I will present what my script looks like, with which I have a problem.
This function creates windows with rewards, which I then put in DFrame.
function AddReward(level, PS2)
net.Receive( "send_reward", function( len, ply)
print(level)
end)
[...]
In DFrame, using this function looks like this:
AddReward( 2, "Rayman")
AddReward( 3, "Puro")
AddReward( 4, "Luke Skywalker")
AddReward( 5, "Rayman")
AddReward( 6, "Rayman")
AddReward( 7, "Rayman")
AddReward( 8, "iron Man")
AddReward( 9, "Duke")
I would like to use Hook.Add TTTEndRound so that at the end of each round I have a "level" variable from each window in the print console, but here the problem gets complicated - if I give print(level) anywhere in the AddReward code, then I get print on opening DFrame level from 1 to 9, but when print(level) is called by net.Receive, then in the console I only have print of the level value of the last added window, i.e. 9.
Does anyone know how I can fix it?
I may not be correct but i dont think that gmod allows you to send that many identical net requests at the same time.(So every request exept the last one gets dismissed)
I suggest you send one reward first them when the window is closed request next reward via net and so on and so on until there are no rewards left.
put net.Receive outside of this function.
Your way of solving this problem is abit weird, you should only call net.Recieve once per message name. How does serverside part of this look? (The code that sends the send_reward message)
It turned out that it was not the fault of the net library, but the use of Hook.Add.
I changed the script like this:
hook.Add( "TTTEndRound", "lvlup_roundend", function()
net.Start( "give_reward" )
net.WriteString( level )
net.SendToServer()
end)
And in serverside:
net.Receive( "give_reward", function( _, ply )
local level = net.ReadString()
print(level)
end )
And the effect is the same, in print you still can only see the level of the last window.
But if I add net.Start outisde hook.Add, then it works perfect, bot net is sending informations only on open window, still need help :/
Your conclusions are incorrect. This is how the net library works (you're using it differently):
In a client-side file you register that an incoming message may occur with net.Receive. Client-side means that these files are only interpreter on the computers of your players (as opposed to your server)
In a server-side you register the name of that message with util.AddNetworkString
Whenever you want to send the message, you start it and give it's name with net.Start
Then you fill it with the net.Write* functions
Then you send it with either net.Send or net.Broadcast
It makes no sense, ever, to run net.Receive multiple times. So for net.Receive to be in a hook, function or other place it's called multiple times is weird.
Your other problems are likely caused by logic errors. From looking at your last message I can already see you are making level global or not local enough to be tied to an event. Right now you're saying something like this in code:
"level = 10" (He everyone, this word 'level' is a variable! If I use it again I mean 10!)
And then later doing:
"net.WriteString( level )" (Hey put the value behind this word 'level' in the net message I'm about to send)
level will be, what you have last set it to be. If you have code like this run at any time before the line with net.WriteString(level), the value will be 10:
for i=1,10 do level = i end
When I say 'before' something, I mean at any time before that something. Think hard about your lines of code and when they are going to be executed for the player (if you're on the client) or all players (if you're on the server).
But as I wrote in my previous post, the net library is not a problem here, I'll give you an example of what I mean:
local function AddReward(level, PS2)
print(level) -- this is activated when I open whole window where this function is used, it prints levels for all windows created with AddReward function (in thix example - from 1 to 9)
hook.Add( "TTTEndRound", "_leveltest1", function() -- this is activated on TTT end round, it prints the level of only the last window created with AddReward function
print(level)
end)
[...]
Also as i said earlier gmod cant run multiple identical net requests so you either need to make them delayed or do as i described previously.
Still don't know how to make it working :/
Maybe now someone can help?
This is the main script:
function AddReward(level, PS2)
local data = Pointshop2.GetItemClassByPrintName( PS2 )
local xperienceTable = {getXpNeeded(1, LocalPlayer():GetNWInt("xp"))}
PlyLevel = xperienceTable[1]
local DOutlinedBox = vgui.Create( "DPanel" )
DOutlinedBox:SetSize(118, 118)
DOutlinedBox:SetPos( 120 * level - 120*2, -2)
DOutlinedBox.Paint = function( self, w, h )
draw.OutlinedBox( 0, 0, w, h, 2, Color( 0, 0, 0 ) )
end
if PS2 then
local DImageButton = vgui.Create( data:GetConfiguredIconControl(), DOutlinedBox )
DImageButton:SetItemClass( data )
DImageButton:SetSize(DOutlinedBox:GetSize() - 4, DOutlinedBox:GetSize() - 4)
DImageButton:SetPos(2, 2)
DImageButton:SetCursor("hand")
DImageButton:SetMouseInputEnabled( false )
DImageButton:SetDragParent(self)
end
local LevelPanel = vgui.Create( "DPanel" )
LevelPanel:SetSize(118, 20)
LevelPanel:SetPos( 120 * level - 120*2, 234)
LevelPanel.Paint = function( self, w, h )
draw.RoundedBox( 3, 0, 0, w, h, Color( 100, 100, 100, 255 ) )
draw.RoundedBox( 3, 0, 0, w, h, Color( 0, 160, 255, 255 ) )
draw.OutlinedBox( 0, 0, w, h, 2, Color( 0, 0, 0 ) )
end
local width, height = surface.GetTextSize( "Level: "..level )
local LevelLabel = vgui.Create( "DLabel", LevelPanel )
LevelLabel:SetPos( ( LevelPanel:GetWide() - width )/2 - 6, 2 )
LevelLabel:SetFont( "WindowLabel" )
LevelLabel:SetTextColor( Color(255, 255, 255) )
LevelLabel:SetText( "Level: "..level )
Rewards:AddPanel( DOutlinedBox )
Rewards:AddPanel( LevelPanel )
-- THERE IS THE MAIN PROBLEM BELOW
hook.Add( "TTTEndRound", "_leveltest1", function() -- this is activated on TTT end round, it prints the level of only the last window created with AddReward function
print(level)
end)
print(level) -- this is activated when I open whole window where this function is used, it prints levels for all windows created with AddReward function (in thix example - from 1 to 3)
end
local function OpenMenu()
SPFrame = vgui.Create( "DFrame" )
SPFrame:SetSize( 900, 500 )
SPFrame:Center()
SPFrame:SetTitle("")
SPFrame:MakePopup()
SPFrame:SetVisible(true)
SPFrame:ShowCloseButton(false)
SPFrame:SetDeleteOnClose(true)
SPFrame.Paint = function( s, w, h )
draw.RoundedBox( 5, 0, 0, w, h, Color( 66, 66, 66, 255 ) )
draw.RoundedBoxEx(5, 0, 0, w, 30, Color(125, 25, 200), true, true, false, false) -- Upper Bar
surface.SetMaterial( Material("flat_ttt_materials/burger_menu.png", "noclamp smooth" ) )
surface.SetDrawColor( Color(255, 255, 255) )
surface.DrawTexturedRect(7, 6, 18, 18)
end
local CloseBut = vgui.Create("DButton", SPFrame)
CloseBut:SetText( "" )
CloseBut:SetPos( SPFrame:GetWide()-30, 0 )
CloseBut:SetSize( 30, 30 )
CloseBut.DoClick = function()
SPFrame:SetVisible(false)
end
CloseBut.Paint = function( s, w, h )
surface.SetMaterial( Material("flat_ttt_materials/close.png", "noclamp smooth" ) )
surface.SetDrawColor( Color(255, 255, 255) )
surface.DrawTexturedRect(7, 8, 14, 14)
end
local MainPanel = vgui.Create( "DPanel", SPFrame )
MainPanel:SetPos( 15, 45 )
MainPanel:SetSize( SPFrame:GetWide() - 30, SPFrame:GetTall() - 60 )
MainPanel.Paint = function( self, w, h )
draw.RoundedBox( 6, 0, 0, w, h, Color( 55, 55, 55, 255 ) )
draw.OutlinedBox( 0, 0, w, h, 2, Color( 0, 0, 0 ) )
end
local Background = vgui.Create("DPanel", MainPanel)
Background:SetSize( Background:GetParent():GetWide() - 28, 120 * 2 + 16 )
Background:SetPos(14, 122)
Background.Paint = function( self, w, h )
draw.RoundedBox( 6, 0, 0, w, h, Color( 35, 35, 35, 255 ) )
draw.OutlinedBox( 0, 0, w, h, 2, Color( 0, 0, 0 ) )
end
for i = 0, 1 do
local TicketWindows = vgui.Create( "DPanel", Background )
TicketWindows:SetSize(118, 118)
TicketWindows:SetPos(0, 0 + i*120)
TicketWindows.Paint = function( self, w, h )
draw.OutlinedBox( 0, 0, w, h, 2, Color( 0, 0, 0 ) )
if i == 0 then
surface.SetMaterial( Material("horizon_sp/pass_free.png", "noclamp smooth" ) )
else
surface.SetMaterial( Material("horizon_sp/pass_vip.png", "noclamp smooth" ) )
end
surface.SetDrawColor( Color(255, 255, 255) )
surface.DrawTexturedRect(6, 6, 104, 104)
end
end
local TicketTextWindow = vgui.Create( "DPanel", Background )
TicketTextWindow:SetSize(118, 20)
TicketTextWindow:SetPos(0, 118*2)
TicketTextWindow.Paint = function( self, w, h )
draw.RoundedBox( 3, 0, 0, w, h, Color( 100, 100, 100, 255 ) )
draw.OutlinedBox( 0, 0, w, h, 2, Color( 0, 0, 0 ) )
end
local width, height = surface.GetTextSize( "Karnet" )
local TicketText = vgui.Create( "DLabel", TicketTextWindow )
TicketText:SetPos( ( TicketTextWindow:GetWide() - width)/2 - 6, 2 )
TicketText:SetFont( "WindowLabel" )
TicketText:SetTextColor( Color(255, 255, 255) )
TicketText:SetText( "Karnet" )
Rewards = vgui.Create( "NewHorizontalScroller", Background )
Rewards:SetSize( Background:GetWide() - 122, 118 * 2 + 16 )
Rewards:SetPos( 120, 2 )
AddReward( 2, "Rayman", false)
AddReward( 3, "Puro", false)
AddReward( 4, "Luke Skywalker", false) -- hook is calling only in this last function
end
net.Receive is a hook based function, it cannot be in another function so it cannot be called again to overwrite hooks.
You need to make different hook ids for it to work. Just make this string like "reward_".. name.. level and this should work nicely.
https://files.facepunch.com/forum/upload/469093/192d51ad-2113-4763-a025-4861567bdad2/image.png
That's exactly what I needed, and I'm surprised I did not get it myself, but thank you for your help!
Don't forget to remove hooks if you don't need them anymore ;)
Sorry, you need to Log In to post a reply to this thread.