So I feel silly posting on here for such a simple problem, but here it is anyways.
I have a local table "local XPSYS = { }" and I'm trying to add a function to that table.
Basically, i'm hooking onto GM:PlayerInitialSpawn, however something is going wrong...
I am getting an error, "attempt to index local 'ply' <a nil value>" at the given function
My assumption is that the hook is getting called but the arguments are not being passed(?)
I'm not sure. That's why I came here. Here is the code relevant to the error
[CODE]
local XPSYS = { }
function XPSYS:InitializePlayerInfo( ply )
local steamID = ply:SteamID()
if( sql.Query( "SELECT * FROM experience WHERE SteamID = '"..steamID.."'" ) == nil ) then
sql.Query("INSERT INTO experience ( SteamID, XP, Level ) \
VALUES ( '"..steamID.."', 0, 1)" )
end
UpdateClient(ply,tonumber(sql.QueryValue("SELECT XP FROM experience WHERE SteamID = '"..steamID.."'")),
tonumber(sql.QueryValue("SELECT Level FROM experience WHERE SteamID = '"..steamID.."'")))
end
hook.Add( "PlayerInitialSpawn", XPSYS, XPSYS.InitializePlayerInfo )
[/CODE]
replace . with : in he hook.add line of the XPSYS function, also in hook.add XPSYS(2nd argument) has to be a string.
You have a : instead of a . between XPSYS and the function name..
[QUOTE=whitestar;49652784]replace . with : in he hook.add line of the XPSYS function, also in hook.add XPSYS(2nd argument) has to be a string.[/QUOTE]
Hmm you seem to be correct. I thought I tried that but guess not.
Now my question is, how come the way i did it does not work?
By my logic, I am defining the function InitializePlayerInfo in the table XPSYS.
And now I want to call it with the arguments of PlayerInitialSpawn through the hook and also
with the self argument (since that is what the : allows for right?). Is there any specific reason that
this doesn't work? Since this doesn't work, can I never pass the self argument through the hook?
Thanks for clearing up any confusion!
[B]EDIT:[/B]Derp i'm sorry, I replied to the wrong person, what you suggested doesn't work.
[editline]1st February 2016[/editline]
[QUOTE=boxvader;49652788]You have a : instead of a . between XPSYS and the function name..[/QUOTE]
Hmm you seem to be correct. I thought I tried that but guess not.
Now my question is, how come the way i did it does not work?
By my logic, I am defining the function InitializePlayerInfo in the table XPSYS.
And now I want to call it with the arguments of PlayerInitialSpawn through the hook and also
with the self argument (since that is what the : allows for right?). Is there any specific reason that
this doesn't work? Since this doesn't work, can I never pass the self argument through the hook?
Thanks for clearing up any confusion!
You simply could make a 2nd (local) function, which is not in the table, like blahfunc(ply) and then use that in the hook which calls blah:blah(ply).
[QUOTE=whitestar;49653121]You simply could make a 2nd (local) function, which is not in the table, like blahfunc(ply) and then use that in the hook which calls blah:blah(ply).[/QUOTE]
I feel like that would defeat the purpose though :D
Is there anyway that I can call a function with the self argument from a hook?
Or does this some how defeat the purpose of a hook? It's fine if you don't know, I'm just trying to
clarify my knowledge :P
normally changing . to : should've fixed it already, huh
[QUOTE=whitestar;49653216]normally changing . to : should've fixed it already, huh[/QUOTE]
No : is used to run a function. In this case he is acceseing a function that is stored inaide a table. That's what . Is for.
See here: [url]http://www.lua.org/pil/6.2.html[/url]
If the function must be a method and you want to call it in a hook, try:
[code]
hook.Add( "PlayerInitialSpawn", "XPSYSPlayerInfoInit", function(pl) XPSYS:InitializePlayerInfo(pl) end)
[/code]
[QUOTE=boxvader;49653908]No : is used to run a function. In this case he is acceseing a function that is stored inaide a table. That's what . Is for.
See here: [url]http://www.lua.org/pil/6.2.html[/url][/QUOTE]
: passes self as the first parameter, that's it. : doesn't run a function () does. You can still do a.b() and that will run a.b just fine. a:b() does the same as a.b(a)
Technically this should work, [url=https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/includes/modules/hook.lua#L92]if the name of the hook isn't a string then it should be passed in as the first argument[/url] (as this is done with panels and entities) but IsValid will return false on your table.
If you want to still use the same programming style, you can keep your original code and do this:
[lua]
local XPSYS = { }
function XPSYS:InitializePlayerInfo( ply )
local steamID = ply:SteamID()
if( sql.Query( "SELECT * FROM experience WHERE SteamID = '"..steamID.."'" ) == nil ) then
sql.Query("INSERT INTO experience ( SteamID, XP, Level ) \
VALUES ( '"..steamID.."', 0, 1)" )
end
UpdateClient(ply,tonumber(sql.QueryValue("SELECT XP FROM experience WHERE SteamID = '"..steamID.."'")),
tonumber(sql.QueryValue("SELECT Level FROM experience WHERE SteamID = '"..steamID.."'")))
end
function XPSYS:IsValid()
return true
end
hook.Add( "PlayerInitialSpawn", XPSYS, XPSYS.InitializePlayerInfo )
[/lua]
Sorry, you need to Log In to post a reply to this thread.