My first attempt at coding in lua!

Hey guys. So I’ve been planning on starting to learn Lua code for a long time and today I decided to sit my self down and learn. So far, I’ve created 3 pieces of code that fully work and here they are.

Now a heads up, these are the most simplest scripts ever so don’t expect big scripts haha.


hook.Add( "PlayerSay", "SteamIDCommand", function( ply, text, team ) -- Took me a while to understand how hooks worked because i'm dumb af

    local steamid64 = ply:SteamID64()
	local steamid = ply:SteamID()

    if( text == "!steamid") then -- Creation of the command !steamid
	    if steamid64 == (nil) then -- Checking if steamid64 is available - if it's not then ply:SteamID64() will defaultly return as a "nil value"
		ply:ChatPrint("Your SteamID64 is currently unretrieveable, please try again later") -- Prints chat to the player that their SteamID64 is unavailable.
		else
	    ply:ChatPrint("Your SteamID 64 is" .. steamid64) -- Concatenating string and variable to produce final product
		end
		
		if steamid == (nil) then
		ply:ChatPrint("Your SteamID is currently unretrieveable, please try again later")
		else
		ply:ChatPrint("Your SteamID is" .. steamid)
	end

end)

^ This code allows for a player to do !steamid to retrieve both of their steamid’s.

Here it is working. Not sure how to make the ChatPrint to go underneath the command like a normal message would but meh whatever.


hook.Add( "PlayerSay", "RetrievePlayerNamesCommand", function ( ply, text, team) -- Since it's a command, it's going to have to use this hook


	if ( text == "!allplayers") then -- Creation of the command !allplayers
		for k, v in pairs(player.GetAll()) do -- Runs through the table which is returned by "player.GetAll()"
		ply:ChatPrint(v:Nick() .. "
") -- v = player assigned to each key of the table - used as a substitute for ply since we're inside the for loop.
	    end -- Only just realised that you have to end for loops - silly me.
    
	end
	
end)

^ This bit of code prints out the names of all the players online once you type in !allplayers

As you can see it works, but again the darn print is above the command. Maybe I just used the wrong function (ply:ChatPrint)


hook.Add( "PlayerSay", "KillPlayerCommand", function ( ply, text, team) -- Another command, another hook.

	commandcheck = string.sub(text, 1, 5) -- Counted the letters in "kill" + the "!", this will check the first 5 letters of the string. This may conflict with other scripts that include this word e.g !killall
	playername = string.sub(text, 7) -- Makeshift "arguement" for this command

	if ( commandcheck == "!kill" or "/kill" ) then -- Makes sure that the first 5 letters of the string are indeed "/kill" or "!kill"
		for k, v in pairs(player.GetAll()) do -- Runs through the player table
			if v:Nick() == playername then -- so that we can make sure the player is indeed online.
				ply:Kill() -- Kills the unfortunate player that is chosen
			else
				ply:ChatPrint("Player could not be found") -- If any of the values in the player table do not match up with "playername" then this means the player does not exist or is offline.
			end
		end
	end
		
end)

^ When I made this I felt so proud of my self, even though it literally took me 3 minutes. I guess you pick up on Lua quite quickly.

There’s me dead by my own hands.

And that’s what happens when you try to kill your totally real friends.

I’d like for you guys to give me some suggestions on where to start next, anyways I could improve these scripts as I’ve seen people do these kind of scripts in like two lines lmao.

Also bare in mind that this was my first attempt at coding in Lua, the session was about 20 minutes so yeah.

Thanks!



return ""


[editline]22nd July 2017[/editline]

Also,



if steamid == (nil) then


Is the same as



if not steamid then


[editline]22nd July 2017[/editline]

BUT ONLY IN THIS CASE

By the way, I cleaned your commands a bit to be as simple as I can make them:



hook.Add( "PlayerSay", "SteamIDCommand", function( ply, text, team )

	if string.lower( text ) == "!steamid" then

		local steamID = ply:SteamID()
		local steamID64 = ply:SteamID64()

		if steamID then
			ply:ChatPrint( "Your SteamID is " .. steamID )
		else
			ply:ChatPrint( "Your SteamID is currently unretrieveable, please try again later" )
		end

		if steamID64 then
	    		ply:ChatPrint( "Your SteamID 64 is " .. steamID64 )
		else
	    		ply:ChatPrint( "Your SteamID64 is currently unretrieveable, please try again later" )
		end

		return ""

	end

end )

hook.Add( "PlayerSay", "RetrievePlayerNamesCommand", function( ply, text, team )

	if string.lower( text ) == "!allplayers" then

		for _, v in ipairs( player.GetHumans() ) do
			ply:ChatPrint( v:Nick() )
		end

		return ""

	end

end )

hook.Add( "PlayerSay", "KillPlayerCommand", function( ply, text, team )

	local command = string.lower( string.sub( text, 1, 5 ) )
	local args = string.sub( text, 7 )

	if command == "!kill" or command == "/kill" then

		local victim

		for _, v in ipairs( player.GetHumans() ) do
			if v:Nick() == args then
				victim = v
			end
		end

		if victim then
			victim:Kill()
		else
			ply:ChatPrint( "Player could not be found" )
		end

		return ""

	end
		
end )


By the way, you created 2 global variables in your original code:



commandcheck = string.sub(text, 1, 5)
playername = string.sub(text, 7)


Global variables are usually regarded with severe hatred and abuse

Also, this doesn’t work as you’d expect:



commandcheck == "!kill" or "/kill"


This version of the command runs whenever the text is anything, even though it looks like it’d only run with /kill or !kill. You have to do this:



commandcheck == "!kill" or commandcheck == "/kill"


Also, this loop doesn’t quite do what you’d expect:



for k, v in pairs(player.GetAll()) do
	if v:Nick() == playername then
		ply:Kill()
	else
		ply:ChatPrint("Player could not be found")
	end
end


This makes it so for every player that doesn’t have the name of playername, it will print “Player could not be found”, even if it is found later in the table. You have to do the sort of thing I did in the changed version of the code to get it to print correctly.

Also,

player.GetAll returns bots as well. you might want

player.GetHumans to make it work with humans only.

It’s also a sequential table, which means you can use

ipairs instead of

pairs, which is slightly faster.

Also you can move the


local steamID = ply:SteamID()
    local steamID64 = ply:SteamID64()

to inside of the if statement, there is no need to assign it every time someone types in chat without it being the command and actually being used.

I guess you could give net library a try, one main thing to note:
Don’t trust the client(side)! You can do checks client side, but still validate data on server side.

Also ye, what Mpan said with the:


commandcheck == "!kill" or "/kill"

Lua reads that as


(commandcheck == "!kill") or ("/kill")

By first checking if the commandcheck is “!kill”, if not, then it checks (if “/kill”), which will result in true, thus running the code with any command.

Also this:


if v:Nick() == playername then -- so that we can make sure the player is indeed online.
				ply:Kill() -- Kills the unfortunate player that is chosen
			else
				ply:ChatPrint("Player could not be found") -- If any of the values in the player table do not match up with "playername" then this means the player does not exist or is offline.
			end

Will kill the caller of that command if it find that nick, it should be v:kill()

But not for chat commands.

Chat commands already have ways to do stuff both on the client and on the server.

For the server:

GM:PlayerSay
For the client:

GM:OnPlayerChat

it was more of a suggestion on what to try next after this, something more specific could be this:
If you type in !colorchat some text here
it will print that text some random color in everyone’s chat.
You could use net library for that, by using net.Broadcast() to send the color and text, then on client using chat.AddText which supports colored text.

It is not the same. For this purpose, either could be substituted, but “not” is true for nil, false, and no value.

True, but for this case it’s pretty similar

check dis out :smiley: