• Usermessages
    18 replies, posted
Well, I'm making a simple CarMod for RP'ing, and I need help with sending some data to client's. I've never been learning how to use every single possibility of usermessages, but I only know how to run it and hook it. CL_INIT.LUA [lua] function PurchaseCars() local CarFrame = vgui.Create( "DFrame" ) CarFrame:SetPos( ScrW( ) / 2 - 250, ScrH( ) / 2 - 200 ) CarFrame:SetSize( 500, 400 ) CarFrame:SetTitle( "Old Bill's car shop" ) CarFrame:SetVisible( true ) CarFrame:SetDraggable( false ) CarFrame:MakePopup( ) local CarTabs = vgui.Create( "DPropertySheet" ) CarTabs:SetParent( CarFrame ) CarTabs:SetPos( 10, 30 ) CarTabs:SetSize( 480, 360 ) local CarList = vgui.Create("DPanelList") CarList:SetSize(475, 355) CarList:SetPos(5, 15) CarList:SetSpacing(5) CarList:EnableHorizontal(false) CarList:EnableVerticalScrollbar(true) local CarList1 = vgui.Create("DPanelList") CarList1:SetSize(475, 355) CarList1:SetPos(5, 15) CarList1:SetSpacing(5) CarList1:EnableHorizontal(false) CarList1:EnableVerticalScrollbar(true) local CarList2 = vgui.Create("DPanelList") CarList2:SetSize(475, 355) CarList2:SetPos(5, 15) CarList2:SetSpacing(5) CarList2:EnableHorizontal(false) CarList2:EnableVerticalScrollbar(true) --[[ THIS IS THE JEEP WHICH IS STARTING RIGHT NOW --]] if file.Exists("carmod/"..LocalPlayer():UniqueID().."/jeep.txt") then -- I got to get the client to read this from the server and not from himself local CarPanel2 = vgui.Create( "DPanel" ) CarPanel2:SetSize( 470, 67 ) CarPanel2:SetPos( 67, 202 ) local CarButton2 = vgui.Create( "DButton" ) CarButton2:SetParent( CarPanel2 ) CarButton2:SetSize( 400, 15 ) CarButton2:SetPos( 67, 52 ) CarButton2:SetText( "Sell your jeep - Are you sure?" ) CarButton2.DoClick = function ( btn ) local CarButton2 = DermaMenu() CarButton2:AddOption("Yes.", function() RunConsoleCommand("sell_jeep") CarFrame:Close() end ) CarButton2:AddOption("No.", function() end ) CarButton2:Open() end local CarIcon2 = vgui.Create( "SpawnIcon" ) CarIcon2:SetParent( CarPanel2 ) CarIcon2:SetPos( 2, 2 ) CarIcon2:SetModel( "models/buggy.mdl" ) CarIcon2:SetToolTip( nil ) CarIcon2.OnCursorEntered = function() end CarIcon2.OnMousePressed = function() end local CarInfo2 = vgui.Create( "DLabel" ) CarInfo2:SetText( "$5000" ) CarInfo2:SetParent( CarPanel2 ) CarInfo2:SetPos( 250, 20 ) CarList1:AddItem( CarPanel2 ) end if !file.Exists("carmod/"..LocalPlayer():UniqueID().."/jeep.txt") then-- I got to get the client to read this from the server and not from himself local CarPanel1 = vgui.Create( "DPanel" ) CarPanel1:SetSize( 470, 67 ) CarPanel1:SetPos( 67, 202 ) local CarButton1 = vgui.Create( "DButton" ) CarButton1:SetParent( CarPanel1 ) CarButton1:SetSize( 400, 15 ) CarButton1:SetPos( 67, 52 ) CarButton1:SetText( "Buy a jeep - Are you sure?" ) CarButton1.DoClick = function ( btn ) local CarButton1 = DermaMenu() CarButton1:AddOption("Yes.", function() RunConsoleCommand("buy_jeep") CarFrame:Close() end ) CarButton1:AddOption("No.", function() end ) CarButton1:Open() end local CarIcon1 = vgui.Create( "SpawnIcon" ) CarIcon1:SetParent( CarPanel1 ) CarIcon1:SetPos( 2, 2 ) CarIcon1:SetModel( "models/buggy.mdl" ) CarIcon1:SetToolTip( nil ) CarIcon1.OnCursorEntered = function() end CarIcon1.OnMousePressed = function() end local CarInfo1 = vgui.Create( "DLabel" ) CarInfo1:SetText( "$10000" ) CarInfo1:SetParent( CarPanel1 ) CarInfo1:SetPos( 250, 20 ) CarList:AddItem( CarPanel1 ) end if file.Exists("carmod/"..LocalPlayer():UniqueID().."/jeep.txt") then -- I got to get the client to read this from the server and not from himself local CarPanel3 = vgui.Create( "DPanel" ) CarPanel3:SetSize( 470, 67 ) CarPanel3:SetPos( 67, 202 ) local CarButton3 = vgui.Create( "DButton" ) CarButton3:SetParent( CarPanel3 ) CarButton3:SetSize( 400, 15 ) CarButton3:SetPos( 67, 52 ) CarButton3:SetText( "Take out or store jeep - Are you sure?" ) CarButton3.DoClick = function ( btn ) local CarButton3 = DermaMenu() CarButton3:AddOption("Take out.", function() RunConsoleCommand("takeout_jeep") CarFrame:Close() end ) CarButton3:AddOption("Store.", function() RunConsoleCommand("store_jeep") CarFrame:Close() end ) CarButton3:Open() end local CarIcon3 = vgui.Create( "SpawnIcon" ) CarIcon3:SetParent( CarPanel3 ) CarIcon3:SetPos( 2, 2 ) CarIcon3:SetModel( "models/buggy.mdl" ) CarIcon3:SetToolTip( nil ) CarIcon3.OnCursorEntered = function() end CarIcon3.OnMousePressed = function() end local CarInfo3 = vgui.Create( "DLabel" ) CarInfo3:SetText( "Jeep" ) CarInfo3:SetParent( CarPanel3 ) CarInfo3:SizeToContents() CarInfo3:SetPos( 240, 23 ) CarList2:AddItem( CarPanel3 ) end --[[ THIS IS THE JEEP WHICH IS ENDING RIGHT NOW --]] --[[ THIS IS THE AIRBOAT WHICH IS STARTING RIGHT NOW --]] if file.Exists("carmod/"..LocalPlayer():UniqueID().."/airboat.txt") then -- I got to get the client to read this from the server and not from himself local CarPanel4 = vgui.Create( "DPanel" ) CarPanel4:SetSize( 470, 67 ) CarPanel4:SetPos( 67, 202 ) local CarButton4 = vgui.Create( "DButton" ) CarButton4:SetParent( CarPanel4 ) CarButton4:SetSize( 400, 15 ) CarButton4:SetPos( 67, 52 ) CarButton4:SetText( "Sell your airboat - Are you sure?" ) CarButton4.DoClick = function ( btn ) local CarButton4 = DermaMenu() CarButton4:AddOption("Yes.", function() RunConsoleCommand("sell_airboat") CarFrame:Close() end ) CarButton4:AddOption("No.", function() end ) CarButton4:Open() end local CarIcon4 = vgui.Create( "SpawnIcon" ) CarIcon4:SetParent( CarPanel4 ) CarIcon4:SetPos( 2, 2 ) CarIcon4:SetModel( "models/airboat.mdl" ) CarIcon4:SetToolTip( nil ) CarIcon4.OnCursorEntered = function() end CarIcon4.OnMousePressed = function() end local CarInfo4 = vgui.Create( "DLabel" ) CarInfo4:SetText( "$15000" ) CarInfo4:SetParent( CarPanel4 ) CarInfo4:SetPos( 250, 20 ) CarList1:AddItem( CarPanel4 ) end if !file.Exists("carmod/"..LocalPlayer():UniqueID().."/airboat.txt") then -- I got to get the client to read this from the server and not from himself local CarPanel5 = vgui.Create( "DPanel" ) CarPanel5:SetSize( 470, 67 ) CarPanel5:SetPos( 67, 202 ) local CarButton5 = vgui.Create( "DButton" ) CarButton5:SetParent( CarPanel5 ) CarButton5:SetSize( 400, 15 ) CarButton5:SetPos( 67, 52 ) CarButton5:SetText( "Buy a airboat - Are you sure?" ) CarButton5.DoClick = function ( btn ) local CarButton5 = DermaMenu() CarButton5:AddOption("Yes.", function() RunConsoleCommand("buy_airboat") CarFrame:Close() end ) CarButton5:AddOption("No.", function() end ) CarButton5:Open() end local CarIcon5 = vgui.Create( "SpawnIcon" ) CarIcon5:SetParent( CarPanel5 ) CarIcon5:SetPos( 2, 2 ) CarIcon5:SetModel( "models/airboat.mdl" ) CarIcon5:SetToolTip( nil ) CarIcon5.OnCursorEntered = function() end CarIcon5.OnMousePressed = function() end local CarInfo5 = vgui.Create( "DLabel" ) CarInfo5:SetText( "$20000" ) CarInfo5:SetParent( CarPanel5 ) CarInfo5:SetPos( 250, 20 ) CarList:AddItem( CarPanel5 ) end if file.Exists("carmod/"..LocalPlayer():UniqueID().."/airboat.txt") then -- I got to get the client to read this from the server and not from himself local CarPanel6 = vgui.Create( "DPanel" ) CarPanel6:SetSize( 470, 67 ) CarPanel6:SetPos( 67, 202 ) local CarButton6 = vgui.Create( "DButton" ) CarButton6:SetParent( CarPanel6 ) CarButton6:SetSize( 400, 15 ) CarButton6:SetPos( 67, 52 ) CarButton6:SetText( "Take out or store airboat - Are you sure?" ) CarButton6.DoClick = function ( btn ) local CarButton6 = DermaMenu() CarButton6:AddOption("Take out.", function() RunConsoleCommand("takeout_airboat") CarFrame:Close() end ) CarButton6:AddOption("Store car.", function() RunConsoleCommand("store_airboat") CarFrame:Close() end ) CarButton6:Open() end local CarIcon6 = vgui.Create( "SpawnIcon" ) CarIcon6:SetParent( CarPanel6 ) CarIcon6:SetPos( 2, 2 ) CarIcon6:SetModel( "mode
You could make the player run a console command to check if it exists in their name: [B]Serverside[/B] [lua]concommand.Add("doiownacar", function(ply, cmd, args) if file.Exists("carmod/"..ply:UniqueID().."/jeep.txt") then umsg.Start("Carowner", ply ) umsg.Bool( true ) umsg.End() end) [/lua] [B]Clientside[/B] [lua]usermessage.Hook("Carowner", function (data) Haveacar = data:ReadBool() end) [/lua] [B]Then just do something like:[/B] [lua]if Haveacar then --I own a car else --I dont have a car [/lua]
Yeah I understand what you mean, but maybe someone else has a better way. I will take your way if not anyone else answers. [editline]24th April 2011[/editline] Well I don't care if it's using datastream or usermessages, just what you guys feel is better or easier for you guys to help me with.
[lua] -- File must be ran by both server and client! if SERVER then local tab = {"Yay","I","Got","The","Table"} -- You cant have this over 128 characters unless using Overv's umsg function SendMeThatTable(ply,cmd,args) umsg.Start("SendMeTheTable",ply) -- First argument is the name and second is who to send it to umsg.Float(#tab) -- Send the number of indexes in the table for k,v in pairs(tab) do -- Loop through the table umsg.String(v) -- Send the client the table value end umsg.End() -- You must end the usermessage end concommand.Add("GiveMeThatTable",SendMeThatTable) elseif CLIENT then print("loaded client") local tab = {} function GetMeThatTable(um) -- The first argument [um] is provided by the hook print("float - "..um:ReadFloat()) for i=1,um:ReadFloat() do -- Recompile the table.. tab[#tab+1]=um:ReadString() -- Add the values end end usermessage.Hook("SendMeTheTable",GetMeThatTable) -- Umsg hook, first arg should be the name of the usermessage sent function PrintThatTable() PrintTable(tab) end concommand.Add("PrintThatTable",PrintThatTable) RunConsoleCommand("GiveMeThatTable") end [/lua] There is an example, untested.
God this is confusing. [editline]24th April 2011[/editline] But I will try to read it over and over again.
Okay, Zack helped me but I still got 1 problem. Whenever I buy a car it doesn't move the car to the sell cars and Garage tab. So here is the new part of the code. INIT.LUA [lua] function DoesPlayerHaveCar(ply,cmd,args) if not args[1] then return end if file.Exists("carmod/"..ply:UniqueID().."/"..args[1]..".txt") then umsg.Start("DoesPlayerHaveCar",ply) umsg.Float(1) umsg.End() end end concommand.Add("DoesPlayerHaveCar",DoesPlayerHaveCar) [/lua] CL_INIT.LUA [lua] local function HasCar(car) RunConsoleCommand("DoesPlayerHaveCar",car) usermessage.Hook("DoesPlayerHaveCar",function(um) if um:ReadFloat() == 1 then return true else return false end end) end [/lua] So.. Whenever I want to check if the person has a car, I'll do this: [lua] if HasCar("jeep") then -- rest of the button, panel, icon etc. here end [/lua]
I think you should just send over a table of there cars when you open the menu, then check if they have it. Zack has a function for sending tables string by string that he practically read my mind on. Or you can do it the easy way and use datastream.
I never used Datastream and I already tried using it, but I couldn't figure it out. [editline]24th April 2011[/editline] And do you know what's wrong there?
[QUOTE=cis.joshb;29392412]I think you should just send over a table of there cars when you open the menu, then check if they have it. Zack has a function for sending tables string by string that he practically read my mind on. Or you can do it the easy way and use datastream.[/QUOTE] Datastream is like doing what I do except adding 500 unneeded usermessages.
Yeah, Zack isn't the only one telling me that I should use usermessages instead of Datastream so I wish I could figure this out before, but I've been trying to see what's wrong but I can't seem to find it.
Usermessages are more efficient, to be sure. Datastream is easier, though. So go with usermessages if you are willing to put the extra time is, and have a faster running gamemode. I think the way you are accessing information through concommands is kind of hacky. (copy pasted from Zack) [lua] local tab = {"Yay","I","Got","The","Table"} -- You cant have this over 128 characters unless using Overv's umsg function SendMeThatTable(ply,cmd,args) umsg.Start("SendMeTheTable",ply) -- First argument is the name and second is who to send it to umsg.Float(#tab) -- Send the number of indexes in the table for k,v in pairs(tab) do -- Loop through the table umsg.String(v) -- Send the client the table value end umsg.End() -- You must end the usermessage end concommand.Add("GiveMeThatTable",SendMeThatTable) [/lua] Use that to send a table, with your own adjustments of course. The table should have their owned cars. Then check if they have the specific cars, and make the derma stuff if they do. You could also use a for loop for each string given to you and create a derma thingy that uses what "i" is to calculate where it should be, but the other way would be easier.
You should give cars and ID and have a table of cars on the client and server so you can access what type of car it is via the ID then you only need to network a number and not a string its much more efficient and you are then very unlikely over going over the size limit
I know, but I want what I already got working first of all.
Just ask if you don't understand what my problem was.
why don't people localize functions that are only used in their scripts?
Is it needed?
[QUOTE=Persious;29409159]Just ask if you don't understand what my problem was.[/QUOTE] What's the problem
Why are you asking if they have a car when you'd be better off having a table of what cars they own and just sending the table to the player by usermessage and then the client can go through the table with the list of cars they own and then let them spawn it? [lua]local cars = { "jeep", "bmw", "corvette" } -- example for k, v in pairs( cars ) do -- add to the list and do what not end[/lua] EDIT: I would also suggest you using SQL for this, it helps keep storage?? clean and easier to access information instead of having to have hundreds of files and folders.
I got a friend helping me. Everything's fixed. Thanks tho.
Sorry, you need to Log In to post a reply to this thread.