• Calling functions dynamically
    13 replies, posted
What I'm trying to do is make a function to add a chat command, etc, code I've come up with is: [lua] function AddChatCmd( text, func ) local function Chat( ply, txt ) if string.lower( txt ) == text then func end end hook.Add( "PlayerSay", Chat ) end [/lua] Should I be calling the local function with a hook inside the function? And can you call a function contained in a variable by just typing the var name?
The problem is that you can't make a function with the chatbox (unless you runstring some text from it.
[QUOTE=yakahughes;21416417]The problem is that you can't make a function with the chatbox (unless you runstring some text from it.[/QUOTE] Then how do you do it, and what is this runstring you speak of?
[lua]local commands = {} function CreateChatFunction(Pl, Txt) local exploded = string.Explode(" ", Txt) local command, funcname = exploded[1], exploded[2] if commands[funcname] then commands[cmd]() return Txt end if command == "createfunc" then table.remove(exploded, 1) table.remove(exploded, 1) local func = table.concat(exploded, " ") commands[funcname] = function() RunString(func) end return "" end end hook.Add("PlayerSay", "ChatFunctions", CreateChatFunction)[/lua] I have no idea if this will work.
[lua]local chatcommands = {}; function AddChatCommand(name, func) chatcommands[name] = func; end hook.Add("PlayerSay", "ChatCommand", function(ply, text) local cmd, args = text:match("/(.+)%s(.+)"); -- Unnecessary, could just use string.Explode here. if cmd then for name, func in pairs(chatcommands) do if name:lower() == cmd:lower() then func(ply, cmd, string.Explode(" ", args); break; end end return ""; end end); AddChatCommand("kick", function(ply, cmd, args) -- Example usage. (use like concommand.Add) if ply:IsAdmin() and args[1] then for _, p in ipairs(player.GetAll()) do if p:Nick():find(args[1]) then p:Kick(); return ; end end end end);[/lua] Something like this would be better. Note that the string pattern match is unnecessary, you could just do the string.Explode there and use the first argument for the cmd and the rest for the arguments.
[QUOTE=MakeR;21421926][lua]Code I don't understand[/lua] Something like this would be better. Note that the string pattern match is unnecessary, you could just do the string.Explode there and use the first argument for the cmd and the rest for the arguments.[/QUOTE] I really don't understand what you're doing there. [lua] local chatcommands = {}; function AddChatCommand(name, func) chatcommands[name] = func; end [/lua] Why are you making that table? Is chatcommands[name] = func adding an entry to the table? Why not use table.insert? [lua] # hook.Add("PlayerSay", "ChatCommand", function(ply, text) # local cmd, args = text:match("/(.+)%s(.+)"); -- Where are you getting args from? # if cmd then -- What is cmd? What is if cmd supposed to do? # for name, func in pairs(chatcommands) do -- What are you doing with func? It's an argument in a different function, so how are you calling it here? # if name:lower() == cmd:lower() then -- What is name? Where is that defined? # func(ply, cmd, string.Explode(" ", args); -- Again, what is func doing here. # break; # end # end # return ""; # end # end); [/lua] Really hate to come across as stupid or anything, but this doesn't make sense to me and I want to be able to come up with this sort of thing on my own. What my original question was is how you can pass a function as an argument in another function and call it in there, and your post just confused me even more.
[lua]function callfunc(f) f() end function sayhi() print("hi!") end callfunc(sayhi)[/lua] [editline]05:07PM[/editline] Didn't mean to confuse you :eng99: [editline]05:10PM[/editline] I really suggest you read the Lua reference manual, it can be found [url=http://www.lua.org/manual/5.1/]here[/url]. Some of those questions in your comments will become much clearer once you have a better understanding of the syntax of Lua. [editline]05:13PM[/editline] You just need to add parenthesis after func in your first post for it to work, but it is not really a good way to go about this. [lua]function AddChatCmd( text, func ) local function Chat( ply, txt ) if string.lower( txt ) == text then func() end end hook.Add( "PlayerSay", Chat ) end [/lua]
[QUOTE=MakeR;21426994] Stuff [/QUOTE] Thank you, that's a lot clearer.
As to your earlier question [quote=Mossman123]Why are you making that table? Is chatcommands[name] = func adding an entry to the table? Why not use table.insert?[/quote] Yes, doing chatcommands[name] = func sets the key [name] of the chatcommands table to whatever the func variable is. The structure of the table would then look like (if name were "asdf" and func was a function): chatcommands: [lua] asdf = function(address in memory)[/lua] But table.insert takes a parameter and inserts it at the lowest available numeric key in the table. If you did table.insert(chatcommands, func) then the table would look like: chatcommands: [lua] 1 = function(address in memory)[/lua] As you can see, the string "asdf" as the key is much more helpful in this case for telling which function this is than the key 1, because you can take the first word in the chat string and see if it is "asdf", and then call chatcommands["asdf"] (or put the first word in a variable and call chatcommands[variablename], which is the way you would actually do it).
[lua]-- Different ways of using functions -- You don't have to use the "function f() dosomething end" format, since functions are like regular variables local f = function() print("Hi!") end -- This function f2() f() end -- And this f2 = f -- Produce the same output when run local t = {} t["f3"] = f -- Both of these calls are valid: t.f3() t["f3"]() -- Remember, functions are just like any other variable in lua -- you just need to remember to put a parentheses after the variable name -- If it doesn't make sense, imagine a function as just a special kind of string that you run after using ()[/lua] Hope that helps.
[QUOTE=Entoros;21428737][lua] -- This function f2() f() end -- Is the same as f2 = f [/lua][/QUOTE] [lua]function f() print("Hi!") end function f2() f() end print(f==f2)[/lua] Output: [code]false[/code] No it isn't, but I know what you mean. Calling f2 will yield the same results as calling f.
Sorry, I should have been more clear. Just talking about output here.
[lua] function Test( ply, text ) ply:Kill() ply:ConCommand( "say"..text ) end AddChatCmd( Test, "/Test" ) function AddChatCmd( ply, text, func, cmd ) local expl = string.Explode( " ", text ) if string.lower( expl[1] ) == text then if string.lower( expl[2] ) then func( ply, expl[2] ) else func( ply ) end end end hook.Add( "PlayerSay", AddChatCmd ) AddChatCmd( Test, "/test" ) [/lua] I tried this and it doesn't seem to work. Can someone explain what I'm doing wrong here? I'm also not really sure how to pass the ply arguments for the function being passed inside the AddChatCmd function.
[lua]local commands = {} function CreateChatFunction(Pl, Txt) local exploded = string.Explode(" ", Txt) local command, funcname = exploded[1], exploded[2] if commands[command] then commands[command]() return Txt end if command == "createfunc" then table.remove(exploded, 1) table.remove(exploded, 1) local func = table.concat(exploded, " ") commands[funcname] = function() RunString(func) end end end hook.Add("PlayerSay", "ChatFunctions", CreateChatFunction) [/lua] Tested working: [code] yakahughes: createfunc asdf print'lol' yakahughes: asdf lol[/code]
Sorry, you need to Log In to post a reply to this thread.