Hi!
I am coding a few things(Kind of an archive) for lua codes, and one I am having trouble with is targeting players by chat.
You see this is every administration mod, where admins can type a command and a portion of a players name and it will find them and perform the action on them.
For Instance:
Let's say on a server there are some guys named 'Larry', 'Pual', and 'Joe'
The admin could type a command like 'kick' with a parameter of 'L','Lar', or 'LARRY' and it would pick out him, and only him. Not disturbing 'Paul' or 'Joe'
I would assume I would need to run a 'for loop' for all the players names and branch off that, but I wouldn't know where to start.
Any help would be appreciated. :D
[lua]
function FindPlayer(str)
local matches = {};
for k,v in pairs(player.GetAll()) do
if (v:GetName():lower():match(str:lower()) || v:SteamID():lower() == str:lower()) then
table.insert(matches, v);
end
end
if (table.Count(matches) == 0) then
return false, "No players found!";
end
if (table.Count(matches) > 1) then
return false, "More than 1 player found!";
end
return matches[1];
end
// usage:
local str = "jo" // this is the argument. eg !kick jo
local target, err = FindPlayer(str);
if (!target) then
Msg(err); // because print is broken :'(
return;
end
// target is good to go here!
target:Kick("kicked :P");
[/lua]
[editline]17th October 2012[/editline]
hook it into PlayerSay
[QUOTE=G4MB!T;38068453][lua]
function FindPlayer(str)
local matches = {};
for k,v in pairs(player.GetAll()) do
if (v:GetName():lower():match(str:lower()) || v:SteamID():lower() == str:lower()) then
table.insert(matches, v);
end
end
if (table.Count(matches) == 0) then
return false, "No players found!";
end
if (table.Count(matches) > 1) then
return false, "More than 1 player found!";
end
return matches[1];
end
// usage:
local str = "jo" // this is the argument. eg !kick jo
local target, err = FindPlayer(str);
if (!target) then
Msg(err); // because print is broken :'(
return;
end
// target is good to go here!
target:Kick("kicked :P");
[/lua]
[editline]17th October 2012[/editline]
hook it into PlayerSay[/QUOTE]
Thanks, but one problem:
When I hook it into PlayerSay
[SUB]hook.Add( "PlayerSay", "FindPlayer", FindPlayer );[/SUB]
I get this error:
[SUB]Hook 'FindPlayer' Failed: [gamemodes\flagrunner\gamemode\init.lua:107] attempt to call method 'lower' (a nil value)[/SUB]
That's because you're doing it wrong. PlayerSay takes a player (sender), a string (chat message), and a bool (public or not). You can't plug what he gave you directly into it because it's a single component of a larger function you're going to have to write yourself.
If you want to write a command parser (and your name isn't, say, Horsey) you're going to need two things — a PlayerSay hook using [url=http://pgl.yoyo.org/luai/i/string.find]string.find[/url] to try to find a chat command, and a table that matches chat commands with hook functions and runs the appropriate function.
And [i]then[/i] you can write a function for your "/kick" command that uses FindPlayer to try to find a single player and kick him.
no i meant like hook.Add("PlayerSay", "TargetPlayers", function(ply, text, bTeam) FindPlayer(string.Explode(" ", text)[1]) end)
something along the lines of that
[QUOTE=Luni;38077805]That's because you're doing it wrong. PlayerSay takes a player (sender), a string (chat message), and a bool (public or not). You can't plug what he gave you directly into it because it's a single component of a larger function you're going to have to write yourself.
If you want to write a command parser (and your name isn't, say, Horsey) you're going to need two things — a PlayerSay hook using [url=http://pgl.yoyo.org/luai/i/string.find]string.find[/url] to try to find a chat command, and a table that matches chat commands with hook functions and runs the appropriate function.
And [i]then[/i] you can write a function for your "/kick" command that uses FindPlayer to try to find a single player and kick him.[/QUOTE]
Still confused like hell, but thanks! I'll look it over and see if I can figure it out.
[lua]
hook.Add( "PlayerSay", "Chat Command", function( ply, text, toall )
local text2 = string.lower(text) -- Make everything lowercase.
if string.sub(text2, 0, #"!kick") == "!kick" then -- Check if the first 5 letters are "!kick"
text2 = string.Explode( " ", text ) -- Make the normal text (not all lowercase) into a table, seperated by spaces. Set what was the lowercase string as the table.
local victim, err = FindPlayer( text2[2] or "" ) -- Assume the first value in the table is the chat command, second should be the player. Send a blank string if there is only one value in the table.
if IsValid(victim) then -- Make sure it's valid.
victim:Kick( text[3] or "Kicked by "..ply:Nick() ) -- If you have a reason (assuming that's after the name), use it. If not, say who kicked the person.
else
ply:PrintMessage( HUD_PRINTTALK, err ) -- Tell the client what error they received.
end
return "" -- Don't send the command to the chat.
end
end )[/lua]
Beware Skiddie Noob Above Me He Doesnt Know Shit That Said It Is Overly Obvious How To Do This So Im Going To Let You Figure It Out On Your Own
Sorry, you need to Log In to post a reply to this thread.