Chat Command with an argument - Finding a players name
9 replies, posted
Hi everyone. I feel like I've messed up. The base lua files are yelling at me
[CODE]
[ERROR] lua/includes/util.lua:184: attempt to index local 'object' (a number value)
1. IsValid - lua/includes/util.lua:184
2. unknown - addons/ulib/lua/ulib/shared/hook.lua:186
[/CODE]
basically, I'm trying to make a whois system that opens a derma menu when someone types !whois <name>.
I've never done anything like this before, so I apologise if my code creates seizures
[CODE]
hook.Add("PlayerSay", 0, function( ply, text, teamc, alive )
local whois = string.Explode(" ", text);
local namae = player.GetAll()
if( whois[1] == "!whois" and (string.find( whois[2], namae, 0, true ))) then
print("help")
end
return ""
end)
[/CODE]
Yes I have googled it, ( chat commands with arguments site:facepunch.com ), and all I get is frameworks to add multiple. I just want to make this one command.
So if anyone could point me towards where I should be I'd be very grateful.
I'm pretty sure that the 2nd argument of string.find only takes a string, and you are giving it a table.
[QUOTE=EvacX;41671313]I'm pretty sure that the 2nd argument of string.find only takes a string, and you are giving it a table.[/QUOTE]
Hm. Would there be any other way to find the second argument? I'm stumped.
[code]function findPlayer(name)
for k,v in pairs(player.GetAll()) do
if string.find(name,v:Nick()) then
return v
end
end
return false
end
hook.Add("PlayerSay", 0, function( ply, text, teamc, alive )
local whois = string.Explode(" ", text);
local pl = findPlayer(whois[2])
if( whois[1] == "!whois" and pl) then
print(pl:Nick().." was found.")
end
return ""
end)[/code]
Untested, and doesn't check for multiple matches, but should work.
[QUOTE=KarmaLord;41682271][code]function findPlayer(name)
for k,v in pairs(player.GetAll()) do
if string.find(name,v:Nick()) then
return v
end
end
return false
end
hook.Add("PlayerSay", 0, function( ply, text, teamc, alive )
local whois = string.Explode(" ", text);
local pl = findPlayer(whois[2])
if( whois[1] == "!whois" and pl) then
print(pl:Nick().." was found.")
end
return ""
end)[/code]
Untested, and doesn't check for multiple matches, but should work.[/QUOTE]
Doesn't it seem a bit silly check if there's a player match even if the first word isn't "!whois"?
Getting the same error, I might just rewrite it again. guhguhg
I wrote this as an example for someone else using a console command method:
[lua]concommand.Add( "mycmd", function( ply, cmd, args )
-- ply is the person that calls it IE __YOU__!!!
-- cmd, I've never used
-- args is what you want to use
-- You can do it one of several ways:
-- if you know the ent index of the player, take Entity( tonumber( args[1] ) ) and you have your player.
-- If you want to target by name, you need to search:
local _match = NULL;
for k, v in pairs( player.GetAll( ) ) do
local _find = string.find( string.lower( v:Nick( ) ), string.lower( args[ 1 ] ) ); -- Returns nil if pattern not found, otherwise it returns index or so: [url]http://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index15fa.html[/url]
if ( !_find ) then
continue;
else
_match = v;
break;
end
end
if ( IsValid( _match ) && _match:IsPlayer( ) ) then
print( "We found the player you were looking for, their steamid is : " .. _match:SteamID( ) )
else
print( "The force was not with you on this one young grasshopper." )
end
end )[/lua]
Feel free to use an adapt it.
For PlayerSay, I'd say look into this:
// Here's a PlayerSay Example -- Tested and working....
[lua]function GM:PlayerSay ( Player, text, private )
//
// Do /commands privatly, !commands publicly
//
local _cmd = "whois";
local _bSlash = string.StartWith( text, "/" .. _cmd )
local _bExclaim = string.StartWith( text, "!" .. _cmd )
if ( _bSlash || _bExclaim ) then
// Here's where you can call your data.
local _arg = string.sub( text, string.len( _cmd ) + 3 );
local _match = NULL;
for k, v in pairs( player.GetAll( ) ) do
local _find = string.find( string.lower( v:Nick( ) ), string.lower( _arg ) );
if ( !_find ) then
continue;
else
_match = v;
break;
end
end
print( tostring( _match ) );
if ( !_bExclaim ) then
return "";
end
end
end[/lua]
Thanks all above me, especially Acecool <3
One last question if anyone wants to tell me to not explode everything:
I want to now use v:Nick() as the player in question in a information menu. Would I use the net library? I've never used it before and it's kind of scary. I don't really know where to start.
For example, in TTT, I can just use self.Player as I'm utilising the PANEL:DoRightClick() feature. But I'm trying to make it work in sandbox, and the menu is all clientside. So Acecools code goes in init.lua, and the derma menu is in cl_init? Or should I make a new file?
[URL=http://wiki.garrysmod.com/page/Using_the_net_library]I'm looking here,[/URL] and it seems like I'd use in init.lua[CODE]
util.AddNetworkString( "Menu" ) (at the top because it needs time?), net.Start( "Menu" ), net.Send( "Menu" )[/CODE]
Then in cl_init I'd do [CODE]net.Recieve( "Menu", function( v )
--create menu using v:Nick()
end)[/CODE]
Or would I have to define the Nick of the player again?
I think it'd be cool to learn this, so if anyone could point me in the right direction I would be very extremely muchly grateful.
Instead of sending the full length of a name, I'd personally send Player:EntIndex( ) which is a number. You can re-reference that Player Nick on the other side using Entity( EntIndex ):Nick( ).
Is this for the Sandbox scoreboard, or what? The Sandbox scoreboard allows use of self.Player in as it's referenced in the code.
Here's some of the sandbox code:
[lua]self.AvatarButton.DoClick = function() self.Player:ShowProfile() end
self.Mute.DoClick = function() self.Player:SetMuted( !self.Muted ) end[/lua]
You'd just have to add the right-click functionality to the name, for it to popup a menu. But self.Player exists, so you wouldn't need to network anything unless you want to take administrative action ( whereby you send the command to the server, the server verifies who you are and that your intentions are within the scope of your power, then carries them out -- unless it's a client-side mic mute or something for the client... )
My code was an example of two ways to do a search.. Well, one way, but with the scoreboard everything is in front of you, so you don't need to "search". Just create the code so you can click their name to popup a menu or whatever you want to do.
I've already made that, I'm just messing around to see if I could make it open via chat command. Thank you so much acecool, you're a really good teacher!
Sorry, you need to Log In to post a reply to this thread.